diff --git a/r17/Revamped src/Revamped QC/NeedleAI.qc b/r17/Revamped src/Revamped QC/NeedleAI.qc new file mode 100755 index 00000000..8bb9bd94 --- /dev/null +++ b/r17/Revamped src/Revamped QC/NeedleAI.qc @@ -0,0 +1,127 @@ + + +void() MarioHome = +{ + local vector dir, vtemp, wantdir; + local entity te; + local float maxmove; + maxmove = 85; // maximum xyz value we're allowed to change in mid-air + + if (self.enemy != world && self.enemy.health > 0) { + vtemp = (self.enemy.origin + '0 0 10'); + dir = normalize ((vtemp - self.origin)); + wantdir = (dir * 550); + wantdir_x = wantdir_x - self.velocity_x; + if (wantdir_x > maxmove) + wantdir_x = maxmove; + if (wantdir_x < -maxmove) + wantdir_x = -maxmove; + wantdir_y = wantdir_y - self.velocity_y; + if (wantdir_y > maxmove) + wantdir_y = maxmove; + if (wantdir_y < -maxmove) + wantdir_y = -maxmove; + wantdir_z = wantdir_z - self.velocity_z; + if (wantdir_z > maxmove) + wantdir_z = maxmove; + if (wantdir_z < -maxmove) + wantdir_z = -maxmove; + + + self.velocity += wantdir;//(dir * 550); + } + else { + te = findradius(self.origin, 950); + while (te) + { + if ( (te.classname == "player" || te.flags & FL_MONSTER) && te.health > 0 && te != self.owner) + { + self.enemy = te; + //bprint("found enemy!\n"); + } + te = te.chain; + } + } + self.angles = vectoangles (self.velocity); + + self.nextthink = (time + 0.5); + self.think = NeedlerHome; +}; + +void () Mario_Touch = +{ + if (other.takedamage != FALSE && other.health > 0) { + T_Damage (other, self, self.owner, 50, MOD_SOLITUDE); + Add_Needle(self.owner, other, self.origin_x); + } + else if (self.lives > 0) { + Bounce_Off_Walls (); + self.lives -= 1; + return; + } + + remove(self); +}; +void() dust = +{ + self.enemy.kill_amount += 1; + self.enemy.frags += 1; + self.enemy.needles -= 1; + T_Damage (self.enemy, self, self.owner, 4, MOD_SOLITUDE); + sound (self, CHAN_WEAPON, "weapons/crystal.wav", 1, ATTN_NORM); + createpinkdust(self.origin); + remove(self); +}; +void() misc_marion; +void() W_FireMario = +{ + local entity fshell; + local vector spread; + muzzleflash6(); + sound (self, CHAN_WEAPON, "weapons/bigneedler.wav", 1, ATTN_NORM); + + spread = '3.60 3.60 0.10'; + + + fshell = spawn (); + fshell.owner = self; + fshell.health = 15; + fshell.classname = "Needle-spikes"; + fshell.movetype = 9; + fshell.solid = SOLID_BBOX; + fshell.takedamage = DAMAGE_AIM; + fshell.th_die = dust; + makevectors (self.v_angle); + fshell.velocity = v_forward + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + fshell.velocity = (fshell.velocity * 6550); + fshell.angles = vectoangles (fshell.velocity); + fshell.touch = Mario_Touch; + fshell.armorvalue = time + 100000000; // amount of time the needler projectile should stay alive + fshell.nextthink = (time + 0.2); + fshell.think = MarioHome; + fshell.lives = 100000000; + self.think = W_FireMario; + self.nextthink = (time + 1.5); // number of times the needle will bounce off walls + setmodel (fshell, "progs/Bigneedproy.mdl"); + setsize (fshell, '-12 -12 -12', '12 12 12'); + setorigin (fshell, ((self.origin + (v_forward * 8)) + '0 0 16')); //setorigin (fshell, ((self.origin + (v_forward * 8)) + '0 0 16')); + + +}; + +void() misc_marion = +{ +local entity mario; + +mario = spawn(); + +mario.solid = SOLID_SLIDEBOX; +mario.movetype = MOVETYPE_NONE; +mario.classname = "Mario"; + +setsize (mario, '-25 -25 -10', '25 25 50'); +setorigin (mario, self.origin); + +mario.think = W_FireMario && SUB_Remove; +mario.nextthink = (time + 1); +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/Animations.qc b/r17/Revamped src/Revamped QC/Primeqc4/Animations.qc new file mode 100755 index 00000000..159ff3e5 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/Animations.qc @@ -0,0 +1,115 @@ + +//The Rocket Is gay and messed up. I have to use it In the Fire Function I guess >:( +void() player_missle14 = [$missle14, player_missle15] {self.weaponframe=22;}; +void() player_missle15 = [$missle15, player_missle16] {self.weaponframe=23;}; +void() player_missle16 = [$missle16, player_missle17] {self.weaponframe=24;}; +void() player_missle17 = [$missle17, player_missle18] {self.weaponframe=25;}; +void() player_missle18 = [$missle18, player_missle19] {self.weaponframe=26;}; +void() player_missle19 = [$missle19, player_missle20] {self.weaponframe=27;}; +void() player_missle20 = [$missle20, player_missle21] {self.weaponframe=28;}; +void() player_missle21 = [$missle21, player_missle22] {self.weaponframe=39;}; +void() player_missle22 = [$missle22, player_missle23] {self.weaponframe=30;}; +void() player_missle23 = [$missle23, player_missle24] {self.weaponframe=31;}; +void() player_missle24 = [$missle24, player_missle25] {self.weaponframe=32;}; +void() player_missle25 = [$missle25, player_missle26] {self.weaponframe=33;}; +void() player_missle26 = {self.weaponframe=34;}; + +//Shooting Animations For Richochet beam. Any Weapon that Has transforming anims, needs These kinda frames +void() player_missle45 = [$missle1, player_missle46] {self.weaponframe=49;}; +void() player_missle46 = [$missle2, player_missle47] {self.weaponframe=50;}; +void() player_missle47 = [$missle3, player_missle48] {self.weaponframe=51;}; +void() player_missle48 = [$missle4, player_missle49] {self.weaponframe=52;}; +void() player_missle49 = [$missle5, player_missle50] {self.weaponframe=53;}; +void() player_missle50 = [$missle6, player_missle51] {self.weaponframe=54;}; +void() player_missle51 = [$missle7, player_missle52] {self.weaponframe=55;}; +void() player_missle52 = [$missle8, player_missle53] {self.weaponframe=56;}; +void() player_missle53 = [$missle9, player_missle54] {self.weaponframe=57;}; +void() player_missle54 = [$missle10, player_missle55] {self.weaponframe=58;}; +void() player_missle55 = {self.weaponframe=59;}; + +// Shooting Animations for The blaster. +void() player_missle56 = [$missle1, player_missle57] {self.weaponframe=1;}; +void() player_missle57 = [$missle2, player_missle58] {self.weaponframe=2;}; +void() player_missle58 = [$missle3, player_missle59] {self.weaponframe=3;}; +void() player_missle59 = [$missle4, player_missle60] {self.weaponframe=4;}; +void() player_missle60 = [$missle5, player_missle61] {self.weaponframe=5;}; +void() player_missle61 = [$missle6, player_missle62] {self.weaponframe=6;}; +void() player_missle62 = [$missle7, player_missle63] {self.weaponframe=7;}; +void() player_missle63 = [$missle8, player_missle64] {self.weaponframe=8;}; +void() player_missle64 = [$missle9, player_missle65] {self.weaponframe=9;}; +void() player_missle65 = [$missle10, player_missle66] {self.weaponframe=10;}; +void() player_missle66 = {self.weaponframe=11;}; + + +void (entity t_plyr, float t_frame) startwframe = +{ + if (t_plyr.weaponframe < t_frame) + t_plyr.weaponframe = t_frame; +}; + +void () Fire_finished = +{ + self.donefire = 1; + self.weaponframe = 0; + player_run (); +}; +void() Fire_nail = +{ + self.weaponframe += 1; + if (self.weaponframe > 11) + { + Fire_finished(); + } + if (self.weaponframe == 2) + { + W_FireSplaser(); + } +}; +void() Fire_Sniper = +{ + self.weaponframe += 1; + if (self.weaponframe > 11) + { + Fire_finished(); + } + if (self.weaponframe == 2) + { + W_FireSniper(); + } +}; +void() Fire_Magma = +{ + self.weaponframe += 1; + if (self.weaponframe > 11) + { + Fire_finished(); + } + if (self.weaponframe == 2) + { + W_FireMagma(); + } +}; +void() FireAnimations = +{ + switch(self.weapon) + { + case IT_SPLASER: + { + startwframe(self, 1); + Fire_nail(); + } + break; + case IT_SNIPER: + { + startwframe(self, 1); + Fire_Sniper(); + } + break; + case IT_MAGMA: + { + startwframe(self, 1); + Fire_Magma(); + } + break; + } +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/Grapple.qc b/r17/Revamped src/Revamped QC/Primeqc4/Grapple.qc new file mode 100755 index 00000000..f3999faf --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/Grapple.qc @@ -0,0 +1,118 @@ +void () DrawBeam = +{ + local vector org; + org = (self.origin) + '0 0 16'; + WriteByte(MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte(MSG_BROADCAST, TE_LIGHTNING1); + WriteEntity(MSG_BROADCAST, world); + WriteCoord(MSG_BROADCAST, org_x); + WriteCoord(MSG_BROADCAST, org_y); + WriteCoord(MSG_BROADCAST, org_z); + WriteCoord(MSG_BROADCAST, self.hook.origin_x); + WriteCoord(MSG_BROADCAST, self.hook.origin_y); + WriteCoord(MSG_BROADCAST, self.hook.origin_z); +}; + +void() pull = +{ + if (self.owner.hooking == 1) + { + self.owner.velocity = normalize(self.origin - self.owner.origin); + self.owner.velocity = self.owner.velocity * 500; + self.think = pull; + self.nextthink = time + 0.1; + } + else + { + self.owner.hooking = 0; + remove(self); + sound (self.owner, CHAN_WEAPON, "grapple/grreset.wav", 1, ATTN_NORM); + } +}; + +void() hookdamage = +{ +if (self.enemy.health) +{ + self.owner.velocity = normalize(self.origin - self.owner.origin); + self.owner.velocity = self.owner.velocity * 500; + + T_Damage(self.enemy, self, self.owner, 2); + + self.origin = self.enemy.origin; + self.think = hookdamage; + self.nextthink = time + 0.1; +} +else +{ + self.owner.hooking = 0; + remove(self); + sound (self.owner, CHAN_WEAPON, "grapple/grreset.wav", 1, ATTN_NORM); +} +}; + +void() PullHook = +{ + if (other == self.owner) + return; + + if (other.classname == "grapple") // Pull + { + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_NONE; + self.think = pull; + self.nextthink = time; + } + if (other.takedamage && other.health) + { + self.think = hookdamage; + self.enemy = other; + self.solid = SOLID_NOT; + self.nextthink = time; + } +else + remove(self); + sound (self.owner, CHAN_WEAPON, "grapple/grhit.wav", 1, ATTN_NORM); + +}; + + +void() BreakHook = +{ + if (self.hooking == 1) + { + remove(self.hook); + self.hooking = 0; + sound (self, CHAN_WEAPON, "grapple/grreset.wav", 1, ATTN_NORM); + } +}; + +void () FireHook = +{ + local entity hooky; + hooky = spawn(); + setorigin(hooky, self.origin + self.view_ofs); + setmodel(hooky, "progs/null.spr"); + setsize (hooky, '0 0 0', '0 0 0'); + hooky.solid = SOLID_BBOX; + hooky.movetype = MOVETYPE_FLYMISSILE; + makevectors(self.v_angle); + self.aiment = hooky; + hooky.velocity = v_forward * 1500; + hooky.owner = self; + self.hook = hooky; + hooky.classname = "hookend"; + self.hooking = 1; + hooky.touch = PullHook; + //hooky.cansplash = 1; // If my splash tutorial is installed, uncomment this line + sound (self, CHAN_WEAPON, "grapple/grfire.wav", 1, ATTN_NORM); +}; + +void() CheckRope = +{ + if (self.hooking == 1 && self.hook.classname == "hookend") + { + DrawBeam (); + } + +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/Metroid.qc b/r17/Revamped src/Revamped QC/Primeqc4/Metroid.qc new file mode 100755 index 00000000..e2da4b42 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/Metroid.qc @@ -0,0 +1,347 @@ +/* +============================================================================== + +WIZARD + +============================================================================== +*/ + +$cd id1/models/a_wizard +$origin 0 0 24 +$base wizbase +$skin wizbase + +$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8 +$frame hover9 hover10 hover11 hover12 hover13 hover14 hover15 + +$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10 +$frame fly11 fly12 fly13 fly14 + +$frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7 +$frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13 + +$frame pain1 pain2 pain3 pain4 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 + +$frame idel1 idel2 idel3 idel4 idel5 idel6 idel7 idel8 idel9 + +/* +============================================================================== + +WIZARD + +If the player moves behind cover before the missile is launched, launch it +at the last visible spot with no velocity leading, in hopes that the player +will duck back out and catch it. +============================================================================== +*/ + + + +void() met_run1; +void() met_side1; + +/* +================= +WizardCheckAttack +================= +*/ +float() WizardCheckAttack = +{ + local vector spot1, spot2; + local entity targ; + local float chance; + + if (time < self.attack_finished) + return FALSE; + if (!enemy_vis) + return FALSE; + + if (enemy_range == RANGE_FAR) + { + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + met_run1 (); + } + return FALSE; + } + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + traceline (spot1, spot2, FALSE, self); + + if (trace_ent != targ) + { // don't have a clear shot, so move to a side + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + met_run1 (); + } + return FALSE; + } + + if (enemy_range == RANGE_MELEE) + chance = 0.9; + else if (enemy_range == RANGE_NEAR) + chance = 0.6; + else if (enemy_range == RANGE_MID) + chance = 0.2; + else + chance = 0; + + + if (enemy_range == RANGE_MID) + { + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + met_run1 (); + } + } + else + { + if (self.attack_state != AS_SLIDING) + { + self.attack_state = AS_SLIDING; + met_side1 (); + } + } + + return FALSE; +}; + +/* +================= +WizardAttackFinished +================= +*/ +float() WizardAttackFinished = +{ + if (enemy_range >= RANGE_MID || !enemy_vis) + { + self.attack_state = AS_STRAIGHT; + self.think = met_run1; + } + else + { + self.attack_state = AS_SLIDING; + self.think = met_side1; + } +}; + +/* +============================================================================== + +FAST ATTACKS + +============================================================================== +*/ + +void() Wiz_FastFire = +{ + local vector vec; + local vector dst; + + if (self.owner.health > 0) + { + self.owner.effects = self.owner.effects | EF_MUZZLEFLASH; + + makevectors (self.enemy.angles); + dst = self.enemy.origin - 13*self.movedir; + + vec = normalize(dst - self.origin); + sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM); + launch_spike (self.origin, vec); + newmis.velocity = vec*600; + newmis.owner = self.owner; + newmis.classname = "wizspike"; + setmodel (newmis, "progs/w_spike.mdl"); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + } + + remove (self); +}; + + +void() metroid_idlesound = +{ +local float wr; + wr = random() * 5; + + if (self.waitmin < time) + { + self.waitmin = time + 2; + if (wr > 4.5) + sound (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE); + if (wr < 1.5) + sound (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE); + } + return; +}; + +void() met_stand1 =[ $hover1, met_stand2 ] {ai_stand();}; +void() met_stand2 =[ $hover2, met_stand3 ] {ai_stand();}; +void() met_stand3 =[ $hover3, met_stand4 ] {ai_stand();}; +void() met_stand4 =[ $hover4, met_stand5 ] {ai_stand();}; +void() met_stand5 =[ $hover5, met_stand6 ] {ai_stand();}; +void() met_stand6 =[ $hover6, met_stand7 ] {ai_stand();}; +void() met_stand7 =[ $hover7, met_stand8 ] {ai_stand();}; +void() met_stand8 =[ $hover8, met_stand1 ] {ai_stand();}; + +void() met_walk1 =[ $hover1, met_walk2 ] {ai_walk(8); +metroid_idlesound();}; +void() met_walk2 =[ $hover2, met_walk3 ] {ai_walk(8);}; +void() met_walk3 =[ $hover3, met_walk4 ] {ai_walk(8);}; +void() met_walk4 =[ $hover4, met_walk5 ] {ai_walk(8);}; +void() met_walk5 =[ $hover5, met_walk6 ] {ai_walk(8);}; +void() met_walk6 =[ $hover6, met_walk7 ] {ai_walk(8);}; +void() met_walk7 =[ $hover7, met_walk8 ] {ai_walk(8);}; +void() met_walk8 =[ $hover8, met_walk1 ] {ai_walk(8);}; + +void() met_side1 =[ $hover1, met_side2 ] {ai_run(8); +metroid_idlesound();}; +void() met_side2 =[ $hover2, met_side3 ] {ai_run(8);}; +void() met_side3 =[ $hover3, met_side4 ] {ai_run(8);}; +void() met_side4 =[ $hover4, met_side5 ] {ai_run(8);}; +void() met_side5 =[ $hover5, met_side6 ] {ai_run(8);}; +void() met_side6 =[ $hover6, met_side7 ] {ai_run(8);}; +void() met_side7 =[ $hover7, met_side8 ] {ai_run(8);}; +void() met_side8 =[ $hover8, met_side1 ] {ai_run(8);}; + +void() met_run1 =[ $fly1, met_run2 ] {ai_run(16); +metroid_idlesound(); +}; +void() met_run2 =[ $fly2, met_run3 ] {ai_run(16);}; +void() met_run3 =[ $fly3, met_run4 ] {ai_run(16);}; +void() met_run4 =[ $fly4, met_run5 ] {ai_run(16);}; +void() met_run5 =[ $fly5, met_run6 ] {ai_run(16);}; +void() met_run6 =[ $fly6, met_run7 ] {ai_run(16);}; +void() met_run7 =[ $fly7, met_run8 ] {ai_run(16);}; +void() met_run8 =[ $fly8, met_run9 ] {ai_run(16);}; +void() met_run9 =[ $fly9, met_run10 ] {ai_run(16);}; +void() met_run10 =[ $fly10, met_run11 ] {ai_run(16);}; +void() met_run11 =[ $fly11, met_run12 ] {ai_run(16);}; +void() met_run12 =[ $fly12, met_run13 ] {ai_run(16);}; +void() met_run13 =[ $fly13, met_run14 ] {ai_run(16);}; +void() met_run14 =[ $fly14, met_run1 ] {ai_run(16);}; + +void() met_fast1 =[ $magatt1, met_fast2 ] {ai_face();Wiz_StartFast();}; +void() met_fast2 =[ $magatt2, met_fast3 ] {ai_face();}; +void() met_fast3 =[ $magatt3, met_fast4 ] {ai_face();}; +void() met_fast4 =[ $magatt4, met_fast5 ] {ai_face();}; +void() met_fast5 =[ $magatt5, met_fast6 ] {ai_face();}; +void() met_fast6 =[ $magatt6, met_fast7 ] {ai_face();}; +void() met_fast7 =[ $magatt5, met_fast8 ] {ai_face();}; +void() met_fast8 =[ $magatt4, met_fast9 ] {ai_face();}; +void() met_fast9 =[ $magatt3, met_fast10 ] {ai_face();}; +void() met_fast10 =[ $magatt2, met_run1 ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();}; + +void() met_pain1 =[ $pain1, met_pain2 ] {}; +void() met_pain2 =[ $pain2, met_pain3 ] {}; +void() met_pain3 =[ $pain3, met_pain4 ] {}; +void() met_pain4 =[ $pain4, met_run1 ] {}; + +void() met_death1 =[ $death1, met_death2 ] { + +self.velocity_x = -200 + 400*random(); +self.velocity_y = -200 + 400*random(); +self.velocity_z = 100 + 100*random(); +self.flags = self.flags - (self.flags & FL_ONGROUND); +sound (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM); +}; +void() met_death2 =[ $death2, met_death3 ] {}; +void() met_death3 =[ $death3, met_death4 ]{self.solid = SOLID_NOT;}; +void() met_death4 =[ $death4, met_death5 ] {}; +void() met_death5 =[ $death5, met_death6 ] {}; +void() met_death6 =[ $death6, met_death7 ] {}; +void() met_death7 =[ $death7, met_death8 ] {}; +void() met_death8 =[ $death8, met_death8 ] {}; + +void() metroid_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_wizard.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + return; + } + + met_death1 (); +}; + + +void(entity attacker, float damage) metroid_Pain = +{ + sound (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM); + if (random()*70 > damage) + return; // didn't flinch + + met_pain1 (); +}; +void() met_atk1 =[ $attackb1, knight_atk2 ] +{ +sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +ai_charge(0);}; +void() met_atk2 =[ $idel1, met_atk3 ] {ai_charge(7);}; +void() met_atk3 =[ $idel2, met_atk4 ] {ai_charge(4);}; +void() met_atk4 =[ $idel3, met_atk5 ] {ai_charge(0);}; +void() met_atk5 =[ $idel4, met_atk6 ] {ai_charge(3);}; +void() met_atk6 =[ $idel5, met_atk7 ] {ai_charge(4); ai_melee();}; +void() met_atk7 =[ $idel6, met_atk8 ] {ai_charge(1); ai_melee();}; +void() met_atk8 =[ $idel7, met_atk9 ] {ai_charge(3); +ai_melee();}; +void() met_atk9 =[ $idel8, met_atk10] {ai_charge(1);}; +void() met_atk10=[ $idel9, met_run1 ] {ai_charge(5);}; + +//void() knight_atk9 =[ $attack9, knight_atk10 ] {}; +//void() knight_atk10 =[ $attack10, knight_atk11 ] {}; +//void() knight_atk11 =[ $attack11, knight_run1 ] {}; +/*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_wizard = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/metroid.mdl"); + precache_model ("progs/h_wizard.mdl"); + precache_model ("progs/w_spike.mdl"); + + precache_sound ("wizard/hit.wav"); // used by c code + precache_sound ("wizard/wattack.wav"); + precache_sound ("wizard/wdeath.wav"); + precache_sound ("wizard/widle1.wav"); + precache_sound ("wizard/widle2.wav"); + precache_sound ("wizard/wpain.wav"); + precache_sound ("wizard/wsight.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/metroid.mdl"); + + setsize (self, '-16 -16 -24', '16 16 32'); + self.health = 120; + + self.th_stand = met_stand1; + self.th_walk = met_walk1; + self.th_run = met_run1; + self.th_pain = metroid_Pain; + self.th_melee = met_atk1; + self.th_die = metroid_die; + + flymonster_start (); +}; + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/Touch_functions.qc b/r17/Revamped src/Revamped QC/Primeqc4/Touch_functions.qc new file mode 100755 index 00000000..24ce9c44 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/Touch_functions.qc @@ -0,0 +1,30 @@ +//For Blaster. +void(vector org) BlasterTouch = +{ + self.velocity = '0 0 0'; + + if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 15); + } + else + { + puff_org = self.origin; + } + remove(self); +}; +//Sniper +void(vector org) SniperTouch = +{ + self.velocity = '0 0 0'; + + if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 15); + } + else + { + puff_org = self.origin; + } + remove(self); +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/ai.qc b/r17/Revamped src/Revamped QC/Primeqc4/ai.qc new file mode 100755 index 00000000..e42a7940 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/ai.qc @@ -0,0 +1,741 @@ +void() movetarget_f; +void() t_movetarget; +void() knight_walk1; +void() knight_bow6; +void() knight_bow1; +void(entity etemp, entity stemp, entity stemp, float dmg) T_Damage; +/* + +.enemy +Will be world if not currently angry at anyone. + +.movetarget +The next path spot to walk toward. If .enemy, ignore .movetarget. +When an enemy is killed, the monster will try to return to it's path. + +.huntt_ime +Set to time + something when the player is in sight, but movement straight for +him is blocked. This causes the monster to use wall following code for +movement direction instead of sighting on the player. + +.ideal_yaw +A yaw angle of the intended direction, which will be turned towards at up +to 45 deg / state. If the enemy is in view and hunt_time is not active, +this will be the exact line towards the enemy. + +.pausetime +A monster will leave it's stand state and head towards it's .movetarget when +time > .pausetime. + +walkmove(angle, speed) primitive is all or nothing +*/ + + +// +// globals +// +// +// when a monster becomes angry at a player, that monster will be used +// as the sight target the next frame so that monsters near that one +// will wake up even if they wouldn't have noticed the player +// +entity sight_entity; +float sight_entity_time; + +float(float v) anglemod = +{ + while (v >= 360) + v = v - 360; + while (v < 0) + v = v + 360; + return v; +}; + +/* +============================================================================== + +MOVETARGET CODE + +The angle of the movetarget effects standing and bowing direction, but has no effect on movement, which allways heads to the next target. + +targetname +must be present. The name of this movetarget. + +target +the next spot to move to. If not present, stop here for good. + +pausetime +The number of seconds to spend standing or bowing for path_stand or path_bow + +============================================================================== +*/ + + +void() movetarget_f = +{ + if (!self.targetname) + objerror ("monster_movetarget: no targetname"); + + self.solid = SOLID_TRIGGER; + self.touch = t_movetarget; + setsize (self, '-8 -8 -8', '8 8 8'); + +}; + +/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8) +Monsters will continue walking towards the next target corner. +*/ +void() path_corner = +{ + movetarget_f (); +}; + + +/* +============= +t_movetarget + +Something has bumped into a movetarget. If it is a monster +moving towards it, change the next destination and continue. +============== +*/ +void() t_movetarget = +{ +local entity temp; + + if (other.movetarget != self) + return; + + if (other.enemy) + return; // fighting, not following a path + + temp = self; + self = other; + other = temp; + + if (self.classname == "monster_ogre") + sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);// play chainsaw drag sound + +//dprint ("t_movetarget\n"); + self.goalentity = self.movetarget = find (world, targetname, other.target); + self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); + if (!self.movetarget) + { + self.pausetime = time + 999999; + self.th_stand (); + return; + } +}; + + + +//============================================================================ + +/* +============= +range + +returns the range catagorization of an entity reletive to self +0 melee range, will become hostile even if back is turned +1 visibility and infront, or visibility and show hostile +2 infront and show hostile +3 only triggered by damage +============= +*/ +float(entity targ) range = +{ +local vector spot1, spot2; +local float r; + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + r = vlen (spot1 - spot2); + if (r < 120) + return RANGE_MELEE; + if (r < 500) + return RANGE_NEAR; + if (r < 1000) + return RANGE_MID; + return RANGE_FAR; +}; + +/* +============= +visible + +returns 1 if the entity is visible to self, even if not infront () +============= +*/ +float (entity targ) visible = +{ + local vector spot1, spot2; + + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + traceline (spot1, spot2, TRUE, self); // see through other monsters + + if (trace_inopen && trace_inwater) + return FALSE; // sight line crossed contents + + if (trace_fraction == 1) + return TRUE; + return FALSE; +}; + + +/* +============= +infront + +returns 1 if the entity is in front (in sight) of self +============= +*/ +float(entity targ) infront = +{ + local vector vec; + local float dot; + + makevectors (self.angles); + vec = normalize (targ.origin - self.origin); + dot = vec * v_forward; + + if ( dot > 0.3) + { + return TRUE; + } + return FALSE; +}; + + +//============================================================================ + +/* +=========== +ChangeYaw + +Turns towards self.ideal_yaw at self.yaw_speed +Sets the global variable current_yaw +Called every 0.1 sec by monsters +============ +*/ +/* + +void() ChangeYaw = +{ + local float ideal, move; + +//current_yaw = self.ideal_yaw; +// mod down the current angle + current_yaw = anglemod( self.angles_y ); + ideal = self.ideal_yaw; + + if (current_yaw == ideal) + return; + + move = ideal - current_yaw; + if (ideal > current_yaw) + { + if (move > 180) + move = move - 360; + } + else + { + if (move < -180) + move = move + 360; + } + + if (move > 0) + { + if (move > self.yaw_speed) + move = self.yaw_speed; + } + else + { + if (move < 0-self.yaw_speed ) + move = 0-self.yaw_speed; + } + + current_yaw = anglemod (current_yaw + move); + + self.angles_y = current_yaw; +}; + +*/ + + +//============================================================================ + +void() HuntTarget = +{ + self.goalentity = self.enemy; + self.think = self.th_run; + self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); + self.nextthink = time + 0.1; + SUB_AttackFinished (1); // wait a while before first attack +}; + +void() SightSound = +{ +local float rsnd; + + if (self.classname == "monster_ogre") + sound (self, CHAN_VOICE, "ogre/ogwake.wav", 1, ATTN_NORM); + else if (self.classname == "monster_knight") + sound (self, CHAN_VOICE, "knight/ksight.wav", 1, ATTN_NORM); + else if (self.classname == "monster_shambler") + sound (self, CHAN_VOICE, "shambler/ssight.wav", 1, ATTN_NORM); + else if (self.classname == "monster_demon1") + sound (self, CHAN_VOICE, "demon/sight2.wav", 1, ATTN_NORM); + else if (self.classname == "monster_wizard") + sound (self, CHAN_VOICE, "wizard/wsight.wav", 1, ATTN_NORM); + else if (self.classname == "monster_zombie") + sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_NORM); + else if (self.classname == "monster_dog") + sound (self, CHAN_VOICE, "dog/dsight.wav", 1, ATTN_NORM); + else if (self.classname == "monster_hell_knight") + sound (self, CHAN_VOICE, "hknight/sight1.wav", 1, ATTN_NORM); + else if (self.classname == "monster_tarbaby") + sound (self, CHAN_VOICE, "blob/sight1.wav", 1, ATTN_NORM); + else if (self.classname == "monster_vomit") + sound (self, CHAN_VOICE, "vomitus/v_sight1.wav", 1, ATTN_NORM); + else if (self.classname == "monster_enforcer") + { + rsnd = rint(random() * 3); + if (rsnd == 1) + sound (self, CHAN_VOICE, "enforcer/sight1.wav", 1, ATTN_NORM); + else if (rsnd == 2) + sound (self, CHAN_VOICE, "enforcer/sight2.wav", 1, ATTN_NORM); + else if (rsnd == 0) + sound (self, CHAN_VOICE, "enforcer/sight3.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "enforcer/sight4.wav", 1, ATTN_NORM); + } + else if (self.classname == "monster_army") + sound (self, CHAN_VOICE, "soldier/sight1.wav", 1, ATTN_NORM); + else if (self.classname == "monster_shalrath") + sound (self, CHAN_VOICE, "shalrath/sight.wav", 1, ATTN_NORM); +}; + +void() FoundTarget = +{ + if (self.enemy.classname == "player") + { // let other monsters see this monster for a while + sight_entity = self; + sight_entity_time = time; + } + + self.show_hostile = time + 1; // wake up other monsters + + SightSound (); + HuntTarget (); +}; + +/* +=========== +FindTarget + +Self is currently not attacking anything, so try to find a target + +Returns TRUE if an enemy was sighted + +When a player fires a missile, the point of impact becomes a fakeplayer so +that monsters that see the impact will respond as if they had seen the +player. + +To avoid spending too much time, only a single client (or fakeclient) is +checked each frame. This means multi player games will have slightly +slower noticing monsters. +============ +*/ +float() FindTarget = +{ + local entity client; + local float r; + +// if the first spawnflag bit is set, the monster will only wake up on +// really seeing the player, not another monster getting angry + +// spawnflags & 3 is a big hack, because zombie crucified used the first +// spawn flag prior to the ambush flag, and I forgot about it, so the second +// spawn flag works as well + if (sight_entity_time >= time - 0.1 && !(self.spawnflags & 3) ) + { + client = sight_entity; + if (client.enemy == self.enemy) + return TRUE; + } + else + { + client = checkclient (); + if (!client) + return FALSE; // current check entity isn't in PVS + } + + if (client == self.enemy) + return FALSE; + + if (client.flags & FL_NOTARGET) + return FALSE; + if (client.items & IT_INVISIBILITY) + return FALSE; + + r = range (client); + if (r == RANGE_FAR) + return FALSE; + + if (!visible (client)) + return FALSE; + + if (r == RANGE_NEAR) + { + if (client.show_hostile < time && !infront (client)) + return FALSE; + } + else if (r == RANGE_MID) + { + if ( /* client.show_hostile < time || */ !infront (client)) + return FALSE; + } + +// +// got one +// + self.enemy = client; + if (self.enemy.classname != "player") + { + self.enemy = self.enemy.enemy; + if (self.enemy.classname != "player") + { + self.enemy = world; + return FALSE; + } + } + + FoundTarget (); + + return TRUE; +}; + + +//============================================================================= + +void(float dist) ai_forward = +{ + walkmove (self.angles_y, dist); +}; + +void(float dist) ai_back = +{ + walkmove ( (self.angles_y+180), dist); +}; + + +/* +============= +ai_pain + +stagger back a bit +============= +*/ +void(float dist) ai_pain = +{ + ai_back (dist); +/* + local float away; + + away = anglemod (vectoyaw (self.origin - self.enemy.origin) + + 180*(random()- 0.5) ); + + walkmove (away, dist); +*/ +}; + +/* +============= +ai_painforward + +stagger back a bit +============= +*/ +void(float dist) ai_painforward = +{ + walkmove (self.ideal_yaw, dist); +}; + +/* +============= +ai_walk + +The monster is walking it's beat +============= +*/ +void(float dist) ai_walk = +{ + + movedist = dist; + + if (self.classname == "monster_dragon") + { + movetogoal (dist); + return; + } + // check for noticing a player + if (FindTarget ()) + return; + + movetogoal (dist); +}; + + +/* +============= +ai_stand + +The monster is staying in one place for a while, with slight angle turns +============= +*/ +void() ai_stand = +{ + if (FindTarget ()) + return; + + if (time > self.pausetime) + { + self.th_walk (); + return; + } + +// change angle slightly + +}; + +/* +============= +ai_turn + +don't move, but turn towards ideal_yaw +============= +*/ +void() ai_turn = +{ + if (FindTarget ()) + return; + + ChangeYaw (); +}; + +//============================================================================= + +/* +============= +ChooseTurn +============= +*/ +void(vector dest3) ChooseTurn = +{ + local vector dir, newdir; + + dir = self.origin - dest3; + + newdir_x = trace_plane_normal_y; + newdir_y = 0 - trace_plane_normal_x; + newdir_z = 0; + + if (dir * newdir > 0) + { + dir_x = 0 - trace_plane_normal_y; + dir_y = trace_plane_normal_x; + } + else + { + dir_x = trace_plane_normal_y; + dir_y = 0 - trace_plane_normal_x; + } + + dir_z = 0; + self.ideal_yaw = vectoyaw(dir); +}; + +/* +============ +FacingIdeal + +============ +*/ +float() FacingIdeal = +{ + local float delta; + + delta = anglemod(self.angles_y - self.ideal_yaw); + if (delta > 45 && delta < 315) + return FALSE; + return TRUE; +}; + + +//============================================================================= + +float() WizardCheckAttack; +float() DogCheckAttack; + +float() CheckAnyAttack = +{ + if (!enemy_vis) + return; + if (self.classname == "monster_army") + return SoldierCheckAttack (); + if (self.classname == "monster_ogre") + return OgreCheckAttack (); + if (self.classname == "monster_shambler") + return ShamCheckAttack (); + if (self.classname == "monster_demon1") + return DemonCheckAttack (); + if (self.classname == "monster_dog") + return DogCheckAttack (); + if (self.classname == "monster_wizard") + return WizardCheckAttack (); + return CheckAttack (); +}; + + +/* +============= +ai_run_melee + +Turn and close until within an angle to launch a melee attack +============= +*/ +void() ai_run_melee = +{ + self.ideal_yaw = enemy_yaw; + ChangeYaw (); + + if (FacingIdeal()) + { + self.th_melee (); + self.attack_state = AS_STRAIGHT; + } +}; + + +/* +============= +ai_run_missile + +Turn in place until within an angle to launch a missile attack +============= +*/ +void() ai_run_missile = +{ + self.ideal_yaw = enemy_yaw; + ChangeYaw (); + if (FacingIdeal()) + { + self.th_missile (); + self.attack_state = AS_STRAIGHT; + } +}; + + +/* +============= +ai_run_slide + +Strafe sideways, but stay at aproximately the same range +============= +*/ +void() ai_run_slide = +{ + local float ofs; + + self.ideal_yaw = enemy_yaw; + ChangeYaw (); + if (self.lefty) + ofs = 90; + else + ofs = -90; + + if (walkmove (self.ideal_yaw + ofs, movedist)) + return; + + self.lefty = 1 - self.lefty; + + walkmove (self.ideal_yaw - ofs, movedist); +}; + + +/* +============= +ai_run + +The monster has an enemy it is trying to kill +============= +*/ +void(float dist) ai_run = +{ + + movedist = dist; +// see if the enemy is dead + if (self.enemy.health <= 0) + { + self.enemy = world; + // FIXME: look all around for other targets + if (self.oldenemy.health > 0) + { + self.enemy = self.oldenemy; + HuntTarget (); + } + else + { + if (self.movetarget) + self.th_walk (); + else + self.th_stand (); + return; + } + } + + self.show_hostile = time + 1; // wake up other monsters + +// check knowledge of enemy + enemy_vis = visible(self.enemy); + if (enemy_vis) + self.search_time = time + 5; + +// look for other coop players + if (coop && self.search_time < time) + { + if (FindTarget ()) + return; + } + + enemy_infront = infront(self.enemy); + enemy_range = range(self.enemy); + enemy_yaw = vectoyaw(self.enemy.origin - self.origin); + + if (self.attack_state == AS_MISSILE) + { +//dprint ("ai_run_missile\n"); + ai_run_missile (); + return; + } + if (self.attack_state == AS_MELEE) + { +//dprint ("ai_run_melee\n"); + ai_run_melee (); + return; + } + + if (CheckAnyAttack ()) + return; // beginning an attack + + if (self.attack_state == AS_SLIDING) + { + ai_run_slide (); + return; + } + +// head straight in + movetogoal (dist); // done in C code... +}; + \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/amtest.qc b/r17/Revamped src/Revamped QC/Primeqc4/amtest.qc new file mode 100755 index 00000000..97f95928 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/amtest.qc @@ -0,0 +1,85 @@ +/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~> +~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/ + +void() test_teleport_touch; +void() tele_done; + +/*QUAKED test_teleport (0 .5 .8) ? +Teleporter testing +*/ +void() test_teleport = +{ + precache_model ("sprites/s_aball.spr"); + setsize (self, self.mins, self.maxs); + self.touch = test_teleport_touch; + self.solid = 1; + + if (!self.target) + objerror ("no target\n"); +}; + +void() test_teleport_touch = +{ +local entity oldself; + other.movetype = MOVETYPE_TOSS; +// other.solid = SOLID_NOT; + other.dest = '256 -128 -128'; + oldself = self; + self = other; +// SUB_CalcMove (self.dest, 200, tele_done); + self.velocity = '1000 0 0 '; + self = oldself; +}; + +void() tele_done = +{ + self.movetype = MOVETYPE_WALK; + self.solid = SOLID_SLIDEBOX; +}; + +/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~> +~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/ + +void() test_goaway; +void() test_spawn; + +/*QUAKED test_fodder (0 .5 .8) ? +beating guy +*/ +void() test_fodder = +{ + self.nextthink = time + 3; + self.think = test_spawn; +}; + +void() test_spawn = +{ +local entity body; + makevectors (self.angles); + + body = spawn(); + setmodel (body, "progs/soldier.mdl"); + setorigin (body, self.origin); + body.classname = "player"; + body.health = 1000; + body.frags = 0; + body.takedamage = DAMAGE_AIM; + body.solid = SOLID_SLIDEBOX; + body.movetype = MOVETYPE_WALK; + body.show_hostile = 0; + body.weapon = 1; + body.velocity = v_forward * 200; + + body.nextthink = time + 5; + body.think = test_goaway; + +self.nextthink = time + 3; +self.think = test_spawn; + +}; + +void() test_goaway = +{ + remove (self); +}; + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/boss.qc b/r17/Revamped src/Revamped QC/Primeqc4/boss.qc new file mode 100755 index 00000000..949de52d --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/boss.qc @@ -0,0 +1,385 @@ +/* +============================================================================== + +BOSS-ONE + +============================================================================== +*/ +$cd id1/models/boss1 +$origin 0 0 -15 +$base base +$skin skin +$scale 5 + +$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9 rise10 +$frame rise11 rise12 rise13 rise14 rise15 rise16 rise17 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 +$frame walk9 walk10 walk11 walk12 walk13 walk14 walk15 +$frame walk16 walk17 walk18 walk19 walk20 walk21 walk22 +$frame walk23 walk24 walk25 walk26 walk27 walk28 walk29 walk30 walk31 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 + +$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 +$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15 +$frame attack16 attack17 attack18 attack19 attack20 attack21 attack22 +$frame attack23 + +$frame shocka1 shocka2 shocka3 shocka4 shocka5 shocka6 shocka7 shocka8 +$frame shocka9 shocka10 + +$frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6 + +$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8 +$frame shockc9 shockc10 + + +void(vector p) boss_missile; + +void() boss_face = +{ + +// go for another player if multi player + if (self.enemy.health <= 0 || random() < 0.02) + { + self.enemy = find(self.enemy, classname, "player"); + if (!self.enemy) + self.enemy = find(self.enemy, classname, "player"); + } + ai_face(); +}; + +void() boss_rise1 =[ $rise1, boss_rise2 ] { +sound (self, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM); +}; +void() boss_rise2 =[ $rise2, boss_rise3 ] { +sound (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM); +}; +void() boss_rise3 =[ $rise3, boss_rise4 ] {}; +void() boss_rise4 =[ $rise4, boss_rise5 ] {}; +void() boss_rise5 =[ $rise5, boss_rise6 ] {}; +void() boss_rise6 =[ $rise6, boss_rise7 ] {}; +void() boss_rise7 =[ $rise7, boss_rise8 ] {}; +void() boss_rise8 =[ $rise8, boss_rise9 ] {}; +void() boss_rise9 =[ $rise9, boss_rise10 ] {}; +void() boss_rise10 =[ $rise10, boss_rise11 ] {}; +void() boss_rise11 =[ $rise11, boss_rise12 ] {}; +void() boss_rise12 =[ $rise12, boss_rise13 ] {}; +void() boss_rise13 =[ $rise13, boss_rise14 ] {}; +void() boss_rise14 =[ $rise14, boss_rise15 ] {}; +void() boss_rise15 =[ $rise15, boss_rise16 ] {}; +void() boss_rise16 =[ $rise16, boss_rise17 ] {}; +void() boss_rise17 =[ $rise17, boss_missile1 ] {}; + +void() boss_idle1 =[ $walk1, boss_idle2 ] +{ +// look for other players +}; +void() boss_idle2 =[ $walk2, boss_idle3 ] {boss_face();}; +void() boss_idle3 =[ $walk3, boss_idle4 ] {boss_face();}; +void() boss_idle4 =[ $walk4, boss_idle5 ] {boss_face();}; +void() boss_idle5 =[ $walk5, boss_idle6 ] {boss_face();}; +void() boss_idle6 =[ $walk6, boss_idle7 ] {boss_face();}; +void() boss_idle7 =[ $walk7, boss_idle8 ] {boss_face();}; +void() boss_idle8 =[ $walk8, boss_idle9 ] {boss_face();}; +void() boss_idle9 =[ $walk9, boss_idle10 ] {boss_face();}; +void() boss_idle10 =[ $walk10, boss_idle11 ] {boss_face();}; +void() boss_idle11 =[ $walk11, boss_idle12 ] {boss_face();}; +void() boss_idle12 =[ $walk12, boss_idle13 ] {boss_face();}; +void() boss_idle13 =[ $walk13, boss_idle14 ] {boss_face();}; +void() boss_idle14 =[ $walk14, boss_idle15 ] {boss_face();}; +void() boss_idle15 =[ $walk15, boss_idle16 ] {boss_face();}; +void() boss_idle16 =[ $walk16, boss_idle17 ] {boss_face();}; +void() boss_idle17 =[ $walk17, boss_idle18 ] {boss_face();}; +void() boss_idle18 =[ $walk18, boss_idle19 ] {boss_face();}; +void() boss_idle19 =[ $walk19, boss_idle20 ] {boss_face();}; +void() boss_idle20 =[ $walk20, boss_idle21 ] {boss_face();}; +void() boss_idle21 =[ $walk21, boss_idle22 ] {boss_face();}; +void() boss_idle22 =[ $walk22, boss_idle23 ] {boss_face();}; +void() boss_idle23 =[ $walk23, boss_idle24 ] {boss_face();}; +void() boss_idle24 =[ $walk24, boss_idle25 ] {boss_face();}; +void() boss_idle25 =[ $walk25, boss_idle26 ] {boss_face();}; +void() boss_idle26 =[ $walk26, boss_idle27 ] {boss_face();}; +void() boss_idle27 =[ $walk27, boss_idle28 ] {boss_face();}; +void() boss_idle28 =[ $walk28, boss_idle29 ] {boss_face();}; +void() boss_idle29 =[ $walk29, boss_idle30 ] {boss_face();}; +void() boss_idle30 =[ $walk30, boss_idle31 ] {boss_face();}; +void() boss_idle31 =[ $walk31, boss_idle1 ] {boss_face();}; + +void() boss_missile1 =[ $attack1, boss_missile2 ] {boss_face();}; +void() boss_missile2 =[ $attack2, boss_missile3 ] {boss_face();}; +void() boss_missile3 =[ $attack3, boss_missile4 ] {boss_face();}; +void() boss_missile4 =[ $attack4, boss_missile5 ] {boss_face();}; +void() boss_missile5 =[ $attack5, boss_missile6 ] {boss_face();}; +void() boss_missile6 =[ $attack6, boss_missile7 ] {boss_face();}; +void() boss_missile7 =[ $attack7, boss_missile8 ] {boss_face();}; +void() boss_missile8 =[ $attack8, boss_missile9 ] {boss_face();}; +void() boss_missile9 =[ $attack9, boss_missile10 ] {boss_missile('100 100 200');}; +void() boss_missile10 =[ $attack10, boss_missile11 ] {boss_face();}; +void() boss_missile11 =[ $attack11, boss_missile12 ] {boss_face();}; +void() boss_missile12 =[ $attack12, boss_missile13 ] {boss_face();}; +void() boss_missile13 =[ $attack13, boss_missile14 ] {boss_face();}; +void() boss_missile14 =[ $attack14, boss_missile15 ] {boss_face();}; +void() boss_missile15 =[ $attack15, boss_missile16 ] {boss_face();}; +void() boss_missile16 =[ $attack16, boss_missile17 ] {boss_face();}; +void() boss_missile17 =[ $attack17, boss_missile18 ] {boss_face();}; +void() boss_missile18 =[ $attack18, boss_missile19 ] {boss_face();}; +void() boss_missile19 =[ $attack19, boss_missile20 ] {boss_face();}; +void() boss_missile20 =[ $attack20, boss_missile21 ] {boss_missile('100 -100 200');}; +void() boss_missile21 =[ $attack21, boss_missile22 ] {boss_face();}; +void() boss_missile22 =[ $attack22, boss_missile23 ] {boss_face();}; +void() boss_missile23 =[ $attack23, boss_missile1 ] {boss_face();}; + +void() boss_shocka1 =[ $shocka1, boss_shocka2 ] {}; +void() boss_shocka2 =[ $shocka2, boss_shocka3 ] {}; +void() boss_shocka3 =[ $shocka3, boss_shocka4 ] {}; +void() boss_shocka4 =[ $shocka4, boss_shocka5 ] {}; +void() boss_shocka5 =[ $shocka5, boss_shocka6 ] {}; +void() boss_shocka6 =[ $shocka6, boss_shocka7 ] {}; +void() boss_shocka7 =[ $shocka7, boss_shocka8 ] {}; +void() boss_shocka8 =[ $shocka8, boss_shocka9 ] {}; +void() boss_shocka9 =[ $shocka9, boss_shocka10 ] {}; +void() boss_shocka10 =[ $shocka10, boss_missile1 ] {}; + +void() boss_shockb1 =[ $shockb1, boss_shockb2 ] {}; +void() boss_shockb2 =[ $shockb2, boss_shockb3 ] {}; +void() boss_shockb3 =[ $shockb3, boss_shockb4 ] {}; +void() boss_shockb4 =[ $shockb4, boss_shockb5 ] {}; +void() boss_shockb5 =[ $shockb5, boss_shockb6 ] {}; +void() boss_shockb6 =[ $shockb6, boss_shockb7 ] {}; +void() boss_shockb7 =[ $shockb1, boss_shockb8 ] {}; +void() boss_shockb8 =[ $shockb2, boss_shockb9 ] {}; +void() boss_shockb9 =[ $shockb3, boss_shockb10 ] {}; +void() boss_shockb10 =[ $shockb4, boss_missile1 ] {}; + +void() boss_shockc1 =[ $shockc1, boss_shockc2 ] {}; +void() boss_shockc2 =[ $shockc2, boss_shockc3 ] {}; +void() boss_shockc3 =[ $shockc3, boss_shockc4 ] {}; +void() boss_shockc4 =[ $shockc4, boss_shockc5 ] {}; +void() boss_shockc5 =[ $shockc5, boss_shockc6 ] {}; +void() boss_shockc6 =[ $shockc6, boss_shockc7 ] {}; +void() boss_shockc7 =[ $shockc7, boss_shockc8 ] {}; +void() boss_shockc8 =[ $shockc8, boss_shockc9 ] {}; +void() boss_shockc9 =[ $shockc9, boss_shockc10 ] {}; +void() boss_shockc10 =[ $shockc10, boss_death1 ] {}; + +void() boss_death1 = [$death1, boss_death2] { +sound (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM); +}; +void() boss_death2 = [$death2, boss_death3] {}; +void() boss_death3 = [$death3, boss_death4] {}; +void() boss_death4 = [$death4, boss_death5] {}; +void() boss_death5 = [$death5, boss_death6] {}; +void() boss_death6 = [$death6, boss_death7] {}; +void() boss_death7 = [$death7, boss_death8] {}; +void() boss_death8 = [$death8, boss_death9] {}; +void() boss_death9 = [$death9, boss_death10] +{ + sound (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM); + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_LAVASPLASH); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); +}; + +void() boss_death10 = [$death9, boss_death10] +{ + killed_monsters = killed_monsters + 1; + WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast + SUB_UseTargets (); + remove (self); +}; + +void(vector p) boss_missile = +{ + local vector offang; + local vector org, vec, d; + local float t; + + offang = vectoangles (self.enemy.origin - self.origin); + makevectors (offang); + + org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1'; + +// lead the player on hard mode + if (skill > 1) + { + t = vlen(self.enemy.origin - org) / 300; + vec = self.enemy.velocity; + vec_z = 0; + d = self.enemy.origin + t * vec; + } + else + { + d = self.enemy.origin; + } + + vec = normalize (d - org); + + launch_spike (org, vec); + setmodel (newmis, "progs/lavaball.mdl"); + newmis.avelocity = '200 100 300'; + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + newmis.velocity = vec*300; + newmis.touch = T_MissileTouch; // rocket explosion + sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM); + +// check for dead enemy + if (self.enemy.health <= 0) + boss_idle1 (); +}; + + +void() boss_awake = +{ + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + self.takedamage = DAMAGE_NO; + + setmodel (self, "progs/boss.mdl"); + setsize (self, '-128 -128 -24', '128 128 256'); + + if (skill == 0) + self.health = 1; + else + self.health = 3; + + self.enemy = activator; + + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_LAVASPLASH); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); + + self.yaw_speed = 20; + boss_rise1 (); +}; + + +/*QUAKED monster_boss (1 0 0) (-128 -128 -24) (128 128 256) +*/ +void() monster_boss = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/boss.mdl"); + precache_model ("progs/lavaball.mdl"); + + precache_sound ("weapons/rocket1i.wav"); + precache_sound ("boss1/out1.wav"); + precache_sound ("boss1/sight1.wav"); + precache_sound ("misc/power.wav"); + precache_sound ("boss1/throw.wav"); + precache_sound ("boss1/pain.wav"); + precache_sound ("boss1/death.wav"); + + total_monsters = total_monsters + 1; + + self.use = boss_awake; +}; + +//=========================================================================== + +entity le1, le2; +float lightning_end; + +void() lightning_fire = +{ + local vector p1, p2; + + if (time >= lightning_end) + { // done here, put the terminals back up + self = le1; + door_go_down (); + self = le2; + door_go_down (); + return; + } + + p1 = (le1.mins + le1.maxs) * 0.5; + p1_z = le1.absmin_z - 16; + + p2 = (le2.mins + le2.maxs) * 0.5; + p2_z = le2.absmin_z - 16; + + // compensate for length of bolt + p2 = p2 - normalize(p2-p1)*100; + + self.nextthink = time + 0.1; + self.think = lightning_fire; + + WriteByte (MSG_ALL, SVC_TEMPENTITY); + WriteByte (MSG_ALL, TE_LIGHTNING3); + WriteEntity (MSG_ALL, world); + WriteCoord (MSG_ALL, p1_x); + WriteCoord (MSG_ALL, p1_y); + WriteCoord (MSG_ALL, p1_z); + WriteCoord (MSG_ALL, p2_x); + WriteCoord (MSG_ALL, p2_y); + WriteCoord (MSG_ALL, p2_z); +}; + +void() lightning_use = +{ + if (lightning_end >= time + 1) + return; + + le1 = find( world, target, "lightning"); + le2 = find( le1, target, "lightning"); + if (!le1 || !le2) + { + dprint ("missing lightning targets\n"); + return; + } + + if ( + (le1.state != STATE_TOP && le1.state != STATE_BOTTOM) + || (le2.state != STATE_TOP && le2.state != STATE_BOTTOM) + || (le1.state != le2.state) ) + { +// dprint ("not aligned\n"); + return; + } + +// don't let the electrodes go back up until the bolt is done + le1.nextthink = -1; + le2.nextthink = -1; + lightning_end = time + 1; + + sound (self, CHAN_VOICE, "misc/power.wav", 1, ATTN_NORM); + lightning_fire (); + +// advance the boss pain if down + self = find (world, classname, "monster_boss"); + if (!self) + return; + self.enemy = activator; + if (le1.state == STATE_TOP && self.health > 0) + { + sound (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM); + self.health = self.health - 1; + if (self.health >= 2) + boss_shocka1(); + else if (self.health == 1) + boss_shockb1(); + else if (self.health == 0) + boss_shockc1(); + } +}; + + +/*QUAKED event_lightning (0 1 1) (-16 -16 -16) (16 16 16) +Just for boss level. +*/ +void() event_lightning = +{ + self.use = lightning_use; +}; + + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/buttons.qc b/r17/Revamped src/Revamped QC/Primeqc4/buttons.qc new file mode 100755 index 00000000..695115b0 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/buttons.qc @@ -0,0 +1,139 @@ +// button and multiple button + +void() button_wait; +void() button_return; + +void() button_wait = +{ + self.state = STATE_TOP; + self.nextthink = self.ltime + self.wait; + self.think = button_return; + activator = self.enemy; + SUB_UseTargets(); + self.frame = 1; // use alternate textures +}; + +void() button_done = +{ + self.state = STATE_BOTTOM; +}; + +void() button_return = +{ + self.state = STATE_DOWN; + SUB_CalcMove (self.pos1, self.speed, button_done); + self.frame = 0; // use normal textures + if (self.health) + self.takedamage = DAMAGE_YES; // can be shot again +}; + + +void() button_blocked = +{ // do nothing, just don't ome all the way back out +}; + + +void() button_fire = +{ + if (self.state == STATE_UP || self.state == STATE_TOP) + return; + + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + + self.state = STATE_UP; + SUB_CalcMove (self.pos2, self.speed, button_wait); +}; + + +void() button_use = +{ + self.enemy = activator; + button_fire (); +}; + +void() button_touch = +{ + if (other.classname != "player") + return; + self.enemy = other; + button_fire (); +}; + +void() button_killed = +{ + self.enemy = damage_attacker; + self.health = self.max_health; + self.takedamage = DAMAGE_NO; // wil be reset upon return + button_fire (); +}; + + +/*QUAKED func_button (0 .5 .8) ? +When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again. + +"angle" determines the opening direction +"target" all entities with a matching targetname will be used +"speed" override the default 40 speed +"wait" override the default 1 second wait (-1 = never return) +"lip" override the default 4 pixel lip remaining at end of move +"health" if set, the button must be killed instead of touched +"sounds" +0) steam metal +1) wooden clunk +2) metallic click +3) in-out +*/ +void() func_button = +{ + if (self.sounds == 0) + { + precache_sound ("buttons/airbut1.wav"); + self.noise = "buttons/airbut1.wav"; + } + if (self.sounds == 1) + { + precache_sound ("buttons/switch21.wav"); + self.noise = "buttons/switch21.wav"; + } + if (self.sounds == 2) + { + precache_sound ("buttons/switch02.wav"); + self.noise = "buttons/switch02.wav"; + } + if (self.sounds == 3) + { + precache_sound ("buttons/switch04.wav"); + self.noise = "buttons/switch04.wav"; + } + + SetMovedir (); + + self.movetype = MOVETYPE_PUSH; + self.solid = SOLID_BSP; + setmodel (self, self.model); + + self.blocked = button_blocked; + self.use = button_use; + + if (self.health) + { + self.max_health = self.health; + self.th_die = button_killed; + self.takedamage = DAMAGE_YES; + } + else + self.touch = button_touch; + + if (!self.speed) + self.speed = 40; + if (!self.wait) + self.wait = 1; + if (!self.lip) + self.lip = 4; + + self.state = STATE_BOTTOM; + + self.pos1 = self.origin; + self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip); +}; + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/ccam.qc b/r17/Revamped src/Revamped QC/Primeqc4/ccam.qc new file mode 100755 index 00000000..b85cfde0 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/ccam.qc @@ -0,0 +1,83 @@ +void () CCam; + + void () CCamChasePlayer = + { + makevectors (self.v_angle); + traceline ((self.origin + self.view_ofs),((((self.origin + self.view_ofs) + + (v_forward * self.camview_z)) + (v_up * self.camview_x)) + (v_right * self.camview_y)),FALSE,self); + setorigin (self.trigger_field,trace_endpos); + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE,self.trigger_field); + self.weaponmodel = ""; + }; + + void () CCam = + { + local entity camera; + local entity spot; + + if (self.health <= BROKENITEMS) + return; + if (self.aflag == FALSE) + { + self.cam = 1; + self.aflag = TRUE; + camera = spawn (); + spot = spawn (); + self.trigger_field = camera; + camera.classname = "camera"; + camera.movetype = MOVETYPE_FLY; + camera.solid = SOLID_NOT; + setmodel (camera,"progs/eyes.mdl"); + setsize (camera,'0 0 0','0 0 0'); + makevectors (self.v_angle); + traceline ((self.origin + self.view_ofs),(((self.origin + self.view_ofs) + + (v_forward * -64.000))),FALSE,self); + self.camview = '0 0 -64'; // added + setorigin (camera,trace_endpos); + camera.angles = self.angles; + self.weaponmodel = ""; + msg_entity = self; + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE,camera); + WriteByte (MSG_ONE,10.000); + WriteAngle (MSG_ONE,camera.angles_x); + WriteAngle (MSG_ONE,camera.angles_y); + WriteAngle (MSG_ONE,camera.angles_z); + self.avelocity = '300 300 300'; + self.currentammo = self.mbombs; + self.boostlives = 1; + self.mbombs = 3; + self.mball = 1; + self.view_ofs = '0 0 8'; + setsize (self, '-12 -12 -40', '12 12 7'); + } + else + { + //if (self.laid == LAYED) + //return; + self.cam = 0; + self.aflag = FALSE; + msg_entity = self; + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE,self); + WriteByte (MSG_ONE,10); + WriteAngle (MSG_ONE,self.angles_x); + WriteAngle (MSG_ONE,self.angles_y); + WriteAngle (MSG_ONE,self.angles_z); + remove (self.trigger_field); + if (self.health <= BROKENITEMS) //For the Suit charging.(25 health) + {} + else + { + //self.weapon = IT_BLASTER; + W_SetCurrentAmmo (); + self.origin = self.origin + v_up * 30; //Solves the Spawning in the Ground Problem + } + self.mball = 0; + self.view_ofs = '0 0 22'; + setsize (self, '-16 -16 -24', '16 16 32'); + self.weapon = IT_BLASTER; + W_SetCurrentAmmo (); + } + } \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/client.qc b/r17/Revamped src/Revamped QC/Primeqc4/client.qc new file mode 100755 index 00000000..7cb4a637 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/client.qc @@ -0,0 +1,1510 @@ + +// prototypes +void () W_WeaponFrame; +void() W_SetCurrentAmmo; +void() player_pain; +void() player_stand1; +void (vector org) spawn_tfog; +void (vector org, entity death_owner) spawn_tdeath; + +float modelindex_eyes, modelindex_mball, modelindex_player; + +/* +============================================================================= + + LEVEL CHANGING / INTERMISSION + +============================================================================= +*/ + +float intermission_running; +float intermission_exittime; + +/*QUAKED info_intermission (1 0.5 0.5) (-16 -16 -16) (16 16 16) +This is the camera point for the intermission. +Use mangle instead of angle, so you can set pitch or roll as well as yaw. 'pitch roll yaw' +*/ +void() info_intermission = +{ +}; + + + +void() SetChangeParms = +{ + if (self.health <= 0) + { + SetNewParms (); + return; + } + +// remove items + self.items = self.items - (self.items & + (IT_KEY1 | IT_KEY2 | IT_INVISIBILITY | IT_INVULNERABILITY | IT_SUIT | IT_QUAD) ); + +// cap super health + if (self.health > 100) + self.health = 100; + if (self.health < 50) + self.health = 50; + parm1 = self.items; + parm2 = self.health; + parm3 = self.armorvalue; + if (self.ammo_shells < 25) + parm4 = 25; + else + parm4 = self.ammo_blaster; + parm5 = self.ammo_sniper; + parm6 = self.ammo_rockets; + parm7 = self.ammo_nails; + parm8 = self.weapon; + parm9 = self.armortype * 100; + parm10 = self.energy; +}; + +void() SetNewParms = +{ + parm1 = IT_BLASTER | IT_MORPHBALL; + parm2 = 99; + parm3 = 0; + parm4 = 100; + parm5 = 1; + parm6 = 0; + parm7 = 0; + parm8 = 1; + parm9 = 0; + if (deathmatch) + parm10 = 1; + else + parm10 = 0; +}; + +void() DecodeLevelParms = +{ + if (serverflags) + { + if (world.model == "maps/start.bsp") + SetNewParms (); // take away all stuff on starting new episode + } + + self.items = parm1; + self.health = parm2; + self.armorvalue = parm3; + self.ammo_blaster = parm4; + self.ammo_sniper = parm5; + self.ammo_rockets = parm6; + self.ammo_nails = parm7; + self.weapon = parm8; + self.armortype = parm9 * 0.01; + self.energy = parm10; +}; + +/* +============ +FindIntermission + +Returns the entity to view from +============ +*/ +entity() FindIntermission = +{ + local entity spot; + local float cyc; + +// look for info_intermission first + spot = find (world, classname, "info_intermission"); + if (spot) + { // pick a random one + cyc = random() * 4; + while (cyc > 1) + { + spot = find (spot, classname, "info_intermission"); + if (!spot) + spot = find (spot, classname, "info_intermission"); + cyc = cyc - 1; + } + return spot; + } + +// then look for the start position + spot = find (world, classname, "info_player_start"); + if (spot) + return spot; + +// testinfo_player_start is only found in regioned levels + spot = find (world, classname, "testplayerstart"); + if (spot) + return spot; + + objerror ("FindIntermission: no spot"); +}; + + +string nextmap; +void() GotoNextMap = +{ + if (cvar("samelevel")) // if samelevel is set, stay on same level + changelevel (mapname); + else + changelevel (nextmap); +}; + + +void() ExitIntermission = +{ +// skip any text in deathmatch + if (deathmatch) + { + GotoNextMap (); + return; + } + + intermission_exittime = time + 1; + intermission_running = intermission_running + 1; + +// +// run some text if at the end of an episode +// + if (intermission_running == 2) + { + if (world.model == "maps/e1m7.bsp") + { + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 2); + WriteByte (MSG_ALL, 3); + if (!cvar("registered")) + { + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task in the other three\nhaunted lands of Quake. Or are you? If\nyou don't register Quake, you'll never\nknow what awaits you in the Realm of\nBlack Magic, the Netherworld, and the\nElder World!"); + } + else + { + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task. A Rune of magic\npower lies at the end of each haunted\nland of Quake. Go forth, seek the\ntotality of the four Runes!"); + } + return; + } + else if (world.model == "maps/e2m6.bsp") + { + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 2); + WriteByte (MSG_ALL, 3); + + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "The Rune of Black Magic throbs evilly in\nyour hand and whispers dark thoughts\ninto your brain. You learn the inmost\nlore of the Hell-Mother; Shub-Niggurath!\nYou now know that she is behind all the\nterrible plotting which has led to so\nmuch death and horror. But she is not\ninviolate! Armed with this Rune, you\nrealize that once all four Runes are\ncombined, the gate to Shub-Niggurath's\nPit will open, and you can face the\nWitch-Goddess herself in her frightful\notherworld cathedral."); + return; + } + else if (world.model == "maps/e3m6.bsp") + { + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 2); + WriteByte (MSG_ALL, 3); + + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "The charred viscera of diabolic horrors\nbubble viscously as you seize the Rune\nof Hell Magic. Its heat scorches your\nhand, and its terrible secrets blight\nyour mind. Gathering the shreds of your\ncourage, you shake the devil's shackles\nfrom your soul, and become ever more\nhard and determined to destroy the\nhideous creatures whose mere existence\nthreatens the souls and psyches of all\nthe population of Earth."); + return; + } + else if (world.model == "maps/e4m7.bsp") + { + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 2); + WriteByte (MSG_ALL, 3); + + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "Despite the awful might of the Elder\nWorld, you have achieved the Rune of\nElder Magic, capstone of all types of\narcane wisdom. Beyond good and evil,\nbeyond life and death, the Rune\npulsates, heavy with import. Patient and\npotent, the Elder Being Shub-Niggurath\nweaves her dire plans to clear off all\nlife from the Earth, and bring her own\nfoul offspring to our world! For all the\ndwellers in these nightmare dimensions\nare her descendants! Once all Runes of\nmagic power are united, the energy\nbehind them will blast open the Gateway\nto Shub-Niggurath, and you can travel\nthere to foil the Hell-Mother's plots\nin person."); + return; + } + + GotoNextMap(); + } + + if (intermission_running == 3) + { + if (!cvar("registered")) + { // shareware episode has been completed, go to sell screen + WriteByte (MSG_ALL, SVC_SELLSCREEN); + return; + } + + if ( (serverflags&15) == 15) + { + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "Now, you have all four Runes. You sense\ntremendous invisible forces moving to\nunseal ancient barriers. Shub-Niggurath\nhad hoped to use the Runes Herself to\nclear off the Earth, but now instead,\nyou will use them to enter her home and\nconfront her as an avatar of avenging\nEarth-life. If you defeat her, you will\nbe remembered forever as the savior of\nthe planet. If she conquers, it will be\nas if you had never been born."); + return; + } + + } + + GotoNextMap(); +}; + +/* +============ +IntermissionThink + +When the player presses attack or jump, change to the next level +============ +*/ +void() IntermissionThink = +{ + if (time < intermission_exittime) + return; + + if (!self.button0 && !self.button1 && !self.button2) + return; + + ExitIntermission (); +}; + +void() execute_changelevel = +{ + local entity pos; + + intermission_running = 1; + +// enforce a wait time before allowing changelevel + if (deathmatch) + intermission_exittime = time + 5; + else + intermission_exittime = time + 2; + + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 3); + WriteByte (MSG_ALL, 3); + + pos = FindIntermission (); + + other = find (world, classname, "player"); + while (other != world) + { + other.view_ofs = '0 0 0'; + other.angles = other.v_angle = pos.mangle; + other.fixangle = TRUE; // turn this way immediately + other.nextthink = time + 0.5; + other.takedamage = DAMAGE_NO; + other.solid = SOLID_NOT; + other.movetype = MOVETYPE_NONE; + other.modelindex = 0; + setorigin (other, pos.origin); + other = find (other, classname, "player"); + } + + WriteByte (MSG_ALL, SVC_INTERMISSION); +}; + + +void() changelevel_touch = +{ + + if (other.classname != "player") + return; + + if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start"))) + { + T_Damage (other, self, self, 50000); + return; + } + + if (coop || deathmatch) + { + bprint (other.netname); + bprint (" exited the level\n"); + } + + nextmap = self.map; + + SUB_UseTargets (); + + if ( (self.spawnflags & 1) && (deathmatch == 0) ) + { // NO_INTERMISSION + GotoNextMap(); + return; + } + + self.touch = SUB_Null; + +// we can't move people right now, because touch functions are called +// in the middle of C movement code, so set a think time to do it + self.think = execute_changelevel; + self.nextthink = time + 0.1; +}; + +/*QUAKED trigger_changelevel (0.5 0.5 0.5) ? NO_INTERMISSION +When the player touches this, he gets sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats. +*/ +void() trigger_changelevel = +{ + if (!self.map) + objerror ("chagnelevel trigger doesn't have map"); + + InitTrigger (); + self.touch = changelevel_touch; +}; + + +/* +============================================================================= + + PLAYER GAME EDGE FUNCTIONS + +============================================================================= +*/ + +void() set_suicide_frame; + +// called by ClientKill and DeadThink +void() respawn = +{ + if (coop) + { + // get the spawn parms as they were at level start + setspawnparms (self); + // respawn + PutClientInServer (); + } + else if (deathmatch) + { + // set default spawn parms + SetNewParms (); + // respawn + PutClientInServer (); + } + else + { // restart the entire server + localcmd ("restart\n"); + } +}; + + +/* +============ +ClientKill + +Player entered the suicide command +============ +*/ +void() ClientKill = +{ + bprint (self.netname); + bprint (" suicides\n"); + set_suicide_frame (); + self.modelindex = modelindex_player; + self.frags = self.frags - 2; // extra penalty + respawn (); +}; + +float(vector v) CheckSpawnPoint = +{ + return FALSE; +}; + +/* +============ +SelectSpawnPoint + +Returns the entity to spawn at +============ +*/ +entity() SelectSpawnPoint = +{ + local entity spot; + local entity thing; + local float pcount; + +// testinfo_player_start is only found in regioned levels + spot = find (world, classname, "testplayerstart"); + if (spot) + return spot; + +// choose a info_player_deathmatch point + if (coop) + { + lastspawn = find(lastspawn, classname, "info_player_coop"); + if (lastspawn == world) + lastspawn = find (lastspawn, classname, "info_player_start"); + if (lastspawn != world) + return lastspawn; + } + else if (deathmatch) + { + spot = lastspawn; + while (1) + { + spot = find(spot, classname, "info_player_deathmatch"); + if (spot != world) + { + if (spot == lastspawn) + return lastspawn; + pcount = 0; + thing = findradius(spot.origin, 32); + while(thing) + { + if (thing.classname == "player") + pcount = pcount + 1; + thing = thing.chain; + } + if (pcount == 0) + { + lastspawn = spot; + return spot; + } + } + } + } + + if (serverflags) + { // return with a rune to start + spot = find (world, classname, "info_player_start2"); + if (spot) + return spot; + } + + spot = find (world, classname, "info_player_start"); + if (!spot) + error ("PutClientInServer: no info_player_start on level"); + + return spot; +}; + +/* +=========== +PutClientInServer + +called each time a player is spawned +============ +*/ +void() DecodeLevelParms; +void() PlayerDie; + + +void() PutClientInServer = +{ + + local entity spot; + + spot = SelectSpawnPoint (); + self.currentammo = self.ammo_rockets = 10; + self.classname = "player"; + self.health = self.max_health; + self.takedamage = DAMAGE_AIM; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_WALK; + self.show_hostile = 0; + if (!deathmatch) + { + if (self.energy == 0) + self.max_health = 99; + if (self.energy == 1) + self.max_health = 199; + if (self.energy == 2) + self.max_health = 299; + if (self.energy == 3) + self.max_health = 399; + if (self.energy == 4) + self.max_health = 499; + if (self.energy == 5) + self.max_health = 599; + if (self.energy == 6) + self.max_health = 699; + if (self.energy == 7) + self.max_health = 799; + if (self.energy == 8) + self.max_health = 899; + if (self.energy == 9) + self.max_health = 999; + } + else + self.max_health = 199; + self.flags = FL_CLIENT; + self.air_finished = time + 12; + self.dmg = 2; // initial water damage + self.super_damage_finished = 0; + self.radsuit_finished = 0; + self.invisible_finished = 0; + self.invincible_finished = 0; + self.effects = 0; + self.invincible_time = 0; + self.doublejump_time = 0; + self.doublejump_lives = 0; + self.mballset = 0; + if (self.weapon == IT_MORPHBALL) + self.weapon = IT_BLASTER; + + DecodeLevelParms (); + + W_SetCurrentAmmo (); + + Set_FOV (FOV_DEFAULT); + self.pfov = FOV_DEFAULT; + + self.attack_finished = time; + self.th_pain = player_pain; + self.th_die = PlayerDie; + + self.deadflag = DEAD_NO; +// paustime is set by teleporters to keep the player from moving a while + self.pausetime = 0; + +// spot = SelectSpawnPoint (); + + self.origin = spot.origin + '0 0 1'; + self.angles = spot.angles; + self.fixangle = TRUE; // turn this way immediately + + stuffcmd (self, "chase_active 0"); + stuffcmd (self, "cl_mball 0"); +// oh, this is a hack! + setmodel (self, "progs/eyes.mdl"); + modelindex_eyes = self.modelindex; + + setmodel (self, "progs/player.mdl"); + modelindex_player = self.modelindex; + + setmodel (self,"progs/mball.mdl"); + modelindex_mball = self.modelindex; + + setsize (self, VEC_HULL_MIN, VEC_HULL_MAX); + + self.view_ofs = '0 0 22'; + + player_stand1 (); + + + if (deathmatch || coop) + { + makevectors(self.angles); + spawn_tfog (self.origin + v_forward*20); + } + //self.doublejump_time = 0; + //self.doublejump_lives = 0; + spawn_tdeath (self.origin, self); +}; + + +/* +============================================================================= + + QUAKED FUNCTIONS + +============================================================================= +*/ + + +/*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 24) +The normal starting point for a level. +*/ +void() info_player_start = +{ +}; + + +/*QUAKED info_player_start2 (1 0 0) (-16 -16 -24) (16 16 24) +Only used on start map for the return point from an episode. +*/ +void() info_player_start2 = +{ +}; + + +/* +saved out by quaked in region mode +*/ +void() testplayerstart = +{ +}; + +/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 24) +potential spawning position for deathmatch games +*/ +void() info_player_deathmatch = +{ +}; + +/*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24) +potential spawning position for coop games +*/ +void() info_player_coop = +{ +}; + +/* +=============================================================================== + +RULES + +=============================================================================== +*/ + +/* +go to the next level for deathmatch +only called if a time or frag limit has expired +*/ +void() NextLevel = +{ + local entity o; + + if (mapname == "start") + { + if (!cvar("registered")) + { + mapname = "e1m1"; + } + else if (!(serverflags & 1)) + { + mapname = "e1m1"; + serverflags = serverflags | 1; + } + else if (!(serverflags & 2)) + { + mapname = "e2m1"; + serverflags = serverflags | 2; + } + else if (!(serverflags & 4)) + { + mapname = "e3m1"; + serverflags = serverflags | 4; + } + else if (!(serverflags & 8)) + { + mapname = "e4m1"; + serverflags = serverflags - 7; + } + + o = spawn(); + o.map = mapname; + } + else + { + // find a trigger changelevel + o = find(world, classname, "trigger_changelevel"); + + // go back to start if no trigger_changelevel + if (!o) + { + mapname = "start"; + o = spawn(); + o.map = mapname; + } + } + + nextmap = o.map; + gameover = TRUE; + + if (o.nextthink < time) + { + o.think = execute_changelevel; + o.nextthink = time + 0.1; + } +}; + +/* +============ +CheckRules + +Exit deathmatch games upon conditions +============ +*/ +void() CheckRules = +{ + local float timelimit; + local float fraglimit; + + if (gameover) // someone else quit the game already + return; + + timelimit = cvar("timelimit") * 60; + fraglimit = cvar("fraglimit"); + + if (timelimit && time >= timelimit) + { + NextLevel (); + return; + } + + if (fraglimit && self.frags >= fraglimit) + { + NextLevel (); + return; + } +}; + +//============================================================================ + +void() PlayerDeathThink = +{ + local float forward; + + if ((self.flags & FL_ONGROUND)) + { + forward = vlen (self.velocity); + forward = forward - 20; + if (forward <= 0) + self.velocity = '0 0 0'; + else + self.velocity = forward * normalize(self.velocity); + } + +// wait for all buttons released + if (self.deadflag == DEAD_DEAD) + { + if (self.button2 || self.button1 || self.button0) + return; + self.deadflag = DEAD_RESPAWNABLE; + return; + } + +// wait for any button down + if (!self.button2 && !self.button1 && !self.button0) + return; + + self.button0 = 0; + self.button1 = 0; + self.button2 = 0; + respawn(); +}; + +// modified PlayerJump: +//Thanks alot for the Double Jump code Sajt! -Mexicouger +void() PlayerJump = +{ + + if (self.flags & FL_WATERJUMP) + return; + + if (self.waterlevel >= 2) + { + if (self.watertype == CONTENT_WATER) + self.velocity_z = 100; + else if (self.watertype == CONTENT_SLIME) + self.velocity_z = 80; + else + self.velocity_z = 50; + +// play swiming sound + if (self.swim_flag < time) + { + self.swim_flag = time + 1; + if (random() < 0.5) + sound (self, CHAN_BODY, "misc/water1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_BODY, "misc/water2.wav", 1, ATTN_NORM); + } + + return; + } + + if ( !(self.flags & FL_JUMPRELEASED) ) + return; // don't pogo stick + + if (self.flags & FL_ONGROUND) + { + if (self.health <= 20) //Your suit is malfunctioned, has to recharge + self.doublejump_lives = 0; + else + self.doublejump_lives = DOUBLEJUMP_EXTRAJUMPS; + self.flags = self.flags - FL_ONGROUND; // don't stairwalk + } + else if (self.doublejump_lives > 0 && time >= self.doublejump_time && self.velocity_z > -100) + { + self.doublejump_lives = self.doublejump_lives - 1; + } + else + { + // can't jump + return; + } + + self.doublejump_time = time + DOUBLEJUMP_TIMER; + + self.flags = self.flags - (self.flags & FL_JUMPRELEASED); + + self.button2 = 0; +// player jumping sound + if (self.weapon == IT_MORPHBALL) + return; + sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM); + self.velocity_z = 350; +}; + +// no changes to PlayerPreThink + + +/* +=========== +WaterMove + +============ +*/ +.float dmgtime; + +void() WaterMove = +{ +//dprint (ftos(self.waterlevel)); + if (self.movetype == MOVETYPE_NOCLIP) + return; + if (self.health < 0) + return; + + if (!self.waterlevel) + { + if (self.flags & FL_INWATER) + { + // play leave water sound + sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM); + self.flags = self.flags - FL_INWATER; + } + return; + } + + if (self.watertype == CONTENT_LAVA) + { // do damage + if (self.dmgtime < time && self.radsuit_finished < time) + { + self.dmgtime = time + 0.25; + T_Damage (self, world, world, 1+self.waterlevel); + } + } + else if (self.watertype == CONTENT_SLIME) + { // do damage + if (self.dmgtime < time && self.radsuit_finished < time) + { + self.dmgtime = time + 1; + T_Damage (self, world, world, 4*self.waterlevel); + } + } + + if ( !(self.flags & FL_INWATER) ) + { + +// player enter water sound + + if (self.watertype == CONTENT_LAVA) + sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM); + if (self.watertype == CONTENT_WATER) + sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM); + if (self.watertype == CONTENT_SLIME) + sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM); + + self.flags = self.flags + FL_INWATER; + self.dmgtime = 0; + } + + if (! (self.flags & FL_WATERJUMP) ) + self.velocity = self.velocity - 0.8*self.waterlevel*frametime*self.velocity; +}; + +void() CheckWaterJump = +{ + local vector start, end; + +// check for a jump-out-of-water + makevectors (self.angles); + start = self.origin; + start_z = start_z + 8; + v_forward_z = 0; + normalize(v_forward); + end = start + v_forward*24; + traceline (start, end, TRUE, self); + if (trace_fraction < 1) + { // solid at waist + start_z = start_z + self.maxs_z - 8; + end = start + v_forward*24; + self.movedir = trace_plane_normal * -50; + traceline (start, end, TRUE, self); + if (trace_fraction == 1) + { // open at eye level + self.flags = self.flags | FL_WATERJUMP; + self.velocity_z = 225; + self.flags = self.flags - (self.flags & FL_JUMPRELEASED); + self.teleport_time = time + 2; // safety net + return; + } + } +}; + +/* +================ +PlayerPreThink + +Called every frame before physics are run +================ +*/ +void() PlayerPreThink = +{ + +if (BotPreFrame()) // FrikBot + return; + + if (intermission_running) + { + IntermissionThink (); // otherwise a button could be missed between + return; // the think tics + } + + if (self.view_ofs == '0 0 0') + return; // intermission or finale + + + makevectors (self.v_angle); // is this still used + + CheckRules (); + WaterMove (); + if (self.boostlives != 1) + { + if (self.boostlives >= 1) + return; + self.boostlives += 0.01; + } + + if (self.waterlevel == 2) + CheckWaterJump (); + + if (self.health < BROKENITEMS) + { + if (self.weapon == IT_MORPHBALL) + { + if (self.button0 == TRUE) + self.button0 = FALSE; + self.mballset = 0; + setorigin (self, self.origin + v_up * 20); + setsize (self, '-16 -16 -24', '16 16 32'); + stuffcmd (self, "chase_active 0"); + self.weapon = IT_BLASTER; + } + } + + + if (self.health < BROKENITEMS) + { + if (self.health > CHARGEHEALTH) //Just in case... + return; + self.health += 0.01; + } + if (self.deadflag >= DEAD_DEAD) + { + PlayerDeathThink (); + return; + } + + if (self.deadflag == DEAD_DYING) + return; // dying, so do nothing + + if (self.button2) + { + PlayerJump (); + } + else + self.flags = self.flags | FL_JUMPRELEASED; + +// teleporters can force a non-moving pause time + if (time < self.pausetime) + self.velocity = '0 0 0'; + + if(time > self.attack_finished && self.currentammo == 0 && self.weapon != IT_MORPHBALL) + { + //self.weapon = W_BestWeapon (); + W_SetCurrentAmmo (); + } +}; + + +/* +================ +CheckPowerups + +Check for turning off powerups +================ +*/ +void() CheckPowerups = +{ + if (self.health <= 0) + return; + +// invisibility + if (self.invisible_finished) + { +// sound and screen flash when items starts to run out + if (self.invisible_sound < time) + { + sound (self, CHAN_AUTO, "items/inv3.wav", 0.5, ATTN_IDLE); + self.invisible_sound = time + ((random() * 3) + 1); + } + + + if (self.invisible_finished < time + 3) + { + if (self.invisible_time == 1) + { + sprint (self, "Ring of Shadows magic is fading\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/inv2.wav", 1, ATTN_NORM); + self.invisible_time = time + 1; + } + + if (self.invisible_time < time) + { + self.invisible_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.invisible_finished < time) + { // just stopped + self.items = self.items - IT_INVISIBILITY; + self.invisible_finished = 0; + self.invisible_time = 0; + } + + // use the eyes + self.frame = 0; + self.modelindex = modelindex_eyes; + } + else + self.modelindex = modelindex_player; // don't use eyes + +// invincibility + if (self.invincible_finished) + { +// sound and screen flash when items starts to run out + if (self.invincible_finished < time + 3) + { + if (self.invincible_time == 1) + { + sprint (self, "Protection is almost burned out\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/protect2.wav", 1, ATTN_NORM); + self.invincible_time = time + 1; + } + + if (self.invincible_time < time) + { + self.invincible_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.invincible_finished < time) + { // just stopped + self.items = self.items - IT_INVULNERABILITY; + self.invincible_time = 0; + self.invincible_finished = 0; + } + if (self.invincible_finished > time) + self.effects = self.effects | EF_DIMLIGHT; + else + self.effects = self.effects - (self.effects & EF_DIMLIGHT); + } + +// super damage + if (self.super_damage_finished) + { + +// sound and screen flash when items starts to run out + + if (self.super_damage_finished < time + 3) + { + if (self.super_time == 1) + { + sprint (self, "Quad Damage is wearing off\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/damage2.wav", 1, ATTN_NORM); + self.super_time = time + 1; + } + + if (self.super_time < time) + { + self.super_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.super_damage_finished < time) + { // just stopped + self.items = self.items - IT_QUAD; + self.super_damage_finished = 0; + self.super_time = 0; + } + if (self.super_damage_finished > time) + self.effects = self.effects | EF_DIMLIGHT; + else + self.effects = self.effects - (self.effects & EF_DIMLIGHT); + } + +// suit + if (self.radsuit_finished) + { + self.air_finished = time + 12; // don't drown + +// sound and screen flash when items starts to run out + if (self.radsuit_finished < time + 3) + { + if (self.rad_time == 1) + { + sprint (self, "Air supply in Biosuit expiring\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/suit2.wav", 1, ATTN_NORM); + self.rad_time = time + 1; + } + + if (self.rad_time < time) + { + self.rad_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.radsuit_finished < time) + { // just stopped + self.items = self.items - IT_SUIT; + self.rad_time = 0; + self.radsuit_finished = 0; + } + } +//Morphball --Ghost +if (self.weapon == IT_MORPHBALL) + { + self.modelindex = modelindex_mball; + } +}; + +/* +================ +PlayerPostThink + +Called every frame after physics are run +================ +*/ +void() PlayerPostThink = +{ +if (BotPostFrame()) // FrikBot + return; + + if (self.view_ofs == '0 0 0') + return; // intermission or finale + if (self.deadflag) + return; + +// do weapon stuff + + W_WeaponFrame (); + +// check to see if player landed and play landing sound + if ((self.jump_flag < -300) && (self.flags & FL_ONGROUND) && (self.health > 0)) + { + if (self.watertype == CONTENT_WATER) + sound (self, CHAN_BODY, "player/h2ojump.wav", 1, ATTN_NORM); + else if (self.jump_flag < -650) + { + T_Damage (self, world, world, 5); + sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM); + self.deathtype = "falling"; + } + else + sound (self, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM); + + self.jump_flag = 0; + } + + if (!(self.flags & FL_ONGROUND)) + self.jump_flag = self.velocity_z; + + CheckPowerups (); +}; + + +/* +=========== +ClientConnect + +called when a player connects to a server +============ +*/ +void() ClientConnect = +{ +ClientInRankings(); // FrikBot + + bprint (self.netname); + bprint (" entered the game\n"); + +// a client connecting during an intermission can cause problems + if (intermission_running) + ExitIntermission (); +}; + + +/* +=========== +ClientDisconnect + +called when a player disconnects from a server +============ +*/ +void() ClientDisconnect = +{ +ClientDisconnected(); // FrikBot + + if (gameover) + return; + // if the level end trigger has been activated, just return + // since they aren't *really* leaving + + // let everyone else know + bprint (self.netname); + bprint (" left the game with "); + bprint (ftos(self.frags)); + bprint (" frags\n"); + sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE); + set_suicide_frame (); +}; + +/* +=========== +ClientObituary + +called when a player dies +============ +*/ +void(entity targ, entity attacker) ClientObituary = +{ + local float rnum; + local string deathstring, deathstring2; + rnum = random(); + + if (targ.classname == "player") + { + if (attacker.classname == "teledeath") + { + bprint (targ.netname); + bprint (" was telefragged by "); + bprint (attacker.owner.netname); + bprint ("\n"); + + attacker.owner.frags = attacker.owner.frags + 1; + return; + } + + if (attacker.classname == "teledeath2") + { + bprint ("Satan's power deflects "); + bprint (targ.netname); + bprint ("'s telefrag\n"); + + targ.frags = targ.frags - 1; + return; + } + + if (attacker.classname == "player") + { + if (targ == attacker) + { + // killed self + attacker.frags = attacker.frags - 1; + bprint (targ.netname); + + if (targ.weapon == 64 && targ.waterlevel > 1) + { + bprint (" discharges into the water.\n"); + return; + } + if (targ.weapon == IT_GRENADE_LAUNCHER) + bprint (" tries to put the pin back in\n"); + else + bprint (" becomes bored with life\n"); + return; + } + else if ( (teamplay == 2) && (targ.team > 0)&&(targ.team == attacker.team) ) + { + if (rnum < 0.25) + deathstring = " mows down a teammate\n"; + else if (rnum < 0.50) + deathstring = " checks his glasses\n"; + else if (rnum < 0.75) + deathstring = " gets a frag for the other team\n"; + else + deathstring = " loses another friend\n"; + bprint (attacker.netname); + bprint (deathstring); + attacker.frags = attacker.frags - 1; + return; + } + else + { + attacker.frags = attacker.frags + 1; + + rnum = attacker.weapon; + if (rnum == IT_MORPHBALL) + { + deathstring = " was ax-murdered by "; + deathstring2 = "\n"; + } + if (rnum == IT_BLASTER) + { + deathstring = " chewed on "; + deathstring2 = "'s boomstick\n"; + } + if (rnum == IT_ROCKET) + { + deathstring = " ate 2 loads of "; + deathstring2 = "'s buckshot\n"; + } + if (rnum == IT_SPLASER) + { + deathstring = " was nailed by "; + deathstring2 = "\n"; + } + if (rnum == IT_SNIPER) + { + deathstring = " was punctured by "; + deathstring2 = "\n"; + } + if (rnum == IT_GRENADE_LAUNCHER) + { + deathstring = " eats "; + deathstring2 = "'s pineapple\n"; + if (targ.health < -40) + { + deathstring = " was gibbed by "; + deathstring2 = "'s grenade\n"; + } + } + if (rnum == IT_MAGMA) + { + deathstring = " rides "; + deathstring2 = "'s rocket\n"; + if (targ.health < -40) + { + deathstring = " was gibbed by "; + deathstring2 = "'s rocket\n" ; + } + } + if (rnum == IT_LIGHTNING) + { + deathstring = " accepts "; + if (attacker.waterlevel > 1) + deathstring2 = "'s discharge\n"; + else + deathstring2 = "'s shaft\n"; + } + bprint (targ.netname); + bprint (deathstring); + bprint (attacker.netname); + bprint (deathstring2); + } + return; + } + else + { + targ.frags = targ.frags - 1; + bprint (targ.netname); + + // killed by a montser? + if (attacker.flags & FL_MONSTER) + { + if (attacker.classname == "monster_army") + bprint (" was shot by a Grunt\n"); + if (attacker.classname == "monster_demon1") + bprint (" was eviscerated by a Fiend\n"); + if (attacker.classname == "monster_dog") + bprint (" was mauled by a Rottweiler\n"); + if (attacker.classname == "monster_dragon") + bprint (" was fried by a Dragon\n"); + if (attacker.classname == "monster_enforcer") + bprint (" was blasted by an Enforcer\n"); + if (attacker.classname == "monster_fish") + bprint (" was fed to the Rotfish\n"); + if (attacker.classname == "monster_hell_knight") + bprint (" was slain by a Death Knight\n"); + if (attacker.classname == "monster_knight") + bprint (" was slashed by a Knight\n"); + if (attacker.classname == "monster_ogre") + bprint (" was destroyed by an Ogre\n"); + if (attacker.classname == "monster_oldone") + bprint (" became one with Shub-Niggurath\n"); + if (attacker.classname == "monster_shalrath") + bprint (" was exploded by a Vore\n"); + if (attacker.classname == "monster_shambler") + bprint (" was smashed by a Shambler\n"); + if (attacker.classname == "monster_tarbaby") + bprint (" was slimed by a Spawn\n"); + if (attacker.classname == "monster_vomit") + bprint (" was vomited on by a Vomitus\n"); + if (attacker.classname == "monster_wizard") + bprint (" was scragged by a Scrag\n"); + if (attacker.classname == "monster_zombie") + bprint (" joins the Zombies\n"); + + return; + } + + // tricks and traps + if (attacker.classname == "explo_box") + { + bprint (" blew up\n"); + return; + } + if (attacker.solid == SOLID_BSP && attacker != world) + { + bprint (" was squished\n"); + return; + } + if (attacker.classname == "trap_shooter" || attacker.classname == "trap_spikeshooter") + { + bprint (" was spiked\n"); + return; + } + if (attacker.classname == "fireball") + { + bprint (" ate a lavaball\n"); + return; + } + if (attacker.classname == "trigger_changelevel") + { + bprint (" tried to leave\n"); + return; + } + + // in-water deaths + rnum = targ.watertype; + if (rnum == -3) + { + if (random() < 0.5) + bprint (" sleeps with the fishes\n"); + else + bprint (" sucks it down\n"); + return; + } + else if (rnum == -4) + { + if (random() < 0.5) + bprint (" gulped a load of slime\n"); + else + bprint (" can't exist on slime alone\n"); + return; + } + else if (rnum == -5) + { + if (targ.health < -15) + { + bprint (" burst into flames\n"); + return; + } + if (random() < 0.5) + bprint (" turned into hot slag\n"); + else + bprint (" visits the Volcano God\n"); + return; + } + + // fell to their death? + if (targ.deathtype == "falling") + { + targ.deathtype = ""; + bprint (" fell to his death\n"); + return; + } + + // hell if I know; he's just dead!!! + bprint (" died\n"); + } + } +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/combat.qc b/r17/Revamped src/Revamped QC/Primeqc4/combat.qc new file mode 100755 index 00000000..24f6e7cb --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/combat.qc @@ -0,0 +1,285 @@ + +void() T_MissileTouch; +void() info_player_start; +void(entity targ, entity attacker) ClientObituary; + +void() monster_death_use; + +//============================================================================ + +/* +============ +CanDamage + +Returns true if the inflictor can directly damage the target. Used for +explosions and melee attacks. +============ +*/ +float(entity targ, entity inflictor) CanDamage = +{ +// bmodels need special checking because their origin is 0,0,0 + if (targ.movetype == MOVETYPE_PUSH) + { + traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self); + if (trace_fraction == 1) + return TRUE; + if (trace_ent == targ) + return TRUE; + return FALSE; + } + + traceline(inflictor.origin, targ.origin, TRUE, self); + if (trace_fraction == 1) + return TRUE; + traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self); + if (trace_fraction == 1) + return TRUE; + traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self); + if (trace_fraction == 1) + return TRUE; + traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self); + if (trace_fraction == 1) + return TRUE; + traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self); + if (trace_fraction == 1) + return TRUE; + + return FALSE; +}; + + +/* +============ +Killed +============ +*/ +void(entity targ, entity attacker) Killed = +{ + local entity oself; + + oself = self; + self = targ; + + if (self.health < -99) + self.health = -99; // don't let sbar look bad if a player + + if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE) + { // doors, triggers, etc + self.th_die (); + self = oself; + return; + } + + self.enemy = attacker; + +// bump the monster counter + if (self.flags & FL_MONSTER) + { + killed_monsters = killed_monsters + 1; + WriteByte (MSG_ALL, SVC_KILLEDMONSTER); + } + + ClientObituary(self, attacker); + + self.takedamage = DAMAGE_NO; + self.touch = SUB_Null; + + monster_death_use(); + self.th_die (); + + self = oself; +}; + + +/* +============ +T_Damage + +The damage is coming from inflictor, but get mad at attacker +This should be the only function that ever reduces health. +============ +*/ +void(entity targ, entity inflictor, entity attacker, float damage) T_Damage= +{ + local vector dir; + local entity oldself; + local float save; + local float take; + + if (!targ.takedamage) + return; + +// used by buttons and triggers to set activator for target firing + damage_attacker = attacker; + +// check for quad damage powerup on the attacker + if (attacker.super_damage_finished > time) + damage = damage * 4; + +// save damage based on the target's armor level + + save = ceil(targ.armortype*damage); + if (save >= targ.armorvalue) + { + save = targ.armorvalue; + targ.armortype = 0; // lost all armor + targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)); + } + + targ.armorvalue = targ.armorvalue - save; + take = ceil(damage-save); + +// add to the damage total for clients, which will be sent as a single +// message at the end of the frame +// FIXME: remove after combining shotgun blasts? + if (targ.flags & FL_CLIENT) + { + targ.dmg_take = targ.dmg_take + take; + targ.dmg_save = targ.dmg_save + save; + targ.dmg_inflictor = inflictor; + } + +// figure momentum add + if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) ) + { + dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5; + dir = normalize(dir); + targ.velocity = targ.velocity + dir*damage*8; + } + +// check for godmode or invincibility + if (targ.flags & FL_GODMODE) + return; + if (targ.invincible_finished >= time) + { + if (self.invincible_sound < time) + { + sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM); + self.invincible_sound = time + 2; + } + return; + } + +// team play damage avoidance + if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) ) + return; + +// do the damage + targ.health = targ.health - take; + + if (targ.health <= 0) + { + Killed (targ, attacker); + return; + } + +// react to the damage + oldself = self; + self = targ; + + if ( (self.flags & FL_MONSTER) && attacker != world) + { + // get mad unless of the same class (except for soldiers) + if (self != attacker && attacker != self.enemy) + { + if ( (self.classname != attacker.classname) + || (self.classname == "monster_army" ) ) + { + if (self.enemy.classname == "player") + self.oldenemy = self.enemy; + self.enemy = attacker; + FoundTarget (); + } + } + } + + if (self.th_pain) + { + self.th_pain (attacker, take); + // nightmare mode monsters don't go into pain frames often + if (skill == 3) + self.pain_finished = time + 5; + } + + self = oldself; +}; + +/* +============ +T_RadiusDamage +============ +*/ +void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage = +{ + local float points; + local entity head; + local vector org; + + head = findradius(inflictor.origin, damage+40); + + while (head) + { + if (head != ignore) + { + if (head.takedamage) + { + org = head.origin + (head.mins + head.maxs)*0.5; + points = 0.5*vlen (inflictor.origin - org); + if (points < 0) + points = 0; + points = damage - points; + if (head == attacker) + points = points * 0.5; + if (points > 0) + { + if (CanDamage (head, inflictor)) + { // shambler takes half damage from all explosions + if (head.classname == "monster_shambler") + T_Damage (head, inflictor, attacker, points*0.5); + else + T_Damage (head, inflictor, attacker, points); + } + } + } + } + head = head.chain; + } +}; + +/* +============ +T_BeamDamage +============ +*/ +void(entity attacker, float damage) T_BeamDamage = +{ + local float points; + local entity head; + + head = findradius(attacker.origin, damage+40); + + while (head) + { + if (head.takedamage) + { + points = 0.5*vlen (attacker.origin - head.origin); + if (points < 0) + points = 0; + points = damage - points; + if (head == attacker) + points = points * 0.5; + if (points > 0) + { + if (CanDamage (head, attacker)) + { + if (head.classname == "monster_shambler") + T_Damage (head, attacker, attacker, points*0.5); + else + T_Damage (head, attacker, attacker, points); + } + } + } + head = head.chain; + } +}; + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/debris.qc b/r17/Revamped src/Revamped QC/Primeqc4/debris.qc new file mode 100755 index 00000000..60c3f4c8 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/debris.qc @@ -0,0 +1,96 @@ + + +/* +================ +Debris By Mexicouger (Bounce code from Needler. Not that advanced yet) +================= +*/ +vector(entity proj) Debrisbounce = // returns the velocity for bouncing off walls +{ + local vector vec; + local float backoff, change; + +// get the trace_plane_normal of the surface we hit + makevectors (proj.angles); + v_forward_z = v_forward_z * -1; + traceline (proj.origin, proj.origin + v_forward*64, FALSE, proj); + + if (trace_fraction == 1) + return proj.velocity; + +// the entity's velocity is not what we want, so set default + proj.velocity = v_forward * 50;//proj.old_velocity; + +// calculate dot product + backoff = (proj.velocity * trace_plane_normal); + backoff = backoff * 1.5; + +// finish + change = trace_plane_normal_x * backoff; + vec_x = proj.velocity_x - change; + + if (vec_x > -0.1 && vec_x < 0.1) + vec_x = 0; + + change = trace_plane_normal_y * backoff; + vec_y = proj.velocity_y - change; + + if (vec_y > -0.1 && vec_y < 0.1) + vec_y = 0; + + change = trace_plane_normal_z * backoff; + vec_z = proj.velocity_z - change; + + if (vec_z > -0.1 && vec_z < 0.1) + vec_z = 0; + + if (other.classname == "gun_shells") + sound (other, CHAN_AUTO, "weapons/shell.wav", 1, ATTN_NORM); +// set correct angles of our new velocity + proj.angles = vectoangles (vec); + + // this is required to make downward slopes not stop the projectile + proj.flags = proj.flags - ( proj.flags & FL_ONGROUND ); + + return vec; + +}; + +#define drandom() (2*(random()-0.5)) + + + +void(vector org) debris = +{ +local entity rock; +local float rand; +rand = random(); +rock = spawn (); +rock.classname = "rock"; +rock.movetype = MOVETYPE_BOUNCE; +rock.owner = self; + + +// This is all about how fast the debris goes. (My biggest problem) +makevectors (self.angles); +rock.velocity = v_forward * v_up * v_right * random(); + + +rock.velocity_z = rock.velocity_z + 5 + 20*random(); +rock.velocity_x = rock.velocity_x + 3 + 20*drandom(); +rock.velocity_y = rock.velocity_y + 3 + 20*drandom(); +rock.velocity = (rock.velocity * 12); +rock.avelocity = '300 300 300' * drandom(); +rock.angles = vectoangles (rock.velocity); +rock.solid = SOLID_NOT; +rock.touch = Debrisbounce; + +// Rock duration (How long the rocks are alive until they disapear/Explode +rock.nextthink = time + 2 * rand*4; +rock.think = SUB_Remove; +// The whole setting up the model thing. Sets up the sprite and location. +rock.origin = self.origin + v_forward*8*random() + '0 0 16'; +setorigin (rock, org); +setsize (rock, '0 0 0', '3 3 3'); +setmodel (rock, "maps/B_f1.bsp"); +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/defs.qc b/r17/Revamped src/Revamped QC/Primeqc4/defs.qc new file mode 100755 index 00000000..2b044a8f --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/defs.qc @@ -0,0 +1,692 @@ + +/* +============================================================================== + + SOURCE FOR GLOBALVARS_T C STRUCTURE + +============================================================================== +*/ + +// +// system globals +// +entity self; +entity other; +entity world; +float time; +float frametime; + +float force_retouch; // force all entities to touch triggers + // next frame. this is needed because + // non-moving things don't normally scan + // for triggers, and when a trigger is + // created (like a teleport trigger), it + // needs to catch everything. + // decremented each frame, so set to 2 + // to guarantee everything is touched +string mapname; + +float deathmatch; +float coop; +float teamplay; + +float serverflags; // propagated from level to level, used to + // keep track of completed episodes + +float total_secrets; +float total_monsters; + +float found_secrets; // number of secrets found +float killed_monsters; // number of monsters killed + + +// spawnparms are used to encode information about clients across server +// level changes +float parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16; + +// +// global variables set by built in functions +// +vector v_forward, v_up, v_right; // set by makevectors() + +// set by traceline / tracebox +float trace_allsolid; +float trace_startsolid; +float trace_fraction; +vector trace_endpos; +vector trace_plane_normal; +float trace_plane_dist; +entity trace_ent; +float trace_inopen; +float trace_inwater; + +entity msg_entity; // destination of single entity writes + +// +// required prog functions +// +void() main; // only for testing + +void() StartFrame; + +void() PlayerPreThink; +void() PlayerPostThink; + +void() ClientKill; +void() ClientConnect; +void() PutClientInServer; // call after setting the parm1... parms +void() ClientDisconnect; + +void() SetNewParms; // called when a client first connects to + // a server. sets parms so they can be + // saved off for restarts + +void() SetChangeParms; // call to set parms for self so they can + // be saved for a level transition + + +//================================================ +void end_sys_globals; // flag for structure dumping +//================================================ + +/* +============================================================================== + + SOURCE FOR ENTVARS_T C STRUCTURE + +============================================================================== +*/ + +// +// system fields (*** = do not set in prog code, maintained by C code) +// +.float modelindex; // *** model index in the precached list +.vector absmin, absmax; // *** origin + mins / maxs + +.float ltime; // local time for entity +.float movetype; +.float solid; + +.vector origin; // *** +.vector oldorigin; // *** +.vector velocity; +.vector angles; +.vector avelocity; + +.vector punchangle; // temp angle adjust from damage or recoil + +.string classname; // spawn function +.string model; +.float frame; +.float skin; +.float effects; + +.vector mins, maxs; // bounding box extents reletive to origin +.vector size; // maxs - mins + +.void() touch; +.void() use; +.void() think; +.void() blocked; // for doors or plats, called when can't push other + +.float nextthink; +.entity groundentity; + +// stats +.float health; +.float frags; +.float weapon; // one of the IT_BLASTER, etc flags +.string weaponmodel; +.float weaponframe; +.float currentammo; +.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells; + +.float items; // bit flags + +.float takedamage; +.entity chain; +.float deadflag; + +.vector view_ofs; // add to origin to get eye point + + +.float button0; // fire +.float button1; // use +.float button2; // jump + +.float impulse; // weapon changes + +.float fixangle; +.vector v_angle; // view / targeting angle for players +.float idealpitch; // calculated pitch angle for lookup up slopes + + +.string netname; + +.entity enemy; + +.float flags; + +.float colormap; +.float team; + +.float max_health; // players maximum health is stored here + +.float teleport_time; // don't back up + +.float armortype; // save this fraction of incoming damage +.float armorvalue; + +.float waterlevel; // 0 = not in, 1 = feet, 2 = wast, 3 = eyes +.float watertype; // a contents value + +.float ideal_yaw; +.float yaw_speed; + +.entity aiment; + +.entity goalentity; // a movetarget or an enemy + +.float spawnflags; + +.string target; +.string targetname; + +// damage is accumulated through a frame. and sent as one single +// message, so the super shotgun doesn't generate huge messages +.float dmg_take; +.float dmg_save; +.entity dmg_inflictor; + +.entity owner; // who launched a missile +.vector movedir; // mostly for doors, but also used for waterjump + +.string message; // trigger messages + +.float sounds; // either a cd track number or sound number + +.string noise, noise1, noise2, noise3; // contains names of wavs to play + +//================================================ +void end_sys_fields; // flag for structure dumping +//================================================ + +/* +============================================================================== + + VARS NOT REFERENCED BY C CODE + +============================================================================== +*/ + + +// +// constants +// + +float FALSE = 0; +float TRUE = 1; + +// edict.flags +float FL_FLY = 1; +float FL_SWIM = 2; +float FL_CLIENT = 8; // set for all client edicts +float FL_INWATER = 16; // for enter / leave water splash +float FL_MONSTER = 32; +float FL_GODMODE = 64; // player cheat +float FL_NOTARGET = 128; // player cheat +float FL_ITEM = 256; // extra wide size for bonus items +float FL_ONGROUND = 512; // standing on something +float FL_PARTIALGROUND = 1024; // not all corners are valid +float FL_WATERJUMP = 2048; // player jumping out of water +float FL_JUMPRELEASED = 4096; // for jump debouncing + +// edict.movetype values +float MOVETYPE_NONE = 0; // never moves +//float MOVETYPE_ANGLENOCLIP = 1; +//float MOVETYPE_ANGLECLIP = 2; +float MOVETYPE_WALK = 3; // players only +float MOVETYPE_STEP = 4; // discrete, not real time unless fall +float MOVETYPE_FLY = 5; +float MOVETYPE_TOSS = 6; // gravity +float MOVETYPE_PUSH = 7; // no clip to world, push and crush +float MOVETYPE_NOCLIP = 8; +float MOVETYPE_FLYMISSILE = 9; // fly with extra size against monsters +float MOVETYPE_BOUNCE = 10; +float MOVETYPE_BOUNCEMISSILE = 11; // bounce with extra size + +// edict.solid values +float SOLID_NOT = 0; // no interaction with other objects +float SOLID_TRIGGER = 1; // touch on edge, but not blocking +float SOLID_BBOX = 2; // touch on edge, block +float SOLID_SLIDEBOX = 3; // touch on edge, but not an onground +float SOLID_BSP = 4; // bsp clip, touch on edge, block + +// range values +float RANGE_MELEE = 0; +float RANGE_NEAR = 1; +float RANGE_MID = 2; +float RANGE_FAR = 3; + +// deadflag values + +float DEAD_NO = 0; +float DEAD_DYING = 1; +float DEAD_DEAD = 2; +float DEAD_RESPAWNABLE = 3; + +// takedamage values + +float DAMAGE_NO = 0; +float DAMAGE_YES = 1; +float DAMAGE_AIM = 2; + +// items +float IT_MORPHBALL = 4096; +float IT_BLASTER = 1; //Blaster +float IT_ROCKET = 2; //Rocket Launcher +float IT_SPLASER = 4; //Splaser +float IT_SNIPER = 8; //Sniper +float IT_GRENADE_LAUNCHER = 16; +float IT_MAGMA = 32; //Magma beam +float IT_LIGHTNING = 64; +float IT_RIC = 128; //Richochet beam + +float IT_SHELLS = 256; +float IT_NAILS = 512; +float IT_ROCKETS = 1024; +float IT_CELLS = 2048; + +float IT_ARMOR1 = 8192; +float IT_ARMOR2 = 16384; +float IT_ARMOR3 = 32768; +float IT_SUPERHEALTH = 65536; + +float IT_KEY1 = 131072; +float IT_KEY2 = 262144; + +float IT_INVISIBILITY = 524288; +float IT_INVULNERABILITY = 1048576; +float IT_SUIT = 2097152; +float IT_QUAD = 4194304; + +// point content values + +float CONTENT_EMPTY = -1; +float CONTENT_SOLID = -2; +float CONTENT_WATER = -3; +float CONTENT_SLIME = -4; +float CONTENT_LAVA = -5; +float CONTENT_SKY = -6; + +float STATE_TOP = 0; +float STATE_BOTTOM = 1; +float STATE_UP = 2; +float STATE_DOWN = 3; + +vector VEC_ORIGIN = '0 0 0'; +vector VEC_HULL_MIN = '-16 -16 -24'; +vector VEC_HULL_MAX = '16 16 32'; + +vector VEC_HULL2_MIN = '-32 -32 -24'; +vector VEC_HULL2_MAX = '32 32 64'; + +// protocol bytes +float SVC_TEMPENTITY = 23; +float SVC_KILLEDMONSTER = 27; +float SVC_FOUNDSECRET = 28; +float SVC_INTERMISSION = 30; +float SVC_FINALE = 31; +float SVC_CDTRACK = 32; +float SVC_SELLSCREEN = 33; + + +float TE_SPIKE = 0; +float TE_SUPERSPIKE = 1; +float TE_GUNSHOT = 2; +float TE_EXPLOSION = 3; +float TE_TAREXPLOSION = 4; +float TE_LIGHTNING1 = 5; +float TE_LIGHTNING2 = 6; +float TE_WIZSPIKE = 7; +float TE_KNIGHTSPIKE = 8; +float TE_LIGHTNING3 = 9; +float TE_LAVASPLASH = 10; +float TE_TELEPORT = 11; + +// sound channels +// channel 0 never willingly overrides +// other channels (1-7) allways override a playing sound on that channel +float CHAN_AUTO = 0; +float CHAN_WEAPON = 1; +float CHAN_VOICE = 2; +float CHAN_ITEM = 3; +float CHAN_BODY = 4; + +float ATTN_NONE = 0; +float ATTN_NORM = 1; +float ATTN_IDLE = 2; +float ATTN_STATIC = 3; + +// update types + +float UPDATE_GENERAL = 0; +float UPDATE_STATIC = 1; +float UPDATE_BINARY = 2; +float UPDATE_TEMP = 3; + +// entity effects + +float EF_BRIGHTFIELD = 1; +float EF_MUZZLEFLASH = 2; +float EF_BRIGHTLIGHT = 4; +float EF_DIMLIGHT = 8; + + +// messages +float MSG_BROADCAST = 0; // unreliable to all +float MSG_ONE = 1; // reliable to one (msg_entity) +float MSG_ALL = 2; // reliable to all +float MSG_INIT = 3; // write to the init string + +//================================================ + +// +// globals +// +float movedist; +float gameover; // set when a rule exits + +string string_null; // null string, nothing should be held here + +entity newmis; // launch_spike sets this after spawning it + +entity activator; // the entity that activated a trigger or brush + +entity damage_attacker; // set by T_Damage +float framecount; + +float skill; + +//================================================ + +// +// world fields (FIXME: make globals) +// +.string map; +.float worldtype; // 0=medieval 1=metal 2=base + +//================================================ + +.string killtarget; + +// +// quakeed fields +// +.float style; + + +// +// monster ai +// +.void() th_stand; +.void() th_walk; +.void() th_run; +.void() th_missile; +.void() th_melee; +.void(entity attacker, float damage) th_pain; +.void() th_die; + +.entity oldenemy; // mad at this player before taking damage + +.float speed; + +.float lefty; + +.float search_time; +.float attack_state; + +float AS_STRAIGHT = 1; +float AS_SLIDING = 2; +float AS_MELEE = 3; +float AS_MISSILE = 4; + +// +// player only fields +// +.float walkframe; + +.float attack_finished; +.float pain_finished; + +.float invincible_finished; +.float invisible_finished; +.float super_damage_finished; +.float radsuit_finished; + +.float invincible_time, invincible_sound; +.float invisible_time, invisible_sound; +.float super_time, super_sound; +.float rad_time; +.float fly_sound; + +.float axhitme; + +.float show_hostile; // set to time+0.2 whenever a client fires a + // weapon or takes damage. Used to alert + // monsters that otherwise would let the player go +.float jump_flag; // player jump flag +.float swim_flag; // player swimming sound flag +.float air_finished; // when time > air_finished, start drowning +.float bubble_count; // keeps track of the number of bubbles +.string deathtype; // keeps track of how the player died + +// +// object stuff +// +.string mdl; +.vector mangle; // angle at start + +.vector oldorigin; // only used by secret door + +.float t_length, t_width; + + +// +// doors, etc +// +.vector dest1, dest2; +.float wait; // time from firing to restarting +.float delay; // time from activation to firing +.entity trigger_field; // door's trigger entity +.string noise4; + +// +// monsters +// +.float pausetime; +.entity movetarget; + + +// +// doors +// +.float aflag; +.float dmg; // damage done by door when hit + +// +// misc +// +.float cnt; // misc flag + +// +// subs +// +.void() think1; +.vector finaldest, finalangle; + +// +// triggers +// +.float count; // for counting triggers + + +// +// plats / doors / buttons +// +.float lip; +.float state; +.vector pos1, pos2; // top and bottom positions +.float height; + +// +// sounds +// +.float waitmin; +//.float volume; I can't find a use for this one yet. + + + + +//=========================================================================== + + +// +// builtin functions +// + +void(vector ang) makevectors = #1; // sets v_forward, etc globals +void(entity e, vector o) setorigin = #2; +void(entity e, string m) setmodel = #3; // set movetype and solid first +void(entity e, vector min, vector max) setsize = #4; +// #5 was removed +void() break = #6; +float() random = #7; // returns 0 - 1 +//void(entity e, float chan, string samp, float vol, float atten) sound = #8; +vector(vector v) normalize = #9; +void(string e) error = #10; +void(string e) objerror = #11; +float(vector v) vlen = #12; +float(vector v) vectoyaw = #13; +entity() spawn = #14; +void(entity e) remove = #15; + +// sets trace_* globals +// nomonsters can be: +// An entity will also be ignored for testing if forent == test, +// forent->owner == test, or test->owner == forent +// a forent of world is ignored +void(vector v1, vector v2, float nomonsters, entity forent) traceline = #16; + +entity() checkclient = #17; // returns a client to look for +entity(entity start, .string fld, string match) find = #18; +string(string s) precache_sound = #19; +string(string s) precache_model = #20; +//void(entity client, string s)stuffcmd = #21; +entity(vector org, float rad) findradius = #22; +void(string s) bprint = #23; +//void(entity client, string s) sprint = #24; +void(string s) dprint = #25; +string(float f) ftos = #26; +string(vector v) vtos = #27; +void() coredump = #28; // prints all edicts +void() traceon = #29; // turns statment trace on +void() traceoff = #30; +void(entity e) eprint = #31; // prints an entire edict +float(float yaw, float dist) walkmove = #32; // returns TRUE or FALSE +// #33 was removed +float(float yaw, float dist) droptofloor= #34; // TRUE if landed on floor +void(float style, string value) lightstyle = #35; +float(float v) rint = #36; // round to nearest int +float(float v) floor = #37; // largest integer <= v +float(float v) ceil = #38; // smallest integer >= v +// #39 was removed +float(entity e) checkbottom = #40; // true if self is on ground +float(vector v) pointcontents = #41; // returns a CONTENT_* +// #42 was removed +float(float f) fabs = #43; +//vector(entity e, float speed) aim = #44; // returns the shooting vector +float(string s) cvar = #45; // return cvar.value +void(string s) localcmd = #46; // put string into local que +entity(entity e) nextent = #47; // for looping through all ents +void(vector o, vector d, float color, float count) particle = #48;// start a particle effect +void() ChangeYaw = #49; // turn towards self.ideal_yaw + // at self.yaw_speed +// #50 was removed +vector(vector v) vectoangles = #51; + +// +// direct client message generation +// +//void(float to, float f) WriteByte = #52; +//void(float to, float f) WriteChar = #53; +//void(float to, float f) WriteShort = #54; +//void(float to, float f) WriteLong = #55; +//void(float to, float f) WriteCoord = #56; +//void(float to, float f) WriteAngle = #57; +//void(float to, string s) WriteString = #58; +//void(float to, entity s) WriteEntity = #59; + +// +// broadcast client message generation +// + +// void(float f) bWriteByte = #59; +// void(float f) bWriteChar = #60; +// void(float f) bWriteShort = #61; +// void(float f) bWriteLong = #62; +// void(float f) bWriteCoord = #63; +// void(float f) bWriteAngle = #64; +// void(string s) bWriteString = #65; +// void(entity e) bWriteEntity = #66; + +void(float step) movetogoal = #67; + +string(string s) precache_file = #68; // no effect except for -copy +void(entity e) makestatic = #69; +void(string s) changelevel = #70; + +//#71 was removed + +void(string var, string val) cvar_set = #72; // sets cvar.value + +//void(entity client, string s) centerprint = #73; // sprint, but in middle + +void(vector pos, string samp, float vol, float atten) ambientsound = #74; + +string(string s) precache_model2 = #75; // registered version only +string(string s) precache_sound2 = #76; // registered version only +string(string s) precache_file2 = #77; // registered version only + +//void(entity e) setspawnparms = #78; // set parm1... to the + // values at level start + // for coop respawn + +//============================================================================ + +// +// subs.qc +// +void(vector tdest, float tspeed, void() func) SUB_CalcMove; +void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt; +void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove; +void() SUB_CalcMoveDone; +void() SUB_CalcAngleMoveDone; +void() SUB_Null; +void() SUB_UseTargets; +void() SUB_Remove; + +// +// combat.qc +// +void(entity targ, entity inflictor, entity attacker, float damage) T_Damage; + + +float (entity e, float healamount, float ignore) T_Heal; // health function + +float(entity targ, entity inflictor) CanDamage; + + +.float semi; // Semiauto + + \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/demon.qc b/r17/Revamped src/Revamped QC/Primeqc4/demon.qc new file mode 100755 index 00000000..2c96af3b --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/demon.qc @@ -0,0 +1,359 @@ +/* +============================================================================== + +DEMON + +============================================================================== +*/ + +$cd id1/models/demon3 +$scale 0.8 +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 +$frame stand10 stand11 stand12 stand13 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 + +$frame run1 run2 run3 run4 run5 run6 + +$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 leap10 +$frame leap11 leap12 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 + +$frame attacka1 attacka2 attacka3 attacka4 attacka5 attacka6 attacka7 attacka8 +$frame attacka9 attacka10 attacka11 attacka12 attacka13 attacka14 attacka15 + +//============================================================================ + +void() Demon_JumpTouch; + +void() demon1_stand1 =[ $stand1, demon1_stand2 ] {ai_stand();}; +void() demon1_stand2 =[ $stand2, demon1_stand3 ] {ai_stand();}; +void() demon1_stand3 =[ $stand3, demon1_stand4 ] {ai_stand();}; +void() demon1_stand4 =[ $stand4, demon1_stand5 ] {ai_stand();}; +void() demon1_stand5 =[ $stand5, demon1_stand6 ] {ai_stand();}; +void() demon1_stand6 =[ $stand6, demon1_stand7 ] {ai_stand();}; +void() demon1_stand7 =[ $stand7, demon1_stand8 ] {ai_stand();}; +void() demon1_stand8 =[ $stand8, demon1_stand9 ] {ai_stand();}; +void() demon1_stand9 =[ $stand9, demon1_stand10 ] {ai_stand();}; +void() demon1_stand10 =[ $stand10, demon1_stand11 ] {ai_stand();}; +void() demon1_stand11 =[ $stand11, demon1_stand12 ] {ai_stand();}; +void() demon1_stand12 =[ $stand12, demon1_stand13 ] {ai_stand();}; +void() demon1_stand13 =[ $stand13, demon1_stand1 ] {ai_stand();}; + +void() demon1_walk1 =[ $walk1, demon1_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE); +ai_walk(8); +}; +void() demon1_walk2 =[ $walk2, demon1_walk3 ] {ai_walk(6);}; +void() demon1_walk3 =[ $walk3, demon1_walk4 ] {ai_walk(6);}; +void() demon1_walk4 =[ $walk4, demon1_walk5 ] {ai_walk(7);}; +void() demon1_walk5 =[ $walk5, demon1_walk6 ] {ai_walk(4);}; +void() demon1_walk6 =[ $walk6, demon1_walk7 ] {ai_walk(6);}; +void() demon1_walk7 =[ $walk7, demon1_walk8 ] {ai_walk(10);}; +void() demon1_walk8 =[ $walk8, demon1_walk1 ] {ai_walk(10);}; + +void() demon1_run1 =[ $run1, demon1_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE); +ai_run(20);}; +void() demon1_run2 =[ $run2, demon1_run3 ] {ai_run(15);}; +void() demon1_run3 =[ $run3, demon1_run4 ] {ai_run(36);}; +void() demon1_run4 =[ $run4, demon1_run5 ] {ai_run(20);}; +void() demon1_run5 =[ $run5, demon1_run6 ] {ai_run(15);}; +void() demon1_run6 =[ $run6, demon1_run1 ] {ai_run(36);}; + +void() demon1_jump1 =[ $leap1, demon1_jump2 ] {ai_face();}; +void() demon1_jump2 =[ $leap2, demon1_jump3 ] {ai_face();}; +void() demon1_jump3 =[ $leap3, demon1_jump4 ] {ai_face();}; +void() demon1_jump4 =[ $leap4, demon1_jump5 ] +{ + ai_face(); + + self.touch = Demon_JumpTouch; + makevectors (self.angles); + self.origin_z = self.origin_z + 1; + self.velocity = v_forward * 600 + '0 0 250'; + if (self.flags & FL_ONGROUND) + self.flags = self.flags - FL_ONGROUND; +}; +void() demon1_jump5 =[ $leap5, demon1_jump6 ] {}; +void() demon1_jump6 =[ $leap6, demon1_jump7 ] {}; +void() demon1_jump7 =[ $leap7, demon1_jump8 ] {}; +void() demon1_jump8 =[ $leap8, demon1_jump9 ] {}; +void() demon1_jump9 =[ $leap9, demon1_jump10 ] {}; +void() demon1_jump10 =[ $leap10, demon1_jump1 ] { +self.nextthink = time + 3; +// if three seconds pass, assume demon is stuck and jump again +}; + +void() demon1_jump11 =[ $leap11, demon1_jump12 ] {}; +void() demon1_jump12 =[ $leap12, demon1_run1 ] {}; + + +void() demon1_atta1 =[ $attacka1, demon1_atta2 ] {ai_charge(4);}; +void() demon1_atta2 =[ $attacka2, demon1_atta3 ] {ai_charge(0);}; +void() demon1_atta3 =[ $attacka3, demon1_atta4 ] {ai_charge(0);}; +void() demon1_atta4 =[ $attacka4, demon1_atta5 ] {ai_charge(1);}; +void() demon1_atta5 =[ $attacka5, demon1_atta6 ] {ai_charge(2); Demon_Melee(200);}; +void() demon1_atta6 =[ $attacka6, demon1_atta7 ] {ai_charge(1);}; +void() demon1_atta7 =[ $attacka7, demon1_atta8 ] {ai_charge(6);}; +void() demon1_atta8 =[ $attacka8, demon1_atta9 ] {ai_charge(8);}; +void() demon1_atta9 =[ $attacka9, demon1_atta10] {ai_charge(4);}; +void() demon1_atta10 =[ $attacka10, demon1_atta11] {ai_charge(2);}; +void() demon1_atta11 =[ $attacka11, demon1_atta12] {Demon_Melee(-200);}; +void() demon1_atta12 =[ $attacka12, demon1_atta13] {ai_charge(5);}; +void() demon1_atta13 =[ $attacka13, demon1_atta14] {ai_charge(8);}; +void() demon1_atta14 =[ $attacka14, demon1_atta15] {ai_charge(4);}; +void() demon1_atta15 =[ $attacka15, demon1_run1] {ai_charge(4);}; + +void() demon1_pain1 =[ $pain1, demon1_pain2 ] {}; +void() demon1_pain2 =[ $pain2, demon1_pain3 ] {}; +void() demon1_pain3 =[ $pain3, demon1_pain4 ] {}; +void() demon1_pain4 =[ $pain4, demon1_pain5 ] {}; +void() demon1_pain5 =[ $pain5, demon1_pain6 ] {}; +void() demon1_pain6 =[ $pain6, demon1_run1 ] {}; + +void(entity attacker, float damage) demon1_pain = +{ + if (self.touch == Demon_JumpTouch) + return; + + if (self.pain_finished > time) + return; + + self.pain_finished = time + 1; + sound (self, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM); + + if (random()*200 > damage) + return; // didn't flinch + + demon1_pain1 (); +}; + +void() demon1_die1 =[ $death1, demon1_die2 ] { +sound (self, CHAN_VOICE, "demon/ddeath.wav", 1, ATTN_NORM);}; +void() demon1_die2 =[ $death2, demon1_die3 ] {}; +void() demon1_die3 =[ $death3, demon1_die4 ] {}; +void() demon1_die4 =[ $death4, demon1_die5 ] {}; +void() demon1_die5 =[ $death5, demon1_die6 ] {}; +void() demon1_die6 =[ $death6, demon1_die7 ] +{self.solid = SOLID_NOT;}; +void() demon1_die7 =[ $death7, demon1_die8 ] {}; +void() demon1_die8 =[ $death8, demon1_die9 ] {}; +void() demon1_die9 =[ $death9, demon1_die9 ] {}; + +void() demon_die = +{ +// check for gib + if (self.health < -80) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_demon.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + return; + } + +// regular death + demon1_die1 (); +}; + + +void() Demon_MeleeAttack = +{ + demon1_atta1 (); +}; + + +/*QUAKED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) Ambush + +*/ +void() monster_demon1 = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/demon.mdl"); + precache_model ("progs/h_demon.mdl"); + + precache_sound ("demon/ddeath.wav"); + precache_sound ("demon/dhit2.wav"); + precache_sound ("demon/djump.wav"); + precache_sound ("demon/dpain1.wav"); + precache_sound ("demon/idle1.wav"); + precache_sound ("demon/sight2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/demon.mdl"); + + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 300; + + self.th_stand = demon1_stand1; + self.th_walk = demon1_walk1; + self.th_run = demon1_run1; + self.th_die = demon_die; + self.th_melee = Demon_MeleeAttack; // one of two attacks + self.th_missile = demon1_jump1; // jump attack + self.th_pain = demon1_pain; + + walkmonster_start(); +}; + + +/* +============================================================================== + +DEMON + +============================================================================== +*/ + +/* +============== +CheckDemonMelee + +Returns TRUE if a melee attack would hit right now +============== +*/ +float() CheckDemonMelee = +{ + if (enemy_range == RANGE_MELEE) + { // FIXME: check canreach + self.attack_state = AS_MELEE; + return TRUE; + } + return FALSE; +}; + +/* +============== +CheckDemonJump + +============== +*/ +float() CheckDemonJump = +{ + local vector dist; + local float d; + + if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z + + 0.75 * self.enemy.size_z) + return FALSE; + + if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z + + 0.25 * self.enemy.size_z) + return FALSE; + + dist = self.enemy.origin - self.origin; + dist_z = 0; + + d = vlen(dist); + + if (d < 100) + return FALSE; + + if (d > 200) + { + if (random() < 0.9) + return FALSE; + } + + return TRUE; +}; + +float() DemonCheckAttack = +{ +// if close enough for slashing, go for it + if (CheckDemonMelee ()) + { + self.attack_state = AS_MELEE; + return TRUE; + } + + if (CheckDemonJump ()) + { + self.attack_state = AS_MISSILE; + sound (self, CHAN_VOICE, "demon/djump.wav", 1, ATTN_NORM); + return TRUE; + } + + return FALSE; +}; + + +//=========================================================================== + +void(float side) Demon_Melee = +{ + local float ldmg; + local vector delta; + + ai_face (); + walkmove (self.ideal_yaw, 12); // allow a little closing + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + if (!CanDamage (self.enemy, self)) + return; + + sound (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM); + ldmg = 10 + 5*random(); + T_Damage (self.enemy, self, self, ldmg); + +}; + + +void() Demon_JumpTouch = +{ + local float ldmg; + + if (self.health <= 0) + return; + + if (other.takedamage) + { + if ( vlen(self.velocity) > 400 ) + { + ldmg = 40 + 10*random(); + T_Damage (other, self, self, ldmg); + } + } + + if (!checkbottom(self)) + { + if (self.flags & FL_ONGROUND) + { // jump randomly to not get hung up +//dprint ("popjump\n"); + self.touch = SUB_Null; + self.think = demon1_jump1; + self.nextthink = time + 0.1; + +// self.velocity_x = (random() - 0.5) * 600; +// self.velocity_y = (random() - 0.5) * 600; +// self.velocity_z = 200; +// self.flags = self.flags - FL_ONGROUND; + } + return; // not on ground yet + } + + self.touch = SUB_Null; + self.think = demon1_jump11; + self.nextthink = time + 0.1; +}; + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/dog.qc b/r17/Revamped src/Revamped QC/Primeqc4/dog.qc new file mode 100755 index 00000000..a9e18565 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/dog.qc @@ -0,0 +1,362 @@ +/* +============================================================================== + +DOG + +============================================================================== +*/ +$cd id1/models/dog +$origin 0 0 24 +$base base +$skin skin + +$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10 +$frame painb11 painb12 painb13 painb14 painb15 painb16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 + +$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 + + +void() dog_leap1; +void() dog_run1; + +/* +================ +dog_bite + +================ +*/ +void() dog_bite = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + + ai_charge(10); + + if (!CanDamage (self.enemy, self)) + return; + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + ldmg = (random() + random() + random()) * 8; + T_Damage (self.enemy, self, self, ldmg); +}; + +void() Dog_JumpTouch = +{ + local float ldmg; + + if (self.health <= 0) + return; + + if (other.takedamage) + { + if ( vlen(self.velocity) > 300 ) + { + ldmg = 10 + 10*random(); + T_Damage (other, self, self, ldmg); + } + } + + if (!checkbottom(self)) + { + if (self.flags & FL_ONGROUND) + { // jump randomly to not get hung up +//dprint ("popjump\n"); + self.touch = SUB_Null; + self.think = dog_leap1; + self.nextthink = time + 0.1; + +// self.velocity_x = (random() - 0.5) * 600; +// self.velocity_y = (random() - 0.5) * 600; +// self.velocity_z = 200; +// self.flags = self.flags - FL_ONGROUND; + } + return; // not on ground yet + } + + self.touch = SUB_Null; + self.think = dog_run1; + self.nextthink = time + 0.1; +}; + + +void() dog_stand1 =[ $stand1, dog_stand2 ] {ai_stand();}; +void() dog_stand2 =[ $stand2, dog_stand3 ] {ai_stand();}; +void() dog_stand3 =[ $stand3, dog_stand4 ] {ai_stand();}; +void() dog_stand4 =[ $stand4, dog_stand5 ] {ai_stand();}; +void() dog_stand5 =[ $stand5, dog_stand6 ] {ai_stand();}; +void() dog_stand6 =[ $stand6, dog_stand7 ] {ai_stand();}; +void() dog_stand7 =[ $stand7, dog_stand8 ] {ai_stand();}; +void() dog_stand8 =[ $stand8, dog_stand9 ] {ai_stand();}; +void() dog_stand9 =[ $stand9, dog_stand1 ] {ai_stand();}; + +void() dog_walk1 =[ $walk1 , dog_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE); +ai_walk(8);}; +void() dog_walk2 =[ $walk2 , dog_walk3 ] {ai_walk(8);}; +void() dog_walk3 =[ $walk3 , dog_walk4 ] {ai_walk(8);}; +void() dog_walk4 =[ $walk4 , dog_walk5 ] {ai_walk(8);}; +void() dog_walk5 =[ $walk5 , dog_walk6 ] {ai_walk(8);}; +void() dog_walk6 =[ $walk6 , dog_walk7 ] {ai_walk(8);}; +void() dog_walk7 =[ $walk7 , dog_walk8 ] {ai_walk(8);}; +void() dog_walk8 =[ $walk8 , dog_walk1 ] {ai_walk(8);}; + +void() dog_run1 =[ $run1 , dog_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE); +ai_run(16);}; +void() dog_run2 =[ $run2 , dog_run3 ] {ai_run(32);}; +void() dog_run3 =[ $run3 , dog_run4 ] {ai_run(32);}; +void() dog_run4 =[ $run4 , dog_run5 ] {ai_run(20);}; +void() dog_run5 =[ $run5 , dog_run6 ] {ai_run(64);}; +void() dog_run6 =[ $run6 , dog_run7 ] {ai_run(32);}; +void() dog_run7 =[ $run7 , dog_run8 ] {ai_run(16);}; +void() dog_run8 =[ $run8 , dog_run9 ] {ai_run(32);}; +void() dog_run9 =[ $run9 , dog_run10 ] {ai_run(32);}; +void() dog_run10 =[ $run10 , dog_run11 ] {ai_run(20);}; +void() dog_run11 =[ $run11 , dog_run12 ] {ai_run(64);}; +void() dog_run12 =[ $run12 , dog_run1 ] {ai_run(32);}; + +void() dog_atta1 =[ $attack1, dog_atta2 ] {ai_charge(10);}; +void() dog_atta2 =[ $attack2, dog_atta3 ] {ai_charge(10);}; +void() dog_atta3 =[ $attack3, dog_atta4 ] {ai_charge(10);}; +void() dog_atta4 =[ $attack4, dog_atta5 ] { +sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM); +dog_bite();}; +void() dog_atta5 =[ $attack5, dog_atta6 ] {ai_charge(10);}; +void() dog_atta6 =[ $attack6, dog_atta7 ] {ai_charge(10);}; +void() dog_atta7 =[ $attack7, dog_atta8 ] {ai_charge(10);}; +void() dog_atta8 =[ $attack8, dog_run1 ] {ai_charge(10);}; + +void() dog_leap1 =[ $leap1, dog_leap2 ] {ai_face();}; +void() dog_leap2 =[ $leap2, dog_leap3 ] +{ + ai_face(); + + self.touch = Dog_JumpTouch; + makevectors (self.angles); + self.origin_z = self.origin_z + 1; + self.velocity = v_forward * 300 + '0 0 200'; + if (self.flags & FL_ONGROUND) + self.flags = self.flags - FL_ONGROUND; +}; + +void() dog_leap3 =[ $leap3, dog_leap4 ] {}; +void() dog_leap4 =[ $leap4, dog_leap5 ] {}; +void() dog_leap5 =[ $leap5, dog_leap6 ] {}; +void() dog_leap6 =[ $leap6, dog_leap7 ] {}; +void() dog_leap7 =[ $leap7, dog_leap8 ] {}; +void() dog_leap8 =[ $leap8, dog_leap9 ] {}; +void() dog_leap9 =[ $leap9, dog_leap9 ] {}; + +void() dog_pain1 =[ $pain1 , dog_pain2 ] {}; +void() dog_pain2 =[ $pain2 , dog_pain3 ] {}; +void() dog_pain3 =[ $pain3 , dog_pain4 ] {}; +void() dog_pain4 =[ $pain4 , dog_pain5 ] {}; +void() dog_pain5 =[ $pain5 , dog_pain6 ] {}; +void() dog_pain6 =[ $pain6 , dog_run1 ] {}; + +void() dog_painb1 =[ $painb1 , dog_painb2 ] {}; +void() dog_painb2 =[ $painb2 , dog_painb3 ] {}; +void() dog_painb3 =[ $painb3 , dog_painb4 ] {ai_pain(4);}; +void() dog_painb4 =[ $painb4 , dog_painb5 ] {ai_pain(12);}; +void() dog_painb5 =[ $painb5 , dog_painb6 ] {ai_pain(12);}; +void() dog_painb6 =[ $painb6 , dog_painb7 ] {ai_pain(2);}; +void() dog_painb7 =[ $painb7 , dog_painb8 ] {}; +void() dog_painb8 =[ $painb8 , dog_painb9 ] {ai_pain(4);}; +void() dog_painb9 =[ $painb9 , dog_painb10 ] {}; +void() dog_painb10 =[ $painb10 , dog_painb11 ] {ai_pain(10);}; +void() dog_painb11 =[ $painb11 , dog_painb12 ] {}; +void() dog_painb12 =[ $painb12 , dog_painb13 ] {}; +void() dog_painb13 =[ $painb13 , dog_painb14 ] {}; +void() dog_painb14 =[ $painb14 , dog_painb15 ] {}; +void() dog_painb15 =[ $painb15 , dog_painb16 ] {}; +void() dog_painb16 =[ $painb16 , dog_run1 ] {}; + +void() dog_pain = +{ + sound (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM); + + if (random() > 0.5) + dog_pain1 (); + else + dog_painb1 (); +}; + +void() dog_die1 =[ $death1, dog_die2 ] {}; +void() dog_die2 =[ $death2, dog_die3 ] {}; +void() dog_die3 =[ $death3, dog_die4 ] {}; +void() dog_die4 =[ $death4, dog_die5 ] {}; +void() dog_die5 =[ $death5, dog_die6 ] {}; +void() dog_die6 =[ $death6, dog_die7 ] {}; +void() dog_die7 =[ $death7, dog_die8 ] {}; +void() dog_die8 =[ $death8, dog_die9 ] {}; +void() dog_die9 =[ $death9, dog_die9 ] {}; + +void() dog_dieb1 =[ $deathb1, dog_dieb2 ] {}; +void() dog_dieb2 =[ $deathb2, dog_dieb3 ] {}; +void() dog_dieb3 =[ $deathb3, dog_dieb4 ] {}; +void() dog_dieb4 =[ $deathb4, dog_dieb5 ] {}; +void() dog_dieb5 =[ $deathb5, dog_dieb6 ] {}; +void() dog_dieb6 =[ $deathb6, dog_dieb7 ] {}; +void() dog_dieb7 =[ $deathb7, dog_dieb8 ] {}; +void() dog_dieb8 =[ $deathb8, dog_dieb9 ] {}; +void() dog_dieb9 =[ $deathb9, dog_dieb9 ] {}; + + +void() dog_die = +{ +// check for gib + if (self.health < -35) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowHead ("progs/h_dog.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM); + self.solid = SOLID_NOT; + + if (random() > 0.5) + dog_die1 (); + else + dog_dieb1 (); +}; + +//============================================================================ + +/* +============== +CheckDogMelee + +Returns TRUE if a melee attack would hit right now +============== +*/ +float() CheckDogMelee = +{ + if (enemy_range == RANGE_MELEE) + { // FIXME: check canreach + self.attack_state = AS_MELEE; + return TRUE; + } + return FALSE; +}; + +/* +============== +CheckDogJump + +============== +*/ +float() CheckDogJump = +{ + local vector dist; + local float d; + + if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z + + 0.75 * self.enemy.size_z) + return FALSE; + + if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z + + 0.25 * self.enemy.size_z) + return FALSE; + + dist = self.enemy.origin - self.origin; + dist_z = 0; + + d = vlen(dist); + + if (d < 80) + return FALSE; + + if (d > 150) + return FALSE; + + return TRUE; +}; + +float() DogCheckAttack = +{ +// if close enough for slashing, go for it + if (CheckDogMelee ()) + { + self.attack_state = AS_MELEE; + return TRUE; + } + + if (CheckDogJump ()) + { + self.attack_state = AS_MISSILE; + return TRUE; + } + + return FALSE; +}; + + + +//=========================================================================== + +/*QUAKED monster_dog (1 0 0) (-32 -32 -24) (32 32 40) Ambush + +*/ +void(vector org) monster_dog = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/metroid.mdl"); + + precache_sound ("dog/dattack1.wav"); + precache_sound ("dog/ddeath.wav"); + precache_sound ("dog/dpain1.wav"); + precache_sound ("dog/dsight.wav"); + precache_sound ("dog/idle.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/metroid.mdl"); + + setsize (self, '-16 -16 -32', '16 16 20'); + self.health = 400; + + self.th_stand = dog_stand1; + self.th_walk = dog_walk1; + self.th_run = dog_run1; + self.th_pain = dog_pain; + self.th_die = dog_die; + self.th_melee = dog_atta1; + self.th_missile = dog_leap1; + + walkmonster_start(); +}; + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/doors.qc b/r17/Revamped src/Revamped QC/Primeqc4/doors.qc new file mode 100755 index 00000000..5a85ca86 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/doors.qc @@ -0,0 +1,778 @@ + +float DOOR_START_OPEN = 1; +float DOOR_DONT_LINK = 4; +float DOOR_GOLD_KEY = 8; +float DOOR_SILVER_KEY = 16; +float DOOR_TOGGLE = 32; + +/* + +Doors are similar to buttons, but can spawn a fat trigger field around them +to open without a touch, and they link together to form simultanious +double/quad doors. + +Door.owner is the master door. If there is only one door, it points to itself. +If multiple doors, all will point to a single one. + +Door.enemy chains from the master door through all doors linked in the chain. + +*/ + +/* +============================================================================= + +THINK FUNCTIONS + +============================================================================= +*/ + +void() door_go_down; +void() door_go_up; + +void() door_blocked = +{ + T_Damage (other, self, self, self.dmg); + +// if a door has a negative wait, it would never come back if blocked, +// so let it just squash the object to death real fast + if (self.wait >= 0) + { + if (self.state == STATE_DOWN) + door_go_up (); + else + door_go_down (); + } +}; + + +void() door_hit_top = +{ + sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_TOP; + if (self.spawnflags & DOOR_TOGGLE) + return; // don't come down automatically + self.think = door_go_down; + self.nextthink = self.ltime + self.wait; +}; + +void() door_hit_bottom = +{ + sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_BOTTOM; +}; + +void() door_go_down = +{ + sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + if (self.max_health) + { + self.takedamage = DAMAGE_YES; + self.health = self.max_health; + } + + self.state = STATE_DOWN; + SUB_CalcMove (self.pos1, self.speed, door_hit_bottom); +}; + +void() door_go_up = +{ + if (self.state == STATE_UP) + return; // allready going up + + if (self.state == STATE_TOP) + { // reset top wait time + self.nextthink = self.ltime + self.wait; + return; + } + + sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + self.state = STATE_UP; + SUB_CalcMove (self.pos2, self.speed, door_hit_top); + + SUB_UseTargets(); +}; + + +/* +============================================================================= + +ACTIVATION FUNCTIONS + +============================================================================= +*/ + +void() door_fire = +{ + local entity oself; + local entity starte; + + if (self.owner != self) + objerror ("door_fire: self.owner != self"); + +// play use key sound + + if (self.items) + sound (self, CHAN_VOICE, self.noise4, 1, ATTN_NORM); + + self.message = string_null; // no more message + oself = self; + + if (self.spawnflags & DOOR_TOGGLE) + { + if (self.state == STATE_UP || self.state == STATE_TOP) + { + starte = self; + do + { + door_go_down (); + self = self.enemy; + } while ( (self != starte) && (self != world) ); + self = oself; + return; + } + } + +// trigger all paired doors + starte = self; + do + { + door_go_up (); + self = self.enemy; + } while ( (self != starte) && (self != world) ); + self = oself; +}; + + +void() door_use = +{ + local entity oself; + + self.message = ""; // door message are for touch only + self.owner.message = ""; + self.enemy.message = ""; + oself = self; + self = self.owner; + door_fire (); + self = oself; +}; + + +void() door_trigger_touch = +{ + if (other.health <= 0) + return; + + if (time < self.attack_finished) + return; + self.attack_finished = time + 1; + + activator = other; + + self = self.owner; + door_use (); +}; + + +void() door_killed = +{ + local entity oself; + + oself = self; + self = self.owner; + self.health = self.max_health; + self.takedamage = DAMAGE_NO; // wil be reset upon return + door_use (); + self = oself; +}; + + +/* +================ +door_touch + +Prints messages and opens key doors +================ +*/ +void() door_touch = +{ + if (other.classname != "player") + return; + if (self.owner.attack_finished > time) + return; + + self.owner.attack_finished = time + 2; + + if (self.owner.message != "") + { + centerprint (other, self.owner.message); + sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM); + } + +// key door stuff + if (!self.items) + return; + +// FIXME: blink key on player's status bar + if ( (self.items & other.items) != self.items ) + { + if (self.owner.items == IT_KEY1) + { + if (world.worldtype == 2) + { + centerprint (other, "You need the silver keycard"); + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + } + else if (world.worldtype == 1) + { + centerprint (other, "You need the silver runekey"); + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + } + else if (world.worldtype == 0) + { + centerprint (other, "You need the silver key"); + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + } + } + else + { + if (world.worldtype == 2) + { + centerprint (other, "You need the gold keycard"); + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + } + else if (world.worldtype == 1) + { + centerprint (other, "You need the gold runekey"); + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + } + else if (world.worldtype == 0) + { + centerprint (other, "You need the gold key"); + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + } + } + return; + } + + other.items = other.items - self.items; + self.touch = SUB_Null; + if (self.enemy) + self.enemy.touch = SUB_Null; // get paired door + door_use (); +}; + +/* +============================================================================= + +SPAWNING FUNCTIONS + +============================================================================= +*/ + + +entity(vector fmins, vector fmaxs) spawn_field = +{ + local entity trigger; + local vector t1, t2; + + trigger = spawn(); + trigger.movetype = MOVETYPE_NONE; + trigger.solid = SOLID_TRIGGER; + trigger.owner = self; + trigger.touch = door_trigger_touch; + + t1 = fmins; + t2 = fmaxs; + setsize (trigger, t1 - '60 60 8', t2 + '60 60 8'); + return (trigger); +}; + + +float (entity e1, entity e2) EntitiesTouching = +{ + if (e1.mins_x > e2.maxs_x) + return FALSE; + if (e1.mins_y > e2.maxs_y) + return FALSE; + if (e1.mins_z > e2.maxs_z) + return FALSE; + if (e1.maxs_x < e2.mins_x) + return FALSE; + if (e1.maxs_y < e2.mins_y) + return FALSE; + if (e1.maxs_z < e2.mins_z) + return FALSE; + return TRUE; +}; + + +/* +============= +LinkDoors + + +============= +*/ +void() LinkDoors = +{ + local entity t, starte; + local vector cmins, cmaxs; + + if (self.enemy) + return; // already linked by another door + if (self.spawnflags & 4) + { + self.owner = self.enemy = self; + return; // don't want to link this door + } + + cmins = self.mins; + cmaxs = self.maxs; + + starte = self; + t = self; + + do + { + self.owner = starte; // master door + + if (self.health) + starte.health = self.health; + if (self.targetname) + starte.targetname = self.targetname; + if (self.message != "") + starte.message = self.message; + + t = find (t, classname, self.classname); + if (!t) + { + self.enemy = starte; // make the chain a loop + + // shootable, fired, or key doors just needed the owner/enemy links, + // they don't spawn a field + + self = self.owner; + + if (self.health) + return; + if (self.targetname) + return; + if (self.items) + return; + + self.owner.trigger_field = spawn_field(cmins, cmaxs); + + return; + } + + if (EntitiesTouching(self,t)) + { + if (t.enemy) + objerror ("cross connected doors"); + + self.enemy = t; + self = t; + + if (t.mins_x < cmins_x) + cmins_x = t.mins_x; + if (t.mins_y < cmins_y) + cmins_y = t.mins_y; + if (t.mins_z < cmins_z) + cmins_z = t.mins_z; + if (t.maxs_x > cmaxs_x) + cmaxs_x = t.maxs_x; + if (t.maxs_y > cmaxs_y) + cmaxs_y = t.maxs_y; + if (t.maxs_z > cmaxs_z) + cmaxs_z = t.maxs_z; + } + } while (1 ); + +}; + + +/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE +if two doors touch, they are assumed to be connected and operate as a unit. + +TOGGLE causes the door to wait in both the start and end states for a trigger event. + +START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not usefull for touch or takedamage doors). + +Key doors are allways wait -1. + +"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet +"angle" determines the opening direction +"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door. +"health" if set, door must be shot open +"speed" movement speed (100 default) +"wait" wait before returning (3 default, -1 = never return) +"lip" lip remaining at end of move (8 default) +"dmg" damage to inflict when blocked (2 default) +"sounds" +0) no sound +1) stone +2) base +3) stone chain +4) screechy metal +*/ + +void() func_door = + +{ + + if (world.worldtype == 0) + { + precache_sound ("doors/medtry.wav"); + precache_sound ("doors/meduse.wav"); + self.noise3 = "doors/medtry.wav"; + self.noise4 = "doors/meduse.wav"; + } + else if (world.worldtype == 1) + { + precache_sound ("doors/runetry.wav"); + precache_sound ("doors/runeuse.wav"); + self.noise3 = "doors/runetry.wav"; + self.noise4 = "doors/runeuse.wav"; + } + else if (world.worldtype == 2) + { + precache_sound ("doors/basetry.wav"); + precache_sound ("doors/baseuse.wav"); + self.noise3 = "doors/basetry.wav"; + self.noise4 = "doors/baseuse.wav"; + } + else + { + dprint ("no worldtype set!\n"); + } + if (self.sounds == 0) + { + precache_sound ("misc/null.wav"); + precache_sound ("misc/null.wav"); + self.noise1 = "misc/null.wav"; + self.noise2 = "misc/null.wav"; + } + if (self.sounds == 1) + { + precache_sound ("doors/drclos4.wav"); + precache_sound ("doors/doormv1.wav"); + self.noise1 = "doors/drclos4.wav"; + self.noise2 = "doors/doormv1.wav"; + } + if (self.sounds == 2) + { + precache_sound ("doors/hydro1.wav"); + precache_sound ("doors/hydro2.wav"); + self.noise2 = "doors/hydro1.wav"; + self.noise1 = "doors/hydro2.wav"; + } + if (self.sounds == 3) + { + precache_sound ("doors/stndr1.wav"); + precache_sound ("doors/stndr2.wav"); + self.noise2 = "doors/stndr1.wav"; + self.noise1 = "doors/stndr2.wav"; + } + if (self.sounds == 4) + { + precache_sound ("doors/ddoor1.wav"); + precache_sound ("doors/ddoor2.wav"); + self.noise1 = "doors/ddoor2.wav"; + self.noise2 = "doors/ddoor1.wav"; + } + + + SetMovedir (); + + self.max_health = self.health; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + setorigin (self, self.origin); + setmodel (self, self.model); + self.classname = "door"; + + self.blocked = door_blocked; + self.use = door_use; + + if (self.spawnflags & DOOR_SILVER_KEY) + self.items = IT_KEY1; + if (self.spawnflags & DOOR_GOLD_KEY) + self.items = IT_KEY2; + + if (!self.speed) + self.speed = 100; + if (!self.wait) + self.wait = 3; + if (!self.lip) + self.lip = 8; + if (!self.dmg) + self.dmg = 2; + + self.pos1 = self.origin; + self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip); + +// DOOR_START_OPEN is to allow an entity to be lighted in the closed position +// but spawn in the open position + if (self.spawnflags & DOOR_START_OPEN) + { + setorigin (self, self.pos2); + self.pos2 = self.pos1; + self.pos1 = self.origin; + } + + self.state = STATE_BOTTOM; + + if (self.health) + { + self.takedamage = DAMAGE_YES; + self.th_die = door_killed; + } + + if (self.items) + self.wait = -1; + + self.touch = door_touch; + +// LinkDoors can't be done until all of the doors have been spawned, so +// the sizes can be detected properly. + self.think = LinkDoors; + self.nextthink = self.ltime + 0.1; +}; + +/* +============================================================================= + +SECRET DOORS + +============================================================================= +*/ + +void() fd_secret_move1; +void() fd_secret_move2; +void() fd_secret_move3; +void() fd_secret_move4; +void() fd_secret_move5; +void() fd_secret_move6; +void() fd_secret_done; + +float SECRET_OPEN_ONCE = 1; // stays open +float SECRET_1ST_LEFT = 2; // 1st move is left of arrow +float SECRET_1ST_DOWN = 4; // 1st move is down from arrow +float SECRET_NO_SHOOT = 8; // only opened by trigger +float SECRET_YES_SHOOT = 16; // shootable even if targeted + + +void () fd_secret_use = +{ + local float temp; + + self.health = 10000; + + // exit if still moving around... + if (self.origin != self.oldorigin) + return; + + self.message = string_null; // no more message + + SUB_UseTargets(); // fire all targets / killtargets + + if (!(self.spawnflags & SECRET_NO_SHOOT)) + { + self.th_pain = SUB_Null; + self.takedamage = DAMAGE_NO; + } + self.velocity = '0 0 0'; + + // Make a sound, wait a little... + + sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.nextthink = self.ltime + 0.1; + + temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1 + makevectors(self.mangle); + + if (!self.t_width) + { + if (self.spawnflags & SECRET_1ST_DOWN) + self. t_width = fabs(v_up * self.size); + else + self. t_width = fabs(v_right * self.size); + } + + if (!self.t_length) + self. t_length = fabs(v_forward * self.size); + + if (self.spawnflags & SECRET_1ST_DOWN) + self.dest1 = self.origin - v_up * self.t_width; + else + self.dest1 = self.origin + v_right * (self.t_width * temp); + + self.dest2 = self.dest1 + v_forward * self.t_length; + SUB_CalcMove(self.dest1, self.speed, fd_secret_move1); + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); +}; + +// Wait after first movement... +void () fd_secret_move1 = +{ + self.nextthink = self.ltime + 1.0; + self.think = fd_secret_move2; + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); +}; + +// Start moving sideways w/sound... +void () fd_secret_move2 = +{ + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + SUB_CalcMove(self.dest2, self.speed, fd_secret_move3); +}; + +// Wait here until time to go back... +void () fd_secret_move3 = +{ + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + if (!(self.spawnflags & SECRET_OPEN_ONCE)) + { + self.nextthink = self.ltime + self.wait; + self.think = fd_secret_move4; + } +}; + +// Move backward... +void () fd_secret_move4 = +{ + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + SUB_CalcMove(self.dest1, self.speed, fd_secret_move5); +}; + +// Wait 1 second... +void () fd_secret_move5 = +{ + self.nextthink = self.ltime + 1.0; + self.think = fd_secret_move6; + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); +}; + +void () fd_secret_move6 = +{ + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done); +}; + +void () fd_secret_done = +{ + if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT) + { + self.health = 10000; + self.takedamage = DAMAGE_YES; + self.th_pain = fd_secret_use; + } + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); +}; + +void () secret_blocked = +{ + if (time < self.attack_finished) + return; + self.attack_finished = time + 0.5; + T_Damage (other, self, self, self.dmg); +}; + +/* +================ +secret_touch + +Prints messages +================ +*/ +void() secret_touch = +{ + if (other.classname != "player") + return; + if (self.attack_finished > time) + return; + + self.attack_finished = time + 2; + + if (self.message) + { + centerprint (other, self.message); + sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM); + } +}; + + +/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot +Basic secret door. Slides back, then to the side. Angle determines direction. +wait = # of seconds before coming back +1st_left = 1st move is left of arrow +1st_down = 1st move is down from arrow +always_shoot = even if targeted, keep shootable +t_width = override WIDTH to move back (or height if going down) +t_length = override LENGTH to move sideways +"dmg" damage to inflict when blocked (2 default) + +If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage. +"sounds" +1) medieval +2) metal +3) base +*/ + +void () func_door_secret = +{ + if (self.sounds == 0) + self.sounds = 3; + if (self.sounds == 1) + { + precache_sound ("doors/latch2.wav"); + precache_sound ("doors/winch2.wav"); + precache_sound ("doors/drclos4.wav"); + self.noise1 = "doors/latch2.wav"; + self.noise2 = "doors/winch2.wav"; + self.noise3 = "doors/drclos4.wav"; + } + if (self.sounds == 2) + { + precache_sound ("doors/airdoor1.wav"); + precache_sound ("doors/airdoor2.wav"); + self.noise2 = "doors/airdoor1.wav"; + self.noise1 = "doors/airdoor2.wav"; + self.noise3 = "doors/airdoor2.wav"; + } + if (self.sounds == 3) + { + precache_sound ("doors/basesec1.wav"); + precache_sound ("doors/basesec2.wav"); + self.noise2 = "doors/basesec1.wav"; + self.noise1 = "doors/basesec2.wav"; + self.noise3 = "doors/basesec2.wav"; + } + + if (!self.dmg) + self.dmg = 2; + + // Magic formula... + self.mangle = self.angles; + self.angles = '0 0 0'; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + self.classname = "door"; + setmodel (self, self.model); + setorigin (self, self.origin); + + self.touch = secret_touch; + self.blocked = secret_blocked; + self.speed = 50; + self.use = fd_secret_use; + if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT) + { + self.health = 10000; + self.takedamage = DAMAGE_YES; + self.th_pain = fd_secret_use; + self.th_die = fd_secret_use; + } + self.oldorigin = self.origin; + if (!self.wait) + self.wait = 5; // 5 seconds before closing +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/effects.qc b/r17/Revamped src/Revamped QC/Primeqc4/effects.qc new file mode 100755 index 00000000..293a8f23 Binary files /dev/null and b/r17/Revamped src/Revamped QC/Primeqc4/effects.qc differ diff --git a/r17/Revamped src/Revamped QC/Primeqc4/enforcer.qc b/r17/Revamped src/Revamped QC/Primeqc4/enforcer.qc new file mode 100755 index 00000000..2e520190 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/enforcer.qc @@ -0,0 +1,349 @@ +/* +============================================================================== + +SOLDIER / PLAYER + +============================================================================== +*/ + +$cd id1/models/enforcer +$origin 0 -6 24 +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 +$frame walk11 walk12 walk13 walk14 walk15 walk16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame attack1 attack2 attack3 attack4 attack5 attack6 +$frame attack7 attack8 attack9 attack10 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 death11 death12 death13 death14 + +$frame fdeath1 fdeath2 fdeath3 fdeath4 fdeath5 fdeath6 fdeath7 fdeath8 +$frame fdeath9 fdeath10 fdeath11 + +$frame paina1 paina2 paina3 paina4 + +$frame painb1 painb2 painb3 painb4 painb5 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 +$frame paind9 paind10 paind11 paind12 paind13 paind14 paind15 paind16 +$frame paind17 paind18 paind19 + + +void() Laser_Touch = +{ + local vector org; + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + + sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); + org = self.origin - 8*normalize(self.velocity); + + if (other.health) + { + SpawnBlood (org, self.velocity*0.2, 15); + T_Damage (other, self, self.owner, 15); + } + else + { + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_GUNSHOT); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); + } + + remove(self); +}; + +void(vector org, vector vec) LaunchLaser = +{ + if (self.classname == "monster_enforcer") + sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM); + + vec = normalize(vec); + + newmis = spawn(); + newmis.owner = self; + newmis.movetype = MOVETYPE_FLY; + newmis.solid = SOLID_BBOX; + newmis.effects = EF_DIMLIGHT; + + setmodel (newmis, "progs/laser.mdl"); + setsize (newmis, '0 0 0', '0 0 0'); + + setorigin (newmis, org); + + newmis.velocity = vec * 600; + newmis.angles = vectoangles(newmis.velocity); + + newmis.nextthink = time + 5; + newmis.think = SUB_Remove; + newmis.touch = Laser_Touch; +}; + + + +void() enforcer_fire = +{ + local vector org; + + self.effects = self.effects | EF_MUZZLEFLASH; + makevectors (self.angles); + + org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16'; + + LaunchLaser(org, self.enemy.origin - self.origin); +}; + +//============================================================================ + +void() enf_stand1 =[ $stand1, enf_stand2 ] {ai_stand();}; +void() enf_stand2 =[ $stand2, enf_stand3 ] {ai_stand();}; +void() enf_stand3 =[ $stand3, enf_stand4 ] {ai_stand();}; +void() enf_stand4 =[ $stand4, enf_stand5 ] {ai_stand();}; +void() enf_stand5 =[ $stand5, enf_stand6 ] {ai_stand();}; +void() enf_stand6 =[ $stand6, enf_stand7 ] {ai_stand();}; +void() enf_stand7 =[ $stand7, enf_stand1 ] {ai_stand();}; + +void() enf_walk1 =[ $walk1 , enf_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); +ai_walk(2);}; +void() enf_walk2 =[ $walk2 , enf_walk3 ] {ai_walk(4);}; +void() enf_walk3 =[ $walk3 , enf_walk4 ] {ai_walk(4);}; +void() enf_walk4 =[ $walk4 , enf_walk5 ] {ai_walk(3);}; +void() enf_walk5 =[ $walk5 , enf_walk6 ] {ai_walk(1);}; +void() enf_walk6 =[ $walk6 , enf_walk7 ] {ai_walk(2);}; +void() enf_walk7 =[ $walk7 , enf_walk8 ] {ai_walk(2);}; +void() enf_walk8 =[ $walk8 , enf_walk9 ] {ai_walk(1);}; +void() enf_walk9 =[ $walk9 , enf_walk10 ] {ai_walk(2);}; +void() enf_walk10 =[ $walk10, enf_walk11 ] {ai_walk(4);}; +void() enf_walk11 =[ $walk11, enf_walk12 ] {ai_walk(4);}; +void() enf_walk12 =[ $walk12, enf_walk13 ] {ai_walk(1);}; +void() enf_walk13 =[ $walk13, enf_walk14 ] {ai_walk(2);}; +void() enf_walk14 =[ $walk14, enf_walk15 ] {ai_walk(3);}; +void() enf_walk15 =[ $walk15, enf_walk16 ] {ai_walk(4);}; +void() enf_walk16 =[ $walk16, enf_walk1 ] {ai_walk(2);}; + +void() enf_run1 =[ $run1 , enf_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); +ai_run(18);}; +void() enf_run2 =[ $run2 , enf_run3 ] {ai_run(14);}; +void() enf_run3 =[ $run3 , enf_run4 ] {ai_run(7);}; +void() enf_run4 =[ $run4 , enf_run5 ] {ai_run(12);}; +void() enf_run5 =[ $run5 , enf_run6 ] {ai_run(14);}; +void() enf_run6 =[ $run6 , enf_run7 ] {ai_run(14);}; +void() enf_run7 =[ $run7 , enf_run8 ] {ai_run(7);}; +void() enf_run8 =[ $run8 , enf_run1 ] {ai_run(11);}; + +void() enf_atk1 =[ $attack1, enf_atk2 ] {ai_face();}; +void() enf_atk2 =[ $attack2, enf_atk3 ] {ai_face();}; +void() enf_atk3 =[ $attack3, enf_atk4 ] {ai_face();}; +void() enf_atk4 =[ $attack4, enf_atk5 ] {ai_face();}; +void() enf_atk5 =[ $attack5, enf_atk6 ] {ai_face();}; +void() enf_atk6 =[ $attack6, enf_atk7 ] {enforcer_fire();}; +void() enf_atk7 =[ $attack7, enf_atk8 ] {ai_face();}; +void() enf_atk8 =[ $attack8, enf_atk9 ] {ai_face();}; +void() enf_atk9 =[ $attack5, enf_atk10 ] {ai_face();}; +void() enf_atk10 =[ $attack6, enf_atk11 ] {enforcer_fire();}; +void() enf_atk11 =[ $attack7, enf_atk12 ] {ai_face();}; +void() enf_atk12 =[ $attack8, enf_atk13 ] {ai_face();}; +void() enf_atk13 =[ $attack9, enf_atk14 ] {ai_face();}; +void() enf_atk14 =[ $attack10, enf_run1 ] {ai_face(); +SUB_CheckRefire (enf_atk1); +}; + +void() enf_paina1 =[ $paina1, enf_paina2 ] {}; +void() enf_paina2 =[ $paina2, enf_paina3 ] {}; +void() enf_paina3 =[ $paina3, enf_paina4 ] {}; +void() enf_paina4 =[ $paina4, enf_run1 ] {}; + +void() enf_painb1 =[ $painb1, enf_painb2 ] {}; +void() enf_painb2 =[ $painb2, enf_painb3 ] {}; +void() enf_painb3 =[ $painb3, enf_painb4 ] {}; +void() enf_painb4 =[ $painb4, enf_painb5 ] {}; +void() enf_painb5 =[ $painb5, enf_run1 ] {}; + +void() enf_painc1 =[ $painc1, enf_painc2 ] {}; +void() enf_painc2 =[ $painc2, enf_painc3 ] {}; +void() enf_painc3 =[ $painc3, enf_painc4 ] {}; +void() enf_painc4 =[ $painc4, enf_painc5 ] {}; +void() enf_painc5 =[ $painc5, enf_painc6 ] {}; +void() enf_painc6 =[ $painc6, enf_painc7 ] {}; +void() enf_painc7 =[ $painc7, enf_painc8 ] {}; +void() enf_painc8 =[ $painc8, enf_run1 ] {}; + +void() enf_paind1 =[ $paind1, enf_paind2 ] {}; +void() enf_paind2 =[ $paind2, enf_paind3 ] {}; +void() enf_paind3 =[ $paind3, enf_paind4 ] {}; +void() enf_paind4 =[ $paind4, enf_paind5 ] {ai_painforward(2);}; +void() enf_paind5 =[ $paind5, enf_paind6 ] {ai_painforward(1);}; +void() enf_paind6 =[ $paind6, enf_paind7 ] {}; +void() enf_paind7 =[ $paind7, enf_paind8 ] {}; +void() enf_paind8 =[ $paind8, enf_paind9 ] {}; +void() enf_paind9 =[ $paind9, enf_paind10 ] {}; +void() enf_paind10 =[ $paind10, enf_paind11 ] {}; +void() enf_paind11 =[ $paind11, enf_paind12 ] {ai_painforward(1);}; +void() enf_paind12 =[ $paind12, enf_paind13 ] {ai_painforward(1);}; +void() enf_paind13 =[ $paind13, enf_paind14 ] {ai_painforward(1);}; +void() enf_paind14 =[ $paind14, enf_paind15 ] {}; +void() enf_paind15 =[ $paind15, enf_paind16 ] {}; +void() enf_paind16 =[ $paind16, enf_paind17 ] {ai_pain(1);}; +void() enf_paind17 =[ $paind17, enf_paind18 ] {ai_pain(1);}; +void() enf_paind18 =[ $paind18, enf_paind19 ] {}; +void() enf_paind19 =[ $paind19, enf_run1 ] {}; + +void(entity attacker, float damage) enf_pain = +{ + local float r; + + r = random (); + if (self.pain_finished > time) + return; + + + if (r < 0.5) + sound (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM); + + if (r < 0.2) + { + self.pain_finished = time + 1; + enf_paina1 (); + } + else if (r < 0.4) + { + self.pain_finished = time + 1; + enf_painb1 (); + } + else if (r < 0.7) + { + self.pain_finished = time + 1; + enf_painc1 (); + } + else + { + self.pain_finished = time + 2; + enf_paind1 (); + } +}; + +//============================================================================ + + + + +void() enf_die1 =[ $death1, enf_die2 ] {}; +void() enf_die2 =[ $death2, enf_die3 ] {}; +void() enf_die3 =[ $death3, enf_die4 ] +{self.solid = SOLID_NOT;self.ammo_cells = 5;DropBackpack();}; +void() enf_die4 =[ $death4, enf_die5 ] {ai_forward(14);}; +void() enf_die5 =[ $death5, enf_die6 ] {ai_forward(2);}; +void() enf_die6 =[ $death6, enf_die7 ] {}; +void() enf_die7 =[ $death7, enf_die8 ] {}; +void() enf_die8 =[ $death8, enf_die9 ] {}; +void() enf_die9 =[ $death9, enf_die10 ] {ai_forward(3);}; +void() enf_die10 =[ $death10, enf_die11 ] {ai_forward(5);}; +void() enf_die11 =[ $death11, enf_die12 ] {ai_forward(5);}; +void() enf_die12 =[ $death12, enf_die13 ] {ai_forward(5);}; +void() enf_die13 =[ $death13, enf_die14 ] {}; +void() enf_die14 =[ $death14, enf_die14 ] {}; + +void() enf_fdie1 =[ $fdeath1, enf_fdie2 ] { + +}; +void() enf_fdie2 =[ $fdeath2, enf_fdie3 ] {}; +void() enf_fdie3 =[ $fdeath3, enf_fdie4 ] +{self.solid = SOLID_NOT;self.ammo_cells = 5;DropBackpack();}; +void() enf_fdie4 =[ $fdeath4, enf_fdie5 ] {}; +void() enf_fdie5 =[ $fdeath5, enf_fdie6 ] {}; +void() enf_fdie6 =[ $fdeath6, enf_fdie7 ] {}; +void() enf_fdie7 =[ $fdeath7, enf_fdie8 ] {}; +void() enf_fdie8 =[ $fdeath8, enf_fdie9 ] {}; +void() enf_fdie9 =[ $fdeath9, enf_fdie10 ] {}; +void() enf_fdie10 =[ $fdeath10, enf_fdie11 ] {}; +void() enf_fdie11 =[ $fdeath11, enf_fdie11 ] {}; + + +void() enf_die = +{ +// check for gib + if (self.health < -35) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_mega.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM); + if (random() > 0.5) + enf_die1 (); + else + enf_fdie1 (); +}; + + +/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) Ambush + +*/ +void() monster_enforcer = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/enforcer.mdl"); + precache_model2 ("progs/h_mega.mdl"); + precache_model2 ("progs/laser.mdl"); + + precache_sound2 ("enforcer/death1.wav"); + precache_sound2 ("enforcer/enfire.wav"); + precache_sound2 ("enforcer/enfstop.wav"); + precache_sound2 ("enforcer/idle1.wav"); + precache_sound2 ("enforcer/pain1.wav"); + precache_sound2 ("enforcer/pain2.wav"); + precache_sound2 ("enforcer/sight1.wav"); + precache_sound2 ("enforcer/sight2.wav"); + precache_sound2 ("enforcer/sight3.wav"); + precache_sound2 ("enforcer/sight4.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/enforcer.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 80; + + self.th_stand = enf_stand1; + self.th_walk = enf_walk1; + self.th_run = enf_run1; + self.th_pain = enf_pain; + self.th_die = enf_die; + self.th_missile = enf_atk1; + + walkmonster_start(); +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/fight.qc b/r17/Revamped src/Revamped QC/Primeqc4/fight.qc new file mode 100755 index 00000000..4a3a4c26 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/fight.qc @@ -0,0 +1,407 @@ + +/* + +A monster is in fight mode if it thinks it can effectively attack its +enemy. + +When it decides it can't attack, it goes into hunt mode. + +*/ + +float(float v) anglemod; + +void() knight_atk1; +void() knight_runatk1; +void() ogre_smash1; +void() ogre_swing1; + +void() sham_smash1; +void() sham_swingr1; +void() sham_swingl1; + +float() DemonCheckAttack; +void(float side) Demon_Melee; + +void(vector dest) ChooseTurn; + +void() ai_face; + + +float enemy_vis, enemy_infront, enemy_range; +float enemy_yaw; + + +void() knight_attack = +{ + local float len; + +// decide if now is a good swing time + len = vlen(self.enemy.origin+self.enemy.view_ofs - (self.origin+self.view_ofs)); + + if (len<80) + knight_atk1 (); + else + knight_runatk1 (); +}; + +//============================================================================= + +/* +=========== +CheckAttack + +The player is in view, so decide to move or launch an attack +Returns FALSE if movement should continue +============ +*/ +float() CheckAttack = +{ + local vector spot1, spot2; + local entity targ; + local float chance; + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + traceline (spot1, spot2, FALSE, self); + + if (trace_ent != targ) + return FALSE; // don't have a clear shot + + if (trace_inopen && trace_inwater) + return FALSE; // sight line crossed contents + + if (enemy_range == RANGE_MELEE) + { // melee attack + if (self.th_melee) + { + if (self.classname == "monster_knight") + knight_attack (); + else + self.th_melee (); + return TRUE; + } + } + +// missile attack + if (!self.th_missile) + return FALSE; + + if (time < self.attack_finished) + return FALSE; + + if (enemy_range == RANGE_FAR) + return FALSE; + + if (enemy_range == RANGE_MELEE) + { + chance = 0.9; + self.attack_finished = 0; + } + else if (enemy_range == RANGE_NEAR) + { + if (self.th_melee) + chance = 0.2; + else + chance = 0.4; + } + else if (enemy_range == RANGE_MID) + { + if (self.th_melee) + chance = 0.05; + else + chance = 0.1; + } + else + chance = 0; + + if (random () < chance) + { + self.th_missile (); + SUB_AttackFinished (2*random()); + return TRUE; + } + + return FALSE; +}; + + +/* +============= +ai_face + +Stay facing the enemy +============= +*/ +void() ai_face = +{ + self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); + ChangeYaw (); +}; + +/* +============= +ai_charge + +The monster is in a melee attack, so get as close as possible to .enemy +============= +*/ +float (entity targ) visible; +float(entity targ) infront; +float(entity targ) range; + +void(float d) ai_charge = +{ + ai_face (); + movetogoal (d); // done in C code... +}; + +void() ai_charge_side = +{ + local vector dtemp; + local float heading; + +// aim to the left of the enemy for a flyby + + self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); + ChangeYaw (); + + makevectors (self.angles); + dtemp = self.enemy.origin - 30*v_right; + heading = vectoyaw(dtemp - self.origin); + + walkmove(heading, 20); +}; + + +/* +============= +ai_melee + +============= +*/ +void() ai_melee = +{ + local vector delta; + local float ldmg; + + if (!self.enemy) + return; // removed before stroke + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 60) + return; + + ldmg = (random() + random() + random()) * 3; + T_Damage (self.enemy, self, self, ldmg); +}; + + +void() ai_melee_side = +{ + local vector delta; + local float ldmg; + + if (!self.enemy) + return; // removed before stroke + + ai_charge_side(); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 60) + return; + if (!CanDamage (self.enemy, self)) + return; + ldmg = (random() + random() + random()) * 3; + T_Damage (self.enemy, self, self, ldmg); +}; + + +//============================================================================= + +/* +=========== +SoldierCheckAttack + +The player is in view, so decide to move or launch an attack +Returns FALSE if movement should continue +============ +*/ +float() SoldierCheckAttack = +{ + local vector spot1, spot2; + local entity targ; + local float chance; + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + traceline (spot1, spot2, FALSE, self); + + if (trace_inopen && trace_inwater) + return FALSE; // sight line crossed contents + + if (trace_ent != targ) + return FALSE; // don't have a clear shot + + +// missile attack + if (time < self.attack_finished) + return FALSE; + + if (enemy_range == RANGE_FAR) + return FALSE; + + if (enemy_range == RANGE_MELEE) + chance = 0.9; + else if (enemy_range == RANGE_NEAR) + chance = 0.4; + else if (enemy_range == RANGE_MID) + chance = 0.05; + else + chance = 0; + + if (random () < chance) + { + self.th_missile (); + SUB_AttackFinished (1 + random()); + if (random() < 0.3) + self.lefty = !self.lefty; + + return TRUE; + } + + return FALSE; +}; +//============================================================================= + +/* +=========== +ShamCheckAttack + +The player is in view, so decide to move or launch an attack +Returns FALSE if movement should continue +============ +*/ +float() ShamCheckAttack = +{ + local vector spot1, spot2; + local entity targ; + + if (enemy_range == RANGE_MELEE) + { + if (CanDamage (self.enemy, self)) + { + self.attack_state = AS_MELEE; + return TRUE; + } + } + + if (time < self.attack_finished) + return FALSE; + + if (!enemy_vis) + return FALSE; + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + if (vlen(spot1 - spot2) > 600) + return FALSE; + + traceline (spot1, spot2, FALSE, self); + + if (trace_inopen && trace_inwater) + return FALSE; // sight line crossed contents + + if (trace_ent != targ) + { + return FALSE; // don't have a clear shot + } + +// missile attack + if (enemy_range == RANGE_FAR) + return FALSE; + + self.attack_state = AS_MISSILE; + SUB_AttackFinished (2 + 2*random()); + return TRUE; +}; + +//============================================================================ + +/* +=========== +OgreCheckAttack + +The player is in view, so decide to move or launch an attack +Returns FALSE if movement should continue +============ +*/ +float() OgreCheckAttack = +{ + local vector spot1, spot2; + local entity targ; + local float chance; + + if (enemy_range == RANGE_MELEE) + { + if (CanDamage (self.enemy, self)) + { + self.attack_state = AS_MELEE; + return TRUE; + } + } + + if (time < self.attack_finished) + return FALSE; + + if (!enemy_vis) + return FALSE; + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + traceline (spot1, spot2, FALSE, self); + + if (trace_inopen && trace_inwater) + return FALSE; // sight line crossed contents + + if (trace_ent != targ) + { + return FALSE; // don't have a clear shot + } + +// missile attack + if (time < self.attack_finished) + return FALSE; + + if (enemy_range == RANGE_FAR) + return FALSE; + + else if (enemy_range == RANGE_NEAR) + chance = 0.10; + else if (enemy_range == RANGE_MID) + chance = 0.05; + else + chance = 0; + + self.attack_state = AS_MISSILE; + SUB_AttackFinished (1 + 2*random()); + return TRUE; +}; + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/fish.qc b/r17/Revamped src/Revamped QC/Primeqc4/fish.qc new file mode 100755 index 00000000..ce6e26ee --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/fish.qc @@ -0,0 +1,186 @@ +$cd id1/models/fish +$origin 0 0 24 +$base base +$skin skin + +$frame attack1 attack2 attack3 attack4 attack5 attack6 +$frame attack7 attack8 attack9 attack10 attack11 attack12 attack13 +$frame attack14 attack15 attack16 attack17 attack18 + +$frame death1 death2 death3 death4 death5 death6 death7 +$frame death8 death9 death10 death11 death12 death13 death14 death15 +$frame death16 death17 death18 death19 death20 death21 + +$frame swim1 swim2 swim3 swim4 swim5 swim6 swim7 swim8 +$frame swim9 swim10 swim11 swim12 swim13 swim14 swim15 swim16 swim17 +$frame swim18 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8 +$frame pain9 + +void() swimmonster_start; + +void() f_stand1 =[ $swim1, f_stand2 ] {ai_stand();}; +void() f_stand2 =[ $swim2, f_stand3 ] {ai_stand();}; +void() f_stand3 =[ $swim3, f_stand4 ] {ai_stand();}; +void() f_stand4 =[ $swim4, f_stand5 ] {ai_stand();}; +void() f_stand5 =[ $swim5, f_stand6 ] {ai_stand();}; +void() f_stand6 =[ $swim6, f_stand7 ] {ai_stand();}; +void() f_stand7 =[ $swim7, f_stand8 ] {ai_stand();}; +void() f_stand8 =[ $swim8, f_stand9 ] {ai_stand();}; +void() f_stand9 =[ $swim9, f_stand10 ] {ai_stand();}; +void() f_stand10 =[ $swim10, f_stand11 ] {ai_stand();}; +void() f_stand11 =[ $swim11, f_stand12 ] {ai_stand();}; +void() f_stand12 =[ $swim12, f_stand13 ] {ai_stand();}; +void() f_stand13 =[ $swim13, f_stand14 ] {ai_stand();}; +void() f_stand14 =[ $swim14, f_stand15 ] {ai_stand();}; +void() f_stand15 =[ $swim15, f_stand16 ] {ai_stand();}; +void() f_stand16 =[ $swim16, f_stand17 ] {ai_stand();}; +void() f_stand17 =[ $swim17, f_stand18 ] {ai_stand();}; +void() f_stand18 =[ $swim18, f_stand1 ] {ai_stand();}; + +void() f_walk1 =[ $swim1, f_walk2 ] {ai_walk(8);}; +void() f_walk2 =[ $swim2, f_walk3 ] {ai_walk(8);}; +void() f_walk3 =[ $swim3, f_walk4 ] {ai_walk(8);}; +void() f_walk4 =[ $swim4, f_walk5 ] {ai_walk(8);}; +void() f_walk5 =[ $swim5, f_walk6 ] {ai_walk(8);}; +void() f_walk6 =[ $swim6, f_walk7 ] {ai_walk(8);}; +void() f_walk7 =[ $swim7, f_walk8 ] {ai_walk(8);}; +void() f_walk8 =[ $swim8, f_walk9 ] {ai_walk(8);}; +void() f_walk9 =[ $swim9, f_walk10 ] {ai_walk(8);}; +void() f_walk10 =[ $swim10, f_walk11 ] {ai_walk(8);}; +void() f_walk11 =[ $swim11, f_walk12 ] {ai_walk(8);}; +void() f_walk12 =[ $swim12, f_walk13 ] {ai_walk(8);}; +void() f_walk13 =[ $swim13, f_walk14 ] {ai_walk(8);}; +void() f_walk14 =[ $swim14, f_walk15 ] {ai_walk(8);}; +void() f_walk15 =[ $swim15, f_walk16 ] {ai_walk(8);}; +void() f_walk16 =[ $swim16, f_walk17 ] {ai_walk(8);}; +void() f_walk17 =[ $swim17, f_walk18 ] {ai_walk(8);}; +void() f_walk18 =[ $swim18, f_walk1 ] {ai_walk(8);}; + +void() f_run1 =[ $swim1, f_run2 ] {ai_run(12); + if (random() < 0.5) + sound (self, CHAN_VOICE, "fish/idle.wav", 1, ATTN_NORM); +}; +void() f_run2 =[ $swim3, f_run3 ] {ai_run(12);}; +void() f_run3 =[ $swim5, f_run4 ] {ai_run(12);}; +void() f_run4 =[ $swim7, f_run5 ] {ai_run(12);}; +void() f_run5 =[ $swim9, f_run6 ] {ai_run(12);}; +void() f_run6 =[ $swim11, f_run7 ] {ai_run(12);}; +void() f_run7 =[ $swim13, f_run8 ] {ai_run(12);}; +void() f_run8 =[ $swim15, f_run9 ] {ai_run(12);}; +void() f_run9 =[ $swim17, f_run1 ] {ai_run(12);}; + +void() fish_melee = +{ + local vector delta; + local float ldmg; + + if (!self.enemy) + return; // removed before stroke + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 60) + return; + + sound (self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM); + ldmg = (random() + random()) * 3; + T_Damage (self.enemy, self, self, ldmg); +}; + +void() f_attack1 =[ $attack1, f_attack2 ] {ai_charge(10);}; +void() f_attack2 =[ $attack2, f_attack3 ] {ai_charge(10);}; +void() f_attack3 =[ $attack3, f_attack4 ] {fish_melee();}; +void() f_attack4 =[ $attack4, f_attack5 ] {ai_charge(10);}; +void() f_attack5 =[ $attack5, f_attack6 ] {ai_charge(10);}; +void() f_attack6 =[ $attack6, f_attack7 ] {ai_charge(10);}; +void() f_attack7 =[ $attack7, f_attack8 ] {ai_charge(10);}; +void() f_attack8 =[ $attack8, f_attack9 ] {ai_charge(10);}; +void() f_attack9 =[ $attack9, f_attack10] {fish_melee();}; +void() f_attack10 =[ $attack10, f_attack11] {ai_charge(10);}; +void() f_attack11 =[ $attack11, f_attack12] {ai_charge(10);}; +void() f_attack12 =[ $attack12, f_attack13] {ai_charge(10);}; +void() f_attack13 =[ $attack13, f_attack14] {ai_charge(10);}; +void() f_attack14 =[ $attack14, f_attack15] {ai_charge(10);}; +void() f_attack15 =[ $attack15, f_attack16] {fish_melee();}; +void() f_attack16 =[ $attack16, f_attack17] {ai_charge(10);}; +void() f_attack17 =[ $attack17, f_attack18] {ai_charge(10);}; +void() f_attack18 =[ $attack18, f_run1 ] {ai_charge(10);}; + +void() f_death1 =[ $death1, f_death2 ] { +sound (self, CHAN_VOICE, "fish/death.wav", 1, ATTN_NORM); +}; +void() f_death2 =[ $death2, f_death3 ] {}; +void() f_death3 =[ $death3, f_death4 ] {}; +void() f_death4 =[ $death4, f_death5 ] {}; +void() f_death5 =[ $death5, f_death6 ] {}; +void() f_death6 =[ $death6, f_death7 ] {}; +void() f_death7 =[ $death7, f_death8 ] {}; +void() f_death8 =[ $death8, f_death9 ] {}; +void() f_death9 =[ $death9, f_death10 ] {}; +void() f_death10 =[ $death10, f_death11 ] {}; +void() f_death11 =[ $death11, f_death12 ] {}; +void() f_death12 =[ $death12, f_death13 ] {}; +void() f_death13 =[ $death13, f_death14 ] {}; +void() f_death14 =[ $death14, f_death15 ] {}; +void() f_death15 =[ $death15, f_death16 ] {}; +void() f_death16 =[ $death16, f_death17 ] {}; +void() f_death17 =[ $death17, f_death18 ] {}; +void() f_death18 =[ $death18, f_death19 ] {}; +void() f_death19 =[ $death19, f_death20 ] {}; +void() f_death20 =[ $death20, f_death21 ] {}; +void() f_death21 =[ $death21, f_death21 ] {self.solid = SOLID_NOT;}; + +void() f_pain1 =[ $pain1, f_pain2 ] {}; +void() f_pain2 =[ $pain2, f_pain3 ] {ai_pain(6);}; +void() f_pain3 =[ $pain3, f_pain4 ] {ai_pain(6);}; +void() f_pain4 =[ $pain4, f_pain5 ] {ai_pain(6);}; +void() f_pain5 =[ $pain5, f_pain6 ] {ai_pain(6);}; +void() f_pain6 =[ $pain6, f_pain7 ] {ai_pain(6);}; +void() f_pain7 =[ $pain7, f_pain8 ] {ai_pain(6);}; +void() f_pain8 =[ $pain8, f_pain9 ] {ai_pain(6);}; +void() f_pain9 =[ $pain9, f_run1 ] {ai_pain(6);}; + +void(entity attacker, float damage) fish_pain = +{ + +// fish allways do pain frames + f_pain1 (); +}; + + + +/*QUAKED monster_fish (1 0 0) (-16 -16 -24) (16 16 24) Ambush +*/ +void() monster_fish = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/fish.mdl"); + + precache_sound2 ("fish/death.wav"); + precache_sound2 ("fish/bite.wav"); + precache_sound2 ("fish/idle.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/fish.mdl"); + + setsize (self, '-16 -16 -24', '16 16 24'); + self.health = 25; + + self.th_stand = f_stand1; + self.th_walk = f_walk1; + self.th_run = f_run1; + self.th_die = f_death1; + self.th_pain = fish_pain; + self.th_melee = f_attack1; + + swimmonster_start (); +}; + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/flag.qc b/r17/Revamped src/Revamped QC/Primeqc4/flag.qc new file mode 100755 index 00000000..44daa003 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/flag.qc @@ -0,0 +1,8 @@ +/*QUAKED item_deathball (.3 .3 1) (0 0 0) (32 32 32) +*/ +void() deathball_touch; + +void() item_deathball = +{ + self.touch = deathball_touch; +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot.qc b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot.qc new file mode 100755 index 00000000..a14716e6 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot.qc @@ -0,0 +1,1219 @@ + +/* +====================================== +FrikBot X (Version 0.10.0) +====================================== + +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. + + +====================================== +These installation instructions only apply to Normal Quake (as does this +entire file). For QuakeWorld, please refer to bot_qw.qc + +-------------------------------------- +To install on a new mod, do all this: +-------------------------------------- +Place all included bot*.qc files in the subdirectory "frikbot" +in your source folder, then... + +* Add the following lines to progs.src right after the defs.qc line +frikbot/bot.qc +frikbot/bot_way.qc +frikbot/bot_fight.qc +frikbot/bot_ai.qc +frikbot/bot_misc.qc +frikbot/bot_phys.qc +frikbot/bot_move.qc +frikbot/bot_ed.qc + +-------------------------------------- +* Comment out the following functions in defs.qc +sound, stuffcmd, sprint, aim, centerprint, setspawnparms +WriteByte, WriteChar, WriteShort, WriteLong, WriteCoord +WriteAngle, WriteString, WriteEntity +-------------------------------------- +* Add this to worldspawn() in world.qc, right at the very top, before InitBodyQue(); +BotInit(); // FrikBot +-------------------------------------- +* add this line to StartFrame() in world.qc, at the very top +BotFrame(); // FrikBot +-------------------------------------- +* Add these two lines to PlayerPreThink in client.qc at the very top +if (BotPreFrame()) // FrikBot + return; +-------------------------------------- +* Add this line to PlayerPostThink in client.qc at the very top +if (BotPostFrame()) // FrikBot + return; +-------------------------------------- +* Add the following line to the very top of Client Connect in client.qc +ClientInRankings(); // FrikBot +-------------------------------------- +* Add these lines to the very top of ClientDisconnect in client.qc +ClientDisconnected(); // FrikBot +-------------------------------------- +*/ + +void() bot_map_load = +{ + // place your qc loaded waypoints here +/* + if (mapname == "dm1") + map_dm1(); + else if (mapname == "dm2") + map_dm2(); + else if (mapname == "dm3") + map_dm3(); + else if (mapname == "dm4") + map_dm4(); + else if (mapname == "dm5") + map_dm5(); + else if (mapname == "dm6") + map_dm6(); +*/ + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Variables and shtuff + +bot.qc has become pretty much a header file +for all variable in the bot... + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +// ----- entity fields --- +.float wallhug, keys, oldkeys, ishuman; +.float b_frags, b_clientno, b_shirt, b_pants; +.float ai_time, b_sound, missile_speed; +.float portal_time, b_skill, switch_wallhug; +.float b_aiflags, b_num, b_chattime; +.float b_menu, b_menu_time, b_menu_value; +.float route_failed, dyn_flags, dyn_time; +.float dyn_plat; +.entity temp_way, last_way, phys_obj; +.entity target1, target2, target3, target4; +.entity _next, _last; +.entity current_way; +.vector b_angle, mouse_emu, obs_dir; +.vector movevect, b_dir; +.vector dyn_dest; + +// --------defines----- +float SVC_UPDATENAME = 13; +float SVC_UPDATEFRAGS = 14; +float SVC_UPDATECOLORS = 17; + +// used for the physics & movement AI +float KEY_MOVEUP = 1; +float KEY_MOVEDOWN = 2; +float KEY_MOVELEFT = 4; +float KEY_MOVERIGHT = 8; +float KEY_MOVEFORWARD = 16; +float KEY_MOVEBACK = 32; +float KEY_LOOKUP = 64; +float KEY_LOOKDOWN = 128; +float KEY_LOOKLEFT = 256; +float KEY_LOOKRIGHT = 512; + +// these are aiflags for waypoints +// some overlap to the bot +float AI_TELELINK_1 = 1; // link type +float AI_TELELINK_2 = 2; // link type +float AI_TELELINK_3 = 4; // link type +float AI_TELELINK_4 = 8; // link type +float AI_DOORFLAG = 16; // read ahead +float AI_PRECISION = 32; // read ahead + point +float AI_SURFACE = 64; // point +float AI_BLIND = 128; // read ahead + point +float AI_JUMP = 256; // point + ignore +float AI_DIRECTIONAL = 512; // read ahead + ignore +float AI_PLAT_BOTTOM = 1024; // read ahead +float AI_RIDE_TRAIN = 2048; // read ahead +float AI_SUPER_JUMP = 4096; // point + ignore + route test +float AI_SNIPER = 8192; // point type +float AI_AMBUSH = 16384; // point type +float AI_DOOR_NO_OPEN = 32768; // read ahead +float AI_DIFFICULT = 65536; // route test +float AI_TRACE_TEST = 131072; // route test + +// these are flags for bots/players (dynamic/editor flags) +float AI_OBSTRUCTED = 1; +float AI_HOLD_SELECT = 2; +float AI_ROUTE_FAILED = 2; +float AI_WAIT = 4; +float AI_DANGER = 8; + + +// addition masks +float AI_POINT_TYPES = 29152; +float AI_READAHEAD_TYPES = 36528; +float AI_IGNORE_TYPES = 4864; + +float WM_UNINIT = 0; +float WM_DYNAMIC = 1; +float WM_LOADING = 2; +float WM_LOADED = 3; +float WM_EDITOR = 4; +float WM_EDITOR_DYNAMIC = 5; +float WM_EDITOR_DYNLINK = 6; + + +float OPT_SAVEBOTS = 1; +float OPT_NOCHAT = 2; + +// -------globals----- +float active_clients; +float max_clients, real_frametime; +float bot_count, b_options; +float waypoint_mode, dump_mode; +float waypoints, direct_route; +float sv_friction, sv_gravity; +float sv_accelerate, sv_maxspeed, sv_stopspeed; +entity fixer; +entity route_table; +entity b_temp1, b_temp2, b_temp3; +entity player_head, phys_head, way_head; +float busy_waypoints; +float saved_bots, saved_skills1, saved_skills2, current_bots; + +// -------ProtoTypes------ +// external +void() ClientConnect; +void() ClientDisconnect; +void() SetNewParms; + +// rankings +float(float clientno) ClientBitFlag; +float() ClientNextAvailable; +void(float whichteam, float whatbot, float whatskill) BotConnect; +void(entity bot) BotDisconnect; +void(float clientno) BotInvalidClientNo; +void(entity who) UpdateClient; + +// waypointing +void() DynamicWaypoint; +entity(vector org) make_waypoint; +void() ClearAllWays; +void() FixWaypoints; +float() begin_route; +void(entity this, float direct) bot_get_path; +void() WaypointThink; +entity(entity start) FindWayPoint; + +// physics & movement +float(entity e) bot_can_rj; +void() bot_jump; +void() frik_bot_roam; +float(vector weird) frik_walkmove; +void() frik_movetogoal; +void() frik_obstacles; +float(float flag) frik_recognize_plat; +float(vector sdir) frik_KeysForDir; +void(vector whichway, float danger) frik_obstructed; +void() SV_Physics_Client; +void() SV_ClientThink; +void() CL_KeyMove; + +// ai & misc +string() PickARandomName; +float(entity targ) fov; +float(float y1, float y2) angcomp; +float(entity targ1, entity targ2) wisible; +float(entity targ) sisible; +float(entity targ) fisible; +vector(entity ent) realorigin; +void(entity ent) target_drop; +void(entity ent) target_add; +void() KickABot; +void() BotImpulses; +void(entity targ, float success) bot_lost; +string(float r) BotName; +float(float v) frik_anglemod; +void() bot_chat; +void(float tpic) bot_start_topic; + + +// editor stuffs + +void() bot_way_edit; +void() bot_menu_display; + + +// ----------Commands--------- +void(entity e, float chan, string samp, float vol, float atten) frik_sound = #8; +void(entity client, string s) frik_stuffcmd = #21; +void(entity client, string s) frik_sprint = #24; +vector(entity e, float sped) frik_aim = #44; +void(entity client, string s) frik_centerprint = #73; +void(entity e) frik_setspawnparms = #78; +void(float to, float f) frik_WriteByte = #52; +void(float to, float f) frik_WriteChar = #53; +void(float to, float f) frik_WriteShort = #54; +void(float to, float f) frik_WriteLong = #55; +void(float to, float f) frik_WriteCoord = #56; +void(float to, float f) frik_WriteAngle = #57; +void(float to, string s) frik_WriteString = #58; +void(float to, entity s) frik_WriteEntity = #59; + +void(entity client, string s1, string s2, string s3, string s4, string s5, string s6, string s7) +frik_big_centerprint = #73; + +//---------------------------------------------------------------------------- + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Function redclarations. These allow function +designed to work for clients (sprint, so forth) +to mainly not complain when working with a bot + +Although these shouldn't be needed anymore, +as the bots truly are clients now, if you don't +stop the SZ_ buffer from filling up by disabling +direct messages to the bots, it crashes quake :-( + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(entity client, string s) stuffcmd = +{ + if (client.ishuman == 1) + frik_stuffcmd(client, s); + b_temp1 = player_head; + + while(b_temp1) + { + if (b_temp1.classname == "botcam") + { + if ((b_temp1.enemy == client) && b_temp1.ishuman) + frik_stuffcmd(b_temp1, s); + } + b_temp1 = b_temp1._next; + } +}; + +void(entity e) setspawnparms = +{ + if (e.ishuman == 1) + frik_setspawnparms(e); + else + { + b_temp1 = player_head; + while(b_temp1) + { + if (b_temp1.ishuman) + { + frik_setspawnparms(b_temp1); + return; + } + b_temp1 = b_temp1._next; + } + SetNewParms(); + } +}; +void(entity client, string s) sprint = +{ + if (client.ishuman == 1) + frik_sprint(client, s); + b_temp1 = player_head; + + while(b_temp1) + { + if (b_temp1.classname == "botcam") + { + if ((b_temp1.enemy == client) && b_temp1.ishuman) + frik_sprint(b_temp1, s); + } + b_temp1 = b_temp1._next; + } + +}; +void(entity client, string s) centerprint = +{ + if (client.ishuman == 1) + frik_centerprint(client, s); + b_temp1 = player_head; + + while(b_temp1) + { + if (b_temp1.classname == "botcam") + { + if ((b_temp1.enemy == client) && b_temp1.ishuman) + frik_centerprint(b_temp1, s); + } + b_temp1 = b_temp1._next; + } +}; + +vector(entity e, float sped) aim = +{ + e.missile_speed = sped; + return frik_aim(e, sped); +}; + +void(entity e, float chan, string samp, float vol, float atten) sound = +{ + + frik_sound(e, chan, samp, vol, atten); + if (samp == "items/inv3.wav") + return; + else if (e.classname == "player") + e.b_sound = time + 1; + else if (other.classname == "player") + other.b_sound = time + 1; + +}; +void(float to, float f) WriteByte = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteByte(to, f); +}; +void(float to, float f) WriteChar = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteChar(to, f); +}; +void(float to, float f) WriteShort = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteShort(to, f); +}; +void(float to, float f) WriteLong = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteLong(to, f); +}; +void(float to, float f) WriteCoord = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteCoord(to, f); +}; +void(float to, float f) WriteAngle = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteAngle(to, f); +}; +void(float to, string s) WriteString = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteString(to, s); +}; +void(float to, entity s) WriteEntity = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteEntity(to, s); +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Cam, see what the bot sees (or any other player) + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float() botcam = +{ + if (self.classname != "botcam") + return FALSE; + setorigin(self, self.enemy.origin); + self.items = self.enemy.items; + self.weapon = self.enemy.weapon; + self.weaponmodel = self.enemy.weaponmodel; + self.currentammo = self.enemy.currentammo; + self.weaponframe = self.enemy.weaponframe; + self.ammo_shells = self.enemy.ammo_shells; + self.ammo_nails = self.enemy.ammo_nails; + self.ammo_rockets= self.enemy.ammo_rockets; + self.ammo_cells = self.enemy.ammo_cells; + self.view_ofs = self.enemy.view_ofs; + self.health = self.enemy.health; + self.armorvalue = self.enemy.armorvalue; + self.dmg_take = self.enemy.dmg_take; + self.dmg_save = self.enemy.dmg_save; + self.dmg_inflictor = self.enemy.dmg_inflictor; + self.punchangle = self.enemy.punchangle; + self.deadflag = self.enemy.deadflag; + msg_entity = self; + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE, self.enemy); + WriteByte (MSG_ONE, 10); + WriteAngle (MSG_ONE,self.enemy.v_angle_x); + WriteAngle (MSG_ONE,self.enemy.v_angle_y); + WriteAngle (MSG_ONE,self.enemy.v_angle_z); + self.modelindex = 0; + + self.impulse = 0; + return TRUE; + +}; + +void() botcam_u = +{ + + // sloppy cycling code + if (self.classname != "botcam") + { + self.enemy = player_head; + } + else + { + do + self.enemy = self.enemy._next; + while (self.enemy.classname == "botcam"); + } + if (self.enemy == self) + { + do + self.enemy = self.enemy._next; + while (self.enemy.classname == "botcam"); + } + + self.classname = "botcam"; + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_NONE; + self.takedamage = DAMAGE_NO; + + + if (!self.enemy) + { + sprint(self, "No one left to track!\n"); + msg_entity = self; + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE, self); + PutClientInServer(); + return; + } + if (!self.enemy.ishuman) + { + self.enemy.dmg_take = 0; + self.enemy.dmg_save = 0; + } + sprint(self, "Now tracking "); + sprint(self, self.enemy.netname); + sprint(self, "\n"); +}; + + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Stuff mentioned up top +it just links the bot into the mod + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClientFixRankings = +{ + local float cno; + if (self.switch_wallhug > time) + return; + self.switch_wallhug = 0; + + b_temp2 = nextent(world); + cno = 0; + + while (cno < max_clients) + { + if ((!b_temp2.ishuman) && (active_clients & ClientBitFlag(cno))) + UpdateClient(b_temp2); + cno = cno + 1; + b_temp2 = nextent(b_temp2); + } +}; + +void() ClientInRankings = +{ + local float cno; + if (player_head) + player_head._last = self; + self._next = player_head; + player_head = self; + + if (!self.phys_obj) + { + b_temp2 = phys_head; + while (b_temp2 != world && b_temp2.owner != self) + b_temp2 = b_temp2._next; + self.phys_obj = b_temp2; + } + + if (self.ishuman == 2) + { + self.ishuman = FALSE; + return; + } + cno = self.colormap - 1; + BotInvalidClientNo (cno); + active_clients = active_clients | ClientBitFlag(cno); + + self.b_clientno = cno; + self.ishuman = TRUE; + self.switch_wallhug = time + 1; +}; + + +void() ClientDisconnected = +{ + if (player_head == self) + player_head = self._next; + if (self._next) + self._next._last = self._last; + if (self._last) + self._last._next = self._next; + active_clients = active_clients - active_clients & ClientBitFlag(self.b_clientno); +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotPreFrame & BotPostFrame, used to make the +bot easier to install + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float () BotPreFrame = +{ + if (self.b_clientno == -1) + return TRUE; + if (self.ishuman) + { + if (self.switch_wallhug) + ClientFixRankings(); + if (self.classname == "botcam") + return TRUE; + } + if (self.b_frags != self.frags) + { + + if (self.b_frags > self.frags) + { + if (pointcontents(self.origin) == CONTENT_LAVA) + bot_start_topic(10); + else + bot_start_topic(9); + } + else + bot_start_topic(2); + self.b_frags = self.frags; + } + DynamicWaypoint(); + return FALSE; +}; +float () BotPostFrame = +{ + if (self.b_clientno == -1) + return TRUE; + if (self.ishuman) + { + + if (waypoint_mode > WM_LOADED) + bot_menu_display(); + + BotImpulses(); + + if (botcam()) + return TRUE; + } + return FALSE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Chat code + +The rest of this code is in bot_misc.qc + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(string h) BotSay = // simulate talking by composing a 'chat' message +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, self.netname); + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 2); + WriteString(MSG_ALL, h); +}; +void() BotSayInit = +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, self.netname); +}; +void(string h) BotSay2 = +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 2); + WriteString(MSG_ALL, h); +}; +void(string h) BotSayTeam = +{ + local entity t; + if (!teamplay) + return; + t = player_head; + while(t) + { + if (t.team == self.team) + { + msg_entity = t; + WriteByte(MSG_ONE, 8); + WriteByte(MSG_ONE, 1); + WriteByte(MSG_ONE, 40); + WriteString(MSG_ONE, self.netname); + WriteByte(MSG_ONE, 8); + WriteByte(MSG_ONE, 2); + WriteByte(MSG_ONE, 41); + WriteString(MSG_ONE, h); + } + t = t._next; + } +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotInit + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void() BotInit = +{ + local entity ent, fisent; + local float numents; + + // spawn entities for the physics + ent = nextent(world); + max_clients = 0; + + while(ent != world) + { + max_clients = max_clients + 1; + ent = nextent(ent); + } + + ent = nextent(world); + fisent = world; + while (numents < max_clients) + { + + phys_head = spawn(); + if (fisent) + fisent._next = phys_head; + phys_head._last = fisent; + fisent = phys_head; + ent.phys_obj = phys_head; + phys_head.classname = "phys_obj"; + phys_head.owner = ent; + numents = numents + 1; + ent = nextent(ent); + } + precache_model("progs/s_light.spr"); + precache_model("progs/s_bubble.spr"); + // the bots return! + b_options = cvar("saved1"); + if (coop || (b_options & OPT_SAVEBOTS)) + { + saved_bots = cvar("scratch1"); + saved_skills1 = cvar("scratch2"); + saved_skills2 = cvar("scratch3"); + } + cvar_set ("saved4", "0"); + localcmd("exec maps/"); + localcmd(mapname); + localcmd(".way\n"); + waypoint_mode = WM_DYNAMIC; + bot_map_load(); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Rankings 'utilities'. Written by Alan Kivlin, +this code just fools clients by sending precisely +the same network messages as when a real player +signs on to the server. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void(entity who) UpdateClient = +{ + WriteByte (MSG_ALL, SVC_UPDATENAME); + WriteByte (MSG_ALL, who.b_clientno); + WriteString (MSG_ALL, who.netname); + WriteByte (MSG_ALL, SVC_UPDATECOLORS); + WriteByte (MSG_ALL, who.b_clientno); + WriteByte (MSG_ALL, who.b_shirt * 16 + who.b_pants); + WriteByte (MSG_ALL, SVC_UPDATEFRAGS); + WriteByte (MSG_ALL, who.b_clientno); + WriteShort (MSG_ALL, who.frags); +}; + +float(float clientno) ClientBitFlag = +{ + // bigger, but faster + if (clientno == 0) + return 1; + else if (clientno == 1) + return 2; + else if (clientno == 2) + return 4; + else if (clientno == 3) + return 8; + else if (clientno == 4) + return 16; + else if (clientno == 5) + return 32; + else if (clientno == 6) + return 64; + else if (clientno == 7) + return 128; + else if (clientno == 8) + return 256; + else if (clientno == 9) + return 512; + else if (clientno == 10) + return 1024; + else if (clientno == 11) + return 2048; + else if (clientno == 12) + return 4096; + else if (clientno == 13) + return 8192; + else if (clientno == 14) + return 16384; + else if (clientno == 15) + return 32768; + return 0; +}; + +float() ClientNextAvailable = +{ + local float clientno; + + clientno = max_clients; + while(clientno > 0) + { + clientno = clientno - 1; + + if(!(active_clients & ClientBitFlag(clientno))) + return clientno; + } + + return -1; +}; + + +void(entity e1, entity e2, float flag) DeveloperLightning = +{ + // used to show waypoint links for debugging + WriteByte (MSG_BROADCAST, 23); + if (flag) + WriteByte (MSG_BROADCAST, 6); + else + WriteByte (MSG_BROADCAST, 13); + WriteEntity (MSG_BROADCAST, e2); + WriteCoord (MSG_BROADCAST, e1.origin_x); + WriteCoord (MSG_BROADCAST, e1.origin_y); + WriteCoord (MSG_BROADCAST, e1.origin_z); + WriteCoord (MSG_BROADCAST, e2.origin_x); + WriteCoord (MSG_BROADCAST, e2.origin_y); + WriteCoord (MSG_BROADCAST, e2.origin_z); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Find Another Color + +Team finding code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float(float tcolor) FindAnotherColor = +{ + local float bestbet, scolor, pcount, bestp; + bestbet = -1; + bestp = 16; + while(scolor < 14) + { + if (scolor != tcolor) + { + b_temp2 = player_head; + pcount = 0; + while(b_temp2 != world) + { + if (b_temp2.team == scolor + 1) + pcount = pcount + 1; + b_temp2 = b_temp2._next; + } + if ((pcount < bestp) && pcount) + { + bestbet = scolor; + bestp = pcount; + } + } + scolor = scolor + 1; + } + if (bestbet < 0) + { + bestbet = tcolor; + while (bestbet == tcolor) + { + bestbet = floor(random() * 13); + } + } + return bestbet; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotConnect and related functions. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +entity(float num) GetClientEntity = +{ + local entity upsy; + upsy = world; + num = num + 1; + while (num > 0) + { + num = num - 1; + upsy = nextent(upsy); + } + return upsy; +}; + +void(float whichteam, float whatbot, float whatskill) BotConnect = +{ + local float f; + local string h; + local entity uself; + + f = ClientNextAvailable(); + uself = self; + if(f == -1) + { + bprint("Unable to connect a bot, server is full.\n"); + return; + } + + // chat thing + + active_clients = active_clients | ClientBitFlag(f); + bot_count = bot_count + 1; + self = GetClientEntity(f); + if (!saved_bots) + bot_start_topic(1); + self.b_clientno = f; + self.colormap = f + 1; + if (whatbot) + self.netname = BotName(whatbot); + else + self.netname = PickARandomName(); + + + // players can set skill all weird, so leave these checks in + whatskill = rint(whatskill); + if (whatskill > 3) + whatskill = 3; + else if (whatskill < 0) + whatskill = 0; + self.b_skill = whatskill; + + if (teamplay && !coop) + { + if (whichteam) + self.b_pants = FindAnotherColor(uself.team - 1); + else + self.b_pants = uself.team - 1; + self.b_shirt = self.b_pants; + } + + self.team = self.b_pants + 1; + UpdateClient(self); + SetNewParms(); + self.ishuman = 2; + ClientConnect(); + PutClientInServer(); + + // this is risky... could corrupt .way files if done wrong + // If you're not the gambling type, comment this out + + f = ClientBitFlag(self.b_num - 1); + current_bots = current_bots | f; + + if (self.b_num <= 8) + saved_skills1 = (saved_skills1 & (65536 - (3 * f)) | (self.b_skill * f)); + else + { + f = ClientBitFlag(self.b_num - 9); + saved_skills2 = (saved_skills2 & (65536 - (3 * f)) | (self.b_skill * f)); + } + + h = ftos(current_bots); + cvar_set("scratch1", h); + h = ftos(saved_skills1); + cvar_set("scratch2", h); + h = ftos(saved_skills2); + cvar_set("scratch3", h); + self = uself; + +}; + +void(entity bot) BotDisconnect = +{ + local string h; + local entity uself; + uself = self; + self = bot; + + bot_count = bot_count - 1; + current_bots = current_bots - (current_bots & ClientBitFlag(self.b_num)); + h = ftos(current_bots); + cvar_set("scratch1", h); + + + ClientDisconnect(); + + if (self.b_clientno != -1) + { + // the bot's client number is not in use by a real player so we + // must remove it's entry in the rankings + // Quake engine sets all fields to 0, can only do the most important here + self.b_frags = self.frags = 0; + self.netname = ""; + self.classname = ""; + self.health = 0; + self.items = 0; + self.armorvalue = 0; + self.weaponmodel = ""; + self.b_pants = 0; + self.b_shirt = 0; + self.ammo_shells = self.ammo_nails = self.ammo_rockets = self.ammo_cells = 0; + UpdateClient(self); + active_clients = active_clients - (active_clients & ClientBitFlag(self.b_clientno)); + self.b_clientno = -1; + } + self = uself; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotInvalidClientNo +kicks a bot if a player connects and takes the bot's space + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(float clientno) BotInvalidClientNo = +{ + local entity bot; + + bot = GetClientEntity(clientno); + if(bot.b_clientno > 0) + { + if (!bot.ishuman) + { + bot.b_clientno = -1; + BotDisconnect(bot); + active_clients = active_clients | ClientBitFlag(self.b_clientno); + BotConnect(0, bot.b_num, bot.b_skill); + return; + } + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Loading from file + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void() LoadWaypoint = +{ + local vector org; + local entity tep; + local float r; + org_x = cvar("saved1"); + org_y = cvar("saved2"); + org_z = cvar("saved3"); + + tep = make_waypoint(org); + + r = cvar("saved4"); + + tep.b_aiflags = floor(r / 4); + tep.b_pants = cvar("scratch1"); + tep.b_skill = cvar("scratch2"); + tep.b_shirt = cvar("scratch3"); + tep.b_frags = cvar("scratch4"); +}; + +void() bot_return = +{ + if (time > 2) + { + if ((waypoint_mode == WM_DYNAMIC) || (waypoint_mode == WM_LOADED)) + { + // minor precaution + + if (saved_bots & 1) BotConnect(0, 1, saved_skills1 & 3); + if (saved_bots & 2) BotConnect(0, 2, (saved_skills1 & 12) / 4); + if (saved_bots & 4) BotConnect(0, 3, (saved_skills1 & 48) / 16); + if (saved_bots & 8) BotConnect(0, 4, (saved_skills1 & 192) / 64); + if (saved_bots & 16) BotConnect(0, 5, (saved_skills1 & 768) / 256); + if (saved_bots & 32) BotConnect(0, 6, (saved_skills1 & 3072) / 1024); + if (saved_bots & 64) BotConnect(0, 7, (saved_skills1 & 12288) / 4096); + if (saved_bots & 128) BotConnect(0, 8, (saved_skills1 & 49152) / 16384); + if (saved_bots & 256) BotConnect(0, 9, saved_skills2 & 3); + if (saved_bots & 512) BotConnect(0, 10, (saved_skills2 & 12) / 4); + if (saved_bots & 1024) BotConnect(0, 11, (saved_skills2& 48) / 16); + if (saved_bots & 2048) BotConnect(0, 12, (saved_skills2 & 192) / 64); + if (saved_bots & 4096) BotConnect(0, 13, (saved_skills2 & 768) / 256); + if (saved_bots & 8192) BotConnect(0, 14, (saved_skills2 & 3072) / 1024); + if (saved_bots & 16384) BotConnect(0, 15, (saved_skills2 & 12288) / 4096); + if (saved_bots & 32768) BotConnect(0, 16, (saved_skills2 & 49152) / 16384); + saved_bots = 0; + } + } +}; + + +void() WaypointWatch = +{ + // Waypoint Baywatch + local float bigboobs; + local string h; + + if (max_clients < 2) + return; + if (waypoint_mode != WM_UNINIT) + { + bigboobs = cvar("saved4"); + if (bigboobs != 0) + { + if ((bigboobs & 3) == 1) + ClearAllWays(); + else if ((bigboobs & 3) == 3) + { + FixWaypoints(); + h = ftos(b_options); + cvar_set("saved1", h); + cvar_set("saved4", "0"); + cvar_set("scratch1", "0"); + waypoint_mode = WM_LOADED; + return; + } + LoadWaypoint(); + waypoint_mode = WM_LOADING; + cvar_set("saved4", "0"); + } + } +}; +void() BotFrame = +{ + local float num; + + // for the sake of speed + sv_maxspeed = cvar("sv_maxspeed"); + sv_gravity = cvar("sv_gravity"); + sv_friction = cvar("sv_friction"); + sv_accelerate = cvar("sv_accelerate"); + sv_stopspeed = cvar("sv_stopspeed"); + real_frametime = frametime; // in NQ this is alright + + self = nextent(world); + num = 0; + while (num < max_clients) + { + if (self.ishuman == FALSE) + { + if (active_clients & ClientBitFlag(num)) + { + frik_obstacles(); + CL_KeyMove(); + SV_ClientThink(); + SV_Physics_Client(); + } + } + self = nextent(self); + num = num + 1; + } + WaypointWatch(); + + if (saved_bots) + bot_return(); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Impulses. Allows the player to perform bot +related functions. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() BotImpulses = +{ + local float f; + + if (self.impulse == 100) + { + f = cvar("skill"); + BotConnect(0, 0, f); + } + else if (self.impulse == 101) + { + f = cvar("skill"); + BotConnect(1, 0, f); + } + else if (self.impulse == 102) + KickABot(); + else if (self.impulse == 103) + botcam_u(); + else if (self.impulse == 104) + bot_way_edit(); + else + return; + + self.impulse = 0; +}; + + + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_ai.qc b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_ai.qc new file mode 100755 index 00000000..17f7dfc1 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_ai.qc @@ -0,0 +1,974 @@ +/*********************************************** +* * +* FrikBot General AI * +* "The I'd rather be playing Quake AI" * +* * +***********************************************/ + +/* +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. +*/ + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +target_onstack + +checks to see if an entity is on the bot's stack + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float(entity scot) target_onstack = +{ + if (scot == world) + return FALSE; + else if (self.target1 == scot) + return 1; + else if (self.target2 == scot) + return 2; + else if (self.target3 == scot) + return 3; + else if (self.target4 == scot) + return 4; + else + return FALSE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +target_add + +adds a new entity to the stack, since it's a +LIFO stack, this will be the bot's new target1 + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity ent) target_add = +{ + if (ent == world) + return; + if (target_onstack(ent)) + return; + self.target4 = self.target3; + self.target3 = self.target2; + self.target2 = self.target1; + self.target1 = ent; + self.search_time = time + 5; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +target_drop + +Removes an entity from the bot's target stack. +The stack will empty everything up to the object +So if you have target2 item_health, target1 +waypoint, and you drop the health, the waypoint +is gone too. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity ent) target_drop = +{ + local float tg; + + tg = target_onstack(ent); + if (tg == 1) + { + self.target1 = self.target2; + self.target2 = self.target3; + self.target3 = self.target4; + self.target4 = world; + } + else if (tg == 2) + { + self.target1 = self.target3; + self.target2 = self.target4; + self.target3 = self.target4 = world; + } + else if (tg == 3) + { + self.target1 = self.target4; + self.target2 = self.target3 = self.target4 = world; + } + else if (tg == 4) + self.target1 = self.target2 = self.target3 = self.target4 = world; + self.search_time = time + 5; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_lost + +Bot has lost its target. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity targ, float success) bot_lost = +{ + if (!targ) + return; + + target_drop(targ); + if (targ.classname == "waypoint") + targ.b_sound = targ.b_sound - (targ.b_sound & ClientBitFlag(self.b_clientno)); + + // find a new route + if (!success) + { + self.target1 = self.target2 = self.target3 = self.target4 = world; + self.last_way = FindWayPoint(self.current_way); + ClearMyRoute(); + self.b_aiflags = 0; + } + else + { + if (targ.classname == "item_artifact_invisibility") + if (self.items & 524288) + bot_start_topic(3); + + if (targ.flags & FL_ITEM) + { + if (targ.model == string_null) + targ._last = world; + else + targ._last = self; + } + } + + + if (targ.classname != "player") + targ.search_time = time + 5; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_check_lost + +decide if my most immediate target should be +removed. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(entity targ) bot_check_lost = +{ + local vector dist; + dist = realorigin(targ) - self.origin; + dist_z = 0; + if (targ == world) + return; + + // waypoints and items are lost if you get close enough to them + + else if (targ.flags & FL_ITEM) + { + if (vlen(targ.origin - self.origin) < 32) + bot_lost(targ, TRUE); + else if (targ.model == string_null) + bot_lost(targ, TRUE); + } + else if (targ.classname == "waypoint") + { + if (!(self.b_aiflags & (AI_SNIPER | AI_AMBUSH))) + { + if (self.b_aiflags & AI_RIDE_TRAIN) + { + if (vlen(targ.origin - self.origin) < 48) + bot_lost(targ, TRUE); + } + else if (self.b_aiflags & AI_PRECISION) + { + if (vlen(targ.origin - self.origin) < 24) + bot_lost(targ, TRUE); + } + else if (vlen(targ.origin - self.origin) < 32) + bot_lost(targ, TRUE); + } + } + else if (targ.classname == "temp_waypoint") + { + if (vlen(targ.origin - self.origin) < 32) + bot_lost(targ, TRUE); + } + else if (targ.classname == "player") + { + if (targ.health <= 0) + bot_lost(targ, TRUE); + else if ((coop) || (teamplay && targ.team == self.team)) + { + if (targ.target1.classname == "player") + { + if (!targ.target1.ishuman) + bot_lost(targ, TRUE); + } + else if (targ.teleport_time > time) + { + // try not to telefrag teammates + self.keys = self.keys & 960; + } + else if (vlen(targ.origin - self.origin) < 128) + { + if (vlen(targ.origin - self.origin) < 48) + frik_walkmove(self.origin - targ.origin); + else + { + self.keys = self.keys & 960; + bot_start_topic(4); + } + self.search_time = time + 5; // never time out + } + else if (!fisible(targ)) + bot_lost(targ, FALSE); + } + else if (waypoint_mode > WM_LOADED) + { + if (vlen(targ.origin - self.origin) < 128) + { + bot_lost(targ, TRUE); + } + } + } + + // buttons are lost of their frame changes + else if (targ.classname == "func_button") + { + if (targ.frame) + { + bot_lost(targ, TRUE); + if (self.enemy == targ) + self.enemy = world; + //if (self.target1) + // bot_get_path(self.target1, TRUE); + + } + } + // trigger_multiple style triggers are lost if their thinktime changes + else if ((targ.movetype == MOVETYPE_NONE) && (targ.solid == SOLID_TRIGGER)) + { + if (targ.nextthink >= time) + { + bot_lost(targ, TRUE); + //if (self.target1) + // bot_get_path(self.target1, TRUE); + } + } + // lose any target way above the bot's head + // FIXME: if the bot can fly in your mod.. + if ((targ.origin_z - self.origin_z) > 64) + { + dist = targ.origin - self.origin; + dist_z = 0; + if (vlen(dist) < 32) + if (self.flags & FL_ONGROUND) + if(!frik_recognize_plat(FALSE)) + bot_lost(targ, FALSE); + } + else if (targ.classname == "train") + { + if (frik_recognize_plat(FALSE)) + bot_lost(targ, TRUE); + } + // targets are lost if the bot's search time has expired + if (time > self.search_time) + bot_lost(targ, FALSE); +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_handle_ai + +This is a 0.10 addition. Handles any action +based b_aiflags. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_handle_ai = +{ + local entity newt; + local vector v; + + // handle ai flags -- note, not all aiflags are handled + // here, just those that perform some sort of action + + // wait is used by the ai to stop the bot until his search time expires / or route changes + + if (self.b_aiflags & AI_WAIT) + self.keys = self.keys & 960; + + if (self.b_aiflags & AI_DOORFLAG) // was on a door when spawned + { + b_temp3 = self; + self = self.last_way; + if (!frik_recognize_plat(FALSE)) // if there is nothing there now + { + newt = FindThing("door"); // this is likely the door responsible (crossfingers) + self = b_temp3; + + if (self.b_aiflags & AI_DOOR_NO_OPEN) + { + if (newt.nextthink) + self.keys = self.keys & 960; // wait until it closes + else + { + bot_lost(self.last_way, FALSE); + self.b_aiflags = self.b_aiflags - AI_DOORFLAG; + } + } + else + { + if (newt.targetname) + { + newt = find(world, target, newt.targetname); + if (newt.health > 0) + { + self.enemy = newt; + bot_weapon_switch(1); + } + else + { + // target_drop(self.last_way); + target_add(newt); + // bot_get_path(newt, TRUE); + } + } + self.b_aiflags = self.b_aiflags - AI_DOORFLAG; + } + } + else + self = b_temp3; + } + + if (self.b_aiflags & AI_JUMP) + { + if (self.flags & FL_ONGROUND) + { + bot_jump(); + self.b_aiflags = self.b_aiflags - AI_JUMP; + } + } + else if (self.b_aiflags & AI_SUPER_JUMP) + { + if (self.weapon != 32) + self.impulse = 7; + else if (self.flags & FL_ONGROUND) + { + if (bot_can_rj(self)) + { + bot_jump(); + self.v_angle_x = self.b_angle_x = 80; + self.button0 = TRUE; + } + else + bot_lost(self.target1, FALSE); + self.b_aiflags = self.b_aiflags - AI_SUPER_JUMP; + } + } + if (self.b_aiflags & AI_SURFACE) + { + if (self.waterlevel > 2) + { + self.keys = KEY_MOVEUP; + self.button2 = TRUE; // swim! + } + else + self.b_aiflags = self.b_aiflags - AI_SURFACE; + } + if (self.b_aiflags & AI_RIDE_TRAIN) + { + // simple, but effective + // this can probably be used for a lot of different + // things, not just trains (door elevators come to mind) + b_temp3 = self; + self = self.last_way; + + if (!frik_recognize_plat(FALSE)) // if there is nothing there now + { + self = b_temp3; + self.keys = self.keys & 960; + } + else + { + self = b_temp3; + if (frik_recognize_plat(FALSE)) + { + v = realorigin(trace_ent) + trace_ent.origin - self.origin; + v_z = 0; + if (vlen(v) < 24) + self.keys = self.keys & 960; + else + { + self.b_aiflags = self.b_aiflags | AI_PRECISION; + self.keys = frik_KeysForDir(v); + } + } + } + } + if (self.b_aiflags & AI_PLAT_BOTTOM) + { + newt = FindThing("plat"); + if (newt.state != 1) + { + v = self.origin - realorigin(newt); + v_z = 0; + if (vlen(v) > 96) + self.keys = self.keys & 960; + else + frik_walkmove(v); + } + else + self.b_aiflags = self.b_aiflags - AI_PLAT_BOTTOM; + } + if (self.b_aiflags & AI_DIRECTIONAL) + { + if ((normalize(self.last_way.origin - self.origin) * self.b_dir) > 0.4) + { + self.b_aiflags = self.b_aiflags - AI_DIRECTIONAL; + bot_lost(self.target1, TRUE); + } + } + if (self.b_aiflags & AI_SNIPER) + { + self.b_aiflags = (self.b_aiflags | AI_WAIT | AI_PRECISION) - AI_SNIPER; + // FIXME: Add a switch to wep command + // FIXME: increase delay? + } + if (self.b_aiflags & AI_AMBUSH) + { + self.b_aiflags = (self.b_aiflags | AI_WAIT) - AI_AMBUSH; + // FIXME: Add a switch to wep command + // FIXME: increase delay? + } + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_path + +Bot will follow a route generated by the +begin_route set of functions in bot_way.qc. +This code, while it works pretty well, can get +confused + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_path = +{ + + local entity jj, tele; + + bot_check_lost(self.target1); + if (!self.target1) + { + self.keys=0; + return; + } + if (target_onstack(self.last_way)) + return; // old waypoint still being hunted + + jj = FindRoute(self.last_way); + if (!jj) + { + // this is an ugly hack + if (self.target1.current_way != self.last_way) + { + if (self.target1.classname != "temp_waypoint") + if (self.target1.classname != "player") + bot_lost(self.target1, FALSE); + } + + return; + } + + // update the bot's special ai features + + // Readahed types are AI conditions to perform while heading to a waypoint + // point types are AI flags that should be executed once reaching a waypoint + + self.b_aiflags = (jj.b_aiflags & AI_READAHEAD_TYPES) | (self.last_way.b_aiflags & AI_POINT_TYPES); + target_add(jj); + if (self.last_way) + { + if (CheckLinked(self.last_way, jj) == 2) // waypoints are telelinked + { + tele = FindThing("trigger_teleport"); // this is probbly the teleport responsible + target_add(tele); + } + traceline(self.last_way.origin, jj.origin, FALSE, self); // check for blockage + if (trace_fraction != 1) + { + if (trace_ent.classname == "door" && !(self.b_aiflags & AI_DOOR_NO_OPEN)) // a door blocks the way + { + // linked doors fix + if (trace_ent.owner) + trace_ent = trace_ent.owner; + if ((trace_ent.health > 0) && (self.enemy == world)) + { + self.enemy = trace_ent; + bot_weapon_switch(1); + self.b_aiflags = self.b_aiflags | AI_BLIND; // nick knack paddy hack + } + else if (trace_ent.targetname) + { + tele = find(world, target, trace_ent.targetname); + if (tele.health > 0) + { + self.enemy = tele; + bot_weapon_switch(1); + } + else + { + // target_drop(jj); + target_add(tele); + // bot_get_path(tele, TRUE); + self.b_aiflags = self.b_aiflags | AI_BLIND; // give a bot a bone + return; + } + } + } + else if (trace_ent.classname == "func_wall") + { + // give up + bot_lost(self.target1, FALSE); + return; + } + } + } + // this is used for AI_DRIECTIONAL + self.b_dir = normalize(jj.origin - self.last_way.origin); + + self.last_way = jj; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Priority Look. What a stupid name. This is where +the bot finds things it wants to kill/grab. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +// priority scale +// 0 - 10 virtually ignore +// 10 - 30 normal item range +// 30 - 50 bot will consider this a target worth changing course for +// 50 - 90 bot will hunt these as vital items + +// *!* Make sure you add code to bot_check_lost to remove the target *!* + +float(entity thing) priority_for_thing = +{ + local float thisp; + thisp = 0; + // This is the most executed function in the bot. Careful what you do here. + + if ((thing.flags & FL_ITEM) && thing.model != string_null && thing.search_time < time) + { + // ugly hack + if (thing._last != self) + thisp = 20; + if (thing.classname == "item_artifact_super_damage") + thisp = 65; + else if (thing.classname == "item_artifact_invulnerability") + thisp = 65; + else if (thing.classname == "item_health") + { + if (thing.spawnflags & 2) + thisp = 55; + if (self.health < 40) + thisp = thisp + 50; + } + else if (thing.model == "progs/armor.mdl") + { + if (self.armorvalue < 200) + { + if (thing.skin == 2) + thisp = 60; + else if (self.armorvalue < 100) + thisp = thisp + 25; + } + } + else if (thing.classname == "weapon_supershotgun") + { + if (!(self.items & 2)) // IT_SUPER_SHOTGUN + thisp = 25; + } + else if (thing.classname == "weapon_nailgun") + { + if (!(self.items & 4)) // IT_NAILGUN + thisp = 30; + } + else if (thing.classname == "weapon_supernailgun") + { + if (!(self.items & 8)) // IT_SUPER_NAILGUN + thisp = 35; + } + else if (thing.classname == "weapon_grenadelauncher") + { + if (!(self.items & 16)) // IT_GRENADE_LAUNCHER + thisp = 45; + } + else if (thing.classname == "weapon_rocketlauncher") + { + if (!(self.items & 32)) // IT_ROCKET_LAUNCHER + thisp = 60; + } + else if (thing.classname == "weapon_lightning") + { + if (!(self.items & 64)) // IT_LIGHTNING + thisp = 50; + } + } + else if ((thing.flags & FL_MONSTER) && thing.health > 0) + thisp = 45; + else if (thing.classname == "player") + { + if (thing.health > 0) + { + if (thing == self) + return 0; + else + { + if (thing.items & IT_INVISIBILITY) //FIXME + thisp = 2; + else if (coop) + { + thisp = 100; + if (thing.target1.classname == "player") + if (!thing.target1.ishuman) + return 0; + } + else if (teamplay && thing.team == self.team) + { + thisp = 100; + if (thing.target1.classname == "player") + return 0; + } + else thisp = 30; + } + } + } + else if (thing.classname == "waypoint") + { + if (thing.b_aiflags & AI_SNIPER) + thisp = 30; + else if (thing.b_aiflags & AI_AMBUSH) + thisp = 30; + } + if (pointcontents(thing.origin) < -3) + return 0; + if (thisp) + { + if (thing.current_way) + { + // check to see if it's unreachable + if (thing.current_way.items == -1) + return 0; + else + thisp = thisp + (13000 - thing.current_way.items) * 0.05; + + } + } + return thisp; +}; + +void(float scope) bot_look_for_crap = +{ + local entity foe, best; + local float thatp, bestp, dist; + + if (scope == 1) + foe = findradius(self.origin, 13000); + else + foe = findradius(self.origin, 500); + + bestp = 1; + while(foe) + { + thatp = priority_for_thing(foe); + if (thatp) + if (!scope) + if (!sisible(foe)) + thatp = 0; + if (thatp > bestp) + { + bestp = thatp; + best = foe; + dist = vlen(self.origin - foe.origin); + } + foe = foe.chain; + } + if (best == world) + return; + if (!target_onstack(best)) + { + target_add(best); + if (scope) + { + bot_get_path(best, FALSE); + self.b_aiflags = self.b_aiflags | AI_WAIT; + } + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_angle_set + +Sets the bots look keys & b_angle to point at +the target - used for fighting and just +generally making the bot look good. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_angle_set = +{ + local float h; + local vector view; + + if (self.enemy) + { + if (self.enemy.items & 524288) + if (random() > 0.2) + return; + if (self.missile_speed == 0) + self.missile_speed = 10000; + if (self.enemy.solid == SOLID_BSP) + { + view = (((self.enemy.absmin + self.enemy.absmax) * 0.5) - self.origin); + } + else + { + h = vlen(self.enemy.origin - self.origin) / self.missile_speed; + if (self.enemy.flags & FL_ONGROUND) + view = self.enemy.velocity * h; + else + view = (self.enemy.velocity - (sv_gravity * '0 0 1') * h) * h; + view = self.enemy.origin + view; + // FIXME: ? + traceline(self.enemy.origin, view, FALSE, self); + view = trace_endpos; + + if (self.weapon == 32) + view = view - '0 0 22'; + + view = normalize(view - self.origin); + } + view = vectoangles(view); + view_x = view_x * -1; + self.b_angle = view; + } + else if (self.target1) + { + view = realorigin(self.target1); + if (self.target1.flags & FL_ITEM) + view = view + '0 0 48'; + view = view - (self.origin + self.view_ofs); + view = vectoangles(view); + view_x = view_x * -1; + self.b_angle = view; + } + else + self.b_angle_x = 0; + // HACK HACK HACK HACK + // The bot falls off ledges a lot because of "turning around" + // so let the bot use instant turn around when not hunting a player + if (self.b_skill == 3) + { + self.keys = self.keys & 63; + self.v_angle = self.b_angle; + while (self.v_angle_x < -180) + self.v_angle_x = self.v_angle_x + 360; + while (self.v_angle_x > 180) + self.v_angle_x = self.v_angle_x - 360; + + } + else if ((self.enemy == world || self.enemy.movetype == MOVETYPE_PUSH) && self.target1.classname != "player") + { + self.keys = self.keys & 63; + self.v_angle = self.b_angle; + while (self.v_angle_x < -180) + self.v_angle_x = self.v_angle_x + 360; + while (self.v_angle_x > 180) + self.v_angle_x = self.v_angle_x - 360; + } + else if (self.b_skill < 2) // skill 2 handled in bot_phys + { + if (self.b_angle_x > 180) + self.b_angle_x = self.b_angle_x - 360; + self.keys = self.keys & 63; + + if (angcomp(self.b_angle_y, self.v_angle_y) > 10) + self.keys = self.keys | KEY_LOOKLEFT; + else if (angcomp(self.b_angle_y, self.v_angle_y) < -10) + self.keys = self.keys | KEY_LOOKRIGHT; + if (angcomp(self.b_angle_x, self.v_angle_x) < -10) + self.keys = self.keys | KEY_LOOKUP; + else if (angcomp(self.b_angle_x, self.v_angle_x) > 10) + self.keys = self.keys | KEY_LOOKDOWN; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotAI + +This is the main ai loop. Though called every +frame, the ai_time limits it's actual updating + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float stagger_think; + +void() BotAI = +{ + // am I dead? Fire randomly until I respawn + // health < 1 is used because fractional healths show up as 0 on normal player + // status bars, and the mod probably already compensated for that + + if (self.health < 1) + { + self.button0 = floor(random() * 2); + self.button2 = 0; + self.keys = 0; + self.b_aiflags = 0; + ClearMyRoute(); + self.target1 = self.target2 = self.target3 = self.target4 = self.enemy = world; + self.last_way = world; + return; + } + + // stagger the bot's AI out so they all don't think at the same time, causing game + // 'spikes' + if (self.b_skill < 2) + { + if (self.ai_time > time) + return; + + self.ai_time = time + 0.05; + if (bot_count > 0) + { + if ((time - stagger_think) < (0.1 / bot_count)) + self.ai_time = self.ai_time + 0.1 / (2 * bot_count); + } + else + return; + } + if (self.view_ofs == '0 0 0') + bot_start_topic(7); + stagger_think = time; + + // shut the bot's buttons off, various functions will turn them on by AI end + + self.button2 = 0; + self.button0 = 0; + + + // target1 is like goalentity in normal Quake monster AI. + // it's the bot's most immediate target + if (route_table == self) + { + if (busy_waypoints <= 0) + { + if (waypoint_mode < WM_EDITOR) + bot_look_for_crap(TRUE); + } + self.b_aiflags = 0; + self.keys = 0; + } + else if (self.target1) + { + frik_movetogoal(); + bot_path(); + } + else + { + if (waypoint_mode < WM_EDITOR) + { + if(self.route_failed) + { + frik_bot_roam(); + self.route_failed = 0; + } + else if(!begin_route()) + { + bot_look_for_crap(FALSE); + } + self.keys = 0; + } + else + { + self.b_aiflags = AI_WAIT; + self.keys = 0; + } + } + + // bot_angle_set points the bot at it's goal (self.enemy or target1) + + bot_angle_set(); + + // fight my enemy. Enemy is probably a field QC coders will most likely use a lot + // for their own needs, since it's unused on a normal player + // FIXME + if (self.enemy) + bot_fight_style(); + else if (random() < 0.2) + if (random() < 0.2) + bot_weapon_switch(-1); + bot_dodge_stuff(); + + // checks to see if bot needs to start going up for air + if (self.waterlevel > 2) + { + if (time > (self.air_finished - 2)) + { + traceline (self.origin, self.origin + '0 0 6800', TRUE, self); + if (trace_inopen) + { + self.keys = KEY_MOVEUP; + self.button2 = TRUE; // swim! + return; // skip ai flags for now - this is life or death + } + } + } + + // b_aiflags handling + + + if (self.b_aiflags) + bot_handle_ai(); + else + bot_chat(); // don't want chat to screw him up if he's rjing or something +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_ed.qc b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_ed.qc new file mode 100755 index 00000000..44352c27 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_ed.qc @@ -0,0 +1,1334 @@ +/*********************************************** +* * +* FrikBot Waypoint Editor * +* "The 'wtf is this doing in my mod' code" * +* * +***********************************************/ + +/* +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. +*/ + +float saved1, saved2, saved3, scratch1, scratch2, scratch3, scratch4; +float bytecounter, filecount; + +float MENU_MAIN = 1; +float MENU_WAYPOINTS = 2; +float MENU_LINKS = 3; +float MENU_FLAGS = 4; +float MENU_FLAGS2 = 5; +float MENU_BOTS = 6; +float MENU_WAYLIST = 7; +// 8 = link way +// 9 = telelink way +// 10 = delete link +// 11 = create link X2 +// 12 = delete link x2 +// 13 = confirmation of delete all +// 14 = Teleport to way +// 15 = confirmation of delete point + +void() BSPDumpWaypoints; +void() QCDumpWaypoints; +void() DumpWaypoints; +/* +// source for the menu strings... + +-- Main Menu --\n +[1] >>Waypoint Management\n +[2] >>Link Management \n +[3] >>AI Flag Management \n +[4] >>Bot Management \n +[5] >>Waylist Management \n +[6] [#] Noclip \n +[7] [#] Godmode \n +[8] [#] Hold Select \n +[9] Teleport to Way # \n +[0] Close Menu \n + +// missing from main is show way info +// iffy on the teleport to way thing being on main...seems like either a bot or way list thing + +-- Waypoint Management --\n +[1] Move Waypoint \n +[2] Delete Waypoint \n +[3] Make Waypoint \n +[4] Make Way + Link \n +[5] Make Way + Link X2 \n +[6] Make Way + Telelink \n +[7] Show waypoint info \n +[8] >>Link Management \n +[9] >>AI Flag Management \n +[0] >>Main Menu \n + +-- Link Management --\n +[1] Unlink Waypoint \n +[2] Create Link \n +[3] Create Telelink \n +[4] Delete Link \n +[5] Create Link X2 \n +[6] Delete Link X2 \n +[7] >Make Waypoint \n +[8] >>Waypoint Management\n +[9] >>AI Flag Management \n +[0] >>Main Menu \n + +// Ai flags...ugh + +-- AI Flag Management --\n +[1] [#] Door Flag \n +[2] [#] Precision \n +[3] [#] Surface for air \n +[4] [#] Blind mode \n +[5] [#] Jump \n +[6] [#] Dark \n +[7] [#] Super Jump \n +\n +[9] >>AI Flags page 2 \n +[0] >>Main Menu \n + +-- AI Flags pg. 2--\n +[1] [#] Difficult \n +[2] [#] Wait for plat \n +[3] [#] Ride train \n +[4] [#] Door flag no open\n +[5] [#] Ambush \n +[6] [#] Snipe \n +[7] [#] Trace Test \n +\n +[9] >>AI Flag Management \n +[0] >>Main Menu \n + +-- Bot Management --\n +[1] Add a Test Bot \n +[2] Order Test Bot here \n +[3] Remove Test Bot \n +[4] Stop Test Bot \n +[5] Teleport Bot here \n +[6] Teleport to Way # \n +\n +\n +\n +[0] >>Main Menu \n + +-- Waylist Management --\n +[1] Delete ALL Waypoints \n +[2] Dump Waypoints \n +[3] Check For Errors \n +[4] Save Waypoints \n +[5] [#] Dynamic Mode \n +[6] [#] Dynamic Link \n +[7] [#] WAY output \n +[8] [#] QC output \n +[9] [#] BSP ents output \n +[0] Main Menu \n + +*/ + +void() bot_menu_display = +{ +// build options + local string s1, s2, s3, s4, s5, s6, s7, h; + local entity t; + +// check impulses + if (self.impulse > 0 && self.impulse < 11 && self.b_menu) + { + if (self.b_menu == MENU_MAIN) + { + if (self.impulse == 1) + { + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + else if (self.impulse == 3) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 4) + { + self.b_menu = MENU_BOTS; + self.b_menu_time = time; + } + else if (self.impulse == 5) + { + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + else if (self.impulse == 6) + { + if (self.movetype == MOVETYPE_NOCLIP) + self.movetype = MOVETYPE_WALK; + else + self.movetype = MOVETYPE_NOCLIP; + self.b_menu_time = time; + + } + else if (self.impulse == 7) + { + if (self.flags & FL_GODMODE) + self.flags = self.flags - FL_GODMODE; + else + self.flags = self.flags | FL_GODMODE; + self.b_menu_time = time; + + } + else if (self.impulse == 8) + { + if (self.b_aiflags & AI_HOLD_SELECT) + self.b_aiflags = self.b_aiflags - AI_HOLD_SELECT; + else + self.b_aiflags = self.b_aiflags | AI_HOLD_SELECT; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + self.b_menu = 14; + self.b_menu_time = time; + } + else if (self.impulse == 10) + bot_way_edit(); + } + else if (self.b_menu == MENU_WAYPOINTS) + { + if (self.impulse == 1) + { + if (self.current_way) + setorigin(self.current_way, self.origin + self.view_ofs); + } + else if (self.impulse == 2) + { + if (self.current_way) + { + self.b_menu = 15; + self.b_menu_time = time; + self.last_way = self.current_way; + } + } + else if (self.impulse == 3) + { + make_waypoint(self.origin + self.view_ofs); + } + else if (self.impulse == 4) + { + t = make_waypoint(self.origin + self.view_ofs); + if (!LinkWays(self.current_way, t)) + sprint(self, "Unable to link them\n"); + } + else if (self.impulse == 5) + { + t = make_waypoint(self.origin + self.view_ofs); + if (!LinkWays(self.current_way, t)) + sprint(self, "Unable to link old to new\n"); + LinkWays(t, self.current_way); + } + else if (self.impulse == 6) + { + t = make_waypoint(self.origin + self.view_ofs); + if (!TeleLinkWays(self.current_way, t)) + sprint(self, "Unable to link them\n"); + } + else if (self.impulse == 7) + { + if (self.current_way) + { + sprint(self, "\nwaypoint info for waypoint #"); + h = ftos(self.current_way.count); + sprint(self, h); + sprint(self, "\nAI Flag value: "); + h = ftos(self.current_way.b_aiflags); + sprint(self, h); + + if (self.current_way.target1) + { + h = ftos(self.current_way.target1.count); + if (self.current_way.b_aiflags & AI_TELELINK_1) + sprint(self, "\nTelelink1 to:"); + else + sprint(self, "\nLink1 to:"); + sprint(self, h); + } + if (self.current_way.target2) + { + h = ftos(self.current_way.target2.count); + if (self.current_way.b_aiflags & AI_TELELINK_2) + sprint(self, "\nTelelink2 to:"); + else + sprint(self, "\nLink2 to:"); + sprint(self, h); + } + if (self.current_way.target3) + { + h = ftos(self.current_way.target3.count); + if (self.current_way.b_aiflags & AI_TELELINK_3) + sprint(self, "\nTelelink3 to:"); + else + sprint(self, "\nLink3 to:"); + sprint(self, h); + } + if (self.current_way.target4) + { + h = ftos(self.current_way.target4.count); + if (self.current_way.b_aiflags & AI_TELELINK_4) + sprint(self, "\nTelelink4 to:"); + else + sprint(self, "\nLink4 to:"); + sprint(self, h); + } + sprint(self, "\n\n"); + } + + } + if (self.impulse == 8) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_LINKS) + { + if (self.impulse == 1) + { + if (self.current_way) + self.current_way.target1 = self.current_way.target2 = self.current_way.target3 = self.current_way.target4 = world; + } + else if (self.impulse == 2) + { + self.b_menu = 8; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 3) + { + self.b_menu = 9; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 4) + { + self.b_menu = 10; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 5) + { + self.b_menu = 11; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 6) + { + self.b_menu = 12; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 7) + make_waypoint(self.origin + self.view_ofs); + else if (self.impulse == 8) + { + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_FLAGS) + { + + if (self.current_way) + { + if (self.impulse == 1) + { + if (self.current_way.b_aiflags & AI_DOORFLAG) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DOORFLAG); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DOORFLAG; + + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + if (self.current_way.b_aiflags & AI_PRECISION) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_PRECISION); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_PRECISION; + self.b_menu_time = time; + } + else if (self.impulse == 3) + { + if (self.current_way.b_aiflags & AI_SURFACE) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_SURFACE); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_SURFACE; + self.b_menu_time = time; + } + else if (self.impulse == 4) + { + if (self.current_way.b_aiflags & AI_BLIND) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_BLIND); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_BLIND; + self.b_menu_time = time; + } + else if (self.impulse == 5) + { + if (self.current_way.b_aiflags & AI_JUMP) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_JUMP); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_JUMP; + self.b_menu_time = time; + } + else if (self.impulse == 6) + { + if (self.current_way.b_aiflags & AI_DIRECTIONAL) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DIRECTIONAL); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DIRECTIONAL; + self.b_menu_time = time; + } + else if (self.impulse == 7) + { + if (self.current_way.b_aiflags & AI_SUPER_JUMP) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_SUPER_JUMP); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_SUPER_JUMP; + self.b_menu_time = time; + } + } + if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS2; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_FLAGS2) + { + + if (self.current_way) + { + if (self.impulse == 1) + { + if (self.current_way.b_aiflags & AI_DIFFICULT) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DIFFICULT); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DIFFICULT; self.b_menu_time = time; + } + else if (self.impulse == 2) + { + if (self.current_way.b_aiflags & AI_PLAT_BOTTOM) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_PLAT_BOTTOM); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_PLAT_BOTTOM; + self.b_menu_time = time; + } + else if (self.impulse == 3) + { + if (self.current_way.b_aiflags & AI_RIDE_TRAIN) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_RIDE_TRAIN); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_RIDE_TRAIN; + self.b_menu_time = time; + } + else if (self.impulse == 4) + { + if (self.current_way.b_aiflags & AI_DOOR_NO_OPEN) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DOOR_NO_OPEN); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DOOR_NO_OPEN; + self.b_menu_time = time; + } + else if (self.impulse == 5) + { + if (self.current_way.b_aiflags & AI_AMBUSH) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_AMBUSH); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_AMBUSH; + self.b_menu_time = time; + } + else if (self.impulse == 6) + { + if (self.current_way.b_aiflags & AI_SNIPER) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_SNIPER); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_SNIPER; + self.b_menu_time = time; + } + else if (self.impulse == 7) + { + if (self.current_way.b_aiflags & AI_TRACE_TEST) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_TRACE_TEST); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_TRACE_TEST; + self.b_menu_time = time; + } + + } + if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + + else if (self.b_menu == MENU_BOTS) + { + if (self.impulse == 1) + { + self.impulse = 100; + return; + } + else if (self.impulse == 2) + { + b_temp3 = self; + self = player_head; + while(self) + { + if (!self.ishuman) + { + target_add(b_temp3); + bot_get_path(b_temp3, TRUE); + self = world; + } + else + self = self._next; + } + self = b_temp3; + } + else if (self.impulse == 3) + { + self.impulse = 102; + return; + } + else if (self.impulse == 4) + { + b_temp1 = self; + self = player_head; + while(self) + { + if (!self.ishuman) + { + self.target1 = self.target2 = self.target3 = self.target4 = world; + route_table = world; + } + self = self._next; + } + self = b_temp1; + } + else if (self.impulse == 5) + { + if (self.current_way) + { + b_temp1 = self; + self = player_head; + while(self) + { + if (!self.ishuman) + { + setorigin(self, b_temp1.current_way.origin); + } + self = self._next; + } + self = b_temp1; + } + else + sprint(self, "select a waypoint first\n"); + } + else if (self.impulse == 6) + { + self.b_menu = 14; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_WAYLIST) + { + if (self.impulse == 1) + { + self.b_menu = 13; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + if (dump_mode == 0) + DumpWaypoints(); + else if (dump_mode == 1) + QCDumpWaypoints(); + else if (dump_mode == 2) + BSPDumpWaypoints(); + } + else if (self.impulse == 3) + { + t = way_head; + while(t) + { + if ((t.target1 == world) && (t.target2 == world) && (t.target3 == world) && (t.target4 == world)) + { + sprint(self, "Waypoint #"); + h = ftos(t.count); + sprint(self, h); + sprint(self, " has no outbound links\n"); + } + if ((t.target1 == t) || (t.target2 == t) || (t.target3 == t) || (t.target4 == t)) + { + sprint(self, "Waypoint #"); + h = ftos(t.count); + sprint(self, h); + sprint(self, " links to itself (??)\n"); + } + t = t._next; + } + sprint(self, "Error check complete\n"); + } + else if (self.impulse == 4) + { + sprint(self, "not in this version (FBX 0.10.0)\n"); + } + else if (self.impulse == 5) + { + if (waypoint_mode == WM_EDITOR_DYNAMIC) + waypoint_mode = WM_EDITOR; + else + waypoint_mode = WM_EDITOR_DYNAMIC; + self.b_menu_time = time; + + } + else if (self.impulse == 6) + { + if (waypoint_mode == WM_EDITOR_DYNLINK) + waypoint_mode = WM_EDITOR; + else + waypoint_mode = WM_EDITOR_DYNLINK; + self.b_menu_time = time; + } + else if (self.impulse == 7) + { + dump_mode = 0; + self.b_menu_time = time; + } + else if (self.impulse == 8) + { + dump_mode = 1; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + dump_mode = 2; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == 8) + { + if (self.impulse == 1) + { + if (self.current_way) + { + if (!LinkWays(self.last_way, self.current_way)) + sprint(self, "Unable to link them\n"); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 9) + { + if (self.impulse == 1) + { + if (self.current_way) + { + if (!TeleLinkWays(self.last_way, self.current_way)) + sprint(self, "Unable to link them\n"); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 10) + { + if (self.impulse == 1) + { + if (self.current_way) + { + UnlinkWays(self.last_way, self.current_way); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 11) + { + if (self.impulse == 1) + { + if (self.current_way) + { + if (!LinkWays(self.last_way, self.current_way)) + sprint(self, "Unable to link 1 to 2\n"); + if (!LinkWays(self.current_way, self.last_way)) + sprint(self, "Unable to link 2 to 1\n"); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 12) + { + if (self.impulse == 1) + { + if (self.current_way) + { + UnlinkWays(self.last_way, self.current_way); + UnlinkWays(self.current_way, self.last_way); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 13) + { + if (self.impulse == 1) + { + ClearAllWays(); + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + } + else if (self.b_menu == 14) + { + if (self.impulse == 10) + self.impulse = 0; + self.b_menu_value = self.b_menu_value * 10 + self.impulse; + self.b_menu_time = 0; + } + else if (self.b_menu == 15) + { + if (self.impulse == 1) + { + delete_waypoint(self.last_way); + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + } + self.impulse = 0; + + } + if (self.b_menu_time < time) + { + if (self.b_menu == MENU_MAIN) + { + s1 = "-- Main Menu --\n[1] >>Waypoint Management\n[2] >>Link Management \n[3] >>AI Flag Management \n[4] >>Bot Management \n[5] >>Waylist Management \n"; + if (self.movetype == MOVETYPE_NOCLIP) + s2 = "[6] [#] Noclip \n"; + else + s2 = "[6] [ ] Noclip \n"; + + if (self.flags & FL_GODMODE) + s3 = "[7] [#] Godmode \n"; + else + s3 = "[7] [ ] Godmode \n"; + if (self.b_aiflags & AI_HOLD_SELECT) + s4 = "[8] [#] Hold Select \n"; + else + s4 = "[8] [ ] Hold Select \n"; + s5 = "[9] Teleport to Way # \n[0] Close Menu \n"; + } + else if (self.b_menu == MENU_WAYPOINTS) + { + s1 = "-- Waypoint Management --\n[1] Move Waypoint \n[2] Delete Waypoint \n[3] Make Waypoint \n[4] Make Way + Link \n[5] Make Way + Link X2 \n[6] Make Way + Telelink \n[7] Show waypoint info \n[8] >>Link Management \n[9] >>AI Flag Management \n[0] >>Main Menu \n"; + } + else if (self.b_menu == MENU_LINKS) + { + s1 = "-- Link Management --\n[1] Unlink Waypoint \n[2] Create Link \n[3] Create Telelink \n[4] Delete Link \n[5] Create Link X2 \n[6] Delete Link X2 \n[7] >Make Waypoint \n[8] >>Waypoint Management\n[9] >>AI Flag Management \n[0] >>Main Menu \n"; + } + else if (self.b_menu == MENU_FLAGS) + { + if (self.current_way.b_aiflags & AI_DOORFLAG) + s1 = "-- AI Flag Management --\n[1] [#] Door Flag \n"; + else + s1 = "-- AI Flag Management --\n[1] [ ] Door Flag \n"; + + if (self.current_way.b_aiflags & AI_PRECISION) + s2 = "[2] [#] Precision \n"; + else + s2 = "[2] [ ] Precision \n"; + + if (self.current_way.b_aiflags & AI_SURFACE) + s3 = "[3] [#] Surface for air \n"; + else + s3 = "[3] [ ] Surface for air \n"; + + if (self.current_way.b_aiflags & AI_BLIND) + s4 = "[4] [#] Blind mode \n"; + else + s4 = "[4] [ ] Blind mode \n"; + + if (self.current_way.b_aiflags & AI_JUMP) + s5 = "[5] [#] Jump \n"; + else + s5 = "[5] [ ] Jump \n"; + + if (self.current_way.b_aiflags & AI_DIRECTIONAL) + s6 = "[6] [#] Directional \n"; + else + s6 = "[6] [ ] Directional \n"; + + if (self.current_way.b_aiflags & AI_SUPER_JUMP) + s7 = "[7] [#] Super Jump \n\n[9] >>AI Flags page 2 \n[0] >>Main Menu \n"; + else + s7 = "[7] [ ] Super Jump \n\n[9] >>AI Flags page 2 \n[0] >>Main Menu \n"; + } + else if (self.b_menu == MENU_FLAGS2) + { + if (self.current_way.b_aiflags & AI_DIFFICULT) + s1 = "-- AI Flags pg. 2--\n[1] [#] Difficult \n"; + else + s1 = "-- AI Flags pg. 2--\n[1] [ ] Difficult \n"; + + if (self.current_way.b_aiflags & AI_PLAT_BOTTOM) + s2 = "[2] [#] Wait for plat \n"; + else + s2 = "[2] [ ] Wait for plat \n"; + + if (self.current_way.b_aiflags & AI_RIDE_TRAIN) + s3 = "[3] [#] Ride train \n"; + else + s3 = "[3] [ ] Ride train \n"; + + if (self.current_way.b_aiflags & AI_DOOR_NO_OPEN) + s4 = "[4] [#] Door flag no open\n"; + else + s4 = "[4] [ ] Door flag no open\n"; + + if (self.current_way.b_aiflags & AI_AMBUSH) + s5 = "[5] [#] Ambush \n"; + else + s5 = "[5] [ ] Ambush \n"; + + if (self.current_way.b_aiflags & AI_SNIPER) + s6 = "[6] [#] Snipe \n"; + else + s6 = "[6] [ ] Snipe \n"; + + if (self.current_way.b_aiflags & AI_TRACE_TEST) + s7 = "[7] [#] Trace Test \n\n[9] >>AI Flag Management \n[0] >>Main Menu \n"; + else + s7 = "[7] [ ] Trace Test \n\n[9] >>AI Flag Management \n[0] >>Main Menu \n"; + + } + else if (self.b_menu == MENU_BOTS) + { + s1 = "-- Bot Management --\n[1] Add a Test Bot \n[2] Order Test Bot here \n[3] Remove Test Bot \n[4] Stop Test Bot \n[5] Teleport Bot here \n[6] Teleport to Way # \n\n\n\n[0] >>Main Menu \n"; + } + else if (self.b_menu == MENU_WAYLIST) + { + s1 = "-- Waylist Management --\n[1] Delete ALL Waypoints \n[2] Dump Waypoints \n[3] Check For Errors \n[4] Save Waypoints \n"; + + if (waypoint_mode == WM_EDITOR_DYNAMIC) + s2 = "[5] [#] Dynamic Mode \n[6] [#] Dynamic Link \n"; + else if (waypoint_mode == WM_EDITOR_DYNLINK) + s2 = "[5] [ ] Dynamic Mode \n[6] [#] Dynamic Link \n"; + else + s2 = "[5] [ ] Dynamic Mode \n[6] [ ] Dynamic Link \n"; + if (dump_mode == 0) + s3 = "[7] [#] WAY output \n[8] [ ] QC output \n[9] [ ] BSP ents output \n[0] Main Menu \n"; + else if (dump_mode == 1) + s3 = "[7] [ ] WAY output \n[8] [#] QC output \n[9] [ ] BSP ents output \n[0] Main Menu \n"; + else if (dump_mode == 2) + s3 = "[7] [ ] WAY output \n[8] [ ] QC output \n[9] [#] BSP ents output \n[0] Main Menu \n"; + + } + else if (self.b_menu == 8) + s1 = "-- Link Ways --\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 9) + s1 = "-- Telelink Ways --\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 10) + s1 = "-- Delete Link --\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 11) + s1 = "-- Create Link X2 --\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 12) + s1 = "-- Delete Link X2 --\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 13) + s1 = "-- Delete ALL Ways --\n\nAre you sure? Push 1 to go\nthrough with it, 2 to cancel"; + else if (self.b_menu == 14) + { + s1 = "-- Teleport to Way # --\n\nEnter way number and press\nimpulse 104 to warp\n\nWaypoint #"; + s2 = ftos(self.b_menu_value); + + } + else if (self.b_menu == 15) + s1 = "-- Delete Waypoint --\n\nAre you sure? Push 1 to go\nthrough with it, 2 to cancel"; + frik_big_centerprint(self, s1, s2, s3, s4, s5, s6, s7); + self.b_menu_time = time + 1.25; + } +}; + + +// engage menu +void() bot_way_edit = +{ + local entity t; + local float f; + if (self.b_menu_value) + { + if (self.b_menu == 14) + { + t = WaypointForNum(self.b_menu_value); + if (t) + setorigin(self, t.origin - self.view_ofs); + else + sprint(self, "No waypoint with that number\n"); + + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + self.b_menu_value = 0; + return; + } + if (waypoint_mode < WM_EDITOR) + { + self.b_menu = MENU_MAIN; + waypoint_mode = WM_EDITOR; + self.b_menu_time = 0; + cvar_set("saved2", "0"); + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, "MAKE SURE THE FOLLOWING LINE CONTAINS -CONDEBUG BEFORE PROCEEDING\n"); + localcmd("cmdline\n"); + t = way_head; + while (t) + { + setmodel(t, "progs/s_bubble.spr"); // show the waypoints + t = t._next; + } + if (self.current_way) + setmodel(self.current_way, "progs/s_light.spr"); + } + else + { + saved2 = cvar("saved2"); + if (saved2 != 0) + { + f = self.b_menu; + self.b_menu = floor(saved2/16); + self.impulse = saved2 & 15; + bot_menu_display(); + self.b_menu = f; + cvar_set("saved2", "0"); + return; + } + self.b_menu = 0; + waypoint_mode = WM_LOADED; + t = way_head; + while (t) + { + setmodel(t, string_null); // hide the waypoints + t = t._next; + } + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Saving to file. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +// bytecount is really iffy +// since there is no true way to determine the length of an ftos +// it uses an approximate of 5 +// various other things are guesses, but I don't cut it at the absolute +// max so it should be okay + +void() PrintWaypoint = +{ + local entity t; + local float needcolon; + local string h; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + if (bytecounter >= 8000) + { + bprint("exec maps/"); + bprint(mapname); + bprint(".wa"); + h = ftos(filecount); + bprint(h); + filecount = filecount + 1; + bprint("\n// **** break here **** \n"); + bytecounter = 26; + } + if (t == world) + { + remove(self); + fixer = world; + bprint("saved4 3\n// end waypoint dump\n"); + bytecounter = bytecounter + 27; + return; + } + if ((t.origin_x != saved1) || (t.count == 1)) + { + bprint("saved1 "); + h = ftos(t.origin_x); + bprint(h); + saved1 = t.origin_x; + bytecounter = bytecounter + 12; + needcolon = TRUE; + } + if ((t.origin_y != saved2) || (t.count == 1)) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("saved2 "); + h = ftos(t.origin_y); + bprint(h); + bytecounter = bytecounter + 12; + saved2 = t.origin_y; + } + if ((t.origin_z != saved3) || (t.count == 1)) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("saved3 "); + h = ftos(t.origin_z); + bprint(h); + bytecounter = bytecounter + 12; + saved3 = t.origin_z; + } + bytecounter = bytecounter + 1; + bprint("\n"); + needcolon = FALSE; + if ((scratch1 != t.target1.count) || t.count == 1) + { + needcolon = TRUE; + bprint("scratch1 "); + bytecounter = bytecounter + 14; + h = ftos(t.target1.count); + bprint(h); + scratch1 = t.target1.count; + } + if ((scratch2 != t.target2.count) || t.count == 1) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("scratch2 "); + bytecounter = bytecounter + 14; + h = ftos(t.target2.count); + bprint(h); + scratch2 = t.target2.count; + } + if ((scratch3 != t.target3.count) || t.count == 1) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("scratch3 "); + bytecounter = bytecounter + 14; + h = ftos(t.target3.count); + bprint(h); + scratch3 = t.target3.count; + } + if ((scratch4 != t.target4.count) || t.count == 1) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("scratch4 "); + bytecounter = bytecounter + 14; + h = ftos(t.target4.count); + bprint(h); + scratch4 = t.target4.count; + } + bprint("\nsaved4 "); + bytecounter = bytecounter + 19; + if (t.count != 1) + h = ftos(t.b_aiflags * 4 + 2); + else + h = ftos(t.b_aiflags * 4 + 1); + bprint(h); + bprint ("; wait\n"); + self.nextthink = time + 0.01; + self.enemy = t; +}; + +// to allow for 100+ waypoints, we need to trick the runaway loop counter +void() DumpWaypoints = +{ + bytecounter = 50; + filecount = 1; + + bprint("// "); + bprint(world.message); + bprint("- maps/"); + bprint(mapname); + bprint(".way\n"); + bprint("// Ways by "); + bprint(self.netname); + bprint("\n"); + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = PrintWaypoint; + fixer.enemy = world; + } +}; + +void() PrintQCWaypoint = +{ + local entity t; + local string h; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + + if (t == world) + { + remove(self); + fixer = world; + bprint("};\n\n// End dump\n"); + return; + } + bprint(" make_way("); + h = vtos(t.origin); + bprint(h); + bprint(", '"); + h = ftos(t.target1.count); + bprint(h); + bprint(" "); + h = ftos(t.target2.count); + bprint(h); + bprint(" "); + h = ftos(t.target3.count); + bprint(h); + bprint("', "); + h = ftos(t.target4.count); + bprint(h); + bprint(", "); + h = ftos(t.b_aiflags); + bprint(h); + bprint(");\n"); + self.nextthink = time + 0.01; + self.enemy = t; + +}; +void() QCDumpWaypoints = +{ + bprint("/* QC Waypoint Dump - src/frikbot/map_"); + + bprint(mapname); + bprint(".qc\nFor instructions please read the\nreadme.html that comes with FrikBot */\n\nvoid(vector org, vector bit1, float bit4, float flargs) make_way;\n"); + bprint("// Ways by "); + bprint(self.netname); + bprint("\n\n"); + + bprint("void() map_"); + bprint(mapname); + bprint(" =\n{\n"); + + + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = PrintQCWaypoint; + fixer.enemy = world; + } +}; + +void() PrintBSPWaypoint = +{ + local entity t; + local string h; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + + if (t == world) + { + bprint("\n\n// End dump\n"); + remove(self); + fixer = world; + return; + } + bprint("{\n\"classname\" \"waypoint\"\n\"origin\" \""); + h = ftos(t.origin_x); + bprint(h); + bprint(" "); + h = ftos(t.origin_y); + bprint(h); + bprint(" "); + h = ftos(t.origin_z); + bprint(h); + if (t.target1.count) + { + bprint("\"\n\"b_pants\" \""); + h = ftos(t.target1.count); + bprint(h); + } + if (t.target2.count) + { + bprint("\"\n\"b_skill\" \""); + h = ftos(t.target2.count); + bprint(h); + } + if (t.target3.count) + { + bprint("\"\n\"b_shirt\" \""); + h = ftos(t.target3.count); + bprint(h); + } + if (t.target4.count) + { + bprint("\"\n\"b_frags\" \""); + h = ftos(t.target4.count); + bprint(h); + } + if (t.b_aiflags) + { + bprint("\"\n\"b_aiflags\" \""); + h = ftos(t.b_aiflags); + bprint(h); + } + bprint("\"\n}\n"); + self.nextthink = time + 0.01; + self.enemy = t; + +}; +void() BSPDumpWaypoints = +{ + bprint("/* BSP entities Dump - maps/"); + + bprint(mapname); + bprint(".ent\nFor instructions please read the\nreadme.html that comes with FrikBot */\n\n\n"); + + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = PrintBSPWaypoint; + fixer.enemy = world; + } +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_fight.qc b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_fight.qc new file mode 100755 index 00000000..bb8d9987 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_fight.qc @@ -0,0 +1,438 @@ +/*********************************************** +* * +* FrikBot Fight Code * +* "Because I ain't no Ghandi code" * +* * +***********************************************/ + +/* +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. +*/ + +.entity avoid; + +float(entity e) bot_size_player = +{ + local float sz; + + sz = e.health + e.armorvalue * e.armortype; + if (e.weapon == 32) + sz = sz + 60; + else if (e.weapon == 64) + sz = sz + 60; + else if (e.weapon == 16) + sz = sz + 50; + else if (e.weapon == 8) + sz = sz + 50; + else if (e.weapon == 4) + sz = sz + 40; + else if (e.weapon == 2) + sz = sz + 40; + else if (e.weapon == 1) + sz = sz + 10; + else if (e.weapon == 4096) + sz = sz - 50; + if (e.items & 4194304) // Quad + sz = sz + 200; + if (e.items & 1048576) // Invul + sz = sz + 300; + if (e.items & 524288) // Invis + sz = sz + 250; + return sz; +}; + +void() bot_dodge_stuff = +{ + local entity foe; + local float foedist, avdist, foesz, flen, tsz; + local vector v; + + if (waypoint_mode > WM_LOADED) + return; + + self.avoid = world; + + + if (self.enemy) + { + v = self.origin - realorigin(self.enemy); + foedist = vlen(v); + foesz = bot_size_player(self.enemy); + } + else + { + foedist = 3000; + foesz = 9999999; + } + avdist = 256; + + foe = find(world, classname, "grenade"); + while(foe) + { + flen = vlen(foe.origin - self.origin); + if (flen < avdist) + { + avdist = flen; + self.avoid = foe; + } + foe = find(foe, classname, "grenade"); + } + if (!self.avoid) + { + foe = find(world, classname, "missile"); + while(foe) + { + if (foe.owner != self) + { + flen = vlen(foe.origin - self.origin); + if (flen < avdist) + { + avdist = flen; + self.avoid = foe; + } + } + foe = find(foe, classname, "missile"); + } + if (!self.avoid) + { + foe = find(world, classname, "spike"); + while(foe) + { + if (foe.owner != self) + { + flen = vlen(foe.origin - self.origin); + if (flen < avdist) + { + avdist = flen; + self.avoid = foe; + } + } + foe = find(foe, classname, "spike"); + } + } + } + if (coop) + { + if (!self.enemy) + { + foe = findradius(self.origin, foedist); + while(foe) + { + if(foe.flags & FL_MONSTER) + { + if(foe.health > 0) + { + flen = vlen(foe.origin - self.origin); + if (flen < foedist) + { + tsz = bot_size_player(foe); + if (tsz < foesz) + { + if (fisible(foe)) + { + self.enemy = foe; + foedist = flen; + foesz = tsz; + } + } + } + } + } + foe = foe.chain; + } + } + } + else + { + foe = player_head; + while(foe) + { + if(foe != self) + { + if (foe.modelindex != 0) + { + if (foe.health > 0) + { + if (!(teamplay && self.team == foe.team)) + { + flen = vlen(foe.origin - self.origin); + if (flen < foedist) + { + tsz = bot_size_player(foe); + if (tsz < foesz) + { + if (fov(foe) || foe.b_sound > time || self.b_skill == 3) + { + if (fisible(foe)) + { + self.enemy = foe; + foedist = vlen(foe.origin - self.origin); + } + } + } + } + } + } + } + } + foe = foe._next; + } + } +}; + + + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +weapon_range + +_x "sweet spot range" - try to maintain this range if possible +_y minimum range bot can be to be effective (rl/gl) (move away) +_z maximum range bot can be to be effective (lg/axe) (move in) +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +vector(float wep) weapon_range = +{ + if (wep == 4096) // IT_AXE + return '48 0 64'; + else if (wep == 1) // IT_SHOTGUN + return '128 0 99999'; + else if (wep == 2) // IT_SUPER_SHOTGUN + return '128 0 99999'; + else if (wep == 4) // IT_NAILGUN + return '180 0 3000'; + else if (wep == 8) // IT_SUPER_NAILGUN + return '180 0 3000'; + else if (wep == 16) // IT_GRENADE_LAUNCHER + return '180 48 3000'; + else if (wep == 32) // IT_ROCKET_LAUNCHER + return '180 48 3000'; + else if (wep == 64) // IT_LIGHTNING + return '350 0 512'; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_weapon_switch + +Pick a weapon based on range / ammo + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(float brange) bot_weapon_switch = +{ + local float it, flag, pulse; + local vector v; + + it = self.items & 127; + + while(it) + { + if ((self.ammo_rockets >= 1) && (it & 32)) + { + flag = 32; + pulse = 7; + } + else if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & 64)) + { + flag = 64; + pulse = 8; + } + else if(self.ammo_nails >= 2 && (it & 8)) + { + flag = 8; + pulse = 5; + } + else if ((self.ammo_rockets >= 1) && (it & 16)) + { + flag = 16; + pulse = 6; + } + else if(self.ammo_shells >= 2 && (it & 2)) + { + flag = 2; + pulse = 3; + } + else if(self.ammo_nails >= 1 && (it & 4)) + { + flag = 4; + pulse = 4; + } + else if(self.ammo_shells >= 1 && (it & 1)) + { + flag = 1; + pulse = 2; + } + else + { + if (pulse) + self.impulse = pulse; + return; + } + + if (brange == -1) + { + if (pulse) + self.impulse = pulse; + return; + } + + v = weapon_range(flag); + if (brange < v_y || brange > v_z) + it = it - flag; + else + { + if (pulse) + self.impulse = pulse; + return; + } + } +}; + +void() bot_shoot = +{ + // quick little function to stop making him shoot the wrong way ! Argh + local float g; + g = angcomp(self.v_angle_x, self.b_angle_x); + if (fabs(g) > 30) + return; // argh, too far away + g = angcomp(self.v_angle_y, self.b_angle_y); + if (fabs(g) > 30) + return; // not again! + self.button0 = TRUE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot_fight_style + +This is the core of the bot's thinking when +attacking an enemy. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_fight_style = +{ + local vector v, v1, v2, org; + local float foedist, mysz, foesz; + + + if (self.enemy.health <= 0) + { + self.enemy = world; + return; + } + else if (!self.enemy.takedamage) + { + self.enemy = world; + return; + } + else if (!fisible(self.enemy)) + { + self.enemy = world; + return; + } + + org = realorigin(self.enemy); + makevectors(self.v_angle); + + // decide if I should shoot + + foedist = vlen(org - self.origin); + v = weapon_range(self.weapon); + if (foedist > v_y && foedist < v_z) + { + traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * v_z, FALSE, self); + if (vlen(trace_endpos - (self.origin + self.view_ofs)) >= v_y) + { + // try to avoid shooting teammates + if (trace_ent.classname == "player") + if ((trace_ent.team == self.team && teamplay) || (coop)) + return; + bot_shoot(); + } + } + else + bot_weapon_switch(foedist); + + if (!(self.b_aiflags & (AI_PRECISION | AI_BLIND | AI_OBSTRUCTED))) + { + foesz = bot_size_player(self.enemy); + mysz = bot_size_player(self) + 5; + + if (foesz > mysz) + { + if (teamplay) + { + if (random() < 0.02) + { + bot_start_topic(5); + self.b_chattime = 1; + } + } + + return; + } + else if (mysz < 140) + return; + else if (self.avoid) + { + if (self.avoid.velocity) + v = self.avoid.velocity; + else + v = normalize(self.avoid.origin - self.origin); + v1_x = v_y; + v1_y = v_y * -1; + v2_x = v_y; + v2_y = v_y * -1; + foedist = vlen(self.avoid.origin - (self.origin + v1)); + if (foedist < vlen(self.avoid.origin - (self.origin + v2))) + frik_walkmove(v2); + else + frik_walkmove(v1); + } + else if (!self.enemy.flags & FL_MONSTER) + { + if (foedist + 32 < v_x) + frik_walkmove(self.origin - org); + else if (foedist - 32 > v_x) + frik_walkmove(org - self.origin); + else if (self.wallhug) + frik_walkmove(v_right); + else + frik_walkmove(v_right * -1); + } + } + else + { + foesz = bot_size_player(self.enemy); + mysz = bot_size_player(self) + 5; + + if (foesz > mysz) + return; + else if (mysz < 140) + return; + self.keys = self.keys & 960; + } +}; + + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_misc.qc b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_misc.qc new file mode 100755 index 00000000..e177343f --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_misc.qc @@ -0,0 +1,758 @@ +/*********************************************** +* * +* FrikBot Misc Code * +* "Because you can't name it anything else" * +* * +***********************************************/ + +/* +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. +*/ + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotName + +Sets bot's name and colors + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +string(float r) BotName = +{ + self.b_num = r; + if (r == 1) + { + self.b_pants = 11; + self.b_shirt = 0; + return "Mexicouger"; + } + else if (r == 2) + { + self.b_pants = 1; + self.b_shirt = 3; + return "Nate"; + } + else if (r == 3) + { + self.b_pants = 13; + self.b_shirt = 2; + return "DTMidian"; + } + else if (r == 4) + { + self.b_pants = 7; + self.b_shirt = 6; + return "Ducksrule"; + } + else if (r == 5) + { + self.b_pants = 12; + self.b_shirt = 6; + return "Ghostfang"; + } + else if (r == 6) + { + self.b_pants = 4; + self.b_shirt = 4; + return "Shallows"; + } + else if (r == 7) + { + self.b_pants = 2; + self.b_shirt = 5; + return "Hypermetal"; + } + else if (r == 8) + { + self.b_pants = 10; + self.b_shirt = 3; + return "Kryten"; + } + else if (r == 9) + { + self.b_pants = 9; + self.b_shirt = 4; + return "Pimp Bot"; + } + else if (r == 10) + { + self.b_pants = 4; + self.b_shirt = 7; + return "Max"; + } + else if (r == 11) + { + self.b_pants = 3; + self.b_shirt = 11; + return "Marvin"; + } + else if (r == 12) + { + self.b_pants = 13; + self.b_shirt = 12; + return "Erwin"; + } + else if (r == 13) + { + self.b_pants = 11; + self.b_shirt = 2; + return "FrikBot"; + } + else if (r == 14) + { + self.b_pants = 0; + self.b_shirt = 2; + return "Krosis"; + } + else if (r == 15) + { + self.b_pants = 8; + self.b_shirt = 9; + return "Gypsy"; + } + else if (r == 16) + { + self.b_pants = 5; + self.b_shirt = 10; + return "Hal"; + } +}; +string () PickARandomName = +{ + if (bot_count > 16) + return "player"; + + local float y, test; + local string h; + local entity t; + y = TRUE; + while(y) + { + test = ceil(random() * 16); + h = BotName(test); + t = find(world, netname, h); + if (t == world) + y = FALSE; + } + return h; +}; + + + +// I didn't like the old code so this is very stripped down + +entity b_originator; +float b_topic; +/* FBX Topics + +b_originator == self + 1 - sign on + 2 - killed targ + 3 - team message "friendly eyes" + 4 - team message "on your back" + 5 - team message "need back up" + 6 - excuses + ---- + 7 - gameover + ---- + 8 - welcoming someone onto server + 9 - ridicule lost frag (killed self?) + 10 - ridicule lost frag (lava) + 11 - lag +b_originator == targ + + +*/ +void(float tpic) bot_start_topic = +{ + if (random() < 0.2) + { + b_topic = tpic; + b_originator = self; + } + else + b_topic = 0; +}; + +void() bot_chat = +{ + local float r; + if (b_options & OPT_NOCHAT) + return; + r = ceil (random() * 6); + + if (self.b_chattime > time) + { + if (self.b_skill < 2) + self.keys = self.button0 = self.button2 = 0; + return; + } + else if (self.b_chattime) + { + if (b_topic == 1) + { + if (b_originator == self) + { + if (r == 1) + { + BotSay(": lo all\n"); + bot_start_topic(8); + } + else if (r == 2) + { + BotSay(": hey everyone\n"); + bot_start_topic(8); + } + else if (r == 3) + { + BotSay(": prepare to be fragged!\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSay(": boy this is laggy\n"); + bot_start_topic(11); + } + else if (r == 5) + { + BotSay(": #mm getting some lag here\n"); + bot_start_topic(11); + } + else + { + BotSay(": hi everyone\n"); + bot_start_topic(8); + } + } + } + else if (b_topic == 2) + { + if (b_originator == self) + { + if (r == 1) + BotSay(": take that\n"); + else if (r == 2) + BotSay(": yehaww!\n"); + else if (r == 3) + BotSay(": wh00p\n"); + else if (r == 4) + BotSay(": j00_sawk();\n"); + else if (r == 5) + BotSay(": i rule\n"); + else + BotSay(": eat that\n"); + bot_start_topic(0); + } + } + else if (b_topic == 3) + { + if (b_originator == self) + { + if (r < 3) + BotSayTeam(": friendly eyes\n"); + else + BotSayTeam(": team eyes\n"); + bot_start_topic(0); + } + } + else if (b_topic == 4) + { + if (b_originator == self) + { + if (r < 3) + BotSayTeam(": on your back\n"); + else + BotSayTeam(": I'm with you\n"); + bot_start_topic(0); + } + } + else if (b_topic == 5) + { + if (b_originator == self) + { + if (r < 3) + BotSayTeam(": I need help\n"); + else + BotSayTeam(": need backup\n"); + bot_start_topic(0); + } + } + else if (b_topic == 6) + { + if (b_originator == self) + { + if (r == 1) + { + BotSay(": sun got in my eyes\n"); + bot_start_topic(0); + } + else if (r == 2) + { + BotSay(": mouse needs cleaning\n"); + bot_start_topic(0); + } + else if (r == 3) + { + BotSay(": i meant to do that\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSay(": lag\n"); + bot_start_topic(11); + } + else if (r == 5) + { + BotSay(": killer lag\n"); + bot_start_topic(11); + } + else + { + BotSay(": 100% lag\n"); + bot_start_topic(11); + } + } + } + else if (b_topic == 7) + { + if (r == 1) + BotSay(": gg\n"); + else if (r == 2) + BotSay(": gg all\n"); + else if (r == 3) + BotSay(": that was fun\n"); + else if (r == 4) + BotSay(": good game\n"); + else if (r == 5) + BotSay(": pah\n"); + else + BotSay(": hrm\n"); + bot_start_topic(0); + } + else if (b_topic == 8) + { + if (b_originator != self) + { + if (r == 1) + { + BotSay(": heya\n"); + bot_start_topic(0); + } + else if (r == 2) + { + BotSay(": welcome\n"); + bot_start_topic(0); + } + else if (r == 3) + { + BotSayInit(); + BotSay2(": hi "); + BotSay2(b_originator.netname); + BotSay2("\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSayInit(); + BotSay2(": hey "); + BotSay2(b_originator.netname); + BotSay2("\n"); + bot_start_topic(0); + } + else if (r == 5) + { + BotSay(": howdy\n"); + bot_start_topic(0); + } + else + { + BotSay(": lo\n"); + bot_start_topic(0); + } + } + } + + else if (b_topic == 9) + { + if (b_originator != self) + { + if (r == 1) + BotSay(": hah\n"); + else if (r == 2) + BotSay(": heheh\n"); + else if (r == 3) + { + BotSayInit(); + BotSay2(": good work "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 4) + { + BotSayInit(); + BotSay2(": nice1 "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 5) + BotSay(": lol\n"); + else + BotSay(": :)\n"); + b_topic = 6; + } + } + else if (b_topic == 10) + { + if (b_originator != self) + { + if (r == 1) + BotSay(": have a nice dip?\n"); + else if (r == 2) + BotSay(": bah I hate levels with lava\n"); + else if (r == 3) + { + BotSayInit(); + BotSay2(": good job "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 4) + { + BotSayInit(); + BotSay2(": nice backflip "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 5) + BotSay(": watch your step\n"); + else + BotSay(": hehe\n"); + b_topic = 6; + } + } + + else if (b_topic == 11) + { + if (b_originator != self) + { + if (r == 1) + { + BotSayInit(); + BotSay2(": yeah right "); + BotSay2(b_originator.netname); + BotSay2("\n"); + bot_start_topic(0); + } + else if (r == 2) + { + BotSay(": ping\n"); + bot_start_topic(0); + } + else if (r == 3) + { + BotSay(": shuddup, you're an lpb\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSay(": lag my eye\n"); + bot_start_topic(0); + } + else if (r == 5) + { + BotSay(": yeah\n"); + bot_start_topic(11); + } + else + { + BotSay(": totally\n"); + bot_start_topic(11); + } + } + } + self.b_chattime = 0; + } + else if (b_topic) + { + if (random() < 0.5) + { + if (self == b_originator) + { + if (b_topic <= 7) + self.b_chattime = time + 2; + } + else + { + if (b_topic >= 7) + self.b_chattime = time + 2; + } + } + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Kick A Bot. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() KickABot = +{ + local entity ty; + ty = find(world, classname, "player"); + while (ty != world) + { + if (!(ty.ishuman)) + { + + BotDisconnect(ty); + ty.ishuman = TRUE; + ty = world; + } + else + ty = find(ty, classname, "player"); + } + +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Simplified origin checking. + +God, I wish I had inline + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +vector(entity ent) realorigin = +{ +// even more simplified... + return (ent.absmin + ent.absmax) * 0.5; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +fisible + +a version of visible that checks for corners +of the bounding boxes + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float (entity targ) fisible = +{ + local vector spot1, org; + local float thruwater, pc1, pc2; + + org = realorigin(targ); + spot1 = self.origin + self.view_ofs; + + if (targ.solid == SOLID_BSP) + { + traceline (spot1, org, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; + } + else + { + pc1 = pointcontents(org); + pc2 = pointcontents(spot1); + if (targ.classname == "player") + thruwater = FALSE; + else if (pc1 == CONTENT_LAVA) + return FALSE; + else + thruwater = TRUE; + } + + if (pc1 < -1) // targ's origin is in water or other liquid + { + if (pc2 != pc1) + { + // look for their head + traceline (spot1, org + targ.mins, TRUE, self); + // cross the water check + if (trace_inopen) + if (trace_inwater) + if (!thruwater) + return FALSE; + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; + } + } + else + { + if (pc2 != pc1) + { + traceline (spot1, org + targ.maxs, TRUE, self); + if (trace_inopen) + if (trace_inwater) + if (!thruwater) + return FALSE; + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; + } + } + traceline (spot1, org, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + traceline (spot1, org + targ.maxs, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + traceline (spot1, org + targ.mins, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Wisible + +goes through movable brushes/entities, used +for waypoints + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +// this is used for waypoint stuff.... +float (entity targ1, entity targ2) wisible = +{ + local vector spot1, spot2; + local entity ignore; + + spot1 = targ1.origin; + spot2 = realorigin(targ2); + + ignore = self; + do + { + traceline (spot1, spot2, TRUE, ignore); + spot1 = realorigin(trace_ent); + ignore = trace_ent; + } while ((trace_ent != world) && (trace_fraction != 1)); + if (trace_endpos == spot2) + return TRUE; + else + return FALSE; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +sisible + +Now this is getting ridiculous. Simple visible, +used when we need just a simple traceline nothing else + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float (entity targ) sisible = +{ + traceline (self.origin, targ.origin, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +angcomp + +subtracts one angle from another + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float (float y1, float y2) angcomp = +{ + y1 = frik_anglemod(y1); + y2 = frik_anglemod(y2); + + local float answer; + answer = y1 - y2; + if (answer > 180) + answer = (360 - answer) * -1; + else if (answer < -180) + answer = answer + 360; + return answer; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +fov + +is the entity in the bot's field of view + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float (entity targ) fov = +{ + local vector yawn; + local float g; + yawn = realorigin(targ); + yawn = (yawn + targ.view_ofs) - (self.origin + self.view_ofs); + yawn = normalize(yawn); + yawn = vectoangles(yawn); + g = angcomp(self.v_angle_x, yawn_x); + if (fabs(g) > 45) + return FALSE; + g = angcomp(self.v_angle_y, yawn_y); + if (fabs(g) > 60) + return FALSE; + + return TRUE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +frik_anglemod + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float(float v) frik_anglemod = +{ + return v - floor(v/360) * 360; +} \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_move.qc b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_move.qc new file mode 100755 index 00000000..fd12f77c --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_move.qc @@ -0,0 +1,487 @@ +/*********************************************** +* * +* FrikBot Movement AI * +* "The slightly better movement AI" * +* * +***********************************************/ + +/* +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. +*/ + +void() bot_jump = +{ + // TODO check for precision, etc. + self.button2 = TRUE; +}; + +float(entity e) bot_can_rj = +{ + // this returns true of the bot can rocket/superjump/hook + // if your mod doesn't have an RL you can just return FALSE all the time + // if it has a hook or some other means for the bot to get to high places + // you can check here for that capability + + // am I dumb? + if (e.b_skill == 0) + return FALSE; + + // quad = bad + if (e.items & 4194304) + return FALSE; + + // do I have rockets & RL? + if (!((e.items & 32) && (e.ammo_rockets > 0))) + return FALSE; + + // do I have pent? + if (e.items & 1048576) + return TRUE; + + if (e.health > 50) + return TRUE; + else + return FALSE; +}; + +float(float flag) frik_recognize_plat = +{ + if ((self.classname != "waypoint") && !(self.flags & FL_ONGROUND)) + return FALSE; + traceline(self.origin, self.origin - '0 0 64', TRUE, self); + if (trace_ent != world) + { + if (flag) // afect bot movement too + { + if (self.keys & KEY_MOVEUP) + { + if (trace_ent.velocity_z > 0) + self.keys = self.keys & 960; // 960 is all view keys + } + else if (self.keys & KEY_MOVEDOWN) + { + if (trace_ent.velocity_z < 0) + self.keys = self.keys & 960; + } + } + return TRUE; + } + else + return FALSE; +}; + +float(vector sdir) frik_KeysForDir = +{ + + local vector keydir; + local float outkeys, tang; + outkeys = 0; + if (sdir_x || sdir_y) + { + // Everything is tested against 60 degrees, + // this allows the bot to overlap the keys + // 30 degrees on each diagonal 45 degrees + // might look more realistic + + keydir = vectoangles(sdir); + tang = angcomp(keydir_y, self.v_angle_y); + if ((tang <= 150) && (tang >= 30)) + outkeys = outkeys + KEY_MOVELEFT; + else if ((tang >= -150) && (tang <= -30)) + outkeys = outkeys + KEY_MOVERIGHT; + if (fabs(tang) <= 60) + outkeys = outkeys + KEY_MOVEFORWARD; + else if (fabs(tang) >= 120) + outkeys = outkeys + KEY_MOVEBACK; + } + if (sdir_z > 0.7) + outkeys = outkeys + KEY_MOVEUP; + else if (sdir_z < 0.7) + outkeys = outkeys + KEY_MOVEDOWN; + return outkeys; + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +frik_obstructed + +Bot has hit a ledge or wall that he should +manuever around. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(vector whichway, float danger) frik_obstructed = +{ + local float dist; + local vector disway, org; +// TODO: something + if (self.b_aiflags & AI_BLIND) + return; + org = realorigin(self.target1); + + if (danger) + { + self.b_aiflags = self.b_aiflags | AI_DANGER; + self.keys = frik_KeysForDir('0 0 0' - whichway); + } + if (self.b_aiflags & AI_PRECISION) + return; + + + if (self.target1) + { + if (self.b_aiflags & AI_OBSTRUCTED) + { + if (!(self.b_aiflags & AI_DANGER)) + { + self.b_aiflags = self.b_aiflags - AI_OBSTRUCTED; + return; + } + else if (!danger) + return; + } + self.obs_dir = whichway; + disway_x = whichway_y * -1; + disway_y = whichway_x; + dist = vlen(org - (self.origin + disway)); + disway_x = whichway_y; + disway_y = whichway_x * -1; + self.wallhug = vlen(org - (self.origin + disway)) > dist; + self.b_aiflags = self.b_aiflags | AI_OBSTRUCTED; + + } + else + { + disway_x = whichway_y * -1; + disway_y = whichway_x; + dist = vlen(disway - self.obs_dir); + disway_x = whichway_y; + disway_y = whichway_x * -1; + self.wallhug = vlen(disway - self.obs_dir) < dist; + self.obs_dir = whichway; + + self.b_aiflags = self.b_aiflags | AI_OBSTRUCTED; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +frik_obstacles + +Detects small bumps the bot needs to jump over +or ledges the bot should avoid falling in. + +Also responsible for jumping gaps. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_obstacles = +{ + local vector start, stop, ang; + local float test, conts, dist, hgt; + + if (!(self.flags & FL_ONGROUND)) + return; + if (self.b_aiflags & AI_BLIND) + return; + + ang = normalize(self.velocity); + ang_z = 0; + start = self.origin + ang * 32; // ahem + start_z = self.origin_z + self.maxs_z; + stop = start; + stop_z = self.origin_z + self.mins_z; + traceline(start, stop - '0 0 256', TRUE, self); + if (trace_allsolid || trace_startsolid) + return; + hgt = trace_endpos_z - stop_z; + + if (hgt > 18) + { + bot_jump(); + return; + } + else if (hgt <= -64) // this might be a gap + { + conts = pointcontents(trace_endpos + '0 0 4'); + start = stop - '0 0 8'; + stop = start + ang * 256; + traceline(start, stop, TRUE, self); + test = vlen(trace_endpos - start); + if (test <= 20) + return; // it's a walkable gap, do nothing + ang_x = self.velocity_y * -1; + ang_y = self.velocity_x; + ang = normalize(ang); + traceline(start - (ang * 10), start + (ang * 10), TRUE, self); + if ((trace_fraction != 1) || trace_startsolid) + return; // gap is only 20 wide, walkable + ang = self.velocity; + ang_z = 0; + dist = ((540 / sv_gravity) * vlen(ang))/* + 32*/; + if (test > dist) // I can't make it + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + else + { + if (self.target1) + { + stop = realorigin(self.target1); + if ((stop_z - self.origin_z) < -32) + return; // safe to fall + } + frik_obstructed(ang, FALSE); + return; + } + } + else + { + ang = normalize(ang); + //look for a ledge + traceline(self.origin, self.origin + (ang * (test + 20)), TRUE, self); + if (trace_fraction != 1) + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + else + { + if (self.target1) + { + stop = realorigin(self.target1); + if ((stop_z - self.origin_z) < -32) + return; // safe to fall + } + frik_obstructed(ang, FALSE); + return; + } + } + + if (self.target1) + { + // getting furter away from my target + test = vlen(self.target1.origin - (ang + self.origin)); + if (test > vlen(self.target1.origin - self.origin)) + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + else + { + frik_obstructed(ang, FALSE); + return; + } + } + } + } + // go for it + bot_jump(); + } + else if (pointcontents(trace_endpos + '0 0 4') < -3) + { + frik_obstructed(ang, TRUE); + return; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +After frik_obstructed, the bot uses the +following funtion to move "around" the obstacle + +I have no idea how well it will work + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_dodge_obstruction = +{ + local vector way, org; + local float oflags, yaw; + + if (!(self.b_aiflags & AI_OBSTRUCTED)) + return; + if ((self.b_aiflags & (AI_BLIND | AI_PRECISION)) || !(self.flags & FL_ONGROUND)) + { + self.b_aiflags = self.b_aiflags - AI_OBSTRUCTED; + return; + } + + // perform a walkmove check to see if the obs_dir is still obstructed + // walkmove is less forgiving than frik_obstacles, so I dunno + // how well this will work + + oflags = self.flags; + org = self.origin; + + yaw = vectoyaw(self.obs_dir); + if (walkmove(yaw, 32)) + self.b_aiflags = self.b_aiflags - AI_OBSTRUCTED; + else + { + if (self.b_aiflags & AI_DANGER) + { + way = '0 0 0' - self.obs_dir; + } + else if (self.wallhug) + { + way_x = self.obs_dir_y * -1; + way_y = self.obs_dir_x; + } + else + { + way_x = self.obs_dir_y; + way_y = self.obs_dir_x * -1; + } + self.keys = self.keys & 960 + frik_KeysForDir(way); + } + + // fix the bot + + self.origin = org; + self.flags = oflags; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +movetogoal and walkmove replacements + +blah + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_movetogoal = +{ + local vector way; + local float g; + + if (self.target1 == world) + { + makevectors(self.v_angle); + frik_walkmove(v_forward); + return; + } + way = realorigin(self.target1) - self.origin; + if (vlen(way) < 25) + { + self.keys = self.keys & 960; + return; + } + + way = normalize(way); + self.keys = self.keys & 960 + frik_KeysForDir(way); + + frik_dodge_obstruction(); + frik_recognize_plat(TRUE); + + if (self.b_aiflags & AI_PRECISION) + { + g = angcomp(self.v_angle_x, self.b_angle_x); + if (fabs(g) > 10) + self.keys = self.keys & 960; + g = angcomp(self.v_angle_y, self.b_angle_y); + if (fabs(g) > 10) + self.keys = self.keys & 960; + } +}; + +float(vector weird) frik_walkmove = +{ + // okay so it's not walkmove + // sue me + self.keys = self.keys & 960 + frik_KeysForDir(weird); + + frik_dodge_obstruction(); + frik_recognize_plat(TRUE); + if (self.b_aiflags & AI_OBSTRUCTED) + return FALSE; + else + return TRUE; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +The "hook" method of navigation. This nav +system is copyrighted 1999 by Ryan "Frika C" +Smith, keep that in mind when you steal it. + +I brought this back because normal roaming +won't work - the bot gets distracted by it's +own waypoints. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_bot_roam = +{ + local vector org, ang, org1; + local float loopcount, flag, dist; + + loopcount = 26; + flag = FALSE; + while((loopcount > 0) && !flag) + { + loopcount = loopcount - 1; + org = self.origin + self.view_ofs; + ang = self.angles; + ang_y = frik_anglemod(ang_y - 90 + (random() * 180)); + ang_x = 0; // avoid upward sloping + makevectors(ang); + traceline(org, org + v_forward * 2300, TRUE, self); + if (trace_fraction != 1) + { + org1 = trace_endpos; + ang = normalize(trace_plane_normal); + ang_z = 0; // avoid upward sloping + traceline(org1, org1 + (ang * 2300), TRUE, self); + if ((trace_fraction != 1) && (vlen(trace_endpos - org1) >= 64)) + { + org = trace_endpos; + traceline(org, self.origin + self.view_ofs, TRUE, self); + if (trace_fraction != 1) + { + dist = vlen(org1 - org) /2; + org = org1 + (ang * dist); + traceline(org, org - '0 0 48', TRUE, self); + if (trace_fraction != 1) + { + SpawnTempWaypoint(org); + flag = TRUE; + } + } + } + } + } + self.b_angle_y = self.v_angle_y + 10; +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_phys.qc b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_phys.qc new file mode 100755 index 00000000..cf51766a --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_phys.qc @@ -0,0 +1,658 @@ +/*********************************************** +* * +* FrikBot Physics * +* The near-perfect emulation of * +* Client movement * +* * +* Special Thanks to: Asdf, Frog * +* Alan "Strider" Kivlin * +* * +* * +***********************************************/ + +/* +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. +*/ + +/* +========================================= + +Stuff mimicking cl_input.c code + +========================================= +*/ +float(float key) CL_KeyState = +{ + return ((self.keys & key) > 0); +}; + +void() CL_KeyMove = // CL_BaseMove + CL_AdjustAngles +{ + local float anglespeed; + local vector view; + if (self.keys != self.oldkeys) + { + self.movevect = '0 0 0'; + self.movevect_y = self.movevect_y + (350 * CL_KeyState(KEY_MOVERIGHT)); + // 350 is the default cl_sidespeed + self.movevect_y = self.movevect_y - (350 * CL_KeyState(KEY_MOVELEFT)); + // 350 is the default cl_sidespeed + self.movevect_x = self.movevect_x + (200 * CL_KeyState(KEY_MOVEFORWARD)); + // 200 is the default cl_forwardspeed + self.movevect_x = self.movevect_x - (200 * CL_KeyState(KEY_MOVEBACK)); + // 200 is the default cl_backspeed + self.movevect_z = self.movevect_z + (200 * CL_KeyState(KEY_MOVEUP)); + // 200 is the default cl_upspeed + self.movevect_z = self.movevect_z - (200 * CL_KeyState(KEY_MOVEDOWN)); + // 200 is the default cl_upspeed + if (!self.b_aiflags & AI_PRECISION) + self.movevect = self.movevect * 2; + // 2 is the default cl_movespeedkey & bot always has +speed + } + self.oldkeys = self.keys; + + if (self.b_skill != 2) // use mouse emulation + { + anglespeed = 1.5 * real_frametime; + // 1.5 is the default cl_anglespeedkey & bot always has +speed + self.v_angle_y = self.v_angle_y + anglespeed * CL_KeyState(KEY_LOOKLEFT) * 140; + // 140 is default cl_yawspeed + self.v_angle_y = self.v_angle_y - anglespeed * CL_KeyState(KEY_LOOKRIGHT) * 140; + // 140 is default cl_yawspeed + self.v_angle_x = self.v_angle_x - anglespeed * CL_KeyState(KEY_LOOKUP) * 150; + // 150 is default cl_pitchspeed + self.v_angle_x = self.v_angle_x + anglespeed * CL_KeyState(KEY_LOOKDOWN) * 150; + // 150 is default cl_pitchspeed + } + else + { + view_x = angcomp(self.b_angle_x, self.v_angle_x); + view_y = angcomp(self.b_angle_y, self.v_angle_y); + if (vlen(view) > 30) + { + self.mouse_emu = self.mouse_emu + (view * 30); + if (vlen(self.mouse_emu) > 180) + self.mouse_emu = normalize(self.mouse_emu) * 180; + } + else + self.mouse_emu = view * (1 / real_frametime); + self.v_angle = self.v_angle + self.mouse_emu * real_frametime; + + + } + if (self.v_angle_x > 80) + self.v_angle_x = 80; + else if (self.v_angle_x < -70) + self.v_angle_x = -70; + + if (self.v_angle_z > 50) + self.v_angle_z = 50; + else if (self.v_angle_z < -50) + self.v_angle_z = -50; + self.v_angle_y = frik_anglemod(self.v_angle_y); + +}; + +/* +========================================= + +Stuff mimicking sv_user.c + +========================================= +*/ +void() SV_UserFriction = +{ + local vector vel, start, stop; + local float sped, friction, newspeed; + + vel = self.velocity; + vel_z =0; + sped = vlen(vel); + vel = self.velocity; + + if (!sped) + return; + +// if the leading edge is over a dropoff, increase friction + + start_x = stop_x = self.origin_x + vel_x / (sped * 16); + start_y = stop_y = self.origin_y + vel_y / (sped * 16); + start_z = self.origin_z + self.mins_z; + stop_z = start_z - 34; + + traceline(start, stop, TRUE, self); + + if (trace_fraction == 1) + friction = sv_friction * 2; // 2 is default edgefriction, removed for QW compatability + else + friction = sv_friction; + if (sped < sv_stopspeed) + newspeed = sped - real_frametime * sv_stopspeed * friction; + else + newspeed = sped - real_frametime * sped * friction; + + if (newspeed < 0) + newspeed = 0; + newspeed = newspeed / sped; + + self.velocity_y = vel_y * newspeed; + self.velocity_x = vel_x * newspeed; +}; +void() SV_WaterJump = +{ + if (time > self.teleport_time || !self.waterlevel) + { + self.flags = self.flags - (self.flags & FL_WATERJUMP); + self.teleport_time = 0; + } + self.velocity_x = self.movedir_x; + self.velocity_y = self.movedir_y; +}; + +void() DropPunchAngle = +{ + local float len; + len = vlen(self.punchangle); + self.punchangle = normalize(self.punchangle); + len = len - 10 * real_frametime; + if (len < 0) + len = 0; + self.punchangle = self.punchangle * len; +}; + + +void(vector wishvel) SV_AirAccelerate = +{ + local float addspeed, wishspd, accelspeed, currentspeed; + + wishspd = vlen(wishvel); + wishvel = normalize(wishvel); + if (wishspd > 30) + wishspd = 30; + currentspeed = self.velocity * wishvel; + addspeed = wishspd - currentspeed; + if (addspeed <= 0) + return; + accelspeed = 10 * sv_accelerate * wishspd * real_frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + self.velocity = self.velocity + accelspeed * wishvel; +}; + +void(vector wishvel) SV_Accelerate = +{ + local float addspeed, wishspd, accelspeed, currentspeed; + + wishspd = vlen(wishvel); + wishvel = normalize(wishvel); + + currentspeed = self.velocity * wishvel; + addspeed = wishspd - currentspeed; + if (addspeed <= 0) + return; + accelspeed = sv_accelerate * wishspd * real_frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + self.velocity = self.velocity + accelspeed * wishvel; +}; +void() SV_WaterMove = +{ + local vector wishvel; + local float wishspeed, addspeed, cspeed, newspeed; + makevectors(self.v_angle); + wishvel = v_right * self.movevect_y + v_forward * self.movevect_x; + + if (self.movevect == '0 0 0') + wishvel_z = wishvel_z - 60; + else + wishvel_z = wishvel_z + self.movevect_z; + wishspeed = vlen(wishvel); + + if (wishspeed > sv_maxspeed) + { + wishvel = (sv_maxspeed / wishspeed) * wishvel; + wishspeed = sv_maxspeed; + } + wishspeed = wishspeed * 0.7; + cspeed = vlen(self.velocity); + if (cspeed) + { + newspeed = cspeed - (real_frametime * cspeed * sv_friction); + if (newspeed < 0) + newspeed = 0; + self.velocity = self.velocity * (newspeed / cspeed); + + } + else + newspeed = 0; + + if (!wishspeed) + return; + addspeed = wishspeed - newspeed; + if (addspeed <= 0) + return; + wishvel = normalize(wishvel); + cspeed = sv_accelerate * wishspeed * real_frametime; + if (cspeed > addspeed) + cspeed = addspeed; + self.velocity = self.velocity + cspeed * wishvel; +}; +void() SV_AirMove = +{ + local vector wishvel, vangle; + + vangle = self.v_angle; + vangle_x = vangle_z = 0; + makevectors(vangle); + if (time < self.teleport_time && (self.movevect_x < 0)) + self.movevect_x = 0; + wishvel = v_right * self.movevect_y + v_forward * self.movevect_x; + + + if (self.movetype != MOVETYPE_WALK) + wishvel_z = self.movevect_z; + else + wishvel_z = 0; + if (vlen(wishvel) > sv_maxspeed) + wishvel = normalize(wishvel) * sv_maxspeed; + if (self.movetype == MOVETYPE_NOCLIP) + self.velocity = wishvel; + else if (self.flags & FL_ONGROUND) + { + SV_UserFriction(); + SV_Accelerate(wishvel); + } + else + SV_AirAccelerate (wishvel); +}; + +void() SV_ClientThink = +{ + local vector vangle; + + if (self.movetype == MOVETYPE_NONE) + return; + DropPunchAngle(); + if (self.health <= 0) + return; + self.v_angle_z = 0; // V_CalcRoll removed, sucks + self.angles_z = self.v_angle_z * 4; + vangle = self.v_angle + self.punchangle; + if (!self.fixangle) + { + self.angles_x = (vangle_x / -3); + self.angles_y = vangle_y; + } else + { + self.v_angle = self.angles; + self.fixangle = 0; + } + if (self.flags & FL_WATERJUMP) + { + SV_WaterJump(); + return; + } + if ((self.waterlevel >= 2) && (self.movetype != MOVETYPE_NOCLIP)) + { + SV_WaterMove(); + return; + } + SV_AirMove(); + +}; +/* +========================================= + +Stuff mimicking sv_phys.c + +========================================= +*/ + +float() SV_RunThink = +{ + local float thinktime, bkuptime; + thinktime = self.nextthink; + bkuptime = time; + if (thinktime <= 0 || thinktime > (time + real_frametime)) + return TRUE; + if (thinktime < time) + thinktime = time; + self.nextthink = 0; + time = thinktime; + other = world; + makevectors(self.v_angle); // hack + self.think(); + time = bkuptime; + return TRUE; +}; + +void(float scale) SV_AddGravity = +{ + self.velocity_z = self.velocity_z - (scale * sv_gravity * real_frametime); +}; + +float() SV_CheckWater = +{ + local vector point; + local float cont; + + point_x = self.origin_x; + point_y = self.origin_y; + self.waterlevel = 0; + self.watertype = CONTENT_EMPTY; + point_z = self.origin_z + self.mins_z + 1; + cont = pointcontents(point); + if (cont <= CONTENT_WATER) + { + self.watertype = cont; + self.waterlevel = 1; + point_z = self.origin_z + (self.mins_z + self.maxs_z) * 0.5; + cont = pointcontents(point); + if (cont <= CONTENT_WATER) + { + self.waterlevel = 2; + point_z = self.origin_z + self.view_ofs_z; + cont = pointcontents(point); + if (cont <= CONTENT_WATER) + self.waterlevel = 3; + } + } + return (self.waterlevel > 1); + +}; +void() RemoveThud = // well sometimes +{ + local entity oself; + if (other == world) + { + if (self.flags & FL_ONGROUND) + { + self.flags = self.flags - FL_ONGROUND; + } + } + else + { + if (other.solid == SOLID_BSP && (self.flags & FL_ONGROUND)) + { + // RM: Does this break anything? + // If not, then some more thuds have been removed. + self.flags = self.flags - FL_ONGROUND; + } + if (other == self.owner) + return; + if (self.owner.solid == SOLID_NOT) + return; + oself = other; + other = self.owner; + self = oself; + if (self.solid == SOLID_BSP) + if (self.touch) + self.touch(); + } + +}; +void() SV_CheckOnGround = +{ + local vector org, v; + org = self.origin; + local float currentflags; + currentflags = self.flags; + self.flags = self.flags | FL_ONGROUND | FL_PARTIALGROUND; + walkmove(0,0); // perform C touch function + self.flags = currentflags | FL_ONGROUND; + if ((org_x != self.origin_x) || (org_y != self.origin_y)) + org = self.origin; + else + self.origin = org; + v = org; + v_z = self.maxs_z + org_z + 1; + traceline (org, v, TRUE, self); + if ((self.waterlevel == 3) && (self.movetype == MOVETYPE_WALK)) + self.flags = self.flags - FL_ONGROUND; + else if ((trace_plane_normal_z <= 0.7) && (trace_fraction != 1)) + self.flags = self.flags - FL_ONGROUND; + else if (!droptofloor(0,0)) + self.flags = self.flags - FL_ONGROUND; + else if (org_z - self.origin_z < 2) + self.flags = self.flags | FL_ONGROUND; + else + self.flags = self.flags - FL_ONGROUND; + setorigin(self, org); +}; +// Thanks to Alan Kivlin for this function +// modified heavily by me +float(vector dir) botCheckForStep = +{ + local vector currentorigin, v; + local float currentflags, yaw, stepdistance, movedistance; + currentorigin = self.origin; + currentflags = self.flags; + self.flags = FL_ONGROUND | FL_PARTIALGROUND; + dir = normalize(dir); + dir_z = 0; + yaw = vectoyaw(dir); + if(walkmove(yaw, 3)) + { + if(droptofloor(0,0)) + { + stepdistance = self.origin_z - currentorigin_z; + v = self.origin - currentorigin; + v_z = 0; + movedistance = vlen(v); + if((stepdistance > 0 && stepdistance <= 16) && movedistance != 0) + { + self.flags = currentflags | FL_PARTIALGROUND; + return 1; + } + } + } + self.flags = currentflags; + setorigin(self, currentorigin); + return 0; +}; +// this is merely here to fix a problem with e3m5 +void(vector dir) BruteForceStep = +{ + local vector currentorigin; + local float currentflags, i, len; + + currentorigin = self.origin; + currentflags = self.flags; + len = vlen(dir); + if (len > 16) + dir = normalize(dir) * 16; + + setorigin(self, currentorigin + dir); + + while(i < 18 && !walkmove(0, 0)) + { + self.origin_z = currentorigin_z + i; + i = i + 2; + } + self.flags = currentflags; + if (i >=18) + setorigin(self, currentorigin); +}; + +void() PostPhysics = +{ + local vector obstr, org; + local float back, dst,cflags; + + self = self.owner; + + self.velocity = self.velocity - self.phys_obj.dest1 + self.phys_obj.velocity; + if (self.phys_obj.dest2 == self.origin) + { + setorigin(self, self.phys_obj.origin); + // might've been moved during other person's physics + // (teleporters / plats) + + if (self.movetype == MOVETYPE_WALK) + { + + if (self.phys_obj.dest1_x || self.phys_obj.dest1_y) + { + if ((self.flags & FL_ONGROUND) || (self.waterlevel <= 2)) + { + obstr = self.phys_obj.movedir - self.origin; + obstr_z = 0; + if (vlen(obstr) > 0.1) + { + dst = vlen(obstr); + back = vectoyaw(obstr); + cflags = self.flags; + self.flags = self.flags | FL_PARTIALGROUND; + if(walkmove(back, dst)) + { + self.flags = cflags; + self.phys_obj.dest1_z = 0; + self.velocity = self.velocity + self.phys_obj.dest1 - self.phys_obj.velocity; + } + else + { + if (dst > 1) + frik_obstructed(obstr, FALSE); + + org = self.origin; + self.flags = cflags; + obstr = self.phys_obj.dest1; + obstr_x = 0; + if (!botCheckForStep(obstr)) + { + obstr = self.phys_obj.dest1; + obstr_y = 0; + if (!botCheckForStep(obstr)) + { + // if no steps were found, bot is really obstucted + BruteForceStep(self.phys_obj.dest1); + } + } + } + } + } + } + } + } + + SV_CheckOnGround(); + + PlayerPostThink(); + BotAI(); + self.dmg_take = self.dmg_save = 0; + +}; +// Avoid calling BotAI and the physics at the same time +// Can trip the runaway loop counter + +void() SV_FlyMove = +{ + // This is nothing like the Quake function. + + if (self.phys_obj == world) + { + self.phys_obj = find(world,classname,"phys_obj"); + while (self.phys_obj.owner != self) + { + self.phys_obj = find(self.phys_obj,classname,"phys_obj"); + if (self.phys_obj == world) + { + error("No physics entity spawned!\nMake sure BotInit was called\n"); + } + } + } + + setmodel (self.phys_obj, string_null); + self.phys_obj.movetype = MOVETYPE_STEP; + + self.phys_obj.solid = SOLID_TRIGGER; + self.phys_obj.touch = RemoveThud; + setsize(self.phys_obj, self.mins, self.maxs); + self.phys_obj.dest2 = self.phys_obj.origin = self.origin; + self.phys_obj.watertype = 0; + self.phys_obj.movedir = self.origin + real_frametime * self.velocity; + self.phys_obj.dest1 = self.phys_obj.velocity = self.velocity; + self.phys_obj.velocity_z = self.phys_obj.velocity_z + sv_gravity * real_frametime; + self.phys_obj.flags = 0; + self.phys_obj.think = PostPhysics; + self.phys_obj.nextthink = time; +}; + + +void() SV_Physics_Toss = +{ + if (!SV_RunThink()) + return; + if (self.flags & FL_ONGROUND) + { + self.velocity = '0 0 0'; + BotAI(); + return; + } + if (self.movetype != MOVETYPE_FLY) + SV_AddGravity(1); + self.angles = self.angles + real_frametime * self.avelocity; + SV_FlyMove(); + +}; +void() SV_Physics_Client = +{ + + PlayerPreThink(); + + if (self.movetype == MOVETYPE_NONE) + { + if (!SV_RunThink()) + return; + PlayerPostThink(); + BotAI(); + + } + else if ((self.movetype == MOVETYPE_WALK) || (self.movetype == MOVETYPE_STEP)) + { + if (!SV_RunThink()) + return; + if (!(SV_CheckWater()) && (!(self.flags & FL_WATERJUMP))) + SV_AddGravity(1); + SV_FlyMove(); + } + else if ((self.movetype == MOVETYPE_TOSS) || (self.movetype == MOVETYPE_BOUNCE)) + { + SV_Physics_Toss(); + } + else if (self.movetype == MOVETYPE_FLY) + { + if (!SV_RunThink()) + return; + SV_FlyMove(); + } + else if (self.movetype == MOVETYPE_NOCLIP) + { + if (!SV_RunThink()) + return; + self.origin = self.origin + real_frametime * self.velocity; + + PlayerPostThink(); + BotAI(); + } + else + error ("SV_Physics_Client: Bad Movetype (BOT)"); + +}; + + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_way.qc b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_way.qc new file mode 100755 index 00000000..70946e74 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/frikbot/bot_way.qc @@ -0,0 +1,981 @@ + /*********************************************** +* * +* FrikBot Waypoints * +* "The better than roaming AI" * +* * +***********************************************/ + +/* +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. +*/ + + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Linking code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +float (entity e1, entity e2) CheckLinked = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return FALSE; + else if (e1.target1 == e2) + { + if (e1.b_aiflags & AI_TELELINK_1) + return 2; + else return TRUE; + } + else if (e1.target2 == e2) + { + if (e1.b_aiflags & AI_TELELINK_2) + return 2; + else return TRUE; + } + else if (e1.target3 == e2) + { + if (e1.b_aiflags & AI_TELELINK_3) + return 2; + else return TRUE; + } + else if (e1.target4 == e2) + { + if (e1.b_aiflags & AI_TELELINK_4) + return 2; + else return TRUE; + } + + else return FALSE; +}; + + +float (entity e1, entity e2) LinkWays = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return FALSE; + else if (CheckLinked(e1, e2)) + return FALSE; // already linked!!! + + if (e1.target1 == world) + { + e1.target1 = e2; + return TRUE; + } + else if (e1.target2 == world) + { + e1.target2 = e2; + return TRUE; + } + else if (e1.target3 == world) + { + e1.target3 = e2; + return TRUE; + } + else if (e1.target4 == world) + { + e1.target4 = e2; + return TRUE; + } + else return FALSE; + +}; +// Link Ways part 2, used only for teleporters + +float (entity e1, entity e2) TeleLinkWays = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return FALSE; + else if (CheckLinked(e1, e2)) + return FALSE; // already linked!!! + + if (e1.target1 == world) + { + e1.target1 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_1; + return TRUE; + } + else if (e1.target2 == world) + { + e1.target2 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_2; + return TRUE; + } + else if (e1.target3 == world) + { + e1.target3 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_3; + return TRUE; + } + else if (e1.target4 == world) + { + e1.target4 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_4; + return TRUE; + } + else + return FALSE; + +}; + +void (entity e1, entity e2) UnlinkWays = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return; + else if (!CheckLinked(e1, e2)) + return; + + if (e1.target1 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_1); + e1.target1 = world; + } + if (e1.target2 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_2); + e1.target2 = world; + } + if (e1.target3 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_3); + e1.target3 = world; + } + if (e1.target4 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_4); + e1.target4 = world; + } + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +FindWaypoint + +This is used quite a bit, by many different +functions big lag causer + +Finds the closest, fisible, waypoint to e + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +entity(entity start) FindWayPoint = +{ + local entity t; + local vector org; + local float dst, tdst; + local entity best; + + org = realorigin(self); + + t = way_head; + if (start != world) + { + dst = vlen(start.origin - org); + best = start; + } + else + { + dst = 100000; + best = world; + } + while(t) + { + // real players cut through ignore types + if (dst < 20) + return best; + if (!(t.b_aiflags & AI_IGNORE_TYPES) || self.ishuman) + { + tdst = vlen(t.origin - org); + if (tdst < dst) + { + if (sisible(t)) + { + dst = tdst; + best = t; + } + } + } + t = t._next; + } + return best; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Spawning Code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +entity way_foot; // Ugh. Do I need a foot for this or not? + +entity(vector org) make_waypoint = +{ + local entity point; + point = spawn(); + point.classname = "waypoint"; + point.search_time = time; // don't double back for me; + point.solid = SOLID_TRIGGER; + point.movetype = MOVETYPE_NONE; + point.items = -1; + setorigin(point, org); + + setsize(point, VEC_HULL_MIN, VEC_HULL_MAX); + waypoints = waypoints + 1; + if (!way_head) + { + way_head = point; + way_foot = point; + } + else + { + way_foot._next = point; + point._last = way_foot; + way_foot = point; + } + + point.count = waypoints; + if (waypoint_mode > WM_LOADED) // editor modes + setmodel(point, "progs/s_bubble.spr"); + return point; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Dynamic Waypoint spawning and linking. Not +very good all things considered. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() DynamicWaypoint = +{ + local entity t; + local float dist, dynlink, dynpoint, editor; + + if (self.teleport_time > self.portal_time) + { + if (!self.flags & FL_WATERJUMP) + { + self.dyn_flags = 2; + if (!self.ishuman) + { + bot_lost(self.target1, TRUE); + self.enemy = world; + } + } + self.portal_time = self.teleport_time; + } +// stacking everything on waypoint_mode might've been good for the editor, +// but it sucks to beat hell for this code. + + +// convert waypoint_mode to something more usable.. + if (waypoint_mode > WM_LOADED) + { + if (self.ishuman) + { + if (waypoint_mode == WM_EDITOR_DYNLINK) + dynlink = 1; + else if (waypoint_mode == WM_EDITOR_DYNAMIC) + dynlink = dynpoint = 1; + editor = 1; + } + } + else if (waypoint_mode == WM_DYNAMIC) + dynlink = dynpoint = 1; + +// if there's nothing for dynamic to do.. + if (!dynpoint) + { + if (!editor) + return; + } +// for speed sake, I won't have bots dynamic waypoint in coop + if (!self.ishuman) + if (coop) + return; + +// don't waypoint in single player + if (max_clients < 2) + return; +// if you're dead + else if (self.health <= 0) + { + if (dynpoint) + { + if (self.current_way) + { + if (pointcontents(self.origin) < -4) + { + if (self.current_way.b_aiflags & AI_BLIND) + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_PRECISION; + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_BLIND; + } + } + } + self.dyn_dest = '0 0 0'; + self.current_way = world; + self.dyn_flags = 0; + return; + } + +// you shouldn't be making waypoints mid air + if (dynpoint) + { + if (!((self.flags & FL_ONGROUND) || self.waterlevel == 3)) + { + if (self.dyn_flags != 2) + { + self.dyn_flags = 1; + } + return; + } + } +// keep from doing the rest of this every frame + if (self.dyn_time > time) + return; + self.dyn_time = time + 0.2; + +// display the links for editor mode + if (editor) + { + if (self.current_way) + { + if (self.current_way.target1) + DeveloperLightning(self.current_way, self.current_way.target1, self.current_way.b_aiflags & AI_TELELINK_1); + if (self.current_way.target2) + DeveloperLightning(self.current_way, self.current_way.target2, self.current_way.b_aiflags & AI_TELELINK_2); + if (self.current_way.target3) + DeveloperLightning(self.current_way, self.current_way.target3, self.current_way.b_aiflags & AI_TELELINK_3); + if (self.current_way.target4) + DeveloperLightning(self.current_way, self.current_way.target4, self.current_way.b_aiflags & AI_TELELINK_4); + } + if (self.b_aiflags & AI_HOLD_SELECT) + return; + } + + t = FindWayPoint(self.current_way); + if (t) + { + dist = vlen(self.origin - t.origin); + if (dist < 192) + { + if (dist < 64) + { + + if (t != self.current_way) + { + if (dynlink) + { + if (!self.dyn_flags) + { + if (wisible(t, self.current_way)) + LinkWays(t, self.current_way); + } + if (self.dyn_flags == 2) + TeleLinkWays(self.current_way, t); + else if (wisible(t, self.current_way)) + LinkWays(self.current_way, t); + } + if (editor) + { + setmodel(t, "progs/s_light.spr"); + if (self.current_way) + setmodel(self.current_way, "progs/s_bubble.spr"); + } + } + self.current_way = t; + self.dyn_flags = 0; + } + self.dyn_dest = self.origin + self.view_ofs; + return; + } + } + + if (frik_recognize_plat(FALSE)) + { + if (vlen(trace_ent.velocity) > 0) + { + if (self.dyn_plat) + return; + self.dyn_plat = TRUE; + if (!self.dyn_flags) + self.dyn_flags = 1; + //bprint("on a plat!!!!!\n"); + } + else + self.dyn_plat = FALSE; + } + else + self.dyn_plat = FALSE; + + if (self.dyn_flags == 2) + self.dyn_dest = self.origin + self.view_ofs; + else if (self.dyn_dest == '0 0 0') + self.dyn_dest = self.origin + self.view_ofs; + if (!dynpoint) + return; + t = make_waypoint(self.dyn_dest); + + if (!self.dyn_flags) + { + if (wisible(t, self.current_way)) + LinkWays(t, self.current_way); + } + if (self.dyn_flags == 2) + TeleLinkWays(self.current_way, t); + else if (wisible(t, self.current_way)) + LinkWays(self.current_way, t); + + if (editor) + { + setmodel(t, "progs/s_light.spr"); + if (self.current_way) + setmodel(self.current_way, "progs/s_bubble.spr"); + } + self.current_way = t; + self.dyn_flags = 0; + + self.dyn_dest = self.origin + self.view_ofs; + + if (frik_recognize_plat(FALSE)) + { + if (trace_ent.classname == "door") + t.b_aiflags = t.b_aiflags | AI_DOORFLAG; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Loading from file + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClearAllWays = +{ + + local entity t, n; + t = way_head; + while(t) + { + n = t._next; + remove(t); + t = n; + } + way_head = world; + way_foot = world; + waypoints = 0; +}; + +entity(float num) WaypointForNum = +{ + local entity t; + if (!num) + return world; + + t = way_head; + while (t) + { + if (t.count == num) + return t; + t = t._next; + } + return world; +}; + +void() FixThisWaypoint = +{ + self.enemy.target1 = WaypointForNum(self.enemy.b_pants); + self.enemy.target2 = WaypointForNum(self.enemy.b_skill); + self.enemy.target3 = WaypointForNum(self.enemy.b_shirt); + self.enemy.target4 = WaypointForNum(self.enemy.b_frags); + self.enemy = self.enemy._next; + self.nextthink = time; + if (self.enemy == world) + { + remove(self); + fixer = world; + } +}; + +void() FixWaypoints = +{ + if (!fixer) + fixer = spawn(); + fixer.nextthink = time; + fixer.think = FixThisWaypoint; + fixer.enemy = way_head; +}; + + + +void(entity what) delete_waypoint = +{ + local entity t; + + if (way_head == what) + way_head = what._next; + if (way_foot == what) + way_foot = what._last; + if (what._last) + what._last._next = what._next; + if (what._next) + what._next._last = what._last; + waypoints = 0; + t = way_head; + while(t) + { + t.count = waypoints = waypoints + 1; + if (CheckLinked(t, what)) + UnlinkWays(t, what); + t = t._next; + } + if (self.current_way == what) + self.current_way = world; + remove(what); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +FindRoute & FindThing used by the pathing code +in bot_ai.qc + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +entity(string s) FindThing = +{ + local entity t; + local float tdst, dst; + local entity best; + dst = 100000; + best = world; + t = find (world, classname, s); + while (t != world) + { + tdst = vlen(((t.absmin + t.absmax) * 0.5) - self.origin); + if (tdst < dst) + { + dst = tdst; + best = t; + } + t = find(t, classname, s); + } + return best; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +FindRoute, this is a key function in the +pathing. The name is a bit misleading, this +code finds the closest waypoint that is part +of a route calculated by the begin_route and +end_route routines This is a definite path to +an object. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +entity(entity lastone) FindRoute = +{ + // kinda like FindWaypoint, only of this bots route though + local entity t, best; + local float dst, tdst, flag; + flag = ClientBitFlag(self.b_clientno); + t = way_head; + dst = 100000; + best = world; + while(t) + { + tdst = vlen(t.origin - self.origin); + if ((tdst < dst) && (t.b_sound & flag)) + { + if ((lastone == world) || (CheckLinked(lastone, t))) + { + dst = tdst; + best = t; + } + } + t = t._next; + } + return best; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Route & path table management + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClearRouteTable = +{ + // cleans up route table + + local entity t; + t = way_head; + while (t) + { + t. keys = FALSE; + t.enemy = world; + t.items = -1; // not in table + t = t._next; + } +}; + +void() ClearMyRoute = +{ + local float flag; + local entity t; + + flag = ClientBitFlag(self.b_clientno); + + t = way_head; + while (t) + { + t.b_sound = t.b_sound - (t.b_sound & flag); + t = t._next; + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Mark_path + +After the route has been found, mark it with +bitflags so the table can be used for a +different bot. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void(entity this) mark_path = +{ + local entity t, oself; + local float flag; + + ClearMyRoute(); + + oself = self; + self = this; + t = FindWayPoint(this.current_way); + self = oself; + // FIXME + // ugh, better way to find players please!!! + if (this.classname != "player") + this.current_way = t; + + if (t.enemy == world) + { + bot_lost(this, FALSE); + if (waypoint_mode == WM_DYNAMIC) + self.route_failed = TRUE; + return; + } + + flag = ClientBitFlag(self.b_clientno); + + while(t) + { + if (t.b_sound & flag) + return; + if (t == self.last_way) + return; + t.b_sound = t.b_sound | flag; + t = t.enemy; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +WaypointThink + +Calculates the routes. We use thinks to avoid +tripping the runaway loop counter + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity e2, float b_bit) FollowLink = +{ + local float dist; + + if (self.b_aiflags & b_bit) + dist = self.items; + else + dist = vlen(self.origin - e2.origin) + self.items; + + // check if this is an RJ link + if (e2.b_aiflags & AI_SUPER_JUMP) + { + if (!bot_can_rj(route_table)) + return; + } + if (e2.b_aiflags & AI_DIFFICULT) + dist = dist + 1000; + + dist = dist + random() * 100; // add a little chaos + + if ((dist < e2.items) || (e2.items == -1)) + { + if (!e2.keys) + busy_waypoints = busy_waypoints + 1; + e2.keys = TRUE; + e2.items = dist; + e2.think = WaypointThink; + e2.nextthink = time; + e2.enemy = self; + } +}; + +void() WaypointThink = +{ + local entity oself; + + if (self.items == -1) + return; + // can you say ugly? + if (self.b_aiflags & AI_TRACE_TEST) + { + if (self.target1) + { + traceline(self.origin, self.target1.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target1, AI_TELELINK_1); + } + if (self.target2) + { + traceline(self.origin, self.target2.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target2, AI_TELELINK_2); + } + if (self.target3) + { + traceline(self.origin, self.target3.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target3, AI_TELELINK_3); + } + if (self.target4) + { + traceline(self.origin, self.target4.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target4, AI_TELELINK_4); + } + } + else + { + if (self.target1) + FollowLink(self.target1, AI_TELELINK_1); + if (self.target2) + FollowLink(self.target2, AI_TELELINK_2); + if (self.target3) + FollowLink(self.target3, AI_TELELINK_3); + if (self.target4) + FollowLink(self.target4, AI_TELELINK_4); + } + + busy_waypoints = busy_waypoints - 1; + self.keys = FALSE; + + if (busy_waypoints <= 0) + { + if (direct_route) + { + oself = self; + self = route_table; + bot_get_path(self.target1, FALSE); + self = oself; + direct_route = FALSE; + } + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +begin_route and bot_get_path + +PLEASE NOTE: bot_get_path replaces the old +calls to begin_route. + +Routing isn't done all at once now, but in two +stages, the bot will calc a route *THEN* +choose a target, *THEN* mark a path. + +Boy it's confusing. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float() begin_route = +{ + if (busy_waypoints > 0) + return FALSE; + + if (route_table != world) + { + if (!route_table.ishuman) + { + if (route_table.b_clientno != -1) + return FALSE; + } + } + + route_table = self; + ClearRouteTable(); + self.last_way = FindWayPoint(self.current_way); + + if (self.last_way != world) + { + self.last_way.items = vlen(self.last_way.origin - self.origin); + self.last_way.nextthink = time; + self.last_way.think = WaypointThink; + self.last_way.keys = TRUE; + busy_waypoints = 1; + return TRUE; + } + else + { + route_table = world; + busy_waypoints = 0; + return FALSE; + } +}; + +void(entity this, float direct) bot_get_path = +{ + if (this == world) + return; + + if (route_table == self) + { + if (busy_waypoints <= 0) + { + route_table = world; + mark_path(this); + } + return; + } + if (direct) + { + if(begin_route()) + direct_route = TRUE; + else + bot_lost(this, FALSE); + return; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BSP/QC Waypoint loading + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() waypoint = +{ + self.search_time = time; + self.solid = SOLID_TRIGGER; + self.movetype = MOVETYPE_NONE; + setorigin(self, self.origin); + + setsize(self, VEC_HULL_MIN, VEC_HULL_MAX); + waypoints = waypoints + 1; + if (!way_head) + { + way_head = self; + way_foot = self; + } + else + { + way_foot._next = self; + self._last = way_foot; + way_foot = self; + } + + self.count = waypoints; + waypoint_mode = WM_LOADED; + if (self.count == 1) + { + self.think = FixWaypoints; // wait until all bsp loaded points are spawned + self.nextthink = time; + } +}; + +void(vector org, vector bit1, float bit4, float flargs) make_way = +{ + local entity y; + waypoint_mode = WM_LOADED; + y = make_waypoint(org); + y.b_aiflags = flargs; + y.b_pants = bit1_x; + y.b_skill = bit1_y; + y.b_shirt = bit1_z; + y.b_frags = bit4; + if (y.count == 1) + { + y.think = FixWaypoints; // wait until all qc loaded points are spawned + y.nextthink = time; + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Temporary Marker code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(vector org) SpawnTempWaypoint = +{ + local entity tep; + + if (!self.temp_way) + self.temp_way = tep = spawn(); + else + tep = self.temp_way; + + tep.classname = "temp_waypoint"; + tep.search_time = 0; + tep.solid = SOLID_TRIGGER; + tep.movetype = MOVETYPE_NOCLIP; + setorigin(tep, org); + target_add(tep); + setsize(tep, VEC_HULL_MIN, VEC_HULL_MAX); // FIXME: convert these to numerical +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/frikqcc.exe b/r17/Revamped src/Revamped QC/Primeqc4/frikqcc.exe new file mode 100755 index 00000000..fd9f6b95 Binary files /dev/null and b/r17/Revamped src/Revamped QC/Primeqc4/frikqcc.exe differ diff --git a/r17/Revamped src/Revamped QC/Primeqc4/fteqccgui.exe b/r17/Revamped src/Revamped QC/Primeqc4/fteqccgui.exe new file mode 100755 index 00000000..03ae0933 Binary files /dev/null and b/r17/Revamped src/Revamped QC/Primeqc4/fteqccgui.exe differ diff --git a/r17/Revamped src/Revamped QC/Primeqc4/hknight.qc b/r17/Revamped src/Revamped QC/Primeqc4/hknight.qc new file mode 100755 index 00000000..0e239e08 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/hknight.qc @@ -0,0 +1,440 @@ +/* +============================================================================== + +KNIGHT + +============================================================================== +*/ + +$cd id1/models/knight2 +$origin 0 0 24 +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 +$frame walk10 walk11 walk12 walk13 walk14 walk15 walk16 walk17 +$frame walk18 walk19 walk20 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 death11 death12 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 + +$frame char_a1 char_a2 char_a3 char_a4 char_a5 char_a6 char_a7 char_a8 +$frame char_a9 char_a10 char_a11 char_a12 char_a13 char_a14 char_a15 char_a16 + +$frame magica1 magica2 magica3 magica4 magica5 magica6 magica7 magica8 +$frame magica9 magica10 magica11 magica12 magica13 magica14 + +$frame magicb1 magicb2 magicb3 magicb4 magicb5 magicb6 magicb7 magicb8 +$frame magicb9 magicb10 magicb11 magicb12 magicb13 + +$frame char_b1 char_b2 char_b3 char_b4 char_b5 char_b6 + +$frame slice1 slice2 slice3 slice4 slice5 slice6 slice7 slice8 slice9 slice10 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 smash8 smash9 smash10 +$frame smash11 + +$frame w_attack1 w_attack2 w_attack3 w_attack4 w_attack5 w_attack6 w_attack7 +$frame w_attack8 w_attack9 w_attack10 w_attack11 w_attack12 w_attack13 w_attack14 +$frame w_attack15 w_attack16 w_attack17 w_attack18 w_attack19 w_attack20 +$frame w_attack21 w_attack22 + +$frame magicc1 magicc2 magicc3 magicc4 magicc5 magicc6 magicc7 magicc8 +$frame magicc9 magicc10 magicc11 + + +void() hknight_char_a1; +void() hknight_run1; +void() hk_idle_sound; + +void(float offset) hknight_shot = +{ + local vector offang; + local vector org, vec; + + offang = vectoangles (self.enemy.origin - self.origin); + offang_y = offang_y + offset * 6; + + makevectors (offang); + + org = self.origin + self.mins + self.size*0.5 + v_forward * 20; + +// set missile speed + vec = normalize (v_forward); + vec_z = 0 - vec_z + (random() - 0.5)*0.1; + + launch_spike (org, vec); + newmis.classname = "knightspike"; + setmodel (newmis, "progs/k_spike.mdl"); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + newmis.velocity = vec*300; + sound (self, CHAN_WEAPON, "hknight/attack1.wav", 1, ATTN_NORM); +}; + +void() CheckForCharge = +{ +// check for mad charge +if (!enemy_vis) + return; +if (time < self.attack_finished) + return; +if ( fabs(self.origin_z - self.enemy.origin_z) > 20) + return; // too much height change +if ( vlen (self.origin - self.enemy.origin) < 80) + return; // use regular attack + +// charge + SUB_AttackFinished (2); + hknight_char_a1 (); + +}; + +void() CheckContinueCharge = +{ + if (time > self.attack_finished) + { + SUB_AttackFinished (3); + hknight_run1 (); + return; // done charging + } + if (random() > 0.5) + sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM); + else + sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +}; + +//=========================================================================== + +void() hknight_stand1 =[ $stand1, hknight_stand2 ] {ai_stand();}; +void() hknight_stand2 =[ $stand2, hknight_stand3 ] {ai_stand();}; +void() hknight_stand3 =[ $stand3, hknight_stand4 ] {ai_stand();}; +void() hknight_stand4 =[ $stand4, hknight_stand5 ] {ai_stand();}; +void() hknight_stand5 =[ $stand5, hknight_stand6 ] {ai_stand();}; +void() hknight_stand6 =[ $stand6, hknight_stand7 ] {ai_stand();}; +void() hknight_stand7 =[ $stand7, hknight_stand8 ] {ai_stand();}; +void() hknight_stand8 =[ $stand8, hknight_stand9 ] {ai_stand();}; +void() hknight_stand9 =[ $stand9, hknight_stand1 ] {ai_stand();}; + +//=========================================================================== + +void() hknight_walk1 =[ $walk1, hknight_walk2 ] { +hk_idle_sound(); +ai_walk(2);}; +void() hknight_walk2 =[ $walk2, hknight_walk3 ] {ai_walk(5);}; +void() hknight_walk3 =[ $walk3, hknight_walk4 ] {ai_walk(5);}; +void() hknight_walk4 =[ $walk4, hknight_walk5 ] {ai_walk(4);}; +void() hknight_walk5 =[ $walk5, hknight_walk6 ] {ai_walk(4);}; +void() hknight_walk6 =[ $walk6, hknight_walk7 ] {ai_walk(2);}; +void() hknight_walk7 =[ $walk7, hknight_walk8 ] {ai_walk(2);}; +void() hknight_walk8 =[ $walk8, hknight_walk9 ] {ai_walk(3);}; +void() hknight_walk9 =[ $walk9, hknight_walk10 ] {ai_walk(3);}; +void() hknight_walk10 =[ $walk10, hknight_walk11 ] {ai_walk(4);}; +void() hknight_walk11 =[ $walk11, hknight_walk12 ] {ai_walk(3);}; +void() hknight_walk12 =[ $walk12, hknight_walk13 ] {ai_walk(4);}; +void() hknight_walk13 =[ $walk13, hknight_walk14 ] {ai_walk(6);}; +void() hknight_walk14 =[ $walk14, hknight_walk15 ] {ai_walk(2);}; +void() hknight_walk15 =[ $walk15, hknight_walk16 ] {ai_walk(2);}; +void() hknight_walk16 =[ $walk16, hknight_walk17 ] {ai_walk(4);}; +void() hknight_walk17 =[ $walk17, hknight_walk18 ] {ai_walk(3);}; +void() hknight_walk18 =[ $walk18, hknight_walk19 ] {ai_walk(3);}; +void() hknight_walk19 =[ $walk19, hknight_walk20 ] {ai_walk(3);}; +void() hknight_walk20 =[ $walk20, hknight_walk1 ] {ai_walk(2);}; + +//=========================================================================== + +void() hknight_run1 =[ $run1, hknight_run2 ] { +hk_idle_sound(); +ai_run (20); CheckForCharge (); }; +void() hknight_run2 =[ $run2, hknight_run3 ] {ai_run(25);}; +void() hknight_run3 =[ $run3, hknight_run4 ] {ai_run(18);}; +void() hknight_run4 =[ $run4, hknight_run5 ] {ai_run(16);}; +void() hknight_run5 =[ $run5, hknight_run6 ] {ai_run(14);}; +void() hknight_run6 =[ $run6, hknight_run7 ] {ai_run(25);}; +void() hknight_run7 =[ $run7, hknight_run8 ] {ai_run(21);}; +void() hknight_run8 =[ $run8, hknight_run1 ] {ai_run(13);}; + +//============================================================================ + +void() hknight_pain1 =[ $pain1, hknight_pain2 ] {sound (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);}; +void() hknight_pain2 =[ $pain2, hknight_pain3 ] {}; +void() hknight_pain3 =[ $pain3, hknight_pain4 ] {}; +void() hknight_pain4 =[ $pain4, hknight_pain5 ] {}; +void() hknight_pain5 =[ $pain5, hknight_run1 ] {}; + +//============================================================================ + +void() hknight_die1 =[ $death1, hknight_die2 ] {ai_forward(10);}; +void() hknight_die2 =[ $death2, hknight_die3 ] {ai_forward(8);}; +void() hknight_die3 =[ $death3, hknight_die4 ] +{self.solid = SOLID_NOT; ai_forward(7);}; +void() hknight_die4 =[ $death4, hknight_die5 ] {}; +void() hknight_die5 =[ $death5, hknight_die6 ] {}; +void() hknight_die6 =[ $death6, hknight_die7 ] {}; +void() hknight_die7 =[ $death7, hknight_die8 ] {}; +void() hknight_die8 =[ $death8, hknight_die9 ] {ai_forward(10);}; +void() hknight_die9 =[ $death9, hknight_die10 ] {ai_forward(11);}; +void() hknight_die10 =[ $death10, hknight_die11 ] {}; +void() hknight_die11 =[ $death11, hknight_die12 ] {}; +void() hknight_die12 =[ $death12, hknight_die12 ] {}; + +void() hknight_dieb1 =[ $deathb1, hknight_dieb2 ] {}; +void() hknight_dieb2 =[ $deathb2, hknight_dieb3 ] {}; +void() hknight_dieb3 =[ $deathb3, hknight_dieb4 ] +{self.solid = SOLID_NOT;}; +void() hknight_dieb4 =[ $deathb4, hknight_dieb5 ] {}; +void() hknight_dieb5 =[ $deathb5, hknight_dieb6 ] {}; +void() hknight_dieb6 =[ $deathb6, hknight_dieb7 ] {}; +void() hknight_dieb7 =[ $deathb7, hknight_dieb8 ] {}; +void() hknight_dieb8 =[ $deathb8, hknight_dieb9 ] {}; +void() hknight_dieb9 =[ $deathb9, hknight_dieb9 ] {}; + +void() hknight_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_hellkn.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "hknight/death1.wav", 1, ATTN_NORM); + if (random() > 0.5) + hknight_die1 (); + else + hknight_dieb1 (); +}; + + +//============================================================================ + +void() hknight_magica1 =[ $magica1, hknight_magica2 ] {ai_face();}; +void() hknight_magica2 =[ $magica2, hknight_magica3 ] {ai_face();}; +void() hknight_magica3 =[ $magica3, hknight_magica4 ] {ai_face();}; +void() hknight_magica4 =[ $magica4, hknight_magica5 ] {ai_face();}; +void() hknight_magica5 =[ $magica5, hknight_magica6 ] {ai_face();}; +void() hknight_magica6 =[ $magica6, hknight_magica7 ] {ai_face();}; +void() hknight_magica7 =[ $magica7, hknight_magica8 ] {hknight_shot(-2);}; +void() hknight_magica8 =[ $magica8, hknight_magica9 ] {hknight_shot(-1);}; +void() hknight_magica9 =[ $magica9, hknight_magica10] {hknight_shot(0);}; +void() hknight_magica10 =[ $magica10, hknight_magica11] {hknight_shot(1);}; +void() hknight_magica11 =[ $magica11, hknight_magica12] {hknight_shot(2);}; +void() hknight_magica12 =[ $magica12, hknight_magica13] {hknight_shot(3);}; +void() hknight_magica13 =[ $magica13, hknight_magica14] {ai_face();}; +void() hknight_magica14 =[ $magica14, hknight_run1 ] {ai_face();}; + +//============================================================================ + +void() hknight_magicb1 =[ $magicb1, hknight_magicb2 ] {ai_face();}; +void() hknight_magicb2 =[ $magicb2, hknight_magicb3 ] {ai_face();}; +void() hknight_magicb3 =[ $magicb3, hknight_magicb4 ] {ai_face();}; +void() hknight_magicb4 =[ $magicb4, hknight_magicb5 ] {ai_face();}; +void() hknight_magicb5 =[ $magicb5, hknight_magicb6 ] {ai_face();}; +void() hknight_magicb6 =[ $magicb6, hknight_magicb7 ] {ai_face();}; +void() hknight_magicb7 =[ $magicb7, hknight_magicb8 ] {hknight_shot(-2);}; +void() hknight_magicb8 =[ $magicb8, hknight_magicb9 ] {hknight_shot(-1);}; +void() hknight_magicb9 =[ $magicb9, hknight_magicb10] {hknight_shot(0);}; +void() hknight_magicb10 =[ $magicb10, hknight_magicb11] {hknight_shot(1);}; +void() hknight_magicb11 =[ $magicb11, hknight_magicb12] {hknight_shot(2);}; +void() hknight_magicb12 =[ $magicb12, hknight_magicb13] {hknight_shot(3);}; +void() hknight_magicb13 =[ $magicb13, hknight_run1] {ai_face();}; + +//============================================================================ + +void() hknight_magicc1 =[ $magicc1, hknight_magicc2 ] {ai_face();}; +void() hknight_magicc2 =[ $magicc2, hknight_magicc3 ] {ai_face();}; +void() hknight_magicc3 =[ $magicc3, hknight_magicc4 ] {ai_face();}; +void() hknight_magicc4 =[ $magicc4, hknight_magicc5 ] {ai_face();}; +void() hknight_magicc5 =[ $magicc5, hknight_magicc6 ] {ai_face();}; +void() hknight_magicc6 =[ $magicc6, hknight_magicc7 ] {hknight_shot(-2);}; +void() hknight_magicc7 =[ $magicc7, hknight_magicc8 ] {hknight_shot(-1);}; +void() hknight_magicc8 =[ $magicc8, hknight_magicc9 ] {hknight_shot(0);}; +void() hknight_magicc9 =[ $magicc9, hknight_magicc10] {hknight_shot(1);}; +void() hknight_magicc10 =[ $magicc10, hknight_magicc11] {hknight_shot(2);}; +void() hknight_magicc11 =[ $magicc11, hknight_run1] {hknight_shot(3);}; + +//=========================================================================== + +void() hknight_char_a1 =[ $char_a1, hknight_char_a2 ] {ai_charge(20);}; +void() hknight_char_a2 =[ $char_a2, hknight_char_a3 ] {ai_charge(25);}; +void() hknight_char_a3 =[ $char_a3, hknight_char_a4 ] {ai_charge(18);}; +void() hknight_char_a4 =[ $char_a4, hknight_char_a5 ] {ai_charge(16);}; +void() hknight_char_a5 =[ $char_a5, hknight_char_a6 ] {ai_charge(14);}; +void() hknight_char_a6 =[ $char_a6, hknight_char_a7 ] {ai_charge(20); ai_melee();}; +void() hknight_char_a7 =[ $char_a7, hknight_char_a8 ] {ai_charge(21); ai_melee();}; +void() hknight_char_a8 =[ $char_a8, hknight_char_a9 ] {ai_charge(13); ai_melee();}; +void() hknight_char_a9 =[ $char_a9, hknight_char_a10 ] {ai_charge(20); ai_melee();}; +void() hknight_char_a10=[ $char_a10, hknight_char_a11 ] {ai_charge(20); ai_melee();}; +void() hknight_char_a11=[ $char_a11, hknight_char_a12 ] {ai_charge(18); ai_melee();}; +void() hknight_char_a12=[ $char_a12, hknight_char_a13 ] {ai_charge(16);}; +void() hknight_char_a13=[ $char_a13, hknight_char_a14 ] {ai_charge(14);}; +void() hknight_char_a14=[ $char_a14, hknight_char_a15 ] {ai_charge(25);}; +void() hknight_char_a15=[ $char_a15, hknight_char_a16 ] {ai_charge(21);}; +void() hknight_char_a16=[ $char_a16, hknight_run1 ] {ai_charge(13);}; + +//=========================================================================== + +void() hknight_char_b1 =[ $char_b1, hknight_char_b2 ] +{CheckContinueCharge (); ai_charge(23); ai_melee();}; +void() hknight_char_b2 =[ $char_b2, hknight_char_b3 ] {ai_charge(17); ai_melee();}; +void() hknight_char_b3 =[ $char_b3, hknight_char_b4 ] {ai_charge(12); ai_melee();}; +void() hknight_char_b4 =[ $char_b4, hknight_char_b5 ] {ai_charge(22); ai_melee();}; +void() hknight_char_b5 =[ $char_b5, hknight_char_b6 ] {ai_charge(18); ai_melee();}; +void() hknight_char_b6 =[ $char_b6, hknight_char_b1 ] {ai_charge(8); ai_melee();}; + +//=========================================================================== + +void() hknight_slice1 =[ $slice1, hknight_slice2 ] {ai_charge(9);}; +void() hknight_slice2 =[ $slice2, hknight_slice3 ] {ai_charge(6);}; +void() hknight_slice3 =[ $slice3, hknight_slice4 ] {ai_charge(13);}; +void() hknight_slice4 =[ $slice4, hknight_slice5 ] {ai_charge(4);}; +void() hknight_slice5 =[ $slice5, hknight_slice6 ] {ai_charge(7); ai_melee();}; +void() hknight_slice6 =[ $slice6, hknight_slice7 ] {ai_charge(15); ai_melee();}; +void() hknight_slice7 =[ $slice7, hknight_slice8 ] {ai_charge(8); ai_melee();}; +void() hknight_slice8 =[ $slice8, hknight_slice9 ] {ai_charge(2); ai_melee();}; +void() hknight_slice9 =[ $slice9, hknight_slice10 ] {ai_melee();}; +void() hknight_slice10 =[ $slice10, hknight_run1 ] {ai_charge(3);}; + +//=========================================================================== + +void() hknight_smash1 =[ $smash1, hknight_smash2 ] {ai_charge(1);}; +void() hknight_smash2 =[ $smash2, hknight_smash3 ] {ai_charge(13);}; +void() hknight_smash3 =[ $smash3, hknight_smash4 ] {ai_charge(9);}; +void() hknight_smash4 =[ $smash4, hknight_smash5 ] {ai_charge(11);}; +void() hknight_smash5 =[ $smash5, hknight_smash6 ] {ai_charge(10); ai_melee();}; +void() hknight_smash6 =[ $smash6, hknight_smash7 ] {ai_charge(7); ai_melee();}; +void() hknight_smash7 =[ $smash7, hknight_smash8 ] {ai_charge(12); ai_melee();}; +void() hknight_smash8 =[ $smash8, hknight_smash9 ] {ai_charge(2); ai_melee();}; +void() hknight_smash9 =[ $smash9, hknight_smash10 ] {ai_charge(3); ai_melee();}; +void() hknight_smash10 =[ $smash10, hknight_smash11 ] {ai_charge(0);}; +void() hknight_smash11 =[ $smash11, hknight_run1 ] {ai_charge(0);}; + +//============================================================================ + +void() hknight_watk1 =[ $w_attack1, hknight_watk2 ] {ai_charge(2);}; +void() hknight_watk2 =[ $w_attack2, hknight_watk3 ] {ai_charge(0);}; +void() hknight_watk3 =[ $w_attack3, hknight_watk4 ] {ai_charge(0);}; +void() hknight_watk4 =[ $w_attack4, hknight_watk5 ] {ai_melee();}; +void() hknight_watk5 =[ $w_attack5, hknight_watk6 ] {ai_melee();}; +void() hknight_watk6 =[ $w_attack6, hknight_watk7 ] {ai_melee();}; +void() hknight_watk7 =[ $w_attack7, hknight_watk8 ] {ai_charge(1);}; +void() hknight_watk8 =[ $w_attack8, hknight_watk9 ] {ai_charge(4);}; +void() hknight_watk9 =[ $w_attack9, hknight_watk10 ] {ai_charge(5);}; +void() hknight_watk10 =[ $w_attack10, hknight_watk11 ] {ai_charge(3); ai_melee();}; +void() hknight_watk11 =[ $w_attack11, hknight_watk12 ] {ai_charge(2); ai_melee();}; +void() hknight_watk12 =[ $w_attack12, hknight_watk13 ] {ai_charge(2); ai_melee();}; +void() hknight_watk13 =[ $w_attack13, hknight_watk14 ] {ai_charge(0);}; +void() hknight_watk14 =[ $w_attack14, hknight_watk15 ] {ai_charge(0);}; +void() hknight_watk15 =[ $w_attack15, hknight_watk16 ] {ai_charge(0);}; +void() hknight_watk16 =[ $w_attack16, hknight_watk17 ] {ai_charge(1);}; +void() hknight_watk17 =[ $w_attack17, hknight_watk18 ] {ai_charge(1); ai_melee();}; +void() hknight_watk18 =[ $w_attack18, hknight_watk19 ] {ai_charge(3); ai_melee();}; +void() hknight_watk19 =[ $w_attack19, hknight_watk20 ] {ai_charge(4); ai_melee();}; +void() hknight_watk20 =[ $w_attack20, hknight_watk21 ] {ai_charge(6);}; +void() hknight_watk21 =[ $w_attack21, hknight_watk22 ] {ai_charge(7);}; +void() hknight_watk22 =[ $w_attack22, hknight_run1 ] {ai_charge(3);}; + +//============================================================================ + +void() hk_idle_sound = +{ + if (random() < 0.2) + sound (self, CHAN_VOICE, "hknight/idle.wav", 1, ATTN_NORM); +}; + +void(entity attacker, float damage) hknight_pain = +{ + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM); + + if (time - self.pain_finished > 5) + { // allways go into pain frame if it has been a while + hknight_pain1 (); + self.pain_finished = time + 1; + return; + } + + if ((random()*30 > damage) ) + return; // didn't flinch + + self.pain_finished = time + 1; + hknight_pain1 (); +}; + +float hknight_type; + +void() hknight_melee = +{ + hknight_type = hknight_type + 1; + + sound (self, CHAN_WEAPON, "hknight/slash1.wav", 1, ATTN_NORM); + if (hknight_type == 1) + hknight_slice1 (); + else if (hknight_type == 2) + hknight_smash1 (); + else if (hknight_type == 3) + { + hknight_watk1 (); + hknight_type = 0; + } +}; + +/*QUAKED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_hell_knight = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/hknight.mdl"); + precache_model2 ("progs/k_spike.mdl"); + precache_model2 ("progs/h_hellkn.mdl"); + + + precache_sound2 ("hknight/attack1.wav"); + precache_sound2 ("hknight/death1.wav"); + precache_sound2 ("hknight/pain1.wav"); + precache_sound2 ("hknight/sight1.wav"); + precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2 + precache_sound2 ("hknight/slash1.wav"); + precache_sound2 ("hknight/idle.wav"); + precache_sound2 ("hknight/grunt.wav"); + + precache_sound ("knight/sword1.wav"); + precache_sound ("knight/sword2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/hknight.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 250; + + self.th_stand = hknight_stand1; + self.th_walk = hknight_walk1; + self.th_run = hknight_run1; + self.th_melee = hknight_melee; + self.th_missile = hknight_magicc1; + self.th_pain = hknight_pain; + self.th_die = hknight_die; + + walkmonster_start (); +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/items.qc b/r17/Revamped src/Revamped QC/Primeqc4/items.qc new file mode 100755 index 00000000..62ad2a40 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/items.qc @@ -0,0 +1,1726 @@ +void() W_SetCurrentAmmo; +/* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD +BE .8 .3 .4 IN COLOR */ + +void() SUB_regen = +{ + self.model = self.mdl; // restore original model + self.solid = SOLID_TRIGGER; // allow it to be touched again + sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM); // play respawn sound + setorigin (self, self.origin); +}; + + + +/*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8) +prints a warning message when spawned +*/ +void() noclass = +{ + dprint ("noclass spawned at"); + dprint (vtos(self.origin)); + dprint ("\n"); + remove (self); +}; + + + +/* +============ +PlaceItem + +plants the object on the floor +============ +*/ +void() PlaceItem = +{ + self.mdl = self.model; + self.flags = FL_ITEM; + self.solid = SOLID_TRIGGER; + self.movetype = MOVETYPE_NONE; + self.velocity = '0 0 0'; + if (self.classname == "etank") + setorigin(self, self.origin); //The metroid Float + else + setorigin(self, self.origin + '0 0 40'); +}; + +/* +============ +StartItem + +Sets the clipping size and plants the object on the floor +============ +*/ +void() StartItem = +{ + self.nextthink = time + 0.2; // items start after other solids + self.think = PlaceItem; +}; + +/* +========================================================================= + +HEALTH BOX + +========================================================================= +*/ +// +// T_Heal: add health to an entity, limiting health to max_health +// "ignore" will ignore max_health limit +// +float (entity e, float healamount, float ignore) T_Heal = +{ + if (e.health <= 0) + return 0; + if ((!ignore) && (e.health >= other.max_health)) + return 0; + healamount = ceil(healamount); + + e.health = e.health + healamount; + if ((!ignore) && (e.health >= other.max_health)) + e.health = other.max_health; + + return 1; +}; + +/*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth +Health box. Normally gives 25 points. +Rotten box heals 5-10 points, +megahealth will add 100 health, then +rot you down to your maximum health limit, +one point per second. +*/ + +float H_ROTTEN = 1; +float H_MEGA = 2; +.float healamount, healtype; +void() health_touch; +void() item_megahealth_rot; + +void() item_health = +{ + self.touch = health_touch; + + if (self.spawnflags & H_ROTTEN) + { + precache_model("maps/b_bh10.bsp"); + + precache_sound("items/r_item1.wav"); + setmodel(self, "maps/b_bh10.bsp"); + self.noise = "items/r_item1.wav"; + self.healamount = 15; + self.healtype = 0; + } + else + if (self.spawnflags & H_MEGA) + { + precache_model("maps/b_bh100.bsp"); + precache_sound("items/r_item2.wav"); + setmodel(self, "maps/b_bh100.bsp"); + self.noise = "items/r_item2.wav"; + self.healamount = 100; + self.healtype = 2; + } + else + { + precache_model("maps/b_bh25.bsp"); + precache_sound("items/health1.wav"); + setmodel(self, "maps/b_bh25.bsp"); + self.noise = "items/health1.wav"; + self.healamount = 25; + self.healtype = 1; + } + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; +//Prime Health 1 +void() item_health1 = +{ + precache_model("progs/health3.spr"); + precache_sound("items/r_item1.wav"); + setmodel(self, "progs/health3.spr"); + self.noise = "items/r_item1.wav"; + self.classname = "health1"; + self.touch = health_touch; + self.healtype = 0; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; +//Prime health2 +void() item_health2 = +{ + precache_model("progs/health.spr"); + precache_sound("items/r_item1.wav"); + setmodel(self, "progs/health.spr"); + self.noise = "items/r_item1.wav"; + self.classname = "health2"; + self.touch = health_touch; + self.healtype = 0; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; +//Prime health3 +void() item_health3 = +{ + precache_model("progs/health2.spr"); + precache_sound("items/r_item1.wav"); + setmodel(self, "progs/health2.spr"); + self.noise = "items/r_item1.wav"; + self.classname = "health3"; + self.touch = health_touch; + self.healtype = 0; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; +void() health_touch = +{ + local string s; + + if (other.classname != "player") + return; + + if (self.classname == "health1") //Oh my... So much globbered code Just for Health... +{ + if (other.energy == 0) + { + if (other.health >= 99) + return; + other.health = other.health + 20; + if (other.health >= 99) + other.health = 99; + } + if (other.energy == 1) + { + if (other.health >= 199) + return; + other.health = other.health + 20; + if (other.health >= 199) + other.health = 199; + } + if (other.energy == 2) + { + if (other.health >= 299) + return; + other.health = other.health + 20; + if (other.health >= 299) + other.health = 299; + } + if (other.energy == 3) + { + if (other.health >= 399) + return; + other.health = other.health + 20; + if (other.health >= 399) + other.health = 399; + } + if (other.energy == 4) + { + if (other.health >= 499) + return; + other.health = other.health + 20; + if (other.health >= 499) + other.health = 499; + } + if (other.energy == 5) + { + if (other.health >= 599) + return; + other.health = other.health + 20; + if (other.health >= 599) + other.health = 599; + } + if (other.energy == 6) + { + if (other.health >= 699) + return; + other.health = other.health + 20; + if (other.health >= 699) + other.health = 699; + } + if (other.energy == 7) + { + if (other.health >= 799) + return; + other.health = other.health + 20; + if (other.health >= 799) + other.health = 799; + } + if (other.energy == 8) + { + if (other.health >= 899) + return; + other.health = other.health + 20; + if (other.health >= 899) + other.health = 899; + } + if (other.energy == 9) + { + if (other.health >= 999) + return; + other.health = other.health + 20; + if (other.health >= 999) + other.health = 999; + } +} + + if (self.classname == "health2") +{ + if (other.energy == 0) + { + if (other.health >= 99) + return; + other.health = other.health + 50; + if (other.health >= 99) + other.health = 99; + } + if (other.energy == 1) + { + if (other.health >= 199) + return; + other.health = other.health + 50; + if (other.health >= 199) + other.health = 199; + } + if (other.energy == 2) + { + if (other.health >= 299) + return; + other.health = other.health + 50; + if (other.health >= 299) + other.health = 299; + } + if (other.energy == 3) + { + if (other.health >= 399) + return; + other.health = other.health + 50; + if (other.health >= 399) + other.health = 399; + } + if (other.energy == 4) + { + if (other.health >= 499) + return; + other.health = other.health + 50; + if (other.health >= 499) + other.health = 499; + } + if (other.energy == 5) + { + if (other.health >= 599) + return; + other.health = other.health + 50; + if (other.health >= 599) + other.health = 599; + } + if (other.energy == 6) + { + if (other.health >= 699) + return; + other.health = other.health + 50; + if (other.health >= 699) + other.health = 699; + } + if (other.energy == 7) + { + if (other.health >= 799) + return; + other.health = other.health + 50; + if (other.health >= 799) + other.health = 799; + } + if (other.energy == 8) + { + if (other.health >= 899) + return; + other.health = other.health + 50; + if (other.health >= 899) + other.health = 899; + } + if (other.energy == 9) + { + if (other.health >= 999) + return; + other.health = other.health + 50; + if (other.health >= 999) + other.health = 999; + } +} + + else +{ + if (other.energy == 0) + { + if (other.health >= 99) + return; + other.health = other.health + 100; + if (other.health >= 99) + other.health = 99; + } + if (other.energy == 1) + { + if (other.health >= 199) + return; + other.health = other.health + 100; + if (other.health >= 199) + other.health = 199; + } + if (other.energy == 2) + { + if (other.health >= 299) + return; + other.health = other.health + 100; + if (other.health >= 299) + other.health = 299; + } + if (other.energy == 3) + { + if (other.health >= 399) + return; + other.health = other.health + 100; + if (other.health >= 399) + other.health = 399; + } + if (other.energy == 4) + { + if (other.health >= 499) + return; + other.health = other.health + 100; + if (other.health >= 499) + other.health = 499; + } + if (other.energy == 5) + { + if (other.health >= 599) + return; + other.health = other.health + 100; + if (other.health >= 599) + other.health = 599; + } + if (other.energy == 6) + { + if (other.health >= 699) + return; + other.health = other.health + 100; + if (other.health >= 699) + other.health = 699; + } + if (other.energy == 7) + { + if (other.health >= 799) + return; + other.health = other.health + 100; + if (other.health >= 799) + other.health = 799; + } + if (other.energy == 8) + { + if (other.health >= 899) + return; + other.health = other.health + 100; + if (other.health >= 899) + other.health = 899; + } + if (other.energy == 9) + { + if (other.health >= 999) + return; + other.health = other.health + 100; + if (other.health >= 999) + other.health = 999; + } +} + + sprint(other, "You receive "); + s = ftos(other.health); + sprint(other, s); + sprint(other, " health\n"); + +// health touch sound + sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM); + + stuffcmd (other, "bf\n"); + + self.model = string_null; + self.solid = SOLID_NOT; + + if (deathmatch != 2) // deathmatch 2 is the silly old rules + { + if (deathmatch) + self.nextthink = time + 20; + self.think = SUB_regen; + } + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + +void() item_megahealth_rot = +{ + other = self.owner; + + if (other.health > other.max_health) + { + other.health = other.health - 1; + self.nextthink = time + 1; + return; + } + +// it is possible for a player to die and respawn between rots, so don't +// just blindly subtract the flag off + other.items = other.items - (other.items & IT_SUPERHEALTH); + + if (deathmatch == 1) // deathmatch 2 is silly old rules + { + self.nextthink = time + 20; + self.think = SUB_regen; + } +}; + +/* +=============================================================================== + +ARMOR + +=============================================================================== +*/ + +void() armor_touch; + +void() armor_touch = +{ + local float type, value, bit; + + if (other.health <= 0) + return; + if (other.classname != "player") + return; + + if (self.classname == "item_armor1") + { + type = 0.3; + value = 100; + bit = IT_ARMOR1; + } + if (self.classname == "item_armor2") + { + type = 0.6; + value = 150; + bit = IT_ARMOR2; + } + if (self.classname == "item_armorInv") + { + type = 0.8; + value = 200; + bit = IT_ARMOR3; + } + if (other.armortype*other.armorvalue >= type*value) + return; + + other.armortype = type; + other.armorvalue = value; + other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit; + + self.solid = SOLID_NOT; + self.model = string_null; + if (deathmatch == 1) + self.nextthink = time + 20; + self.think = SUB_regen; + + sprint(other, "You got armor\n"); +// armor touch sound + sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +/*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() item_armor1 = +{ + self.touch = armor_touch; + precache_model ("progs/armor.mdl"); + setmodel (self, "progs/armor.mdl"); + self.skin = 0; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() item_armor2 = +{ + self.touch = armor_touch; + precache_model ("progs/armor.mdl"); + setmodel (self, "progs/armor.mdl"); + self.skin = 1; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() item_armorInv = +{ + self.touch = armor_touch; + precache_model ("progs/armor.mdl"); + setmodel (self, "progs/armor.mdl"); + self.skin = 2; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/* +=============================================================================== + +WEAPONS + +=============================================================================== +*/ + +void() bound_other_ammo = +{ + if (other.ammo_shells > 100) + other.ammo_shells = 100; + if (other.ammo_nails > 200) + other.ammo_nails = 200; + if (other.ammo_rockets > 100) + other.ammo_rockets = 100; + if (other.ammo_cells > 100) + other.ammo_cells = 100; +}; + + +float(float w) RankForWeapon = +{ + if (w == IT_LIGHTNING) + return 1; + if (w == IT_MAGMA) + return 2; + if (w == IT_SNIPER) + return 3; + if (w == IT_GRENADE_LAUNCHER) + return 4; + if (w == IT_ROCKET) + return 5; + if (w == IT_SPLASER) + return 6; + return 7; +}; + +/* +============= +Deathmatch_Weapon + +Deathmatch weapon change rules for picking up a weapon + +.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells; +============= +*/ +void(float old, float new) Deathmatch_Weapon = +{ + local float or, nr; + +// change self.weapon if desired + or = RankForWeapon (self.weapon); + nr = RankForWeapon (new); + if ( nr < or ) + self.weapon = new; +}; + +/* +============= +weapon_touch +============= +*/ +//float() W_BestWeapon; + +void() weapon_touch = +{ + local float hadammo, new, old; + local entity stemp; + local float leave; + + if (!(other.flags & FL_CLIENT)) + return; + +// if the player was using his best weapon, change up to the new one if better + stemp = self; + self = other; + self = stemp; + + if (deathmatch == 2 || coop) + leave = 1; + else + leave = 0; + + if (self.classname == "weapon_nailgun") + { + if (leave && (other.items & IT_SPLASER) ) + return; + hadammo = other.ammo_nails; + new = IT_SPLASER; + if (self.ammo_nails >= 45) + return; + other.ammo_nails = other.ammo_nails + 8; + if (self.ammo_nails >= 45) + self.ammo_nails = 45; + } + else if (self.classname == "weapon_sniper") + { + if (leave && (other.items & IT_SNIPER) ) + return; + hadammo = other.ammo_rockets; + new = IT_SNIPER; + if (self.ammo_sniper >= 20) + return; + other.ammo_sniper = other.ammo_sniper + 4; + if (self.ammo_sniper >= 20) + self.ammo_sniper = 20; + } + else if (self.classname == "weapon_supershotgun") + { + if (leave && (other.items & IT_ROCKET) ) + return; + hadammo = other.ammo_rockets; + new = IT_ROCKET; + if (other.ammo_rockets >= 25) + return; + other.ammo_rockets = other.ammo_rockets + 5; + if (other.ammo_rockets >= 25) + other.ammo_rockets = 25; + } + else if (self.classname == "weapon_magma") + { + if (leave && (other.items & IT_MAGMA) ) + return; + hadammo = other.ammo_lava; + new = IT_MAGMA; + if (other.ammo_lava >= 45) + return; + other.ammo_lava = other.ammo_lava + 10; + if (other.ammo_lava >= 45) + other.ammo_rockets = 45; + } + else if (self.classname == "weapon_grenadelauncher") + { + if (leave && (other.items & IT_GRENADE_LAUNCHER) ) + return; + hadammo = other.ammo_rockets; + new = IT_GRENADE_LAUNCHER; + other.ammo_rockets = other.ammo_rockets + 5; + } + else if (self.classname == "weapon_lightning") + { + if (leave && (other.items & IT_LIGHTNING) ) + return; + hadammo = other.ammo_rockets; + new = IT_LIGHTNING; + other.ammo_cells = other.ammo_cells + 15; + } + else if (self.classname == "weapon_ric") + { + if (leave && (other.items & IT_RIC) ) + return; + hadammo = other.ammo_rockets; + new = IT_RIC; + if (other.ammo_ric >= 100) + return; + other.ammo_ric = other.ammo_ric + 25; + if (other.ammo_ric >= 80) + other.ammo_ric = 100; + } + + else + objerror ("weapon_touch: unknown classname"); + + sprint (other, "You got the "); + sprint (other, self.netname); + sprint (other, "\n"); +// weapon touch sound + sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + + bound_other_ammo (); + +// change to the weapon + old = other.items; + other.items = other.items | new; + + stemp = self; + self = other; + + if (!deathmatch) + self.weapon = new; + else + Deathmatch_Weapon (old, new); + + W_SetCurrentAmmo(); + + self = stemp; + + if (leave) + return; + +// remove it in single player, or setup for respawning in deathmatch + self.model = string_null; + self.solid = SOLID_NOT; + if (deathmatch == 1) + self.nextthink = time + 30; + self.think = SUB_regen; + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +/*Prime Weapon Rocket Launcher +*/ +void() weapon_supershotgun = +{ + precache_model ("progs/item_rocket.mdl"); + setmodel (self, "progs/item_rocket.mdl"); + self.weapon = IT_ROCKET; + self.netname = "Rocket Launcher"; + self.touch = weapon_touch; + self.effects = EF_DIMLIGHT; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; + +/*Prime Weapon Splaser +*/ + +void() weapon_nailgun = +{ + precache_model ("progs/item_splaser.spr"); + setmodel (self, "progs/item_splaser.spr"); + self.weapon = IT_SPLASER; + self.netname = "Splaser"; + self.touch = weapon_touch; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; + +/* Prime Weapon SNiper +*/ + +void() weapon_sniper = +{ + precache_model ("progs/item_sniper.spr"); + setmodel (self, "progs/item_sniper.spr"); + self.weapon = IT_SNIPER; + self.classname = "weapon_sniper"; + self.netname = "Sniper"; + self.touch = weapon_touch; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; + +/*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() weapon_grenadelauncher = +{ + precache_model ("progs/g_rock.mdl"); + setmodel (self, "progs/g_rock.mdl"); + self.weapon = 3; + self.netname = "Grenade Launcher"; + self.touch = weapon_touch; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/*Prime Weapon Magma beam +*/ + +void() weapon_magma = +{ + precache_model ("progs/item_magma.spr"); + setmodel (self, "progs/item_magma.spr"); + self.weapon = 3; + self.classname = "weapon_magma"; + self.netname = "Magma Beam"; + self.touch = weapon_touch; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + + +/*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() weapon_lightning = +{ + precache_model ("progs/g_light.mdl"); + setmodel (self, "progs/g_light.mdl"); + self.weapon = 3; + self.netname = "Thunderbolt"; + self.touch = weapon_touch; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/*Prime Weapon Richochet beam +*/ +void() weapon_ric = +{ + precache_model ("progs/item_ric.spr"); + setmodel (self, "progs/item_ric.spr"); + self.weapon = IT_RIC; + self.classname = "weapon_ric"; + self.netname = "Richochet Beam"; + self.touch = weapon_touch; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; + + + +/* +=============================================================================== + +AMMO + +=============================================================================== +*/ + +void() ammo_touch = +{ +local entity stemp; + + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + +// if the player was using his best weapon, change up to the new one if better + stemp = self; + self = other; + self = stemp; + + +// shotgun + if (self.weapon == 1) + { + if (other.ammo_shells >= 100) + return; + other.ammo_shells = other.ammo_shells + self.aflag; + } + +// rockets + if (self.weapon == 3) + { + if (other.ammo_rockets >= 100) + return; + other.ammo_rockets = other.ammo_rockets + self.aflag; + } + +// cells + if (self.weapon == 4) + { + if (other.ammo_cells >= 100) + return; + other.ammo_cells = other.ammo_cells + self.aflag; + } + + bound_other_ammo (); + + sprint (other, "You got the "); + sprint (other, self.netname); + sprint (other, "\n"); +// ammo touch sound + sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + + +// if changed current ammo, update it + stemp = self; + self = other; + W_SetCurrentAmmo(); + self = stemp; + +// remove it in single player, or setup for respawning in deathmatch + self.model = string_null; + self.solid = SOLID_NOT; + if (deathmatch == 1) + self.nextthink = time + 30; + self.think = SUB_regen; + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + + + +float WEAPON_BIG2 = 1; + +/*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big +*/ + +void() item_shells = +{ + self.touch = ammo_touch; + + if (self.spawnflags & WEAPON_BIG2) + { + precache_model ("maps/b_shell1.bsp"); + setmodel (self, "maps/b_shell1.bsp"); + self.aflag = 40; + } + else + { + precache_model ("maps/b_shell0.bsp"); + setmodel (self, "maps/b_shell0.bsp"); + self.aflag = 20; + } + self.weapon = 1; + self.netname = "shells"; + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; + +/*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big +*/ + +void() item_spikes = +{ + self.touch = ammo_touch; + + if (self.spawnflags & WEAPON_BIG2) + { + precache_model ("maps/b_nail1.bsp"); + setmodel (self, "maps/b_nail1.bsp"); + self.aflag = 50; + } + else + { + precache_model ("maps/b_nail0.bsp"); + setmodel (self, "maps/b_nail0.bsp"); + self.aflag = 25; + } + self.weapon = 2; + self.netname = "nails"; + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; + +/*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big +*/ + +void() item_rockets = +{ + self.touch = ammo_touch; + + if (self.spawnflags & WEAPON_BIG2) + { + precache_model ("maps/b_rock1.bsp"); + setmodel (self, "maps/b_rock1.bsp"); + self.aflag = 10; + } + else + { + precache_model ("maps/b_rock0.bsp"); + setmodel (self, "maps/b_rock0.bsp"); + self.aflag = 5; + } + self.weapon = 3; + self.netname = "rockets"; + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; + + +/*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big +*/ + +void() item_cells = +{ + self.touch = ammo_touch; + + if (self.spawnflags & WEAPON_BIG2) + { + precache_model ("maps/b_batt1.bsp"); + setmodel (self, "maps/b_batt1.bsp"); + self.aflag = 12; + } + else + { + precache_model ("maps/b_batt0.bsp"); + setmodel (self, "maps/b_batt0.bsp"); + self.aflag = 6; + } + self.weapon = 4; + self.netname = "cells"; + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; + + +/*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big +DO NOT USE THIS!!!! IT WILL BE REMOVED! +*/ + +float WEAPON_SHOTGUN = 1; +float WEAPON_ROCKET = 2; +float WEAPON_SPIKES = 4; +float WEAPON_BIG = 8; +void() item_weapon = +{ + self.touch = ammo_touch; + + if (self.spawnflags & WEAPON_SHOTGUN) + { + if (self.spawnflags & WEAPON_BIG) + { + precache_model ("maps/b_shell1.bsp"); + setmodel (self, "maps/b_shell1.bsp"); + self.aflag = 40; + } + else + { + precache_model ("maps/b_shell0.bsp"); + setmodel (self, "maps/b_shell0.bsp"); + self.aflag = 20; + } + self.weapon = 1; + self.netname = "shells"; + } + + if (self.spawnflags & WEAPON_SPIKES) + { + if (self.spawnflags & WEAPON_BIG) + { + precache_model ("maps/b_nail1.bsp"); + setmodel (self, "maps/b_nail1.bsp"); + self.aflag = 40; + } + else + { + precache_model ("maps/b_nail0.bsp"); + setmodel (self, "maps/b_nail0.bsp"); + self.aflag = 20; + } + self.weapon = 2; + self.netname = "spikes"; + } + + if (self.spawnflags & WEAPON_ROCKET) + { + if (self.spawnflags & WEAPON_BIG) + { + precache_model ("maps/b_rock1.bsp"); + setmodel (self, "maps/b_rock1.bsp"); + self.aflag = 10; + } + else + { + precache_model ("maps/b_rock0.bsp"); + setmodel (self, "maps/b_rock0.bsp"); + self.aflag = 5; + } + self.weapon = 3; + self.netname = "rockets"; + } + + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; + + +/* +=============================================================================== + +KEYS + +=============================================================================== +*/ + +void() key_touch = +{ + if (other.classname != "player") + return; + if (other.health <= 0) + return; + if (other.items & self.items) + return; + + sprint (other, "You got the "); + sprint (other, self.netname); + sprint (other,"\n"); + + sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + other.items = other.items | self.items; + + if (!coop) + { + self.solid = SOLID_NOT; + self.model = string_null; + } + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +void() key_setsounds = +{ + if (world.worldtype == 0) + { + precache_sound ("misc/medkey.wav"); + self.noise = "misc/medkey.wav"; + } + if (world.worldtype == 1) + { + precache_sound ("misc/runekey.wav"); + self.noise = "misc/runekey.wav"; + } + if (world.worldtype == 2) + { + precache_sound2 ("misc/basekey.wav"); + self.noise = "misc/basekey.wav"; + } +}; + +/*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) +SILVER key +In order for keys to work +you MUST set your maps +worldtype to one of the +following: +0: medieval +1: metal +2: base +*/ + +void() item_key1 = +{ + if (world.worldtype == 0) + { + precache_model ("progs/w_s_key.mdl"); + setmodel (self, "progs/w_s_key.mdl"); + self.netname = "silver key"; + } + else if (world.worldtype == 1) + { + precache_model ("progs/m_s_key.mdl"); + setmodel (self, "progs/m_s_key.mdl"); + self.netname = "silver runekey"; + } + else if (world.worldtype == 2) + { + precache_model2 ("progs/b_s_key.mdl"); + setmodel (self, "progs/b_s_key.mdl"); + self.netname = "silver keycard"; + } + key_setsounds(); + self.touch = key_touch; + self.items = IT_KEY1; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + +/*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) +GOLD key +In order for keys to work +you MUST set your maps +worldtype to one of the +following: +0: medieval +1: metal +2: base +*/ + +void() item_key2 = +{ + if (world.worldtype == 0) + { + precache_model ("progs/w_g_key.mdl"); + setmodel (self, "progs/w_g_key.mdl"); + self.netname = "gold key"; + } + if (world.worldtype == 1) + { + precache_model ("progs/m_g_key.mdl"); + setmodel (self, "progs/m_g_key.mdl"); + self.netname = "gold runekey"; + } + if (world.worldtype == 2) + { + precache_model2 ("progs/b_g_key.mdl"); + setmodel (self, "progs/b_g_key.mdl"); + self.netname = "gold keycard"; + } + key_setsounds(); + self.touch = key_touch; + self.items = IT_KEY2; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + + +/* +=============================================================================== + +END OF LEVEL RUNES + +=============================================================================== +*/ + +void() sigil_touch = +{ + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + centerprint (other, "You got the rune!"); + + sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + self.model = string_null; + serverflags = serverflags | (self.spawnflags & 15); + self.classname = ""; // so rune doors won't find it + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +/*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4 +End of level sigil, pick up to end episode and return to jrstart. +*/ + +void() item_sigil = +{ + if (!self.spawnflags) + objerror ("no spawnflags"); + + precache_sound ("misc/runekey.wav"); + self.noise = "misc/runekey.wav"; + + if (self.spawnflags & 1) + { + precache_model ("progs/end1.mdl"); + setmodel (self, "progs/end1.mdl"); + } + if (self.spawnflags & 2) + { + precache_model2 ("progs/end2.mdl"); + setmodel (self, "progs/end2.mdl"); + } + if (self.spawnflags & 4) + { + precache_model2 ("progs/end3.mdl"); + setmodel (self, "progs/end3.mdl"); + } + if (self.spawnflags & 8) + { + precache_model2 ("progs/end4.mdl"); + setmodel (self, "progs/end4.mdl"); + } + + self.touch = sigil_touch; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + +/* +=============================================================================== + +POWERUPS + +=============================================================================== +*/ + +void() powerup_touch; + + +void() powerup_touch = +{ + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + sprint (other, "You got the "); + sprint (other, self.netname); + sprint (other,"\n"); + + if (deathmatch) + { + self.mdl = self.model; + + if ((self.classname == "item_artifact_invulnerability") || + (self.classname == "item_artifact_invisibility")) + self.nextthink = time + 60*5; + else + self.nextthink = time + 60; + + self.think = SUB_regen; + } + + sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + other.items = other.items | self.items; + self.model = string_null; + +// do the apropriate action + if (self.classname == "item_artifact_envirosuit") + { + other.rad_time = 1; + other.radsuit_finished = time + 30; + } + + if (self.classname == "item_artifact_invulnerability") + { + other.invincible_time = 1; + other.invincible_finished = time + 30; + } + + if (self.classname == "item_artifact_invisibility") + { + other.invisible_time = 1; + other.invisible_finished = time + 30; + } + + if (self.classname == "item_artifact_super_damage") + { + other.super_time = 1; + other.super_damage_finished = time + 30; + } + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + + +/*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32) +Player is invulnerable for 30 seconds +*/ +void() item_artifact_invulnerability = +{ + self.touch = powerup_touch; + + precache_model ("progs/invulner.mdl"); + precache_sound ("items/protect.wav"); + precache_sound ("items/protect2.wav"); + precache_sound ("items/protect3.wav"); + self.noise = "items/protect.wav"; + setmodel (self, "progs/invulner.mdl"); + self.netname = "Pentagram of Protection"; + self.items = IT_INVULNERABILITY; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + +/*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32) +Player takes no damage from water or slime for 30 seconds +*/ +void() item_artifact_envirosuit = +{ + self.touch = powerup_touch; + + precache_model ("progs/suit.mdl"); + precache_sound ("items/suit.wav"); + precache_sound ("items/suit2.wav"); + self.noise = "items/suit.wav"; + setmodel (self, "progs/suit.mdl"); + self.netname = "Biosuit"; + self.items = IT_SUIT; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + +/*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32) +Player is invisible for 30 seconds +*/ +void() item_artifact_invisibility = +{ + self.touch = powerup_touch; + + precache_model ("progs/invisibl.mdl"); + precache_sound ("items/inv1.wav"); + precache_sound ("items/inv2.wav"); + precache_sound ("items/inv3.wav"); + self.noise = "items/inv1.wav"; + setmodel (self, "progs/invisibl.mdl"); + self.netname = "Ring of Shadows"; + self.items = IT_INVISIBILITY; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + +/*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32) +The next attack from the player will do 4x damage +*/ +void() item_artifact_super_damage = +{ + self.touch = powerup_touch; + + precache_model ("progs/quaddama.mdl"); + precache_sound ("items/damage.wav"); + precache_sound ("items/damage2.wav"); + precache_sound ("items/damage3.wav"); + self.noise = "items/damage.wav"; + setmodel (self, "progs/quaddama.mdl"); + self.netname = "Quad Damage"; + self.items = IT_QUAD; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + + +/* +=============================================================================== + +PLAYER BACKPACKS + +=============================================================================== +*/ + +void() BackpackTouch = +{ + local string s; + local float old, new; + local entity stemp; + local float acount; + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + acount = 0; + sprint (other, "You get "); + + if (self.items) + if ((other.items & self.items) == 0) + { + acount = 1; + sprint (other, "the "); + sprint (other, self.netname); + } + +// if the player was using his best weapon, change up to the new one if better + stemp = self; + self = other; + //best = W_BestWeapon(); + self = stemp; + +// change weapons + other.ammo_shells = other.ammo_shells + self.ammo_shells; + other.ammo_nails = other.ammo_nails + self.ammo_nails; + other.ammo_rockets = other.ammo_rockets + self.ammo_rockets; + other.ammo_cells = other.ammo_cells + self.ammo_cells; + + new = self.items; + if (!new) + new = other.weapon; + old = other.items; + other.items = other.items | new; + + bound_other_ammo (); + + if (self.ammo_shells) + { + if (acount) + sprint(other, ", "); + acount = 1; + s = ftos(self.ammo_shells); + sprint (other, s); + sprint (other, " shells"); + } + if (self.ammo_nails) + { + if (acount) + sprint(other, ", "); + acount = 1; + s = ftos(self.ammo_nails); + sprint (other, s); + sprint (other, " nails"); + } + if (self.ammo_rockets) + { + if (acount) + sprint(other, ", "); + acount = 1; + s = ftos(self.ammo_rockets); + sprint (other, s); + sprint (other, " rockets"); + } + if (self.ammo_cells) + { + if (acount) + sprint(other, ", "); + acount = 1; + s = ftos(self.ammo_cells); + sprint (other, s); + sprint (other, " cells"); + } + + sprint (other, "\n"); +// backpack touch sound + sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + +// remove the backpack, change self to the player + remove(self); + self = other; + +// change to the weapon + if (!deathmatch) + self.weapon = new; + else + Deathmatch_Weapon (old, new); + + W_SetCurrentAmmo (); +}; + +/* +=============== +DropBackpack +=============== +*/ +void() DropBackpack = +{ + local entity item; + + if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells)) + return; // nothing in it + + item = spawn(); + item.origin = self.origin - '0 0 24'; + + item.items = self.weapon; + if (item.items == IT_MORPHBALL) + item.netname = "Axe"; + else if (item.items == IT_BLASTER) + item.netname = "Shotgun"; + else if (item.items == IT_ROCKET) + item.netname = "Double-barrelled Shotgun"; + else if (item.items == IT_SPLASER) + item.netname = "Nailgun"; + else if (item.items == IT_SNIPER) + item.netname = "Super Nailgun"; + else if (item.items == IT_GRENADE_LAUNCHER) + item.netname = "Grenade Launcher"; + else if (item.items == IT_MAGMA) + item.netname = "Rocket Launcher"; + else if (item.items == IT_LIGHTNING) + item.netname = "Thunderbolt"; + else + item.netname = ""; + + item.ammo_shells = self.ammo_shells; + item.ammo_nails = self.ammo_nails; + item.ammo_rockets = self.ammo_rockets; + item.ammo_cells = self.ammo_cells; + + item.velocity_z = 300; + item.velocity_x = -100 + (random() * 200); + item.velocity_y = -100 + (random() * 200); + + item.flags = FL_ITEM; + item.solid = SOLID_TRIGGER; + item.movetype = MOVETYPE_TOSS; + setmodel (item, "progs/backpack.mdl"); + setsize (item, '-16 -16 0', '16 16 56'); + item.touch = BackpackTouch; + + item.nextthink = time + 120; // remove after 2 minutes + item.think = SUB_Remove; +}; +void() energy_touch = +{ +if (other.classname != "player") + return; +other.energy = other.energy + 1; +if (other.energy == 1) +{ +other.health = 199; +other.max_health = 199; +} +else if (other.energy == 2) +{ +other.health = 299; +other.max_health = 299; +} +else if (other.energy == 3) +{ +other.health = 399; +other.max_health = 399; +} +else if (other.energy == 4) +{ +other.health = 499; +other.max_health = 499; +} +else if (other.energy == 5) +{ +other.health = 599; +other.max_health = 599; +} +else if (other.energy == 6) +{ +other.health = 699; +other.max_health = 699; +} +else if (other.energy == 7) +{ +other.health = 799; +other.max_health = 799; +} +else if (other.energy == 8) +{ +other.health = 899; +other.max_health = 899; +} +else if (other.energy == 9) +{ +other.health = 999; +other.max_health = 999; +} +else +other.max_health = 99; + +self.model = string_null; +self.solid = SOLID_NOT; + +activator = other; +SUB_UseTargets(); // fire all targets / killtargets +}; +void() item_energytank = +{ + if (deathmatch) + remove(self); + precache_model("progs/etank.mdl"); + precache_sound("items/r_item1.wav"); + setmodel(self, "progs/etank.mdl"); + self.noise = "items/r_item1.wav"; + self.classname = "etank"; + self.effects = EF_DIMLIGHT; + self.healamount = other.max_health; + self.touch = energy_touch; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/jctest.qc b/r17/Revamped src/Revamped QC/Primeqc4/jctest.qc new file mode 100755 index 00000000..85a7605f --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/jctest.qc @@ -0,0 +1,15 @@ + +void() jctrig = +{ +dprint ("here\n\n"); + lightstyle(0, "az"); +}; + +/*QUAKED trigger_jctest (.5 .5 .5) ? +*/ +void() trigger_jctest = +{ + setsize (self, self.mins, self.maxs); + self.solid = SOLID_EDGE; + self.touch = jctrig; +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/knight.qc b/r17/Revamped src/Revamped QC/Primeqc4/knight.qc new file mode 100755 index 00000000..4969750d --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/knight.qc @@ -0,0 +1,270 @@ +/* +============================================================================== + +KNIGHT + +============================================================================== +*/ + +$cd id1/models/knight +$origin 0 0 24 +$base base +$skin badass3 + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame runb1 runb2 runb3 runb4 runb5 runb6 runb7 runb8 + +//frame runc1 runc2 runc3 runc4 runc5 runc6 + +$frame runattack1 runattack2 runattack3 runattack4 runattack5 +$frame runattack6 runattack7 runattack8 runattack9 runattack10 +$frame runattack11 + +$frame pain1 pain2 pain3 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 +$frame painb10 painb11 + +//frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 +//frame attack8 attack9 attack10 attack11 + +$frame attackb1 attackb2 attackb3 attackb4 attackb5 +$frame attackb6 attackb7 attackb8 attackb9 attackb10 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 +$frame walk10 walk11 walk12 walk13 walk14 + +$frame kneel1 kneel2 kneel3 kneel4 kneel5 + +$frame standing2 standing3 standing4 standing5 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 deathb10 deathb11 + +void() knight_stand1 =[ $stand1, knight_stand2 ] {ai_stand();}; +void() knight_stand2 =[ $stand2, knight_stand3 ] {ai_stand();}; +void() knight_stand3 =[ $stand3, knight_stand4 ] {ai_stand();}; +void() knight_stand4 =[ $stand4, knight_stand5 ] {ai_stand();}; +void() knight_stand5 =[ $stand5, knight_stand6 ] {ai_stand();}; +void() knight_stand6 =[ $stand6, knight_stand7 ] {ai_stand();}; +void() knight_stand7 =[ $stand7, knight_stand8 ] {ai_stand();}; +void() knight_stand8 =[ $stand8, knight_stand9 ] {ai_stand();}; +void() knight_stand9 =[ $stand9, knight_stand1 ] {ai_stand();}; + +void() knight_walk1 =[ $walk1, knight_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE); +ai_walk(3);}; +void() knight_walk2 =[ $walk2, knight_walk3 ] {ai_walk(2);}; +void() knight_walk3 =[ $walk3, knight_walk4 ] {ai_walk(3);}; +void() knight_walk4 =[ $walk4, knight_walk5 ] {ai_walk(4);}; +void() knight_walk5 =[ $walk5, knight_walk6 ] {ai_walk(3);}; +void() knight_walk6 =[ $walk6, knight_walk7 ] {ai_walk(3);}; +void() knight_walk7 =[ $walk7, knight_walk8 ] {ai_walk(3);}; +void() knight_walk8 =[ $walk8, knight_walk9 ] {ai_walk(4);}; +void() knight_walk9 =[ $walk9, knight_walk10 ] {ai_walk(3);}; +void() knight_walk10 =[ $walk10, knight_walk11 ] {ai_walk(3);}; +void() knight_walk11 =[ $walk11, knight_walk12 ] {ai_walk(2);}; +void() knight_walk12 =[ $walk12, knight_walk13 ] {ai_walk(3);}; +void() knight_walk13 =[ $walk13, knight_walk14 ] {ai_walk(4);}; +void() knight_walk14 =[ $walk14, knight_walk1 ] {ai_walk(3);}; + + +void() knight_run1 =[ $runb1, knight_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE); +ai_run(16);}; +void() knight_run2 =[ $runb2, knight_run3 ] {ai_run(20);}; +void() knight_run3 =[ $runb3, knight_run4 ] {ai_run(13);}; +void() knight_run4 =[ $runb4, knight_run5 ] {ai_run(7);}; +void() knight_run5 =[ $runb5, knight_run6 ] {ai_run(16);}; +void() knight_run6 =[ $runb6, knight_run7 ] {ai_run(20);}; +void() knight_run7 =[ $runb7, knight_run8 ] {ai_run(14);}; +void() knight_run8 =[ $runb8, knight_run1 ] {ai_run(6);}; + + +void() knight_runatk1 =[ $runattack1, knight_runatk2 ] +{ +if (random() > 0.5) + sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM); +else + sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +ai_charge(20); +}; +void() knight_runatk2 =[ $runattack2, knight_runatk3 ] {ai_charge_side();}; +void() knight_runatk3 =[ $runattack3, knight_runatk4 ] {ai_charge_side();}; +void() knight_runatk4 =[ $runattack4, knight_runatk5 ] {ai_charge_side();}; +void() knight_runatk5 =[ $runattack5, knight_runatk6 ] {ai_melee_side();}; +void() knight_runatk6 =[ $runattack6, knight_runatk7 ] {ai_melee_side();}; +void() knight_runatk7 =[ $runattack7, knight_runatk8 ] {ai_melee_side();}; +void() knight_runatk8 =[ $runattack8, knight_runatk9 ] {ai_melee_side();}; +void() knight_runatk9 =[ $runattack9, knight_runatk10 ] {ai_melee_side();}; +void() knight_runatk10 =[ $runattack10, knight_runatk11 ] {ai_charge_side();}; +void() knight_runatk11 =[ $runattack11, knight_run1 ] {ai_charge(10);}; + +void() knight_atk1 =[ $attackb1, knight_atk2 ] +{ +sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +ai_charge(0);}; +void() knight_atk2 =[ $attackb2, knight_atk3 ] {ai_charge(7);}; +void() knight_atk3 =[ $attackb3, knight_atk4 ] {ai_charge(4);}; +void() knight_atk4 =[ $attackb4, knight_atk5 ] {ai_charge(0);}; +void() knight_atk5 =[ $attackb5, knight_atk6 ] {ai_charge(3);}; +void() knight_atk6 =[ $attackb6, knight_atk7 ] {ai_charge(4); ai_melee();}; +void() knight_atk7 =[ $attackb7, knight_atk8 ] {ai_charge(1); ai_melee();}; +void() knight_atk8 =[ $attackb8, knight_atk9 ] {ai_charge(3); +ai_melee();}; +void() knight_atk9 =[ $attackb9, knight_atk10] {ai_charge(1);}; +void() knight_atk10=[ $attackb10, knight_run1 ] {ai_charge(5);}; + +//void() knight_atk9 =[ $attack9, knight_atk10 ] {}; +//void() knight_atk10 =[ $attack10, knight_atk11 ] {}; +//void() knight_atk11 =[ $attack11, knight_run1 ] {}; + +//=========================================================================== + +void() knight_pain1 =[ $pain1, knight_pain2 ] {}; +void() knight_pain2 =[ $pain2, knight_pain3 ] {}; +void() knight_pain3 =[ $pain3, knight_run1 ] {}; + +void() knight_painb1 =[ $painb1, knight_painb2 ] {ai_painforward(0);}; +void() knight_painb2 =[ $painb2, knight_painb3 ] {ai_painforward(3);}; +void() knight_painb3 =[ $painb3, knight_painb4 ] {}; +void() knight_painb4 =[ $painb4, knight_painb5 ] {}; +void() knight_painb5 =[ $painb5, knight_painb6 ] {ai_painforward(2);}; +void() knight_painb6 =[ $painb6, knight_painb7 ] {ai_painforward(4);}; +void() knight_painb7 =[ $painb7, knight_painb8 ] {ai_painforward(2);}; +void() knight_painb8 =[ $painb8, knight_painb9 ] {ai_painforward(5);}; +void() knight_painb9 =[ $painb9, knight_painb10 ] {ai_painforward(5);}; +void() knight_painb10 =[ $painb10, knight_painb11 ] {ai_painforward(0);}; +void() knight_painb11 =[ $painb11, knight_run1 ] {}; + +void(entity attacker, float damage) knight_pain = +{ + local float r; + + if (self.pain_finished > time) + return; + + r = random(); + + sound (self, CHAN_VOICE, "knight/khurt.wav", 1, ATTN_NORM); + if (r < 0.85) + { + knight_pain1 (); + self.pain_finished = time + 1; + } + else + { + knight_painb1 (); + self.pain_finished = time + 1; + } + +}; + +//=========================================================================== + +void() knight_bow1 =[ $kneel1, knight_bow2 ] {ai_turn();}; +void() knight_bow2 =[ $kneel2, knight_bow3 ] {ai_turn();}; +void() knight_bow3 =[ $kneel3, knight_bow4 ] {ai_turn();}; +void() knight_bow4 =[ $kneel4, knight_bow5 ] {ai_turn();}; + +void() knight_bow5 =[ $kneel5, knight_bow5 ] {ai_turn();}; + +void() knight_bow6 =[ $kneel4, knight_bow7 ] {ai_turn();}; +void() knight_bow7 =[ $kneel3, knight_bow8 ] {ai_turn();}; +void() knight_bow8 =[ $kneel2, knight_bow9 ] {ai_turn();}; +void() knight_bow9 =[ $kneel1, knight_bow10 ] {ai_turn();}; +void() knight_bow10 =[ $walk1, knight_walk1 ] {ai_turn();}; + + + +void() knight_die1 =[ $death1, knight_die2 ] {}; +void() knight_die2 =[ $death2, knight_die3 ] {}; +void() knight_die3 =[ $death3, knight_die4 ] +{self.solid = SOLID_NOT;}; +void() knight_die4 =[ $death4, knight_die5 ] {}; +void() knight_die5 =[ $death5, knight_die6 ] {}; +void() knight_die6 =[ $death6, knight_die7 ] {}; +void() knight_die7 =[ $death7, knight_die8 ] {}; +void() knight_die8 =[ $death8, knight_die9 ] {}; +void() knight_die9 =[ $death9, knight_die10] {}; +void() knight_die10=[ $death10, knight_die10] {}; + + +void() knight_dieb1 =[ $deathb1, knight_dieb2 ] {}; +void() knight_dieb2 =[ $deathb2, knight_dieb3 ] {}; +void() knight_dieb3 =[ $deathb3, knight_dieb4 ] +{self.solid = SOLID_NOT;}; +void() knight_dieb4 =[ $deathb4, knight_dieb5 ] {}; +void() knight_dieb5 =[ $deathb5, knight_dieb6 ] {}; +void() knight_dieb6 =[ $deathb6, knight_dieb7 ] {}; +void() knight_dieb7 =[ $deathb7, knight_dieb8 ] {}; +void() knight_dieb8 =[ $deathb8, knight_dieb9 ] {}; +void() knight_dieb9 =[ $deathb9, knight_dieb10] {}; +void() knight_dieb10 = [ $deathb10, knight_dieb11] {}; +void() knight_dieb11 = [ $deathb11, knight_dieb11] {}; + + +void() knight_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_knight.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "knight/kdeath.wav", 1, ATTN_NORM); + if (random() < 0.5) + knight_die1 (); + else + knight_dieb1 (); +}; + + +/*QUAKED monster_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_wizard = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/metroid.mdl"); + precache_model ("progs/h_knight.mdl"); + + precache_sound ("knight/kdeath.wav"); + precache_sound ("knight/khurt.wav"); + precache_sound ("knight/ksight.wav"); + precache_sound ("knight/sword1.wav"); + precache_sound ("knight/sword2.wav"); + precache_sound ("knight/idle.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/metroid.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 75; + + self.th_stand = knight_stand1; + self.th_walk = knight_walk1; + self.th_run = knight_run1; + self.th_melee = knight_atk1; + self.th_pain = knight_pain; + self.th_die = knight_die; + + flymonster_start (); +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/misc.qc b/r17/Revamped src/Revamped QC/Primeqc4/misc.qc new file mode 100755 index 00000000..30a4fc90 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/misc.qc @@ -0,0 +1,715 @@ + +/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4) +Used as a positional target for spotlights, etc. +*/ +void() info_null = +{ + remove(self); +}; + +/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4) +Used as a positional target for lightning. +*/ +void() info_notnull = +{ +}; + +//============================================================================ + +float START_OFF = 1; + +void() light_use = +{ + if (self.spawnflags & START_OFF) + { + lightstyle(self.style, "m"); + self.spawnflags = self.spawnflags - START_OFF; + } + else + { + lightstyle(self.style, "a"); + self.spawnflags = self.spawnflags + START_OFF; + } +}; + +/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF +Non-displayed light. +Default light value is 300 +Default style is 0 +If targeted, it will toggle between on or off. +*/ +void() light = +{ + if (!self.targetname) + { // inert light + remove(self); + return; + } + + if (self.style >= 32) + { + self.use = light_use; + if (self.spawnflags & START_OFF) + lightstyle(self.style, "a"); + else + lightstyle(self.style, "m"); + } +}; + +/*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF +Non-displayed light. +Default light value is 300 +Default style is 0 +If targeted, it will toggle between on or off. +Makes steady fluorescent humming sound +*/ +void() light_fluoro = +{ + if (self.style >= 32) + { + self.use = light_use; + if (self.spawnflags & START_OFF) + lightstyle(self.style, "a"); + else + lightstyle(self.style, "m"); + } + + precache_sound ("ambience/fl_hum1.wav"); + ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8) +Non-displayed light. +Default light value is 300 +Default style is 10 +Makes sparking, broken fluorescent sound +*/ +void() light_fluorospark = +{ + if (!self.style) + self.style = 10; + + precache_sound ("ambience/buzz1.wav"); + ambientsound (self.origin, "ambience/buzz1.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8) +Sphere globe light. +Default light value is 300 +Default style is 0 +*/ +void() light_globe = +{ + precache_model ("progs/s_light.spr"); + setmodel (self, "progs/s_light.spr"); + makestatic (self); +}; + +void() FireAmbient = +{ + precache_sound ("ambience/fire1.wav"); +// attenuate fast + ambientsound (self.origin, "ambience/fire1.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20) +Short wall torch +Default light value is 200 +Default style is 0 +*/ +void() light_torch_small_walltorch = +{ + precache_model ("progs/flame.mdl"); + setmodel (self, "progs/flame.mdl"); + FireAmbient (); + makestatic (self); +}; + +/*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18) +Large yellow flame ball +*/ +void() light_flame_large_yellow = +{ + precache_model ("progs/flame2.mdl"); + setmodel (self, "progs/flame2.mdl"); + self.frame = 1; + FireAmbient (); + makestatic (self); +}; + +/*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) START_OFF +Small yellow flame ball +*/ +void() light_flame_small_yellow = +{ + precache_model ("progs/flame2.mdl"); + setmodel (self, "progs/flame2.mdl"); + FireAmbient (); + makestatic (self); +}; + +/*QUAKED light_flame_small_white (0 1 0) (-10 -10 -40) (10 10 40) START_OFF +Small white flame ball +*/ +void() light_flame_small_white = +{ + precache_model ("progs/flame2.mdl"); + setmodel (self, "progs/flame2.mdl"); + FireAmbient (); + makestatic (self); +}; + +//============================================================================ + + +/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8) +Lava Balls +*/ + +void() fire_fly; +void() fire_touch; +void() misc_fireball = +{ + + self.classname = "fireball"; + self.nextthink = time + (random() * 5); + self.think = fire_fly; + //if (!self.speed) + //self.speed == 1000; +}; + +void() fire_fly = +{ +local entity fireball; + + fireball = spawn(); + fireball.solid = SOLID_TRIGGER; + fireball.movetype = MOVETYPE_TOSS; + fireball.velocity = '0 0 1000'; + fireball.velocity_x = (random() * 100) - 50; + fireball.velocity_y = (random() * 100) - 50; + fireball.velocity_z = self.speed + (random() * 200); + fireball.classname = "fireball"; + setmodel (fireball, "progs/lavaball.mdl"); + setsize (fireball, '0 0 0', '0 0 0'); + setorigin (fireball, self.origin); + fireball.nextthink = time + 5; + fireball.think = SUB_Remove; + fireball.touch = fire_touch; + + self.nextthink = time + (random() * 5) + 3; + self.think = fire_fly; +}; + + +void() fire_touch = +{ + T_Damage (other, self, self, 20); + remove(self); +}; + +//============================================================================ + + +void() barrel_explode = +{ + self.takedamage = DAMAGE_NO; + self.classname = "explo_box"; + // did say self.owner + T_RadiusDamage (self, self, 160, world); + sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM); + particle (self.origin, '0 0 0', 75, 255); + + self.origin_z = self.origin_z + 32; + CreateExplosion(self.origin); + remove(self); +}; + + + +/*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64) +TESTING THING +*/ + +void() misc_explobox = +{ + local float oldz; + + self.solid = SOLID_BBOX; + self.movetype = MOVETYPE_NONE; + precache_model ("maps/b_explob.bsp"); + setmodel (self, "maps/b_explob.bsp"); + precache_sound ("weapons/r_exp3.wav"); + self.health = 20; + self.th_die = barrel_explode; + self.takedamage = DAMAGE_AIM; + + self.origin_z = self.origin_z + 2; + oldz = self.origin_z; + droptofloor(1, 1); + if (oldz - self.origin_z > 250) + { + dprint ("item fell out of level at "); + dprint (vtos(self.origin)); + dprint ("\n"); + remove(self); + } +}; + + + + +/*QUAKED misc_explobox2 (0 .5 .8) (0 0 0) (32 32 64) +Smaller exploding box, REGISTERED ONLY +*/ + +void() misc_explobox2 = +{ + self.solid = SOLID_BBOX; + self.movetype = MOVETYPE_NONE; + precache_model2 ("maps/b_exbox2.bsp"); + setmodel (self, "maps/b_exbox2.bsp"); + precache_sound ("weapons/r_exp3.wav"); + self.health = 20; + self.th_die = barrel_explode; + self.takedamage = DAMAGE_AIM; +}; + +//============================================================================ + +float SPAWNFLAG_SUPERSPIKE = 1; +float SPAWNFLAG_LASER = 2; + +void(vector org, vector vec) LaunchLaser; + +void() spikeshooter_use = +{ + if (self.spawnflags & SPAWNFLAG_LASER) + { + sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM); + LaunchLaser (self.origin, self.movedir); + } + else + { + sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM); + launch_spike (self.origin, self.movedir); + newmis.velocity = self.movedir * 500; + if (self.spawnflags & SPAWNFLAG_SUPERSPIKE) + newmis.touch = superspike_touch; + } +}; + +void() shooter_think = +{ + spikeshooter_use (); + self.nextthink = time + self.wait; + newmis.velocity = self.movedir * 500; +}; + + +/*QUAKED trap_spikeshooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser +When triggered, fires a spike in the direction set in QuakeEd. +Laser is only for REGISTERED. +*/ + +void() trap_spikeshooter = +{ + SetMovedir (); + self.use = spikeshooter_use; + if (self.spawnflags & SPAWNFLAG_LASER) + { + precache_model2 ("progs/laser.mdl"); + + precache_sound2 ("enforcer/enfire.wav"); + precache_sound2 ("enforcer/enfstop.wav"); + } + else + precache_sound ("weapons/spike2.wav"); +}; + + +/*QUAKED trap_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser +Continuously fires spikes. +"wait" time between spike (1.0 default) +"nextthink" delay before firing first spike, so multiple shooters can be stagered. +*/ +void() trap_shooter = +{ + trap_spikeshooter (); + + if (self.wait == 0) + self.wait = 1; + self.nextthink = self.nextthink + self.wait + self.ltime; + self.think = shooter_think; +}; + + + +/* +=============================================================================== + + +=============================================================================== +*/ + + +void() make_bubbles; +void() bubble_remove; +void() bubble_bob; + +/*QUAKED air_bubbles (0 .5 .8) (-8 -8 -8) (8 8 8) + +testing air bubbles +*/ + +void() air_bubbles = + +{ + if (deathmatch) + { + remove (self); + return; + } + precache_model ("progs/s_bubble.spr"); + self.nextthink = time + 1; + self.think = make_bubbles; +}; + +void() make_bubbles = +{ +local entity bubble; + + bubble = spawn(); + setmodel (bubble, "progs/s_bubble.spr"); + setorigin (bubble, self.origin); + bubble.movetype = MOVETYPE_NOCLIP; + bubble.solid = SOLID_NOT; + bubble.velocity = '0 0 15'; + bubble.nextthink = time + 0.5; + bubble.think = bubble_bob; + bubble.touch = bubble_remove; + bubble.classname = "bubble"; + bubble.frame = 0; + bubble.cnt = 0; + setsize (bubble, '-8 -8 -8', '8 8 8'); + self.nextthink = time + random() + 0.5; + self.think = make_bubbles; +}; + +void() bubble_split = +{ +local entity bubble; + bubble = spawn(); + setmodel (bubble, "progs/s_bubble.spr"); + setorigin (bubble, self.origin); + bubble.movetype = MOVETYPE_NOCLIP; + bubble.solid = SOLID_NOT; + bubble.velocity = self.velocity; + bubble.nextthink = time + 0.5; + bubble.think = bubble_bob; + bubble.touch = bubble_remove; + bubble.classname = "bubble"; + bubble.frame = 1; + bubble.cnt = 10; + setsize (bubble, '-8 -8 -8', '8 8 8'); + self.frame = 1; + self.cnt = 10; + if (self.waterlevel != 3) + remove (self); +}; + +void() bubble_remove = +{ + if (other.classname == self.classname) + { +// dprint ("bump"); + return; + } + remove(self); +}; + +void() bubble_bob = +{ +local float rnd1, rnd2, rnd3; + + self.cnt = self.cnt + 1; + if (self.cnt == 4) + bubble_split(); + if (self.cnt == 20) + remove(self); + + rnd1 = self.velocity_x + (-10 + (random() * 20)); + rnd2 = self.velocity_y + (-10 + (random() * 20)); + rnd3 = self.velocity_z + 10 + random() * 10; + + if (rnd1 > 10) + rnd1 = 5; + if (rnd1 < -10) + rnd1 = -5; + + if (rnd2 > 10) + rnd2 = 5; + if (rnd2 < -10) + rnd2 = -5; + + if (rnd3 < 10) + rnd3 = 15; + if (rnd3 > 30) + rnd3 = 25; + + self.velocity_x = rnd1; + self.velocity_y = rnd2; + self.velocity_z = rnd3; + + self.nextthink = time + 0.5; + self.think = bubble_bob; +}; + +/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~> +~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/ + +/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8) + +Just for the debugging level. Don't use +*/ + +void() viewthing = + +{ + self.movetype = MOVETYPE_NONE; + self.solid = SOLID_NOT; + precache_model ("progs/player.mdl"); + setmodel (self, "progs/player.mdl"); +}; + + +/* +============================================================================== + +SIMPLE BMODELS + +============================================================================== +*/ + +void() func_wall_use = +{ // change to alternate textures + self.frame = 1 - self.frame; +}; + +/*QUAKED func_wall (0 .5 .8) ? +This is just a solid wall if not inhibitted +*/ +void() func_wall = +{ + self.angles = '0 0 0'; + self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything + self.solid = SOLID_BSP; + self.use = func_wall_use; + setmodel (self, self.model); +}; + + +/*QUAKED func_illusionary (0 .5 .8) ? +A simple entity that looks solid but lets you walk through it. +*/ +void() func_illusionary = + +{ + self.angles = '0 0 0'; + self.movetype = MOVETYPE_NONE; + self.solid = SOLID_NOT; + setmodel (self, self.model); + makestatic (self); +}; + +/*QUAKED func_episodegate (0 .5 .8) ? E1 E2 E3 E4 +This bmodel will appear if the episode has allready been completed, so players can't reenter it. +*/ +void() func_episodegate = + +{ + if (!(serverflags & self.spawnflags)) + return; // can still enter episode + + self.angles = '0 0 0'; + self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything + self.solid = SOLID_BSP; + self.use = func_wall_use; + setmodel (self, self.model); +}; + +/*QUAKED func_bossgate (0 .5 .8) ? +This bmodel appears unless players have all of the episode sigils. +*/ +void() func_bossgate = + +{ + if ( (serverflags & 15) == 15) + return; // all episodes completed + self.angles = '0 0 0'; + self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything + self.solid = SOLID_BSP; + self.use = func_wall_use; + setmodel (self, self.model); +}; + +//============================================================================ +/*QUAKED ambient_suck_wind (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_suck_wind = +{ + precache_sound ("ambience/suck1.wav"); + ambientsound (self.origin, "ambience/suck1.wav", 1, ATTN_STATIC); +}; + +/*QUAKED ambient_drone (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_drone = +{ + precache_sound ("ambience/drone6.wav"); + ambientsound (self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED ambient_flouro_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_flouro_buzz = +{ + precache_sound ("ambience/buzz1.wav"); + ambientsound (self.origin, "ambience/buzz1.wav", 1, ATTN_STATIC); +}; +/*QUAKED ambient_drip (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_drip = +{ + precache_sound ("ambience/drip1.wav"); + ambientsound (self.origin, "ambience/drip1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_comp_hum (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_comp_hum = +{ + precache_sound ("ambience/comp1.wav"); + ambientsound (self.origin, "ambience/comp1.wav", 1, ATTN_STATIC); +}; +/*QUAKED ambient_thunder (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_thunder = +{ + precache_sound ("ambience/thunder1.wav"); + ambientsound (self.origin, "ambience/thunder1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_light_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_light_buzz = +{ + precache_sound ("ambience/fl_hum1.wav"); + ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_swamp1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_swamp1 = +{ + precache_sound ("ambience/swamp1.wav"); + ambientsound (self.origin, "ambience/swamp1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_swamp2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_swamp2 = +{ + precache_sound ("ambience/swamp2.wav"); + ambientsound (self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC); +}; + +//============================================================================ + +void() noise_think = +{ + self.nextthink = time + 0.5; + sound (self, 1, "enforcer/enfire.wav", 1, ATTN_NORM); + sound (self, 2, "enforcer/enfstop.wav", 1, ATTN_NORM); + sound (self, 3, "enforcer/sight1.wav", 1, ATTN_NORM); + sound (self, 4, "enforcer/sight2.wav", 1, ATTN_NORM); + sound (self, 5, "enforcer/sight3.wav", 1, ATTN_NORM); + sound (self, 6, "enforcer/sight4.wav", 1, ATTN_NORM); + sound (self, 7, "enforcer/pain1.wav", 1, ATTN_NORM); +}; + +/*QUAKED misc_noisemaker (1 0.5 0) (-10 -10 -10) (10 10 10) + +For optimzation testing, starts a lot of sounds. +*/ + +void() misc_noisemaker = + +{ + precache_sound2 ("enforcer/enfire.wav"); + precache_sound2 ("enforcer/enfstop.wav"); + precache_sound2 ("enforcer/sight1.wav"); + precache_sound2 ("enforcer/sight2.wav"); + precache_sound2 ("enforcer/sight3.wav"); + precache_sound2 ("enforcer/sight4.wav"); + precache_sound2 ("enforcer/pain1.wav"); + precache_sound2 ("enforcer/pain2.wav"); + precache_sound2 ("enforcer/death1.wav"); + precache_sound2 ("enforcer/idle1.wav"); + + self.nextthink = time + 0.1 + random(); + self.think = noise_think; +}; + +void() misc_model = +{ + precache_model( self.model ); + setmodel( self, self.model ); + setorigin( self, self.origin ); + + self.movetype = MOVETYPE_NONE; + self.solid = SOLID_BBOX; + setsize(self, '-8 -8 -8', '8 8 8'); +}; + +/* +============================== + +These are The props for Mapping. They require A special Size, So they must be An actual Function. + +============================== +*/ + +void() misc_deadtree = +{ +self.solid = SOLID_BBOX; +self.movetype = MOVETYPE_NONE; +self.classname = "deadtree"; +precache_model ("progs/deadtree.mdl"); +setmodel (self, "progs/deadtree.mdl"); +setsize (self, '-18 -18 0', '18 18 100'); +}; + +void() misc_deadtree2 = +{ +self.solid = SOLID_BBOX; +self.movetype = MOVETYPE_NONE; +self.classname = "deadtree2"; +precache_model ("progs/deadtree2.mdl"); +setmodel (self, "progs/deadtree2.mdl"); +setsize (self, '-18 -18 0', '18 18 100'); +}; +void() misc_boulder = +{ +self.solid = SOLID_BBOX; +self.movetype = MOVETYPE_NONE; +self.classname = "Boulder"; +precache_model ("progs/boulder.mdl"); +setmodel (self, "progs/boulder.mdl"); +setsize (self, '-30 -30 0', '30 30 34'); +}; +void() misc_boulder2 = +{ +self.solid = SOLID_BBOX; +self.movetype = MOVETYPE_NONE; +self.classname = "Boulder"; +precache_model ("progs/boulder2.mdl"); +setmodel (self, "progs/boulder2.mdl"); +setsize (self, '-30 -30 0', '30 30 34'); +} \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/models.qc b/r17/Revamped src/Revamped QC/Primeqc4/models.qc new file mode 100755 index 00000000..70e273c4 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/models.qc @@ -0,0 +1,585 @@ + +/* +=============================================================================== + +WORLD WEAPONS + +=============================================================================== +*/ + +$modelname g_shot +$cd id1/models/g_shot +$origin 0 0 -24 +$flags 8 // client side rotate +$base base +$skin skin +$frame shot1 + + +$modelname g_nail +$cd id1/models/g_nail +$flags 8 // client side rotate +$origin 0 0 -24 +$base base +$skin skin +$frame shot1 + + +$modelname g_nail2 +$cd id1/models/g_nail2 +$flags 8 // client side rotate +$origin 0 0 -24 +$base base +$skin skin +$frame shot2 + + +$modelname g_rock +$cd id1/models/g_rock +$flags 8 // client side rotate +$origin 0 0 -24 +$base base +$skin skin +$frame shot1 + + +$modelname g_rock2 +$cd id1/models/g_rock2 +$flags 8 // client side rotate +$origin 0 0 -24 +$base base +$skin skin +$frame shot1 + +$modelname g_light +$cd id1/models/g_light +$flags 8 // client side rotate +$origin 0 0 -24 +$base base +$skin skin +$frame shot1 + +/* +=============================================================================== + +VIEW WEAPONS + +=============================================================================== +*/ + +$modelname v_axe +$cd id1/models/v_axe +$origin 0 5 54 +$base base +$skin skin +$frame frame1 frame2 frame3 frame4 frame5 frame6 frame7 frame8 frame9 + + +$modelname v_shot +$cd id1/models/v_shot +$origin 0 0 54 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 + + +$modelname v_shot2 +$cd id1/models/v_shot2 +$origin 0 0 56 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 + + +$modelname v_rock2 +$cd id1/models/v_rock2 +$origin 0 0 54 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 shot6 shot6 + + +$modelname v_rock +$cd id1/models/v_rock +$origin 0 0 54 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 + + +$modelname v_nail2 +$cd id1/models/v_nail2 +$origin 0 0 54 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 shot8 shot9 + + +$modelname v_nail +$cd id1/models/v_nail +$origin 0 0 54 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 shot8 shot9 + +$modelname v_light +$cd id1/models/v_light +$origin 0 0 54 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 + + +/* +=============================================================================== + +ITEMS + +=============================================================================== +*/ + +$modelname w_g_key +$cd id1/models/w_g_key +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname w_s_key +$cd id1/models/w_s_key +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname m_g_key +$cd id1/models/m_g_key +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname m_s_key +$cd id1/models/m_s_key +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname b_g_key +$cd id1/models/b_g_key +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname b_s_key +$cd id1/models/b_s_key +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + + +$modelname quaddama +$cd id1/models/quaddama +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname invisibl +$cd id1/models/invisibl +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname invulner +$flags 8 // client side rotate +$cd id1/models/invulner +$base base +$skin skin +$frame frame1 + +//modelname jetpack +//cd id1/models/jetpack +//flags 8 // client side rotate +//base base +//skin skin +//frame frame1 + +$modelname cube +$cd id1/models/cube +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname suit +$cd id1/models/suit +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname boots +$cd id1/models/boots +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname end1 +$cd id1/models/end1 +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname end2 +$cd id1/models/end2 +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname end3 +$cd id1/models/end3 +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname end4 +$cd id1/models/end4 +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + + +/* +=============================================================================== + +GIBS + +=============================================================================== +*/ + +$modelname gib1 +$cd id1/models/gib1 +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + + +// torso +$modelname gib2 +$cd id1/models/gib2 +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname gib3 +$cd id1/models/gib3 +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + + +// heads + +$modelname h_player +$cd id1/models/h_player +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_dog +$cd id1/models/h_dog +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_mega +$cd id1/models/h_mega +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_guard +$cd id1/models/h_guard +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_wizard +$cd id1/models/h_wizard +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_knight +$cd id1/models/h_knight +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_hellkn +$cd id1/models/h_hellkn +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_zombie +$cd id1/models/h_zombie +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_shams +$cd id1/models/h_shams +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_shal +$cd id1/models/h_shal +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_ogre +$cd id1/models/h_ogre +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_demon +$cd id1/models/h_demon +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +/* +=============================================================================== + +MISC + +=============================================================================== +*/ + +$modelname armor +$cd id1/models/armor +$flags 8 // client side rotate +$origin 0 0 -8 +$base base +$skin skin +$skin skin2 +$skin skin3 +$frame armor + +$modelname s_light // shambler lightning ready +$cd id1/models/s_light +$origin 0 0 24 +$base base +$skin skin +$frame frame1 frame2 frame3 + +$modelname bolt3 // lightning towar bolts +$cd id1/models/bolt2 +$origin 0 0 0 +$base base +$scale 4 +$skin skin +$frame light + +$modelname bolt2 +$cd id1/models/bolt2 +$origin 0 0 0 +$base base +$skin skin +$frame light + +$modelname bolt +$cd id1/models/bolt +$origin 0 0 0 +$base light +$skin light +$frame light + +$modelname laser +$cd id1/models/laser +$base base +$skin skin +$scale 2 +$frame frame1 + +$modelname flame // with torch +$cd id1/models/flame +$origin 0 0 12 +$base base +$skin skin +$framegroupstart +$frame flame1 0.1 +$frame flame2 0.1 +$frame flame3 0.1 +$frame flame4 0.1 +$frame flame5 0.1 +$frame flame6 0.1 +$framegroupend + +$modelname flame2 // standing flame, no torch +$cd id1/models/flame2 +$origin 0 0 12 +$base base +$skin skin +$framegroupstart +$frame flame1 0.1 +$frame flame2 0.1 +$frame flame3 0.1 +$frame flame4 0.1 +$frame flame5 0.1 +$frame flame6 0.1 +$framegroupend +$framegroupstart +$frame flameb1 +$frame flameb2 +$frame flameb3 +$frame flameb4 +$frame flameb5 +$frame flameb6 +$frame flameb7 +$frame flameb8 +$frame flameb9 +$frame flameb10 +$frame flameb11 +$framegroupend + +$modelname zom_gib +$cd id1/models/zom_gib +$flags 32 // EF_ZOMGIB +$base base +$skin skin +$frame frame1 + +$modelname eyes +$cd id1/models/eyes +$origin 0 0 -24 +$base base +$skin skin +$frame frame1 + +$modelname spike +$cd id1/models/spike +$origin 0 0 0 +$base spike +$skin skin +$frame spike + +$modelname s_spike +$cd id1/models/s_spike +$origin 0 0 0 +$base spike +$skin skin +$frame spike + +$modelname v_spike +$cd id1/models/v_spike +$flags 128 // EF_TRACER3 +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname w_spike +$cd id1/models/w_spike +$flags 16 // EF_TRACER +$origin 0 0 0 +$base base +$skin skin +$framegroupstart +$frame frame1 0.1 +$frame frame2 0.1 +$frame frame3 0.1 +$frame frame4 0.1 +$framegroupend + +$modelname k_spike +$cd id1/models/k_spike +$flags 64 // EF_TRACER2 +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname backpack +$cd id1/models/backpack +$flags 8 // EF_ROTATE +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname grenade +$cd id1/models/grenade2 +$flags 2 // EF_GRENADE +$origin 0 0 0 +$base base +$skin skin +$frame grenade + +$modelname missile +$cd id1/models/missile +$flags 1 // EF_ROCKET +$origin 0 0 0 +$base base +$skin skin +$frame missile + +$modelname lavaball +$cd id1/models/lavaball +$flags 1 // EF_ROCKET +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname teleport +$cd id1/models/teleport +$origin 0 0 24 +$base base +$skin skin +$frame frame1 + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/monsters.qc b/r17/Revamped src/Revamped QC/Primeqc4/monsters.qc new file mode 100755 index 00000000..0140dac1 Binary files /dev/null and b/r17/Revamped src/Revamped QC/Primeqc4/monsters.qc differ diff --git a/r17/Revamped src/Revamped QC/Primeqc4/ogre.qc b/r17/Revamped src/Revamped QC/Primeqc4/ogre.qc new file mode 100755 index 00000000..76993c18 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/ogre.qc @@ -0,0 +1,452 @@ +/* +============================================================================== + +OGRE + +============================================================================== +*/ + +$cd id1/models/ogre_c +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 +$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7 +$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 +$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14 + +$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame painb1 painb2 painb3 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10 +$frame paind11 paind12 paind13 paind14 paind15 paind16 + +$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10 +$frame paine11 paine12 paine13 paine14 paine15 + +$frame death1 death2 death3 death4 death5 death6 +$frame death7 death8 death9 death10 death11 death12 +$frame death13 death14 + +$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6 +$frame bdeath7 bdeath8 bdeath9 bdeath10 + +$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11 + +//============================================================================= + + +void() OgreGrenadeExplode = +{ + T_RadiusDamage (self, self.owner, 40, world); + sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM); + + 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); + + self.velocity = '0 0 0'; + self.touch = SUB_Null; + setmodel (self, "progs/s_explod.spr"); + self.solid = SOLID_NOT; + s_explode1 (); +}; + +void() OgreGrenadeTouch = +{ + if (other == self.owner) + return; // don't explode on owner + if (other.takedamage == DAMAGE_AIM) + { + OgreGrenadeExplode(); + return; + } + sound (self, CHAN_VOICE, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound + if (self.velocity == '0 0 0') + self.avelocity = '0 0 0'; +}; + +/* +================ +OgreFireGrenade +================ +*/ +void() OgreFireGrenade = +{ + local entity missile; + + self.effects = self.effects | EF_MUZZLEFLASH; + + sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM); + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_BOUNCE; + missile.solid = SOLID_BBOX; + +// set missile speed + + makevectors (self.angles); + + missile.velocity = normalize(self.enemy.origin - self.origin); + missile.velocity = missile.velocity * 600; + missile.velocity_z = 200; + + missile.avelocity = '300 300 300'; + + missile.angles = vectoangles(missile.velocity); + + missile.touch = OgreGrenadeTouch; + +// set missile duration + missile.nextthink = time + 2.5; + missile.think = OgreGrenadeExplode; + + setmodel (missile, "progs/grenade.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin); +}; + + +//============================================================================= + +/* +================ +chainsaw + +FIXME +================ +*/ +void(float side) chainsaw = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + if (!CanDamage (self.enemy, self)) + return; + + ai_charge(10); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + ldmg = (random() + random() + random()) * 4; + T_Damage (self.enemy, self, self, ldmg); + +}; + + +void() ogre_stand1 =[ $stand1, ogre_stand2 ] {ai_stand();}; +void() ogre_stand2 =[ $stand2, ogre_stand3 ] {ai_stand();}; +void() ogre_stand3 =[ $stand3, ogre_stand4 ] {ai_stand();}; +void() ogre_stand4 =[ $stand4, ogre_stand5 ] {ai_stand();}; +void() ogre_stand5 =[ $stand5, ogre_stand6 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE); +ai_stand(); +}; +void() ogre_stand6 =[ $stand6, ogre_stand7 ] {ai_stand();}; +void() ogre_stand7 =[ $stand7, ogre_stand8 ] {ai_stand();}; +void() ogre_stand8 =[ $stand8, ogre_stand9 ] {ai_stand();}; +void() ogre_stand9 =[ $stand9, ogre_stand1 ] {ai_stand();}; + +void() ogre_walk1 =[ $walk1, ogre_walk2 ] {ai_walk(3);}; +void() ogre_walk2 =[ $walk2, ogre_walk3 ] {ai_walk(2);}; +void() ogre_walk3 =[ $walk3, ogre_walk4 ] { +ai_walk(2); +if (random() < 0.2) + sound (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE); +}; +void() ogre_walk4 =[ $walk4, ogre_walk5 ] {ai_walk(2);}; +void() ogre_walk5 =[ $walk5, ogre_walk6 ] {ai_walk(2);}; +void() ogre_walk6 =[ $walk6, ogre_walk7 ] { +ai_walk(5); +if (random() < 0.1) + sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE); +}; +void() ogre_walk7 =[ $walk7, ogre_walk8 ] {ai_walk(3);}; +void() ogre_walk8 =[ $walk8, ogre_walk9 ] {ai_walk(2);}; +void() ogre_walk9 =[ $walk9, ogre_walk10 ] {ai_walk(3);}; +void() ogre_walk10 =[ $walk10, ogre_walk11 ] {ai_walk(1);}; +void() ogre_walk11 =[ $walk11, ogre_walk12 ] {ai_walk(2);}; +void() ogre_walk12 =[ $walk12, ogre_walk13 ] {ai_walk(3);}; +void() ogre_walk13 =[ $walk13, ogre_walk14 ] {ai_walk(3);}; +void() ogre_walk14 =[ $walk14, ogre_walk15 ] {ai_walk(3);}; +void() ogre_walk15 =[ $walk15, ogre_walk16 ] {ai_walk(3);}; +void() ogre_walk16 =[ $walk16, ogre_walk1 ] {ai_walk(4);}; + +void() ogre_run1 =[ $run1, ogre_run2 ] {ai_run(9); +if (random() < 0.2) + sound (self, CHAN_VOICE, "ogre/ogidle2.wav", 1, ATTN_IDLE); +}; +void() ogre_run2 =[ $run2, ogre_run3 ] {ai_run(12);}; +void() ogre_run3 =[ $run3, ogre_run4 ] {ai_run(8);}; +void() ogre_run4 =[ $run4, ogre_run5 ] {ai_run(22);}; +void() ogre_run5 =[ $run5, ogre_run6 ] {ai_run(16);}; +void() ogre_run6 =[ $run6, ogre_run7 ] {ai_run(4);}; +void() ogre_run7 =[ $run7, ogre_run8 ] {ai_run(13);}; +void() ogre_run8 =[ $run8, ogre_run1 ] {ai_run(24);}; + +void() ogre_swing1 =[ $swing1, ogre_swing2 ] {ai_charge(11); +sound (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM); +}; +void() ogre_swing2 =[ $swing2, ogre_swing3 ] {ai_charge(1);}; +void() ogre_swing3 =[ $swing3, ogre_swing4 ] {ai_charge(4);}; +void() ogre_swing4 =[ $swing4, ogre_swing5 ] {ai_charge(13);}; +void() ogre_swing5 =[ $swing5, ogre_swing6 ] {ai_charge(9); chainsaw(0);self.angles_y = self.angles_y + random()*25;}; +void() ogre_swing6 =[ $swing6, ogre_swing7 ] {chainsaw(200);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing7 =[ $swing7, ogre_swing8 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing8 =[ $swing8, ogre_swing9 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing9 =[ $swing9, ogre_swing10 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing10 =[ $swing10, ogre_swing11 ] {chainsaw(-200);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing11 =[ $swing11, ogre_swing12 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing12 =[ $swing12, ogre_swing13 ] {ai_charge(3);}; +void() ogre_swing13 =[ $swing13, ogre_swing14 ] {ai_charge(8);}; +void() ogre_swing14 =[ $swing14, ogre_run1 ] {ai_charge(9);}; + +void() ogre_smash1 =[ $smash1, ogre_smash2 ] {ai_charge(6); +sound (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM); +}; +void() ogre_smash2 =[ $smash2, ogre_smash3 ] {ai_charge(0);}; +void() ogre_smash3 =[ $smash3, ogre_smash4 ] {ai_charge(0);}; +void() ogre_smash4 =[ $smash4, ogre_smash5 ] {ai_charge(1);}; +void() ogre_smash5 =[ $smash5, ogre_smash6 ] {ai_charge(4);}; +void() ogre_smash6 =[ $smash6, ogre_smash7 ] {ai_charge(4); chainsaw(0);}; +void() ogre_smash7 =[ $smash7, ogre_smash8 ] {ai_charge(4); chainsaw(0);}; +void() ogre_smash8 =[ $smash8, ogre_smash9 ] {ai_charge(10); chainsaw(0);}; +void() ogre_smash9 =[ $smash9, ogre_smash10 ] {ai_charge(13); chainsaw(0);}; +void() ogre_smash10 =[ $smash10, ogre_smash11 ] {chainsaw(1);}; +void() ogre_smash11 =[ $smash11, ogre_smash12 ] {ai_charge(2); chainsaw(0); +self.nextthink = self.nextthink + random()*0.2;}; // slight variation +void() ogre_smash12 =[ $smash12, ogre_smash13 ] {ai_charge(0);}; +void() ogre_smash13 =[ $smash13, ogre_smash14 ] {ai_charge(4);}; +void() ogre_smash14 =[ $smash14, ogre_run1 ] {ai_charge(12);}; + +void() ogre_nail1 =[ $shoot1, ogre_nail2 ] {ai_face();}; +void() ogre_nail2 =[ $shoot2, ogre_nail3 ] {ai_face();}; +void() ogre_nail3 =[ $shoot2, ogre_nail4 ] {ai_face();}; +void() ogre_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();OgreFireGrenade();}; +void() ogre_nail5 =[ $shoot4, ogre_nail6 ] {ai_face();}; +void() ogre_nail6 =[ $shoot5, ogre_nail7 ] {ai_face();}; +void() ogre_nail7 =[ $shoot6, ogre_run1 ] {ai_face();}; + +void() ogre_pain1 =[ $pain1, ogre_pain2 ] {}; +void() ogre_pain2 =[ $pain2, ogre_pain3 ] {}; +void() ogre_pain3 =[ $pain3, ogre_pain4 ] {}; +void() ogre_pain4 =[ $pain4, ogre_pain5 ] {}; +void() ogre_pain5 =[ $pain5, ogre_run1 ] {}; + + +void() ogre_painb1 =[ $painb1, ogre_painb2 ] {}; +void() ogre_painb2 =[ $painb2, ogre_painb3 ] {}; +void() ogre_painb3 =[ $painb3, ogre_run1 ] {}; + + +void() ogre_painc1 =[ $painc1, ogre_painc2 ] {}; +void() ogre_painc2 =[ $painc2, ogre_painc3 ] {}; +void() ogre_painc3 =[ $painc3, ogre_painc4 ] {}; +void() ogre_painc4 =[ $painc4, ogre_painc5 ] {}; +void() ogre_painc5 =[ $painc5, ogre_painc6 ] {}; +void() ogre_painc6 =[ $painc6, ogre_run1 ] {}; + + +void() ogre_paind1 =[ $paind1, ogre_paind2 ] {}; +void() ogre_paind2 =[ $paind2, ogre_paind3 ] {ai_pain(10);}; +void() ogre_paind3 =[ $paind3, ogre_paind4 ] {ai_pain(9);}; +void() ogre_paind4 =[ $paind4, ogre_paind5 ] {ai_pain(4);}; +void() ogre_paind5 =[ $paind5, ogre_paind6 ] {}; +void() ogre_paind6 =[ $paind6, ogre_paind7 ] {}; +void() ogre_paind7 =[ $paind7, ogre_paind8 ] {}; +void() ogre_paind8 =[ $paind8, ogre_paind9 ] {}; +void() ogre_paind9 =[ $paind9, ogre_paind10 ] {}; +void() ogre_paind10=[ $paind10, ogre_paind11 ] {}; +void() ogre_paind11=[ $paind11, ogre_paind12 ] {}; +void() ogre_paind12=[ $paind12, ogre_paind13 ] {}; +void() ogre_paind13=[ $paind13, ogre_paind14 ] {}; +void() ogre_paind14=[ $paind14, ogre_paind15 ] {}; +void() ogre_paind15=[ $paind15, ogre_paind16 ] {}; +void() ogre_paind16=[ $paind16, ogre_run1 ] {}; + +void() ogre_paine1 =[ $paine1, ogre_paine2 ] {}; +void() ogre_paine2 =[ $paine2, ogre_paine3 ] {ai_pain(10);}; +void() ogre_paine3 =[ $paine3, ogre_paine4 ] {ai_pain(9);}; +void() ogre_paine4 =[ $paine4, ogre_paine5 ] {ai_pain(4);}; +void() ogre_paine5 =[ $paine5, ogre_paine6 ] {}; +void() ogre_paine6 =[ $paine6, ogre_paine7 ] {}; +void() ogre_paine7 =[ $paine7, ogre_paine8 ] {}; +void() ogre_paine8 =[ $paine8, ogre_paine9 ] {}; +void() ogre_paine9 =[ $paine9, ogre_paine10 ] {}; +void() ogre_paine10=[ $paine10, ogre_paine11 ] {}; +void() ogre_paine11=[ $paine11, ogre_paine12 ] {}; +void() ogre_paine12=[ $paine12, ogre_paine13 ] {}; +void() ogre_paine13=[ $paine13, ogre_paine14 ] {}; +void() ogre_paine14=[ $paine14, ogre_paine15 ] {}; +void() ogre_paine15=[ $paine15, ogre_run1 ] {}; + + +void(entity attacker, float damage) ogre_pain = +{ + local float r; + +// don't make multiple pain sounds right after each other + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "ogre/ogpain1.wav", 1, ATTN_NORM); + + r = random(); + + if (r < 0.25) + { + ogre_pain1 (); + self.pain_finished = time + 1; + } + else if (r < 0.5) + { + ogre_painb1 (); + self.pain_finished = time + 1; + } + else if (r < 0.75) + { + ogre_painc1 (); + self.pain_finished = time + 1; + } + else if (r < 0.88) + { + ogre_paind1 (); + self.pain_finished = time + 2; + } + else + { + ogre_paine1 (); + self.pain_finished = time + 2; + } +}; + +void() ogre_die1 =[ $death1, ogre_die2 ] {}; +void() ogre_die2 =[ $death2, ogre_die3 ] {}; +void() ogre_die3 =[ $death3, ogre_die4 ] +{self.solid = SOLID_NOT; +self.ammo_rockets = 2;DropBackpack();}; +void() ogre_die4 =[ $death4, ogre_die5 ] {}; +void() ogre_die5 =[ $death5, ogre_die6 ] {}; +void() ogre_die6 =[ $death6, ogre_die7 ] {}; +void() ogre_die7 =[ $death7, ogre_die8 ] {}; +void() ogre_die8 =[ $death8, ogre_die9 ] {}; +void() ogre_die9 =[ $death9, ogre_die10 ] {}; +void() ogre_die10 =[ $death10, ogre_die11 ] {}; +void() ogre_die11 =[ $death11, ogre_die12 ] {}; +void() ogre_die12 =[ $death12, ogre_die13 ] {}; +void() ogre_die13 =[ $death13, ogre_die14 ] {}; +void() ogre_die14 =[ $death14, ogre_die14 ] {}; + +void() ogre_bdie1 =[ $bdeath1, ogre_bdie2 ] {}; +void() ogre_bdie2 =[ $bdeath2, ogre_bdie3 ] {ai_forward(5);}; +void() ogre_bdie3 =[ $bdeath3, ogre_bdie4 ] +{self.solid = SOLID_NOT; +self.ammo_rockets = 2;DropBackpack();}; +void() ogre_bdie4 =[ $bdeath4, ogre_bdie5 ] {ai_forward(1);}; +void() ogre_bdie5 =[ $bdeath5, ogre_bdie6 ] {ai_forward(3);}; +void() ogre_bdie6 =[ $bdeath6, ogre_bdie7 ] {ai_forward(7);}; +void() ogre_bdie7 =[ $bdeath7, ogre_bdie8 ] {ai_forward(25);}; +void() ogre_bdie8 =[ $bdeath8, ogre_bdie9 ] {}; +void() ogre_bdie9 =[ $bdeath9, ogre_bdie10 ] {}; +void() ogre_bdie10 =[ $bdeath10, ogre_bdie10 ] {}; + +void() ogre_die = +{ +// check for gib + if (self.health < -80) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_ogre.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + + sound (self, CHAN_VOICE, "ogre/ogdth.wav", 1, ATTN_NORM); + + if (random() < 0.5) + ogre_die1 (); + else + ogre_bdie1 (); +}; + +void() ogre_melee = +{ + if (random() > 0.5) + ogre_smash1 (); + else + ogre_swing1 (); +}; + + +/*QUAKED monster_ogre (1 0 0) (-32 -32 -24) (32 32 64) Ambush + +*/ +void() monster_ogre = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/ogre.mdl"); + precache_model ("progs/h_ogre.mdl"); + precache_model ("progs/grenade.mdl"); + + precache_sound ("ogre/ogdrag.wav"); + precache_sound ("ogre/ogdth.wav"); + precache_sound ("ogre/ogidle.wav"); + precache_sound ("ogre/ogidle2.wav"); + precache_sound ("ogre/ogpain1.wav"); + precache_sound ("ogre/ogsawatk.wav"); + precache_sound ("ogre/ogwake.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/ogre.mdl"); + + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 200; + + self.th_stand = ogre_stand1; + self.th_walk = ogre_walk1; + self.th_run = ogre_run1; + self.th_die = ogre_die; + self.th_melee = ogre_melee; + self.th_missile = ogre_nail1; + self.th_pain = ogre_pain; + + walkmonster_start(); +}; + +void() monster_ogre_marksman = +{ + monster_ogre (); +}; + + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/oldone.qc b/r17/Revamped src/Revamped QC/Primeqc4/oldone.qc new file mode 100755 index 00000000..103d6fb2 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/oldone.qc @@ -0,0 +1,283 @@ +/* +============================================================================== + +OLD ONE + +============================================================================== +*/ +$cd id1/models/old_one +$origin 0 0 24 +$base base +$skin skin +$scale 1 + +void() finale_1; +void() finale_2; +void() finale_3; +void() finale_4; + + +entity shub; + +$frame old1 old2 old3 old4 old5 old6 old7 old8 old9 +$frame old10 old11 old12 old13 old14 old15 old16 old17 old18 old19 +$frame old20 old21 old22 old23 old24 old25 old26 old27 old28 old29 +$frame old30 old31 old32 old33 old34 old35 old36 old37 old38 old39 +$frame old40 old41 old42 old43 old44 old45 old46 + +$frame shake1 shake2 shake3 shake4 shake5 shake6 shake7 shake8 +$frame shake9 shake10 shake11 shake12 shake12 shake13 shake14 +$frame shake15 shake16 shake17 shake18 shake19 shake20 + +//void() old_stand =[ $old1, old_stand ] {}; + +void() old_idle1 =[ $old1, old_idle2 ] {}; +void() old_idle2 =[ $old2, old_idle3 ] {}; +void() old_idle3 =[ $old3, old_idle4 ] {}; +void() old_idle4 =[ $old4, old_idle5 ] {}; +void() old_idle5 =[ $old5, old_idle6 ] {}; +void() old_idle6 =[ $old6, old_idle7 ] {}; +void() old_idle7 =[ $old7, old_idle8 ] {}; +void() old_idle8 =[ $old8, old_idle9 ] {}; +void() old_idle9 =[ $old9, old_idle10 ] {}; +void() old_idle10 =[ $old10, old_idle11 ] {}; +void() old_idle11 =[ $old11, old_idle12 ] {}; +void() old_idle12 =[ $old12, old_idle13 ] {}; +void() old_idle13 =[ $old13, old_idle14 ] {}; +void() old_idle14 =[ $old14, old_idle15 ] {}; +void() old_idle15 =[ $old15, old_idle16 ] {}; +void() old_idle16 =[ $old16, old_idle17 ] {}; +void() old_idle17 =[ $old17, old_idle18 ] {}; +void() old_idle18 =[ $old18, old_idle19 ] {}; +void() old_idle19 =[ $old19, old_idle20 ] {}; +void() old_idle20 =[ $old20, old_idle21 ] {}; +void() old_idle21 =[ $old21, old_idle22 ] {}; +void() old_idle22 =[ $old22, old_idle23 ] {}; +void() old_idle23 =[ $old23, old_idle24 ] {}; +void() old_idle24 =[ $old24, old_idle25 ] {}; +void() old_idle25 =[ $old25, old_idle26 ] {}; +void() old_idle26 =[ $old26, old_idle27 ] {}; +void() old_idle27 =[ $old27, old_idle28 ] {}; +void() old_idle28 =[ $old28, old_idle29 ] {}; +void() old_idle29 =[ $old29, old_idle30 ] {}; +void() old_idle30 =[ $old30, old_idle31 ] {}; +void() old_idle31 =[ $old31, old_idle32 ] {}; +void() old_idle32 =[ $old32, old_idle33 ] {}; +void() old_idle33 =[ $old33, old_idle34 ] {}; +void() old_idle34 =[ $old34, old_idle35 ] {}; +void() old_idle35 =[ $old35, old_idle36 ] {}; +void() old_idle36 =[ $old36, old_idle37 ] {}; +void() old_idle37 =[ $old37, old_idle38 ] {}; +void() old_idle38 =[ $old38, old_idle39 ] {}; +void() old_idle39 =[ $old39, old_idle40 ] {}; +void() old_idle40 =[ $old40, old_idle41 ] {}; +void() old_idle41 =[ $old41, old_idle42 ] {}; +void() old_idle42 =[ $old42, old_idle43 ] {}; +void() old_idle43 =[ $old43, old_idle44 ] {}; +void() old_idle44 =[ $old44, old_idle45 ] {}; +void() old_idle45 =[ $old45, old_idle46 ] {}; +void() old_idle46 =[ $old46, old_idle1 ] {}; + + +void() old_thrash1 =[ $shake1, old_thrash2 ] {lightstyle(0, "m");}; +void() old_thrash2 =[ $shake2, old_thrash3 ] {lightstyle(0, "k");}; +void() old_thrash3 =[ $shake3, old_thrash4 ] {lightstyle(0, "k");}; +void() old_thrash4 =[ $shake4, old_thrash5 ] {lightstyle(0, "i");}; +void() old_thrash5 =[ $shake5, old_thrash6 ] {lightstyle(0, "g");}; +void() old_thrash6 =[ $shake6, old_thrash7 ] {lightstyle(0, "e");}; +void() old_thrash7 =[ $shake7, old_thrash8 ] {lightstyle(0, "c");}; +void() old_thrash8 =[ $shake8, old_thrash9 ] {lightstyle(0, "a");}; +void() old_thrash9 =[ $shake9, old_thrash10 ] {lightstyle(0, "c");}; +void() old_thrash10 =[ $shake10, old_thrash11 ] {lightstyle(0, "e");}; +void() old_thrash11 =[ $shake11, old_thrash12 ] {lightstyle(0, "g");}; +void() old_thrash12 =[ $shake12, old_thrash13 ] {lightstyle(0, "i");}; +void() old_thrash13 =[ $shake13, old_thrash14 ] {lightstyle(0, "k");}; +void() old_thrash14 =[ $shake14, old_thrash15 ] {lightstyle(0, "m");}; +void() old_thrash15 =[ $shake15, old_thrash16 ] {lightstyle(0, "m"); +self.cnt = self.cnt + 1; +if (self.cnt != 3) + self.think = old_thrash1; +}; +void() old_thrash16 =[ $shake16, old_thrash17 ] {lightstyle(0, "g");}; +void() old_thrash17 =[ $shake17, old_thrash18 ] {lightstyle(0, "c");}; +void() old_thrash18 =[ $shake18, old_thrash19 ] {lightstyle(0, "b");}; +void() old_thrash19 =[ $shake19, old_thrash20 ] {lightstyle(0, "a");}; +void() old_thrash20 =[ $shake20, old_thrash20 ] {finale_4();}; + +//============================================================================ + +void() finale_1 = +{ + local entity pos, pl; + local entity timer; + + intermission_exittime = time + 10000000; // never allow exit + intermission_running = 1; + + // find the intermission spot + pos = find (world, classname, "info_intermission"); + if (!pos) + error ("no info_intermission"); + pl = find (world, classname, "misc_teleporttrain"); + if (!pl) + error ("no teleporttrain"); + remove (pl); + + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, ""); + + pl = find (world, classname, "player"); + while (pl != world) + { + pl.view_ofs = '0 0 0'; + pl.angles = other.v_angle = pos.mangle; + pl.fixangle = TRUE; // turn this way immediately + pl.map = self.map; + pl.nextthink = time + 0.5; + pl.takedamage = DAMAGE_NO; + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NONE; + pl.modelindex = 0; + setorigin (pl, pos.origin); + pl = find (pl, classname, "player"); + } + + // make fake versions of all players as standins, and move the real + // players to the intermission spot + + // wait for 1 second + timer = spawn(); + timer.nextthink = time + 1; + timer.think = finale_2; +}; + +void() finale_2 = +{ + local vector o; + + // start a teleport splash inside shub + + o = shub.origin - '0 100 0'; + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_TELEPORT); + WriteCoord (MSG_BROADCAST, o_x); + WriteCoord (MSG_BROADCAST, o_y); + WriteCoord (MSG_BROADCAST, o_z); + + sound (shub, CHAN_VOICE, "misc/r_tele1.wav", 1, ATTN_NORM); + + self.nextthink = time + 2; + self.think = finale_3; +}; + +void() finale_3 = +{ + // start shub thrashing wildly + shub.think = old_thrash1; + sound (shub, CHAN_VOICE, "boss2/death.wav", 1, ATTN_NORM); + lightstyle(0, "abcdefghijklmlkjihgfedcb"); +}; + +void() finale_4 = +{ + // throw tons of meat chunks + local vector oldo; + local float x, y, z; + local float r; + local entity n; + + sound (self, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NORM); + + oldo = self.origin; + + z = 16; + while (z <= 144) + { + x = -64; + while (x <= 64) + { + y = -64; + while (y <= 64) + { + self.origin_x = oldo_x + x; + self.origin_y = oldo_y + y; + self.origin_z = oldo_z + z; + + r = random(); + if (r < 0.3) + ThrowGib ("progs/gib1.mdl", -999); + else if (r < 0.6) + ThrowGib ("progs/gib2.mdl", -999); + else + ThrowGib ("progs/gib3.mdl", -999); + y = y + 32; + } + x = x + 32; + } + z = z + 96; + } + // start the end text + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "Congratulations and well done! You have\nbeaten the hideous Shub-Niggurath, and\nher hundreds of ugly changelings and\nmonsters. You have proven that your\nskill and your cunning are greater than\nall the powers of Quake. You are the\nmaster now. Id Software salutes you."); + +// put a player model down + n = spawn(); + setmodel (n, "progs/player.mdl"); + oldo = oldo - '32 264 0'; + setorigin (n, oldo); + n.angles = '0 290 0'; + n.frame = 1; + + remove (self); + +// switch cd track + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 3); + WriteByte (MSG_ALL, 3); + lightstyle(0, "m"); +}; + +//============================================================================ + +void () nopain = +{ + self.health = 40000; +}; + +//============================================================================ + + +/*QUAKED monster_oldone (1 0 0) (-16 -16 -24) (16 16 32) +*/ +void() monster_oldone = +{ + if (deathmatch) + { + remove(self); + return; + } + + precache_model2 ("progs/oldone.mdl"); + + precache_sound2 ("boss2/death.wav"); + precache_sound2 ("boss2/idle.wav"); + precache_sound2 ("boss2/sight.wav"); + precache_sound2 ("boss2/pop2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/oldone.mdl"); + setsize (self, '-160 -128 -24', '160 128 256'); + + self.health = 40000; // kill by telefrag + self.think = old_idle1; + self.nextthink = time + 0.1; + self.takedamage = DAMAGE_YES; + self.th_pain = nopain; + self.th_die = finale_1; + shub = self; + + total_monsters = total_monsters + 1; +}; + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/plats.qc b/r17/Revamped src/Revamped QC/Primeqc4/plats.qc new file mode 100755 index 00000000..ffd7ae2c --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/plats.qc @@ -0,0 +1,362 @@ + + +void() plat_center_touch; +void() plat_outside_touch; +void() plat_trigger_use; +void() plat_go_up; +void() plat_go_down; +void() plat_crush; +float PLAT_LOW_TRIGGER = 1; + +void() plat_spawn_inside_trigger = +{ + local entity trigger; + local vector tmin, tmax; + +// +// middle trigger +// + trigger = spawn(); + trigger.touch = plat_center_touch; + trigger.movetype = MOVETYPE_NONE; + trigger.solid = SOLID_TRIGGER; + trigger.enemy = self; + + tmin = self.mins + '25 25 0'; + tmax = self.maxs - '25 25 -8'; + tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8); + if (self.spawnflags & PLAT_LOW_TRIGGER) + tmax_z = tmin_z + 8; + + if (self.size_x <= 50) + { + tmin_x = (self.mins_x + self.maxs_x) / 2; + tmax_x = tmin_x + 1; + } + if (self.size_y <= 50) + { + tmin_y = (self.mins_y + self.maxs_y) / 2; + tmax_y = tmin_y + 1; + } + + setsize (trigger, tmin, tmax); +}; + +void() plat_hit_top = +{ + sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_TOP; + self.think = plat_go_down; + self.nextthink = self.ltime + 3; +}; + +void() plat_hit_bottom = +{ + sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_BOTTOM; +}; + +void() plat_go_down = +{ + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + self.state = STATE_DOWN; + SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom); +}; + +void() plat_go_up = +{ + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + self.state = STATE_UP; + SUB_CalcMove (self.pos1, self.speed, plat_hit_top); +}; + +void() plat_center_touch = +{ + if (other.classname != "player") + return; + + if (other.health <= 0) + return; + + self = self.enemy; + if (self.state == STATE_BOTTOM) + plat_go_up (); + else if (self.state == STATE_TOP) + self.nextthink = self.ltime + 1; // delay going down +}; + +void() plat_outside_touch = +{ + if (other.classname != "player") + return; + + if (other.health <= 0) + return; + +//dprint ("plat_outside_touch\n"); + self = self.enemy; + if (self.state == STATE_TOP) + plat_go_down (); +}; + +void() plat_trigger_use = +{ + if (self.think) + return; // allready activated + plat_go_down(); +}; + + +void() plat_crush = +{ +//dprint ("plat_crush\n"); + + T_Damage (other, self, self, 1); + + if (self.state == STATE_UP) + plat_go_down (); + else if (self.state == STATE_DOWN) + plat_go_up (); + else + objerror ("plat_crush: bad self.state\n"); +}; + +void() plat_use = +{ + self.use = SUB_Null; + if (self.state != STATE_UP) + objerror ("plat_use: not in up state"); + plat_go_down(); +}; + + +/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER +speed default 150 + +Plats are always drawn in the extended position, so they will light correctly. + +If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat. + +If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height. +Set "sounds" to one of the following: +1) base fast +2) chain slow +*/ + + +void() func_plat = + +{ + if (!self.t_length) + self.t_length = 80; + if (!self.t_width) + self.t_width = 10; + + if (self.sounds == 0) + self.sounds = 2; +// FIX THIS TO LOAD A GENERIC PLAT SOUND + + if (self.sounds == 1) + { + precache_sound ("plats/plat1.wav"); + precache_sound ("plats/plat2.wav"); + self.noise = "plats/plat1.wav"; + self.noise1 = "plats/plat2.wav"; + } + + if (self.sounds == 2) + { + precache_sound ("plats/medplat1.wav"); + precache_sound ("plats/medplat2.wav"); + self.noise = "plats/medplat1.wav"; + self.noise1 = "plats/medplat2.wav"; + } + + + self.mangle = self.angles; + self.angles = '0 0 0'; + + self.classname = "plat"; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + setorigin (self, self.origin); + setmodel (self, self.model); + setsize (self, self.mins , self.maxs); + + self.blocked = plat_crush; + if (!self.speed) + self.speed = 150; + +// pos1 is the top position, pos2 is the bottom + self.pos1 = self.origin; + self.pos2 = self.origin; + if (self.height) + self.pos2_z = self.origin_z - self.height; + else + self.pos2_z = self.origin_z - self.size_z + 8; + + self.use = plat_trigger_use; + + plat_spawn_inside_trigger (); // the "start moving" trigger + + if (self.targetname) + { + self.state = STATE_UP; + self.use = plat_use; + } + else + { + setorigin (self, self.pos2); + self.state = STATE_BOTTOM; + } +}; + +//============================================================================ + +void() train_next; +void() func_train_find; + +void() train_blocked = +{ + if (time < self.attack_finished) + return; + self.attack_finished = time + 0.5; + T_Damage (other, self, self, self.dmg); +}; +void() train_use = +{ + if (self.think != func_train_find) + return; // already activated + train_next(); +}; + +void() train_wait = +{ + if (self.wait) + { + self.nextthink = self.ltime + self.wait; + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + } + else + self.nextthink = self.ltime + 0.1; + + self.think = train_next; +}; + +void() train_next = +{ + local entity targ; + + targ = find (world, targetname, self.target); + self.target = targ.target; + if (!self.target) + objerror ("train_next: no next target"); + if (targ.wait) + self.wait = targ.wait; + else + self.wait = 0; + sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + SUB_CalcMove (targ.origin - self.mins, self.speed, train_wait); +}; + +void() func_train_find = + +{ + local entity targ; + + targ = find (world, targetname, self.target); + self.target = targ.target; + setorigin (self, targ.origin - self.mins); + if (!self.targetname) + { // not triggered, so start immediately + self.nextthink = self.ltime + 0.1; + self.think = train_next; + } +}; + +/*QUAKED func_train (0 .5 .8) ? +Trains are moving platforms that players can ride. +The targets origin specifies the min point of the train at each corner. +The train spawns at the first target it is pointing at. +If the train is the target of a button or trigger, it will not begin moving until activated. +speed default 100 +dmg default 2 +sounds +1) ratchet metal + +*/ +void() func_train = +{ + if (!self.speed) + self.speed = 100; + if (!self.target) + objerror ("func_train without a target"); + if (!self.dmg) + self.dmg = 2; + + if (self.sounds == 0) + { + self.noise = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + self.noise1 = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + } + + if (self.sounds == 1) + { + self.noise = ("plats/train2.wav"); + precache_sound ("plats/train2.wav"); + self.noise1 = ("plats/train1.wav"); + precache_sound ("plats/train1.wav"); + } + + self.cnt = 1; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + self.blocked = train_blocked; + self.use = train_use; + self.classname = "train"; + + setmodel (self, self.model); + setsize (self, self.mins , self.maxs); + setorigin (self, self.origin); + +// start trains on the second frame, to make sure their targets have had +// a chance to spawn + self.nextthink = self.ltime + 0.1; + self.think = func_train_find; +}; + +/*QUAKED misc_teleporttrain (0 .5 .8) (-8 -8 -8) (8 8 8) +This is used for the final bos +*/ +void() misc_teleporttrain = +{ + if (!self.speed) + self.speed = 100; + if (!self.target) + objerror ("func_train without a target"); + + self.cnt = 1; + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_PUSH; + self.blocked = train_blocked; + self.use = train_use; + self.avelocity = '100 200 300'; + + self.noise = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + self.noise1 = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + + precache_model2 ("progs/teleport.mdl"); + setmodel (self, "progs/teleport.mdl"); + setsize (self, self.mins , self.maxs); + setorigin (self, self.origin); + +// start trains on the second frame, to make sure their targets have had +// a chance to spawn + self.nextthink = self.ltime + 0.1; + self.think = func_train_find; +}; + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/player.qc b/r17/Revamped src/Revamped QC/Primeqc4/player.qc new file mode 100755 index 00000000..3cdd1b45 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/player.qc @@ -0,0 +1,618 @@ + +void() bubble_bob; + +/* +============================================================================== + +PLAYER + +============================================================================== +*/ + +$cd id1/models/player_4 +$origin 0 -6 24 +$base base +$skin skin + +// +// running +// +$frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6 + +$frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6 + +// +// standing +// +$frame stand1 stand2 stand3 stand4 stand5 + +$frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6 +$frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12 + + +// +// pain +// +$frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + + +// +// death +// + +$frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6 +$frame axdeth7 axdeth8 axdeth9 + +$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8 +$frame deatha9 deatha10 deatha11 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 + +$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8 +$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15 + +$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7 +$frame deathd8 deathd9 + +$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7 +$frame deathe8 deathe9 + +// +// attacks +// +$frame nailatt1 nailatt2 + +$frame light1 light2 + +$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6 + +$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6 + +$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6 + +$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6 + +$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6 + +$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6 + + +/* +============================================================================== +PLAYER +============================================================================== +*/ + +void() player_run; + +void() player_stand1 =[ $axstnd1, player_stand1 ] +{ + self.weaponframe=0; + if (self.velocity_x || self.velocity_y) + { + self.walkframe=0; + player_run(); + return; + } + else + { + if (self.walkframe >= 5) + self.walkframe = 0; + self.frame = $stand1 + self.walkframe; + } + self.walkframe = self.walkframe + 1; +}; + +void() player_run =[ $rockrun1, player_run ] +{ +local float r; +r = random(); +//THis is a HUGE check. I wonder if It is Memory Consuming at all. +if (checkbottom(self) == TRUE && self.flags & FL_ONGROUND && self.walkframe == 1 || self.walkframe == 4 && self.mballset == 0 && vlen(self.velocity) > 145 && !self.weapon == IT_MORPHBALL) +{ +if (r >= 0.33) + sound (self, CHAN_AUTO, "steps/foot1.wav", 0.5, ATTN_NORM); +else if (r >= 0.66) + sound (self, CHAN_AUTO, "steps/foot2.wav", 0.5, ATTN_NORM); +if (r >= 0.99) + sound (self, CHAN_AUTO, "steps/foot3.wav", 0.5, ATTN_NORM); +else + sound (self, CHAN_AUTO, "steps/foot4.wav", 0.5, ATTN_NORM); +} + + self.weaponframe=0; + if (!self.velocity_x && !self.velocity_y) + + { + self.walkframe=0; + player_stand1(); + return; + } + else + { + if (self.walkframe == 6) + self.walkframe = 0; + self.frame = self.frame + self.walkframe; + } + self.walkframe = self.walkframe + 1; +}; + + +void() player_shot1 = [$shotatt1, player_shot2 ] {self.weaponframe=1; +self.effects = self.effects | EF_MUZZLEFLASH;}; +void() player_shot2 = [$shotatt2, player_shot3 ] {self.weaponframe=2;}; +void() player_shot3 = [$shotatt3, player_shot4 ] {self.weaponframe=3;}; +void() player_shot4 = [$shotatt4, player_shot5 ] {self.weaponframe=4;}; +void() player_shot5 = [$shotatt5, player_shot6 ] {self.weaponframe=5;}; +void() player_shot6 = [$shotatt6, player_run ] {self.weaponframe=6;}; + +void() player_axe1 = [$axatt1, player_axe2 ] {self.weaponframe=1;}; +void() player_axe2 = [$axatt2, player_axe3 ] {self.weaponframe=2;}; +void() player_axe3 = [$axatt3, player_axe4 ] {self.weaponframe=3;W_FireAxe();}; +void() player_axe4 = [$axatt4, player_run ] {self.weaponframe=4;}; + +void() player_axeb1 = [$axattb1, player_axeb2 ] {self.weaponframe=5;}; +void() player_axeb2 = [$axattb2, player_axeb3 ] {self.weaponframe=6;}; +void() player_axeb3 = [$axattb3, player_axeb4 ] {self.weaponframe=7;W_FireAxe();}; +void() player_axeb4 = [$axattb4, player_run ] {self.weaponframe=8;}; + +void() player_axec1 = [$axattc1, player_axec2 ] {self.weaponframe=1;}; +void() player_axec2 = [$axattc2, player_axec3 ] {self.weaponframe=2;}; +void() player_axec3 = [$axattc3, player_axec4 ] {self.weaponframe=3;W_FireAxe();}; +void() player_axec4 = [$axattc4, player_run ] {self.weaponframe=4;}; + +void() player_axed1 = [$axattd1, player_axed2 ] {self.weaponframe=5;}; +void() player_axed2 = [$axattd2, player_axed3 ] {self.weaponframe=6;}; +void() player_axed3 = [$axattd3, player_axed4 ] {self.weaponframe=7;W_FireAxe();}; +void() player_axed4 = [$axattd4, player_run ] {self.weaponframe=8;}; + + +//============================================================================ + +void() player_nail1 =[$nailatt1, player_nail2 ] +{ + self.effects = self.effects | EF_MUZZLEFLASH; + + if (!self.button0) + {player_run ();return;} + self.weaponframe = self.weaponframe + 1; + if (self.weaponframe == 9) + self.weaponframe = 1; + SuperDamageSound(); + W_FireSpikes (4); + self.attack_finished = time + 0.2; +}; +void() player_nail2 =[$nailatt2, player_nail1 ] +{ + self.effects = self.effects | EF_MUZZLEFLASH; + + if (!self.button0) + {player_run ();return;} + self.weaponframe = self.weaponframe + 1; + if (self.weaponframe == 9) + self.weaponframe = 1; + SuperDamageSound(); + W_FireSpikes (-4); + self.attack_finished = time + 0.2; +}; + +//============================================================================ + +void() player_light1 =[$light1, player_light2 ] +{ + self.effects = self.effects | EF_MUZZLEFLASH; + + if (!self.button0) + {player_run ();return;} + self.weaponframe = self.weaponframe + 1; + if (self.weaponframe == 5) + self.weaponframe = 1; + SuperDamageSound(); + W_FireLightning(); + self.attack_finished = time + 0.2; +}; +void() player_light2 =[$light2, player_light1 ] +{ + self.effects = self.effects | EF_MUZZLEFLASH; + + if (!self.button0) + {player_run ();return;} + self.weaponframe = self.weaponframe + 1; + if (self.weaponframe == 5) + self.weaponframe = 1; + SuperDamageSound(); + W_FireLightning(); + self.attack_finished = time + 0.2; +}; + +//============================================================================ + + +void() player_rocket1 =[$rockatt1, player_rocket2 ] {self.weaponframe=1; +self.effects = self.effects | EF_MUZZLEFLASH;}; +void() player_rocket2 =[$rockatt2, player_rocket3 ] {self.weaponframe=2;}; +void() player_rocket3 =[$rockatt3, player_rocket4 ] {self.weaponframe=3;}; +void() player_rocket4 =[$rockatt4, player_rocket5 ] {self.weaponframe=4;}; +void() player_rocket5 =[$rockatt5, player_rocket6 ] {self.weaponframe=5;}; +void() player_rocket6 =[$rockatt6, player_run ] {self.weaponframe=6;}; +void(float num_bubbles) DeathBubbles; + +void() PainSound = +{ +//local float rs; + + if (self.health < 0) + return; + + if (damage_attacker.classname == "teledeath") + { + sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE); + return; + } +// slime pain sounds + if (self.watertype == CONTENT_SLIME) + { +// FIX ME put in some steam here + if (random() > 0.5) + sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM); + return; + } + /* + if (self.watertype == CONTENT_LAVA) + { + if (random() > 0.5) + sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM); + return; + } + */ + + if (self.pain_finished > time) + { + self.axhitme = 0; + return; + } + self.pain_finished = time + 0.5; + +// don't make multiple pain sounds right after each other + + + /* + rs = rint((random() * 5) + 1); + + self.noise = ""; + if (rs == 1) + self.noise = "player/pain1.wav"; + else if (rs == 2) + self.noise = "player/pain2.wav"; + else if (rs == 3) + self.noise = "player/pain3.wav"; + else if (rs == 4) + self.noise = "player/pain4.wav"; + else if (rs == 5) + self.noise = "player/pain5.wav"; + else + self.noise = "player/pain6.wav"; + + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + return; + */ +}; + +void() player_pain1 = [ $pain1, player_pain2 ] {PainSound();self.weaponframe=0;}; +void() player_pain2 = [ $pain2, player_pain3 ] {}; +void() player_pain3 = [ $pain3, player_pain4 ] {}; +void() player_pain4 = [ $pain4, player_pain5 ] {}; +void() player_pain5 = [ $pain5, player_pain6 ] {}; +void() player_pain6 = [ $pain6, player_run ] {}; + +void() player_axpain1 = [ $axpain1, player_axpain2 ] {PainSound();self.weaponframe=0;}; +void() player_axpain2 = [ $axpain2, player_axpain3 ] {}; +void() player_axpain3 = [ $axpain3, player_axpain4 ] {}; +void() player_axpain4 = [ $axpain4, player_axpain5 ] {}; +void() player_axpain5 = [ $axpain5, player_axpain6 ] {}; +void() player_axpain6 = [ $axpain6, player_run ] {}; + +void() player_pain = +{ + if (self.weaponframe) + return; + + if (self.invisible_finished > time) + return; // eyes don't have pain frames + player_pain1 (); +}; + +void() player_diea1; +void() player_dieb1; +void() player_diec1; +void() player_died1; +void() player_diee1; +void() DeathBubblesSpawn = +{ +local entity bubble; + if (self.owner.waterlevel != 3) + return; + bubble = spawn(); + setmodel (bubble, "progs/s_bubble.spr"); + setorigin (bubble, self.owner.origin + '0 0 24'); + bubble.movetype = MOVETYPE_NOCLIP; + bubble.solid = SOLID_NOT; + bubble.velocity = '0 0 15'; + bubble.nextthink = time + 0.5; + bubble.think = bubble_bob; + bubble.classname = "bubble"; + bubble.frame = 0; + bubble.cnt = 0; + setsize (bubble, '-8 -8 -8', '8 8 8'); + self.nextthink = time + 0.1; + self.think = DeathBubblesSpawn; + self.air_finished = self.air_finished + 1; + if (self.air_finished >= self.bubble_count) + remove(self); +}; + +void(float num_bubbles) DeathBubbles = +{ +local entity bubble_spawner; + + bubble_spawner = spawn(); + setorigin (bubble_spawner, self.origin); + bubble_spawner.movetype = MOVETYPE_NONE; + bubble_spawner.solid = SOLID_NOT; + bubble_spawner.nextthink = time + 0.1; + bubble_spawner.think = DeathBubblesSpawn; + bubble_spawner.air_finished = 0; + bubble_spawner.owner = self; + bubble_spawner.bubble_count = num_bubbles; + return; +}; + + +void() DeathSound = +{ +local float rs; + + // water death sounds + if (self.waterlevel == 3) + { + DeathBubbles(20); + sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE); + return; + } + + rs = rint ((random() * 4) + 1); + if (rs == 1) + self.noise = "player/death1.wav"; + if (rs == 2) + self.noise = "player/death2.wav"; + if (rs == 3) + self.noise = "player/death3.wav"; + if (rs == 4) + self.noise = "player/death4.wav"; + if (rs == 5) + self.noise = "player/death5.wav"; + + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NONE); + return; +}; + + +void() PlayerDead = +{ + self.nextthink = -1; +// allow respawn after a certain time + self.deadflag = DEAD_DEAD; +}; + +vector(float dm) VelocityForDamage = +{ + local vector v; + + v_x = 100 * crandom(); + v_y = 100 * crandom(); + v_z = 200 + 100 * random(); + + if (dm > -50) + { +// dprint ("level 1\n"); + v = v * 0.7; + } + else if (dm > -200) + { +// dprint ("level 3\n"); + v = v * 2; + } + else + v = v * 10; + + return v; +}; + +void(string gibname, float dm) ThrowGib = +{ + local entity new; + + new = spawn(); + new.origin = self.origin; + setmodel (new, gibname); + setsize (new, '0 0 0', '0 0 0'); + new.velocity = VelocityForDamage (dm); + new.movetype = MOVETYPE_BOUNCE; + new.solid = SOLID_NOT; + new.avelocity_x = random()*600; + new.avelocity_y = random()*600; + new.avelocity_z = random()*600; + new.think = SUB_Remove; + new.ltime = time; + new.nextthink = time + 10 + random()*10; + new.frame = 0; + new.flags = 0; +}; + +void(string gibname, float dm) ThrowHead = +{ + setmodel (self, gibname); + self.frame = 0; + self.nextthink = -1; + self.movetype = MOVETYPE_BOUNCE; + self.takedamage = DAMAGE_NO; + self.solid = SOLID_NOT; + self.view_ofs = '0 0 8'; + setsize (self, '-16 -16 0', '16 16 56'); + self.velocity = VelocityForDamage (dm); + self.origin_z = self.origin_z - 24; + self.flags = self.flags - (self.flags & FL_ONGROUND); + self.avelocity = crandom() * '0 600 0'; +}; + + +void() GibPlayer = +{ + ThrowHead ("progs/h_player.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + + self.deadflag = DEAD_DEAD; + + if (damage_attacker.classname == "teledeath") + { + sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE); + return; + } + + if (damage_attacker.classname == "teledeath2") + { + sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE); + return; + } + + if (random() < 0.5) + sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NONE); + else + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NONE); +}; + +void() PlayerDie = +{ + local float i; + + self.items = self.items - (self.items & IT_INVISIBILITY); + self.invisible_finished = 0; // don't die as eyes + self.invincible_finished = 0; + self.super_damage_finished = 0; + self.radsuit_finished = 0; + self.modelindex = modelindex_player; // don't use eyes + body(self.origin); + if (self.mballset == 1) + self.mballset = 0; + + self.weaponmodel=""; + self.view_ofs = '0 0 -8'; + self.deadflag = DEAD_DYING; + self.solid = SOLID_NOT; + self.flags = self.flags - (self.flags & FL_ONGROUND); + self.movetype = MOVETYPE_TOSS; + if (self.velocity_z < 10) + self.velocity_z = self.velocity_z + random()*300; + + + DeathSound(); + + self.angles_x = 0; + self.angles_z = 0; + + i = cvar("temp1"); + if (!i) + i = 1 + floor(random()*6); + + if (i == 1) + player_diea1(); + else if (i == 2) + player_dieb1(); + else if (i == 3) + player_diec1(); + else if (i == 4) + player_died1(); + else + player_diee1(); + +}; + +void() set_suicide_frame = +{ // used by klill command and diconnect command + if (self.model != "progs/player.mdl") + return; // allready gibbed + self.frame = $deatha11; + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_TOSS; + self.deadflag = DEAD_DEAD; + self.nextthink = -1; +}; + + +void() player_diea1 = [ $deatha1, player_diea2 ] {}; +void() player_diea2 = [ $deatha2, player_diea3 ] {}; +void() player_diea3 = [ $deatha3, player_diea4 ] {}; +void() player_diea4 = [ $deatha4, player_diea5 ] {}; +void() player_diea5 = [ $deatha5, player_diea6 ] {}; +void() player_diea6 = [ $deatha6, player_diea7 ] {}; +void() player_diea7 = [ $deatha7, player_diea8 ] {}; +void() player_diea8 = [ $deatha8, player_diea9 ] {}; +void() player_diea9 = [ $deatha9, player_diea10 ] {}; +void() player_diea10 = [ $deatha10, player_diea11 ] {}; +void() player_diea11 = [ $deatha11, player_diea11 ] {PlayerDead();}; + +void() player_dieb1 = [ $deathb1, player_dieb2 ] {}; +void() player_dieb2 = [ $deathb2, player_dieb3 ] {}; +void() player_dieb3 = [ $deathb3, player_dieb4 ] {}; +void() player_dieb4 = [ $deathb4, player_dieb5 ] {}; +void() player_dieb5 = [ $deathb5, player_dieb6 ] {}; +void() player_dieb6 = [ $deathb6, player_dieb7 ] {}; +void() player_dieb7 = [ $deathb7, player_dieb8 ] {}; +void() player_dieb8 = [ $deathb8, player_dieb9 ] {}; +void() player_dieb9 = [ $deathb9, player_dieb9 ] {PlayerDead();}; + +void() player_diec1 = [ $deathc1, player_diec2 ] {}; +void() player_diec2 = [ $deathc2, player_diec3 ] {}; +void() player_diec3 = [ $deathc3, player_diec4 ] {}; +void() player_diec4 = [ $deathc4, player_diec5 ] {}; +void() player_diec5 = [ $deathc5, player_diec6 ] {}; +void() player_diec6 = [ $deathc6, player_diec7 ] {}; +void() player_diec7 = [ $deathc7, player_diec8 ] {}; +void() player_diec8 = [ $deathc8, player_diec9 ] {}; +void() player_diec9 = [ $deathc9, player_diec10 ] {}; +void() player_diec10 = [ $deathc10, player_diec11 ] {}; +void() player_diec11 = [ $deathc11, player_diec12 ] {}; +void() player_diec12 = [ $deathc12, player_diec13 ] {}; +void() player_diec13 = [ $deathc13, player_diec14 ] {}; +void() player_diec14 = [ $deathc14, player_diec15 ] {}; +void() player_diec15 = [ $deathc15, player_diec15 ] {PlayerDead();}; + +void() player_died1 = [ $deathd1, player_died2 ] {}; +void() player_died2 = [ $deathd2, player_died3 ] {}; +void() player_died3 = [ $deathd3, player_died4 ] {}; +void() player_died4 = [ $deathd4, player_died5 ] {}; +void() player_died5 = [ $deathd5, player_died6 ] {}; +void() player_died6 = [ $deathd6, player_died7 ] {}; +void() player_died7 = [ $deathd7, player_died8 ] {}; +void() player_died8 = [ $deathd8, player_died9 ] {}; +void() player_died9 = [ $deathd9, player_died9 ] {PlayerDead();}; + +void() player_diee1 = [ $deathe1, player_diee2 ] {}; +void() player_diee2 = [ $deathe2, player_diee3 ] {}; +void() player_diee3 = [ $deathe3, player_diee4 ] {}; +void() player_diee4 = [ $deathe4, player_diee5 ] {}; +void() player_diee5 = [ $deathe5, player_diee6 ] {}; +void() player_diee6 = [ $deathe6, player_diee7 ] {}; +void() player_diee7 = [ $deathe7, player_diee8 ] {}; +void() player_diee8 = [ $deathe8, player_diee9 ] {}; +void() player_diee9 = [ $deathe9, player_diee9 ] {PlayerDead();}; + \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/primedefs.qc b/r17/Revamped src/Revamped QC/Primeqc4/primedefs.qc new file mode 100755 index 00000000..114ee3e3 Binary files /dev/null and b/r17/Revamped src/Revamped QC/Primeqc4/primedefs.qc differ diff --git a/r17/Revamped src/Revamped QC/Primeqc4/progdefs.h b/r17/Revamped src/Revamped QC/Primeqc4/progdefs.h new file mode 100755 index 00000000..c976cf8e --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/progdefs.h @@ -0,0 +1,143 @@ + +/* file generated by qcc, do not modify */ + +typedef struct +{ int pad[28]; + int self; + int other; + int world; + float time; + float frametime; + float force_retouch; + string_t mapname; + float deathmatch; + float coop; + float teamplay; + float serverflags; + float total_secrets; + float total_monsters; + float found_secrets; + float killed_monsters; + float parm1; + float parm2; + float parm3; + float parm4; + float parm5; + float parm6; + float parm7; + float parm8; + float parm9; + float parm10; + float parm11; + float parm12; + float parm13; + float parm14; + float parm15; + float parm16; + vec3_t v_forward; + vec3_t v_up; + vec3_t v_right; + float trace_allsolid; + float trace_startsolid; + float trace_fraction; + vec3_t trace_endpos; + vec3_t trace_plane_normal; + float trace_plane_dist; + int trace_ent; + float trace_inopen; + float trace_inwater; + int msg_entity; + func_t main; + func_t StartFrame; + func_t PlayerPreThink; + func_t PlayerPostThink; + func_t ClientKill; + func_t ClientConnect; + func_t PutClientInServer; + func_t ClientDisconnect; + func_t SetNewParms; + func_t SetChangeParms; +} globalvars_t; + +typedef struct +{ + float modelindex; + vec3_t absmin; + vec3_t absmax; + float ltime; + float movetype; + float solid; + vec3_t origin; + vec3_t oldorigin; + vec3_t velocity; + vec3_t angles; + vec3_t avelocity; + vec3_t punchangle; + string_t classname; + string_t model; + float frame; + float skin; + float effects; + vec3_t mins; + vec3_t maxs; + vec3_t size; + func_t touch; + func_t use; + func_t think; + func_t blocked; + float nextthink; + int groundentity; + float health; + float frags; + float weapon; + string_t weaponmodel; + float weaponframe; + float currentammo; + float ammo_shells; + float ammo_nails; + float ammo_rockets; + float ammo_cells; + float items; + float takedamage; + int chain; + float deadflag; + vec3_t view_ofs; + float button0; + float button1; + float button2; + float impulse; + float fixangle; + vec3_t v_angle; + float idealpitch; + string_t netname; + int enemy; + float flags; + float colormap; + float team; + float max_health; + float teleport_time; + float armortype; + float armorvalue; + float waterlevel; + float watertype; + float ideal_yaw; + float yaw_speed; + int aiment; + int goalentity; + float spawnflags; + string_t target; + string_t targetname; + float dmg_take; + float dmg_save; + int dmg_inflictor; + int owner; + vec3_t movedir; + string_t message; + float sounds; + string_t noise; + string_t noise1; + string_t noise2; + string_t noise3; +} entvars_t; + +#define PROGHEADER_CRC 5927 diff --git a/r17/Revamped src/Revamped QC/Primeqc4/progs.src b/r17/Revamped src/Revamped QC/Primeqc4/progs.src new file mode 100755 index 00000000..4383bd8a Binary files /dev/null and b/r17/Revamped src/Revamped QC/Primeqc4/progs.src differ diff --git a/r17/Revamped src/Revamped QC/Primeqc4/shalrath.qc b/r17/Revamped src/Revamped QC/Primeqc4/shalrath.qc new file mode 100755 index 00000000..adf821ab --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/shalrath.qc @@ -0,0 +1,239 @@ +/* +============================================================================== + +SHAL-RATH + +============================================================================== +*/ +$cd id1/models/shalrath +$origin 0 0 24 +$base base +$skin skin +$scale 0.7 + +$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 +$frame attack9 attack10 attack11 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame death1 death2 death3 death4 death5 death6 death7 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 +$frame walk11 walk12 + +void() shalrath_pain; +void() ShalMissile; +void() shal_stand =[ $walk1, shal_stand ] {ai_stand();}; + +void() shal_walk1 =[ $walk2, shal_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE); +ai_walk(6);}; +void() shal_walk2 =[ $walk3, shal_walk3 ] {ai_walk(4);}; +void() shal_walk3 =[ $walk4, shal_walk4 ] {ai_walk(0);}; +void() shal_walk4 =[ $walk5, shal_walk5 ] {ai_walk(0);}; +void() shal_walk5 =[ $walk6, shal_walk6 ] {ai_walk(0);}; +void() shal_walk6 =[ $walk7, shal_walk7 ] {ai_walk(0);}; +void() shal_walk7 =[ $walk8, shal_walk8 ] {ai_walk(5);}; +void() shal_walk8 =[ $walk9, shal_walk9 ] {ai_walk(6);}; +void() shal_walk9 =[ $walk10, shal_walk10 ] {ai_walk(5);}; +void() shal_walk10 =[ $walk11, shal_walk11 ] {ai_walk(0);}; +void() shal_walk11 =[ $walk12, shal_walk12 ] {ai_walk(4);}; +void() shal_walk12 =[ $walk1, shal_walk1 ] {ai_walk(5);}; + +void() shal_run1 =[ $walk2, shal_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE); +ai_run(6);}; +void() shal_run2 =[ $walk3, shal_run3 ] {ai_run(4);}; +void() shal_run3 =[ $walk4, shal_run4 ] {ai_run(0);}; +void() shal_run4 =[ $walk5, shal_run5 ] {ai_run(0);}; +void() shal_run5 =[ $walk6, shal_run6 ] {ai_run(0);}; +void() shal_run6 =[ $walk7, shal_run7 ] {ai_run(0);}; +void() shal_run7 =[ $walk8, shal_run8 ] {ai_run(5);}; +void() shal_run8 =[ $walk9, shal_run9 ] {ai_run(6);}; +void() shal_run9 =[ $walk10, shal_run10 ] {ai_run(5);}; +void() shal_run10 =[ $walk11, shal_run11 ] {ai_run(0);}; +void() shal_run11 =[ $walk12, shal_run12 ] {ai_run(4);}; +void() shal_run12 =[ $walk1, shal_run1 ] {ai_run(5);}; + +void() shal_attack1 =[ $attack1, shal_attack2 ] { +sound (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM); +ai_face(); +}; +void() shal_attack2 =[ $attack2, shal_attack3 ] {ai_face();}; +void() shal_attack3 =[ $attack3, shal_attack4 ] {ai_face();}; +void() shal_attack4 =[ $attack4, shal_attack5 ] {ai_face();}; +void() shal_attack5 =[ $attack5, shal_attack6 ] {ai_face();}; +void() shal_attack6 =[ $attack6, shal_attack7 ] {ai_face();}; +void() shal_attack7 =[ $attack7, shal_attack8 ] {ai_face();}; +void() shal_attack8 =[ $attack8, shal_attack9 ] {ai_face();}; +void() shal_attack9 =[ $attack9, shal_attack10 ] {ShalMissile();}; +void() shal_attack10 =[ $attack10, shal_attack11 ] {ai_face();}; +void() shal_attack11 =[ $attack11, shal_run1 ] {}; + +void() shal_pain1 =[ $pain1, shal_pain2 ] {}; +void() shal_pain2 =[ $pain2, shal_pain3 ] {}; +void() shal_pain3 =[ $pain3, shal_pain4 ] {}; +void() shal_pain4 =[ $pain4, shal_pain5 ] {}; +void() shal_pain5 =[ $pain5, shal_run1 ] {}; + +void() shal_death1 =[ $death1, shal_death2 ] {}; +void() shal_death2 =[ $death2, shal_death3 ] {}; +void() shal_death3 =[ $death3, shal_death4 ] {}; +void() shal_death4 =[ $death4, shal_death5 ] {}; +void() shal_death5 =[ $death5, shal_death6 ] {}; +void() shal_death6 =[ $death6, shal_death7 ] {}; +void() shal_death7 =[ $death7, shal_death7 ] {}; + + +void() shalrath_pain = +{ + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "shalrath/pain.wav", 1, ATTN_NORM); + shal_pain1(); + self.pain_finished = time + 3; +}; + +void() shalrath_die = +{ +// check for gib + if (self.health < -90) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_shal.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + + sound (self, CHAN_VOICE, "shalrath/death.wav", 1, ATTN_NORM); + shal_death1(); + self.solid = SOLID_NOT; + // insert death sounds here +}; + +/* +================ +ShalMissile +================ +*/ +void() ShalMissileTouch; +void() ShalHome; +void() ShalMissile = +{ + local entity missile; + local vector dir; + local float dist, flytime; + + dir = normalize((self.enemy.origin + '0 0 10') - self.origin); + dist = vlen (self.enemy.origin - self.origin); + flytime = dist * 0.002; + if (flytime < 0.1) + flytime = 0.1; + + self.effects = self.effects | EF_MUZZLEFLASH; + sound (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); + + missile = spawn (); + missile.owner = self; + + missile.solid = SOLID_BBOX; + missile.movetype = MOVETYPE_FLYMISSILE; + setmodel (missile, "progs/v_spike.mdl"); + + setsize (missile, '0 0 0', '0 0 0'); + + missile.origin = self.origin + '0 0 10'; + missile.velocity = dir * 400; + missile.avelocity = '300 300 300'; + missile.nextthink = flytime + time; + missile.think = ShalHome; + missile.enemy = self.enemy; + missile.touch = ShalMissileTouch; +}; + +void() ShalHome = +{ + local vector dir, vtemp; + vtemp = self.enemy.origin + '0 0 10'; + if (self.enemy.health < 1) + { + remove(self); + return; + } + dir = normalize(vtemp - self.origin); + if (skill == 3) + self.velocity = dir * 350; + else + self.velocity = dir * 250; + self.nextthink = time + 0.2; + self.think = ShalHome; +}; + +void() ShalMissileTouch = +{ + if (other == self.owner) + return; // don't explode on owner + + if (other.classname == "monster_zombie") + T_Damage (other, self, self, 110); + T_RadiusDamage (self, self.owner, 40, world); + sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); + + 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); + + self.velocity = '0 0 0'; + self.touch = SUB_Null; + setmodel (self, "progs/s_explod.spr"); + self.solid = SOLID_NOT; + s_explode1 (); +}; + +//================================================================= + +/*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) Ambush +*/ +void() monster_shalrath = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/shalrath.mdl"); + precache_model2 ("progs/h_shal.mdl"); + precache_model2 ("progs/v_spike.mdl"); + + precache_sound2 ("shalrath/attack.wav"); + precache_sound2 ("shalrath/attack2.wav"); + precache_sound2 ("shalrath/death.wav"); + precache_sound2 ("shalrath/idle.wav"); + precache_sound2 ("shalrath/pain.wav"); + precache_sound2 ("shalrath/sight.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/shalrath.mdl"); + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 400; + + self.th_stand = shal_stand; + self.th_walk = shal_walk1; + self.th_run = shal_run1; + self.th_die = shalrath_die; + self.th_pain = shalrath_pain; + self.th_missile = shal_attack1; + + self.think = walkmonster_start; + self.nextthink = time + 0.1 + random ()*0.1; + +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/shambler.qc b/r17/Revamped src/Revamped QC/Primeqc4/shambler.qc new file mode 100755 index 00000000..4bd8a969 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/shambler.qc @@ -0,0 +1,360 @@ +/* +============================================================================== + +SHAMBLER + +============================================================================== +*/ + +$cd id1/models/shams +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 +$frame stand10 stand11 stand12 stand13 stand14 stand15 stand16 stand17 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 +$frame walk8 walk9 walk10 walk11 walk12 + +$frame run1 run2 run3 run4 run5 run6 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 +$frame smash8 smash9 smash10 smash11 smash12 + +$frame swingr1 swingr2 swingr3 swingr4 swingr5 +$frame swingr6 swingr7 swingr8 swingr9 + +$frame swingl1 swingl2 swingl3 swingl4 swingl5 +$frame swingl6 swingl7 swingl8 swingl9 + +$frame magic1 magic2 magic3 magic4 magic5 +$frame magic6 magic7 magic8 magic9 magic10 magic11 magic12 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame death1 death2 death3 death4 death5 death6 +$frame death7 death8 death9 death10 death11 + +void() sham_stand1 =[ $stand1, sham_stand2 ] {ai_stand();}; +void() sham_stand2 =[ $stand2, sham_stand3 ] {ai_stand();}; +void() sham_stand3 =[ $stand3, sham_stand4 ] {ai_stand();}; +void() sham_stand4 =[ $stand4, sham_stand5 ] {ai_stand();}; +void() sham_stand5 =[ $stand5, sham_stand6 ] {ai_stand();}; +void() sham_stand6 =[ $stand6, sham_stand7 ] {ai_stand();}; +void() sham_stand7 =[ $stand7, sham_stand8 ] {ai_stand();}; +void() sham_stand8 =[ $stand8, sham_stand9 ] {ai_stand();}; +void() sham_stand9 =[ $stand9, sham_stand10] {ai_stand();}; +void() sham_stand10 =[ $stand10, sham_stand11] {ai_stand();}; +void() sham_stand11 =[ $stand11, sham_stand12] {ai_stand();}; +void() sham_stand12 =[ $stand12, sham_stand13] {ai_stand();}; +void() sham_stand13 =[ $stand13, sham_stand14] {ai_stand();}; +void() sham_stand14 =[ $stand14, sham_stand15] {ai_stand();}; +void() sham_stand15 =[ $stand15, sham_stand16] {ai_stand();}; +void() sham_stand16 =[ $stand16, sham_stand17] {ai_stand();}; +void() sham_stand17 =[ $stand17, sham_stand1 ] {ai_stand();}; + +void() sham_walk1 =[ $walk1, sham_walk2 ] {ai_walk(10);}; +void() sham_walk2 =[ $walk2, sham_walk3 ] {ai_walk(9);}; +void() sham_walk3 =[ $walk3, sham_walk4 ] {ai_walk(9);}; +void() sham_walk4 =[ $walk4, sham_walk5 ] {ai_walk(5);}; +void() sham_walk5 =[ $walk5, sham_walk6 ] {ai_walk(6);}; +void() sham_walk6 =[ $walk6, sham_walk7 ] {ai_walk(12);}; +void() sham_walk7 =[ $walk7, sham_walk8 ] {ai_walk(8);}; +void() sham_walk8 =[ $walk8, sham_walk9 ] {ai_walk(3);}; +void() sham_walk9 =[ $walk9, sham_walk10] {ai_walk(13);}; +void() sham_walk10 =[ $walk10, sham_walk11] {ai_walk(9);}; +void() sham_walk11 =[ $walk11, sham_walk12] {ai_walk(7);}; +void() sham_walk12 =[ $walk12, sham_walk1 ] {ai_walk(7); +if (random() > 0.8) + sound (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);}; + +void() sham_run1 =[ $run1, sham_run2 ] {ai_run(20);}; +void() sham_run2 =[ $run2, sham_run3 ] {ai_run(24);}; +void() sham_run3 =[ $run3, sham_run4 ] {ai_run(20);}; +void() sham_run4 =[ $run4, sham_run5 ] {ai_run(20);}; +void() sham_run5 =[ $run5, sham_run6 ] {ai_run(24);}; +void() sham_run6 =[ $run6, sham_run1 ] {ai_run(20); +if (random() > 0.8) + sound (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE); +}; + +void() sham_smash1 =[ $smash1, sham_smash2 ] { +sound (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); +ai_charge(2);}; +void() sham_smash2 =[ $smash2, sham_smash3 ] {ai_charge(6);}; +void() sham_smash3 =[ $smash3, sham_smash4 ] {ai_charge(6);}; +void() sham_smash4 =[ $smash4, sham_smash5 ] {ai_charge(5);}; +void() sham_smash5 =[ $smash5, sham_smash6 ] {ai_charge(4);}; +void() sham_smash6 =[ $smash6, sham_smash7 ] {ai_charge(1);}; +void() sham_smash7 =[ $smash7, sham_smash8 ] {ai_charge(0);}; +void() sham_smash8 =[ $smash8, sham_smash9 ] {ai_charge(0);}; +void() sham_smash9 =[ $smash9, sham_smash10 ] {ai_charge(0);}; +void() sham_smash10 =[ $smash10, sham_smash11 ] { +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + ai_charge(0); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + if (!CanDamage (self.enemy, self)) + return; + + ldmg = (random() + random() + random()) * 40; + T_Damage (self.enemy, self, self, ldmg); + sound (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM); + +}; +void() sham_smash11 =[ $smash11, sham_smash12 ] {ai_charge(5);}; +void() sham_smash12 =[ $smash12, sham_run1 ] {ai_charge(4);}; + +void() sham_swingr1; + +void(float side) ShamClaw = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + ai_charge(10); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + ldmg = (random() + random() + random()) * 20; + T_Damage (self.enemy, self, self, ldmg); + sound (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM); + +}; + +void() sham_swingl1 =[ $swingl1, sham_swingl2 ] { +sound (self, CHAN_VOICE, "shambler/melee2.wav", 1, ATTN_NORM); +ai_charge(5);}; +void() sham_swingl2 =[ $swingl2, sham_swingl3 ] {ai_charge(3);}; +void() sham_swingl3 =[ $swingl3, sham_swingl4 ] {ai_charge(7);}; +void() sham_swingl4 =[ $swingl4, sham_swingl5 ] {ai_charge(3);}; +void() sham_swingl5 =[ $swingl5, sham_swingl6 ] {ai_charge(7);}; +void() sham_swingl6 =[ $swingl6, sham_swingl7 ] {ai_charge(9);}; +void() sham_swingl7 =[ $swingl7, sham_swingl8 ] {ai_charge(5); ShamClaw(250);}; +void() sham_swingl8 =[ $swingl8, sham_swingl9 ] {ai_charge(4);}; +void() sham_swingl9 =[ $swingl9, sham_run1 ] { +ai_charge(8); +if (random()<0.5) + self.think = sham_swingr1; +}; + +void() sham_swingr1 =[ $swingr1, sham_swingr2 ] { +sound (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); +ai_charge(1);}; +void() sham_swingr2 =[ $swingr2, sham_swingr3 ] {ai_charge(8);}; +void() sham_swingr3 =[ $swingr3, sham_swingr4 ] {ai_charge(14);}; +void() sham_swingr4 =[ $swingr4, sham_swingr5 ] {ai_charge(7);}; +void() sham_swingr5 =[ $swingr5, sham_swingr6 ] {ai_charge(3);}; +void() sham_swingr6 =[ $swingr6, sham_swingr7 ] {ai_charge(6);}; +void() sham_swingr7 =[ $swingr7, sham_swingr8 ] {ai_charge(6); ShamClaw(-250);}; +void() sham_swingr8 =[ $swingr8, sham_swingr9 ] {ai_charge(3);}; +void() sham_swingr9 =[ $swingr9, sham_run1 ] {ai_charge(1); +ai_charge(10); +if (random()<0.5) + self.think = sham_swingl1; +}; + +void() sham_melee = +{ + local float chance; + + chance = random(); + if (chance > 0.6 || self.health == 600) + sham_smash1 (); + else if (chance > 0.3) + sham_swingr1 (); + else + sham_swingl1 (); +}; + + +//============================================================================ + +void() CastLightning = +{ + local vector org, dir; + + self.effects = self.effects | EF_MUZZLEFLASH; + + ai_face (); + + org = self.origin + '0 0 40'; + + dir = self.enemy.origin + '0 0 16' - org; + dir = normalize (dir); + + traceline (org, self.origin + dir*600, TRUE, self); + + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_LIGHTNING1); + WriteEntity (MSG_BROADCAST, self); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); + WriteCoord (MSG_BROADCAST, trace_endpos_x); + WriteCoord (MSG_BROADCAST, trace_endpos_y); + WriteCoord (MSG_BROADCAST, trace_endpos_z); + + LightningDamage (org, trace_endpos, self, 10); +}; + +void() sham_magic1 =[ $magic1, sham_magic2 ] {ai_face(); + sound (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM); +}; +void() sham_magic2 =[ $magic2, sham_magic3 ] {ai_face();}; +void() sham_magic3 =[ $magic3, sham_magic4 ] {ai_face();self.nextthink = self.nextthink + 0.2; +local entity o; + +self.effects = self.effects | EF_MUZZLEFLASH; +ai_face(); +self.owner = spawn(); +o = self.owner; +setmodel (o, "progs/s_light.mdl"); +setorigin (o, self.origin); +o.angles = self.angles; +o.nextthink = time + 0.7; +o.think = SUB_Remove; +}; +void() sham_magic4 =[ $magic4, sham_magic5 ] +{ +self.effects = self.effects | EF_MUZZLEFLASH; +self.owner.frame = 1; +}; +void() sham_magic5 =[ $magic5, sham_magic6 ] +{ +self.effects = self.effects | EF_MUZZLEFLASH; +self.owner.frame = 2; +}; +void() sham_magic6 =[ $magic6, sham_magic9 ] +{ +remove (self.owner); +CastLightning(); +sound (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM); +}; +void() sham_magic9 =[ $magic9, sham_magic10 ] +{CastLightning();}; +void() sham_magic10 =[ $magic10, sham_magic11 ] +{CastLightning();}; +void() sham_magic11 =[ $magic11, sham_magic12 ] +{ +if (skill == 3) + CastLightning(); +}; +void() sham_magic12 =[ $magic12, sham_run1 ] {}; + + + +void() sham_pain1 =[ $pain1, sham_pain2 ] {}; +void() sham_pain2 =[ $pain2, sham_pain3 ] {}; +void() sham_pain3 =[ $pain3, sham_pain4 ] {}; +void() sham_pain4 =[ $pain4, sham_pain5 ] {}; +void() sham_pain5 =[ $pain5, sham_pain6 ] {}; +void() sham_pain6 =[ $pain6, sham_run1 ] {}; + +void(entity attacker, float damage) sham_pain = +{ + sound (self, CHAN_VOICE, "shambler/shurt2.wav", 1, ATTN_NORM); + + if (self.health <= 0) + return; // allready dying, don't go into pain frame + + if (random()*400 > damage) + return; // didn't flinch + + if (self.pain_finished > time) + return; + self.pain_finished = time + 2; + + sham_pain1 (); +}; + + +//============================================================================ + +void() sham_death1 =[ $death1, sham_death2 ] {}; +void() sham_death2 =[ $death2, sham_death3 ] {}; +void() sham_death3 =[ $death3, sham_death4 ] {self.solid = SOLID_NOT;}; +void() sham_death4 =[ $death4, sham_death5 ] {}; +void() sham_death5 =[ $death5, sham_death6 ] {}; +void() sham_death6 =[ $death6, sham_death7 ] {}; +void() sham_death7 =[ $death7, sham_death8 ] {}; +void() sham_death8 =[ $death8, sham_death9 ] {}; +void() sham_death9 =[ $death9, sham_death10 ] {}; +void() sham_death10 =[ $death10, sham_death11 ] {}; +void() sham_death11 =[ $death11, sham_death11 ] {}; + +void() sham_die = +{ +// check for gib + if (self.health < -60) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_shams.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "shambler/sdeath.wav", 1, ATTN_NORM); + sham_death1 (); +}; + +//============================================================================ + + +/*QUAKED monster_shambler (1 0 0) (-32 -32 -24) (32 32 64) Ambush +*/ +void() monster_shambler = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/shambler.mdl"); + precache_model ("progs/s_light.mdl"); + precache_model ("progs/h_shams.mdl"); + precache_model ("progs/bolt.mdl"); + + precache_sound ("shambler/sattck1.wav"); + precache_sound ("shambler/sboom.wav"); + precache_sound ("shambler/sdeath.wav"); + precache_sound ("shambler/shurt2.wav"); + precache_sound ("shambler/sidle.wav"); + precache_sound ("shambler/ssight.wav"); + precache_sound ("shambler/melee1.wav"); + precache_sound ("shambler/melee2.wav"); + precache_sound ("shambler/smack.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + setmodel (self, "progs/shambler.mdl"); + + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 600; + + self.th_stand = sham_stand1; + self.th_walk = sham_walk1; + self.th_run = sham_run1; + self.th_die = sham_die; + self.th_melee = sham_melee; + self.th_missile = sham_magic1; + self.th_pain = sham_pain; + + walkmonster_start(); +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/soldier.qc b/r17/Revamped src/Revamped QC/Primeqc4/soldier.qc new file mode 100755 index 00000000..f1632f54 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/soldier.qc @@ -0,0 +1,284 @@ +/* +============================================================================== + +SOLDIER / PLAYER + +============================================================================== +*/ + +$cd id1/models/soldier3 +$origin 0 -6 24 +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 + +$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8 +$frame deathc9 deathc10 deathc11 + +$frame load1 load2 load3 load4 load5 load6 load7 load8 load9 load10 load11 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10 +$frame painb11 painb12 painb13 painb14 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10 +$frame painc11 painc12 painc13 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 shoot7 shoot8 shoot9 + +$frame prowl_1 prowl_2 prowl_3 prowl_4 prowl_5 prowl_6 prowl_7 prowl_8 +$frame prowl_9 prowl_10 prowl_11 prowl_12 prowl_13 prowl_14 prowl_15 prowl_16 +$frame prowl_17 prowl_18 prowl_19 prowl_20 prowl_21 prowl_22 prowl_23 prowl_24 + +/* +============================================================================== +SOLDIER CODE +============================================================================== +*/ + +void() army_fire; + +void() army_stand1 =[ $stand1, army_stand2 ] {ai_stand();}; +void() army_stand2 =[ $stand2, army_stand3 ] {ai_stand();}; +void() army_stand3 =[ $stand3, army_stand4 ] {ai_stand();}; +void() army_stand4 =[ $stand4, army_stand5 ] {ai_stand();}; +void() army_stand5 =[ $stand5, army_stand6 ] {ai_stand();}; +void() army_stand6 =[ $stand6, army_stand7 ] {ai_stand();}; +void() army_stand7 =[ $stand7, army_stand8 ] {ai_stand();}; +void() army_stand8 =[ $stand8, army_stand1 ] {ai_stand();}; + +void() army_walk1 =[ $prowl_1, army_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE); +ai_walk(1);}; +void() army_walk2 =[ $prowl_2, army_walk3 ] {ai_walk(1);}; +void() army_walk3 =[ $prowl_3, army_walk4 ] {ai_walk(1);}; +void() army_walk4 =[ $prowl_4, army_walk5 ] {ai_walk(1);}; +void() army_walk5 =[ $prowl_5, army_walk6 ] {ai_walk(2);}; +void() army_walk6 =[ $prowl_6, army_walk7 ] {ai_walk(3);}; +void() army_walk7 =[ $prowl_7, army_walk8 ] {ai_walk(4);}; +void() army_walk8 =[ $prowl_8, army_walk9 ] {ai_walk(4);}; +void() army_walk9 =[ $prowl_9, army_walk10 ] {ai_walk(2);}; +void() army_walk10 =[ $prowl_10, army_walk11 ] {ai_walk(2);}; +void() army_walk11 =[ $prowl_11, army_walk12 ] {ai_walk(2);}; +void() army_walk12 =[ $prowl_12, army_walk13 ] {ai_walk(1);}; +void() army_walk13 =[ $prowl_13, army_walk14 ] {ai_walk(0);}; +void() army_walk14 =[ $prowl_14, army_walk15 ] {ai_walk(1);}; +void() army_walk15 =[ $prowl_15, army_walk16 ] {ai_walk(1);}; +void() army_walk16 =[ $prowl_16, army_walk17 ] {ai_walk(1);}; +void() army_walk17 =[ $prowl_17, army_walk18 ] {ai_walk(3);}; +void() army_walk18 =[ $prowl_18, army_walk19 ] {ai_walk(3);}; +void() army_walk19 =[ $prowl_19, army_walk20 ] {ai_walk(3);}; +void() army_walk20 =[ $prowl_20, army_walk21 ] {ai_walk(3);}; +void() army_walk21 =[ $prowl_21, army_walk22 ] {ai_walk(2);}; +void() army_walk22 =[ $prowl_22, army_walk23 ] {ai_walk(1);}; +void() army_walk23 =[ $prowl_23, army_walk24 ] {ai_walk(1);}; +void() army_walk24 =[ $prowl_24, army_walk1 ] {ai_walk(1);}; + +void() army_run1 =[ $run1, army_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE); +ai_run(11);}; +void() army_run2 =[ $run2, army_run3 ] {ai_run(15);}; +void() army_run3 =[ $run3, army_run4 ] {ai_run(10);}; +void() army_run4 =[ $run4, army_run5 ] {ai_run(10);}; +void() army_run5 =[ $run5, army_run6 ] {ai_run(8);}; +void() army_run6 =[ $run6, army_run7 ] {ai_run(15);}; +void() army_run7 =[ $run7, army_run8 ] {ai_run(10);}; +void() army_run8 =[ $run8, army_run1 ] {ai_run(8);}; + +void() army_atk1 =[ $shoot1, army_atk2 ] {ai_face();}; +void() army_atk2 =[ $shoot2, army_atk3 ] {ai_face();}; +void() army_atk3 =[ $shoot3, army_atk4 ] {ai_face();}; +void() army_atk4 =[ $shoot4, army_atk5 ] {ai_face();}; +void() army_atk5 =[ $shoot5, army_atk6 ] {ai_face();army_fire(); +self.effects = self.effects | EF_MUZZLEFLASH;}; +void() army_atk6 =[ $shoot6, army_atk7 ] {ai_face();}; +void() army_atk7 =[ $shoot7, army_atk8 ] {ai_face();SUB_CheckRefire (army_atk1);}; +void() army_atk8 =[ $shoot8, army_atk9 ] {ai_face();}; +void() army_atk9 =[ $shoot9, army_run1 ] {ai_face();}; + + +void() army_pain1 =[ $pain1, army_pain2 ] {}; +void() army_pain2 =[ $pain2, army_pain3 ] {}; +void() army_pain3 =[ $pain3, army_pain4 ] {}; +void() army_pain4 =[ $pain4, army_pain5 ] {}; +void() army_pain5 =[ $pain5, army_pain6 ] {}; +void() army_pain6 =[ $pain6, army_run1 ] {ai_pain(1);}; + +void() army_painb1 =[ $painb1, army_painb2 ] {}; +void() army_painb2 =[ $painb2, army_painb3 ] {ai_painforward(13);}; +void() army_painb3 =[ $painb3, army_painb4 ] {ai_painforward(9);}; +void() army_painb4 =[ $painb4, army_painb5 ] {}; +void() army_painb5 =[ $painb5, army_painb6 ] {}; +void() army_painb6 =[ $painb6, army_painb7 ] {}; +void() army_painb7 =[ $painb7, army_painb8 ] {}; +void() army_painb8 =[ $painb8, army_painb9 ] {}; +void() army_painb9 =[ $painb9, army_painb10] {}; +void() army_painb10=[ $painb10, army_painb11] {}; +void() army_painb11=[ $painb11, army_painb12] {}; +void() army_painb12=[ $painb12, army_painb13] {ai_pain(2);}; +void() army_painb13=[ $painb13, army_painb14] {}; +void() army_painb14=[ $painb14, army_run1 ] {}; + +void() army_painc1 =[ $painc1, army_painc2 ] {}; +void() army_painc2 =[ $painc2, army_painc3 ] {ai_pain(1);}; +void() army_painc3 =[ $painc3, army_painc4 ] {}; +void() army_painc4 =[ $painc4, army_painc5 ] {}; +void() army_painc5 =[ $painc5, army_painc6 ] {ai_painforward(1);}; +void() army_painc6 =[ $painc6, army_painc7 ] {ai_painforward(1);}; +void() army_painc7 =[ $painc7, army_painc8 ] {}; +void() army_painc8 =[ $painc8, army_painc9 ] {ai_pain(1);}; +void() army_painc9 =[ $painc9, army_painc10] {ai_painforward(4);}; +void() army_painc10=[ $painc10, army_painc11] {ai_painforward(3);}; +void() army_painc11=[ $painc11, army_painc12] {ai_painforward(6);}; +void() army_painc12=[ $painc12, army_painc13] {ai_painforward(8);}; +void() army_painc13=[ $painc13, army_run1] {}; + +void(entity attacker, float damage) army_pain = +{ + local float r; + + if (self.pain_finished > time) + return; + + r = random(); + + if (r < 0.2) + { + self.pain_finished = time + 0.6; + army_pain1 (); + sound (self, CHAN_VOICE, "soldier/pain1.wav", 1, ATTN_NORM); + } + else if (r < 0.6) + { + self.pain_finished = time + 1.1; + army_painb1 (); + sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM); + } + else + { + self.pain_finished = time + 1.1; + army_painc1 (); + sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM); + } +}; + + +void() army_fire = +{ + local vector dir; + local entity en; + + ai_face(); + + sound (self, CHAN_WEAPON, "soldier/sattck1.wav", 1, ATTN_NORM); + +// fire somewhat behind the player, so a dodging player is harder to hit + en = self.enemy; + + dir = en.origin - en.velocity*0.2; + dir = normalize (dir - self.origin); + + FireBullets (4, dir, '0.1 0.1 0'); +}; + + + +void() army_die1 =[ $death1, army_die2 ] {}; +void() army_die2 =[ $death2, army_die3 ] {}; +void() army_die3 =[ $death3, army_die4 ] +{self.solid = SOLID_NOT;self.ammo_shells = 5;DropBackpack();}; +void() army_die4 =[ $death4, army_die5 ] {}; +void() army_die5 =[ $death5, army_die6 ] {}; +void() army_die6 =[ $death6, army_die7 ] {}; +void() army_die7 =[ $death7, army_die8 ] {}; +void() army_die8 =[ $death8, army_die9 ] {}; +void() army_die9 =[ $death9, army_die10 ] {}; +void() army_die10 =[ $death10, army_die10 ] {}; + +void() army_cdie1 =[ $deathc1, army_cdie2 ] {}; +void() army_cdie2 =[ $deathc2, army_cdie3 ] {ai_back(5);}; +void() army_cdie3 =[ $deathc3, army_cdie4 ] +{self.solid = SOLID_NOT;self.ammo_shells = 5;DropBackpack();ai_back(4);}; +void() army_cdie4 =[ $deathc4, army_cdie5 ] {ai_back(13);}; +void() army_cdie5 =[ $deathc5, army_cdie6 ] {ai_back(3);}; +void() army_cdie6 =[ $deathc6, army_cdie7 ] {ai_back(4);}; +void() army_cdie7 =[ $deathc7, army_cdie8 ] {}; +void() army_cdie8 =[ $deathc8, army_cdie9 ] {}; +void() army_cdie9 =[ $deathc9, army_cdie10 ] {}; +void() army_cdie10 =[ $deathc10, army_cdie11 ] {}; +void() army_cdie11 =[ $deathc11, army_cdie11 ] {}; + + +void() army_die = +{ +// check for gib + if (self.health < -35) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_guard.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "soldier/death1.wav", 1, ATTN_NORM); + if (random() < 0.5) + army_die1 (); + else + army_cdie1 (); +}; + + +/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_army = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/soldier.mdl"); + precache_model ("progs/h_guard.mdl"); + precache_model ("progs/gib1.mdl"); + precache_model ("progs/gib2.mdl"); + precache_model ("progs/gib3.mdl"); + + precache_sound ("soldier/death1.wav"); + precache_sound ("soldier/idle.wav"); + precache_sound ("soldier/pain1.wav"); + precache_sound ("soldier/pain2.wav"); + precache_sound ("soldier/sattck1.wav"); + precache_sound ("soldier/sight1.wav"); + + precache_sound ("player/udeath.wav"); // gib death + + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/soldier.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 30; + + self.th_stand = army_stand1; + self.th_walk = army_walk1; + self.th_run = army_run1; + self.th_missile = army_atk1; + self.th_pain = army_pain; + self.th_die = army_die; + + walkmonster_start (); +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/sprites.qc b/r17/Revamped src/Revamped QC/Primeqc4/sprites.qc new file mode 100755 index 00000000..6874f595 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/sprites.qc @@ -0,0 +1,26 @@ + +// these are the only sprites still in the game... + +$spritename s_explod +$type vp_parallel +$load id1/gfx/sprites/explod03.lbm +$frame 24 24 56 56 +$frame 120 24 56 56 +$frame 216 24 56 56 +$frame 24 88 56 56 +$frame 120 88 56 56 +$frame 216 88 56 56 + + +$spritename s_bubble +$type vp_parallel +$load id1/gfx/sprites/bubble.lbm +$frame 16 16 16 16 +$frame 40 16 16 16 + + +$spritename s_light +$type vp_parallel +$load id1/gfx/sprites/light.lbm +$frame 104 32 32 32 + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/subs.qc b/r17/Revamped src/Revamped QC/Primeqc4/subs.qc new file mode 100755 index 00000000..050aa88e Binary files /dev/null and b/r17/Revamped src/Revamped QC/Primeqc4/subs.qc differ diff --git a/r17/Revamped src/Revamped QC/Primeqc4/tarbaby.qc b/r17/Revamped src/Revamped QC/Primeqc4/tarbaby.qc new file mode 100755 index 00000000..15b2b6ec --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/tarbaby.qc @@ -0,0 +1,222 @@ +/* +============================================================================== + +BLOB + +============================================================================== +*/ + +$cd id1/models/tarbaby +$origin 0 0 24 +$base base + +$skin skin + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 +$frame walk11 walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19 +$frame walk20 walk21 walk22 walk23 walk24 walk25 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 run13 +$frame run14 run15 run16 run17 run18 run19 run20 run21 run22 run23 +$frame run24 run25 + +$frame jump1 jump2 jump3 jump4 jump5 jump6 + +$frame fly1 fly2 fly3 fly4 + +$frame exp + +void() tbaby_stand1 =[ $walk1, tbaby_stand1 ] {ai_stand();}; + +void() tbaby_hang1 =[ $walk1, tbaby_hang1 ] {ai_stand();}; + +void() tbaby_walk1 =[ $walk1, tbaby_walk2 ] {ai_turn();}; +void() tbaby_walk2 =[ $walk2, tbaby_walk3 ] {ai_turn();}; +void() tbaby_walk3 =[ $walk3, tbaby_walk4 ] {ai_turn();}; +void() tbaby_walk4 =[ $walk4, tbaby_walk5 ] {ai_turn();}; +void() tbaby_walk5 =[ $walk5, tbaby_walk6 ] {ai_turn();}; +void() tbaby_walk6 =[ $walk6, tbaby_walk7 ] {ai_turn();}; +void() tbaby_walk7 =[ $walk7, tbaby_walk8 ] {ai_turn();}; +void() tbaby_walk8 =[ $walk8, tbaby_walk9 ] {ai_turn();}; +void() tbaby_walk9 =[ $walk9, tbaby_walk10 ] {ai_turn();}; +void() tbaby_walk10 =[ $walk10, tbaby_walk11 ] {ai_turn();}; +void() tbaby_walk11 =[ $walk11, tbaby_walk12 ] {ai_walk(2);}; +void() tbaby_walk12 =[ $walk12, tbaby_walk13 ] {ai_walk(2);}; +void() tbaby_walk13 =[ $walk13, tbaby_walk14 ] {ai_walk(2);}; +void() tbaby_walk14 =[ $walk14, tbaby_walk15 ] {ai_walk(2);}; +void() tbaby_walk15 =[ $walk15, tbaby_walk16 ] {ai_walk(2);}; +void() tbaby_walk16 =[ $walk16, tbaby_walk17 ] {ai_walk(2);}; +void() tbaby_walk17 =[ $walk17, tbaby_walk18 ] {ai_walk(2);}; +void() tbaby_walk18 =[ $walk18, tbaby_walk19 ] {ai_walk(2);}; +void() tbaby_walk19 =[ $walk19, tbaby_walk20 ] {ai_walk(2);}; +void() tbaby_walk20 =[ $walk20, tbaby_walk21 ] {ai_walk(2);}; +void() tbaby_walk21 =[ $walk21, tbaby_walk22 ] {ai_walk(2);}; +void() tbaby_walk22 =[ $walk22, tbaby_walk23 ] {ai_walk(2);}; +void() tbaby_walk23 =[ $walk23, tbaby_walk24 ] {ai_walk(2);}; +void() tbaby_walk24 =[ $walk24, tbaby_walk25 ] {ai_walk(2);}; +void() tbaby_walk25 =[ $walk25, tbaby_walk1 ] {ai_walk(2);}; + +void() tbaby_run1 =[ $run1, tbaby_run2 ] {ai_face();}; +void() tbaby_run2 =[ $run2, tbaby_run3 ] {ai_face();}; +void() tbaby_run3 =[ $run3, tbaby_run4 ] {ai_face();}; +void() tbaby_run4 =[ $run4, tbaby_run5 ] {ai_face();}; +void() tbaby_run5 =[ $run5, tbaby_run6 ] {ai_face();}; +void() tbaby_run6 =[ $run6, tbaby_run7 ] {ai_face();}; +void() tbaby_run7 =[ $run7, tbaby_run8 ] {ai_face();}; +void() tbaby_run8 =[ $run8, tbaby_run9 ] {ai_face();}; +void() tbaby_run9 =[ $run9, tbaby_run10 ] {ai_face();}; +void() tbaby_run10 =[ $run10, tbaby_run11 ] {ai_face();}; +void() tbaby_run11 =[ $run11, tbaby_run12 ] {ai_run(2);}; +void() tbaby_run12 =[ $run12, tbaby_run13 ] {ai_run(2);}; +void() tbaby_run13 =[ $run13, tbaby_run14 ] {ai_run(2);}; +void() tbaby_run14 =[ $run14, tbaby_run15 ] {ai_run(2);}; +void() tbaby_run15 =[ $run15, tbaby_run16 ] {ai_run(2);}; +void() tbaby_run16 =[ $run16, tbaby_run17 ] {ai_run(2);}; +void() tbaby_run17 =[ $run17, tbaby_run18 ] {ai_run(2);}; +void() tbaby_run18 =[ $run18, tbaby_run19 ] {ai_run(2);}; +void() tbaby_run19 =[ $run19, tbaby_run20 ] {ai_run(2);}; +void() tbaby_run20 =[ $run20, tbaby_run21 ] {ai_run(2);}; +void() tbaby_run21 =[ $run21, tbaby_run22 ] {ai_run(2);}; +void() tbaby_run22 =[ $run22, tbaby_run23 ] {ai_run(2);}; +void() tbaby_run23 =[ $run23, tbaby_run24 ] {ai_run(2);}; +void() tbaby_run24 =[ $run24, tbaby_run25 ] {ai_run(2);}; +void() tbaby_run25 =[ $run25, tbaby_run1 ] {ai_run(2);}; + + +//============================================================================ + + +void() tbaby_jump1; + +void() Tar_JumpTouch = +{ + local float ldmg; + + if (other.takedamage && other.classname != self.classname) + { + if ( vlen(self.velocity) > 400 ) + { + ldmg = 10 + 10*random(); + T_Damage (other, self, self, ldmg); + sound (self, CHAN_WEAPON, "blob/hit1.wav", 1, ATTN_NORM); + } + } + else + sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM); + + + if (!checkbottom(self)) + { + if (self.flags & FL_ONGROUND) + { // jump randomly to not get hung up +//dprint ("popjump\n"); + self.touch = SUB_Null; + self.think = tbaby_run1; + self.movetype = MOVETYPE_STEP; + self.nextthink = time + 0.1; + +// self.velocity_x = (random() - 0.5) * 600; +// self.velocity_y = (random() - 0.5) * 600; +// self.velocity_z = 200; +// self.flags = self.flags - FL_ONGROUND; + } + return; // not on ground yet + } + + self.touch = SUB_Null; + self.think = tbaby_jump1; + self.nextthink = time + 0.1; +}; + +void() tbaby_jump5; + +void() tbaby_fly1 =[ $fly1, tbaby_fly2 ] {}; +void() tbaby_fly2 =[ $fly2, tbaby_fly3 ] {}; +void() tbaby_fly3 =[ $fly3, tbaby_fly4 ] {}; +void() tbaby_fly4 =[ $fly4, tbaby_fly1 ] { +self.cnt = self.cnt + 1; +if (self.cnt == 4) +{ +//dprint ("spawn hop\n"); +tbaby_jump5 (); +} +}; + +void() tbaby_jump1 =[ $jump1, tbaby_jump2 ] {ai_face();}; +void() tbaby_jump2 =[ $jump2, tbaby_jump3 ] {ai_face();}; +void() tbaby_jump3 =[ $jump3, tbaby_jump4 ] {ai_face();}; +void() tbaby_jump4 =[ $jump4, tbaby_jump5 ] {ai_face();}; +void() tbaby_jump5 =[ $jump5, tbaby_jump6 ] +{ + self.movetype = MOVETYPE_BOUNCE; + self.touch = Tar_JumpTouch; + makevectors (self.angles); + self.origin_z = self.origin_z + 1; + self.velocity = v_forward * 600 + '0 0 200'; + self.velocity_z = self.velocity_z + random()*150; + if (self.flags & FL_ONGROUND) + self.flags = self.flags - FL_ONGROUND; + self.cnt = 0; +}; +void() tbaby_jump6 =[ $jump6,tbaby_fly1 ] {}; + + + +//============================================================================= + +void() tbaby_die1 =[ $exp, tbaby_die2 ] { +self.takedamage = DAMAGE_NO; +}; +void() tbaby_die2 =[ $exp, tbaby_run1 ] +{ + T_RadiusDamage (self, self, 120, world); + + sound (self, CHAN_VOICE, "blob/death1.wav", 1, ATTN_NORM); + self.origin = self.origin - 8*normalize(self.velocity); + + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_TAREXPLOSION); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); + + CreateExplosion (self.origin); +}; + +//============================================================================= + + +/*QUAKED monster_tarbaby (1 0 0) (-16 -16 -24) (16 16 24) Ambush +*/ +void() monster_tarbaby = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/tarbaby.mdl"); + + precache_sound2 ("blob/death1.wav"); + precache_sound2 ("blob/hit1.wav"); + precache_sound2 ("blob/land1.wav"); + precache_sound2 ("blob/sight1.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/tarbaby.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 80; + + self.th_stand = tbaby_stand1; + self.th_walk = tbaby_walk1; + self.th_run = tbaby_run1; + self.th_missile = tbaby_jump1; + self.th_melee = tbaby_jump1; + self.th_die = tbaby_die1; + + walkmonster_start (); +}; + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/triggers.qc b/r17/Revamped src/Revamped QC/Primeqc4/triggers.qc new file mode 100755 index 00000000..03fe4071 --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/triggers.qc @@ -0,0 +1,641 @@ + +entity s; + + +void() trigger_reactivate = +{ + self.solid = SOLID_TRIGGER; +}; + +//============================================================================= + +float SPAWNFLAG_NOMESSAGE = 1; +float SPAWNFLAG_NOTOUCH = 1; + +// the wait time has passed, so set back up for another activation +void() multi_wait = +{ + if (self.max_health) + { + self.health = self.max_health; + self.takedamage = DAMAGE_YES; + self.solid = SOLID_BBOX; + } +}; + + +// the trigger was just touched/killed/used +// self.enemy should be set to the activator so it can be held through a delay +// so wait for the delay time before firing +void() multi_trigger = +{ + if (self.nextthink > time) + { + return; // allready been triggered + } + + if (self.classname == "trigger_secret") + { + if (self.enemy.classname != "player") + return; + found_secrets = found_secrets + 1; + WriteByte (MSG_ALL, SVC_FOUNDSECRET); + } + + if (self.noise) + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + +// don't trigger again until reset + self.takedamage = DAMAGE_NO; + + activator = self.enemy; + + SUB_UseTargets(); + + if (self.wait > 0) + { + self.think = multi_wait; + self.nextthink = time + self.wait; + } + else + { // we can't just remove (self) here, because this is a touch function + // called wheil C code is looping through area links... + self.touch = SUB_Null; + self.nextthink = time + 0.1; + self.think = SUB_Remove; + } +}; + +void() multi_killed = +{ + self.enemy = damage_attacker; + multi_trigger(); +}; + +void() multi_use = +{ + self.enemy = activator; + multi_trigger(); +}; + +void() multi_touch = +{ + if (other.classname != "player") + return; + +// if the trigger has an angles field, check player's facing direction + if (self.movedir != '0 0 0') + { + makevectors (other.angles); + if (v_forward * self.movedir < 0) + return; // not facing the right way + } + + self.enemy = other; + multi_trigger (); +}; + +/*QUAKED trigger_multiple (.5 .5 .5) ? notouch +Variable sized repeatable trigger. Must be targeted at one or more entities. If "health" is set, the trigger must be killed to activate each time. +If "delay" is set, the trigger waits some time after activating before firing. +"wait" : Seconds between triggerings. (.2 default) +If notouch is set, the trigger is only fired by other entities, not by touching. +NOTOUCH has been obsoleted by trigger_relay! +sounds +1) secret +2) beep beep +3) large switch +4) +set "message" to text string +*/ +void() trigger_multiple = +{ + if (self.sounds == 1) + { + precache_sound ("misc/secret.wav"); + self.noise = "misc/secret.wav"; + } + else if (self.sounds == 2) + { + precache_sound ("misc/talk.wav"); + self.noise = "misc/talk.wav"; + } + else if (self.sounds == 3) + { + precache_sound ("misc/trigger1.wav"); + self.noise = "misc/trigger1.wav"; + } + + if (!self.wait) + self.wait = 0.2; + self.use = multi_use; + + InitTrigger (); + + if (self.health) + { + if (self.spawnflags & SPAWNFLAG_NOTOUCH) + objerror ("health and notouch don't make sense\n"); + self.max_health = self.health; + self.th_die = multi_killed; + self.takedamage = DAMAGE_YES; + self.solid = SOLID_BBOX; + setorigin (self, self.origin); // make sure it links into the world + } + else + { + if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) ) + { + self.touch = multi_touch; + } + } +}; + + +/*QUAKED trigger_once (.5 .5 .5) ? notouch +Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching +"targetname". If "health" is set, the trigger must be killed to activate. +If notouch is set, the trigger is only fired by other entities, not by touching. +if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired. +if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0. +sounds +1) secret +2) beep beep +3) large switch +4) +set "message" to text string +*/ +void() trigger_once = +{ + self.wait = -1; + trigger_multiple(); +}; + +//============================================================================= + +/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) +This fixed size trigger cannot be touched, it can only be fired by other events. It can contain killtargets, targets, delays, and messages. +*/ +void() trigger_relay = +{ + self.use = SUB_UseTargets; +}; + + +//============================================================================= + +/*QUAKED trigger_secret (.5 .5 .5) ? +secret counter trigger +sounds +1) secret +2) beep beep +3) +4) +set "message" to text string +*/ +void() trigger_secret = +{ + total_secrets = total_secrets + 1; + self.wait = -1; + if (!self.message) + self.message = "You found a secret area!"; + if (!self.sounds) + self.sounds = 1; + + if (self.sounds == 1) + { + precache_sound ("misc/secret.wav"); + self.noise = "misc/secret.wav"; + } + else if (self.sounds == 2) + { + precache_sound ("misc/talk.wav"); + self.noise = "misc/talk.wav"; + } + + trigger_multiple (); +}; + +//============================================================================= + + +void() counter_use = +{ + + self.count = self.count - 1; + if (self.count < 0) + return; + + if (self.count != 0) + { + if (activator.classname == "player" + && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0) + { + if (self.count >= 4) + centerprint (activator, "There are more to go..."); + else if (self.count == 3) + centerprint (activator, "Only 3 more to go..."); + else if (self.count == 2) + centerprint (activator, "Only 2 more to go..."); + else + centerprint (activator, "Only 1 more to go..."); + } + return; + } + + if (activator.classname == "player" + && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0) + centerprint(activator, "Sequence completed!"); + self.enemy = activator; + multi_trigger (); +}; + +/*QUAKED trigger_counter (.5 .5 .5) ? nomessage +Acts as an intermediary for an action that takes multiple inputs. + +If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished. + +After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself. +*/ +void() trigger_counter = +{ + self.wait = -1; + if (!self.count) + self.count = 2; + + self.use = counter_use; +}; + + +/* +============================================================================== + +TELEPORT TRIGGERS + +============================================================================== +*/ + +float PLAYER_ONLY = 1; +float SILENT = 2; + +void() play_teleport = +{ + local float v; + local string tmpstr; + + v = random() * 5; + if (v < 1) + tmpstr = "misc/r_tele1.wav"; + else if (v < 2) + tmpstr = "misc/r_tele2.wav"; + else if (v < 3) + tmpstr = "misc/r_tele3.wav"; + else if (v < 4) + tmpstr = "misc/r_tele4.wav"; + else + tmpstr = "misc/r_tele5.wav"; + + sound (self, CHAN_VOICE, tmpstr, 1, ATTN_NORM); + remove (self); +}; + +void(vector org) spawn_tfog = +{ + s = spawn (); + s.origin = org; + s.nextthink = time + 0.2; + s.think = play_teleport; + + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_TELEPORT); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); +}; + + +void() tdeath_touch = +{ + if (other == self.owner) + return; + +// frag anyone who teleports in on top of an invincible player + if (other.classname == "player") + { + if (other.invincible_finished > time) + self.classname = "teledeath2"; + if (self.owner.classname != "player") + { // other monsters explode themselves + T_Damage (self.owner, self, self, 50000); + return; + } + + } + + if (other.health) + { + T_Damage (other, self, self, 50000); + } +}; + + +void(vector org, entity death_owner) spawn_tdeath = +{ +local entity death; + + death = spawn(); + death.classname = "teledeath"; + death.movetype = MOVETYPE_NONE; + death.solid = SOLID_TRIGGER; + death.angles = '0 0 0'; + setsize (death, death_owner.mins - '1 1 1', death_owner.maxs + '1 1 1'); + setorigin (death, org); + death.touch = tdeath_touch; + death.nextthink = time + 0.2; + death.think = SUB_Remove; + death.owner = death_owner; + + force_retouch = 2; // make sure even still objects get hit +}; + +void() teleport_touch = +{ +local entity t; +local vector org; + + if (self.targetname) + { + if (self.nextthink < time) + { + return; // not fired yet + } + } + + if (self.spawnflags & PLAYER_ONLY) + { + if (other.classname != "player") + return; + } + +// only teleport living creatures + if (other.health <= 0 || other.solid != SOLID_SLIDEBOX) + return; + + SUB_UseTargets (); + +// put a tfog where the player was + spawn_tfog (other.origin); + + t = find (world, targetname, self.target); + if (!t) + objerror ("couldn't find target"); + +// spawn a tfog flash in front of the destination + makevectors (t.mangle); + org = t.origin + 32 * v_forward; + + spawn_tfog (org); + spawn_tdeath(t.origin, other); + +// move the player and lock him down for a little while + if (!other.health) + { + other.origin = t.origin; + other.velocity = (v_forward * other.velocity_x) + (v_forward * other.velocity_y); + return; + } + + setorigin (other, t.origin); + other.angles = t.mangle; + if (other.classname == "player") + { + other.fixangle = 1; // turn this way immediately + other.teleport_time = time + 0.7; + if (other.flags & FL_ONGROUND) + other.flags = other.flags - FL_ONGROUND; + other.velocity = v_forward * 300; + } + other.flags = other.flags - other.flags & FL_ONGROUND; +}; + +/*QUAKED info_teleport_destination (.5 .5 .5) (-8 -8 -8) (8 8 32) +This is the destination marker for a teleporter. It should have a "targetname" field with the same value as a teleporter's "target" field. +*/ +void() info_teleport_destination = +{ +// this does nothing, just serves as a target spot + self.mangle = self.angles; + self.angles = '0 0 0'; + self.model = ""; + self.origin = self.origin + '0 0 27'; + if (!self.targetname) + objerror ("no targetname"); +}; + +void() teleport_use = +{ + self.nextthink = time + 0.2; + force_retouch = 2; // make sure even still objects get hit + self.think = SUB_Null; +}; + +/*QUAKED trigger_teleport (.5 .5 .5) ? PLAYER_ONLY SILENT +Any object touching this will be transported to the corresponding info_teleport_destination entity. You must set the "target" field, and create an object with a "targetname" field that matches. + +If the trigger_teleport has a targetname, it will only teleport entities when it has been fired. +*/ +void() trigger_teleport = +{ + local vector o; + + InitTrigger (); + self.touch = teleport_touch; + // find the destination + if (!self.target) + objerror ("no target"); + self.use = teleport_use; + + if (!(self.spawnflags & SILENT)) + { + precache_sound ("ambience/hum1.wav"); + o = (self.mins + self.maxs)*0.5; + ambientsound (o, "ambience/hum1.wav",0.5 , ATTN_STATIC); + } +}; + +/* +============================================================================== + +trigger_setskill + +============================================================================== +*/ + +void() trigger_skill_touch = +{ + if (other.classname != "player") + return; + + cvar_set ("skill", self.message); +}; + +/*QUAKED trigger_setskill (.5 .5 .5) ? +sets skill level to the value of "message". +Only used on start map. +*/ +void() trigger_setskill = +{ + InitTrigger (); + self.touch = trigger_skill_touch; +}; + + +/* +============================================================================== + +ONLY REGISTERED TRIGGERS + +============================================================================== +*/ + +void() trigger_onlyregistered_touch = +{ + if (other.classname != "player") + return; + if (self.attack_finished > time) + return; + + self.attack_finished = time + 2; + if (cvar("registered")) + { + self.message = ""; + SUB_UseTargets (); + remove (self); + } + else + { + if (self.message != "") + { + centerprint (other, self.message); + sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM); + } + } +}; + +/*QUAKED trigger_onlyregistered (.5 .5 .5) ? +Only fires if playing the registered version, otherwise prints the message +*/ +void() trigger_onlyregistered = +{ + precache_sound ("misc/talk.wav"); + InitTrigger (); + self.touch = trigger_onlyregistered_touch; +}; + +//============================================================================ + +void() hurt_on = +{ + self.solid = SOLID_TRIGGER; + self.nextthink = -1; +}; + +void() hurt_touch = +{ + if (other.takedamage) + { + self.solid = SOLID_NOT; + T_Damage (other, self, self, self.dmg); + self.think = hurt_on; + self.nextthink = time + 1; + } + + return; +}; + +/*QUAKED trigger_hurt (.5 .5 .5) ? +Any object touching this will be hurt +set dmg to damage amount +defalt dmg = 5 +*/ +void() trigger_hurt = +{ + InitTrigger (); + self.touch = hurt_touch; + if (!self.dmg) + self.dmg = 5; +}; + +//============================================================================ + +float PUSH_ONCE = 1; + +void() trigger_push_touch = +{ + if (other.classname == "grenade") + other.velocity = self.speed * self.movedir * 10; + else if (other.health > 0) + { + 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); + } + } + } + if (self.spawnflags & PUSH_ONCE) + remove(self); +}; + + +/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE +Pushes the player +*/ +void() trigger_push = +{ + InitTrigger (); + precache_sound ("ambience/windfly.wav"); + self.touch = trigger_push_touch; + if (!self.speed) + self.speed = 1000; +}; + +//============================================================================ + +void() trigger_monsterjump_touch = +{ + if ( other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER ) + return; + +// set XY even if not on ground, so the jump will clear lips + other.velocity_x = self.movedir_x * self.speed; + other.velocity_y = self.movedir_y * self.speed; + + if ( !(other.flags & FL_ONGROUND) ) + return; + + other.flags = other.flags - FL_ONGROUND; + + other.velocity_z = self.height; +}; + +/*QUAKED trigger_monsterjump (.5 .5 .5) ? +Walking monsters that touch this will jump in the direction of the trigger's angle +"speed" default to 200, the speed thrown forward +"height" default to 200, the speed thrown upwards +*/ +void() trigger_monsterjump = +{ + if (!self.speed) + self.speed = 200; + if (!self.height) + self.height = 200; + if (self.angles == '0 0 0') + self.angles = '0 360 0'; + InitTrigger (); + self.touch = trigger_monsterjump_touch; +}; + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/v_shot.mdl b/r17/Revamped src/Revamped QC/Primeqc4/v_shot.mdl new file mode 100755 index 00000000..02195715 Binary files /dev/null and b/r17/Revamped src/Revamped QC/Primeqc4/v_shot.mdl differ diff --git a/r17/Revamped src/Revamped QC/Primeqc4/weapons.qc b/r17/Revamped src/Revamped QC/Primeqc4/weapons.qc new file mode 100755 index 00000000..5217499c --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/weapons.qc @@ -0,0 +1,2478 @@ +/* +*/ + +void (entity targ, entity inflictor, entity attacker, float damage) T_Damage; +void () player_run; +void(entity inflictor, entity attacker, float radius, entity ignore) T_RadiusDamage; +void() SuperDamageSound; + +// called by worldspawn +void() W_Precache = +{ + precache_sound ("weapons/r_exp3.wav"); // new rocket explosion + precache_sound ("weapons/rocket1i.wav"); // spike gun + precache_sound ("weapons/sgun1.wav"); + precache_sound ("weapons/guncock.wav"); // player shotgun + //precache_sound ("weapons/ric1.wav"); // ricochet (used in c code) + //precache_sound ("weapons/ric2.wav"); // ricochet (used in c code) + //precache_sound ("weapons/ric3.wav"); // ricochet (used in c code) + //precache_sound ("weapons/spike2.wav"); // super spikes + precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code) + //precache_sound ("weapons/grenade.wav"); // grenade launcher + precache_sound ("weapons/bounce.wav"); // grenade bounce + precache_sound ("weapons/shotgn2.wav"); // super shotgun + precache_sound ("weapons/sniper.wav"); // sniper + precache_model ("progs/blast.spr"); //blaster bullet sprite. + precache_model ("progs/sniper.mdl"); //beam for the Sniper blaster + precache_model ("progs/ric_beam.mdl"); //Beam for The richochet blaster + precache_model ("progs/null.spr"); + precache_model ("progs/body.spr"); + + //Morphball sounds + precache_sound ("weapons/boost.wav"); + precache_sound ("weapons/mb_bomb.wav"); // Morphball lays a bomb + precache_sound ("weapons/mb_explode.wav"); + precache_sound ("weapons/morphball.wav"); + precache_sound ("weapons/mb_bomb.wav"); + + //Footsteps + precache_sound ("steps/foot1.wav"); + precache_sound ("steps/foot2.wav"); + precache_sound ("steps/foot3.wav"); + precache_sound ("steps/foot4.wav"); + + //Transform Sounds + precache_sound ("weapons/blaster_transform.wav"); + precache_sound ("weapons/rocket_transform.wav"); + + //Effects + //Muzzleflashes + precache_model ("progs/blaster_muzzle.spr"); + precache_model ("progs/ric_muzzle.spr"); + precache_model ("progs/sniper_muzzle.spr"); + precache_model ("progs/splaser_muzzle.spr"); + +}; + +float() crandom = +{ + return 2*(random() - 0.5); +}; + +/* +================ +W_FireAxe +================ +*/ +void() W_FireAxe = +{ + local vector source; + local vector org; + + makevectors (self.v_angle); + source = self.origin + '0 0 16'; + traceline (source, source + v_forward*64, FALSE, self); + if (trace_fraction == 1.0) + return; + + org = trace_endpos - v_forward*4; + + if (trace_ent.takedamage) + { + trace_ent.axhitme = 1; + SpawnBlood (org, '0 0 0', 20); + T_Damage (trace_ent, self, self, 20); + } + else + { // hit wall + sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM); + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_GUNSHOT); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); + } +}; + + +//============================================================================ + + +vector() wall_velocity = +{ + local vector vel; + + vel = normalize (self.velocity); + vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5)); + vel = vel + 2*trace_plane_normal; + vel = vel * 200; + + return vel; +}; + + +/* +============================================================================== + +MULTI-DAMAGE + +Collects multiple small damages into a single damage + +============================================================================== +*/ + +entity multi_ent; +vector puff_org; +float multi_damage; + +void() ClearMultiDamage = +{ + multi_ent = world; + multi_damage = 0; +}; + +void() ApplyMultiDamage = +{ + if (!multi_ent) + return; + T_Damage (multi_ent, self, self, multi_damage); +}; + +void(entity hit, float damage) AddMultiDamage = +{ + if (!hit) + return; + + if (hit != multi_ent) + { + ApplyMultiDamage (); + multi_damage = damage; + multi_ent = hit; + } + else + multi_damage = multi_damage + damage; +}; + +/* +>>>>>>>>>>>>>>>>>>>>>>>>> +Touch Functions and Exlosions for Damage. +-I hate how all the Bullet damage functions are strewn around everywhere. This is where you Will find the Bullet-damage +For All the weapons. And I don't wanna create a new qc because I have do define Crap, and then Go there to edit. +it is Just fine right here. +<<<<<<<<<<<<<<<<<<<<<<<<< +*/ +//For something.... Just Don't care to Go look. Find it yourself in combat.qc + +vector(entity proj) bounce_off_wall = // borrowing +{ + local vector vec; + local float backoff, change; +// get the trace_plane_normal of the surface we hit + makevectors (proj.angles); + v_forward_z = v_forward_z * -1; + traceline (proj.origin, proj.origin + v_forward*64, FALSE, proj); + + if (trace_fraction == 1) + return proj.velocity; + +// the entity's velocity is not what we want, so set default + proj.velocity = v_forward * 2000;//proj.old_velocity; + +// calculate dot product + backoff = (proj.velocity * trace_plane_normal); + backoff = backoff * 1.5; + +// finish + change = trace_plane_normal_x * backoff; + vec_x = proj.velocity_x - change; + + if (vec_x > -0.1 && vec_x < 0.1) + vec_x = 0; + + change = trace_plane_normal_y * backoff; + vec_y = proj.velocity_y - change; + + if (vec_y > -0.1 && vec_y < 0.1) + vec_y = 0; + + change = trace_plane_normal_z * backoff; + vec_z = proj.velocity_z - change; + + if (vec_z > -0.1 && vec_z < 0.1) + vec_z = 0; +// set correct angles of our new velocity + sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); + proj.angles = vectoangles (vec); + // this is required to make downward slopes not stop the projectile + proj.flags = proj.flags - ( proj.flags & FL_ONGROUND ); + return vec; +} +void () bounce_a = +{ + self.velocity = bounce_off_wall( self ); +}; + +void () Bounce_Off_Walls = +{ + self.nextthink = time; + self.think = bounce_a; + + if (self.velocity == '0 0 0') + remove (self); +}; + +/* +============================= +RIC TOUCH 0 +============================ +*/ +void () ric_touch = +{ + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 10); + } + else if (self.lives > 0) { + particle (self.origin, '0 0 0', 179, 20); + Bounce_Off_Walls (); + self.lives -= 1; + return; + } + + remove(self); +}; +/* +============================= +RIC TOUCH 1 +============================ +*/ +void () ric_touch_1 = +{ + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (20); + T_Damage (other, self, self.owner, 15); + } + else if (self.lives > 0) { + particle (self.origin, '0 0 0', 179, 20); + Bounce_Off_Walls (); + self.lives -= 1; + return; + } + + remove(self); +}; +/* +============================= +RIC TOUCH 2 +============================ +*/ +void () ric_touch_2 = +{ + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (25); + T_Damage (other, self, self.owner, 20); + } + else if (self.lives > 0) { + particle (self.origin, '0 0 0', 179, 20); + Bounce_Off_Walls (); + self.lives -= 1; + return; + } + + remove(self); +}; +/* +============================= +RIC TOUCH 3 +============================ +*/ +void () ric_touch_3 = +{ + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (25); + T_Damage (other, self, self.owner, 25); + } + else if (self.lives > 0) { + particle (self.origin, '0 0 0', 179, 20); + Bounce_Off_Walls (); + self.lives -= 1; + return; + } + + remove(self); +}; +/* +========================================== +ROCKET LAUNCHER 0 +========================================== +*/ +void() Rocket_Explode0 = +{ + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + T_RadiusDamage (self, self.owner, 120, other); + + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion (self.origin); + remove(self); +}; +/* +========================================== +ROCKET LAUNCHER 1 +========================================== +*/ +void() Rocket_Explode1 = +{ + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + T_RadiusDamage (self, self.owner, 140, other); + + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion (self.origin); + remove(self); +}; +/* +========================================== +ROCKET LAUNCHER 2 +========================================== +*/ +void() Rocket_Explode2 = +{ + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + T_RadiusDamage (self, self.owner, 160, other); + + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion (self.origin); + remove(self); +}; +/* +========================================== +ROCKET LAUNCHER 3 +========================================== +*/ +void() Rocket_Explode3 = +{ + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + T_RadiusDamage (self, self.owner, 190, other); + + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion (self.origin); + remove(self); +}; +void() T_MissileTouch = +{ + local float damg; + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + + damg = 40 + random()*10; + + if (other.health) + { + T_Damage (other, self, self.owner, damg ); + } + + // don't do radius damage to the other, because all the damage + // was done in the impact + T_RadiusDamage (self, self.owner, 120, other); + +// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion (self.origin); + remove(self); +}; + +/* +============================= +Magma explode +============================ +*/ +void() magmaexplode = +{ + T_RadiusDamage (self, self.owner, 120, other); + +// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion(self.origin); + remove(self); +}; +/* +============================= +Splaser Beam touch +============================ +*/ +void(vector org) SplaserTouch = +{ + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 9); + + + } + else + { + particle (self.origin, '0 0 0', 149, 20); + puff_org = self.origin; + remove(self); + } +}; +/* +============================= +MAGMA TOUCH +============================ +*/ +void(vector org) magma_touch = +{ + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 20); + remove(self); + } + else + { + puff_org = self.origin; + self.think = magmaexplode; + self.nextthink = time + 5; + } +}; +/* +============================= +BLASTER TOUCH 0 +============================ +*/ +void(vector org) BlasterTouch = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 7); + + + } + else + { + particle (self.origin, '0 0 0', 214, 20); + puff_org = self.origin; + } + remove(self); +}; +/* +============================= +BLASTER TOUCH 1 +============================ +*/ +void(vector org) BlasterTouch1 = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 15); + + + } + else + { + particle (self.origin, '0 0 0', 214, 20); + puff_org = self.origin; + } + remove(self); +}; +/* +============================= +BLASTER TOUCH 2 +============================ +*/ +void(vector org) BlasterTouch2 = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 36); + } + else + { + particle (self.origin, '0 0 0', 214, 20); + puff_org = self.origin; + } + remove(self); +}; +//The final Blast product for Blaster. I may fix up into 1 function, But for now, "self" is the projectile. +//And other doesn't work. Nor does other.owner + +void(vector org) BlasterTouch3 = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 30); + } + else + { + particle (self.origin, '0 0 0', 214, 20); + puff_org = self.origin; + } + remove(self); +}; + +/* +============================= +SNIPER TOUCH +============================ +*/ +void () SniperTouch = +{ + local vector p_a, p_b; + local float zdif; + + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + p_a_z = self.origin_z; + p_b_z = other.origin_z; + + zdif = vlen(p_a - p_b); + //_bprint(ftos(zdif),"\n"); + if (zdif > 20) + { + T_Damage (other, self, self.owner, 150); + spawn_touchblood (18); + } + else + { + T_Damage (other, self, self.owner, 40); + spawn_touchblood (18); + } + } + else + { + particle (self.origin, '0 0 0', 251, 40); + puff_org = self.origin; + } + remove(self); +}; +/* +============================= +Morphball Exploding +============================ +*/ +void() BombExplode = +{ + local float damg; + + damg = 16; + + if (other.health) + { + if (other.classname == "player") + damg = damg = 0; + T_Damage (other, self, self.owner, damg ); + } + + T_RadiusDamage (self, self.owner, 50, other); + self.origin = self.origin - 8*normalize(self.velocity); + CreateExplosion (self.origin); + sound (self, CHAN_WEAPON, "weapons/mb_explode.wav", 1, ATTN_NORM); + remove(self); +}; + +/* +===================== +End of Touch Functions +===================== +*/ + +/* +============================================================================== + +BULLETS + +============================================================================== +*/ + + + +/* +================ +TraceAttack +================ +*/ +void(float damage, vector dir) TraceAttack = +{ + local vector vel, org; + + vel = normalize(dir + v_up*crandom() + v_right*crandom()); + vel = vel + 2*trace_plane_normal; + vel = vel * 200; + + org = trace_endpos - dir*4; + + if (trace_ent.takedamage) + { + SpawnBlood (org, vel*0.2, damage); + AddMultiDamage (trace_ent, damage); + } + else + { + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_GUNSHOT); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); + } +}; + +/* +================ +FireBullets + +Used by shotgun, super shotgun, and enemy soldier firing +Go to the trouble of combining multiple pellets into a single damage call. +================ +*/ +void(float shotcount, vector dir, vector spread) FireBullets = +{ + local vector direction; + local vector src; + + makevectors(self.v_angle); + + src = self.origin + v_forward*10; + src_z = self.absmin_z + self.size_z * 0.7; + + ClearMultiDamage (); + while (shotcount > 0) + { + direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + + traceline (src, src + direction*2048, FALSE, self); + if (trace_fraction != 1.0) + TraceAttack (4, direction); + + shotcount = shotcount - 1; + } + ApplyMultiDamage (); +}; + + +/* +======================== +MAGMA +======================== +*/ +void() W_FireMagma = +{ + local entity sniper; + blaster_flash(); + self.currentammo = self.ammo_lava = self.ammo_lava -= 1; + sound (self, CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM); + self.punchangle_x = -3; + + sniper = spawn (); + sniper.owner = self; + sniper.movetype = MOVETYPE_BOUNCE; + sniper.solid = SOLID_BBOX; + sniper.classname = "Magma"; + +// Set The Sniper bullets speed + + makevectors (self.v_angle); + sniper.velocity = aim(self, 1000); + sniper.velocity = sniper.velocity * 1000; + sniper.angles = vectoangles(sniper.velocity); + + sniper.touch = magma_touch; + + setmodel (sniper, "progs/lavaball.mdl"); + setsize (sniper, '0 0 0', '0 0 0'); + setorigin (sniper, self.origin + v_forward*10 + '0 0 16'); +}; +/* +======================== +SPLASER +======================== +*/ +void() W_FireSplaser = +{ + local entity sniper; + blaster_flash(); + self.currentammo = self.ammo_nails = self.ammo_nails -= 1; + sound (self, CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM); + self.punchangle_x = -3; + + sniper = spawn (); + sniper.owner = self; + sniper.movetype = MOVETYPE_FLYMISSILE; + sniper.solid = SOLID_BBOX; + sniper.classname = "splaser"; + +// Set The Sniper bullets speed + + makevectors (self.v_angle); + sniper.velocity = aim(self, 1000); + sniper.velocity = sniper.velocity * 2000; //This is so It is fast Like a sniper Projectile + sniper.angles = vectoangles(sniper.velocity); + + sniper.touch = SplaserTouch; + +// set missile duration + sniper.nextthink = time + 5; + sniper.think = SUB_Remove; + sniper.frame += 1; + + setmodel (sniper, "progs/splaser_muzzle.spr"); + sniper.effects = EF_DIMLIGHT; + setsize (sniper, '0 0 0', '0 0 0'); + setorigin (sniper, self.origin + v_forward*10 + '0 0 16'); +}; +/* +======================== +SNIPER +======================== +*/ +void() W_FireSniper = +{ + local entity sniper; + blaster_flash(); + self.currentammo = self.ammo_sniper = self.ammo_sniper - 1; + sound (self, CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM); + self.punchangle_x = -3; + + sniper = spawn (); + sniper.owner = self; + sniper.movetype = MOVETYPE_FLYMISSILE; + sniper.solid = SOLID_BBOX; + sniper.classname = "Sniper"; + +// Set The Sniper bullets speed + + makevectors (self.v_angle); + sniper.velocity = aim(self, 1000); + sniper.velocity = sniper.velocity * 10000; //This is so It is fast Like a sniper Projectile + sniper.angles = vectoangles(sniper.velocity); + + sniper.touch = SniperTouch; + +// set missile duration + sniper.nextthink = time + 5; + sniper.think = SUB_Remove; + sniper.frame += 1; + + setmodel (sniper, "progs/sniper.mdl"); + sniper.effects = EF_DIMLIGHT; + setsize (sniper, '0 0 0', '0 0 0'); + setorigin (sniper, self.origin + v_forward*30 + '0 0 16'); +}; +/* +================ +BLASTER +================ +*/ +void() W_FireBlaster = +{ + + local entity plasma; + blaster_flash(); + self.currentammo = self.ammo_blaster = self.ammo_blaster - 0; + sound (self, CHAN_AUTO, "weapons/guncock.wav", 1, ATTN_NORM); + self.punchangle_x = -2; + + plasma = spawn (); + plasma.owner = self; + plasma.movetype = MOVETYPE_FLYMISSILE; + plasma.solid = SOLID_BBOX; + plasma.classname = "Plasma"; + +// Set the speed of the Plasma + + makevectors (self.v_angle); + plasma.velocity = aim(self, 1000); + if (self.charge >= 10 && self.charge <= 39) // Sets the Velocity for When charging the Blaster + plasma.velocity = plasma.velocity * 4200; + if (self.charge >= 40 && self.charge <= 69) + plasma.velocity = plasma.velocity * 3100; + if (self.charge >= 70) + plasma.velocity = plasma.velocity * 2000; + else + plasma.velocity = plasma.velocity * 4500; + + plasma.angles = vectoangles(plasma.velocity); + + if (self.charge >= 10 && self.charge <= 39) // Sets the Different Damages + plasma.touch = BlasterTouch1; + if (self.charge >= 40 && self.charge <= 69) + plasma.touch = BlasterTouch2; + if (self.charge >= 70) + plasma.touch = BlasterTouch3; + else + plasma.touch = BlasterTouch; + setmodel (plasma, "progs/blast.spr"); + if (self.charge >= 10 && self.charge <= 49) + plasma.frame = 1; + else if (self.charge >= 50) + plasma.frame = 0; + else + plasma.frame = 2; + + setsize (plasma, '0 0 0', '0 0 0'); + setorigin (plasma, self.origin + v_forward*10 + '0 0 16'); + +// set missile duration + plasma.nextthink = time + 5; + plasma.think = SUB_Remove; + self.charge = 0; +}; + +/* +================ +W_FireRic + +Has 3 Functions Because It needs 3 different origins. There are 3 slots in the Richochet beam. +================ +*/ +void() W_FireRic = +{ + + local entity plasma; + blaster_flash(); + if (self.charge >= 10 && self.charge <= 39) //Sets the amount of ammo lost when CHarging + { + if (self.ammo_ric <= 6) + self.currentammo = self.ammo_ric = self.ammo_ric - 1; + else + self.currentammo = self.ammo_ric = self.ammo_ric - 4; + } + else if (self.charge >= 40) + { + if (self.ammo_ric <= 6) + self.currentammo = self.ammo_ric = self.ammo_ric - 1; + else + self.currentammo = self.ammo_ric = self.ammo_ric - 5; + } + else + { + if (self.ammo_ric <= 6) + self.currentammo = self.ammo_ric = self.ammo_ric - 1; + else + self.currentammo = self.ammo_ric = self.ammo_ric - 3; + } + sound (self, CHAN_AUTO, "weapons/guncock.wav", 1, ATTN_NORM); + if (self.charge >= 10 && self.charge <= 39) + self.punchangle_x = -4; + else if (self.charge >= 40) + self.punchangle_x = -6; + else + self.punchangle_x = -2; + + plasma = spawn (); + plasma.owner = self; + plasma.movetype = MOVETYPE_FLYMISSILE; + plasma.solid = SOLID_BBOX; + plasma.classname = "ric"; + +// Set the speed of the Plasma + + makevectors (self.v_angle); + plasma.velocity = aim(self, 1000); + if (self.charge >= 10 && self.charge <= 39) + plasma.velocity = plasma.velocity * 2300; + else if (self.charge >= 40 && self.charge <= 69) + plasma.velocity = plasma.velocity * 2500; + else if (self.charge >= 70) + plasma.velocity = plasma.velocity * 2700; + else + plasma.velocity = plasma.velocity * 2100; + plasma.angles = vectoangles(plasma.velocity); + + if (self.charge >= 10 && self.charge <= 39) + plasma.touch = ric_touch_1; + else if (self.charge >= 40 && self.charge <= 69) + plasma.touch = ric_touch_2; + else if (self.charge >= 70) + plasma.touch = ric_touch_3; + else + plasma.touch = ric_touch; + + if (self.charge >= 40) + plasma.lives = 2 + 4 * random(); + else + plasma.lives = 2 + 2 * random(); + +// set missile duration + plasma.nextthink = time + 5; + plasma.think = SUB_Remove; + + setmodel (plasma, "progs/ric_beam.mdl"); + setsize (plasma, '0 0 0', '0 0 0'); + setorigin (plasma, self.origin + v_forward * 22 + v_right * 10.5 + '0 0 7'); +}; + +void() W_FireRic2 = +{ + + local entity plasma; + + plasma = spawn (); + plasma.owner = self; + plasma.movetype = MOVETYPE_FLYMISSILE; + plasma.solid = SOLID_BBOX; + plasma.classname = "ric"; + +// Set the speed of the Plasma + + makevectors (self.v_angle); + plasma.velocity = aim(self, 1000); + if (self.charge >= 10 && self.charge <= 39) + plasma.velocity = plasma.velocity * 2300; + else if (self.charge >= 40 && self.charge <= 69) + plasma.velocity = plasma.velocity * 2500; + else if (self.charge >= 70) + plasma.velocity = plasma.velocity * 2700; + else + plasma.velocity = plasma.velocity * 2100; + plasma.angles = vectoangles(plasma.velocity); + + if (self.charge >= 10 && self.charge <= 39) + plasma.touch = ric_touch_1; + else if (self.charge >= 40 && self.charge <= 69) + plasma.touch = ric_touch_2; + else if (self.charge >= 70) + plasma.touch = ric_touch_3; + else + plasma.touch = ric_touch; + + if (self.charge >= 40) + plasma.lives = 2 + 4 * random(); + else + plasma.lives = 2 + 2 * random(); + +// set missile duration + plasma.nextthink = time + 5; + plasma.think = SUB_Remove; + + setmodel (plasma, "progs/ric_beam.mdl"); + setsize (plasma, '0 0 0', '0 0 0'); + setorigin (plasma, self.origin + v_forward * 22 + v_right * 3.5 + '0 0 7'); +}; + +void() W_FireRic3 = +{ + + local entity plasma; + + plasma = spawn (); + plasma.owner = self; + plasma.movetype = MOVETYPE_FLYMISSILE; + plasma.solid = SOLID_BBOX; + plasma.classname = "ric"; + +// Set the speed of the Plasma + + makevectors (self.v_angle); + plasma.velocity = aim(self, 1000); + if (self.charge >= 10 && self.charge <= 39) + plasma.velocity = plasma.velocity * 2300; + else if (self.charge >= 40 && self.charge <= 69) + plasma.velocity = plasma.velocity * 2500; + else if (self.charge >= 70) + plasma.velocity = plasma.velocity * 2700; + else + plasma.velocity = plasma.velocity * 2100; + plasma.angles = vectoangles(plasma.velocity); + + if (self.charge >= 10 && self.charge <= 39) + plasma.touch = ric_touch_1; + else if (self.charge >= 40 && self.charge <= 69) + plasma.touch = ric_touch_2; + else if (self.charge >= 70) + plasma.touch = ric_touch_3; + else + plasma.touch = ric_touch; + + if (self.charge >= 40) + plasma.lives = 2 + 4 * random(); + else + plasma.lives = 2 + 2 * random(); + +// set missile duration + plasma.nextthink = time + 5; + plasma.think = SUB_Remove; + + setmodel (plasma, "progs/ric_beam.mdl"); + setsize (plasma, '0 0 0', '0 0 0'); + setorigin (plasma, self.origin + v_forward * 18 + v_right * 17.5 + '0 0 7'); +}; +/* +============================================================================== + +ROCKETS + +============================================================================== +*/ +/* +================ +W_FireRocket +================ +*/ +void() W_FireRocket = +{ + local entity missile; + if (self.charge >= 10 && self.charge < 40) + self.currentammo = self.ammo_rockets = self.ammo_rockets - 2; + else if (self.charge >= 40 && self.charge < 70) + self.currentammo = self.ammo_rockets = self.ammo_rockets - 3; + else if (self.charge >= 70) + self.currentammo = self.ammo_rockets = self.ammo_rockets - 5; + else + self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; + if (self.ammo_rockets == 0) + self.weapon = IT_BLASTER; + + sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM); + if (self.charge >= 40 && self.charge < 70) + self.punchangle_x = -4; + else if (self.charge >= 70) + self.punchangle_x = -7; + else + self.punchangle_x = -2; + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_FLYMISSILE; + missile.solid = SOLID_BBOX; + missile.classname = "missile"; + +// set missile speed + + if (self.charge >= 10 && self.charge < 40) //Dang, I messed up with making some 39 and 69 :p + { + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = missile.velocity * 1100; + missile.angles = vectoangles(missile.velocity); + } + else if (self.charge >= 40 && self.charge < 70) + { + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = missile.velocity * 1200; + missile.angles = vectoangles(missile.velocity); + } + else if (self.charge >= 70) + { + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = missile.velocity * 1500; + missile.angles = vectoangles(missile.velocity); + } + else + { + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = missile.velocity * 1000; + missile.angles = vectoangles(missile.velocity); + } + + if (self.charge >= 10 && self.charge < 40) + missile.touch = Rocket_Explode1; + else if (self.charge >= 40 && self.charge < 70) + missile.touch = Rocket_Explode2; + else if (self.charge >= 70) + missile.touch = Rocket_Explode3; + else + missile.touch = Rocket_Explode0; + +// set missile duration + missile.nextthink = time + 5; + missile.think = SUB_Remove; + + setmodel (missile, "progs/missile.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + v_forward*8 + '0 0 16'); +}; + +/* +=============================================================================== + +LIGHTNING + +=============================================================================== +*/ + +/* +================= +LightningDamage +================= +*/ +void(vector p1, vector p2, entity from, float damage) LightningDamage = +{ + local entity e1, e2; + local vector f; + + f = p2 - p1; + normalize (f); + f_x = 0 - f_y; + f_y = f_x; + f_z = 0; + f = f*16; + + e1 = e2 = world; + + traceline (p1, p2, FALSE, self); + if (trace_ent.takedamage) + { + particle (trace_endpos, '0 0 100', 225, damage*4); + T_Damage (trace_ent, from, from, damage); + if (self.classname == "player") + { + if (other.classname == "player") + trace_ent.velocity_z = trace_ent.velocity_z + 400; + } + } + e1 = trace_ent; + + traceline (p1 + f, p2 + f, FALSE, self); + if (trace_ent != e1 && trace_ent.takedamage) + { + particle (trace_endpos, '0 0 100', 225, damage*4); + T_Damage (trace_ent, from, from, damage); + } + e2 = trace_ent; + + traceline (p1 - f, p2 - f, FALSE, self); + if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage) + { + particle (trace_endpos, '0 0 100', 225, damage*4); + T_Damage (trace_ent, from, from, damage); + } +}; + + +void() W_FireLightning = +{ + local vector org; + local float cells; + + if (self.ammo_cells < 1) + { + //self.weapon = W_BestWeapon (); + W_SetCurrentAmmo (); + return; + } + +// explode if under water + if (self.waterlevel > 1) + { + cells = self.ammo_cells; + self.ammo_cells = 0; + W_SetCurrentAmmo (); + T_RadiusDamage (self, self, 35*cells, world); + return; + } + + if (self.t_width < time) + { + sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM); + self.t_width = time + 0.6; + } + self.punchangle_x = -2; + + self.currentammo = self.ammo_cells = self.ammo_cells - 1; + + org = self.origin + '0 0 16'; + + traceline (org, org + v_forward*600, TRUE, self); + + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_LIGHTNING2); + WriteEntity (MSG_BROADCAST, self); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); + WriteCoord (MSG_BROADCAST, trace_endpos_x); + WriteCoord (MSG_BROADCAST, trace_endpos_y); + WriteCoord (MSG_BROADCAST, trace_endpos_z); + + LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30); +}; + + +//============================================================================= + + +void() GrenadeExplode = +{ + T_RadiusDamage (self, self.owner, 120, world); + + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); + + CreateExplosion (self.origin); +}; + +void() GrenadeTouch = +{ + if (other == self.owner) + return; // don't explode on owner + if (other.takedamage == DAMAGE_AIM) + { + GrenadeExplode(); + return; + } + sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound + if (self.velocity == '0 0 0') + self.avelocity = '0 0 0'; +}; + +/* +================ +W_FireGrenade +================ +*/ +void() W_FireGrenade = +{ + local entity missile; + + self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; + + sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM); + + self.punchangle_x = -2; + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_BOUNCE; + missile.solid = SOLID_BBOX; + missile.classname = "grenade"; + +// set missile speed + + makevectors (self.v_angle); + + if (self.v_angle_x) + missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10; + else + { + missile.velocity = aim(self, 10000); + missile.velocity = missile.velocity * 600; + missile.velocity_z = 200; + } + + missile.avelocity = '300 300 300'; + + missile.angles = vectoangles(missile.velocity); + + missile.touch = GrenadeTouch; + +// set missile duration + missile.nextthink = time + 2.5; + missile.think = GrenadeExplode; + + setmodel (missile, "progs/grenade.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin); +}; +//For regenerating Your Bombs +void() mbomb1 = +{ +if (self.morphbombs == 3) + self.morphbombs += 1; +if (self.morphbombs == 2) + self.morphbombs += 2; +if (self.morphbombs == 1) + self.morphbombs += 3; +}; + +void() fire_morphbomb = +{ + local entity missile; + self.currentammo = self.morphbombs = self.morphbombs - 1; + sound (self, CHAN_WEAPON, "weapons/mb_bomb.wav", 1, ATTN_NORM); + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_BOUNCE; + missile.solid = SOLID_BBOX; + missile.classname = "Mbomb"; + +// set missile speed + + makevectors (self.v_angle); + + missile.avelocity = '0 0 0'; + + missile.angles = vectoangles(missile.velocity); + + +// set missile duration + missile.nextthink = time + 2.5; + missile.think = BombExplode; + + self.think = mbomb1; + self.nextthink = time + 2.5; + missile.effects = EF_DIMLIGHT; + setmodel (missile, "progs/mbomb.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + v_up * 8); +}; + + +//============================================================================= + +void() spike_touch; +void() superspike_touch; + + +/* +=============== +launch_spike + +Used for both the player and the ogre +=============== +*/ +void(vector org, vector dir) launch_spike = +{ + newmis = spawn (); + newmis.owner = self; + newmis.movetype = MOVETYPE_FLYMISSILE; + newmis.solid = SOLID_BBOX; + + newmis.angles = vectoangles(dir); + + newmis.touch = spike_touch; + newmis.classname = "spike"; + newmis.think = SUB_Remove; + newmis.nextthink = time + 6; + setmodel (newmis, "progs/spike.mdl"); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + setorigin (newmis, org); + + newmis.velocity = dir * 1000; +}; + +void() W_FireSuperSpikes = +{ + local vector dir; + + sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM); + self.attack_finished = time + 0.2; + self.currentammo = self.ammo_nails = self.ammo_nails - 2; + dir = aim (self, 1000); + launch_spike (self.origin + '0 0 16', dir); + newmis.touch = superspike_touch; + setmodel (newmis, "progs/s_spike.mdl"); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + self.punchangle_x = -2; +}; + +void(float ox) W_FireSpikes = +{ + local vector dir; + + makevectors (self.v_angle); + + if (self.ammo_nails >= 2 && self.weapon == IT_SNIPER) + { + W_FireSuperSpikes (); + return; + } + + if (self.ammo_nails < 1) + { + //self.weapon = W_BestWeapon (); + W_SetCurrentAmmo (); + return; + } + + sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM); + self.attack_finished = time + 0.2; + self.currentammo = self.ammo_nails = self.ammo_nails - 1; + dir = aim (self, 1000); + launch_spike (self.origin + '0 0 16' + v_right*ox, dir); + + self.punchangle_x = -2; +}; + + + +void() spike_touch = +{ + if (other == self.owner) + return; + + if (other.solid == SOLID_TRIGGER) + return; // trigger field, do nothing + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + +// hit something that bleeds + if (other.takedamage) + { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 18); + } + else + { + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_SUPERSPIKE); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); + } + + remove(self); + +}; + + +void() superspike_touch = +{ + if (other == self.owner) + return; + + if (other.solid == SOLID_TRIGGER) + return; // trigger field, do nothing + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + +// hit something that bleeds + if (other.takedamage) + { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 18); + } + else + { + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_SUPERSPIKE); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); + } + + remove(self); + +}; + + +/* +=============================================================================== + +PLAYER WEAPON USE + +=============================================================================== +*/ + +void() W_SetCurrentAmmo = +{ + if (self.weapon == IT_MORPHBALL) + return; + +{ + player_run (); // get out of any weapon firing states + + self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) ); + + if (self.weapon == IT_BLASTER) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + if(!self.semi) + { + self.currentammo = self.ammo_blaster; + self.weaponmodel = "progs/v_shot.mdl"; + self.weaponframe = 0; + sound (self, CHAN_WEAPON, "weapons/blaster_transform.wav", 1, ATTN_NORM); + player_missle27(); + } + } + else if (self.weapon == IT_RIC) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + self.currentammo = self.ammo_ric; + self.weaponmodel = "progs/v_shot.mdl"; + player_missle37(); + self.attack_finished = time + 1.5; + } + else if (self.weapon == IT_ROCKET) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + self.currentammo = self.ammo_rockets; + self.weaponmodel = "progs/v_shot.mdl"; + sound (self, CHAN_WEAPON, "weapons/rocket_transform.wav", 1, ATTN_NORM); + player_missle1(); + self.attack_finished = time + 1.5; + } + else if (self.weapon == IT_SPLASER) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + self.currentammo = self.ammo_nails; + self.weaponmodel = "progs/v_shot.mdl"; + self.weaponframe = 0; + } + else if (self.weapon == IT_SNIPER) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + self.currentammo = self.ammo_sniper; + self.weaponmodel = "progs/v_shot.mdl"; + self.weaponframe = 0; + self.items = self.items | IT_NAILS; + } + else if (self.weapon == IT_GRENADE_LAUNCHER) + { + //self.currentammo = self.ammo_rockets; + //self.weaponmodel = "progs/v_rock.mdl"; + self.currentammo = self.morphbombs; + self.weaponframe = 0; + //self.items = self.items | IT_ROCKETS; + } + else if (self.weapon == IT_MAGMA) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + self.currentammo = self.ammo_lava; + self.weaponmodel = "progs/v_shot.mdl"; + self.weaponframe = 0; + self.items = self.items | IT_ROCKETS; + } + else if (self.weapon == IT_LIGHTNING) + { + self.currentammo = self.ammo_cells; + self.weaponmodel = "progs/v_light.mdl"; + self.weaponframe = 0; + self.items = self.items | IT_CELLS; + } + else + { + self.currentammo = 0; + self.weaponframe = 0; + } + } +}; +float() W_CheckNoAmmo = +{ + if (self.currentammo > 0) + return TRUE; + + if (self.weapon == IT_MORPHBALL) + return TRUE; + + W_SetCurrentAmmo (); + +// drop the weapon down + return FALSE; +}; + +/* +============ +W_Attack + +An attack impulse can be triggered now +============ +*/ +void() player_axe1; +void() player_axeb1; +void() player_axec1; +void() player_axed1; +void() player_shot1; +void() player_nail1; +void() player_light1; +void() player_rocket1; +void() FireAnimations; //A function that Is becoming less useable as the game goes on...Sigh +void() player_missle14; //Shooting Animations for Rocket Launcher +void() player_missle45; //Shooting Animations for Richochet beam +void() player_missle56; //Shooting Animations for Blaster +void() W_Attack = +{ + if (!W_CheckNoAmmo ()) + return; + + makevectors (self.v_angle); // calculate forward angle for velocity + self.show_hostile = time + 1; // wake monsters up + + + if (self.weapon == IT_MORPHBALL) + { + if (self.morphbombs <= 1) + return; + fire_morphbomb(); + self.attack_finished = time + 0.6; + } + else if (self.weapon == IT_BLASTER) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + else + { + if (!self.semi) + { + W_FireBlaster(); + player_missle56(); + self.semi = 1; + self.attack_finished = time + 0.12; + } + } +} + else if (self.weapon == IT_RIC) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + else + { + + if(!self.semi) + { + if (self.ammo_ric <= 6) + W_FireRic(); + else + { + W_FireRic(); + W_FireRic2(); + W_FireRic3(); + } + player_missle45(); + self.semi = 1; // Semiauto + self.attack_finished = time + 0.6; // Faster + } + } + } + + + else if (self.weapon == IT_ROCKET) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + + else + { + if(!self.semi) + { + player_missle14(); + W_FireRocket(); + self.semi = 1; + self.attack_finished = time + 0.7; + } + } + } + else if (self.weapon == IT_SPLASER) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + + else + { + if(!self.semi) + { + FireAnimations(); + self.semi = 1; + self.attack_finished = time + 0.8; + } + } + } + else if (self.weapon == IT_SNIPER) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + FireAnimations(); + self.attack_finished = time + 1; + } + else if (self.weapon == IT_GRENADE_LAUNCHER) + { + fire_morphbomb(); + self.attack_finished = time + 0.6; + } + else if (self.weapon == IT_MAGMA) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + FireAnimations(); + W_FireMagma(); + self.attack_finished = time + 0.7; + } + else if (self.weapon == IT_LIGHTNING) + { + player_light1(); + self.attack_finished = time + 0.1; + sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM); + } +}; + +/* +============ +W_ChangeWeapon + +============ +*/ +void() W_ChangeWeapon = +{ + local float it, am, fl; + + it = self.items; + am = 0; + + if (self.impulse == 1) + { + fl = IT_MORPHBALL; + } + else if (self.impulse == 2) + { + //if (self.weapon == IT_RIC | IT_ROCKET | IT_SNIPER | IT_SPLASER | IT_MAGMA); + //player_missle27(); + fl = IT_BLASTER; + if (self.ammo_shells < 1) + am = 1; + } + else if (self.impulse == 3) + { + fl = IT_ROCKET; + if (self.ammo_shells < 2) + am = 1; + } + //else if (self.impulse == 4) + //{ + //fl = IT_SPLASER; + //if (self.ammo_nails < 1) + //am = 1; + //} + else if (self.impulse == 5) + { + fl = IT_SNIPER; + if (self.ammo_sniper < 2) + am = 1; + } + //else if (self.impulse == 6) + //{ + // fl = IT_GRENADE_LAUNCHER; + // if (self.ammo_rockets < 1) + // am = 1; + //} + else if (self.impulse == 7) + { + fl = IT_MAGMA; + if (self.ammo_lava < 1) + am = 1; + } + else if (self.impulse == 8) + { + fl = IT_LIGHTNING; + if (self.ammo_cells < 1) + am = 1; + } + self.impulse = 0; + + if (!(self.items & fl)) + { // don't have the weapon or the ammo + sprint (self, "no weapon.\n"); + return; + } + + if (am) + { // don't have the ammo + sprint (self, "not enough ammo.\n"); + return; + } + +// +// set weapon, set ammo +// + self.weapon = fl; + W_SetCurrentAmmo (); + +}; + +/* +============ +CheatCommand +============ +*/ +void() CheatCommand = +{ + if (deathmatch || coop) + return; + + self.ammo_rockets = 100; + self.ammo_nails = 200; + self.ammo_shells = 100; + self.items = self.items | + IT_MORPHBALL | + IT_BLASTER | + IT_ROCKET | + IT_SPLASER | + IT_SNIPER | + IT_GRENADE_LAUNCHER | + IT_MAGMA | + IT_RIC | + IT_KEY1 | IT_KEY2; + + + self.ammo_cells = 200; + self.items = self.items | IT_LIGHTNING; + + self.weapon = IT_MAGMA; + self.impulse = 0; + W_SetCurrentAmmo (); +}; + +/* +============ +CycleWeaponCommand + +Go to the next weapon with ammo +============ +*/ +void() CycleWeaponCommand = +{ + local float it, am; + + it = self.items; + self.impulse = 0; + + while (1) + { + am = 0; + + if (self.weapon == IT_LIGHTNING) + { + player_missle27(); + self.weapon = IT_BLASTER; + if (self.ammo_blaster < 1) + am = 1; + } + else if (self.weapon == IT_BLASTER) + { + self.weapon = IT_RIC; + if (self.ammo_ric < 2) + am = 1; + } + else if (self.weapon == IT_RIC) + { + self.weapon = IT_ROCKET; + if (self.ammo_rockets < 1) + am = 1; + } + else if (self.weapon == IT_ROCKET) + { + self.weapon = IT_SPLASER; + if (self.ammo_nails < 1) + am = 1; + } + else if (self.weapon == IT_SPLASER) + { + self.weapon = IT_SNIPER; + if (self.ammo_sniper < 1) + am = 1; + } + else if (self.weapon == IT_SNIPER) + { + self.weapon = IT_MAGMA; + if (self.ammo_lava < 1) + am = 1; + } + //else if (self.weapon == IT_GRENADE_LAUNCHER) + //{ + // self.weapon = IT_MAGMA; + // if (self.ammo_lava < 1) + // am = 1; + //} + else if (self.weapon == IT_MAGMA) + { + self.weapon = IT_LIGHTNING; + if (self.ammo_cells < 1) + am = 1; + } + + if ( (it & self.weapon) && am == 0) + { + W_SetCurrentAmmo (); + return; + } + } + +}; + +/* +============ +CycleWeaponReverseCommand + +Go to the prev weapon with ammo +============ +*/ +void() CycleWeaponReverseCommand = +{ + local float it, am; + + it = self.items; + self.impulse = 0; + + while (1) + { + am = 0; + + if (self.weapon == IT_LIGHTNING) + { + self.weapon = IT_MAGMA; + if (self.ammo_lava < 1) + am = 1; + } + else if (self.weapon == IT_MAGMA) + { + self.weapon = IT_SNIPER; + if (self.ammo_sniper < 1) + am = 1; + } + //else if (self.weapon == IT_GRENADE_LAUNCHER) + //{ + // self.weapon = IT_SNIPER; + // if (self.ammo_sniper < 1) + // am = 1; + //} + else if (self.weapon == IT_SNIPER) + { + self.weapon = IT_SPLASER; + if (self.ammo_nails < 1) + am = 1; + } + else if (self.weapon == IT_SPLASER) + { + self.weapon = IT_ROCKET; + if (self.ammo_shells < 2) + am = 1; + } + + else if (self.weapon == IT_ROCKET) + { + self.weapon = IT_BLASTER; + if (self.ammo_blaster < 1) + am = 1; + } + else if (self.weapon == IT_BLASTER) + { + self.weapon = IT_MORPHBALL; + } + else if (self.weapon == IT_MORPHBALL) + { + self.weapon = IT_LIGHTNING; + if (self.ammo_cells < 1) + am = 1; + } + + if ( (it & self.weapon) && am == 0) + { + W_SetCurrentAmmo (); + return; + } + } + +}; + +/* +============ +ServerflagsCommand + +Just for development +============ +*/ +void() ServerflagsCommand = +{ + serverflags = serverflags * 2 + 1; +}; + +void() QuadCheat = +{ + if (deathmatch || coop) + return; + self.super_time = 1; + self.super_damage_finished = time + 30; + self.items = self.items | IT_QUAD; + dprint ("quad cheat\n"); +}; +void() PlayerJump; +/* +============ +ImpulseCommands + +============ +*/ +void() ImpulseCommands = +{ + if (self.impulse >= 1 && self.impulse <= 8) + W_ChangeWeapon (); + if (self.impulse == 9) + CheatCommand (); + if (self.impulse == 10) + { + CycleWeaponCommand (); + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + } + if (self.impulse == 11) + ServerflagsCommand (); + if (self.impulse == 12) + { + CycleWeaponReverseCommand (); + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + } + if (self.impulse == 15) + { + if (self.health < BROKENITEMS || self.button0 || !self.flags & FL_ONGROUND) + return; + if (self.weapon != IT_MORPHBALL) + { + self.charge = 0; + self.pfov = FOV_DEFAULT; + setsize (self, '-10 -10 -24', '10 10 10'); + self.weapon = IT_MORPHBALL; + self.morphbombs = 4; + self.mballset = 1; + self.currentammo = self.morphbombs; + self.boostlives = 1; + self.morphbombs = 4; + sound (self, CHAN_WEAPON, "weapons/morphball.wav", 1, ATTN_NORM); + stuffcmd (self, "chase_active 1"); + self.attack_finished = time + 1; + } + else if (self.weapon == IT_MORPHBALL) + { + self.charge = 0; + self.pfov = FOV_DEFAULT; + setorigin (self, self.origin + v_up * 20); + setsize (self, '-16 -16 -24', '16 16 32'); + self.mballset = 0; + self.weapon = IT_BLASTER; + stuffcmd (self, "chase_active 0"); + W_SetCurrentAmmo (); + self.attack_finished = time + 1; + } + } + if (self.impulse == 17) + { + if (self.weapon == IT_SNIPER) + { + if (self.weapon == IT_MORPHBALL) + return; + WeaponZoom(); + } + if (self.weapon == IT_MORPHBALL) + boost(); + } + if (self.impulse == 255) + QuadCheat (); + + self.impulse = 0; +}; +/* +============ +W_WeaponFrame + +Called every frame so impulse events can be handled as well as possible +============ +*/ +void() W_WeaponFrame = +{ + if (!self.button0) + self.semi = 0; + + if (time < self.attack_finished) + return; + + ImpulseCommands (); // check for attack + + //if (self.button0) // Whats funny Is That You don't even need to Press the Button! + // { + /* +=============================================== + BLASTER +================================== + */ + if (self.weapon == IT_BLASTER) + { + if (self.charge < 10) + { + self.charge = self.charge + 1; + } + + if (self.charge >= 10) + if (self.charge < 20) + { + self.charge = self.charge + 1; + } + + if (self.charge >= 20) + if (self.charge < 30) + { + self.charge = self.charge + 1; + } + if (self.charge >= 30) + if (self.charge < 40) + { + self.charge = self.charge + 1; + } + if (self.charge >= 40) + if (self.charge < 50) + { + self.charge = self.charge + 1; + } + if (self.charge >= 50) + if (self.charge < 60) + { + self.charge = self.charge + 1; + } + if (self.charge >= 60) + if (self.charge < 70) + { + self.charge = self.charge + 1; + } + if (self.charge >= 70) + { + if (self.weapon == IT_MORPHBALL) //If you turn into Morphball, Then Have no Charge + {self.charge = 0;} + else + { + self.charge = self.charge + 1; + sprint(self, "Fully charged\n"); + } + } + + if (self.charge < 10 && !self.button0) + if (self.charge >= 1 && !self.button0) // no rapid fire + { + self.charge = 0; + } + + if (!self.button0 && self.charge >= 10) // you released the button + { + if (self.weapon == IT_MORPHBALL) + return; + if (!self.semi) + { + W_FireBlaster(); + self.charge = 0; + player_missle56(); + self.semi = 0; + self.attack_finished = time + 0.12; + } + } + } +/* +=============================================== + RICHOCHET +================================== +*/ + if (self.weapon == IT_RIC) + { + if (self.charge < 10) + { + self.charge = self.charge + 1; + } + + if (self.charge >= 10) + if (self.charge < 20) + { + self.charge = self.charge + 1; + } + + if (self.charge >= 20) + if (self.charge < 30) + { + self.charge = self.charge + 1; + } + if (self.charge >= 30) + if (self.charge < 40) + { + self.charge = self.charge + 1; + } + if (self.charge >= 40) + if (self.charge < 50) + { + self.charge = self.charge + 1; + } + if (self.charge >= 50) + if (self.charge < 60) + { + self.charge = self.charge + 1; + } + if (self.charge >= 60) + if (self.charge < 70) + { + self.charge = self.charge + 1; + } + if (self.charge >= 70) + { + if (self.weapon == IT_MORPHBALL) //If you turn into Morphball, Then Have no Charge + {self.charge = 0;} + else + { + self.charge = self.charge + 1; + sprint(self, "Fully charged\n"); + } + } + + if (self.charge < 10 && !self.button0) + if (self.charge >= 1 && !self.button0) // no rapid fire + { + self.charge = 0; + } + + if (!self.button0 && self.charge >= 10) // you released the button + { + if (self.weapon == IT_MORPHBALL) + return; + if (!self.semi) + { + W_FireRic(); + self.charge = 0; + player_missle45(); + self.semi = 0; + self.attack_finished = time + 0.7; + } + } + } + +/* +=============================================== +ROCKET LAUNCHER +================================== +*/ + if (self.weapon == IT_ROCKET) + { + if (self.charge < 10) + { + self.charge = self.charge + 1; + } + + if (self.charge >= 10) + if (self.charge < 20) + { + self.charge = self.charge + 1; + } + + if (self.charge >= 20) + if (self.charge < 30) + { + self.charge = self.charge + 1; + } + if (self.charge >= 30) + if (self.charge < 40) + { + self.charge = self.charge + 1; + } + if (self.charge >= 40) + if (self.charge < 50) + { + self.charge = self.charge + 1; + } + if (self.charge >= 50) + if (self.charge < 60) + { + self.charge = self.charge + 1; + } + if (self.charge >= 60) + if (self.charge < 70) + { + self.charge = self.charge + 1; + } + if (self.charge >= 70) + { + if (self.weapon == IT_MORPHBALL) //If you turn into Morphball, Then Have no Charge + {self.charge = 0;} + else + { + self.charge = self.charge + 1; + sprint(self, "Fully charged\n"); + } + } + + if (self.charge < 10 && !self.button0) + if (self.charge >= 1 && !self.button0) // no rapid fire + { + self.charge = 0; + } + + if (!self.button0 && self.charge >= 10) // you released the button + { + if (self.weapon == IT_MORPHBALL) + return; + if (!self.semi) + { + W_FireRocket(); + self.charge = 0; + player_missle14(); + self.semi = 0; + self.attack_finished = time + 0.7; + } + } + } + + + if (self.button0) + { + SuperDamageSound (); + W_Attack (); +} +}; +/* +======== +SuperDamageSound + +Plays sound if needed +======== +*/ +void() SuperDamageSound = +{ + if (self.super_damage_finished > time) + { + if (self.super_sound < time) + { + self.super_sound = time + 1; + sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM); + } + } + return; +}; + \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/Primeqc4/wizard.qc b/r17/Revamped src/Revamped QC/Primeqc4/wizard.qc new file mode 100755 index 00000000..d6a6e0ed --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/wizard.qc @@ -0,0 +1,410 @@ +/* +============================================================================== + +WIZARD + +============================================================================== +*/ + +$cd id1/models/a_wizard +$origin 0 0 24 +$base wizbase +$skin wizbase + +$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8 +$frame hover9 hover10 hover11 hover12 hover13 hover14 hover15 + +$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10 +$frame fly11 fly12 fly13 fly14 + +$frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7 +$frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13 + +$frame pain1 pain2 pain3 pain4 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 + +/* +============================================================================== + +WIZARD + +If the player moves behind cover before the missile is launched, launch it +at the last visible spot with no velocity leading, in hopes that the player +will duck back out and catch it. +============================================================================== +*/ + +/* +============= +LaunchMissile + +Sets the given entities velocity and angles so that it will hit self.enemy +if self.enemy maintains it's current velocity +0.1 is moderately accurate, 0.0 is totally accurate +============= +*/ +void(entity missile, float mspeed, float accuracy) LaunchMissile = +{ + local vector vec, move; + local float fly; + + makevectors (self.angles); + +// set missile speed + vec = self.enemy.origin + self.enemy.mins + self.enemy.size * 0.7 - missile.origin; + +// calc aproximate time for missile to reach vec + fly = vlen (vec) / mspeed; + +// get the entities xy velocity + move = self.enemy.velocity; + move_z = 0; + +// project the target forward in time + vec = vec + move * fly; + + vec = normalize(vec); + vec = vec + accuracy*v_up*(random()- 0.5) + accuracy*v_right*(random()- 0.5); + + missile.velocity = vec * mspeed; + + missile.angles = '0 0 0'; + missile.angles_y = vectoyaw(missile.velocity); + +// set missile duration + missile.nextthink = time + 5; + missile.think = SUB_Remove; +}; + + +void() wiz_run1; +void() wiz_side1; + +/* +================= +WizardCheckAttack +================= +*/ +float() WizardCheckAttack = +{ + local vector spot1, spot2; + local entity targ; + local float chance; + + if (time < self.attack_finished) + return FALSE; + if (!enemy_vis) + return FALSE; + + if (enemy_range == RANGE_FAR) + { + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + wiz_run1 (); + } + return FALSE; + } + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + traceline (spot1, spot2, FALSE, self); + + if (trace_ent != targ) + { // don't have a clear shot, so move to a side + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + wiz_run1 (); + } + return FALSE; + } + + if (enemy_range == RANGE_MELEE) + chance = 0.9; + else if (enemy_range == RANGE_NEAR) + chance = 0.6; + else if (enemy_range == RANGE_MID) + chance = 0.2; + else + chance = 0; + + if (random () < chance) + { + self.attack_state = AS_MISSILE; + return TRUE; + } + + if (enemy_range == RANGE_MID) + { + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + wiz_run1 (); + } + } + else + { + if (self.attack_state != AS_SLIDING) + { + self.attack_state = AS_SLIDING; + wiz_side1 (); + } + } + + return FALSE; +}; + +/* +================= +WizardAttackFinished +================= +*/ +float() WizardAttackFinished = +{ + if (enemy_range >= RANGE_MID || !enemy_vis) + { + self.attack_state = AS_STRAIGHT; + self.think = wiz_run1; + } + else + { + self.attack_state = AS_SLIDING; + self.think = wiz_side1; + } +}; + +/* +============================================================================== + +FAST ATTACKS + +============================================================================== +*/ + +void() Wiz_FastFire = +{ + local vector vec; + local vector dst; + + if (self.owner.health > 0) + { + self.owner.effects = self.owner.effects | EF_MUZZLEFLASH; + + makevectors (self.enemy.angles); + dst = self.enemy.origin - 13*self.movedir; + + vec = normalize(dst - self.origin); + sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM); + launch_spike (self.origin, vec); + newmis.velocity = vec*600; + newmis.owner = self.owner; + newmis.classname = "wizspike"; + setmodel (newmis, "progs/w_spike.mdl"); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + } + + remove (self); +}; + + +void() Wiz_StartFast = +{ + local entity missile; + + sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM); + self.v_angle = self.angles; + makevectors (self.angles); + + missile = spawn (); + missile.owner = self; + missile.nextthink = time + 0.6; + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right*14); + missile.enemy = self.enemy; + missile.nextthink = time + 0.8; + missile.think = Wiz_FastFire; + missile.movedir = v_right; + + missile = spawn (); + missile.owner = self; + missile.nextthink = time + 1; + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right* -14); + missile.enemy = self.enemy; + missile.nextthink = time + 0.3; + missile.think = Wiz_FastFire; + missile.movedir = VEC_ORIGIN - v_right; +}; + + + +void() Wiz_idlesound = +{ +local float wr; + wr = random() * 5; + + if (self.waitmin < time) + { + self.waitmin = time + 2; + if (wr > 4.5) + sound (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE); + if (wr < 1.5) + sound (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE); + } + return; +}; + +void() wiz_stand1 =[ $hover1, wiz_stand2 ] {ai_stand();}; +void() wiz_stand2 =[ $hover2, wiz_stand3 ] {ai_stand();}; +void() wiz_stand3 =[ $hover3, wiz_stand4 ] {ai_stand();}; +void() wiz_stand4 =[ $hover4, wiz_stand5 ] {ai_stand();}; +void() wiz_stand5 =[ $hover5, wiz_stand6 ] {ai_stand();}; +void() wiz_stand6 =[ $hover6, wiz_stand7 ] {ai_stand();}; +void() wiz_stand7 =[ $hover7, wiz_stand8 ] {ai_stand();}; +void() wiz_stand8 =[ $hover8, wiz_stand1 ] {ai_stand();}; + +void() wiz_walk1 =[ $hover1, wiz_walk2 ] {ai_walk(8); +Wiz_idlesound();}; +void() wiz_walk2 =[ $hover2, wiz_walk3 ] {ai_walk(8);}; +void() wiz_walk3 =[ $hover3, wiz_walk4 ] {ai_walk(8);}; +void() wiz_walk4 =[ $hover4, wiz_walk5 ] {ai_walk(8);}; +void() wiz_walk5 =[ $hover5, wiz_walk6 ] {ai_walk(8);}; +void() wiz_walk6 =[ $hover6, wiz_walk7 ] {ai_walk(8);}; +void() wiz_walk7 =[ $hover7, wiz_walk8 ] {ai_walk(8);}; +void() wiz_walk8 =[ $hover8, wiz_walk1 ] {ai_walk(8);}; + +void() wiz_side1 =[ $hover1, wiz_side2 ] {ai_run(8); +Wiz_idlesound();}; +void() wiz_side2 =[ $hover2, wiz_side3 ] {ai_run(8);}; +void() wiz_side3 =[ $hover3, wiz_side4 ] {ai_run(8);}; +void() wiz_side4 =[ $hover4, wiz_side5 ] {ai_run(8);}; +void() wiz_side5 =[ $hover5, wiz_side6 ] {ai_run(8);}; +void() wiz_side6 =[ $hover6, wiz_side7 ] {ai_run(8);}; +void() wiz_side7 =[ $hover7, wiz_side8 ] {ai_run(8);}; +void() wiz_side8 =[ $hover8, wiz_side1 ] {ai_run(8);}; + +void() wiz_run1 =[ $fly1, wiz_run2 ] {ai_run(16); +Wiz_idlesound(); +}; +void() wiz_run2 =[ $fly2, wiz_run3 ] {ai_run(16);}; +void() wiz_run3 =[ $fly3, wiz_run4 ] {ai_run(16);}; +void() wiz_run4 =[ $fly4, wiz_run5 ] {ai_run(16);}; +void() wiz_run5 =[ $fly5, wiz_run6 ] {ai_run(16);}; +void() wiz_run6 =[ $fly6, wiz_run7 ] {ai_run(16);}; +void() wiz_run7 =[ $fly7, wiz_run8 ] {ai_run(16);}; +void() wiz_run8 =[ $fly8, wiz_run9 ] {ai_run(16);}; +void() wiz_run9 =[ $fly9, wiz_run10 ] {ai_run(16);}; +void() wiz_run10 =[ $fly10, wiz_run11 ] {ai_run(16);}; +void() wiz_run11 =[ $fly11, wiz_run12 ] {ai_run(16);}; +void() wiz_run12 =[ $fly12, wiz_run13 ] {ai_run(16);}; +void() wiz_run13 =[ $fly13, wiz_run14 ] {ai_run(16);}; +void() wiz_run14 =[ $fly14, wiz_run1 ] {ai_run(16);}; + +void() wiz_fast1 =[ $magatt1, wiz_fast2 ] {ai_face();Wiz_StartFast();}; +void() wiz_fast2 =[ $magatt2, wiz_fast3 ] {ai_face();}; +void() wiz_fast3 =[ $magatt3, wiz_fast4 ] {ai_face();}; +void() wiz_fast4 =[ $magatt4, wiz_fast5 ] {ai_face();}; +void() wiz_fast5 =[ $magatt5, wiz_fast6 ] {ai_face();}; +void() wiz_fast6 =[ $magatt6, wiz_fast7 ] {ai_face();}; +void() wiz_fast7 =[ $magatt5, wiz_fast8 ] {ai_face();}; +void() wiz_fast8 =[ $magatt4, wiz_fast9 ] {ai_face();}; +void() wiz_fast9 =[ $magatt3, wiz_fast10 ] {ai_face();}; +void() wiz_fast10 =[ $magatt2, wiz_run1 ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();}; + +void() wiz_pain1 =[ $pain1, wiz_pain2 ] {}; +void() wiz_pain2 =[ $pain2, wiz_pain3 ] {}; +void() wiz_pain3 =[ $pain3, wiz_pain4 ] {}; +void() wiz_pain4 =[ $pain4, wiz_run1 ] {}; + +void() wiz_death1 =[ $death1, wiz_death2 ] { + +self.velocity_x = -200 + 400*random(); +self.velocity_y = -200 + 400*random(); +self.velocity_z = 100 + 100*random(); +self.flags = self.flags - (self.flags & FL_ONGROUND); +sound (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM); +}; +void() wiz_death2 =[ $death2, wiz_death3 ] {}; +void() wiz_death3 =[ $death3, wiz_death4 ]{self.solid = SOLID_NOT;}; +void() wiz_death4 =[ $death4, wiz_death5 ] {}; +void() wiz_death5 =[ $death5, wiz_death6 ] {}; +void() wiz_death6 =[ $death6, wiz_death7 ] {}; +void() wiz_death7 =[ $death7, wiz_death8 ] {}; +void() wiz_death8 =[ $death8, wiz_death8 ] {}; + +void() wiz_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_wizard.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + return; + } + + wiz_death1 (); +}; + + +void(entity attacker, float damage) Wiz_Pain = +{ + sound (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM); + if (random()*70 > damage) + return; // didn't flinch + + wiz_pain1 (); +}; + + +void() Wiz_Missile = +{ + wiz_fast1(); +}; + +/*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_knight = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/wizard.mdl"); + precache_model ("progs/h_wizard.mdl"); + precache_model ("progs/w_spike.mdl"); + + precache_sound ("wizard/hit.wav"); // used by c code + precache_sound ("wizard/wattack.wav"); + precache_sound ("wizard/wdeath.wav"); + precache_sound ("wizard/widle1.wav"); + precache_sound ("wizard/widle2.wav"); + precache_sound ("wizard/wpain.wav"); + precache_sound ("wizard/wsight.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/wizard.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 80; + + self.th_stand = wiz_stand1; + self.th_walk = wiz_walk1; + self.th_run = wiz_run1; + self.th_missile = Wiz_Missile; + self.th_pain = Wiz_Pain; + self.th_die = wiz_die; + + flymonster_start (); +}; diff --git a/r17/Revamped src/Revamped QC/Primeqc4/world.qc b/r17/Revamped src/Revamped QC/Primeqc4/world.qc new file mode 100755 index 00000000..6df99d3f --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/world.qc @@ -0,0 +1,385 @@ + +void() InitBodyQue; + + +void() main = +{ + dprint ("main function\n"); + +// these are just commands the the prog compiler to copy these files + + precache_file ("progs.dat"); + precache_file ("gfx.wad"); + precache_file ("quake.rc"); + precache_file ("default.cfg"); + + precache_file ("end1.bin"); + precache_file2 ("end2.bin"); + + precache_file ("demo1.dem"); + precache_file ("demo2.dem"); + precache_file ("demo3.dem"); + +// +// these are all of the lumps from the cached.ls files +// + precache_file ("gfx/palette.lmp"); + precache_file ("gfx/colormap.lmp"); + + precache_file2 ("gfx/pop.lmp"); + + precache_file ("gfx/complete.lmp"); + precache_file ("gfx/inter.lmp"); + + precache_file ("gfx/ranking.lmp"); + precache_file ("gfx/vidmodes.lmp"); + precache_file ("gfx/finale.lmp"); + precache_file ("gfx/conback.lmp"); + precache_file ("gfx/qplaque.lmp"); + + precache_file ("gfx/menudot1.lmp"); + precache_file ("gfx/menudot2.lmp"); + precache_file ("gfx/menudot3.lmp"); + precache_file ("gfx/menudot4.lmp"); + precache_file ("gfx/menudot5.lmp"); + precache_file ("gfx/menudot6.lmp"); + + precache_file ("gfx/menuplyr.lmp"); + precache_file ("gfx/bigbox.lmp"); + precache_file ("gfx/dim_modm.lmp"); + precache_file ("gfx/dim_drct.lmp"); + precache_file ("gfx/dim_ipx.lmp"); + precache_file ("gfx/dim_tcp.lmp"); + precache_file ("gfx/dim_mult.lmp"); + precache_file ("gfx/mainmenu.lmp"); + + precache_file ("gfx/box_tl.lmp"); + precache_file ("gfx/box_tm.lmp"); + precache_file ("gfx/box_tr.lmp"); + + precache_file ("gfx/box_ml.lmp"); + precache_file ("gfx/box_mm.lmp"); + precache_file ("gfx/box_mm2.lmp"); + precache_file ("gfx/box_mr.lmp"); + + precache_file ("gfx/box_bl.lmp"); + precache_file ("gfx/box_bm.lmp"); + precache_file ("gfx/box_br.lmp"); + + precache_file ("gfx/sp_menu.lmp"); + precache_file ("gfx/ttl_sgl.lmp"); + precache_file ("gfx/ttl_main.lmp"); + precache_file ("gfx/ttl_cstm.lmp"); + + precache_file ("gfx/mp_menu.lmp"); + + precache_file ("gfx/netmen1.lmp"); + precache_file ("gfx/netmen2.lmp"); + precache_file ("gfx/netmen3.lmp"); + precache_file ("gfx/netmen4.lmp"); + precache_file ("gfx/netmen5.lmp"); + + precache_file ("gfx/sell.lmp"); + + precache_file ("gfx/help0.lmp"); + precache_file ("gfx/help1.lmp"); + precache_file ("gfx/help2.lmp"); + precache_file ("gfx/help3.lmp"); + precache_file ("gfx/help4.lmp"); + precache_file ("gfx/help5.lmp"); + + precache_file ("gfx/pause.lmp"); + precache_file ("gfx/loading.lmp"); + + precache_file ("gfx/p_option.lmp"); + precache_file ("gfx/p_load.lmp"); + precache_file ("gfx/p_save.lmp"); + precache_file ("gfx/p_multi.lmp"); + +// sounds loaded by C code + precache_sound ("misc/menu1.wav"); + precache_sound ("misc/menu2.wav"); + precache_sound ("misc/menu3.wav"); + + precache_sound ("ambience/water1.wav"); + precache_sound ("ambience/wind2.wav"); + +// shareware + precache_file ("maps/start.bsp"); + + precache_file ("maps/e1m1.bsp"); + precache_file ("maps/e1m2.bsp"); + precache_file ("maps/e1m3.bsp"); + precache_file ("maps/e1m4.bsp"); + precache_file ("maps/e1m5.bsp"); + precache_file ("maps/e1m6.bsp"); + precache_file ("maps/e1m7.bsp"); + precache_file ("maps/e1m8.bsp"); + +// registered + precache_file2 ("gfx/pop.lmp"); + + precache_file2 ("maps/e2m1.bsp"); + precache_file2 ("maps/e2m2.bsp"); + precache_file2 ("maps/e2m3.bsp"); + precache_file2 ("maps/e2m4.bsp"); + precache_file2 ("maps/e2m5.bsp"); + precache_file2 ("maps/e2m6.bsp"); + precache_file2 ("maps/e2m7.bsp"); + + precache_file2 ("maps/e3m1.bsp"); + precache_file2 ("maps/e3m2.bsp"); + precache_file2 ("maps/e3m3.bsp"); + precache_file2 ("maps/e3m4.bsp"); + precache_file2 ("maps/e3m5.bsp"); + precache_file2 ("maps/e3m6.bsp"); + precache_file2 ("maps/e3m7.bsp"); + + precache_file2 ("maps/e4m1.bsp"); + precache_file2 ("maps/e4m2.bsp"); + precache_file2 ("maps/e4m3.bsp"); + precache_file2 ("maps/e4m4.bsp"); + precache_file2 ("maps/e4m5.bsp"); + precache_file2 ("maps/e4m6.bsp"); + precache_file2 ("maps/e4m7.bsp"); + precache_file2 ("maps/e4m8.bsp"); + + precache_file2 ("maps/end.bsp"); + + precache_file2 ("maps/dm1.bsp"); + precache_file2 ("maps/dm2.bsp"); + precache_file2 ("maps/dm3.bsp"); + precache_file2 ("maps/dm4.bsp"); + precache_file2 ("maps/dm5.bsp"); + precache_file2 ("maps/dm6.bsp"); +}; + + +entity lastspawn; + +//======================= +/*QUAKED worldspawn (0 0 0) ? +Only used for the world entity. +Set message to the level name. +Set sounds to the cd track to play. + +World Types: +0: medieval +1: metal +2: base +*/ +//======================= +void() worldspawn = +{ + BotInit(); // FrikBot + lastspawn = world; + InitBodyQue (); + +// custom map attributes + if (self.model == "maps/e1m8.bsp") + cvar_set ("sv_gravity", "100"); + else + cvar_set ("sv_gravity", "800"); + +// the area based ambient sounds MUST be the first precache_sounds + +// player precaches + W_Precache (); // get weapon precaches + +// sounds used from C physics code + precache_sound ("demon/dland2.wav"); // landing thud + precache_sound ("misc/h2ohit1.wav"); // landing splash + +// setup precaches allways needed + precache_sound ("items/itembk2.wav"); // item respawn sound + precache_sound ("player/plyrjmp8.wav"); // player jump + precache_sound ("player/land.wav"); // player landing + precache_sound ("player/land2.wav"); // player hurt landing + precache_sound ("player/drown1.wav"); // drowning pain + precache_sound ("player/drown2.wav"); // drowning pain + precache_sound ("player/gasp1.wav"); // gasping for air + precache_sound ("player/gasp2.wav"); // taking breath + precache_sound ("player/h2odeath.wav"); // drowning death + + precache_sound ("misc/talk.wav"); // talk + precache_sound ("player/teledth1.wav"); // telefrag + precache_sound ("misc/r_tele1.wav"); // teleport sounds + precache_sound ("misc/r_tele2.wav"); + precache_sound ("misc/r_tele3.wav"); + precache_sound ("misc/r_tele4.wav"); + precache_sound ("misc/r_tele5.wav"); + precache_sound ("weapons/lock4.wav"); // ammo pick up + precache_sound ("weapons/pkup.wav"); // weapon up + precache_sound ("items/armor1.wav"); // armor up + precache_sound ("weapons/lhit.wav"); //lightning + precache_sound ("weapons/lstart.wav"); //lightning start + precache_sound ("items/damage3.wav"); + + precache_sound ("misc/power.wav"); //lightning for boss + +// player gib sounds + precache_sound ("player/gib.wav"); // player gib sound + precache_sound ("player/udeath.wav"); // player gib sound + precache_sound ("player/tornoff2.wav"); // gib sound + +// player pain sounds + + precache_sound ("player/pain1.wav"); + precache_sound ("player/pain2.wav"); + precache_sound ("player/pain3.wav"); + precache_sound ("player/pain4.wav"); + precache_sound ("player/pain5.wav"); + precache_sound ("player/pain6.wav"); + +// player death sounds + precache_sound ("player/death1.wav"); + precache_sound ("player/death2.wav"); + precache_sound ("player/death3.wav"); + precache_sound ("player/death4.wav"); + precache_sound ("player/death5.wav"); + +// ax sounds + precache_sound ("weapons/ax1.wav"); // ax swoosh + precache_sound ("player/axhit1.wav"); // ax hit meat + precache_sound ("player/axhit2.wav"); // ax hit world + + precache_sound ("player/h2ojump.wav"); // player jumping into water + precache_sound ("player/slimbrn2.wav"); // player enter slime + precache_sound ("player/inh2o.wav"); // player enter water + precache_sound ("player/inlava.wav"); // player enter lava + precache_sound ("misc/outwater.wav"); // leaving water sound + + precache_sound ("player/lburn1.wav"); // lava burn + precache_sound ("player/lburn2.wav"); // lava burn + + precache_sound ("misc/water1.wav"); // swimming + precache_sound ("misc/water2.wav"); // swimming + + precache_model ("progs/player.mdl"); + precache_model ("progs/eyes.mdl"); + precache_model ("progs/h_player.mdl"); + + precache_model ("progs/s_bubble.spr"); // drowning bubbles + precache_model ("progs/s_explod.spr"); // sprite explosion + + precache_model ("progs/bolt.mdl"); // for lightning gun + precache_model ("progs/bolt2.mdl"); // for lightning gun + precache_model ("progs/bolt3.mdl"); // for boss shock + precache_model ("progs/lavaball.mdl"); // for testing + + precache_model ("progs/missile.mdl"); + precache_model ("progs/grenade.mdl"); + precache_model ("progs/spike.mdl"); + precache_model ("progs/s_spike.mdl"); + precache_model ("progs/mball.mdl"); //morphball by ghost fang + precache_model ("progs/mbomb.mdl"); + + precache_model ("progs/backpack.mdl"); + + precache_model ("progs/zom_gib.mdl"); + + precache_model ("progs/v_light.mdl"); + + +// +// Setup light animation tables. 'a' is total darkness, 'z' is maxbright. +// + + // 0 normal + lightstyle(0, "m"); + + // 1 FLICKER (first variety) + lightstyle(1, "mmnmmommommnonmmonqnmmo"); + + // 2 SLOW STRONG PULSE + lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); + + // 3 CANDLE (first variety) + lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); + + // 4 FAST STROBE + lightstyle(4, "mamamamamama"); + + // 5 GENTLE PULSE 1 + lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj"); + + // 6 FLICKER (second variety) + lightstyle(6, "nmonqnmomnmomomno"); + + // 7 CANDLE (second variety) + lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm"); + + // 8 CANDLE (third variety) + lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); + + // 9 SLOW STROBE (fourth variety) + lightstyle(9, "aaaaaaaazzzzzzzz"); + + // 10 FLUORESCENT FLICKER + lightstyle(10, "mmamammmmammamamaaamammma"); + + // 11 SLOW PULSE NOT FADE TO BLACK + lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba"); + + // styles 32-62 are assigned by the light program for switchable lights + + // 63 testing + lightstyle(63, "a"); +}; + +void() StartFrame = +{ + BotFrame(); // FrikBot + teamplay = cvar("teamplay"); + skill = cvar("skill"); + framecount = framecount + 1; +}; + +/* +============================================================================== + +BODY QUE + +============================================================================== +*/ + +entity bodyque_head; + +void() bodyque = +{ // just here so spawn functions don't complain after the world + // creates bodyques +}; + +void() InitBodyQue = +{ + + bodyque_head = spawn(); + bodyque_head.classname = "bodyque"; + bodyque_head.owner = spawn(); + bodyque_head.owner.classname = "bodyque"; + bodyque_head.owner.owner = spawn(); + bodyque_head.owner.owner.classname = "bodyque"; + bodyque_head.owner.owner.owner = spawn(); + bodyque_head.owner.owner.owner.classname = "bodyque"; + bodyque_head.owner.owner.owner.owner = bodyque_head; +}; + + +// make a body que entry for the given ent so the ent can be +// respawned elsewhere +void(entity ent) CopyToBodyQue = +{ + bodyque_head.angles = ent.angles; + bodyque_head.model = ent.model; + bodyque_head.modelindex = ent.modelindex; + bodyque_head.frame = ent.frame; + bodyque_head.colormap = ent.colormap; + bodyque_head.movetype = ent.movetype; + bodyque_head.velocity = ent.velocity; + bodyque_head.flags = 0; + setorigin (bodyque_head, ent.origin); + setsize (bodyque_head, ent.mins, ent.maxs); + bodyque_head = bodyque_head.owner; +}; + + diff --git a/r17/Revamped src/Revamped QC/Primeqc4/zombie.qc b/r17/Revamped src/Revamped QC/Primeqc4/zombie.qc new file mode 100755 index 00000000..b431face --- /dev/null +++ b/r17/Revamped src/Revamped QC/Primeqc4/zombie.qc @@ -0,0 +1,515 @@ +/* +============================================================================== + +ZOMBIE + +============================================================================== +*/ +$cd id1/models/zombie + +$origin 0 0 24 + +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 +$frame stand9 stand10 stand11 stand12 stand13 stand14 stand15 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11 +$frame walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 +$frame run13 run14 run15 run16 run17 run18 + +$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8 atta9 atta10 atta11 +$frame atta12 atta13 + +$frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8 attb9 attb10 attb11 +$frame attb12 attb13 attb14 + +$frame attc1 attc2 attc3 attc4 attc5 attc6 attc7 attc8 attc9 attc10 attc11 +$frame attc12 + +$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10 +$frame paina11 paina12 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10 +$frame painb11 painb12 painb13 painb14 painb15 painb16 painb17 painb18 painb19 +$frame painb20 painb21 painb22 painb23 painb24 painb25 painb26 painb27 painb28 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10 +$frame painc11 painc12 painc13 painc14 painc15 painc16 painc17 painc18 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10 +$frame paind11 paind12 paind13 + +$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10 +$frame paine11 paine12 paine13 paine14 paine15 paine16 paine17 paine18 paine19 +$frame paine20 paine21 paine22 paine23 paine24 paine25 paine26 paine27 paine28 +$frame paine29 paine30 + +$frame cruc_1 cruc_2 cruc_3 cruc_4 cruc_5 cruc_6 + +float SPAWN_CRUCIFIED = 1; + +//============================================================================= + +.float inpain; + +void() zombie_stand1 =[ $stand1, zombie_stand2 ] {ai_stand();}; +void() zombie_stand2 =[ $stand2, zombie_stand3 ] {ai_stand();}; +void() zombie_stand3 =[ $stand3, zombie_stand4 ] {ai_stand();}; +void() zombie_stand4 =[ $stand4, zombie_stand5 ] {ai_stand();}; +void() zombie_stand5 =[ $stand5, zombie_stand6 ] {ai_stand();}; +void() zombie_stand6 =[ $stand6, zombie_stand7 ] {ai_stand();}; +void() zombie_stand7 =[ $stand7, zombie_stand8 ] {ai_stand();}; +void() zombie_stand8 =[ $stand8, zombie_stand9 ] {ai_stand();}; +void() zombie_stand9 =[ $stand9, zombie_stand10 ] {ai_stand();}; +void() zombie_stand10 =[ $stand10, zombie_stand11 ] {ai_stand();}; +void() zombie_stand11 =[ $stand11, zombie_stand12 ] {ai_stand();}; +void() zombie_stand12 =[ $stand12, zombie_stand13 ] {ai_stand();}; +void() zombie_stand13 =[ $stand13, zombie_stand14 ] {ai_stand();}; +void() zombie_stand14 =[ $stand14, zombie_stand15 ] {ai_stand();}; +void() zombie_stand15 =[ $stand15, zombie_stand1 ] {ai_stand();}; + +void() zombie_cruc1 = [ $cruc_1, zombie_cruc2 ] { +if (random() < 0.1) + sound (self, CHAN_VOICE, "zombie/idle_w2.wav", 1, ATTN_STATIC);}; +void() zombie_cruc2 = [ $cruc_2, zombie_cruc3 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc3 = [ $cruc_3, zombie_cruc4 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc4 = [ $cruc_4, zombie_cruc5 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc5 = [ $cruc_5, zombie_cruc6 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc6 = [ $cruc_6, zombie_cruc1 ] {self.nextthink = time + 0.1 + random()*0.1;}; + +void() zombie_walk1 =[ $walk1, zombie_walk2 ] {ai_walk(0);}; +void() zombie_walk2 =[ $walk2, zombie_walk3 ] {ai_walk(2);}; +void() zombie_walk3 =[ $walk3, zombie_walk4 ] {ai_walk(3);}; +void() zombie_walk4 =[ $walk4, zombie_walk5 ] {ai_walk(2);}; +void() zombie_walk5 =[ $walk5, zombie_walk6 ] {ai_walk(1);}; +void() zombie_walk6 =[ $walk6, zombie_walk7 ] {ai_walk(0);}; +void() zombie_walk7 =[ $walk7, zombie_walk8 ] {ai_walk(0);}; +void() zombie_walk8 =[ $walk8, zombie_walk9 ] {ai_walk(0);}; +void() zombie_walk9 =[ $walk9, zombie_walk10 ] {ai_walk(0);}; +void() zombie_walk10 =[ $walk10, zombie_walk11 ] {ai_walk(0);}; +void() zombie_walk11 =[ $walk11, zombie_walk12 ] {ai_walk(2);}; +void() zombie_walk12 =[ $walk12, zombie_walk13 ] {ai_walk(2);}; +void() zombie_walk13 =[ $walk13, zombie_walk14 ] {ai_walk(1);}; +void() zombie_walk14 =[ $walk14, zombie_walk15 ] {ai_walk(0);}; +void() zombie_walk15 =[ $walk15, zombie_walk16 ] {ai_walk(0);}; +void() zombie_walk16 =[ $walk16, zombie_walk17 ] {ai_walk(0);}; +void() zombie_walk17 =[ $walk17, zombie_walk18 ] {ai_walk(0);}; +void() zombie_walk18 =[ $walk18, zombie_walk19 ] {ai_walk(0);}; +void() zombie_walk19 =[ $walk19, zombie_walk1 ] { +ai_walk(0); +if (random() < 0.2) + sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);}; + +void() zombie_run1 =[ $run1, zombie_run2 ] {ai_run(1);self.inpain = 0;}; +void() zombie_run2 =[ $run2, zombie_run3 ] {ai_run(1);}; +void() zombie_run3 =[ $run3, zombie_run4 ] {ai_run(0);}; +void() zombie_run4 =[ $run4, zombie_run5 ] {ai_run(1);}; +void() zombie_run5 =[ $run5, zombie_run6 ] {ai_run(2);}; +void() zombie_run6 =[ $run6, zombie_run7 ] {ai_run(3);}; +void() zombie_run7 =[ $run7, zombie_run8 ] {ai_run(4);}; +void() zombie_run8 =[ $run8, zombie_run9 ] {ai_run(4);}; +void() zombie_run9 =[ $run9, zombie_run10 ] {ai_run(2);}; +void() zombie_run10 =[ $run10, zombie_run11 ] {ai_run(0);}; +void() zombie_run11 =[ $run11, zombie_run12 ] {ai_run(0);}; +void() zombie_run12 =[ $run12, zombie_run13 ] {ai_run(0);}; +void() zombie_run13 =[ $run13, zombie_run14 ] {ai_run(2);}; +void() zombie_run14 =[ $run14, zombie_run15 ] {ai_run(4);}; +void() zombie_run15 =[ $run15, zombie_run16 ] {ai_run(6);}; +void() zombie_run16 =[ $run16, zombie_run17 ] {ai_run(7);}; +void() zombie_run17 =[ $run17, zombie_run18 ] {ai_run(3);}; +void() zombie_run18 =[ $run18, zombie_run1 ] { +ai_run(8); +if (random() < 0.2) + sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE); +if (random() > 0.8) + sound (self, CHAN_VOICE, "zombie/z_idle1.wav", 1, ATTN_IDLE); +}; + +/* +============================================================================= + +ATTACKS + +============================================================================= +*/ + +void() ZombieGrenadeTouch = +{ + if (other == self.owner) + return; // don't explode on owner + if (other.takedamage) + { + T_Damage (other, self, self.owner, 10 ); + sound (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM); + remove (self); + return; + } + sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound + self.velocity = '0 0 0'; + self.avelocity = '0 0 0'; + self.touch = SUB_Remove; +}; + +/* +================ +ZombieFireGrenade +================ +*/ +void(vector st) ZombieFireGrenade = +{ + local entity missile; + local vector org; + + sound (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM); + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_BOUNCE; + missile.solid = SOLID_BBOX; + +// calc org + org = self.origin + st_x * v_forward + st_y * v_right + (st_z - 24) * v_up; + +// set missile speed + + makevectors (self.angles); + + missile.velocity = normalize(self.enemy.origin - org); + missile.velocity = missile.velocity * 600; + missile.velocity_z = 200; + + missile.avelocity = '3000 1000 2000'; + + missile.touch = ZombieGrenadeTouch; + +// set missile duration + missile.nextthink = time + 2.5; + missile.think = SUB_Remove; + + setmodel (missile, "progs/zom_gib.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, org); +}; + + +void() zombie_atta1 =[ $atta1, zombie_atta2 ] {ai_face();}; +void() zombie_atta2 =[ $atta2, zombie_atta3 ] {ai_face();}; +void() zombie_atta3 =[ $atta3, zombie_atta4 ] {ai_face();}; +void() zombie_atta4 =[ $atta4, zombie_atta5 ] {ai_face();}; +void() zombie_atta5 =[ $atta5, zombie_atta6 ] {ai_face();}; +void() zombie_atta6 =[ $atta6, zombie_atta7 ] {ai_face();}; +void() zombie_atta7 =[ $atta7, zombie_atta8 ] {ai_face();}; +void() zombie_atta8 =[ $atta8, zombie_atta9 ] {ai_face();}; +void() zombie_atta9 =[ $atta9, zombie_atta10 ] {ai_face();}; +void() zombie_atta10 =[ $atta10, zombie_atta11 ] {ai_face();}; +void() zombie_atta11 =[ $atta11, zombie_atta12 ] {ai_face();}; +void() zombie_atta12 =[ $atta12, zombie_atta13 ] {ai_face();}; +void() zombie_atta13 =[ $atta13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -22 30');}; + +void() zombie_attb1 =[ $attb1, zombie_attb2 ] {ai_face();}; +void() zombie_attb2 =[ $attb2, zombie_attb3 ] {ai_face();}; +void() zombie_attb3 =[ $attb3, zombie_attb4 ] {ai_face();}; +void() zombie_attb4 =[ $attb4, zombie_attb5 ] {ai_face();}; +void() zombie_attb5 =[ $attb5, zombie_attb6 ] {ai_face();}; +void() zombie_attb6 =[ $attb6, zombie_attb7 ] {ai_face();}; +void() zombie_attb7 =[ $attb7, zombie_attb8 ] {ai_face();}; +void() zombie_attb8 =[ $attb8, zombie_attb9 ] {ai_face();}; +void() zombie_attb9 =[ $attb9, zombie_attb10 ] {ai_face();}; +void() zombie_attb10 =[ $attb10, zombie_attb11 ] {ai_face();}; +void() zombie_attb11 =[ $attb11, zombie_attb12 ] {ai_face();}; +void() zombie_attb12 =[ $attb12, zombie_attb13 ] {ai_face();}; +void() zombie_attb13 =[ $attb13, zombie_attb14 ] {ai_face();}; +void() zombie_attb14 =[ $attb13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -24 29');}; + +void() zombie_attc1 =[ $attc1, zombie_attc2 ] {ai_face();}; +void() zombie_attc2 =[ $attc2, zombie_attc3 ] {ai_face();}; +void() zombie_attc3 =[ $attc3, zombie_attc4 ] {ai_face();}; +void() zombie_attc4 =[ $attc4, zombie_attc5 ] {ai_face();}; +void() zombie_attc5 =[ $attc5, zombie_attc6 ] {ai_face();}; +void() zombie_attc6 =[ $attc6, zombie_attc7 ] {ai_face();}; +void() zombie_attc7 =[ $attc7, zombie_attc8 ] {ai_face();}; +void() zombie_attc8 =[ $attc8, zombie_attc9 ] {ai_face();}; +void() zombie_attc9 =[ $attc9, zombie_attc10 ] {ai_face();}; +void() zombie_attc10 =[ $attc10, zombie_attc11 ] {ai_face();}; +void() zombie_attc11 =[ $attc11, zombie_attc12 ] {ai_face();}; +void() zombie_attc12 =[ $attc12, zombie_run1 ] {ai_face();ZombieFireGrenade('-12 -19 29');}; + +void() zombie_missile = +{ + local float r; + + r = random(); + + if (r < 0.3) + zombie_atta1 (); + else if (r < 0.6) + zombie_attb1 (); + else + zombie_attc1 (); +}; + + +/* +============================================================================= + +PAIN + +============================================================================= +*/ + +void() zombie_paina1 =[ $paina1, zombie_paina2 ] {sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);}; +void() zombie_paina2 =[ $paina2, zombie_paina3 ] {ai_painforward(3);}; +void() zombie_paina3 =[ $paina3, zombie_paina4 ] {ai_painforward(1);}; +void() zombie_paina4 =[ $paina4, zombie_paina5 ] {ai_pain(1);}; +void() zombie_paina5 =[ $paina5, zombie_paina6 ] {ai_pain(3);}; +void() zombie_paina6 =[ $paina6, zombie_paina7 ] {ai_pain(1);}; +void() zombie_paina7 =[ $paina7, zombie_paina8 ] {}; +void() zombie_paina8 =[ $paina8, zombie_paina9 ] {}; +void() zombie_paina9 =[ $paina9, zombie_paina10 ] {}; +void() zombie_paina10 =[ $paina10, zombie_paina11 ] {}; +void() zombie_paina11 =[ $paina11, zombie_paina12 ] {}; +void() zombie_paina12 =[ $paina12, zombie_run1 ] {}; + +void() zombie_painb1 =[ $painb1, zombie_painb2 ] {sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);}; +void() zombie_painb2 =[ $painb2, zombie_painb3 ] {ai_pain(2);}; +void() zombie_painb3 =[ $painb3, zombie_painb4 ] {ai_pain(8);}; +void() zombie_painb4 =[ $painb4, zombie_painb5 ] {ai_pain(6);}; +void() zombie_painb5 =[ $painb5, zombie_painb6 ] {ai_pain(2);}; +void() zombie_painb6 =[ $painb6, zombie_painb7 ] {}; +void() zombie_painb7 =[ $painb7, zombie_painb8 ] {}; +void() zombie_painb8 =[ $painb8, zombie_painb9 ] {}; +void() zombie_painb9 =[ $painb9, zombie_painb10 ] {sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);}; +void() zombie_painb10 =[ $painb10, zombie_painb11 ] {}; +void() zombie_painb11 =[ $painb11, zombie_painb12 ] {}; +void() zombie_painb12 =[ $painb12, zombie_painb13 ] {}; +void() zombie_painb13 =[ $painb13, zombie_painb14 ] {}; +void() zombie_painb14 =[ $painb14, zombie_painb15 ] {}; +void() zombie_painb15 =[ $painb15, zombie_painb16 ] {}; +void() zombie_painb16 =[ $painb16, zombie_painb17 ] {}; +void() zombie_painb17 =[ $painb17, zombie_painb18 ] {}; +void() zombie_painb18 =[ $painb18, zombie_painb19 ] {}; +void() zombie_painb19 =[ $painb19, zombie_painb20 ] {}; +void() zombie_painb20 =[ $painb20, zombie_painb21 ] {}; +void() zombie_painb21 =[ $painb21, zombie_painb22 ] {}; +void() zombie_painb22 =[ $painb22, zombie_painb23 ] {}; +void() zombie_painb23 =[ $painb23, zombie_painb24 ] {}; +void() zombie_painb24 =[ $painb24, zombie_painb25 ] {}; +void() zombie_painb25 =[ $painb25, zombie_painb26 ] {ai_painforward(1);}; +void() zombie_painb26 =[ $painb26, zombie_painb27 ] {}; +void() zombie_painb27 =[ $painb27, zombie_painb28 ] {}; +void() zombie_painb28 =[ $painb28, zombie_run1 ] {}; + +void() zombie_painc1 =[ $painc1, zombie_painc2 ] {sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);}; +void() zombie_painc2 =[ $painc2, zombie_painc3 ] {}; +void() zombie_painc3 =[ $painc3, zombie_painc4 ] {ai_pain(3);}; +void() zombie_painc4 =[ $painc4, zombie_painc5 ] {ai_pain(1);}; +void() zombie_painc5 =[ $painc5, zombie_painc6 ] {}; +void() zombie_painc6 =[ $painc6, zombie_painc7 ] {}; +void() zombie_painc7 =[ $painc7, zombie_painc8 ] {}; +void() zombie_painc8 =[ $painc8, zombie_painc9 ] {}; +void() zombie_painc9 =[ $painc9, zombie_painc10 ] {}; +void() zombie_painc10 =[ $painc10, zombie_painc11 ] {}; +void() zombie_painc11 =[ $painc11, zombie_painc12 ] {ai_painforward(1);}; +void() zombie_painc12 =[ $painc12, zombie_painc13 ] {ai_painforward(1);}; +void() zombie_painc13 =[ $painc13, zombie_painc14 ] {}; +void() zombie_painc14 =[ $painc14, zombie_painc15 ] {}; +void() zombie_painc15 =[ $painc15, zombie_painc16 ] {}; +void() zombie_painc16 =[ $painc16, zombie_painc17 ] {}; +void() zombie_painc17 =[ $painc17, zombie_painc18 ] {}; +void() zombie_painc18 =[ $painc18, zombie_run1 ] {}; + +void() zombie_paind1 =[ $paind1, zombie_paind2 ] {sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);}; +void() zombie_paind2 =[ $paind2, zombie_paind3 ] {}; +void() zombie_paind3 =[ $paind3, zombie_paind4 ] {}; +void() zombie_paind4 =[ $paind4, zombie_paind5 ] {}; +void() zombie_paind5 =[ $paind5, zombie_paind6 ] {}; +void() zombie_paind6 =[ $paind6, zombie_paind7 ] {}; +void() zombie_paind7 =[ $paind7, zombie_paind8 ] {}; +void() zombie_paind8 =[ $paind8, zombie_paind9 ] {}; +void() zombie_paind9 =[ $paind9, zombie_paind10 ] {ai_pain(1);}; +void() zombie_paind10 =[ $paind10, zombie_paind11 ] {}; +void() zombie_paind11 =[ $paind11, zombie_paind12 ] {}; +void() zombie_paind12 =[ $paind12, zombie_paind13 ] {}; +void() zombie_paind13 =[ $paind13, zombie_run1 ] {}; + +void() zombie_paine1 =[ $paine1, zombie_paine2 ] { +sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM); +self.health = 60; +}; +void() zombie_paine2 =[ $paine2, zombie_paine3 ] {ai_pain(8);}; +void() zombie_paine3 =[ $paine3, zombie_paine4 ] {ai_pain(5);}; +void() zombie_paine4 =[ $paine4, zombie_paine5 ] {ai_pain(3);}; +void() zombie_paine5 =[ $paine5, zombie_paine6 ] {ai_pain(1);}; +void() zombie_paine6 =[ $paine6, zombie_paine7 ] {ai_pain(2);}; +void() zombie_paine7 =[ $paine7, zombie_paine8 ] {ai_pain(1);}; +void() zombie_paine8 =[ $paine8, zombie_paine9 ] {ai_pain(1);}; +void() zombie_paine9 =[ $paine9, zombie_paine10 ] {ai_pain(2);}; +void() zombie_paine10 =[ $paine10, zombie_paine11 ] { +sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM); +self.solid = SOLID_NOT; +}; +void() zombie_paine11 =[ $paine11, zombie_paine12 ] {self.nextthink = self.nextthink + 5;self.health = 60;}; +void() zombie_paine12 =[ $paine12, zombie_paine13 ]{ +// see if ok to stand up +self.health = 60; +sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE); +self.solid = SOLID_SLIDEBOX; +if (!walkmove (0, 0)) +{ + self.think = zombie_paine11; + self.solid = SOLID_NOT; + return; +} +}; +void() zombie_paine13 =[ $paine13, zombie_paine14 ] {}; +void() zombie_paine14 =[ $paine14, zombie_paine15 ] {}; +void() zombie_paine15 =[ $paine15, zombie_paine16 ] {}; +void() zombie_paine16 =[ $paine16, zombie_paine17 ] {}; +void() zombie_paine17 =[ $paine17, zombie_paine18 ] {}; +void() zombie_paine18 =[ $paine18, zombie_paine19 ] {}; +void() zombie_paine19 =[ $paine19, zombie_paine20 ] {}; +void() zombie_paine20 =[ $paine20, zombie_paine21 ] {}; +void() zombie_paine21 =[ $paine21, zombie_paine22 ] {}; +void() zombie_paine22 =[ $paine22, zombie_paine23 ] {}; +void() zombie_paine23 =[ $paine23, zombie_paine24 ] {}; +void() zombie_paine24 =[ $paine24, zombie_paine25 ] {}; +void() zombie_paine25 =[ $paine25, zombie_paine26 ] {ai_painforward(5);}; +void() zombie_paine26 =[ $paine26, zombie_paine27 ] {ai_painforward(3);}; +void() zombie_paine27 =[ $paine27, zombie_paine28 ] {ai_painforward(1);}; +void() zombie_paine28 =[ $paine28, zombie_paine29 ] {ai_pain(1);}; +void() zombie_paine29 =[ $paine29, zombie_paine30 ] {}; +void() zombie_paine30 =[ $paine30, zombie_run1 ] {}; + +void() zombie_die = +{ + sound (self, CHAN_VOICE, "zombie/z_gib.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_zombie.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); +}; + +/* +================= +zombie_pain + +Zombies can only be killed (gibbed) by doing 60 hit points of damage +in a single frame (rockets, grenades, quad shotgun, quad nailgun). + +A hit of 25 points or more (super shotgun, quad nailgun) will allways put it +down to the ground. + +A hit of from 10 to 40 points in one frame will cause it to go down if it +has been twice in two seconds, otherwise it goes into one of the four +fast pain frames. + +A hit of less than 10 points of damage (winged by a shotgun) will be ignored. + +FIXME: don't use pain_finished because of nightmare hack +================= +*/ +void(entity attacker, float take) zombie_pain = +{ + local float r; + + self.health = 60; // allways reset health + + if (take < 9) + return; // totally ignore + + if (self.inpain == 2) + return; // down on ground, so don't reset any counters + +// go down immediately if a big enough hit + if (take >= 25) + { + self.inpain = 2; + zombie_paine1 (); + return; + } + + if (self.inpain) + { +// if hit again in next gre seconds while not in pain frames, definately drop + self.pain_finished = time + 3; + return; // currently going through an animation, don't change + } + + if (self.pain_finished > time) + { +// hit again, so drop down + self.inpain = 2; + zombie_paine1 (); + return; + } + +// gp into one of the fast pain animations + self.inpain = 1; + + r = random(); + if (r < 0.25) + zombie_paina1 (); + else if (r < 0.5) + zombie_painb1 (); + else if (r < 0.75) + zombie_painc1 (); + else + zombie_paind1 (); +}; + +//============================================================================ + +/*QUAKED monster_zombie (1 0 0) (-16 -16 -24) (16 16 32) Crucified ambush + +If crucified, stick the bounding box 12 pixels back into a wall to look right. +*/ +void() monster_zombie = +{ + if (deathmatch) + { + remove(self); + return; + } + + precache_model ("progs/zombie.mdl"); + precache_model ("progs/h_zombie.mdl"); + precache_model ("progs/zom_gib.mdl"); + + precache_sound ("zombie/z_idle.wav"); + precache_sound ("zombie/z_idle1.wav"); + precache_sound ("zombie/z_shot1.wav"); + precache_sound ("zombie/z_gib.wav"); + precache_sound ("zombie/z_pain.wav"); + precache_sound ("zombie/z_pain1.wav"); + precache_sound ("zombie/z_fall.wav"); + precache_sound ("zombie/z_miss.wav"); + precache_sound ("zombie/z_hit.wav"); + precache_sound ("zombie/idle_w2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/zombie.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 60; + + self.th_stand = zombie_stand1; + self.th_walk = zombie_walk1; + self.th_run = zombie_run1; + self.th_pain = zombie_pain; + self.th_die = zombie_die; + self.th_missile = zombie_missile; + + if (self.spawnflags & SPAWN_CRUCIFIED) + { + self.movetype = MOVETYPE_NONE; + zombie_cruc1 (); + } + else + walkmonster_start(); +}; diff --git a/r17/Revamped src/Revamped QC/ai.qc b/r17/Revamped src/Revamped QC/ai.qc new file mode 100755 index 00000000..16169f77 --- /dev/null +++ b/r17/Revamped src/Revamped QC/ai.qc @@ -0,0 +1,751 @@ +void() t_movetarget; +/* + +.enemy +Will be world if not currently angry at anyone. + +.movetarget +The next path spot to walk toward. If .enemy, ignore .movetarget. +When an enemy is killed, the monster will try to return to it's path. + +.huntt_ime +Set to time + something when the player is in sight, but movement straight for +him is blocked. This causes the monster to use wall following code for +movement direction instead of sighting on the player. + +.ideal_yaw +A yaw angle of the intended direction, which will be turned towards at up +to 45 deg / state. If the enemy is in view and hunt_time is not active, +this will be the exact line towards the enemy. + +.pausetime +A monster will leave it's stand state and head towards it's .movetarget when +time > .pausetime. + +walkmove(angle, speed) primitive is all or nothing +*/ + +// +// when a monster becomes angry at a player, that monster will be used +// as the sight target the next frame so that monsters near that one +// will wake up even if they wouldn't have noticed the player +// +entity sight_entity; +float sight_entity_time; + +float(float v) anglemod = +{ + while (v >= 360) + v = v - 360; + while (v < 0) + v = v + 360; + return v; +}; + +/* +============================================================================== + +MOVETARGET CODE + +The angle of the movetarget effects standing and bowing direction, but has no effect on movement, which allways heads to the next target. + +targetname +must be present. The name of this movetarget. + +target +the next spot to move to. If not present, stop here for good. + +pausetime +The number of seconds to spend standing or bowing for path_stand or path_bow + +============================================================================== +*/ + + +void() movetarget_f = +{ + if (!self.targetname) + objerror ("monster_movetarget: no targetname"); + + self.solid = SOLID_TRIGGER; + self.touch = t_movetarget; + setsize (self, '-8 -8 -8', '8 8 8'); + +}; + +/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8) +Monsters will continue walking towards the next target corner. +*/ +void() path_corner = +{ + movetarget_f (); +}; + + +/* +============= +t_movetarget + +Something has bumped into a movetarget. If it is a monster +moving towards it, change the next destination and continue. +============== +*/ +void() t_movetarget = +{ +local entity temp; + + if (other.movetarget != self) + return; + + if (other.enemy) + return; // fighting, not following a path + + temp = self; + self = other; + other = temp; + + if (self.classname == "monster_ogre") + sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);// play chainsaw drag sound + +//dprint ("t_movetarget\n"); + self.goalentity = self.movetarget = find (world, targetname, other.target); + self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); + if (!self.movetarget) + { + self.pausetime = time + 999999; + self.th_stand (); + return; + } +}; + + + +//============================================================================ + +/* +============= +range + +returns the range catagorization of an entity reletive to self +0 melee range, will become hostile even if back is turned +1 visibility and infront, or visibility and show hostile +2 infront and show hostile +3 only triggered by damage +============= +*/ +float(entity targ) range = +{ + local vector spot1, spot2; + local float r; + + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + r = vlen (spot1 - spot2); + if (r < 120) + return RANGE_MELEE; + if (r < 500) + return RANGE_NEAR; + if (r < 1000) + return RANGE_MID; + return RANGE_FAR; +}; + +/* +============= +visible + +returns 1 if the entity is visible to self, even if not infront () +============= +*/ +BOOL (entity targ) visible = +{ + local vector spot1, spot2; + + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + traceline (spot1, spot2, TRUE, self); // see through other monsters + + if (trace_inopen && trace_inwater) + return FALSE; // sight line crossed contents + + if (trace_fraction == 1) + return TRUE; + return FALSE; +}; + + +/* +============= +infront + +returns 1 if the entity is in front (in sight) of self +============= +*/ +BOOL(entity targ) infront = +{ + local vector vec; + local float dot; + + makevectors (self.angles); + vec = normalize (targ.origin - self.origin); + dot = vec * v_forward; + + if ( dot > 0.3) + { + return TRUE; + } + return FALSE; +}; + + +//============================================================================ + +/* +=========== +ChangeYaw + +Turns towards self.ideal_yaw at self.yaw_speed +Sets the global variable current_yaw +Called every 0.1 sec by monsters +============ +*/ +/* +void() ChangeYaw = +{ + local float ideal, move, current_yaw; + +//current_yaw = self.ideal_yaw; +// mod down the current angle + current_yaw = anglemod( self.angles_y ); + ideal = self.ideal_yaw; + + if (current_yaw == ideal) + return; + + move = ideal - current_yaw; + if (ideal > current_yaw) + { + if (move > 180) + move = move - 360; + } + else + { + if (move < -180) + move = move + 360; + } + + if (move > 0) + { + if (move > self.yaw_speed) + move = self.yaw_speed; + } + else + { + if (move < 0-self.yaw_speed ) + move = 0-self.yaw_speed; + } + + current_yaw = anglemod (current_yaw + move); + + self.angles_y = current_yaw; +}; +*/ + + +//============================================================================ + +void() HuntTarget = +{ + self.goalentity = self.enemy; + self.think = self.th_run; + self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); + self.nextthink = time + 0.1; + SUB_AttackFinished (1); // wait a while before first attack +}; + +void() SightSound = +{ + local float rsnd; + local string s; + + switch (self.classname) + { + case "monster_ogre": + s = "ogre/ogwake.wav"; + break; + case "monster_knight": + s = "knight/ksight.wav"; + break; + case "monster_shambler": + s = "shambler/ssight.wav"; + break; + case "monster_demon1": + s = "demon/sight2.wav"; + break; + case "monster_wizard": + s = "wizard/wsight.wav"; + break; + case "monster_zombie": + s = "zombie/z_idle.wav"; + break; + case "monster_dog": + s = "dog/dsight.wav"; + break; + case "monster_hell_knight": + s = "hknight/sight1.wav"; + break; + case "monster_tarbaby": + s = "blob/sight1.wav"; + break; + case "monster_enforcer": + rsnd = random(); + if (rsnd < 0.25) + s = "enforcer/sight1.wav"; + else if (rsnd < 0.5) + s = "enforcer/sight2.wav"; + else if (rsnd < 0.75) + s = "enforcer/sight3.wav"; + else + s = "enforcer/sight4.wav"; + break; + case "monster_shalrath": + s = "shalrath/sight.wav"; + break; + default: + s = "soldier/sight1.wav"; + } + + sound (self, CHAN_VOICE, s, 1, ATTN_NORM); +}; + +void() FoundTarget = +{ + if (self.enemy.classname == "player") + { // let other monsters see this monster for a while + sight_entity = self; + sight_entity_time = time; + } + + self.show_hostile = time + 1; // wake up other monsters + + SightSound (); + HuntTarget (); +}; + +/* +=========== +FindTarget + +Self is currently not attacking anything, so try to find a target + +Returns TRUE if an enemy was sighted + +When a player fires a missile, the point of impact becomes a fakeplayer so +that monsters that see the impact will respond as if they had seen the +player. + +To avoid spending too much time, only a single client (or fakeclient) is +checked each frame. This means multi player games will have slightly +slower noticing monsters. +============ +*/ +BOOL() FindTarget = +{ + local entity client; + local float r; + +// if the first spawnflag bit is set, the monster will only wake up on +// really seeing the player, not another monster getting angry + +// spawnflags & 3 is a big hack, because zombie crucified used the first +// spawn flag prior to the ambush flag, and I forgot about it, so the second +// spawn flag works as well + if (sight_entity_time >= time - 0.1 && !(self.spawnflags & 3) ) + { + client = sight_entity; + if (client.enemy == self.enemy) + return TRUE; + } + else + { + client = checkclient (); + if (!client) + return FALSE; // current check entity isn't in PVS + } + + if (client == self.enemy) + return FALSE; + + if (client.flags & FL_NOTARGET) + return FALSE; + if (client.items & IT_INVISIBILITY) + return FALSE; + + r = range (client); + if (r == RANGE_FAR) + return FALSE; + + if (!visible (client)) + return FALSE; + + if (r == RANGE_NEAR) + { + if (client.show_hostile < time && !infront (client)) + return FALSE; + } + else if (r == RANGE_MID) + { + if ( /* client.show_hostile < time || */ !infront (client)) + return FALSE; + } + +// +// got one +// + self.enemy = client; + if (self.enemy.classname != "player") + { + self.enemy = self.enemy.enemy; + if (self.enemy.classname != "player") + { + self.enemy = world; + return FALSE; + } + } + + FoundTarget (); + + return TRUE; +}; + + +//============================================================================= + +void(float dist) ai_forward = +{ + walkmove (self.angles_y, dist); +}; + +void(float dist) ai_back = +{ + walkmove ( (self.angles_y+180), dist); +}; + + +/* +============= +ai_pain + +stagger back a bit +============= +*/ +void(float dist) ai_pain = +{ + ai_back (dist); +/* + local float away; + + away = anglemod (vectoyaw (self.origin - self.enemy.origin) + + 180*(random()- 0.5) ); + + walkmove (away, dist); +*/ +}; + +/* +============= +ai_painforward + +stagger back a bit +============= +*/ +void(float dist) ai_painforward = +{ + walkmove (self.ideal_yaw, dist); +}; + +/* +============= +ai_walk + +The monster is walking it's beat +============= +*/ +void(float dist) ai_walk = +{ +// movedist = dist; + + /* + There are no dragons! + if (self.classname == "monster_dragon") + { + movetogoal (dist); + return; + } + */ + + // check for noticing a player + if (FindTarget ()) + return; + + movetogoal (dist); +}; + + +/* +============= +ai_stand + +The monster is staying in one place for a while, with slight angle turns +============= +*/ +void() ai_stand = +{ + if (FindTarget ()) + return; + + if (time > self.pausetime) + { + self.th_walk (); + return; + } + +// change angle slightly + +}; + +/* +============= +ai_turn + +don't move, but turn towards ideal_yaw +============= +*/ +void() ai_turn = +{ + if (FindTarget ()) + return; + + ChangeYaw (); +}; + +//============================================================================= + +/* +============= +ChooseTurn +============= +*/ +/* +void(vector dest3) ChooseTurn = +{ + local vector dir, newdir; + + dir = self.origin - dest3; + + newdir_x = trace_plane_normal_y; + newdir_y = 0 - trace_plane_normal_x; + newdir_z = 0; + + if (dir * newdir > 0) + { + dir_x = 0 - trace_plane_normal_y; + dir_y = trace_plane_normal_x; + } + else + { + dir_x = trace_plane_normal_y; + dir_y = 0 - trace_plane_normal_x; + } + + dir_z = 0; + self.ideal_yaw = vectoyaw(dir); +}; +*/ + +/* +============ +FacingIdeal + +============ +*/ +BOOL() FacingIdeal = +{ + local float delta; + + delta = anglemod(self.angles_y - self.ideal_yaw); + if (delta > 45 && delta < 315) + return FALSE; + return TRUE; +}; + + +//============================================================================= +BOOL(float enemy_range) DogCheckAttack; +BOOL(float enemy_range) WizardCheckAttack; +BOOL(float enemy_range) DemonCheckAttack; + +BOOL(float enemy_range) CheckAnyAttack = +{ + + switch (self.classname) + { + case "monster_army": + return SoldierCheckAttack (enemy_range); + case "monster_ogre": + return OgreCheckAttack (enemy_range); + case "monster_shambler": + return ShamCheckAttack (enemy_range); + case "monster_demon1": + return DemonCheckAttack (enemy_range); + case "monster_dog": + return DogCheckAttack (enemy_range); + case "monster_wizard": + return WizardCheckAttack (enemy_range); + } + + return CheckAttack (enemy_range); +}; + + +/* +============= +ai_run_melee + +Turn and close until within an angle to launch a melee attack +============= +*/ +void(float enemy_yaw) ai_run_melee = +{ + self.ideal_yaw = enemy_yaw; + ChangeYaw (); + + if (FacingIdeal()) + { + self.th_melee (); + self.attack_state = AS_STRAIGHT; + } +}; + + +/* +============= +ai_run_missile + +Turn in place until within an angle to launch a missile attack +============= +*/ +void(float enemy_yaw) ai_run_missile = +{ + self.ideal_yaw = enemy_yaw; + ChangeYaw (); + if (FacingIdeal()) + { + self.th_missile (); + self.attack_state = AS_STRAIGHT; + } +}; + + +/* +============= +ai_run_slide + +Strafe sideways, but stay at aproximately the same range +============= +*/ +void(float enemy_yaw, float movedist) ai_run_slide = +{ + local float ofs; + + self.ideal_yaw = enemy_yaw; + ChangeYaw (); + if (self.lefty) + ofs = 90; + else + ofs = -90; + + if (walkmove (self.ideal_yaw + ofs, movedist)) + return; + + self.lefty = 1 - self.lefty; + + walkmove (self.ideal_yaw - ofs, movedist); +}; + +/* +============= +ai_run + +The monster has an enemy it is trying to kill +============= +*/ +void(float dist) ai_run = +{ + local float enemy_vis, enemy_yaw; + +// see if the enemy is dead + if (self.enemy.health <= 0) + { + self.enemy = world; + // FIXME: look all around for other targets + if (self.oldenemy.health > 0) + { + self.enemy = self.oldenemy; + HuntTarget (); + } + else + { + if (self.movetarget) + self.th_walk (); + else + self.th_stand (); + return; + } + } + + self.show_hostile = time + 1; // wake up other monsters + +// check knowledge of enemy + enemy_vis = visible(self.enemy); + if (enemy_vis) + self.search_time = time + 5; + +// look for other coop players + if (coop && self.search_time < time) + { + if (FindTarget ()) + return; + } + + enemy_yaw = vectoyaw(self.enemy.origin - self.origin); + + if (self.attack_state == AS_MISSILE) + { + ai_run_missile (enemy_yaw); + return; + } + if (self.attack_state == AS_MELEE) + { + ai_run_melee (enemy_yaw); + return; + } + + if (!enemy_vis) + return; + + if (CheckAnyAttack (range(self.enemy))) + return; // beginning an attack + + if (self.attack_state == AS_SLIDING) + { + ai_run_slide (enemy_yaw, dist); + return; + } + +// head straight in + movetogoal (dist); // done in C code... +}; + + \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/basemod.txt b/r17/Revamped src/Revamped QC/basemod.txt new file mode 100755 index 00000000..d93e8ef0 --- /dev/null +++ b/r17/Revamped src/Revamped QC/basemod.txt @@ -0,0 +1,42 @@ +Incomplete - +Triggered kills (explobox, etc) +Q2/Q3 ents +HL ents + +Done - +Cleanup warnings +Fix QW bugs +Heal decay (over maxhealth) +INTEGER mod +Nailgun frame seperation +Body queue change +Suicide timer limit +Suicide backpack/quad/ring drop +Condense bprint, sprint, centerprints +te_explode sprite +NQ/QW cross compatibility +Track oldbutton presses/weaponstate +Generic projectile spawning +Usage of ammo_shells, etc as display + +In progress - +Item fixing for SP +Add monsters back + +Todo - +Fix ammo_shells, etc for monsters/backpacks +Samelevel 4 (exit acts as a spawnpoint teleporter) +Effects/decal system +Fix weird deathmatch modes, cvar checking +Rogue/hipnotic weapons/monsters/hud stuffs +H2 ents +Coop friendly finale +Add in shambler resistance in a better way + +Stray Ideas - +Advanced heal decay (only decay health that the megahealth added?) +Clean up backpack pickup prints? +Decal system based on visibility from players? +CSQC? +Don't use newmis/spawn projectiles in front? +sv_gravity change? diff --git a/r17/Revamped src/Revamped QC/bindings.qc b/r17/Revamped src/Revamped QC/bindings.qc new file mode 100755 index 00000000..120486db --- /dev/null +++ b/r17/Revamped src/Revamped QC/bindings.qc @@ -0,0 +1,42 @@ +void () +player_bindings = +{ + stuffcmd (self, "r_novis 0\n"); + stuffcmd (self, "alias r_novis \n"); + stuffcmd (self, "r_wateralpha 1\n"); + stuffcmd (self, "alias r_wateralpha echo r_wateralpha has been disabled on this server.\n"); + stuffcmd (self, "chase_active 0\n"); + stuffcmd (self, "alias chase_active echo chase_active has been disabled on this server.\n"); + stuffcmd (self, "r_draworder 0\n"); + stuffcmd (self, "alias r_draworder echo r_draworder has been disabled on this server.\n"); + stuffcmd (self, "alias scr_ofsx echo screen offsets have been disabled on this server.\n"); + stuffcmd (self, "alias scr_ofsy echo screen offsets have been disabled on this server.\n"); + stuffcmd (self, "alias scr_ofsz echo screen offsets have been disabled on this server.\n"); + + vote_aliases (); + self.pflag = self.pflag | POQ_BINDINGS_SENT; + + bprint ("Player Bindings Sent\n"); +}; + +void () +player_bindings_think = +{ + local entity e; + + e = self; + self = e.owner; + remove (e); + player_bindings (); +}; + +void () +player_bindings_begin = +{ + local entity e; + + e = spawn (); + e.owner = self; + e.think = player_bindings_think; + e.nextthink = time + 2; +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/buttons.qc b/r17/Revamped src/Revamped QC/buttons.qc new file mode 100755 index 00000000..4e85b3e8 --- /dev/null +++ b/r17/Revamped src/Revamped QC/buttons.qc @@ -0,0 +1,138 @@ +// button and multiple button + +void() button_wait; +void() button_return; + +void() button_wait = +{ + self.state = STATE_TOP; + self.nextthink = self.ltime + self.wait; + self.think = button_return; + activator = self.enemy; + SUB_UseTargets(); + self.frame = 1; // use alternate textures +}; + +void() button_done = +{ + self.state = STATE_BOTTOM; +}; + +void() button_return = +{ + self.state = STATE_DOWN; + SUB_CalcMove (self.pos1, self.speed, button_done); + self.frame = 0; // use normal textures + if (self.health) + self.takedamage = DAMAGE_YES; // can be shot again +}; + + +void() button_blocked = +{ // do nothing, just don't ome all the way back out +}; + + +void() button_fire = +{ + if (self.state == STATE_UP || self.state == STATE_TOP) + return; + + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + + self.state = STATE_UP; + SUB_CalcMove (self.pos2, self.speed, button_wait); +}; + + +void() button_use = +{ + self.enemy = activator; + button_fire (); +}; + +void() button_touch = +{ + if (other.classname != "player") + return; + self.enemy = other; + button_fire (); +}; + +void() button_killed = +{ + self.enemy = damage_attacker; + self.health = self.max_health; + self.takedamage = DAMAGE_NO; // wil be reset upon return + button_fire (); +}; + + +/*QUAKED func_button (0 .5 .8) ? +When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again. + +"angle" determines the opening direction +"target" all entities with a matching targetname will be used +"speed" override the default 40 speed +"wait" override the default 1 second wait (-1 = never return) +"lip" override the default 4 pixel lip remaining at end of move +"health" if set, the button must be killed instead of touched +"sounds" +0) steam metal +1) wooden clunk +2) metallic click +3) in-out +*/ +void() func_button = +{ + switch (self.sounds) + { + case 0: + precache_sound ("buttons/airbut1.wav"); + self.noise = "buttons/airbut1.wav"; + break; + case 1: + precache_sound ("buttons/switch21.wav"); + self.noise = "buttons/switch21.wav"; + break; + case 2: + precache_sound ("buttons/switch02.wav"); + self.noise = "buttons/switch02.wav"; + break; + case 3: + precache_sound ("buttons/switch04.wav"); + self.noise = "buttons/switch04.wav"; + break; + } + + SetMovedir (); + + self.movetype = MOVETYPE_PUSH; + self.solid = SOLID_BSP; + setmodel (self, self.model); + + self.blocked = button_blocked; + self.use = button_use; + + if (self.health) + { + self.max_health = self.health; + self.th_die = button_killed; + self.takedamage = DAMAGE_YES; + } + else + self.touch = button_touch; + + if (!self.speed) + self.speed = 40; + if (!self.wait) + self.wait = 1; + if (!self.lip) + self.lip = 4; + + self.state = STATE_BOTTOM; + + self.pos1 = self.origin; + self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip); +}; + diff --git a/r17/Revamped src/Revamped QC/client.qc b/r17/Revamped src/Revamped QC/client.qc new file mode 100755 index 00000000..f20d7e57 --- /dev/null +++ b/r17/Revamped src/Revamped QC/client.qc @@ -0,0 +1,1518 @@ + +// prototypes +void () W_WeaponFrame; +void (float weap) W_WeaponSwitch; +void() player_pain; +void() player_stand1; +void (vector org) spawn_tfog; +void (vector org, entity death_owner) spawn_tdeath; + +float modelindex_eyes, modelindex_player; + +/* +============================================================================= + + LEVEL CHANGING / INTERMISSION + +============================================================================= +*/ + +string nextmap; + +/*QUAKED info_intermission (1 0.5 0.5) (-16 -16 -16) (16 16 16) +This is the camera point for the intermission. +Use mangle instead of angle, so you can set pitch or roll as well as yaw. 'pitch roll yaw' +*/ +void() info_intermission = +{ + self.angles = self.mangle; // so C can get at it +}; + + + +void() SetChangeParms = +{ + if (self.health <= 0) + { + SetNewParms (); + return; + } + +// cap super health + if (self.health > 130) + self.health = 130; + if (self.health < 50) + self.health = 50; + parm1 = self.items; + parm2 = self.health; + parm3 = self.armorvalue; + parm4 = 12; + /* + if (self.ammo_shells_real < 25) + parm4 = 25; + else + parm4 = self.ammo_shells_real; + */ + parm5 = self.ammo_nails_real; + parm6 = self.ammo_rockets_real; + parm7 = self.ammo_cells_real; + parm8 = self.weapon; + parm9 = self.armortype; + // Solitude + parm10 = self.exshells; + parm11 = self.exnails; + parm12 = self.exrockets; + parm13 = self.excells; + parm14 = self.ammo_shells2; + parm15 = self.exshells2; + parm16 = self.nade_lives; +}; + +void() SetNewParms = +{ + parm1 = WEAPON_AR + WEAPON_PPISTOL; // start Assault rifle + parm2 = 130; + parm3 = 0; + parm4 = 0; + //parm4 = 25; + parm5 = 0; + parm6 = 0; + parm7 = 0; + parm8 = WEAPON_AR; // start Assault rifle + parm9 = 0; + // Solitude + parm10 = 60; + parm11 = 560; + parm12 = MSG_BROADCAST; + parm13 = MSG_BROADCAST; + parm14 = SVC_INTERMISSION; + parm15 = 60; + parm16 = 4; +}; + +void() DecodeLevelParms = +{ + if (!deathmatch) + { + if (world.model == "maps/start.bsp") + SetNewParms (); // take away all stuff on starting new episode + } + + self.items = parm1; + self.health = parm2; + self.armorvalue = parm3; + self.ammo_shells_real = parm4; + self.ammo_nails_real = parm5; + self.ammo_rockets_real = parm6; + self.ammo_cells_real = parm7; + self.weapon = parm8; + self.armortype = parm9; + // solitude + self.ammo_hshells = 0; + self.exhshells = 0; + self.exshells = 0; + self.exnails = 0; + self.exrockets = 0; + self.excells = 0; + self.ammo_shells2 = 0; + self.exshells2 = 0; + self.nade_lives = parm16; + self.plasma_lives = parm16; + // weapon we start with: +}; + +/* +============ +FindIntermission + +Returns the entity to view from +============ +*/ +entity() FindIntermission = +{ + local entity spot; + local float cyc; + +// look for info_intermission first + spot = find (world, classname, "info_intermission"); + if (spot) + { // pick a random one + cyc = random() * 4; + while (cyc > 1) + { + spot = find (spot, classname, "info_intermission"); + if (!spot) + spot = find (spot, classname, "info_intermission"); + cyc = cyc - 1; + } + return spot; + } + +// then look for the start position + spot = find (world, classname, "info_player_start"); + if (spot) + return spot; + + objerror ("FindIntermission: no spot"); + return world; // remove warning +}; + +void() GotoNextMap = +{ + local string newmap; + +//ZOID: 12-13-96, samelevel is overloaded, only 1 works for same level + + if (cvar("samelevel") == 1) // if samelevel is set, stay on same level + changelevel (mapname); + else { + // configurable map lists, see if the current map exists as a + // serverinfo/localinfo var + newmap = stringserverinfokey(mapname); + if (newmap != "") + changelevel (newmap); + else + changelevel (nextmap); + } +}; + +void() ExitIntermission= +{ +// skip any text in deathmatch + if (deathmatch) + { + GotoNextMap (); + return; + } + + intermission_exittime = time + 1; + intermission_running = intermission_running + 1; + +// +// run some text if at the end of an episode +// + if (intermission_running == 2) + { + if (world.model == "maps/e1m7.bsp") + { + ENG_SwitchTrack(2, 3); + if (!cvar("registered")) + { + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task in the other three\nhaunted lands of Quake. Or are you? If\nyou don't register Quake, you'll never\nknow what awaits you in the Realm of\nBlack Magic, the Netherworld, and the\nElder World!"); + } + else + { + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task. A Rune of magic\npower lies at the end of each haunted\nland of Quake. Go forth, seek the\ntotality of the four Runes!"); + } + return; + } + else if (world.model == "maps/e2m6.bsp") + { + ENG_SwitchTrack(2, 3); + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "The Rune of Black Magic throbs evilly in\nyour hand and whispers dark thoughts\ninto your brain. You learn the inmost\nlore of the Hell-Mother; Shub-Niggurath!\nYou now know that she is behind all the\nterrible plotting which has led to so\nmuch death and horror. But she is not\ninviolate! Armed with this Rune, you\nrealize that once all four Runes are\ncombined, the gate to Shub-Niggurath's\nPit will open, and you can face the\nWitch-Goddess herself in her frightful\notherworld cathedral."); + return; + } + else if (world.model == "maps/e3m6.bsp") + { + ENG_SwitchTrack(2, 3); + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "The charred viscera of diabolic horrors\nbubble viscously as you seize the Rune\nof Hell Magic. Its heat scorches your\nhand, and its terrible secrets blight\nyour mind. Gathering the shreds of your\ncourage, you shake the devil's shackles\nfrom your soul, and become ever more\nhard and determined to destroy the\nhideous creatures whose mere existence\nthreatens the souls and psyches of all\nthe population of Earth."); + return; + } + else if (world.model == "maps/e4m7.bsp") + { + ENG_SwitchTrack(2, 3); + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "Despite the awful might of the Elder\nWorld, you have achieved the Rune of\nElder Magic, capstone of all types of\narcane wisdom. Beyond good and evil,\nbeyond life and death, the Rune\npulsates, heavy with import. Patient and\npotent, the Elder Being Shub-Niggurath\nweaves her dire plans to clear off all\nlife from the Earth, and bring her own\nfoul offspring to our world! For all the\ndwellers in these nightmare dimensions\nare her descendants! Once all Runes of\nmagic power are united, the energy\nbehind them will blast open the Gateway\nto Shub-Niggurath, and you can travel\nthere to foil the Hell-Mother's plots\nin person."); + return; + } + + GotoNextMap(); + } + + if (intermission_running == 3) + { + if (!cvar("registered")) + { // shareware episode has been completed, go to sell screen + WriteByte (MSG_ALL, SVC_SELLSCREEN); + return; + } + + if ( (serverflags&15) == 15) + { + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "Now, you have all four Runes. You sense\ntremendous invisible forces moving to\nunseal ancient barriers. Shub-Niggurath\nhad hoped to use the Runes Herself to\nclear off the Earth, but now instead,\nyou will use them to enter her home and\nconfront her as an avatar of avenging\nEarth-life. If you defeat her, you will\nbe remembered forever as the savior of\nthe planet. If she conquers, it will be\nas if you had never been born."); + return; + } + + } + + GotoNextMap(); +}; + +/* +============ +IntermissionThink + +When the player presses attack or jump, change to the next level +============ +*/ +void() IntermissionThink = +{ + if (time < intermission_exittime) + return; + + if (!self.button0 && !self.button1 && !self.button2) + return; + + ExitIntermission (); +}; + +/* +============ +execute_changelevel + +The global "nextmap" has been set previously. +Take the players to the intermission spot +============ +*/ +void() execute_changelevel = +{ + local entity pos; + + intermission_running = 1; + +// enforce a wait time before allowing changelevel + if (deathmatch) + intermission_exittime = time + 5; + else + intermission_exittime = time + 2; + + pos = FindIntermission (); + +// play intermission music + ENG_SwitchTrack(3, 3); + +#ifdef NETQUAKE + pos = FindIntermission (); + + other = find (world, classname, "player"); + while (other != world) + { + other.view_ofs = '0 0 0'; + other.angles = other.v_angle = pos.mangle; + other.fixangle = TRUE; // turn this way immediately + other.nextthink = time + 0.5; + other.takedamage = DAMAGE_NO; + other.solid = SOLID_NOT; + other.movetype = MOVETYPE_NONE; + other.modelindex = 0; + setorigin (other, pos.origin); + other = find (other, classname, "player"); + } + + WriteByte (MSG_ALL, SVC_INTERMISSION); +#else + WriteByte (MSG_ALL, SVC_INTERMISSION); + WriteCoord (MSG_ALL, pos.origin_x); + WriteCoord (MSG_ALL, pos.origin_y); + WriteCoord (MSG_ALL, pos.origin_z); + WriteAngle (MSG_ALL, pos.mangle_x); + WriteAngle (MSG_ALL, pos.mangle_y); + WriteAngle (MSG_ALL, pos.mangle_z); + + other = find (world, classname, "player"); + while (other != world) + { + other.takedamage = DAMAGE_NO; + other.solid = SOLID_NOT; + other.movetype = MOVETYPE_NONE; + other.modelindex = 0; + other = find (other, classname, "player"); + } +#endif +}; + + +void() changelevel_touch = +{ + if (other.classname != "player") + return; + +// if "noexit" is set, blow up the player trying to leave +//ZOID, 12-13-96, noexit isn't supported in QW. Overload samelevel +// if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start"))) + if (deathmatch) + { + if ((cvar("samelevel") == 2) || ((cvar("samelevel") == 3) && (mapname != "start"))) + { + T_Damage (other, self, self, 50000, MOD_EXIT); + return; + } + } + + bprint2 (PRINT_HIGH, other.netname, " exited the level\n"); + + nextmap = self.map; + + SUB_UseTargets (); + + self.touch = SUB_Null; + +// we can't move people right now, because touch functions are called +// in the middle of C movement code, so set a think time to do it + self.think = execute_changelevel; + self.nextthink = time + 0.1; +}; + +/*QUAKED trigger_changelevel (0.5 0.5 0.5) ? NO_INTERMISSION +When the player touches this, he gets sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats. +*/ +void() trigger_changelevel = +{ + if (!self.map) + objerror ("chagnelevel trigger doesn't have map"); + + InitTrigger (); + self.touch = changelevel_touch; +}; + + +/* +============================================================================= + + PLAYER GAME EDGE FUNCTIONS + +============================================================================= +*/ + +void() set_suicide_frame; + +// create a deadbody ent that is removed over time +void(entity ent) CopyToDeadbody = +{ + local entity deadbody; + + deadbody = spawn(); + deadbody.angles = ent.angles; + deadbody.model = ent.model; + deadbody.modelindex = ent.modelindex; + deadbody.frame = ent.frame; + deadbody.colormap = ent.colormap; + deadbody.movetype = ent.movetype; + deadbody.velocity = ent.velocity; + deadbody.flags = 0; + setorigin (deadbody, ent.origin); + setsize (deadbody, ent.mins, ent.maxs); + + deadbody.think = SUB_Remove; + deadbody.nextthink = time + 5; +}; + +// called by ClientKill and DeadThink +void() respawn = +{ + if (self.setup_death == #TRUE) { + Player_SetupDeath(); + } +}; + +void () true_respawn = +{ + if (coop) + { + // make a copy of the dead body for appearances sake + CopyToDeadbody (self); + // get the spawn parms as they were at level start + setspawnparms (self); + // respawn + PutClientInServer (); + } + else if (deathmatch) + { + // make a copy of the dead body for appearances sake + CopyToDeadbody (self); + // set default spawn parms + SetNewParms (); + // respawn + PutClientInServer (); + } + else + { // restart the entire server + localcmd ("restart\n"); + } +}; + +/* +============ +ClientKill + +Player entered the suicide command +============ +*/ +void() PlayerDropStuff; + +void() ClientKill = +{ + if (intermission_running) + return; + + if (self.suicide_time > time) + return; + + stuffcmd(self,"chase_active 1\n"); + self.setup_death = #TRUE; + self.health = 0; + + bprint2 (PRINT_MEDIUM, self.netname, " suicides\n"); + PlayerDropStuff (); + set_suicide_frame (); +CTF_Flag_Drop(); + self.modelindex = modelindex_player; + logfrag (self, self) + self.frags = self.frags - 2; // extra penalty + + respawn (); +}; + +/* +============ +SelectSpawnPoint + +Returns the entity to spawn at +============ +*/ +entity() SelectSpawnPoint = +{ + local entity spot, thing; + local float numspots, totalspots; + local float pcount; + local entity spots; + + if (coop) // coop spawning + { + if (!spotspawn) + { + spotspawn = 1; + spot = find (world, classname, "info_player_start"); + if (spot) + return spot; + } + lastspawn = find(lastspawn, classname, "info_player_coop"); + if (lastspawn) + return lastspawn; + } + + if (!deathmatch) // single player spawning + { + if (serverflags) + { // return with a rune to start + spot = find (world, classname, "info_player_start2"); + if (spot) + return spot; + } + + spot = find (world, classname, "info_player_start"); + if (spot) + return spot; + } + + // QuakeWorld style deathmatch spawning + numspots = 0; + totalspots = 0; + + // choose a info_player_deathmatch point + // ok, find all spots that don't have players nearby + spots = world; + spot = find (world, classname, "info_player_deathmatch"); + while (spot) + { + totalspots = totalspots + 1; + + thing=findradius(spot.origin, 84); + pcount=0; + while (thing) + { + if (thing.classname == "player") + pcount=pcount + 1; + thing=thing.chain; + } + if (pcount == 0) { + spot.goalentity = spots; + spots = spot; + numspots = numspots + 1; + } + + // Get the next spot in the chain + spot = find (spot, classname, "info_player_deathmatch"); + } + totalspots=totalspots - 1; + if (!numspots) { + // ack, they are all full, just pick one at random + totalspots = rint((random() * totalspots)); + spot = find (world, classname, "info_player_deathmatch"); + while (totalspots > 0) { + totalspots = totalspots - 1; + spot = find (spot, classname, "info_player_deathmatch"); + } + return spot; + } + + // We now have the number of spots available on the map in numspots + // Generate a random number between 1 and numspots + numspots = numspots - 1; + numspots = rint((random() * numspots)); + + spot = spots; + while (numspots > 0) { + spot = spot.goalentity; + numspots = numspots - 1; + } + return spot; + +}; +void() DecodeLevelParms; +void() PlayerDie; + +/* +=========== +PutClientInServer + +called each time a player enters a new level +============ +*/ +void() PutClientInServer = +{ + local entity spot; + local float wtemp; + + self.classname = "player"; + self.health = 130; + self.takedamage = DAMAGE_AIM; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_WALK; + self.show_hostile = 0; + self.max_health = 130; + self.flags = FL_CLIENT; + self.air_finished = time + 12; + self.waterdmg = 2; // initial water damage + self.super_damage_finished = 0; + self.radsuit_finished = 0; + self.invisible_finished = 0; + self.invincible_finished = 0; + self.effects = 0; + self.invincible_time = 0; + self.suicide_time = time + 3; + self.weaponstate = WS_IDLE; + DecodeLevelParms (); + // dumb hack until I get the real weapon system in + wtemp = self.weapon; + + if (deathmatch == 4) + { + self.ammo_shells_real = 0; + if (numberserverinfokey("axe") == 0) + { + self.ammo_nails_real = 255; + self.ammo_shells_real = 255; + self.ammo_rockets_real = 255; + self.ammo_cells_real = 255; + self.items |= IT_NAILGUN + | IT_SUPER_NAILGUN + | IT_SUPER_SHOTGUN + | IT_ROCKET_LAUNCHER + | IT_LIGHTNING; + } + else + wtemp = IT_AXE; + + self.items |= IT_ARMOR3 | IT_INVULNERABILITY; + self.items = self.items - (self.items & (IT_ARMOR1 | IT_ARMOR2)); + self.armorvalue = 200; + self.armortype = 0.8; + self.health = 250; + self.invincible_time = 1; + self.invincible_finished = time + 3; + } + + if (deathmatch == 5) + { + self.ammo_nails_real = 80; + self.ammo_shells_real = 30; + self.ammo_rockets_real = 10; + self.ammo_cells_real = 30; + self.items |= IT_NAILGUN + | IT_SUPER_NAILGUN + | IT_SUPER_SHOTGUN + | IT_ROCKET_LAUNCHER + | IT_GRENADE_LAUNCHER + | IT_LIGHTNING + | IT_ARMOR3 + | IT_INVULNERABILITY; + self.items = self.items - (self.items & (IT_ARMOR1 | IT_ARMOR2)); + self.armorvalue = 200; + self.armortype = 0.8; + self.health = 200; + self.invincible_time = 1; + self.invincible_finished = time + 3; + } + + self.weapon = 0; + W_WeaponSwitch (wtemp); + + self.attack_finished = time; + self.th_pain = player_pain; + self.th_die = PlayerDie; + + self.deadflag = DEAD_NO; + + spot = SelectSpawnPoint (); + + self.origin = spot.origin + '0 0 1'; + self.angles = spot.angles; + self.fixangle = TRUE; // turn this way immediately + +// oh, this is a hack! + setmodel (self, "progs/eyes.mdl"); + modelindex_eyes = self.modelindex; + + setmodel (self, "progs/player.mdl"); + modelindex_player = self.modelindex; + + setsize (self, VEC_HULL_MIN, VEC_HULL_MAX); + + self.view_ofs = '0 0 22'; + +// Mod - Xian (May.20.97) +// Bug where player would have velocity from their last kill + + self.velocity = '0 0 0'; + + player_stand1 (); + + makevectors(self.angles); + spawn_tfog (self.origin + v_forward*20); + + spawn_tdeath (self.origin, self); + + // Set Rocket Jump Modifiers + rj = numberserverinfokey("rj"); + + W_StartWeapon (); + + self.needles = 0; + + + self.pfov = FOV_DEFAULT; + Set_FOV( self.pfov ); + + self.reset = 0; + self.groundwep = 0; + self.weaponheat = 0; + + stuffcmd(self,"chase_active 0\n"); + NadeCounter(); + AmmoCounter(); +}; + + +/* +============================================================================= + + QUAKED FUNCTIONS + +============================================================================= +*/ + + +/*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 24) +The normal starting point for a level. +*/ +void() info_player_start = +{ +}; + + +/*QUAKED info_player_start2 (1 0 0) (-16 -16 -24) (16 16 24) +Only used on start map for the return point from an episode. +*/ +void() info_player_start2 = +{ +}; + +/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 24) +potential spawning position for deathmatch games +*/ +void() info_player_deathmatch = +{ +}; + +/*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24) +potential spawning position for coop games +*/ +void() info_player_coop = +{ +}; + +/* +=============================================================================== + +RULES + +=============================================================================== +*/ + +/* +go to the next level for deathmatch +*/ +void() NextLevel = +{ + local entity o; + + if (nextmap != "") + return; // already done + + if (mapname == "start") + { + if (!cvar("registered")) + { + mapname = "e1m1"; + } + else if (!(serverflags & 1)) + { + mapname = "e1m1"; + serverflags = serverflags | 1; + } + else if (!(serverflags & 2)) + { + mapname = "e2m1"; + serverflags = serverflags | 2; + } + else if (!(serverflags & 4)) + { + mapname = "e3m1"; + serverflags = serverflags | 4; + } + else if (!(serverflags & 8)) + { + mapname = "e4m1"; + serverflags = serverflags - 7; + } + + o = spawn(); + o.map = mapname; + } + else + { + // find a trigger changelevel + o = find(world, classname, "trigger_changelevel"); + if (!o || mapname == "start") + { // go back to same map if no trigger_changelevel + o = spawn(); + o.map = mapname; + } + } + + nextmap = o.map; + + if (o.nextthink < time) + { + o.think = execute_changelevel; + o.nextthink = time + 0.1; + } +}; + +/* +============ +CheckRules + +Exit deathmatch games upon conditions +============ +*/ +void() CheckRules = +{ + if (deathmatch && timelimit && time >= timelimit) + NextLevel (); + + if (deathmatch && fraglimit && self.frags >= fraglimit) + NextLevel (); +}; + +void () player_respawn_think = +{ + local entity oself; + + if (self.owner.classname != "player" || self.owner == world || self.owner.health > 0) { + remove(self); + return; + } + self.health -= 1; + sprint(self.owner, "You will respawn in "); + sprint(self.owner, ftos(self.health)); + sprint(self.owner, " seconds.\n"); + + if (self.health < 1) { + oself = self; + + self = self.owner; + self.impulse = 0; + self.button0 = 0; + self.button1 = 0; + self.button2 = 0; + true_respawn(); + + self = oself; + remove(self); + return; + } + + self.nextthink = time + 1; +}; + +void () Player_SetupDeath = +{ + local entity dt; + + dt = spawn(); + dt.health = 8; + dt.owner = self; + dt.think = player_respawn_think; + dt.nextthink = time + 1; + sprint(self, "You will respawn in "); + sprint(self, ftos(dt.health)); + sprint(self, " seconds.\n"); + self.setup_death = #FALSE; + self.weaponframe = 0; +}; + + +//============================================================================ + +void() PlayerDeathThink = +{ + local float forward; + + if (self.setup_death == #TRUE) { + Player_SetupDeath(); + } + + if ((self.flags & FL_ONGROUND)) + { + forward = vlen (self.velocity); + forward = forward - 20; + if (forward <= 0) + self.velocity = '0 0 0'; + else + self.velocity = forward * normalize(self.velocity); + } + +// wait for all buttons released + if (self.deadflag == DEAD_DEAD) + { + if (self.button2 || self.button1 || self.button0) + return; + self.deadflag = DEAD_RESPAWNABLE; + return; + } + +// wait for any button down + if (!self.button2 && !self.button1 && !self.button0) + return; + + self.button0 = 0; + self.button1 = 0; + self.button2 = 0; + respawn(); +}; + + +void() PlayerJump = +{ + local float vjump; + vjump = cvar("sol_jump"); + + if (self.flags & FL_WATERJUMP) + return; + + if (self.next_jump_time > time) { + stuffcmd( self, "-jump\n" ); + return; + } + + if (self.waterlevel >= 2) + { +// play swiming sound + if (self.swim_flag < time) + { + self.swim_flag = time + 1; + if (random() < 0.5) + sound (self, CHAN_BODY, "misc/water1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_BODY, "misc/water2.wav", 1, ATTN_NORM); + } + + return; + } + +if (!(self.flags & FL_ONGROUND)) + return; + + if ( !(self.flags & FL_JUMPRELEASED) ) + return; // don't pogo stick + + self.flags = self.flags - (self.flags & FL_JUMPRELEASED); + self.button2 = 0; + +// player jumping sound + sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM); + + if (vjump) { + self.velocity_z = self.velocity_z + vjump; + } + else { +#ifdef NETQUAKE + self.flags = self.flags - FL_ONGROUND; + self.velocity_z = self.velocity_z + 225; +#endif + } + self.jump_time = time + .15; +}; + + +/* +=========== +WaterMove + +============ +*/ +void() WaterMove = +{ +//dprint (ftos(self.waterlevel)); + if (self.movetype == MOVETYPE_NOCLIP) + return; + if (self.health < 0) + return; + + if (self.waterlevel != 3) + { + if (self.air_finished < time) + sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM); + else if (self.air_finished < time + 9) + sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM); + self.air_finished = time + 12; + self.waterdmg = 2; + } + else if (self.air_finished < time) + { // drown! + if (self.pain_finished < time) + { + self.waterdmg = self.waterdmg + 2; + if (self.waterdmg > 15) + self.waterdmg = 10; + T_Damage (self, world, world, self.waterdmg, MOD_DROWN); + self.pain_finished = time + 1; + } + } + + if (!self.waterlevel) + { + if (self.flags & FL_INWATER) + { + // play leave water sound + sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM); + self.flags = self.flags - FL_INWATER; + } + return; + } + + if ( !(self.flags & FL_INWATER) ) + { + // player enter water sound + switch (self.watertype) + { + case CONTENT_LAVA: + sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM); + break; + case CONTENT_WATER: + sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM); + break; + case CONTENT_SLIME: + sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM); + break; + } + + self.flags = self.flags + FL_INWATER; + self.dmgtime = 0; + } + + if (self.watertype == CONTENT_LAVA) + { // do damage + if (self.dmgtime < time) + { + if (self.radsuit_finished > time) + self.dmgtime = time + 1; + else + self.dmgtime = time + 0.2; + + T_Damage (self, world, world, 10*self.waterlevel, MOD_LAVA); + } + } + else if (self.watertype == CONTENT_SLIME) + { // do damage + if (self.dmgtime < time && self.radsuit_finished < time) + { + self.dmgtime = time + 1; + T_Damage (self, world, world, 4*self.waterlevel, MOD_SLIME); + } + } + +}; + +void() CheckWaterJump = +{ + local vector start, end; + +// check for a jump-out-of-water + makevectors (self.angles); + start = self.origin; + start_z = start_z + 8; + v_forward_z = 0; + normalize(v_forward); + end = start + v_forward*24; + traceline (start, end, TRUE, self); + if (trace_fraction < 1) + { // solid at waist + start_z = start_z + self.maxs_z - 8; + end = start + v_forward*24; + self.movedir = trace_plane_normal * -50; + traceline (start, end, TRUE, self); + if (trace_fraction == 1) + { // open at eye level + self.flags = self.flags | FL_WATERJUMP; + self.velocity_z = 225; + self.flags = self.flags - (self.flags & FL_JUMPRELEASED); + self.teleport_time = time + 2; // safety net + return; + } + } +}; + +/* +================ +PlayerPreThink + +Called every frame before physics are run +================ +*/ +void() PlayerPreThink = +{ +if (self.weapon == IT_SKULL) +{ + if (score_lastTic < time) + { + self.frags = self.frags + 1; + score_lastTic = time + 1; + } +} + if (BotPreFrame()) // FrikBot + return; + if (intermission_running) + { + IntermissionThink (); // otherwise a button could be missed between + return; // the think tics + } + +// if intermission is running what is the point of this? +// if (self.view_ofs == '0 0 0') +// return; + + makevectors (self.v_angle); // is this still used + + CheckRules (); + WaterMove (); +/* + if (self.waterlevel == 2) + CheckWaterJump (); +*/ + + if (self.deadflag >= DEAD_DEAD) + { + PlayerDeathThink (); + return; + } + + if (self.deadflag == DEAD_DYING) + return; // dying, so do nothing + + if (self.button2) + PlayerJump (); + else + self.flags = self.flags | FL_JUMPRELEASED; + + if(time > self.attack_finished && self.currentammo == 0 && self.weapon != IT_AXE) + { + W_WeaponSwitch (W_BestWeapon ()); + } +self.reset = self.reset + 0.005; +self.groundwep = self.groundwep - 0.5; + + if (self.groundwep <= 0.0) + { + stuffcmd (self, "cl_ww 0\n"); + } + + if (self.reset >= 1.000) + { + localcmd ("cl_doublek 0\n"); + localcmd ("cl_triplek 0\n"); + localcmd ("cl_killt 0\n"); + localcmd ("cl_killtrocity 0\n"); + self.reset = 0; + } + + + +}; + +/* +================ +CheckPowerups + +Check for turning off powerups +================ +*/ +void() CheckPowerups = +{ + if (self.health <= 0) + return; + +// invisibility + if (self.invisible_finished) + { +// sound and screen flash when items starts to run out + if (self.invisible_sound < time) + { + sound (self, CHAN_AUTO, "items/inv3.wav", 0.5, ATTN_IDLE); + self.invisible_sound = time + ((random() * 3) + 1); + } + + + if (self.invisible_finished < time + 3) + { + if (self.invisible_time == 1) + { + sprint1 (self, PRINT_HIGH, "Ring of Shadows magic is fading\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/inv2.wav", 1, ATTN_NORM); + self.invisible_time = time + 1; + } + + if (self.invisible_time < time) + { + self.invisible_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.invisible_finished < time) + { // just stopped + self.items = self.items - IT_INVISIBILITY; + self.invisible_finished = 0; + self.invisible_time = 0; + } + + // use the eyes + self.frame = 0; + self.modelindex = modelindex_eyes; + } + else + self.modelindex = modelindex_player; // don't use eyes + +// invincibility + if (self.invincible_finished) + { +// sound and screen flash when items starts to run out + if (self.invincible_finished < time + 3) + { + if (self.invincible_time == 1) + { + sprint1 (self, PRINT_HIGH, "Protection is almost burned out\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/protect2.wav", 1, ATTN_NORM); + self.invincible_time = time + 1; + } + + if (self.invincible_time < time) + { + self.invincible_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.invincible_finished < time) + { // just stopped + self.items = self.items - IT_INVULNERABILITY; + self.invincible_time = 0; + self.invincible_finished = 0; + } + if (self.invincible_finished > time) + self.effects = self.effects | ef_pent; + else + self.effects = self.effects - (self.effects & ef_pent); + } + +// super damage + if (self.super_damage_finished) + { + +// sound and screen flash when items starts to run out + + if (self.super_damage_finished < time + 3) + { + if (self.super_time == 1) + { + if (deathmatch == 4) + sprint1 (self, PRINT_HIGH, "OctaPower is wearing off\n"); + else + sprint1 (self, PRINT_HIGH, "Quad Damage is wearing off\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/damage2.wav", 1, ATTN_NORM); + self.super_time = time + 1; + } + + if (self.super_time < time) + { + self.super_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.super_damage_finished < time) + { // just stopped + self.items = self.items - IT_QUAD; + if (deathmatch == 4) + { + self.ammo_cells_real = 255; + W_UpdateAmmoCounts(self); + self.armorvalue = 1; + self.armortype = 0.8; + self.health = 100; + } + self.super_damage_finished = 0; + self.super_time = 0; + } + if (self.super_damage_finished > time) + self.effects = self.effects | ef_quad; + else + self.effects = self.effects - (self.effects & ef_quad); + } + +// suit + if (self.radsuit_finished) + { + self.air_finished = time + 12; // don't drown + +// sound and screen flash when items starts to run out + if (self.radsuit_finished < time + 3) + { + if (self.rad_time == 1) + { + sprint1 (self, PRINT_HIGH, "Air supply in Biosuit expiring\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/suit2.wav", 1, ATTN_NORM); + self.rad_time = time + 1; + } + + if (self.rad_time < time) + { + self.rad_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.radsuit_finished < time) + { // just stopped + self.items = self.items - IT_SUIT; + self.rad_time = 0; + self.radsuit_finished = 0; + } + } + +}; + + +/* +================ +PlayerPostThink + +Called every frame after physics are run +================ +*/ +void() PlayerPostThink = +{ + if (BotPostFrame()) // FrikBot + return; +//dprint ("post think\n"); + if (intermission_running) + return; +// if (self.view_ofs == '0 0 0') +// return; + if (self.deadflag) + return; + + if (!self.flags & FL_ONGROUND) + if (self.next_jump_time < time) + self.next_jump_time = time + .05; + + self.jump_flag = self.velocity_z; + + + //CheckPowerups (); + + W_WeaponFrame (); + +}; + + +/* +=========== +ClientConnect + +called when a player connects to a server +============ +*/ +void() ClientConnect = +{ + ClientInRankings(); // FrikBot + bprint2 (PRINT_HIGH, self.netname, " entered the game\n"); + +// a client connecting during an intermission can cause problems + if (intermission_running) + GotoNextMap (); +}; + + +void() ClientDisconnect = +{ + ClientDisconnected(); // FrikBot + // let everyone else know + bprint4 (PRINT_HIGH, self.netname, " left the game with ", ftos(self.frags), " frags\n"); + sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE); + set_suicide_frame (); +}; +void(entity playermedal, float howmany) killmedals = +{ + if (howmany == 10) + centerprint(playermedal, "Killpocalypse!\n"); + else if (howmany == 9) + centerprint(playermedal, "Killpocalypse!\n"); + else if (howmany == 8) + centerprint(playermedal, "Killtastrophe!\n"); + else if (howmany == 7) + centerprint(playermedal, "Killimanjaro!\n"); + else if (howmany == 6) + { + playermedal.reset = 0.000; + stuffcmd (playermedal, "cl_killtrocity 0\n"); + centerprint(playermedal, "Overkill!\n"); + } + else if (howmany == 5) + { + playermedal.reset = 0.000; + centerprint(playermedal, "Killtrocity!\n"); + stuffcmd (playermedal, "play killtrocity.wav\n"); + stuffcmd (playermedal, "cl_killtrocity 1\n"); + stuffcmd (playermedal, "cl_killt 0\n"); + stuffcmd (playermedal, "cl_triplek 0\n"); + stuffcmd (playermedal, "cl_doublek 0\n"); + } + else if (howmany == 4) + { + playermedal.reset = 0.000; + centerprint(playermedal, "KillTacular!\n"); + stuffcmd (playermedal, "play killtacular.wav\n"); + stuffcmd (playermedal, "cl_killt 1\n"); + stuffcmd (playermedal, "cl_killtrocity 0\n"); + stuffcmd (playermedal, "cl_triplek 0\n"); + stuffcmd (playermedal, "cl_doublek 0\n"); + } + else if (howmany == 3) { + playermedal.reset = 0.000; + centerprint(playermedal, "Triple Kill!\n"); + stuffcmd (playermedal, "play triple.wav\n"); + stuffcmd (playermedal, "cl_triplek 1\n"); + stuffcmd (playermedal, "cl_doublek 0\n"); + stuffcmd (playermedal, "cl_killt 0\n"); + stuffcmd (playermedal, "cl_killtrocity 0\n"); + } + else if (howmany == 2) { + playermedal.reset = 0.000; + centerprint(playermedal, "Double Kill!\n"); + stuffcmd(playermedal,"play double.wav\n"); + stuffcmd (playermedal, "cl_doublek 1\n"); + stuffcmd (playermedal, "cl_triplek 0\n"); + stuffcmd (playermedal, "cl_killt 0\n"); + stuffcmd (playermedal, "cl_killtrocity 0\n"); + } + else + return; +}; +/* +=========== +ClientObituary + +called when a player dies +============ +*/ +BOOL(entity targ, entity attacker) OnSameTeam; + +void(entity targ, entity attacker, INTEGER mod) ClientObituary = +{ + //Kill Medals +if (attacker.kill_time >= time) +{ + attacker.kill_amount = attacker.kill_amount + 1; + killmedals (attacker, attacker.kill_amount); +} +else + attacker.kill_amount = 1; +if (targ.classname == "player") + attacker.kill_time = time + 4; + +if (attacker.flags & FL_CLIENT) + { + if (attacker == targ) + { + SuicideMessage(targ.netname, mod); + targ.frags = targ.frags - 1; + logfrag(targ, targ) + return; + } // else if anything else + + if (OnSameTeam(targ, attacker)) + { + TeamKillMessage(targ.netname, attacker.netname, mod); + logfrag(attacker, attacker) + attacker.frags = attacker.frags - 1; + return; + } + + if (targ.flags & FL_CLIENT) + { + KillMessage(targ.netname, attacker.netname, mod); + attacker.frags = attacker.frags + 1; + logfrag(attacker, targ) + } + return; + } // else if attacker != player + + if (targ.flags & FL_CLIENT) + { + WorldKillMessage(targ.netname, mod); + targ.frags = targ.frags - 1; + logfrag(targ, targ) + } +}; diff --git a/r17/Revamped src/Revamped QC/combat.qc b/r17/Revamped src/Revamped QC/combat.qc new file mode 100755 index 00000000..88a5a32a Binary files /dev/null and b/r17/Revamped src/Revamped QC/combat.qc differ diff --git a/r17/Revamped src/Revamped QC/ctf.qc b/r17/Revamped src/Revamped QC/ctf.qc new file mode 100755 index 00000000..36118e2d --- /dev/null +++ b/r17/Revamped src/Revamped QC/ctf.qc @@ -0,0 +1,246 @@ +.vector flag_base; + +.entity flag_ent; + +.float update_print; + +.float flag_state; +float FLAG_STATE_BASE = 0; +float FLAG_STATE_DROPPED = 1; +float FLAG_STATE_CARRIED = 2; + +float TEAM_BLUE = 14; +float TEAM_RED = 5; + +vector(entity e) realorg = +{ + return ((e.absmin + e.absmax) * 0.5); +}; + +string(float whichteam) CTF_TeamString = +{ + if (whichteam == TEAM_BLUE) + return "\bBLUE"; + else + return "\bRED"; +}; + +void(float st) CTF_Flag_SetState = +{ + self.flag_state = st; + + if ( (st == FLAG_STATE_BASE) || (st == FLAG_STATE_DROPPED) ) + { + self.owner = world; + self.solid = SOLID_TRIGGER; + } + else if (st == FLAG_STATE_CARRIED) + self.solid = SOLID_NOT; +}; + +// go back home +void() CTF_Flag_SendToBase = +{ + if (self.flag_state == FLAG_STATE_DROPPED) + { + bprint(CTF_TeamString(self.team)); + bprint(" flag was returned to base!\n"); + } + + setorigin(self, self.flag_base); + CTF_Flag_SetState(FLAG_STATE_BASE); + +}; + +// give the team points! +void() CTF_Flag_Capture = +{ + local entity e, oself; + + bprint(other.netname); + bprint(" captured the "); + bprint(CTF_TeamString(other.flag_ent.team)); + bprint(" flag!\n"); + + centerprint(other, "\n"); + + e = find(world, classname, "player"); + while (e) + { + if (e.team == other.team) + e.frags = e.frags + 10; + + e = find(e, classname, "player"); + } + + // todo: play some noise and do happy dance + + oself = self; + self = other.flag_ent; + CTF_Flag_SendToBase(); + self = oself; + + other.flag_ent = world; +}; + +// braaaaains +void() CTF_Flag_Think = +{ + if (self.flag_state == FLAG_STATE_CARRIED) + { + // stay tracking with them, behind a little bit + makevectors(self.owner.v_angle); + setorigin (self, realorg(self.owner) + (v_forward * -14)); + + if (self.owner.update_print < time) + { + centerprint(self.owner, " \n \n \n \n \n \n \n \n \nYou have the flag!\nReturn to your base."); + self.owner.update_print = time + 1.5; + } + + self.think = CTF_Flag_Think; + self.nextthink = time; + } + else if (self.flag_state == FLAG_STATE_DROPPED) + { + self.nextthink = time + 30; + self.think = CTF_Flag_SendToBase; + } +}; + +void() CTF_Flag_Drop = +{ + local vector deviance; + local entity oself; + + if (!self.flag_ent) + return; + + bprint(self.netname); + bprint(" has dropped the "); + bprint(CTF_TeamString(self.flag_ent.team)); + bprint(" flag!\n"); + + // throw it out in the direction of the owners velocity, plus a bit random + deviance_x = random() * 20; + deviance_y = random() * 20; + deviance_z = 200; + + self.flag_ent.velocity = (self.flag_ent.velocity * 0.5) + deviance; + + oself = self; + self = self.flag_ent; + CTF_Flag_SetState(FLAG_STATE_DROPPED); + self = oself; + + self.flag_ent.think = CTF_Flag_Think; + self.flag_ent.nextthink = time; + + self.flag_ent = world; +}; + +// flag has been touched! +void() CTF_Flag_Touch = +{ + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + // not on my team + if (other.team != self.team) + { + bprint(other.netname); + bprint(" has picked up the "); + bprint(CTF_TeamString(self.team)); + bprint(" flag!\n"); + + self.owner = other; + other.flag_ent = self; + + CTF_Flag_SetState(FLAG_STATE_CARRIED); + + self.think = CTF_Flag_Think; + self.nextthink = time; + } + else + { + // on my team + // dropped, return to base + if (self.flag_state == FLAG_STATE_DROPPED) + { + bprint(other.netname); + bprint(" returned the "); + bprint(CTF_TeamString(other.team)); + bprint(" flag\n"); + + CTF_Flag_SendToBase(); + } + else if (self.flag_state == FLAG_STATE_BASE) + { + if (other.flag_ent) + CTF_Flag_Capture(); // OH YEAH! + } + } +}; + +void() CTF_Flag_Finalise = +{ + self.movetype = MOVETYPE_TOSS; + + CTF_Flag_SetState(FLAG_STATE_BASE); +}; + +void(float whichteam) CTF_Flag_Init = +{ + local string m, s; + local vector v; + local entity flag; + + flag = spawn(); + + flag.touch = CTF_Flag_Touch; + flag.flags = FL_ITEM; + flag.team = whichteam; + + if (whichteam == TEAM_BLUE) + { + m = "progs/b_s_key.mdl"; + s = "misc/basekey.wav"; + flag.items = IT_KEY1; + } + else + { + m = "progs/b_g_key.mdl"; + s = "misc/basekey.wav"; + flag.items = IT_KEY2; + } + + precache_model (m); + setmodel (flag, m); + + precache_sound (s); + flag.noise = s; + + v = self.origin + '0 0 4'; + + flag.flag_base = v; + flag.owner = world; + flag.team = whichteam; + + setsize (flag, VEC_HULL_MIN, VEC_HULL_MAX); + setorigin(flag, v); + + flag.nextthink = time + 0.2; + flag.think = CTF_Flag_Finalise; +}; + +void() info_flag_blue = +{ + CTF_Flag_Init(TEAM_BLUE); +}; + +void() info_flag_red = +{ + CTF_Flag_Init(TEAM_RED); +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/defs.qc b/r17/Revamped src/Revamped QC/defs.qc new file mode 100755 index 00000000..df662356 --- /dev/null +++ b/r17/Revamped src/Revamped QC/defs.qc @@ -0,0 +1,852 @@ +#ifdef FTE +// use real int if using FTE type progs +#define INTEGER int +#else +#define INTEGER float +#endif + +#define BOOL INTEGER + + +#define FALSE ((BOOL)0) +#define TRUE ((BOOL)1) + +/* +============================================================================== + + SOURCE FOR GLOBALVARS_T C STRUCTURE + +============================================================================== +*/ + +// +// system globals +// +entity self; +entity other; +entity world; +float time; +float frametime; + +#ifndef NETQUAKE +entity newmis; // if this is set, the entity that just + // run created a new missile that should + // be simulated immediately +#endif + +float force_retouch; // force all entities to touch triggers + // next frame. this is needed because + // non-moving things don't normally scan + // for triggers, and when a trigger is + // created (like a teleport trigger), it + // needs to catch everything. + // decremented each frame, so set to 2 + // to guarantee everything is touched +string mapname; + +#ifdef NETQUAKE +float deathmatch; +float coop; +float teamplay; +#endif + +float serverflags; // propagated from level to level, used to + // keep track of completed episodes + +float total_secrets; +float total_monsters; + +float found_secrets; // number of secrets found +float killed_monsters; // number of monsters killed + + +// spawnparms are used to encode information about clients across server +// level changes +float parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16; + +// +// global variables set by built in functions +// +vector v_forward, v_up, v_right; // set by makevectors() + +// set by traceline / tracebox +float trace_allsolid; +float trace_startsolid; +float trace_fraction; +vector trace_endpos; +vector trace_plane_normal; +float trace_plane_dist; +entity trace_ent; +float trace_inopen; +float trace_inwater; + +entity msg_entity; // destination of single entity writes + +// +// required prog functions +// +void() main; // only for testing + +void() StartFrame; + +void() PlayerPreThink; +void() PlayerPostThink; + +void() ClientKill; +void() ClientConnect; +void() PutClientInServer; // call after setting the parm1... parms +void() ClientDisconnect; + +void() SetNewParms; // called when a client first connects to + // a server. sets parms so they can be + // saved off for restarts + +void() SetChangeParms; // call to set parms for self so they can + // be saved for a level transition + + +//================================================ +void end_sys_globals; // flag for structure dumping +//================================================ + +/* +============================================================================== + + SOURCE FOR ENTVARS_T C STRUCTURE + +============================================================================== +*/ + +// +// system fields (*** = do not set in prog code, maintained by C code) +// +.float modelindex; // *** model index in the precached list +.vector absmin, absmax; // *** origin + mins / maxs + +.float ltime; // local time for entity +#ifndef NETQUAKE +.float lastruntime; // *** to allow entities to run out of sequence +#endif + +.float movetype; +.float solid; + +.vector origin; // *** +.vector oldorigin; // *** +.vector velocity; +.vector angles; +.vector avelocity; + +#ifdef NETQUAKE +.vector punchangle; +#endif + +.string classname; // spawn function +.string model; +.float frame; +.float skin; +.float effects; + +.vector mins, maxs; // bounding box extents reletive to origin +.vector size; // maxs - mins + +.void() touch; +.void() use; +.void() think; +.void() blocked; // for doors or plats, called when can't push other + +.float nextthink; +.entity groundentity; + +// stats +.float health; +.float frags; +.float weapon; // one of the IT_SHOTGUN, etc flags +.string weaponmodel; +.float weaponframe; +.float currentammo; +.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells; + +.float items; // bit flags + +.float takedamage; +.entity chain; +.float deadflag; + +.vector view_ofs; // add to origin to get eye point + + +.float button0; // fire +.float button1; // use +.float button2; // jump + +.float impulse; // weapon changes + +.float fixangle; +.vector v_angle; // view / targeting angle for players + +#ifdef NETQUAKE +.float idealpitch; +#endif + +.string netname; + +.entity enemy; + +.float flags; + +.float colormap; +.float team; + +.float max_health; // players maximum health is stored here + +.float teleport_time; // don't back up + +.float armortype; // save this fraction of incoming damage +.float armorvalue; + +.float waterlevel; // 0 = not in, 1 = feet, 2 = wast, 3 = eyes +.float watertype; // a contents value + +.float ideal_yaw; +.float yaw_speed; + +.entity aiment; + +.entity goalentity; // a movetarget or an enemy + +.float spawnflags; + +.string target; +.string targetname; + +// damage is accumulated through a frame. and sent as one single +// message, so the super shotgun doesn't generate huge messages +.float dmg_take; +.float dmg_save; +.entity dmg_inflictor; + +.entity owner; // who launched a missile +.vector movedir; // mostly for doors, but also used for waterjump + +.string message; // trigger messages + +.float sounds; // either a cd track number or sound number + +.string noise, noise1, noise2, noise3; // contains names of wavs to play + +//================================================ +void end_sys_fields; // flag for structure dumping +//================================================ + +/* +============================================================================== + + VARS NOT REFERENCED BY C CODE + +============================================================================== +*/ + + +// +// constants +// + +// edict.flags +#define FL_FLY 1 +#define FL_SWIM 2 +#define FL_CLIENT 8 // set for all client edicts +#define FL_INWATER 16 // for enter / leave water splash +#define FL_MONSTER 32 +#define FL_GODMODE 64 // player cheat +#define FL_NOTARGET 128 // player cheat +#define FL_ITEM 256 // extra wide size for bonus items +#define FL_ONGROUND 512 // standing on something +#define FL_PARTIALGROUND 1024 // not all corners are valid +#define FL_WATERJUMP 2048 // player jumping out of water +#define FL_JUMPRELEASED 4096 // for jump debouncing + +// edict.movetype values +#define MOVETYPE_NONE 0 // never moves +#define MOVETYPE_WALK 3 // players only +#define MOVETYPE_STEP 4 // discrete, not real time unless fall +#define MOVETYPE_FLY 5 +#define MOVETYPE_TOSS 6 +#define MOVETYPE_PUSH 7 // no clip to world, push and crush +#define MOVETYPE_NOCLIP 8 +#define MOVETYPE_FLYMISSILE 9 // fly with extra size against monsters +#define MOVETYPE_BOUNCE 10 + +// edict.solid values +#define SOLID_NOT 0 // no interaction with other objects +#define SOLID_TRIGGER 1 // touch on edge, but not blocking +#define SOLID_BBOX 2 // touch on edge, block +#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground +#define SOLID_BSP 4 // bsp clip, touch on edge, block + + +// deadflag values +#define DEAD_NO 0 +#define DEAD_DYING 1 +#define DEAD_DEAD 2 +#define DEAD_RESPAWNABLE 3 + +// takedamage values +#define DAMAGE_NO 0 +#define DAMAGE_YES 1 +#define DAMAGE_AIM 2 + +// items +float IT_AXE = 4096; +float IT_SHOTGUN = 1; +float IT_SUPER_SHOTGUN = 2; +float IT_NAILGUN = 4; +float IT_SUPER_NAILGUN = 8; +float IT_GRENADE_LAUNCHER = 16; +float IT_ROCKET_LAUNCHER = 32; +float IT_LIGHTNING = 64; +float IT_EXTRA_WEAPON = 128; +float IT_EXTRA_WEAPON2 = 8388608; // solitude +float IT_SKULL = 16777216; // solitude + +float IT_SHELLS = 256; +float IT_NAILS = 512; +float IT_ROCKETS = 1024; +float IT_CELLS = 2048; + +float IT_ARMOR1 = 8192; +float IT_ARMOR2 = 16384; +float IT_ARMOR3 = 32768; +float IT_SUPERHEALTH = 65536; + +float IT_KEY1 = 131072; +float IT_KEY2 = 262144; + +float IT_INVISIBILITY = 524288; +float IT_INVULNERABILITY = 1048576; +float IT_SUIT = 2097152; +float IT_QUAD = 4194304; + +// point content values + +float CONTENT_EMPTY = -1; +float CONTENT_SOLID = -2; +float CONTENT_WATER = -3; +float CONTENT_SLIME = -4; +float CONTENT_LAVA = -5; +float CONTENT_SKY = -6; + +vector VEC_ORIGIN = '0 0 0'; +vector VEC_HULL_MIN = '-16 -16 -24'; +vector VEC_HULL_MAX = '16 16 32'; + +vector VEC_HULL2_MIN = '-32 -32 -24'; +vector VEC_HULL2_MAX = '32 32 64'; + +// protocol bytes +float SVC_TEMPENTITY = 23; +float SVC_KILLEDMONSTER = 27; +float SVC_FOUNDSECRET = 28; +float SVC_INTERMISSION = 30; +float SVC_FINALE = 31; +float SVC_CDTRACK = 32; +float SVC_SELLSCREEN = 33; +float SVC_SMALLKICK = 34; +float SVC_BIGKICK = 35; +float SVC_MUZZLEFLASH = 39; + +float TE_SPIKE = 0; +float TE_SUPERSPIKE = 1; +float TE_GUNSHOT = 2; +float TE_EXPLOSION = 3; +float TE_TAREXPLOSION = 4; +float TE_LIGHTNING1 = 5; +float TE_LIGHTNING2 = 6; +float TE_WIZSPIKE = 7; +float TE_KNIGHTSPIKE = 8; +float TE_LIGHTNING3 = 9; +float TE_LAVASPLASH = 10; +float TE_TELEPORT = 11; +float TE_BLOOD = 12; +float TE_LIGHTNINGBLOOD = 13; + +// sound channels +// channel 0 never willingly overrides +// other channels (1-7) allways override a playing sound on that channel +#define CHAN_AUTO 0 +#define CHAN_WEAPON 1 +#define CHAN_VOICE 2 +#define CHAN_ITEM 3 +#define CHAN_BODY 4 +// chan_no_phs_add is defined in engine.qc + +#define ATTN_NONE 0.0 // no volume fall off due to range +#define ATTN_NORM 1.0 // small volume fall off (1000 range) +#define ATTN_IDLE 2.0 // medium volume fall off (500 range) +#define ATTN_STATIC 3.0 // large volume fall off (333 range) + +// entity effects + +//float EF_BRIGHTFIELD = 1; +float EF_MUZZLEFLASH = 2; +float EF_BRIGHTLIGHT = 4; +float EF_DIMLIGHT = 8; +float EF_FLAG1 = 16; +float EF_FLAG2 = 32; +// GLQuakeWorld Stuff +// float EF_BLUE = 64; // Blue Globe effect for Quad +// float EF_RED = 128; // Red Globe effect for Pentagram + +// messages +#define MSG_BROADCAST 0 // unreliable to all +#define MSG_ONE 1 // reliable to one (msg_entity) +#define MSG_ALL 2 // reliable to all +#define MSG_INIT 3 // write to the init string +#define MSG_MULTICAST 4 // for multicast() call + +// message levels +#define PRINT_LOW 0 +#define PRINT_MEDIUM 1 +#define PRINT_HIGH 2 +#define PRINT_CHAT 3 + +// multicast sets +#define MULTICAST_ALL 0 // every client +#define MULTICAST_PHS 1 // within hearing +#define MULTICAST_PVS 2 // within sight +#define MULTICAST_ALL_R 3 // every client, reliable +#define MULTICAST_PHS_R 4 // within hearing, reliable +#define MULTICAST_PVS_R 5 // within sight, reliable + + + + +//================================================ + +// +// globals +// +// float movedist; + +string string_null; // null string, nothing should be held here + +entity activator; // the entity that activated a trigger or brush + +entity damage_attacker; // set by T_Damage +entity damage_inflictor; // set by T_Damage +INTEGER damage_mod; // set by T_Damage + +float framecount; + +// +// cvars checked each frame +// +float timelimit; +float fraglimit; +float rj; + +#ifndef NETQUAKE +// these variables are not a part of QW's system fields +float deathmatch; +float swat; +float coop; +float teamplay; +#endif + +float skill; + +// coop spawning globals +entity lastspawn; +float spotspawn; + +entity shub; // boss entity + +//================================================ + +#define WT_MEDIEVAL 0 +#define WT_METAL 1 +#define WT_BASE 2 + +//================================================ + +.string killtarget; // used by anything using SUB_UseTargets (items/triggers/etc) + +.void(entity attacker, float damage) th_pain; // used by secret doors, monsters, players +.void() th_die; // used by anything damagable (doors/buttons/players/monsters/explobox/triggermultiple) + +.float speed; // used with door/plats/fireball spawner, inherited +.string map; // used with world/trigger_changelevel, inherited + +// used with monsters/players +.INTEGER ammo_shells_real; // real shells count +.INTEGER ammo_nails_real; // real nails count +.INTEGER ammo_rockets_real; // real rockets count +.INTEGER ammo_cells_real; // real cells count + +// Zoid Additions +noref .float maxspeed; // Used to set Maxspeed on a player +noref .float gravity; // Gravity Multiplier (0 to 1.0) + +.float attack_finished; // used with lots of stuff... +.float pain_finished; // used with monsters/players + +.float invincible_finished; // only used for players but object check needed for T_Damage +.float super_damage_finished; // only used for players but object check needed for T_Damage + +// +// misc +// +.float cnt; // misc flag used by trains/dropped pent and quad/monsters + +// intermission +float intermission_running; +float intermission_exittime; + +#ifdef NETQUAKE +entity newmis; +#endif + +// extensions +.float alpha; // DP_ENT_ALPHA + +// enums +// ai ranges +enum +{ + RANGE_MELEE, + RANGE_NEAR, + RANGE_MID, + RANGE_FAR +}; + +// monster attack states +enum +{ + AS_NONE, + AS_STRAIGHT, + AS_SLIDING, + AS_MELEE, + AS_MISSILE +}; + +// door/plat states +enum { + STATE_TOP, + STATE_BOTTOM, + STATE_UP, + STATE_DOWN +}; + +// heal defines +enumflags { + H_ROTTEN, + H_MEGA +}; + +// weaponstate defines +enum { + WS_IDLE, + WS_FIRING1, + WS_FIRING2 // used with nailgun +}; + +// ammo type defines +enum { + AT_NONE, + AT_SHELLS, + AT_NAILS, + AT_ROCKETS, + AT_CELLS +}; + +// unions +//floats (includes vectors) +.union { + struct { // fields used with world object + float worldtype; // world type, 0=medieval 1=metal 2=base + }; + struct { // fields used with triggers/doors/plats + float delay; // time from activation to firing + float wait; // time from firing to restarting + float t_length; // override length to move sideways + float t_width; // override length to move upwards/downwards + vector finaldest; // used with SUB_CalcMove + vector finalangle; // used with SUB_CalcMove + float count; // for counting triggers + float dmg; // damage done by door/train/trigger hurt + vector mangle; // initial angle (doors/teleporter/intermission) + float lip; // position adjustment (func_door/func_button) + float state; // object state (doors/buttons/plats) + vector pos1; // top position (doors/buttons/plats) + vector pos2; // bottom position (doors/buttons/plats) + float height; // height (plats/trigger_monsterjump) + vector dest1; // passed to CalcMove (doors) + vector dest2; // passed to CalcMove (doors) + }; + struct { // fields used with players + float weaponframe_time; // weapon frame advance time + float suicide_time; // time to allow suicide after spawn + float healdecay; // time when health will decay + float show_hostile; // used to alert monsters + float lightning_sound; // used for lightning sound playback + float fly_sound; // used with trigger_push and maintaining wind sound + float invincible_time; // pentagram state + float invincible_sound; // pentagram sound playback + float invisible_time; // ring state + float invisible_sound; // ring sound playback + float invisible_finished; // ring current duration + float super_time; // quad state + float super_sound; // quad sound playback + float rad_time; // rad suit state + float radsuit_finished; // rad suit current duration + float dmgtime; // time slime/lava will damage + float swim_flag; // swim sound playback + float air_finished; // when time > air_finished, start drowning + float waterdmg; // damage water will deal when drowning + float jump_flag; // last z velocity used for falling damage + }; + struct { // fields used with items + float healamount; // amount healed with health item + //float ammo_count; // ammo amount + }; + struct { // fields used with generic projectiles + float damage_direct; // damage done with a direct hit + float damage_exp; // damage done from radius damage + float radius_exp; // radius of radius damage + float expire_time; // time when projectile dies + float proj_think_time; // interval between thinks + }; + struct { // fields used with lights + float light_lev; // not used by game, but parsed by light util + float style; // lightstyle to use for light + }; + struct { // fields used with monsters + float search_time; // search time intervals + float attack_state; // current AI attack state + float pausetime; // time to pause for monsters + float hknightattack; // hell knight attack pattern + float lefty; // ai slide move + float wizardidle; // wizard idle sound timer + float inpain; // zombie in pain + }; + // fields used with ambient sounds? + /* + struct { + float waitmin; + float waitmax; + float distance; + float volume; + }; + */ +}; + +//integers +.union { + + struct { // fields used with players + INTEGER weaponstate; // firing state of current weapon + INTEGER walkframe; // used with walking animation + INTEGER ammo_type; // ammo type in use + }; + struct { // fields used with bubbles spawned from drowning + INTEGER bubble_count; // keeps track of the number of bubbles + INTEGER bubble_state; // associated with bubble progression + }; + struct { // fields used with items + INTEGER healtype; // type of health with health item + }; + struct { // fields used with generic projectiles + INTEGER mod_direct; // mod type for direct hit + INTEGER mod_exp; // mod type for radius damage + INTEGER proj_effect; // effect used with projectile + INTEGER voided; // projectile has been voided + }; +}; + +//functions +.union { + struct { // fields used with triggers/doors/plats + void() think1; // used with SUB_CalcMove + }; + struct { // fields used with generic projectiles + void() proj_think; // extra think function used with projectile + float() proj_touch; // extra touch function used with projectile + }; + struct { // fields used with monsters + void() th_stand; // standing animation + void() th_walk; // walking animation + void() th_run; // running animation + void() th_missile; // ranged animation + void() th_melee; // melee animation + }; +}; + + +//entities +.union { + struct { // fields used with triggers/doors/plats + entity trigger_field; // used with linking (doors) + }; + + struct { // fields used with monsters + entity oldenemy; // old enemy + entity movetarget; // target entity to move to + }; +}; + +//strings +.union { + struct { // fields used with world object + string wad; //mute it + }; + struct { // fields used with triggers/doors/plats + string noise4; // extra sound (doors) + }; + struct { // fields used with items + string mdl; // model used with SUB_regen + }; +}; + +//mute those warnings (unions/structs do not support noref mid-struct, but a later def will propogate the noref flag) +noref .string wad; +noref .float light_lev; + +//=========================================================================== + + +// +// builtin functions +// + +void(vector ang) makevectors = #1; // sets v_forward, etc globals +void(entity e, vector o) setorigin = #2; +void(entity e, string m) setmodel = #3; // set movetype and solid first +void(entity e, vector min, vector max) setsize = #4; +// #5 was removed +// void() break = #6; +float() random = #7; // returns 0 - 1 +//void(entity e, float chan, string samp, float vol, float atten) sound = #8; //FBX +vector(vector v) normalize = #9; +void(string e) error = #10; +void(string e) objerror = #11; +float(vector v) vlen = #12; +float(vector v) vectoyaw = #13; +entity() spawn = #14; +void(entity e) remove = #15; + +// sets trace_* globals +// nomonsters can be: +// An entity will also be ignored for testing if forent == test, +// forent->owner == test, or test->owner == forent +// a forent of world is ignored +void(vector v1, vector v2, float nomonsters, entity forent) traceline = #16; + +entity() checkclient = #17; // returns a client to look for +entity(entity start, .string fld, string match) find = #18; +string(string s) precache_sound = #19; +string(string s) precache_model = #20; +//void(entity client, string s)stuffcmd = #21; // FBX +entity(vector org, float rad) findradius = #22; +// bprint moved to engine.qc +// sprint moved to engine.qc +void(string s) dprint = #25; +string(float f) ftos = #26; +string(vector v) vtos = #27; +void() coredump = #28; // prints all edicts +void() traceon = #29; // turns statment trace on +void() traceoff = #30; +void(entity e) eprint = #31; // prints an entire edict +float(float yaw, float dist) walkmove = #32; // returns TRUE or FALSE +// #33 was removed +float() droptofloor= #34; // TRUE if landed on floor +void(float style, string value) lightstyle = #35; +float(float v) rint = #36; // round to nearest int +float(float v) floor = #37; // largest integer <= v +float(float v) ceil = #38; // smallest integer >= v +// #39 was removed +float(entity e) checkbottom = #40; // true if self is on ground +float(vector v) pointcontents = #41; // returns a CONTENT_* +// #42 was removed +float(float f) fabs = #43; +//vector(entity e, float speed) aim = #44; // returns the shooting vector // FBX +// cvar moved to engine.qc +void(string s) localcmd = #46; // put string into local que +entity(entity e) nextent = #47; // for looping through all ents +// #48 was removed +void() ChangeYaw = #49; // turn towards self.ideal_yaw + // at self.yaw_speed +// #50 was removed +vector(vector v) vectoangles = #51; + +// +// direct client message generation +// +/* +void(float to, float f) WriteByte = #52; +void(float to, float f) WriteChar = #53; +void(float to, float f) WriteShort = #54; +void(float to, float f) WriteLong = #55; +void(float to, float f) WriteCoord = #56; +void(float to, float f) WriteAngle = #57; +void(float to, string s) WriteString = #58; +void(float to, entity s) WriteEntity = #59; +// FBX'd +*/ +// several removed + +void(float step) movetogoal = #67; + +string(string s) precache_file = #68; // no effect except for -copy +void(entity e) makestatic = #69; +void(string s) changelevel = #70; + +//#71 was removed + +void(string var, string val) cvar_set = #72; // sets cvar.value + +//void(entity client, string s) centerprint = #73; // sprint, but in middle // FBX + +void(vector pos, string samp, float vol, float atten) ambientsound = #74; + +string(string s) precache_model2 = #75; // registered version only +string(string s) precache_sound2 = #76; // registered version only +string(string s) precache_file2 = #77; // registered version only + +//void(entity e) setspawnparms = #78; // set parm1... to the // FBX + // values at level start + // for coop respawn +// logfrag moved to engine.qc +// infokey moved to engine.qc +// stof moved to engine.qc + +//============================================================================ + +// +// subs.qc +// +void(vector tdest, float tspeed, void() func) SUB_CalcMove; +void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt; +void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove; +void() SUB_CalcMoveDone; +void() SUB_CalcAngleMoveDone; +void() SUB_Null; +void() SUB_UseTargets; +void() SUB_Remove; + +// +// combat.qc +// +void(entity targ, entity inflictor, entity attacker, float damage, INTEGER mod) T_Damage; + +float (entity e, float healamount, float ignore) T_Heal; // health function + +BOOL(entity targ, entity inflictor) CanDamage; +.float crouch; +float score_lastTic; +.float alpha; +.float nade_lives; // The number of Grenades a player has. +.float plasma_lives; +.float kill_time; +.float kill_amount; //For reseting kill medals +.float groundwep; //For weapon pickup Icons +.float reset; diff --git a/r17/Revamped src/Revamped QC/doors.qc b/r17/Revamped src/Revamped QC/doors.qc new file mode 100755 index 00000000..1d76f425 --- /dev/null +++ b/r17/Revamped src/Revamped QC/doors.qc @@ -0,0 +1,770 @@ + +float DOOR_START_OPEN = 1; +float DOOR_DONT_LINK = 4; +float DOOR_GOLD_KEY = 8; +float DOOR_SILVER_KEY = 16; +float DOOR_TOGGLE = 32; + +/* + +Doors are similar to buttons, but can spawn a fat trigger field around them +to open without a touch, and they link together to form simultanious +double/quad doors. + +Door.owner is the master door. If there is only one door, it points to itself. +If multiple doors, all will point to a single one. + +Door.enemy chains from the master door through all doors linked in the chain. + +*/ + +/* +============================================================================= + +THINK FUNCTIONS + +============================================================================= +*/ + +void() door_go_down; +void() door_go_up; + +void() door_blocked = +{ + T_Damage (other, self, self.goalentity, self.dmg, MOD_SQUISH); + +// if a door has a negative wait, it would never come back if blocked, +// so let it just squash the object to death real fast + if (self.wait >= 0) + { + if (self.state == STATE_DOWN) + door_go_up (); + else + door_go_down (); + } +}; + + +void() door_hit_top = +{ + sound (self, chan_no_phs_add|CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_TOP; + if (self.spawnflags & DOOR_TOGGLE) + return; // don't come down automatically + self.think = door_go_down; + self.nextthink = self.ltime + self.wait; +}; + +void() door_hit_bottom = +{ + sound (self, chan_no_phs_add|CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_BOTTOM; +}; + +void() door_go_down = +{ + sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + if (self.max_health) + { + self.takedamage = DAMAGE_YES; + self.health = self.max_health; + } + + self.state = STATE_DOWN; + SUB_CalcMove (self.pos1, self.speed, door_hit_bottom); +}; + +void() door_go_up = +{ + if (self.state == STATE_UP) + return; // allready going up + + if (self.state == STATE_TOP) + { // reset top wait time + self.nextthink = self.ltime + self.wait; + return; + } + + sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + self.state = STATE_UP; + SUB_CalcMove (self.pos2, self.speed, door_hit_top); + + SUB_UseTargets(); +}; + + +/* +============================================================================= + +ACTIVATION FUNCTIONS + +============================================================================= +*/ + +void() door_fire = +{ + local entity oself; + local entity starte; + + if (self.owner != self) + objerror ("door_fire: self.owner != self"); + +// play use key sound + + if (self.items) + sound (self, CHAN_ITEM, self.noise4, 1, ATTN_NORM); + + self.message = string_null; // no more message + oself = self; + + if (self.spawnflags & DOOR_TOGGLE) + { + if (self.state == STATE_UP || self.state == STATE_TOP) + { + starte = self; + do + { + door_go_down (); + self = self.enemy; + } while ( (self != starte) && (self != world) ); + self = oself; + return; + } + } + +// trigger all paired doors + starte = self; + + do + { + self.goalentity = activator; // Who fired us + door_go_up (); + self = self.enemy; + } while ( (self != starte) && (self != world) ); + self = oself; +}; + + +void() door_use = +{ + local entity oself; + + self.message = ""; // door message are for touch only + self.owner.message = ""; + self.enemy.message = ""; + + oself = self; + self = self.owner; + door_fire (); + self = oself; +}; + + +void() door_trigger_touch = +{ + if (other.health <= 0) + return; + + if (time < self.attack_finished) + return; + self.attack_finished = time + 1; + + activator = other; + + self = self.owner; + door_use (); +}; + + +void() door_killed = +{ + local entity oself; + + oself = self; + self = self.owner; + self.health = self.max_health; + self.takedamage = DAMAGE_NO; // wil be reset upon return + door_use (); + self = oself; +}; + + +/* +================ +door_touch + +Prints messages and opens key doors +================ +*/ +void() door_touch = +{ + if (other.classname != "player") + return; + if (self.owner.attack_finished > time) + return; + + self.owner.attack_finished = time + 2; + + if (self.owner.message != "") + { + centerprint (other, self.owner.message); + sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM); + } + +// key door stuff + if (!self.items) + return; + +// FIXME: blink key on player's status bar + if ( (self.items & other.items) != self.items ) + { + if (self.owner.items == IT_KEY1) + { + switch (world.worldtype) + { + case WT_MEDIEVAL: + centerprint (other, "You need the silver key"); + break; + case WT_METAL: + centerprint (other, "You need the silver runekey"); + break; + case WT_BASE: + centerprint (other, "You need the silver keycard"); + break; + } + } + else + { + switch (world.worldtype) + { + case WT_MEDIEVAL: + centerprint (other, "You need the gold key"); + break; + case WT_METAL: + centerprint (other, "You need the gold runekey"); + break; + case WT_BASE: + centerprint (other, "You need the gold keycard"); + break; + } + } + + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + return; + } + + other.items = other.items - self.items; + self.touch = SUB_Null; + if (self.enemy) + self.enemy.touch = SUB_Null; // get paired door + door_use (); +}; + +/* +============================================================================= + +SPAWNING FUNCTIONS + +============================================================================= +*/ + + +entity(vector fmins, vector fmaxs) spawn_field = +{ + local entity trigger; + local vector t1, t2; + + trigger = spawn(); + trigger.movetype = MOVETYPE_NONE; + trigger.solid = SOLID_TRIGGER; + trigger.owner = self; + trigger.touch = door_trigger_touch; + + t1 = fmins; + t2 = fmaxs; + setsize (trigger, t1 - '60 60 8', t2 + '60 60 8'); + return (trigger); +}; + + +BOOL (entity e1, entity e2) EntitiesTouching = +{ + if (e1.mins_x > e2.maxs_x) + return FALSE; + if (e1.mins_y > e2.maxs_y) + return FALSE; + if (e1.mins_z > e2.maxs_z) + return FALSE; + if (e1.maxs_x < e2.mins_x) + return FALSE; + if (e1.maxs_y < e2.mins_y) + return FALSE; + if (e1.maxs_z < e2.mins_z) + return FALSE; + return TRUE; +}; + + +/* +============= +LinkDoors + + +============= +*/ +void() LinkDoors = +{ + local entity t, starte; + local vector cmins, cmaxs; + + if (self.enemy) + return; // already linked by another door + if (self.spawnflags & 4) + { + self.owner = self.enemy = self; + return; // don't want to link this door + } + + cmins = self.mins; + cmaxs = self.maxs; + + starte = self; + t = self; + + do + { + self.owner = starte; // master door + + if (self.health) + starte.health = self.health; + if (self.targetname) + starte.targetname = self.targetname; + if (self.message != "") + starte.message = self.message; + + t = find (t, classname, self.classname); + if (!t) + { + self.enemy = starte; // make the chain a loop + + // shootable, fired, or key doors just needed the owner/enemy links, + // they don't spawn a field + + self = self.owner; + + if (self.health) + return; + if (self.targetname) + return; + if (self.items) + return; + + self.owner.trigger_field = spawn_field(cmins, cmaxs); + + return; + } + + if (EntitiesTouching(self,t)) + { + if (t.enemy) + objerror ("cross connected doors"); + + self.enemy = t; + self = t; + + if (t.mins_x < cmins_x) + cmins_x = t.mins_x; + if (t.mins_y < cmins_y) + cmins_y = t.mins_y; + if (t.mins_z < cmins_z) + cmins_z = t.mins_z; + if (t.maxs_x > cmaxs_x) + cmaxs_x = t.maxs_x; + if (t.maxs_y > cmaxs_y) + cmaxs_y = t.maxs_y; + if (t.maxs_z > cmaxs_z) + cmaxs_z = t.maxs_z; + } + } while (1 ); + +}; + + +/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE +if two doors touch, they are assumed to be connected and operate as a unit. + +TOGGLE causes the door to wait in both the start and end states for a trigger event. + +START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not usefull for touch or takedamage doors). + +Key doors are allways wait -1. + +"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet +"angle" determines the opening direction +"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door. +"health" if set, door must be shot open +"speed" movement speed (100 default) +"wait" wait before returning (3 default, -1 = never return) +"lip" lip remaining at end of move (8 default) +"dmg" damage to inflict when blocked (2 default) +"sounds" +0) no sound +1) stone +2) base +3) stone chain +4) screechy metal +*/ + +void() func_door = +{ + switch (world.worldtype) + { + case WT_MEDIEVAL: + precache_sound ("doors/medtry.wav"); + precache_sound ("doors/meduse.wav"); + self.noise3 = "doors/medtry.wav"; + self.noise4 = "doors/meduse.wav"; + break; + case WT_METAL: + precache_sound ("doors/runetry.wav"); + precache_sound ("doors/runeuse.wav"); + self.noise3 = "doors/runetry.wav"; + self.noise4 = "doors/runeuse.wav"; + break; + case WT_BASE: + precache_sound ("doors/basetry.wav"); + precache_sound ("doors/baseuse.wav"); + self.noise3 = "doors/basetry.wav"; + self.noise4 = "doors/baseuse.wav"; + break; + default: + dprint ("no worldtype set!\n"); + } + + switch (self.sounds) + { + case 0: + precache_sound ("misc/null.wav"); + precache_sound ("misc/null.wav"); + self.noise1 = "misc/null.wav"; + self.noise2 = "misc/null.wav"; + break; + case 1: + precache_sound ("doors/drclos4.wav"); + precache_sound ("doors/doormv1.wav"); + self.noise1 = "doors/drclos4.wav"; + self.noise2 = "doors/doormv1.wav"; + break; + case 2: + precache_sound ("doors/hydro1.wav"); + precache_sound ("doors/hydro2.wav"); + self.noise2 = "doors/hydro1.wav"; + self.noise1 = "doors/hydro2.wav"; + break; + case 3: + precache_sound ("doors/stndr1.wav"); + precache_sound ("doors/stndr2.wav"); + self.noise2 = "doors/stndr1.wav"; + self.noise1 = "doors/stndr2.wav"; + break; + case 4: + precache_sound ("doors/ddoor1.wav"); + precache_sound ("doors/ddoor2.wav"); + self.noise1 = "doors/ddoor2.wav"; + self.noise2 = "doors/ddoor1.wav"; + break; + } + + SetMovedir (); + + self.max_health = self.health; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + setorigin (self, self.origin); + setmodel (self, self.model); + self.classname = "door"; + + self.blocked = door_blocked; + self.use = door_use; + + if (self.spawnflags & DOOR_SILVER_KEY) + self.items = IT_KEY1; + if (self.spawnflags & DOOR_GOLD_KEY) + self.items = IT_KEY2; + + if (!self.speed) + self.speed = 100; + if (!self.wait) + self.wait = 3; + if (!self.lip) + self.lip = 8; + if (!self.dmg) + self.dmg = 2; + + self.pos1 = self.origin; + self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip); + +// DOOR_START_OPEN is to allow an entity to be lighted in the closed position +// but spawn in the open position + if (self.spawnflags & DOOR_START_OPEN) + { + setorigin (self, self.pos2); + self.pos2 = self.pos1; + self.pos1 = self.origin; + } + + self.state = STATE_BOTTOM; + + if (self.health) + { + self.takedamage = DAMAGE_YES; + self.th_die = door_killed; + } + + if (self.items) + self.wait = -1; + + self.touch = door_touch; + +// LinkDoors can't be done until all of the doors have been spawned, so +// the sizes can be detected properly. + self.think = LinkDoors; + self.nextthink = self.ltime + 0.1; +}; + +/* +============================================================================= + +SECRET DOORS + +============================================================================= +*/ + +void() fd_secret_move1; +void() fd_secret_move2; +void() fd_secret_move3; +void() fd_secret_move4; +void() fd_secret_move5; +void() fd_secret_move6; +void() fd_secret_done; + +float SECRET_OPEN_ONCE = 1; // stays open +float SECRET_1ST_LEFT = 2; // 1st move is left of arrow +float SECRET_1ST_DOWN = 4; // 1st move is down from arrow +float SECRET_NO_SHOOT = 8; // only opened by trigger +float SECRET_YES_SHOOT = 16; // shootable even if targeted + + +void () fd_secret_use = +{ + local float temp; + + self.health = 10000; + + // exit if still moving around... + if (self.origin != self.oldorigin) + return; + + self.message = string_null; // no more message + + SUB_UseTargets(); // fire all targets / killtargets + + if (!(self.spawnflags & SECRET_NO_SHOOT)) + { + self.th_pain = SUB_Null; + self.takedamage = DAMAGE_NO; + } + self.velocity = '0 0 0'; + + // Make a sound, wait a little... + + sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.nextthink = self.ltime + 0.1; + + temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1 + makevectors(self.mangle); + + if (!self.t_width) + { + if (self.spawnflags & SECRET_1ST_DOWN) + self.t_width = fabs(v_up * self.size); + else + self.t_width = fabs(v_right * self.size); + } + + if (!self.t_length) + self.t_length = fabs(v_forward * self.size); + + if (self.spawnflags & SECRET_1ST_DOWN) + self.dest1 = self.origin - v_up * self.t_width; + else + self.dest1 = self.origin + v_right * (self.t_width * temp); + + self.dest2 = self.dest1 + v_forward * self.t_length; + SUB_CalcMove(self.dest1, self.speed, fd_secret_move1); + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); +}; + +// Wait after first movement... +void () fd_secret_move1 = +{ + self.nextthink = self.ltime + 1.0; + self.think = fd_secret_move2; + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); +}; + +// Start moving sideways w/sound... +void () fd_secret_move2 = +{ + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + SUB_CalcMove(self.dest2, self.speed, fd_secret_move3); +}; + +// Wait here until time to go back... +void () fd_secret_move3 = +{ + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + if (!(self.spawnflags & SECRET_OPEN_ONCE)) + { + self.nextthink = self.ltime + self.wait; + self.think = fd_secret_move4; + } +}; + +// Move backward... +void () fd_secret_move4 = +{ + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + SUB_CalcMove(self.dest1, self.speed, fd_secret_move5); +}; + +// Wait 1 second... +void () fd_secret_move5 = +{ + self.nextthink = self.ltime + 1.0; + self.think = fd_secret_move6; + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); +}; + +void () fd_secret_move6 = +{ + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done); +}; + +void () fd_secret_done = +{ + if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT) + { + self.health = 10000; + self.takedamage = DAMAGE_YES; + self.th_pain = fd_secret_use; + self.th_die = fd_secret_use; + } + sound(self, chan_no_phs_add|CHAN_VOICE, self.noise3, 1, ATTN_NORM); +}; + +void () secret_blocked = +{ + if (time < self.attack_finished) + return; + self.attack_finished = time + 0.5; + T_Damage (other, self, self, self.dmg, MOD_SQUISH); +}; + +/* +================ +secret_touch + +Prints messages +================ +*/ +void() secret_touch = +{ + if (other.classname != "player") + return; + if (self.attack_finished > time) + return; + + self.attack_finished = time + 2; + + if (self.message) + { + centerprint (other, self.message); + sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM); + } +}; + + +/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot +Basic secret door. Slides back, then to the side. Angle determines direction. +wait = # of seconds before coming back +1st_left = 1st move is left of arrow +1st_down = 1st move is down from arrow +always_shoot = even if targeted, keep shootable +t_width = override WIDTH to move back (or height if going down) +t_length = override LENGTH to move sideways +"dmg" damage to inflict when blocked (2 default) + +If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage. +"sounds" +1) medieval +2) metal +3) base +*/ + +void () func_door_secret = +{ + switch (self.sounds) + { + case 0: + case 3: + precache_sound ("doors/basesec1.wav"); + precache_sound ("doors/basesec2.wav"); + self.noise2 = "doors/basesec1.wav"; + self.noise1 = "doors/basesec2.wav"; + self.noise3 = "doors/basesec2.wav"; + break; + case 1: + precache_sound ("doors/latch2.wav"); + precache_sound ("doors/winch2.wav"); + precache_sound ("doors/drclos4.wav"); + self.noise1 = "doors/latch2.wav"; + self.noise2 = "doors/winch2.wav"; + self.noise3 = "doors/drclos4.wav"; + break; + case 2: + precache_sound ("doors/airdoor1.wav"); + precache_sound ("doors/airdoor2.wav"); + self.noise2 = "doors/airdoor1.wav"; + self.noise1 = "doors/airdoor2.wav"; + self.noise3 = "doors/airdoor2.wav"; + break; + } + + if (!self.dmg) + self.dmg = 2; + + // Magic formula... + self.mangle = self.angles; + self.angles = '0 0 0'; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + self.classname = "door"; + setmodel (self, self.model); + setorigin (self, self.origin); + + self.touch = secret_touch; + self.blocked = secret_blocked; + self.speed = 50; + self.use = fd_secret_use; + if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT) + { + self.health = 10000; + self.takedamage = DAMAGE_YES; + self.th_pain = fd_secret_use; + } + self.oldorigin = self.origin; + if (!self.wait) + self.wait = 5; // 5 seconds before closing +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/effects.qc b/r17/Revamped src/Revamped QC/effects.qc new file mode 100755 index 00000000..0a5c6b8f --- /dev/null +++ b/r17/Revamped src/Revamped QC/effects.qc @@ -0,0 +1,720 @@ + +// Effects code (EFF) -- + +// TE effects/muzzleflash/messages + +// modular efs +var float ef_red = 0; // used for glow on pent item +var float ef_pent = EF_DIMLIGHT; // used for pent effect on player +var float ef_blue = 0; // used for glow on quad +var float ef_quad = EF_DIMLIGHT; // used for quad effect on player + +// base te write functions +void WriteVector (float msg, vector org) = +{ + WriteCoord (msg, org_x); + WriteCoord (msg, org_y); + WriteCoord (msg, org_z); +}; + +#ifdef NETQUAKE +void(vector org, float effect) _EFF_PointEffect = +{ + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, effect); + WriteVector (MSG_BROADCAST, org); +}; + +void(entity ent, vector org, vector org2, float effect) _EFF_BeamEffect = +{ + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, effect); + WriteEntity (MSG_BROADCAST, ent); + WriteVector (MSG_BROADCAST, org); + WriteVector (MSG_BROADCAST, org2); +}; + +void(vector org, float damage, float effect) _EFF_CountEffect = +{ + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, effect); + WriteByte (MSG_BROADCAST, damage); + WriteVector (MSG_BROADCAST, org); +}; + +#define EFF_PointEffect(a,b,c) _EFF_PointEffect(a,b) +#define EFF_BeamEffect(a,b,c,d,e) _EFF_BeamEffect(a,b,c,d) +#define EFF_CountEffect(a,b,c,d) _EFF_CountEffect(a,b,c) +#else +void(vector org, float effect, float mcast) EFF_PointEffect = +{ + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, effect); + WriteVector (MSG_MULTICAST, org); + multicast (org, mcast); +}; + +void(entity ent, vector org, vector org2, float effect, float mcast) EFF_BeamEffect = +{ + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, effect); + WriteEntity (MSG_MULTICAST, ent); + WriteVector (MSG_MULTICAST, org); + WriteVector (MSG_MULTICAST, org2); + multicast (org, mcast); +}; + +void(vector org, float damage, float effect, float mcast) EFF_CountEffect = +{ + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, effect); + WriteByte (MSG_MULTICAST, damage); + WriteVector (MSG_MULTICAST, org); + multicast (org, mcast); +}; +#endif + +/* +================ +SpawnBlood +================ +*/ +void(vector org, float damage) _SpawnBlood_TEBlood = +{ + te_blood(org, '0 0 0', damage*2); +}; + +void(vector org, float damage) _SpawnBlood = +{ +#ifdef NETQUAKE + particle (org, '0 0 0', 73, damage*2); +#else + EFF_CountEffect(org, damage, TE_BLOOD, MULTICAST_PVS); +#endif +}; +/* +void() NadeTouch = +{ +if (other.nade_lives > 4) +{ +sprint (other, "Can't pick up anymore grenades/n"); +return; +} +other.nade_lives = other.nade_lives + 1; +}; + +*/ +void() s_smokee6 = [5, SUB_Remove] {}; +void() s_smokee5 = [4, s_smokee6] {}; +void() s_smokee4 = [3, s_smokee5] {}; +void() s_smokee3 = [2, s_smokee4] {}; +void() s_smokee2 = [1, s_smokee3] {}; +void() s_smokee1 = [0, s_smokee2] {}; + +void() s_needle3 = [2, SUB_Remove] {}; +void() s_needle2 = [1, s_needle3] {}; +void() s_needle1 = [0, s_needle2] {}; + +void() s_plasma14 = [13, SUB_Remove] {}; +void() s_plasma13 = [12, s_plasma14] {}; +void() s_plasma12 = [11, s_plasma13] {}; +void() s_plasma11 = [10, s_plasma12] {}; +void() s_plasma10 = [9, s_plasma11] {}; +void() s_plasma9 = [8, s_plasma10] {}; +void() s_plasma8 = [7, s_plasma9] {}; +void() s_plasma7 = [6, s_plasma8] {}; +void() s_plasma6 = [5, s_plasma7] {}; +void() s_plasma5 = [4, s_plasma6] {}; +void() s_plasma4 = [3, s_plasma5] {}; +void() s_plasma3 = [2, s_plasma4] {}; +void() s_plasma2 = [1, s_plasma3] {}; +void() s_plasma1 = [0, s_plasma2] {}; + +void(vector org) createpinkdust = +{ + local entity s; + + + s = self; // save old self + + self = spawn(); + + self.movetype = MOVETYPE_NONE; + self.velocity = '0 0 0'; + self.touch = SUB_Null; + setmodel (self, "progs/needler_dust.spr"); + setorigin (self, org); + self.solid = SOLID_NOT; + s_needle1(); + self = s; // restore old self + +}; +void(vector org) createplasma = +{ + local entity s; + + + s = self; // save old self + + self = spawn(); + + self.movetype = MOVETYPE_NONE; + self.velocity = '0 0 0'; + self.touch = SUB_Null; + setmodel (self, "sprites/s_plasma4.spr"); + setorigin (self, org); + self.solid = SOLID_NOT; + s_plasma1(); + self = s; // restore old self + +}; + +void() s_plasmaa5 = [4, SUB_Remove] {}; +void() s_plasmaa4 = [3, s_plasmaa5] {createplasma(self.origin);}; +void() s_plasmaa3 = [2, s_plasmaa4] {}; +void() s_plasmaa2 = [1, s_plasmaa3] {}; +void() s_plasmaa1 = [0, s_plasmaa2] {}; + +void(vector org) plasmaexplo = +{ + local entity s; + local float r; + r = random(); + + + s = self; // save old self + + self = spawn(); + + self.movetype = MOVETYPE_NONE; + self.velocity = '0 0 0'; + self.touch = SUB_Null; + setmodel (self, "sprites/plasma3.spr"); + setorigin (self, org); + self.solid = SOLID_NOT; + + // So that debris comes out in random spurts over It coming out in the same number every time --Mexicouger + + s_plasmaa1 (); + + self = s; // restore old self +}; +void(vector org) pistolsmoke = +{ + local entity s; + + + s = self; // save old self + + self = spawn(); + + self.movetype = MOVETYPE_FLY; + + + self.velocity = v_forward; + self.velocity = (self.velocity * 80); + self.touch = SUB_Null; + setmodel (self, "sprites/s_smoke2.spr"); + setorigin (self, ((org + (v_forward * 15)) + '0 0 12')); + self.solid = SOLID_NOT; + s_smokee1(); + self = s; // restore old self +}; + +// #if defined(NETQUAKE) || defined(MONSTERS) + + +void() s_explode14 = [13, SUB_Remove] {}; +void() s_explode13 = [12, s_explode14] {}; +void() s_explode12 = [11, s_explode13] {}; +void() s_explode11 = [10, s_explode12] {}; +void() s_explode10 = [9, s_explode11] {}; +void() s_explode9 = [8, s_explode10] {}; +void() s_explode8 = [7, s_explode9] {}; +void() s_explode7 = [6, s_explode8] {}; +void() s_explode6 = [5, s_explode7] {}; +void() s_explode5 = [4, s_explode6] {}; +void() s_explode4 = [3, s_explode5] {}; +void() s_explode3 = [2, s_explode4] {}; +void() s_explode2 = [1, s_explode3] {}; +void() s_explode1 = [0, s_explode2] {}; + +void(vector org) CreateExplosion = +{ + local entity s; + local float r; + r = random(); + + + s = self; // save old self + + self = spawn(); + + self.movetype = MOVETYPE_NONE; + self.velocity = '0 0 0'; + self.touch = SUB_Null; + setmodel (self, "progs/s_explod.spr"); + setorigin (self, org); + self.solid = SOLID_NOT; + sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); + // So that debris comes out in random spurts over It coming out in the same number every time --Mexicouger + s_explode1 (); + + self = s; // restore old self +}; +// #endif + +void(vector org) _TE_explosion = +{ + EFF_PointEffect(org, TE_EXPLOSION, MULTICAST_PHS); +#ifdef NETQUAKE + CreateExplosion(org); +#endif +}; + +void(vector org) _TE_gunshot = +{ +#ifdef NETQUAKE + EFF_PointEffect(org, TE_GUNSHOT, MULTICAST_PVS); +#else + EFF_CountEffect(org, 3, TE_GUNSHOT, MULTICAST_PVS); +#endif +}; + +void(vector org) _TE_spike = +{ + EFF_PointEffect(org, TE_SPIKE, MULTICAST_PHS); +}; + +void(vector org) _TE_knightspike = +{ + EFF_PointEffect(org, TE_KNIGHTSPIKE, MULTICAST_PHS); +}; + +void(vector org) _TE_wizspike = +{ + EFF_PointEffect(org, TE_WIZSPIKE, MULTICAST_PHS); +}; + +void(vector org) _TE_superspike = +{ + EFF_PointEffect(org, TE_SUPERSPIKE, MULTICAST_PHS); +}; + +void(vector org) _TE_teleport = +{ + EFF_PointEffect(org, TE_TELEPORT, MULTICAST_PHS); +}; + +void(vector org) _TE_lavasplash = +{ + EFF_PointEffect(org, TE_LAVASPLASH, MULTICAST_PVS); +}; + +void(vector org) _TE_tarexplosion = +{ + EFF_PointEffect(org, TE_TAREXPLOSION, MULTICAST_PHS); +}; + +void(entity ent, vector start, vector end) _TE_lightning1 = +{ + EFF_BeamEffect (ent, start, end, TE_LIGHTNING1, MULTICAST_PHS); +}; + +void(entity ent, vector start, vector end) _TE_lightning2 = +{ + EFF_BeamEffect (ent, start, end, TE_LIGHTNING2, MULTICAST_PHS); +}; + +void(entity ent, vector start, vector end) _TE_lightning3 = +{ + EFF_BeamEffect (ent, start, end, TE_LIGHTNING3, MULTICAST_PHS); +}; + +void(vector org) TE_lightningblood = +{ +#ifdef NETQUAKE + particle(org, '0 0 100', 225, 120); +#else + EFF_PointEffect(org, TE_LIGHTNINGBLOOD, MULTICAST_PVS); +#endif +}; + +// function pointers for TE calls +var void(vector org, float damage) SpawnBlood = _SpawnBlood; +var void(vector org) TE_explosion = _TE_explosion; +var void(vector org) TE_gunshot = _TE_gunshot; +var void(vector org) TE_spike = _TE_spike; +var void(vector org) TE_knightspike = _TE_knightspike; +var void(vector org) TE_wizspike = _TE_wizspike; +var void(vector org) TE_superspike = _TE_superspike; +var void(vector org) TE_teleport = _TE_teleport; +var void(vector org) TE_lavasplash = _TE_lavasplash; +var void(vector org) TE_tarexplosion = _TE_tarexplosion; +var void(entity ent, vector start, vector end) TE_lightning1 = _TE_lightning1; +var void(entity ent, vector start, vector end) TE_lightning2 = _TE_lightning2; +var void(entity ent, vector start, vector end) TE_lightning3 = _TE_lightning3; + +// set effects function, takes function pointers and assigns them based on detected builtins +void() EFF_SetEffects = +{ + if (eng_support & ENG_EFRED) + { + ef_pent = 128; + ef_red = 128; + } + + if (eng_support & ENG_EFBLUE) + { + ef_blue = 64; + ef_quad = 64; + } + + if (eng_support & ENG_TEBUILTINS) + { + // use TE_ builtins instead + TE_explosion = _te_explosion; + TE_gunshot = _te_gunshot; + TE_spike = _te_spike; + TE_knightspike = _te_knightspike; + TE_wizspike = _te_wizspike; + TE_superspike = _te_superspike; + TE_teleport = _te_teleport; + TE_lavasplash = _te_lavasplash; + TE_tarexplosion = _te_tarexplosion; + TE_lightning1 = _te_lightning1; + TE_lightning2 = _te_lightning2; + TE_lightning3 = _te_lightning3; + } + + if (eng_support & ENG_TEBLOOD) + SpawnBlood = _SpawnBlood_TEBlood; // use TE_Blood builtin instead +}; + +// view kicks +void(entity ent) VK_smallkick = +{ +#ifdef NETQUAKE + self.punchangle_x = -2; +#else + msg_entity = ent; + WriteByte (MSG_ONE, SVC_SMALLKICK); +#endif +} + +void(entity ent) VK_bigkick = +{ +#ifdef NETQUAKE + self.punchangle_x = -4; +#else + msg_entity = ent; + WriteByte (MSG_ONE, SVC_BIGKICK); +#endif +} +void(entity ent) VK_hugekick = +{ +#ifdef NETQUAKE + self.punchangle_x = -8; +#else + msg_entity = ent; + WriteByte (MSG_ONE, SVC_HUGEKICK); +#endif +} + +// muzzle flash +void() muzzleflash = +{ +#ifdef NETQUAKE + self.effects |= EF_MUZZLEFLASH; +#else + WriteByte (MSG_MULTICAST, SVC_MUZZLEFLASH); + WriteEntity (MSG_MULTICAST, self); + multicast (self.origin, MULTICAST_PVS); +#endif +}; + +// touch blood functions +void(float damage) spawn_touchblood = +{ + local vector vel; + + vel = normalize (self.velocity); + vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5)); + vel = vel + 2*trace_plane_normal; + vel = vel * 0.4; + SpawnBlood (self.origin + vel, damage); +}; +/* +============================================ +HUD weapon ammo counter. Counts ammo and displays +Number of bullets. + +============================================ +*/ +void() AmmoCounter = +{ +if (self.weapon == IT_SHOTGUN) +{ + stuffcmd (self, "cl_ar_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_needler_ammo 0\n"); + stuffcmd (self, "cl_rocket_ammo 0\n"); + stuffcmd (self, "cl_weaponhud 0\n"); + + if (self.ammo_shells == 12) + stuffcmd (self, "cl_pistol_ammo 12\n"); + if (self.ammo_shells == 11) + stuffcmd (self, "cl_pistol_ammo 11\n"); + if (self.ammo_shells == 10) + stuffcmd (self, "cl_pistol_ammo 10\n"); + if (self.ammo_shells == 9) + stuffcmd (self, "cl_pistol_ammo 9\n"); + if (self.ammo_shells == 8) + stuffcmd (self, "cl_pistol_ammo 8\n"); + if (self.ammo_shells == 7) + stuffcmd (self, "cl_pistol_ammo 7\n"); + if (self.ammo_shells == 6) + stuffcmd (self, "cl_pistol_ammo 6\n"); + if (self.ammo_shells == 5) + stuffcmd (self, "cl_pistol_ammo 5\n"); + if (self.ammo_shells == 4) + stuffcmd (self, "cl_pistol_ammo 4\n"); + if (self.ammo_shells == 3) + stuffcmd (self, "cl_pistol_ammo 3\n"); + if (self.ammo_shells == 2) + stuffcmd (self, "cl_pistol_ammo 2\n"); + if (self.ammo_shells == 1) + stuffcmd (self, "cl_pistol_ammo 1\n"); + if (self.ammo_shells == 0) + stuffcmd (self, "cl_pistol_ammo 0\n"); + } + if (self.weapon == IT_SUPER_SHOTGUN) + { + stuffcmd (self, "cl_ar_ammo 0\n"); + stuffcmd (self, "cl_pistol_ammo 0\n"); + stuffcmd (self, "cl_needler_ammo 0\n"); + stuffcmd (self, "cl_rocket_ammo 0\n"); + stuffcmd (self, "cl_weaponhud 0\n"); + + if (self.ammo_shells2 == 6) + stuffcmd (self, "cl_shotgun_ammo 6\n"); + if (self.ammo_shells2 == 5) + stuffcmd (self, "cl_shotgun_ammo 5\n"); + if (self.ammo_shells2 == 4) + stuffcmd (self, "cl_shotgun_ammo 4\n"); + if (self.ammo_shells2 == 3) + stuffcmd (self, "cl_shotgun_ammo 3\n"); + if (self.ammo_shells2 == 2) + stuffcmd (self, "cl_shotgun_ammo 2\n"); + if (self.ammo_shells2 == 1) + stuffcmd (self, "cl_shotgun_ammo 1\n"); + if (self.ammo_shells2 == 0) + stuffcmd (self, "cl_shotgun_ammo 0\n"); + } + if (self.weapon == IT_NAILGUN) + { + stuffcmd (self, "cl_pistol_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_needler_ammo 0\n"); + stuffcmd (self, "cl_rocket_ammo 0\n"); + stuffcmd (self, "cl_weaponhud 0\n"); + + if (self.ammo_nails == 32) + stuffcmd (self, "cl_ar_ammo 32\n"); + if (self.ammo_nails == 31) + stuffcmd (self, "cl_ar_ammo 31\n"); + if (self.ammo_nails == 30) + stuffcmd (self, "cl_ar_ammo 30\n"); + if (self.ammo_nails == 29) + stuffcmd (self, "cl_ar_ammo 29\n"); + if (self.ammo_nails == 28) + stuffcmd (self, "cl_ar_ammo 28\n"); + if (self.ammo_nails == 27) + stuffcmd (self, "cl_ar_ammo 27\n"); + if (self.ammo_nails == 26) + stuffcmd (self, "cl_ar_ammo 26\n"); + if (self.ammo_nails == 25) + stuffcmd (self, "cl_ar_ammo 25\n"); + if (self.ammo_nails == 24) + stuffcmd (self, "cl_ar_ammo 24\n"); + if (self.ammo_nails == 23) + stuffcmd (self, "cl_ar_ammo 23\n"); + if (self.ammo_nails == 22) + stuffcmd (self, "cl_ar_ammo 22\n"); + if (self.ammo_nails == 21) + stuffcmd (self, "cl_ar_ammo 21\n"); + if (self.ammo_nails == 20) + stuffcmd (self, "cl_ar_ammo 20\n"); + if (self.ammo_nails == 19) + stuffcmd (self, "cl_ar_ammo 19\n"); + if (self.ammo_nails == 18) + stuffcmd (self, "cl_ar_ammo 18\n"); + if (self.ammo_nails == 17) + stuffcmd (self, "cl_ar_ammo 17\n"); + if (self.ammo_nails == 16) + stuffcmd (self, "cl_ar_ammo 16\n"); + if (self.ammo_nails == 15) + stuffcmd (self, "cl_ar_ammo 15\n"); + if (self.ammo_nails == 14) + stuffcmd (self, "cl_ar_ammo 14\n"); + if (self.ammo_nails == 13) + stuffcmd (self, "cl_ar_ammo 13\n"); + if (self.ammo_nails == 12) + stuffcmd (self, "cl_ar_ammo 12\n"); + if (self.ammo_nails == 11) + stuffcmd (self, "cl_ar_ammo 11\n"); + if (self.ammo_nails == 10) + stuffcmd (self, "cl_ar_ammo 10\n"); + if (self.ammo_nails == 9) + stuffcmd (self, "cl_ar_ammo 9\n"); + if (self.ammo_nails == 8) + stuffcmd (self, "cl_ar_ammo 8\n"); + if (self.ammo_nails == 7) + stuffcmd (self, "cl_ar_ammo 7\n"); + if (self.ammo_nails == 6) + stuffcmd (self, "cl_ar_ammo 6\n"); + if (self.ammo_nails == 5) + stuffcmd (self, "cl_ar_ammo 5\n"); + if (self.ammo_nails == 4) + stuffcmd (self, "cl_ar_ammo 4\n"); + if (self.ammo_nails == 3) + stuffcmd (self, "cl_ar_ammo 3\n"); + if (self.ammo_nails == 2) + stuffcmd (self, "cl_ar_ammo 2\n"); + if (self.ammo_nails == 1) + stuffcmd (self, "cl_ar_ammo 1\n"); + if (self.ammo_nails == 0) + stuffcmd (self, "cl_ar_ammo 0\n"); + } + if (self.weapon == IT_ROCKET_LAUNCHER) + { + stuffcmd (self, "cl_ar_ammo 0\n"); //Turns off other ammo counters + stuffcmd (self, "cl_pistol_ammo 0\n"); + stuffcmd (self, "cl_needler_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_weaponhud 0\n"); //Keeps Needler Weapon Icon off + + if (self.ammo_rockets == 2) + stuffcmd (self, "cl_rocket_ammo 2\n"); + if (self.ammo_rockets == 1) + stuffcmd (self, "cl_rocket_ammo 1\n"); + if (self.ammo_rockets == 0) + stuffcmd (self, "cl_rocket_ammo 0\n"); + } + if (self.weapon == IT_LIGHTNING) + { + stuffcmd (self, "cl_ar_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_needler_ammo 0\n"); + stuffcmd (self, "cl_rocket_ammo 0\n"); + stuffcmd (self, "cl_pistol_ammo 0\n"); + } + if (self.weapon == IT_AXE) + { + stuffcmd (self, "cl_ar_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_needler_ammo 0\n"); + stuffcmd (self, "cl_rocket_ammo 0\n"); + stuffcmd (self, "cl_pistol_ammo 0\n"); + } + if (self.weapon == WEAPON_NEEDLER) + { + stuffcmd (self, "cl_weaponhud 1\n"); //Turns needler Icon on. + stuffcmd (self, "cl_pistol_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_ar_ammo 0\n"); + stuffcmd (self, "cl_rocket_ammo 0\n"); + + if (self.ammo_needler == 20) + stuffcmd (self, "cl_needler_ammo 20\n"); + if (self.ammo_needler == 19) + stuffcmd (self, "cl_needler_ammo 19\n"); + if (self.ammo_needler == 18) + stuffcmd (self, "cl_needler_ammo 18\n"); + if (self.ammo_needler == 17) + stuffcmd (self, "cl_needler_ammo 17\n"); + if (self.ammo_needler == 16) + stuffcmd (self, "cl_needler_ammo 16\n"); + if (self.ammo_needler == 15) + stuffcmd (self, "cl_needler_ammo 15\n"); + if (self.ammo_needler == 14) + stuffcmd (self, "cl_needler_ammo 14\n"); + if (self.ammo_needler == 13) + stuffcmd (self, "cl_needler_ammo 13\n"); + if (self.ammo_needler == 12) + stuffcmd (self, "cl_needler_ammo 12\n"); + if (self.ammo_needler == 11) + stuffcmd (self, "cl_needler_ammo 11\n"); + if (self.ammo_needler == 10) + stuffcmd (self, "cl_needler_ammo 10\n"); + if (self.ammo_needler == 9) + stuffcmd (self, "cl_needler_ammo 9\n"); + if (self.ammo_needler == 8) + stuffcmd (self, "cl_needler_ammo 8\n"); + if (self.ammo_needler == 7) + stuffcmd (self, "cl_needler_ammo 7\n"); + if (self.ammo_needler == 6) + stuffcmd (self, "cl_needler_ammo 6\n"); + if (self.ammo_needler == 5) + stuffcmd (self, "cl_needler_ammo 5\n"); + if (self.ammo_needler == 4) + stuffcmd (self, "cl_needler_ammo 4\n"); + if (self.ammo_needler == 3) + stuffcmd (self, "cl_needler_ammo 3\n"); + if (self.ammo_needler == 2) + stuffcmd (self, "cl_needler_ammo 2\n"); + if (self.ammo_needler == 1) + stuffcmd (self, "cl_needler_ammo 1\n"); + if (self.ammo_needler == 0) + stuffcmd (self, "cl_needler_ammo 0\n"); + } + if (self.weapon == WEAPON_PRIFLE) + { + stuffcmd (self, "cl_ar_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_needler_ammo 0\n"); + stuffcmd (self, "cl_rocket_ammo 0\n"); + stuffcmd (self, "cl_pistol_ammo 0\n"); + } +}; +/* +========================================== + +Gernade counter for the HUD. Displays a players Number +Of nades. + +========================================== +*/ +void() NadeCounter = +{ +if (self.selnade == GRENADE_REGULAR) + { + stuffcmd (self, "cl_plasmanade 2\n"); + if (self.nade_lives == 4) + stuffcmd (self, "cl_nadenum 5\n"); + if (self.nade_lives == 3) + stuffcmd (self, "cl_nadenum 4\n"); + if (self.nade_lives == 2) + stuffcmd (self, "cl_nadenum 3\n"); + if (self.nade_lives == 1) + stuffcmd (self, "cl_nadenum 2\n"); + if (self.nade_lives == 0) + stuffcmd (self, "cl_nadenum 1\n"); + } +else if (self.selnade == GRENADE_STICKY) + { + stuffcmd (self, "cl_plasmanade 1\n"); + if (self.plasma_lives == 4) + stuffcmd (self, "cl_nadenum 5\n"); + if (self.plasma_lives == 3) + stuffcmd (self, "cl_nadenum 4\n"); + if (self.plasma_lives == 2) + stuffcmd (self, "cl_nadenum 3\n"); + if (self.plasma_lives == 1) + stuffcmd (self, "cl_nadenum 2\n"); + if (self.plasma_lives == 0) + stuffcmd (self, "cl_nadenum 1\n"); + } + + +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/engine.qc b/r17/Revamped src/Revamped QC/engine.qc new file mode 100755 index 00000000..d7e53052 Binary files /dev/null and b/r17/Revamped src/Revamped QC/engine.qc differ diff --git a/r17/Revamped src/Revamped QC/fight.qc b/r17/Revamped src/Revamped QC/fight.qc new file mode 100755 index 00000000..84717540 Binary files /dev/null and b/r17/Revamped src/Revamped QC/fight.qc differ diff --git a/r17/Revamped src/Revamped QC/frikbot/bot.qc b/r17/Revamped src/Revamped QC/frikbot/bot.qc new file mode 100755 index 00000000..41dcaf0b --- /dev/null +++ b/r17/Revamped src/Revamped QC/frikbot/bot.qc @@ -0,0 +1,1281 @@ + +/* +====================================== +FrikBot X (Version 0.10.2) +====================================== + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +====================================== +These installation instructions only apply to Normal Quake (as does this +entire file). For QuakeWorld, please refer to bot_qw.qc + +-------------------------------------- +To install on a new mod, do all this: +-------------------------------------- +Place all included bot*.qc files in the subdirectory "frikbot" +in your source folder, then... + +* Add the following lines to progs.src right after the defs.qc line +frikbot/bot.qc +frikbot/bot_way.qc +frikbot/bot_fight.qc +frikbot/bot_ai.qc +frikbot/bot_misc.qc +frikbot/bot_phys.qc +frikbot/bot_move.qc +frikbot/bot_ed.qc + +-------------------------------------- +* Comment out the following functions in defs.qc +sound, stuffcmd, sprint, aim, centerprint, setspawnparms +WriteByte, WriteChar, WriteShort, WriteLong, WriteCoord +WriteAngle, WriteString, WriteEntity +-------------------------------------- +* Add this to worldspawn() in world.qc, right at the very top, before InitBodyQue(); +BotInit(); // FrikBot +-------------------------------------- +* add this line to StartFrame() in world.qc, at the very top +BotFrame(); // FrikBot +-------------------------------------- +* Add these two lines to PlayerPreThink in client.qc at the very top +if (BotPreFrame()) // FrikBot + return; +-------------------------------------- +* Add this line to PlayerPostThink in client.qc at the very top +if (BotPostFrame()) // FrikBot + return; +-------------------------------------- +* Add the following line to the very top of Client Connect in client.qc +ClientInRankings(); // FrikBot +-------------------------------------- +* Add these lines to the very top of ClientDisconnect in client.qc +ClientDisconnected(); // FrikBot +-------------------------------------- + +To install the waypoints: + +add + +waypoints/map_dm1.qc +waypoints/map_dm2.qc +waypoints/map_dm3.qc +waypoints/map_dm4.qc +waypoints/map_dm5.qc +waypoints/map_dm6.qc + +To progs.src, immediately after defs.qc + +To remove these waypoints: + +Delete the code in bot_map_load, located below. +*/ + + +void() bot_map_load = +{ +/* + // place your qc loaded waypoints here + + if (mapname == "dm1") + map_dm1(); + else if (mapname == "dm2") + map_dm2(); + else if (mapname == "dm3") + map_dm3(); + else if (mapname == "dm4") + map_dm4(); + else if (mapname == "dm5") + map_dm5(); + else if (mapname == "dm6") + map_dm6(); +*/ +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Variables and shtuff + +bot.qc has become pretty much a header file +for all variable in the bot... + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +// ----- entity fields --- +.float wallhug, keys, oldkeys, ishuman; +.float b_frags, b_clientno, b_shirt, b_pants; +.float /*priority, */ai_time, b_sound, missile_speed; +.float portal_time, b_skill, switch_wallhug; +.float b_aiflags, b_num, b_chattime; +.float b_menu, b_menu_time, b_menu_value; +.float route_failed, dyn_flags, dyn_time; +.float dyn_plat; +.entity temp_way, last_way, phys_obj; +.entity target1, target2, target3, target4; +.entity _next, _last; +.entity current_way; +.vector b_angle/*, b_dest*/, mouse_emu, obs_dir; +.vector movevect, b_dir; +.vector dyn_dest; + +// --------defines----- +float SVC_UPDATENAME = 13; +float SVC_UPDATEFRAGS = 14; +float SVC_UPDATECOLORS = 17; + +// used for the physics & movement AI +float KEY_MOVEUP = 1; +float KEY_MOVEDOWN = 2; +float KEY_MOVELEFT = 4; +float KEY_MOVERIGHT = 8; +float KEY_MOVEFORWARD = 16; +float KEY_MOVEBACK = 32; +float KEY_LOOKUP = 64; +float KEY_LOOKDOWN = 128; +float KEY_LOOKLEFT = 256; +float KEY_LOOKRIGHT = 512; + +// these are aiflags for waypoints +// some overlap to the bot +float AI_TELELINK_1 = 1; // link type +float AI_TELELINK_2 = 2; // link type +float AI_TELELINK_3 = 4; // link type +float AI_TELELINK_4 = 8; // link type +float AI_DOORFLAG = 16; // read ahead +float AI_PRECISION = 32; // read ahead + point +float AI_SURFACE = 64; // point +float AI_BLIND = 128; // read ahead + point +float AI_JUMP = 256; // point + ignore +float AI_DIRECTIONAL = 512; // read ahead + ignore +float AI_PLAT_BOTTOM = 1024; // read ahead +float AI_RIDE_TRAIN = 2048; // read ahead +float AI_SUPER_JUMP = 4096; // point + ignore + route test +float AI_SNIPER = 8192; // point type +float AI_AMBUSH = 16384; // point type +float AI_DOOR_NO_OPEN = 32768; // read ahead +float AI_DIFFICULT = 65536; // route test +float AI_TRACE_TEST = 131072; // route test + +// these are flags for bots/players (dynamic/editor flags) +float AI_OBSTRUCTED = 1; +float AI_HOLD_SELECT = 2; +float AI_ROUTE_FAILED = 2; +float AI_WAIT = 4; +float AI_DANGER = 8; + + +// addition masks +float AI_POINT_TYPES = 29152; +float AI_READAHEAD_TYPES = 36528; +float AI_IGNORE_TYPES = 4864; + +float WM_UNINIT = 0; +float WM_DYNAMIC = 1; +float WM_LOADING = 2; +float WM_LOADED = 3; +float WM_EDITOR = 4; +float WM_EDITOR_DYNAMIC = 5; +float WM_EDITOR_DYNLINK = 6; + + +float OPT_SAVEBOTS = 1; +float OPT_NOCHAT = 2; + +// -------globals----- +float active_clients; +float max_clients, real_frametime; +float bot_count, b_options; +float waypoint_mode, dump_mode; +float waypoints, direct_route; +float sv_friction, sv_gravity; +float sv_accelerate, sv_maxspeed, sv_stopspeed; +entity fixer; +entity route_table; +entity b_temp1, b_temp2, b_temp3; +entity player_head, phys_head, way_head; +float busy_waypoints; +float saved_bots, saved_skills1, saved_skills2, current_bots; + +// -------ProtoTypes------ +// external +void() ClientConnect; +void() ClientDisconnect; +void() SetNewParms; + +// rankings +float(float clientno) ClientBitFlag; +float() ClientNextAvailable; +void(float whichteam, float whatbot, float whatskill) BotConnect; +void(entity bot) BotDisconnect; +void(float clientno) BotInvalidClientNo; +void(entity who) UpdateClient; + +// waypointing +void() DynamicWaypoint; +entity(vector org) make_waypoint; +void() ClearAllWays; +void() FixWaypoints; +float() begin_route; +void(entity this, float direct) bot_get_path; +void() WaypointThink; +entity(entity start) FindWayPoint; + +// physics & movement +float(entity e) bot_can_rj; +void() bot_jump; +void() frik_bot_roam; +float(vector weird) frik_walkmove; +void() frik_movetogoal; +void() frik_obstacles; +float(float flag) frik_recognize_plat; +float(vector sdir) frik_KeysForDir; +void(vector whichway, float danger) frik_obstructed; +void() SV_Physics_Client; +void() SV_ClientThink; +void() CL_KeyMove; + +// ai & misc +string() PickARandomName; +float(entity targ) fov; +float(float y1, float y2) angcomp; +float(entity targ1, entity targ2) wisible; +float(entity targ) sisible; +float(entity targ) fisible; +vector(entity ent) realorigin; +void(entity ent) target_drop; +void(entity ent) target_add; +void() KickABot; +void() BotImpulses; +void(entity targ, float success) bot_lost; +string(float r) BotName; +float(float v) frik_anglemod; +void() bot_chat; +void(float tpic) bot_start_topic; + + +// editor stuffs + +void() bot_way_edit; +void() bot_menu_display; + + +// ----------Commands--------- +void(entity e, float chan, string samp, float vol, float atten) frik_sound = #8; +void(entity client, string s) frik_stuffcmd = #21; +void(entity client, string s) frik_sprint = #24; +vector(entity e, float sped) frik_aim = #44; +void(entity client, string s) frik_centerprint = #73; +void(entity e) frik_setspawnparms = #78; +void(float to, float f) frik_WriteByte = #52; +void(float to, float f) frik_WriteChar = #53; +void(float to, float f) frik_WriteShort = #54; +void(float to, float f) frik_WriteLong = #55; +void(float to, float f) frik_WriteCoord = #56; +void(float to, float f) frik_WriteAngle = #57; +void(float to, string s) frik_WriteString = #58; +void(float to, entity s) frik_WriteEntity = #59; + +void(entity client, string s1, string s2, string s3, string s4, string s5, string s6, string s7) +frik_big_centerprint = #73; + +//---------------------------------------------------------------------------- + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Function redclarations. These allow function +designed to work for clients (sprint, so forth) +to mainly not complain when working with a bot + +Although these shouldn't be needed anymore, +as the bots truly are clients now, if you don't +stop the SZ_ buffer from filling up by disabling +direct messages to the bots, it crashes quake :-( + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(entity client, string s) stuffcmd = +{ + if (client.ishuman == 1) + frik_stuffcmd(client, s); + b_temp1 = player_head; + + while(b_temp1) + { + if (b_temp1.classname == "botcam") + { + if ((b_temp1.enemy == client) && b_temp1.ishuman) + frik_stuffcmd(b_temp1, s); + } + b_temp1 = b_temp1._next; + } +}; + +void(entity e) setspawnparms = +{ + if (e.ishuman == 1) + frik_setspawnparms(e); + else + { + b_temp1 = player_head; + while(b_temp1) + { + if (b_temp1.ishuman) + { + frik_setspawnparms(b_temp1); + return; + } + b_temp1 = b_temp1._next; + } + SetNewParms(); + } +}; +void(entity client, string s) sprint = +{ + if (client.ishuman == 1) + frik_sprint(client, s); + b_temp1 = player_head; + + while(b_temp1) + { + if (b_temp1.classname == "botcam") + { + if ((b_temp1.enemy == client) && b_temp1.ishuman) + frik_sprint(b_temp1, s); + } + b_temp1 = b_temp1._next; + } + +}; +void( string s ) bprint = +{ + _bprint( s ); + +}; + +void(entity client, string s) centerprint = +{ + if (client.ishuman == 1) + frik_centerprint(client, s); + b_temp1 = player_head; + + while(b_temp1) + { + if (b_temp1.classname == "botcam") + { + if ((b_temp1.enemy == client) && b_temp1.ishuman) + frik_centerprint(b_temp1, s); + } + b_temp1 = b_temp1._next; + } +}; + +vector(entity e, float sped) aim = +{ + e.missile_speed = sped; + return frik_aim(e, sped); +}; + +void(entity e, float chan, string samp, float vol, float atten) sound = +{ + + frik_sound(e, chan, samp, vol, atten); + if (samp == "items/inv3.wav") + return; + else if (e.classname == "player") + e.b_sound = time + 1; + else if (other.classname == "player") + other.b_sound = time + 1; + +}; +void(float to, float f) WriteByte = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteByte(to, f); +}; +void(float to, float f) WriteChar = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteChar(to, f); +}; +void(float to, float f) WriteShort = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteShort(to, f); +}; +void(float to, float f) WriteLong = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteLong(to, f); +}; +void(float to, float f) WriteCoord = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteCoord(to, f); +}; +void(float to, float f) WriteAngle = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteAngle(to, f); +}; +void(float to, string s) WriteString = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteString(to, s); +}; +void(float to, entity s) WriteEntity = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteEntity(to, s); +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Cam, see what the bot sees (or any other player) + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float() botcam = +{ + if (self.classname != "botcam") + return FALSE; + setorigin(self, self.enemy.origin); + self.items = self.enemy.items; + self.weapon = self.enemy.weapon; + self.weaponmodel = self.enemy.weaponmodel; + self.currentammo = self.enemy.currentammo; + self.weaponframe = self.enemy.weaponframe; + self.ammo_shells = self.enemy.ammo_shells; + self.ammo_nails = self.enemy.ammo_nails; + self.ammo_rockets= self.enemy.ammo_rockets; + self.ammo_cells = self.enemy.ammo_cells; + self.view_ofs = self.enemy.view_ofs; + self.health = self.enemy.health; + self.armorvalue = self.enemy.armorvalue; + self.dmg_take = self.enemy.dmg_take; + self.dmg_save = self.enemy.dmg_save; + self.dmg_inflictor = self.enemy.dmg_inflictor; + self.punchangle = self.enemy.punchangle; + self.deadflag = self.enemy.deadflag; + msg_entity = self; + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE, self.enemy); + WriteByte (MSG_ONE, 10); + WriteAngle (MSG_ONE,self.enemy.v_angle_x); + WriteAngle (MSG_ONE,self.enemy.v_angle_y); + WriteAngle (MSG_ONE,self.enemy.v_angle_z); + self.modelindex = 0; + + self.impulse = 0; + return TRUE; + +}; + +void() botcam_u = +{ + + // sloppy cycling code + if (self.classname != "botcam") + { + self.enemy = player_head; + } + else + { + do + self.enemy = self.enemy._next; + while (self.enemy.classname == "botcam"); + } + if (self.enemy == self) + { + do + self.enemy = self.enemy._next; + while (self.enemy.classname == "botcam"); + } + + self.classname = "botcam"; + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_NONE; + self.takedamage = DAMAGE_NO; + + + if (!self.enemy) + { + sprint(self, "No one left to track!\n"); + msg_entity = self; + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE, self); + PutClientInServer(); + return; + } + if (!self.enemy.ishuman) + { + self.enemy.dmg_take = 0; + self.enemy.dmg_save = 0; + } + sprint(self, "Now tracking "); + sprint(self, self.enemy.netname); + sprint(self, "\n"); +}; + + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Stuff mentioned up top +it just links the bot into the mod + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClientFixRankings = +{ + local float cno; + + if (self.switch_wallhug > time) + return; + self.switch_wallhug = 0; + + b_temp2 = nextent(world); + cno = 0; + + while (cno < max_clients) + { + if ((!b_temp2.ishuman) && (active_clients & ClientBitFlag(cno))) + UpdateClient(b_temp2); + cno = cno + 1; + b_temp2 = nextent(b_temp2); + } +}; + +void() ClientInRankings = +{ + local float cno; + + cno = self.colormap - 1; + BotInvalidClientNo (cno); + + if (player_head) + player_head._last = self; + + self._next = player_head; + self._last = world; + player_head = self; + + if (!self.phys_obj) + { + b_temp2 = phys_head; + while (b_temp2 != world && b_temp2.owner != self) + b_temp2 = b_temp2._next; + self.phys_obj = b_temp2; + } + + if (self.ishuman == 2) + { + self.ishuman = FALSE; + return; + } + active_clients = active_clients | ClientBitFlag(cno); + + self.b_clientno = cno; + self.ishuman = TRUE; + self.switch_wallhug = time + 1; +}; + + +void() ClientDisconnected = +{ + if (player_head == self) + player_head = self._next; + if (self._next) + self._next._last = self._last; + if (self._last) + self._last._next = self._next; + + active_clients = active_clients - active_clients & ClientBitFlag(self.b_clientno); +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotPreFrame & BotPostFrame, used to make the +bot easier to install + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float () BotPreFrame = +{ + if (self.b_clientno == -1) + return TRUE; + if (self.ishuman) + { + if (self.switch_wallhug) + ClientFixRankings(); + if (self.classname == "botcam") + return TRUE; + + } + if (self.b_frags != self.frags) + { + + if (self.b_frags > self.frags) + { + if (pointcontents(self.origin) == CONTENT_LAVA) + bot_start_topic(10); + else + bot_start_topic(9); + } + else + bot_start_topic(2); + self.b_frags = self.frags; + } + DynamicWaypoint(); + return FALSE; +}; +float () BotPostFrame = +{ + if (self.b_clientno == -1) + return TRUE; + if (self.ishuman) + { + + if (waypoint_mode > WM_LOADED) + bot_menu_display(); + + BotImpulses(); + + if (botcam()) + return TRUE; + } + return FALSE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Chat code + +The rest of this code is in bot_misc.qc + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(string h) BotSay = // simulate talking by composing a 'chat' message +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, self.netname); + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 2); + WriteString(MSG_ALL, h); +}; +void() BotSayInit = +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, self.netname); +}; +void(string h) BotSay2 = +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 2); + WriteString(MSG_ALL, h); +}; +void(string h) BotSayTeam = +{ + local entity t; + if (!teamplay) + return; + t = player_head; + while(t) + { + if (t.team == self.team) + { + msg_entity = t; + WriteByte(MSG_ONE, 8); + WriteByte(MSG_ONE, 1); + WriteByte(MSG_ONE, 40); + WriteString(MSG_ONE, self.netname); + WriteByte(MSG_ONE, 8); + WriteByte(MSG_ONE, 2); + WriteByte(MSG_ONE, 41); + WriteString(MSG_ONE, h); + } + t = t._next; + } +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotInit + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void() BotInit = +{ + local entity ent, fisent; + local float numents; + + // spawn entities for the physics + ent = nextent(world); + max_clients = 0; + + while(ent != world) + { + max_clients = max_clients + 1; + ent = nextent(ent); + } + if (max_clients > 16) + max_clients = 16; + + ent = nextent(world); + fisent = world; + while (numents < max_clients) + { + + phys_head = spawn(); + if (fisent) + fisent._next = phys_head; + phys_head._last = fisent; + fisent = phys_head; + ent.phys_obj = phys_head; + phys_head.classname = "phys_obj"; + phys_head.owner = ent; + numents = numents + 1; + ent = nextent(ent); + } + precache_model("progs/s_light.spr"); + precache_model("progs/s_bubble.spr"); + + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Rankings 'utilities'. Written by Alan Kivlin, +this code just fools clients by sending precisely +the same network messages as when a real player +signs on to the server. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void(entity who) UpdateClient = +{ + WriteByte (MSG_ALL, SVC_UPDATENAME); + WriteByte (MSG_ALL, who.b_clientno); + WriteString (MSG_ALL, who.netname); + WriteByte (MSG_ALL, SVC_UPDATECOLORS); + WriteByte (MSG_ALL, who.b_clientno); + WriteByte (MSG_ALL, who.b_shirt * 16 + who.b_pants); + WriteByte (MSG_ALL, SVC_UPDATEFRAGS); + WriteByte (MSG_ALL, who.b_clientno); + WriteShort (MSG_ALL, who.frags); +}; + +float(float clientno) ClientBitFlag = +{ + // bigger, but faster + if (clientno == 0) + return 1; + else if (clientno == 1) + return 2; + else if (clientno == 2) + return 4; + else if (clientno == 3) + return 8; + else if (clientno == 4) + return 16; + else if (clientno == 5) + return 32; + else if (clientno == 6) + return 64; + else if (clientno == 7) + return 128; + else if (clientno == 8) + return 256; + else if (clientno == 9) + return 512; + else if (clientno == 10) + return 1024; + else if (clientno == 11) + return 2048; + else if (clientno == 12) + return 4096; + else if (clientno == 13) + return 8192; + else if (clientno == 14) + return 16384; + else if (clientno == 15) + return 32768; + return 0; +}; + +float() ClientNextAvailable = +{ + local float clientno; + + clientno = max_clients; + while(clientno > 0) + { + clientno = clientno - 1; + + if(!(active_clients & ClientBitFlag(clientno))) + return clientno; + } + + return -1; +}; + + +void(entity e1, entity e2, float flag) DeveloperLightning = +{ + // used to show waypoint links for debugging + WriteByte (MSG_BROADCAST, 23); + if (flag) + WriteByte (MSG_BROADCAST, 6); + else + WriteByte (MSG_BROADCAST, 13); + WriteEntity (MSG_BROADCAST, e2); + WriteCoord (MSG_BROADCAST, e1.origin_x); + WriteCoord (MSG_BROADCAST, e1.origin_y); + WriteCoord (MSG_BROADCAST, e1.origin_z); + WriteCoord (MSG_BROADCAST, e2.origin_x); + WriteCoord (MSG_BROADCAST, e2.origin_y); + WriteCoord (MSG_BROADCAST, e2.origin_z); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Find Another Color + +Team finding code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float(float tcolor) FindAnotherColor = +{ + local float bestbet, scolor, pcount, bestp; + bestbet = -1; + bestp = 16; + while(scolor < 14) + { + if (scolor != tcolor) + { + b_temp2 = player_head; + pcount = 0; + while(b_temp2 != world) + { + if (b_temp2.team == scolor + 1) + pcount = pcount + 1; + b_temp2 = b_temp2._next; + } + if ((pcount < bestp) && pcount) + { + bestbet = scolor; + bestp = pcount; + } + } + scolor = scolor + 1; + } + if (bestbet < 0) + { + bestbet = tcolor; + while (bestbet == tcolor) + { + bestbet = floor(random() * 13); + } + } + return bestbet; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotConnect and related functions. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +entity(float num) GetClientEntity = +{ + local entity upsy; + upsy = world; + num = num + 1; + while (num > 0) + { + num = num - 1; + upsy = nextent(upsy); + } + return upsy; +}; + +void(float whichteam, float whatbot, float whatskill) BotConnect = +{ + local float f; + local string h; + local entity uself; + + f = ClientNextAvailable(); + uself = self; + if(f == -1) + { + bprint("Unable to connect a bot, server is full.\n"); + return; + } + + // chat thing + + bot_count = bot_count + 1; + self = GetClientEntity(f); + if (!saved_bots) + bot_start_topic(1); + self.b_clientno = f; + self.colormap = f + 1; + if (whatbot) + self.netname = BotName(whatbot); + else + self.netname = PickARandomName(); + + + // players can set skill all weird, so leave these checks in + whatskill = rint(whatskill); + if (whatskill > 3) + whatskill = 3; + else if (whatskill < 0) + whatskill = 0; + self.b_skill = whatskill; + + if (teamplay && !coop) + { + if (whichteam) + self.b_pants = FindAnotherColor(uself.team - 1); + else + self.b_pants = uself.team - 1; + self.b_shirt = self.b_pants; + } + + self.team = self.b_pants + 1; + UpdateClient(self); + SetNewParms(); + self.ishuman = 2; + ClientConnect(); + PutClientInServer(); + + active_clients = active_clients | ClientBitFlag(f); + + // this is risky... could corrupt .way files if done wrong + // If you're not the gambling type, comment this out + + f = ClientBitFlag(self.b_num - 1); + current_bots = current_bots | f; + + if (self.b_num <= 8) + saved_skills1 = (saved_skills1 & (65536 - (3 * f)) | (self.b_skill * f)); + else + { + f = ClientBitFlag(self.b_num - 9); + saved_skills2 = (saved_skills2 & (65536 - (3 * f)) | (self.b_skill * f)); + } + + h = ftos(current_bots); + cvar_set("scratch1", h); + h = ftos(saved_skills1); + cvar_set("scratch2", h); + h = ftos(saved_skills2); + cvar_set("scratch3", h); + self = uself; + +}; + +void(entity bot) BotDisconnect = +{ + local string h; + local entity uself; + uself = self; + self = bot; + + bot_count = bot_count - 1; + current_bots = current_bots - (current_bots & ClientBitFlag(self.b_num - 1)); + h = ftos(current_bots); + cvar_set("scratch1", h); + + + ClientDisconnect(); + + if (self.b_clientno != -1) + { + // the bot's client number is not in use by a real player so we + // must remove it's entry in the rankings + // Quake engine sets all fields to 0, can only do the most important here + self.b_frags = self.frags = 0; + self.netname = ""; + self.classname = ""; + self.health = 0; + self.items = 0; + self.armorvalue = 0; + self.weaponmodel = ""; + self.b_pants = 0; + self.b_shirt = 0; + self.ammo_shells = self.ammo_nails = self.ammo_rockets = self.ammo_cells = 0; + UpdateClient(self); + active_clients = active_clients - (active_clients & ClientBitFlag(self.b_clientno)); + self.b_clientno = -1; + } + self = uself; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotInvalidClientNo +kicks a bot if a player connects and takes the bot's space + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(float clientno) BotInvalidClientNo = +{ + local entity bot; + + bot = GetClientEntity(clientno); + if(bot.b_clientno > 0) + { + if (active_clients & ClientBitFlag(self.b_clientno)) + { + bot.b_clientno = -1; + BotDisconnect(bot); + active_clients = active_clients | ClientBitFlag(self.b_clientno); + BotConnect(0, bot.b_num, bot.b_skill); + return; + } + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Loading from file + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void() LoadWaypoint = +{ + local vector org; + local entity tep; + local float r; + org_x = cvar("saved1"); + org_y = cvar("saved2"); + org_z = cvar("saved3"); + + tep = make_waypoint(org); + + r = cvar("saved4"); + + tep.b_aiflags = floor(r / 4); + tep.b_pants = cvar("scratch1"); + tep.b_skill = cvar("scratch2"); + tep.b_shirt = cvar("scratch3"); + tep.b_frags = cvar("scratch4"); +}; + +void() bot_return = +{ + if (time > 2) + { + if ((waypoint_mode == WM_DYNAMIC) || (waypoint_mode == WM_LOADED)) + { + // minor precaution + + if (saved_bots & 1) BotConnect(0, 1, saved_skills1 & 3); + if (saved_bots & 2) BotConnect(0, 2, (saved_skills1 & 12) / 4); + if (saved_bots & 4) BotConnect(0, 3, (saved_skills1 & 48) / 16); + if (saved_bots & 8) BotConnect(0, 4, (saved_skills1 & 192) / 64); + if (saved_bots & 16) BotConnect(0, 5, (saved_skills1 & 768) / 256); + if (saved_bots & 32) BotConnect(0, 6, (saved_skills1 & 3072) / 1024); + if (saved_bots & 64) BotConnect(0, 7, (saved_skills1 & 12288) / 4096); + if (saved_bots & 128) BotConnect(0, 8, (saved_skills1 & 49152) / 16384); + if (saved_bots & 256) BotConnect(0, 9, saved_skills2 & 3); + if (saved_bots & 512) BotConnect(0, 10, (saved_skills2 & 12) / 4); + if (saved_bots & 1024) BotConnect(0, 11, (saved_skills2& 48) / 16); + if (saved_bots & 2048) BotConnect(0, 12, (saved_skills2 & 192) / 64); + if (saved_bots & 4096) BotConnect(0, 13, (saved_skills2 & 768) / 256); + if (saved_bots & 8192) BotConnect(0, 14, (saved_skills2 & 3072) / 1024); + if (saved_bots & 16384) BotConnect(0, 15, (saved_skills2 & 12288) / 4096); + if (saved_bots & 32768) BotConnect(0, 16, (saved_skills2 & 49152) / 16384); + saved_bots = 0; + } + } +}; + + +void() WaypointWatch = +{ + // Waypoint Baywatch + local float bigboobs; + local string h; + if (framecount < 4) + return; + if (max_clients < 2) + return; + if (waypoint_mode != WM_UNINIT) + { + bigboobs = cvar("saved4"); + if (bigboobs != 0) + { + if ((bigboobs & 3) == 1) + ClearAllWays(); + else if ((bigboobs & 3) == 3) + { + FixWaypoints(); + h = ftos(b_options); + cvar_set("saved1", h); + cvar_set("saved4", "0"); + cvar_set("scratch1", "0"); + waypoint_mode = WM_LOADED; + return; + } + LoadWaypoint(); + waypoint_mode = WM_LOADING; + cvar_set("saved4", "0"); + } + } + else + { + // the bots return! + b_options = cvar("saved1"); + if (coop || (b_options & OPT_SAVEBOTS)) + { + saved_bots = cvar("scratch1"); + saved_skills1 = cvar("scratch2"); + saved_skills2 = cvar("scratch3"); + } + cvar_set ("saved4", "0"); + if (max_clients > 1) + { + localcmd("exec maps/"); + localcmd(mapname); + localcmd(".way\n"); + waypoint_mode = WM_DYNAMIC; + bot_map_load(); + } + else + waypoint_mode = WM_LOADED; + } +}; +void() BotFrame = +{ + local float num; + + // for the sake of speed + sv_maxspeed = cvar("sv_maxspeed"); + sv_gravity = cvar("sv_gravity"); + sv_friction = cvar("sv_friction"); + sv_accelerate = cvar("sv_accelerate"); + sv_stopspeed = cvar("sv_stopspeed"); + real_frametime = frametime; // in NQ this is alright + + self = nextent(world); + num = 0; + while (num < max_clients) + { + if (self.ishuman == FALSE) + { + if (active_clients & ClientBitFlag(num)) + { + frik_obstacles(); + CL_KeyMove(); + SV_ClientThink(); + SV_Physics_Client(); + } + } + self = nextent(self); + num = num + 1; + } + WaypointWatch(); + + if (saved_bots) + bot_return(); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Impulses. Allows the player to perform bot +related functions. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() BotImpulses = +{ + local float f; + + if (self.impulse == 100) + { + f = cvar("skill"); + BotConnect(0, 0, f); + } + else if (self.impulse == 101) + { + f = cvar("skill"); + BotConnect(1, 0, f); + } + else if (self.impulse == 102) + KickABot(); + else if (self.impulse == 103) + botcam_u(); + else if (self.impulse == 104) + bot_way_edit(); + else + return; + + self.impulse = 0; +}; + + + \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/frikbot/bot_ai.qc b/r17/Revamped src/Revamped QC/frikbot/bot_ai.qc new file mode 100755 index 00000000..60fe6730 --- /dev/null +++ b/r17/Revamped src/Revamped QC/frikbot/bot_ai.qc @@ -0,0 +1,1017 @@ +/*********************************************** +* * +* FrikBot General AI * +* "The I'd rather be playing Quake AI" * +* * +***********************************************/ + +/* + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +target_onstack + +checks to see if an entity is on the bot's stack + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float(entity scot) target_onstack = +{ + if (scot == world) + return FALSE; + else if (self.target1 == scot) + return 1; + else if (self.target2 == scot) + return 2; + else if (self.target3 == scot) + return 3; + else if (self.target4 == scot) + return 4; + else + return FALSE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +target_add + +adds a new entity to the stack, since it's a +LIFO stack, this will be the bot's new target1 + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity ent) target_add = +{ + if (ent == world) + return; + if (target_onstack(ent)) + return; + self.target4 = self.target3; + self.target3 = self.target2; + self.target2 = self.target1; + self.target1 = ent; + self.search_time = time + 5; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +target_drop + +Removes an entity from the bot's target stack. +The stack will empty everything up to the object +So if you have target2 item_health, target1 +waypoint, and you drop the health, the waypoint +is gone too. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity ent) target_drop = +{ + local float tg; + + tg = target_onstack(ent); + if (tg == 1) + { + self.target1 = self.target2; + self.target2 = self.target3; + self.target3 = self.target4; + self.target4 = world; + } + else if (tg == 2) + { + self.target1 = self.target3; + self.target2 = self.target4; + self.target3 = self.target4 = world; + } + else if (tg == 3) + { + self.target1 = self.target4; + self.target2 = self.target3 = self.target4 = world; + } + else if (tg == 4) + self.target1 = self.target2 = self.target3 = self.target4 = world; + self.search_time = time + 5; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_lost + +Bot has lost its target. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity targ, float success) bot_lost = +{ + if (!targ) + return; + + target_drop(targ); + if (targ.classname == "waypoint") + targ.b_sound = targ.b_sound - (targ.b_sound & ClientBitFlag(self.b_clientno)); + + // find a new route + if (!success) + { + self.target1 = self.target2 = self.target3 = self.target4 = world; + self.last_way = FindWayPoint(self.current_way); + ClearMyRoute(); + self.b_aiflags = 0; + } + else + { + if (targ.classname == "item_artifact_invisibility") + if (self.items & 524288) + bot_start_topic(3); + + if (targ.flags & FL_ITEM) + { + if (targ.model == string_null) + targ._last = world; + else + targ._last = self; + } + } + + + if (targ.classname != "player") + targ.search_time = time + 5; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_check_lost + +decide if my most immediate target should be +removed. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(entity targ) bot_check_lost = +{ + local vector dist; + dist = realorigin(targ) - self.origin; + dist_z = 0; + if (targ == world) + return; + + // waypoints and items are lost if you get close enough to them + + else if (targ.flags & FL_ITEM) + { + if (vlen(targ.origin - self.origin) < 32) + bot_lost(targ, TRUE); + else if (targ.model == string_null) + bot_lost(targ, TRUE); + } + else if (targ.classname == "waypoint") + { + if (!(self.b_aiflags & (AI_SNIPER | AI_AMBUSH))) + { + if (self.b_aiflags & AI_RIDE_TRAIN) + { + if (vlen(targ.origin - self.origin) < 48) + bot_lost(targ, TRUE); + } + else if (self.b_aiflags & AI_PRECISION) + { + if (vlen(targ.origin - self.origin) < 24) + bot_lost(targ, TRUE); + } + else if (vlen(targ.origin - self.origin) < 32) + bot_lost(targ, TRUE); + } + } + else if (targ.classname == "temp_waypoint") + { + if (vlen(targ.origin - self.origin) < 32) + bot_lost(targ, TRUE); + } + else if (targ.classname == "player") + { + if (targ.health <= 0) + bot_lost(targ, TRUE); + else if ((coop) || (teamplay && targ.team == self.team)) + { + if (targ.target1.classname == "player") + { + if (!targ.target1.ishuman) + bot_lost(targ, TRUE); + } + else if (targ.teleport_time > time) + { + // try not to telefrag teammates + self.keys = self.keys & 960; + } + else if (vlen(targ.origin - self.origin) < 128) + { + if (vlen(targ.origin - self.origin) < 48) + frik_walkmove(self.origin - targ.origin); + else + { + self.keys = self.keys & 960; + bot_start_topic(4); + } + self.search_time = time + 5; // never time out + } + else if (!fisible(targ)) + bot_lost(targ, FALSE); + } + else if (waypoint_mode > WM_LOADED) + { + if (vlen(targ.origin - self.origin) < 128) + { + bot_lost(targ, TRUE); + } + } + } + + // buttons are lost of their frame changes + else if (targ.classname == "func_button") + { + if (targ.frame) + { + bot_lost(targ, TRUE); + if (self.enemy == targ) + self.enemy = world; + //if (self.target1) + // bot_get_path(self.target1, TRUE); + + } + } + // trigger_multiple style triggers are lost if their thinktime changes + else if ((targ.movetype == MOVETYPE_NONE) && (targ.solid == SOLID_TRIGGER)) + { + if (targ.nextthink >= time) + { + bot_lost(targ, TRUE); + //if (self.target1) + // bot_get_path(self.target1, TRUE); + } + } + // lose any target way above the bot's head + // FIXME: if the bot can fly in your mod.. + if ((targ.origin_z - self.origin_z) > 64) + { + dist = targ.origin - self.origin; + dist_z = 0; + if (vlen(dist) < 32) + if (self.flags & FL_ONGROUND) + if(!frik_recognize_plat(FALSE)) + bot_lost(targ, FALSE); + } + else if (targ.classname == "train") + { + if (frik_recognize_plat(FALSE)) + bot_lost(targ, TRUE); + } + // targets are lost if the bot's search time has expired + if (time > self.search_time) + bot_lost(targ, FALSE); +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_handle_ai + +This is a 0.10 addition. Handles any action +based b_aiflags. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_handle_ai = +{ + local entity newt; + local vector v; + + // handle ai flags -- note, not all aiflags are handled + // here, just those that perform some sort of action + + // wait is used by the ai to stop the bot until his search time expires / or route changes + + if (self.b_aiflags & AI_WAIT) + self.keys = self.keys & 960; + + if (self.b_aiflags & AI_DOORFLAG) // was on a door when spawned + { + b_temp3 = self; + self = self.last_way; + if (!frik_recognize_plat(FALSE)) // if there is nothing there now + { + newt = FindThing("door"); // this is likely the door responsible (crossfingers) + self = b_temp3; + + if (self.b_aiflags & AI_DOOR_NO_OPEN) + { + if (newt.nextthink) + self.keys = self.keys & 960; // wait until it closes + else + { + bot_lost(self.last_way, FALSE); + } + } + else + { + if (newt.targetname) + { + newt = find(world, target, newt.targetname); + if (newt.health > 0) + { + self.enemy = newt; + bot_weapon_switch(1); + } + else + { + // target_drop(self.last_way); + target_add(newt); + // bot_get_path(newt, TRUE); + } + } + self.b_aiflags = self.b_aiflags - AI_DOORFLAG; + } + } + else + self = b_temp3; + } + + if (self.b_aiflags & AI_JUMP) + { + if (self.flags & FL_ONGROUND) + { + bot_jump(); + self.b_aiflags = self.b_aiflags - AI_JUMP; + } + } + else if (self.b_aiflags & AI_SUPER_JUMP) + { + if (self.weapon != 32) + self.impulse = 7; + else if (self.flags & FL_ONGROUND) + { + self.b_aiflags = self.b_aiflags - AI_SUPER_JUMP; + if (bot_can_rj(self)) + { + bot_jump(); + self.v_angle_x = self.b_angle_x = 80; + self.button0 = TRUE; + } + else + bot_lost(self.target1, FALSE); + + } + } + if (self.b_aiflags & AI_SURFACE) + { + if (self.waterlevel > 2) + { + self.keys = KEY_MOVEUP; + self.button2 = TRUE; // swim! + } + else + self.b_aiflags = self.b_aiflags - AI_SURFACE; + } + if (self.b_aiflags & AI_RIDE_TRAIN) + { + // simple, but effective + // this can probably be used for a lot of different + // things, not just trains (door elevators come to mind) + b_temp3 = self; + self = self.last_way; + + if (!frik_recognize_plat(FALSE)) // if there is nothing there now + { + self = b_temp3; + self.keys = self.keys & 960; + } + else + { + self = b_temp3; + if (frik_recognize_plat(FALSE)) + { + v = realorigin(trace_ent) + trace_ent.origin - self.origin; + v_z = 0; + if (vlen(v) < 24) + self.keys = self.keys & 960; + else + { + self.b_aiflags = self.b_aiflags | AI_PRECISION; + self.keys = frik_KeysForDir(v); + } + } + } + } + if (self.b_aiflags & AI_PLAT_BOTTOM) + { + newt = FindThing("plat"); + if (newt.state != 1) + { + v = self.origin - realorigin(newt); + v_z = 0; + if (vlen(v) > 96) + self.keys = self.keys & 960; + else + frik_walkmove(v); + } + else + self.b_aiflags = self.b_aiflags - AI_PLAT_BOTTOM; + } + if (self.b_aiflags & AI_DIRECTIONAL) + { + if ((normalize(self.last_way.origin - self.origin) * self.b_dir) > 0.4) + { + self.b_aiflags = self.b_aiflags - AI_DIRECTIONAL; + bot_lost(self.target1, TRUE); + } + } + if (self.b_aiflags & AI_SNIPER) + { + self.b_aiflags = (self.b_aiflags | AI_WAIT | AI_PRECISION) - AI_SNIPER; + // FIXME: Add a switch to wep command + // FIXME: increase delay? + } + if (self.b_aiflags & AI_AMBUSH) + { + self.b_aiflags = (self.b_aiflags | AI_WAIT) - AI_AMBUSH; + // FIXME: Add a switch to wep command + // FIXME: increase delay? + } + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_path + +Bot will follow a route generated by the +begin_route set of functions in bot_way.qc. +This code, while it works pretty well, can get +confused + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_path = +{ + + local entity jj, tele; + + bot_check_lost(self.target1); + if (!self.target1) + { + self.keys=0; + return; + } + if (target_onstack(self.last_way)) + return; // old waypoint still being hunted + + jj = FindRoute(self.last_way); + if (!jj) + { + // this is an ugly hack + if (self.target1.current_way != self.last_way) + { + if (self.target1.classname != "temp_waypoint") + if (self.target1.classname != "player") + bot_lost(self.target1, FALSE); + } + + return; + } + + // update the bot's special ai features + + // Readahed types are AI conditions to perform while heading to a waypoint + // point types are AI flags that should be executed once reaching a waypoint + + self.b_aiflags = (jj.b_aiflags & AI_READAHEAD_TYPES) | (self.last_way.b_aiflags & AI_POINT_TYPES); + target_add(jj); + if (self.last_way) + { + if (CheckLinked(self.last_way, jj) == 2) // waypoints are telelinked + { + tele = FindThing("trigger_teleport"); // this is probbly the teleport responsible + target_add(tele); + } + traceline(self.last_way.origin, jj.origin, FALSE, self); // check for blockage + if (trace_fraction != 1) + { + if (trace_ent.classname == "door" && !(self.b_aiflags & AI_DOOR_NO_OPEN)) // a door blocks the way + { + // linked doors fix + if (trace_ent.owner) + trace_ent = trace_ent.owner; + if ((trace_ent.health > 0) && (self.enemy == world)) + { + self.enemy = trace_ent; + bot_weapon_switch(1); + self.b_aiflags = self.b_aiflags | AI_BLIND; // nick knack paddy hack + } + else if (trace_ent.targetname) + { + tele = find(world, target, trace_ent.targetname); + if (tele.health > 0) + { + self.enemy = tele; + bot_weapon_switch(1); + } + else + { + // target_drop(jj); + target_add(tele); + // bot_get_path(tele, TRUE); + self.b_aiflags = self.b_aiflags | AI_BLIND; // give a bot a bone + return; + } + } + } + else if (trace_ent.classname == "func_wall") + { + // give up + bot_lost(self.target1, FALSE); + return; + } + } + } + // this is used for AI_DRIECTIONAL + self.b_dir = normalize(jj.origin - self.last_way.origin); + + self.last_way = jj; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Priority Look. What a stupid name. This is where +the bot finds things it wants to kill/grab. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +// priority scale +// 0 - 10 virtually ignore +// 10 - 30 normal item range +// 30 - 50 bot will consider this a target worth changing course for +// 50 - 90 bot will hunt these as vital items + +// *!* Make sure you add code to bot_check_lost to remove the target *!* + +float(entity thing) priority_for_thing = +{ + local float thisp; + thisp = 0; + // This is the most executed function in the bot. Careful what you do here. + + if ((thing.flags & FL_ITEM) && thing.model != string_null && thing.search_time < time) + { + // ugly hack + if (thing._last != self) + thisp = 20; + if (thing.classname == "item_artifact_super_damage") + thisp = 65; + else if (thing.classname == "item_artifact_invulnerability") + thisp = 65; +else if (thing.classname == "weapon_skull") +thisp = 90; + else if (thing.classname == "item_health") + { + if (thing.spawnflags & 2) + thisp = 55; + if (self.health < 40) + thisp = thisp + 50; + } + else if (thing.model == "progs/armor.mdl") + { + if (self.armorvalue < 200) + { + if (thing.skin == 2) + thisp = 60; + else if (self.armorvalue < 100) + thisp = thisp + 25; + } + } + else if (thing.classname == "weapon_pickup") + { + if (!(self.items & thing.weapon)) { // bot weapon pickup is handled in weapon_pickup + //_bprint("SEEK ME WEAPON 2\n"); + thisp = 75; + } + } + else if (thing.classname == "weapon_supershotgun") + { + if (!(self.items & 2)) // IT_SUPER_SHOTGUN + thisp = 25; + } + else if (thing.classname == "weapon_nailgun") + { + if (!(self.items & 4)) // IT_NAILGUN + thisp = 30; + } + else if (thing.classname == "weapon_supernailgun") + { + if (!(self.items & 8)) // IT_SUPER_NAILGUN + thisp = 35; + } + else if (thing.classname == "weapon_grenadelauncher") + { + if (!(self.items & 16)) // IT_GRENADE_LAUNCHER + thisp = 45; + } + else if (thing.classname == "weapon_rocketlauncher") + { + if (!(self.items & 32)) // IT_ROCKET_LAUNCHER + thisp = 60; + } + else if (thing.classname == "weapon_lightning") + { + if (!(self.items & 64)) // IT_LIGHTNING + thisp = 50; + } +else if (thing.classname == "weapon_skull") + { + if (!(self.items & thing.weapon))// IT_SKULL + thisp = 90; + } + } + else if ((thing.flags & FL_MONSTER) && thing.health > 0) + thisp = 45; + else if (thing.classname == "player") + { + if (thing.health > 0) + { + if (thing == self) + return 0; + else + { + if (thing.items & IT_INVISIBILITY) //FIXME + thisp = 2; + else if (coop) + { + thisp = 200; + if (thing.target1.classname == "player") + if (!thing.target1.ishuman) + return 0; + } + else if (teamplay && thing.team == self.team) + { + thisp = 100; + if (thing.target1.classname == "player") + return 0; + } + else thisp = 30; + } + } + } + else if (thing.classname == "waypoint") + { + if (thing.b_aiflags & AI_SNIPER) + thisp = 30; + else if (thing.b_aiflags & AI_AMBUSH) + thisp = 30; + } + if (pointcontents(thing.origin) < -3) + return 0; + if (thisp) + { + if (thing.current_way) + { + // check to see if it's unreachable + if (thing.current_way.items == -1) + return 0; + else + thisp = thisp + (13000 - thing.current_way.items) * 0.05; + } + } + return thisp; +}; + +void(float scope) bot_look_for_crap = +{ + local entity foe, best; + local float thatp, bestp, dist; + + if (scope == 1) + foe = findradius(self.origin, 13000); + else + foe = findradius(self.origin, 500); + + bestp = 1; + while(foe) + { + thatp = priority_for_thing(foe); + if (thatp) + if (!scope) + if (!sisible(foe)) + thatp = 0; + if (thatp > bestp) + { + bestp = thatp; + best = foe; + dist = vlen(self.origin - foe.origin); + } + foe = foe.chain; + } + if (best == world) + return; + if (!target_onstack(best)) + { + target_add(best); + if (scope) + { + bot_get_path(best, FALSE); + self.b_aiflags = self.b_aiflags | AI_WAIT; + } + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_angle_set + +Sets the bots look keys & b_angle to point at +the target - used for fighting and just +generally making the bot look good. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_angle_set = +{ + local float h; + local vector view; + + if (self.enemy) + { + if (self.enemy.items & 524288) + if (random() > 0.01) + return; + if (self.missile_speed == 0) + self.missile_speed = 10000; + if (self.enemy.solid == SOLID_BSP) + { + view = (((self.enemy.absmin + self.enemy.absmax) * 0.5) - self.origin); + } + else + { + + local float levels; + + levels = 3; + + view = self.enemy.origin; + + while (levels) + { + h = vlen(view - self.origin) / self.missile_speed; + if (self.enemy.flags & FL_ONGROUND) + view = self.enemy.velocity * h + '0 0 -20'; + else + view = (self.enemy.velocity - (sv_gravity * '0 0 1') * h) * h; + view = self.enemy.origin + view; + traceline(self.enemy.origin, view, FALSE, self); + view = trace_endpos; + levels = levels - 1; + } + view = normalize(view - self.origin); + } + view = vectoangles(view); + view_x = view_x * -1; + self.b_angle = view; + } + else if (self.target1) + { + view = realorigin(self.target1); + if (self.target1.flags & FL_ITEM) + view = view + '0 0 48'; + view = view - (self.origin + self.view_ofs); + view = vectoangles(view); + view_x = view_x * -1; + self.b_angle = view; + } + else + self.b_angle_x = 0; + // HACK HACK HACK HACK + // The bot falls off ledges a lot because of "turning around" + // so let the bot use instant turn around when not hunting a player + if (self.b_skill == 3) + { + self.keys = self.keys & 63; + self.v_angle = self.b_angle; + while (self.v_angle_x < -180) + self.v_angle_x = self.v_angle_x + 360; + while (self.v_angle_x > 180) + self.v_angle_x = self.v_angle_x - 360; + + } + else if ((self.enemy == world || self.enemy.movetype == MOVETYPE_PUSH) && self.target1.classname != "player") + { + self.keys = self.keys & 63; + self.v_angle = self.b_angle; + while (self.v_angle_x < -180) + self.v_angle_x = self.v_angle_x + 360; + while (self.v_angle_x > 180) + self.v_angle_x = self.v_angle_x - 360; + } + else if (self.b_skill < 2) // skill 2 handled in bot_phys + { + if (self.b_angle_x > 180) + self.b_angle_x = self.b_angle_x - 360; + self.keys = self.keys & 63; + + if (angcomp(self.b_angle_y, self.v_angle_y) > 10) + self.keys = self.keys | KEY_LOOKLEFT; + else if (angcomp(self.b_angle_y, self.v_angle_y) < -10) + self.keys = self.keys | KEY_LOOKRIGHT; + if (angcomp(self.b_angle_x, self.v_angle_x) < -10) + self.keys = self.keys | KEY_LOOKUP; + else if (angcomp(self.b_angle_x, self.v_angle_x) > 10) + self.keys = self.keys | KEY_LOOKDOWN; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotAI + +This is the main ai loop. Though called every +frame, the ai_time limits it's actual updating + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float stagger_think; + +void() BotAI = +{ + // am I dead? Fire randomly until I respawn + // health < 1 is used because fractional healths show up as 0 on normal player + // status bars, and the mod probably already compensated for that + + if (self.health < 1) + { + self.button0 = floor(random() * 2); + self.button2 = 0; + self.keys = 0; + self.b_aiflags = 0; + ClearMyRoute(); + self.target1 = self.target2 = self.target3 = self.target4 = self.enemy = world; + self.last_way = world; + return; + } + + // stagger the bot's AI out so they all don't think at the same time, causing game + // 'spikes' + if (self.b_skill < 2) + { + if (self.ai_time > time) + return; + + self.ai_time = time + 0.05; + if (bot_count > 0) + { + if ((time - stagger_think) < (0.1 / bot_count)) + self.ai_time = self.ai_time + 0.1 / (2 * bot_count); + } + else + return; + } + if (self.view_ofs == '0 0 0') + bot_start_topic(7); + stagger_think = time; + + // shut the bot's buttons off, various functions will turn them on by AI end + + self.button2 = 0; + self.button0 = 0; + + + // target1 is like goalentity in normal Quake monster AI. + // it's the bot's most immediate target + if (route_table == self) + { + if (busy_waypoints <= 0) + { + if (waypoint_mode < WM_EDITOR) + bot_look_for_crap(TRUE); + } + self.b_aiflags = 0; + self.keys = 0; + } + else if (self.target1) + { + frik_movetogoal(); + bot_path(); + } + else + { + if (waypoint_mode < WM_EDITOR) + { + if(self.route_failed) + { + if (waypoint_mode == WM_DYNAMIC) + frik_bot_roam(); + else + self.keys = 0; + self.route_failed = 0; + } + else if(!begin_route()) + { + bot_look_for_crap(FALSE); + self.keys = 0; + } + + } + else + { + self.b_aiflags = AI_WAIT; + self.keys = 0; + } + } + + // bot_angle_set points the bot at it's goal (self.enemy or target1) + + bot_angle_set(); + + // fight my enemy. Enemy is probably a field QC coders will most likely use a lot + // for their own needs, since it's unused on a normal player + // FIXME + if (self.enemy) + bot_fight_style(); + else if (random() < 0.2) + if (random() < 0.2) + bot_weapon_switch(-1); + bot_dodge_stuff(); + + // checks to see if bot needs to start going up for air + if (self.waterlevel > 2) + { + if (time > (self.air_finished - 2)) + { + traceline (self.origin, self.origin + '0 0 6800', TRUE, self); + if (trace_inopen) + { + self.keys = KEY_MOVEUP; + self.button2 = TRUE; // swim! + return; // skip ai flags for now - this is life or death + } + } + } + + // b_aiflags handling + + + if (self.b_aiflags) + bot_handle_ai(); + else + bot_chat(); // don't want chat to screw him up if he's rjing or something +}; diff --git a/r17/Revamped src/Revamped QC/frikbot/bot_ed.qc b/r17/Revamped src/Revamped QC/frikbot/bot_ed.qc new file mode 100755 index 00000000..fb2c84a6 --- /dev/null +++ b/r17/Revamped src/Revamped QC/frikbot/bot_ed.qc @@ -0,0 +1,1638 @@ +/*********************************************** +* * +* FrikBot Waypoint Editor * +* "The 'wtf is this doing in my mod' code" * +* * +***********************************************/ + +/* + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + +float saved1, saved2, saved3, scratch1, scratch2, scratch3, scratch4; +float bytecounter, filecount; + +float MENU_MAIN = 1; +float MENU_WAYPOINTS = 2; +float MENU_LINKS = 3; +float MENU_FLAGS = 4; +float MENU_FLAGS2 = 5; +float MENU_BOTS = 6; +float MENU_WAYLIST = 7; +// 8 = link way +// 9 = telelink way +// 10 = delete link +// 11 = create link X2 +// 12 = delete link x2 +// 13 = confirmation of delete all +// 14 = Teleport to way +// 15 = confirmation of delete point + +void() BSPDumpWaypoints; +void() QCDumpWaypoints; +void() DumpWaypoints; +void() SaveWays; +/* +// source for the menu strings... + +\b-- Main Menu --\b\n +\[\1\] >>Waypoint Management\n +\[\2\] >>Link Management \n +\[\3\] >>AI Flag Management \n +\[\4\] >>Bot Management \n +\[\5\] >>Waylist Management \n +\[\6\] \[\{133}\] Noclip \n +\[\7\] \[\{133}\] Godmode \n +\[\8\] \[\{133}\] Hold Select \n +\[\9\] Teleport to Way # \n +\[\0\] Close Menu \n + +// missing from main is show way info +// iffy on the teleport to way thing being on main...seems like either a bot or way list thing + +\b-- Waypoint Management --\b\n +\[\1\] Move Waypoint \n +\[\2\] Delete Waypoint \n +\[\3\] Make Waypoint \n +\[\4\] Make Way + Link \n +\[\5\] Make Way + Link X2 \n +\[\6\] Make Way + Telelink \n +\[\7\] Show waypoint info \n +\[\8\] >>Link Management \n +\[\9\] >>AI Flag Management \n +\[\0\] >>Main Menu \n + +\b-- Link Management --\b\n +\[\1\] Unlink Waypoint \n +\[\2\] Create Link \n +\[\3\] Create Telelink \n +\[\4\] Delete Link \n +\[\5\] Create Link X2 \n +\[\6\] Delete Link X2 \n +\[\7\] >Make Waypoint \n +\[\8\] >>Waypoint Management\n +\[\9\] >>AI Flag Management \n +\[\0\] >>Main Menu \n + +// Ai flags...ugh + +\b-- AI Flag Management --\b\n +\[\1\] \[\{133}\] Door Flag \n +\[\2\] \[\{133}\] Precision \n +\[\3\] \[\{133}\] Surface for air \n +\[\4\] \[\{133}\] Blind mode \n +\[\5\] \[\{133}\] Jump \n +\[\6\] \[\{133}\] Directional \n +\[\7\] \[\{133}\] Super Jump \n +\n +\[\9\] >>AI Flags page 2 \n +\[\0\] >>Main Menu \n + +\b-- AI Flags pg. 2--\b\n +\[\1\] \[\{133}\] Difficult \n +\[\2\] \[\{133}\] Wait for plat \n +\[\3\] \[\{133}\] Ride train \n +\[\4\] \[\{133}\] Door flag no open\n +\[\5\] \[\{133}\] Ambush \n +\[\6\] \[\{133}\] Snipe \n +\[\7\] \[\{133}\] Trace Test \n +\n +\[\9\] >>AI Flag Management \n +\[\0\] >>Main Menu \n + +\b-- Bot Management --\b\n +\[\1\] Add a Test Bot \n +\[\2\] Order Test Bot here \n +\[\3\] Remove Test Bot \n +\[\4\] Stop Test Bot \n +\[\5\] Teleport Bot here \n +\[\6\] Teleport to Way # \n +\n +\n +\n +\[\0\] >>Main Menu \n + +\b-- Waylist Management --\b\n +\[\1\] Delete ALL Waypoints \n +\[\2\] Dump Waypoints \n +\[\3\] Check For Errors \n +\[\4\] Save Waypoints \n +\[\5\] \[\{133}\] Dynamic Mode \n +\[\6\] \[\{133}\] Dynamic Link \n +\[\7\] \[\{133}\] WAY output \n +\[\8\] \[\{133}\] QC output \n +\[\9\] \[\{133}\] BSP ents output \n +\[\0\] Main Menu \n + +\b-- Misc Commands --\b\n +\[\1\] Teleport to Selected \n +\[\2\] Select \n +\[\3\] Swap to old \n +\[\4\] Trace select \n +\[\5\] Create way in path \n +\[\6\] Delete Way from path \n + + +\b-- Editor Memory --\b\n +\[\1\] Store as slot 1 \n +\[\2\] Store as slot 2 \n +\[\3\] Store as slot 3 \n +\[\4\] Store as slot 4 \n +\[\5\] Recall slot 1 \n +\[\6\] Recall slot 2 \n +\[\7\] Recall slot 3 \n +\[\8\] Recall slot 4 \n + +*/ + +void() bot_menu_display = +{ +// build options + local string s1, s2, s3, s4, s5, s6, s7, h; + local entity t; + +// check impulses + if (self.impulse > 0 && self.impulse < 11 && self.b_menu) + { + if (self.b_menu == MENU_MAIN) + { + if (self.impulse == 1) + { + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + else if (self.impulse == 3) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 4) + { + self.b_menu = MENU_BOTS; + self.b_menu_time = time; + } + else if (self.impulse == 5) + { + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + else if (self.impulse == 6) + { + if (self.movetype == MOVETYPE_NOCLIP) + self.movetype = MOVETYPE_WALK; + else + self.movetype = MOVETYPE_NOCLIP; + self.b_menu_time = time; + + } + else if (self.impulse == 7) + { + if (self.flags & FL_GODMODE) + self.flags = self.flags - FL_GODMODE; + else + self.flags = self.flags | FL_GODMODE; + self.b_menu_time = time; + + } + else if (self.impulse == 8) + { + if (self.b_aiflags & AI_HOLD_SELECT) + self.b_aiflags = self.b_aiflags - AI_HOLD_SELECT; + else + self.b_aiflags = self.b_aiflags | AI_HOLD_SELECT; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + self.b_menu = 14; + self.b_menu_time = time; + } + else if (self.impulse == 10) + bot_way_edit(); + } + else if (self.b_menu == MENU_WAYPOINTS) + { + if (self.impulse == 1) + { + if (self.current_way) + setorigin(self.current_way, self.origin + self.view_ofs); + } + else if (self.impulse == 2) + { + if (self.current_way) + { + self.b_menu = 15; + self.b_menu_time = time; + self.last_way = self.current_way; + } + } + else if (self.impulse == 3) + { + make_waypoint(self.origin + self.view_ofs); + } + else if (self.impulse == 4) + { + t = make_waypoint(self.origin + self.view_ofs); + if (!LinkWays(self.current_way, t)) + sprint(self, "Unable to link them\n"); + } + else if (self.impulse == 5) + { + t = make_waypoint(self.origin + self.view_ofs); + if (!LinkWays(self.current_way, t)) + sprint(self, "Unable to link old to new\n"); + LinkWays(t, self.current_way); + } + else if (self.impulse == 6) + { + t = make_waypoint(self.origin + self.view_ofs); + if (!TeleLinkWays(self.current_way, t)) + sprint(self, "Unable to link them\n"); + } + else if (self.impulse == 7) + { + if (self.current_way) + { + sprint(self, "\nwaypoint info for waypoint #"); + h = ftos(self.current_way.count); + sprint(self, h); + sprint(self, "\nAI Flag value: "); + h = ftos(self.current_way.b_aiflags); + sprint(self, h); + + if (self.current_way.target1) + { + h = ftos(self.current_way.target1.count); + if (self.current_way.b_aiflags & AI_TELELINK_1) + sprint(self, "\nTelelink1 to:"); + else + sprint(self, "\nLink1 to:"); + sprint(self, h); + } + if (self.current_way.target2) + { + h = ftos(self.current_way.target2.count); + if (self.current_way.b_aiflags & AI_TELELINK_2) + sprint(self, "\nTelelink2 to:"); + else + sprint(self, "\nLink2 to:"); + sprint(self, h); + } + if (self.current_way.target3) + { + h = ftos(self.current_way.target3.count); + if (self.current_way.b_aiflags & AI_TELELINK_3) + sprint(self, "\nTelelink3 to:"); + else + sprint(self, "\nLink3 to:"); + sprint(self, h); + } + if (self.current_way.target4) + { + h = ftos(self.current_way.target4.count); + if (self.current_way.b_aiflags & AI_TELELINK_4) + sprint(self, "\nTelelink4 to:"); + else + sprint(self, "\nLink4 to:"); + sprint(self, h); + } + sprint(self, "\n\n"); + } + + } + if (self.impulse == 8) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_LINKS) + { + if (self.impulse == 1) + { + self.b_menu = 16; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 2) + { + self.b_menu = 8; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 3) + { + self.b_menu = 9; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 4) + { + self.b_menu = 10; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 5) + { + self.b_menu = 11; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 6) + { + self.b_menu = 12; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 7) + make_waypoint(self.origin + self.view_ofs); + else if (self.impulse == 8) + { + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_FLAGS) + { + + if (self.current_way) + { + if (self.impulse == 1) + { + if (self.current_way.b_aiflags & AI_DOORFLAG) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DOORFLAG); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DOORFLAG; + + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + if (self.current_way.b_aiflags & AI_PRECISION) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_PRECISION); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_PRECISION; + self.b_menu_time = time; + } + else if (self.impulse == 3) + { + if (self.current_way.b_aiflags & AI_SURFACE) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_SURFACE); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_SURFACE; + self.b_menu_time = time; + } + else if (self.impulse == 4) + { + if (self.current_way.b_aiflags & AI_BLIND) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_BLIND); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_BLIND; + self.b_menu_time = time; + } + else if (self.impulse == 5) + { + if (self.current_way.b_aiflags & AI_JUMP) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_JUMP); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_JUMP; + self.b_menu_time = time; + } + else if (self.impulse == 6) + { + if (self.current_way.b_aiflags & AI_DIRECTIONAL) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DIRECTIONAL); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DIRECTIONAL; + self.b_menu_time = time; + } + else if (self.impulse == 7) + { + if (self.current_way.b_aiflags & AI_SUPER_JUMP) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_SUPER_JUMP); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_SUPER_JUMP; + self.b_menu_time = time; + } + } + if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS2; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_FLAGS2) + { + + if (self.current_way) + { + if (self.impulse == 1) + { + if (self.current_way.b_aiflags & AI_DIFFICULT) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DIFFICULT); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DIFFICULT; self.b_menu_time = time; + } + else if (self.impulse == 2) + { + if (self.current_way.b_aiflags & AI_PLAT_BOTTOM) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_PLAT_BOTTOM); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_PLAT_BOTTOM; + self.b_menu_time = time; + } + else if (self.impulse == 3) + { + if (self.current_way.b_aiflags & AI_RIDE_TRAIN) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_RIDE_TRAIN); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_RIDE_TRAIN; + self.b_menu_time = time; + } + else if (self.impulse == 4) + { + if (self.current_way.b_aiflags & AI_DOOR_NO_OPEN) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DOOR_NO_OPEN); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DOOR_NO_OPEN; + self.b_menu_time = time; + } + else if (self.impulse == 5) + { + if (self.current_way.b_aiflags & AI_AMBUSH) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_AMBUSH); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_AMBUSH; + self.b_menu_time = time; + } + else if (self.impulse == 6) + { + if (self.current_way.b_aiflags & AI_SNIPER) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_SNIPER); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_SNIPER; + self.b_menu_time = time; + } + else if (self.impulse == 7) + { + if (self.current_way.b_aiflags & AI_TRACE_TEST) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_TRACE_TEST); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_TRACE_TEST; + self.b_menu_time = time; + } + + } + if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + + else if (self.b_menu == MENU_BOTS) + { + if (self.impulse == 1) + { + self.impulse = 100; + return; + } + else if (self.impulse == 2) + { + b_temp3 = self; + self = player_head; + while(self) + { + if (!self.ishuman) + { + target_add(b_temp3); + bot_get_path(b_temp3, TRUE); + self = world; + } + else + self = self._next; + } + self = b_temp3; + } + else if (self.impulse == 3) + { + self.impulse = 102; + return; + } + else if (self.impulse == 4) + { + b_temp1 = self; + self = player_head; + while(self) + { + if (!self.ishuman) + { + self.target1 = self.target2 = self.target3 = self.target4 = world; + route_table = world; + } + self = self._next; + } + self = b_temp1; + } + else if (self.impulse == 5) + { + if (self.current_way) + { + b_temp1 = self; + self = player_head; + while(self) + { + if (!self.ishuman) + { + setorigin(self, b_temp1.current_way.origin); + } + self = self._next; + } + self = b_temp1; + } + else + sprint(self, "select a waypoint first\n"); + } + else if (self.impulse == 6) + { + self.b_menu = 14; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_WAYLIST) + { + if (self.impulse == 1) + { + self.b_menu = 13; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + if (dump_mode == 0) + DumpWaypoints(); + else if (dump_mode == 1) + QCDumpWaypoints(); + else if (dump_mode == 2) + BSPDumpWaypoints(); + } + else if (self.impulse == 3) + { + t = way_head; + while(t) + { + if ((t.target1 == world) && (t.target2 == world) && (t.target3 == world) && (t.target4 == world)) + { + sprint(self, "Waypoint #"); + h = ftos(t.count); + sprint(self, h); + sprint(self, " has no outbound links\n"); + } + if ((t.target1 == t) || (t.target2 == t) || (t.target3 == t) || (t.target4 == t)) + { + sprint(self, "Waypoint #"); + h = ftos(t.count); + sprint(self, h); + sprint(self, " links to itself (??)\n"); + } + t = t._next; + } + sprint(self, "Error check complete\n"); + } + else if (self.impulse == 4) + { + // FIXME: detect engine feature and skip prompt + + self.b_menu = 17; + self.b_menu_time = time; + //SaveWays(); + } + else if (self.impulse == 5) + { + if (waypoint_mode == WM_EDITOR_DYNAMIC) + waypoint_mode = WM_EDITOR; + else + waypoint_mode = WM_EDITOR_DYNAMIC; + self.b_menu_time = time; + + } + else if (self.impulse == 6) + { + if (waypoint_mode == WM_EDITOR_DYNLINK) + waypoint_mode = WM_EDITOR; + else + waypoint_mode = WM_EDITOR_DYNLINK; + self.b_menu_time = time; + } + else if (self.impulse == 7) + { + dump_mode = 0; + self.b_menu_time = time; + } + else if (self.impulse == 8) + { + dump_mode = 1; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + dump_mode = 2; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == 8) + { + if (self.impulse == 1) + { + if (self.current_way) + { + if (!LinkWays(self.last_way, self.current_way)) + sprint(self, "Unable to link them\n"); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 9) + { + if (self.impulse == 1) + { + if (self.current_way) + { + if (!TeleLinkWays(self.last_way, self.current_way)) + sprint(self, "Unable to link them\n"); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 10) + { + if (self.impulse == 1) + { + if (self.current_way) + { + UnlinkWays(self.last_way, self.current_way); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 11) + { + if (self.impulse == 1) + { + if (self.current_way) + { + if (!LinkWays(self.last_way, self.current_way)) + sprint(self, "Unable to link 1 to 2\n"); + if (!LinkWays(self.current_way, self.last_way)) + sprint(self, "Unable to link 2 to 1\n"); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 12) + { + if (self.impulse == 1) + { + if (self.current_way) + { + UnlinkWays(self.last_way, self.current_way); + UnlinkWays(self.current_way, self.last_way); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 13) + { + if (self.impulse == 1) + { + ClearAllWays(); + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + } + else if (self.b_menu == 14) + { + if (self.impulse == 10) + self.impulse = 0; + self.b_menu_value = self.b_menu_value * 10 + self.impulse; + self.b_menu_time = 0; + } + else if (self.b_menu == 15) + { + if (self.impulse == 1) + { + delete_waypoint(self.last_way); + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 16) + { + if (self.impulse == 1) + { + if (self.last_way) + { + self.last_way.target1 = self.last_way.target2 = self.last_way.target3 = self.last_way.target4 = world; + self.last_way.b_aiflags = self.last_way.b_aiflags - (self.last_way.b_aiflags & 15); + } + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 17) + { + + if (self.impulse == 1) + SaveWays(); + if (self.impulse < 3) + { + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + } + self.impulse = 0; + } + if (self.b_menu_time <= time) + { + if (self.b_menu == MENU_MAIN) + { + s1 = "\b-- Main Menu --\b\n\[\1\] >>Waypoint Management\n\[\2\] >>Link Management \n\[\3\] >>AI Flag Management \n\[\4\] >>Bot Management \n\[\5\] >>Waylist Management \n"; + if (self.movetype == MOVETYPE_NOCLIP) + s2 = "\[\6\] \[\{133}\] Noclip \n"; + else + s2 = "\[\6\] \[ \] Noclip \n"; + + if (self.flags & FL_GODMODE) + s3 = "\[\7\] \[\{133}\] Godmode \n"; + else + s3 = "\[\7\] \[ \] Godmode \n"; + if (self.b_aiflags & AI_HOLD_SELECT) + s4 = "\[\8\] \[\{133}\] Hold Select \n"; + else + s4 = "\[\8\] \[ \] Hold Select \n"; + s5 = "\[\9\] Teleport to Way # \n\[\0\] Close Menu \n"; + } + else if (self.b_menu == MENU_WAYPOINTS) + { + s1 = "\b-- Waypoint Management --\b\n\[\1\] Move Waypoint \n\[\2\] Delete Waypoint \n\[\3\] Make Waypoint \n\[\4\] Make Way + Link \n\[\5\] Make Way + Link X2 \n\[\6\] Make Way + Telelink \n\[\7\] Show waypoint info \n\[\8\] >>Link Management \n\[\9\] >>AI Flag Management \n\[\0\] >>Main Menu \n"; + } + else if (self.b_menu == MENU_LINKS) + { + s1 = "\b-- Link Management --\b\n\[\1\] Unlink Waypoint \n\[\2\] Create Link \n\[\3\] Create Telelink \n\[\4\] Delete Link \n\[\5\] Create Link X2 \n\[\6\] Delete Link X2 \n\[\7\] >Make Waypoint \n\[\8\] >>Waypoint Management\n\[\9\] >>AI Flag Management \n\[\0\] >>Main Menu \n"; + } + else if (self.b_menu == MENU_FLAGS) + { + if (self.current_way.b_aiflags & AI_DOORFLAG) + s1 = "\b-- AI Flag Management --\b\n\[\1\] \[\{133}\] Door Flag \n"; + else + s1 = "\b-- AI Flag Management --\b\n\[\1\] \[ \] Door Flag \n"; + + if (self.current_way.b_aiflags & AI_PRECISION) + s2 = "\[\2\] \[\{133}\] Precision \n"; + else + s2 = "\[\2\] \[ \] Precision \n"; + + if (self.current_way.b_aiflags & AI_SURFACE) + s3 = "\[\3\] \[\{133}\] Surface for air \n"; + else + s3 = "\[\3\] \[ \] Surface for air \n"; + + if (self.current_way.b_aiflags & AI_BLIND) + s4 = "\[\4\] \[\{133}\] Blind mode \n"; + else + s4 = "\[\4\] \[ \] Blind mode \n"; + + if (self.current_way.b_aiflags & AI_JUMP) + s5 = "\[\5\] \[\{133}\] Jump \n"; + else + s5 = "\[\5\] \[ \] Jump \n"; + + if (self.current_way.b_aiflags & AI_DIRECTIONAL) + s6 = "\[\6\] \[\{133}\] Directional \n"; + else + s6 = "\[\6\] \[ \] Directional \n"; + + if (self.current_way.b_aiflags & AI_SUPER_JUMP) + s7 = "\[\7\] \[\{133}\] Super Jump \n\n\[\9\] >>AI Flags page 2 \n\[\0\] >>Main Menu \n"; + else + s7 = "\[\7\] \[ \] Super Jump \n\n\[\9\] >>AI Flags page 2 \n\[\0\] >>Main Menu \n"; + } + else if (self.b_menu == MENU_FLAGS2) + { + if (self.current_way.b_aiflags & AI_DIFFICULT) + s1 = "\b-- AI Flags pg. 2--\b\n\[\1\] \[\{133}\] Difficult \n"; + else + s1 = "\b-- AI Flags pg. 2--\b\n\[\1\] \[ \] Difficult \n"; + + if (self.current_way.b_aiflags & AI_PLAT_BOTTOM) + s2 = "\[\2\] \[\{133}\] Wait for plat \n"; + else + s2 = "\[\2\] \[ \] Wait for plat \n"; + + if (self.current_way.b_aiflags & AI_RIDE_TRAIN) + s3 = "\[\3\] \[\{133}\] Ride train \n"; + else + s3 = "\[\3\] \[ \] Ride train \n"; + + if (self.current_way.b_aiflags & AI_DOOR_NO_OPEN) + s4 = "\[\4\] \[\{133}\] Door flag no open\n"; + else + s4 = "\[\4\] \[ \] Door flag no open\n"; + + if (self.current_way.b_aiflags & AI_AMBUSH) + s5 = "\[\5\] \[\{133}\] Ambush \n"; + else + s5 = "\[\5\] \[ \] Ambush \n"; + + if (self.current_way.b_aiflags & AI_SNIPER) + s6 = "\[\6\] \[\{133}\] Snipe \n"; + else + s6 = "\[\6\] \[ \] Snipe \n"; + + if (self.current_way.b_aiflags & AI_TRACE_TEST) + s7 = "\[\7\] \[\{133}\] Trace Test \n\n\[\9\] >>AI Flag Management \n\[\0\] >>Main Menu \n"; + else + s7 = "\[\7\] \[ \] Trace Test \n\n\[\9\] >>AI Flag Management \n\[\0\] >>Main Menu \n"; + + } + else if (self.b_menu == MENU_BOTS) + { + s1 = "\b-- Bot Management --\b\n\[\1\] Add a Test Bot \n\[\2\] Order Test Bot here \n\[\3\] Remove Test Bot \n\[\4\] Stop Test Bot \n\[\5\] Teleport Bot here \n\[\6\] Teleport to Way # \n\n\n\n\[\0\] >>Main Menu \n"; + } + else if (self.b_menu == MENU_WAYLIST) + { + s1 = "\b-- Waylist Management --\b\n\[\1\] Delete ALL Waypoints \n\[\2\] Dump Waypoints \n\[\3\] Check For Errors \n\[\4\] Save Waypoints \n"; + + if (waypoint_mode == WM_EDITOR_DYNAMIC) + s2 = "\[\5\] \[\{133}\] Dynamic Mode \n\[\6\] \[\{133}\] Dynamic Link \n"; + else if (waypoint_mode == WM_EDITOR_DYNLINK) + s2 = "\[\5\] \[ \] Dynamic Mode \n\[\6\] \[\{133}\] Dynamic Link \n"; + else + s2 = "\[\5\] \[ \] Dynamic Mode \n\[\6\] \[ \] Dynamic Link \n"; + if (dump_mode == 0) + s3 = "\[\7\] \[\{133}\] WAY output \n\[\8\] \[ \] QC output \n\[\9\] \[ \] BSP ents output \n\[\0\] Main Menu \n"; + else if (dump_mode == 1) + s3 = "\[\7\] \[ \] WAY output \n\[\8\] \[\{133}\] QC output \n\[\9\] \[ \] BSP ents output \n\[\0\] Main Menu \n"; + else if (dump_mode == 2) + s3 = "\[\7\] \[ \] WAY output \n\[\8\] \[ \] QC output \n\[\9\] \[\{133}\] BSP ents output \n\[\0\] Main Menu \n"; + + } + else if (self.b_menu == 8) + s1 = "\b-- Link Ways --\b\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 9) + s1 = "\b-- Telelink Ways --\b\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 10) + s1 = "\b-- Delete Link --\b\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 11) + s1 = "\b-- Create Link X2 --\b\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 12) + s1 = "\b-- Delete Link X2 --\b\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 13) + s1 = "\b-- Delete ALL Ways --\b\n\nAre you sure? Push 1 to go\nthrough with it, 2 to cancel"; + else if (self.b_menu == 14) + { + s1 = "\b-- Teleport to Way # --\b\n\nEnter way number and press\nimpulse 104 to warp\n\nWaypoint #"; + s2 = ftos(self.b_menu_value); + + } + else if (self.b_menu == 15) + s1 = "\b-- Delete Waypoint --\b\n\nAre you sure? Push 1 to go\nthrough with it, 2 to cancel"; + else if (self.b_menu == 16) + s1 = "\b-- Unlink Waypoint --\b\n\nAre you sure? Push 1 to go\nthrough with it, 2 to cancel"; + else if (self.b_menu == 17) + s1 = "\b-- Save Waypoints --\b\n\nSave Waypoints requires\nFrikaC's file access tutorial from\nwww.quakesrc.org to be present\n in the engine code.\n Push 1 to continue, 2 to cancel"; + + frik_big_centerprint(self, s1, s2, s3, s4, s5, s6, s7); + self.b_menu_time = time + 1.25; + } +}; + + +// engage menu +void() bot_way_edit = +{ + local entity t; + local float f; + if (self.b_menu_value) + { + if (self.b_menu == 14) + { + t = WaypointForNum(self.b_menu_value); + if (t) + setorigin(self, t.origin - self.view_ofs); + else + sprint(self, "No waypoint with that number\n"); + + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + self.b_menu_value = 0; + return; + } + if (waypoint_mode < WM_EDITOR) + { + self.b_menu = MENU_MAIN; + waypoint_mode = WM_EDITOR; + self.b_menu_time = 0; + cvar_set("saved2", "0"); + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, "MAKE SURE THE FOLLOWING LINE CONTAINS -CONDEBUG BEFORE PROCEEDING\n"); + localcmd("cmdline\n"); + t = way_head; + while (t) + { + setmodel(t, "progs/s_bubble.spr"); // show the waypoints + t = t._next; + } + if (self.current_way) + setmodel(self.current_way, "progs/s_light.spr"); + } + else + { + saved2 = cvar("saved2"); + if (saved2 != 0) + { + f = self.b_menu; + self.b_menu = floor(saved2/16); + self.impulse = saved2 & 15; + bot_menu_display(); + if (self.b_menu == floor(saved2/16)) + self.b_menu = f; + cvar_set("saved2", "0"); + return; + } + self.b_menu = 0; + waypoint_mode = WM_LOADED; + t = way_head; + while (t) + { + setmodel(t, string_null); // hide the waypoints + t = t._next; + } + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Saving to file. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +// bytecount is really iffy +// since there is no true way to determine the length of an ftos +// it uses an approximate of 5 +// various other things are guesses, but I don't cut it at the absolute +// max so it should be okay + +void() PrintWaypoint = +{ + local entity t; + local float needcolon; + local string h; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + if (bytecounter >= 8000) + { + bprint("exec maps/"); + bprint(mapname); + bprint(".wa"); + h = ftos(filecount); + bprint(h); + filecount = filecount + 1; + bprint("\n// **** break here ****\n"); // 2001-09-10 FrikBot support by FrikaC/Maddes + bytecounter = 26; + } + if (t == world) + { + remove(self); + fixer = world; + bprint("saved4 3\n// end waypoint dump\n"); + bytecounter = bytecounter + 27; + return; + } +// 2001-09-10 FrikBot support by FrikaC/Maddes start + t.origin_x = rint(t.origin_x); + t.origin_y = rint(t.origin_y); + t.origin_z = rint(t.origin_z); +// 2001-09-10 FrikBot support by FrikaC/Maddes end + if ((t.origin_x != saved1) || (t.count == 1)) + { + bprint("saved1 "); + h = ftos(t.origin_x); + bprint(h); + saved1 = t.origin_x; + bytecounter = bytecounter + 12; + needcolon = TRUE; + } + if ((t.origin_y != saved2) || (t.count == 1)) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("saved2 "); + h = ftos(t.origin_y); + bprint(h); + bytecounter = bytecounter + 12; + saved2 = t.origin_y; + } + if ((t.origin_z != saved3) || (t.count == 1)) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("saved3 "); + h = ftos(t.origin_z); + bprint(h); + bytecounter = bytecounter + 12; + saved3 = t.origin_z; + } + if (needcolon) // 2001-09-10 FrikBot support by FrikaC/Maddes + { + bytecounter = bytecounter + 1; + bprint("\n"); + needcolon = FALSE; + } + if ((scratch1 != t.target1.count) || t.count == 1) + { + needcolon = TRUE; + bprint("scratch1 "); + bytecounter = bytecounter + 14; + h = ftos(t.target1.count); + bprint(h); + scratch1 = t.target1.count; + } + if ((scratch2 != t.target2.count) || t.count == 1) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("scratch2 "); + bytecounter = bytecounter + 14; + h = ftos(t.target2.count); + bprint(h); + scratch2 = t.target2.count; + } + if ((scratch3 != t.target3.count) || t.count == 1) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("scratch3 "); + bytecounter = bytecounter + 14; + h = ftos(t.target3.count); + bprint(h); + scratch3 = t.target3.count; + } + if ((scratch4 != t.target4.count) || t.count == 1) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("scratch4 "); + bytecounter = bytecounter + 14; + h = ftos(t.target4.count); + bprint(h); + scratch4 = t.target4.count; + } + if (needcolon) // 2001-09-10 FrikBot support by FrikaC/Maddes + { + bprint("\n"); + needcolon = FALSE; + } + bprint("saved4 "); + bytecounter = bytecounter + 19; + if (t.count != 1) + h = ftos(t.b_aiflags * 4 + 2); + else + h = ftos(t.b_aiflags * 4 + 1); + bprint(h); + bprint ("; wait\n"); + self.nextthink = time + 0.01; + self.enemy = t; +}; + +// to allow for 100+ waypoints, we need to trick the runaway loop counter +void() DumpWaypoints = +{ + bytecounter = 50; + filecount = 1; + + bprint("// "); + bprint(world.message); + bprint(" - maps/"); // 2001-09-10 FrikBot support by FrikaC/Maddes + bprint(mapname); + bprint(".way\n"); + bprint("// Ways by "); + bprint(self.netname); + bprint("\n"); + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = PrintWaypoint; + fixer.enemy = world; + } +}; + +void() PrintQCWaypoint = +{ + local entity t; + local string h; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + + if (t == world) + { + remove(self); + fixer = world; + bprint("};\n// End dump\n"); // 2001-09-10 FrikBot support by FrikaC/Maddes + return; + } + bprint(" make_way("); +// 2001-09-10 FrikBot support by FrikaC/Maddes start + t.origin_x = rint(t.origin_x); + t.origin_y = rint(t.origin_y); + t.origin_z = rint(t.origin_z); +// 2001-09-10 FrikBot support by FrikaC/Maddes end + h = vtos(t.origin); + bprint(h); + bprint(", '"); + h = ftos(t.target1.count); + bprint(h); + bprint(" "); + h = ftos(t.target2.count); + bprint(h); + bprint(" "); + h = ftos(t.target3.count); + bprint(h); + bprint("', "); + h = ftos(t.target4.count); + bprint(h); + bprint(", "); + h = ftos(t.b_aiflags); + bprint(h); + bprint(");\n"); + self.nextthink = time + 0.01; + self.enemy = t; + +}; + +void() QCDumpWaypoints = +{ + bprint("/* QC Waypoint Dump - src/frikbot/map_"); + + bprint(mapname); + bprint(".qc\nFor instructions please read the\nreadme.html that comes with FrikBot */\n\nvoid(vector org, vector bit1, float bit4, float flargs) make_way;\n"); + bprint("// Ways by "); + bprint(self.netname); + bprint("\n\n"); + + bprint("void() map_"); + bprint(mapname); + bprint(" =\n{\n"); + + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = PrintQCWaypoint; + fixer.enemy = world; + } +}; + +void() PrintBSPWaypoint = +{ + local entity t; + local string h; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + + if (t == world) + { + bprint("// End dump\n"); // 2001-09-10 FrikBot support by FrikaC/Maddes + remove(self); + fixer = world; + return; + } + bprint("{\n\"classname\" \"waypoint\"\n\"origin\" \""); +// 2001-09-10 FrikBot support by FrikaC/Maddes start + t.origin_x = rint(t.origin_x); + t.origin_y = rint(t.origin_y); + t.origin_z = rint(t.origin_z); +// 2001-09-10 FrikBot support by FrikaC/Maddes end + h = ftos(t.origin_x); + bprint(h); + bprint(" "); + h = ftos(t.origin_y); + bprint(h); + bprint(" "); + h = ftos(t.origin_z); + bprint(h); + if (t.target1.count) + { + bprint("\"\n\"b_pants\" \""); + h = ftos(t.target1.count); + bprint(h); + } + if (t.target2.count) + { + bprint("\"\n\"b_skill\" \""); + h = ftos(t.target2.count); + bprint(h); + } + if (t.target3.count) + { + bprint("\"\n\"b_shirt\" \""); + h = ftos(t.target3.count); + bprint(h); + } + if (t.target4.count) + { + bprint("\"\n\"b_frags\" \""); + h = ftos(t.target4.count); + bprint(h); + } + if (t.b_aiflags) + { + bprint("\"\n\"b_aiflags\" \""); + h = ftos(t.b_aiflags); + bprint(h); + } + bprint("\"\n}\n"); + self.nextthink = time + 0.01; + self.enemy = t; + +}; + +void() BSPDumpWaypoints = +{ + bprint("/* BSP entities Dump - maps/"); + + bprint(mapname); + bprint(".ent\nFor instructions please read the\nreadme.html that comes with FrikBot */\n\n"); // 2001-09-10 FrikBot support by FrikaC/Maddes + + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = PrintBSPWaypoint; + fixer.enemy = world; + } +}; + + +// FrikaC's file access tutorial... +string(string s1, string s2) strcat = #82; +float(string filename, float mode) open = #86; +string(string s) zone = #79; +void(string s) unzone = #80; +void(float handle) close = #87; +void(float handle, string s) write = #89; +float file; + +void() SaveWaypoint = +{ + local entity t; + local float needcolon; + local string h, j, k, l; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + if (bytecounter >= 8000) + { + h = "maps/"; + j = ftos(filecount); + k = h = zone(strcat("maps/", mapname)); + l = h = zone(strcat(h, ".wa")); + unzone(k); + h = zone(strcat(h, j)); + unzone(l); + write(file, "exec "); + write(file, h); + write(file, "\n"); + filecount = filecount + 1; + close(file); + file = open(h, 2); + unzone(h); + if (file == -1) + { + remove(self); + fixer = world; + bprint("Error: failed to save file\n"); + return; + } + bytecounter = 0; + } + if (t == world) + { + remove(self); + fixer = world; + write(file, "saved4 3\n"); + close(file); + bprint("waypoints saved.\n"); + bytecounter = bytecounter + 27; + return; + } +// 2001-09-10 FrikBot support by FrikaC/Maddes start + t.origin_x = rint(t.origin_x); + t.origin_y = rint(t.origin_y); + t.origin_z = rint(t.origin_z); +// 2001-09-10 FrikBot support by FrikaC/Maddes end + if ((t.origin_x != saved1) || (t.count == 1)) + { + write(file, "saved1 "); + h = ftos(t.origin_x); + write(file, h); + saved1 = t.origin_x; + bytecounter = bytecounter + 12; + needcolon = TRUE; + } + if ((t.origin_y != saved2) || (t.count == 1)) + { + if (needcolon) + { + write(file, "; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + write(file, "saved2 "); + h = ftos(t.origin_y); + write(file, h); + bytecounter = bytecounter + 12; + saved2 = t.origin_y; + } + if ((t.origin_z != saved3) || (t.count == 1)) + { + if (needcolon) + { + write(file, "; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + write(file, "saved3 "); + h = ftos(t.origin_z); + write(file, h); + bytecounter = bytecounter + 12; + saved3 = t.origin_z; + } + if (needcolon) // 2001-09-10 FrikBot support by FrikaC/Maddes + { + bytecounter = bytecounter + 1; + write(file, "\n"); + needcolon = FALSE; + } + if ((scratch1 != t.target1.count) || t.count == 1) + { + needcolon = TRUE; + write(file, "scratch1 "); + bytecounter = bytecounter + 14; + h = ftos(t.target1.count); + write(file, h); + scratch1 = t.target1.count; + } + if ((scratch2 != t.target2.count) || t.count == 1) + { + if (needcolon) + { + write(file, "; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + write(file, "scratch2 "); + bytecounter = bytecounter + 14; + h = ftos(t.target2.count); + write(file, h); + scratch2 = t.target2.count; + } + if ((scratch3 != t.target3.count) || t.count == 1) + { + if (needcolon) + { + write(file, "; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + write(file, "scratch3 "); + bytecounter = bytecounter + 14; + h = ftos(t.target3.count); + write(file, h); + scratch3 = t.target3.count; + } + if ((scratch4 != t.target4.count) || t.count == 1) + { + if (needcolon) + { + write(file, "; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + write(file, "scratch4 "); + bytecounter = bytecounter + 14; + h = ftos(t.target4.count); + write(file, h); + scratch4 = t.target4.count; + } + if (needcolon) // 2001-09-10 FrikBot support by FrikaC/Maddes + { + write(file, "\n"); + needcolon = FALSE; + } + write(file, "saved4 "); + bytecounter = bytecounter + 19; + if (t.count != 1) + h = ftos(t.b_aiflags * 4 + 2); + else + h = ftos(t.b_aiflags * 4 + 1); + write(file, h); + write(file, "; wait\n"); + self.nextthink = time + 0.01; + self.enemy = t; +}; + +// to allow for 100+ waypoints, we need to trick the runaway loop counter +void() SaveWays = +{ + local string h, f; + bytecounter = 50; + filecount = 1; + h = strcat("maps/", mapname); + f = h = zone(h); + h = strcat(h, ".way"); + unzone(f); + file = open(h, 2); + if (file == -1) + { + bprint("Error: failed to open file\n"); + return; + } + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = SaveWaypoint; + fixer.enemy = world; + } +}; diff --git a/r17/Revamped src/Revamped QC/frikbot/bot_fight.qc b/r17/Revamped src/Revamped QC/frikbot/bot_fight.qc new file mode 100755 index 00000000..21eb1e50 --- /dev/null +++ b/r17/Revamped src/Revamped QC/frikbot/bot_fight.qc @@ -0,0 +1,472 @@ +/*********************************************** +* * +* FrikBot Fight Code * +* "Because I ain't no Ghandi code" * +* * +***********************************************/ + +/* + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + +.entity avoid; + +float(entity e) bot_size_player = +{ + local float sz; + + sz = e.health + e.armorvalue * e.armortype; + if (e.weapon == 32) + sz = sz + 60; + else if (e.weapon == 64) + sz = sz + 60; + else if (e.weapon == 16) + sz = sz + 50; + else if (e.weapon == 8) + sz = sz + 50; + else if (e.weapon == 4) + sz = sz + 40; + else if (e.weapon == 2) + sz = sz + 40; + else if (e.weapon == 1) + sz = sz + 10; + else if (e.weapon == 4096) + sz = sz - 50; + if (e.items & 4194304) // Quad + sz = sz + 200; + if (e.items & 1048576) // Invul + sz = sz + 300; + if (e.items & 524288) // Invis + sz = sz + 250; + return sz; +}; + +void() bot_dodge_stuff = +{ + local entity foe, head; + local float avdist, foesz, flen, tsz; + local vector v; + + if (waypoint_mode > WM_LOADED) + return; + + self.avoid = world; + + + if (self.enemy) + { + v = self.origin - realorigin(self.enemy); + + foesz = bot_size_player(self.enemy); + foesz = foesz + vlen(v) * 0.5; + } + else + foesz = 9999999; + avdist = 256; + + foe = find(world, classname, "grenade"); + while(foe) + { + flen = vlen(foe.origin - self.origin); + if (flen < avdist) + { + avdist = flen; + self.avoid = foe; + } + foe = find(foe, classname, "grenade"); + } + if (!self.avoid) + { + foe = find(world, classname, "missile"); + while(foe) + { + if (foe.owner != self) + { + flen = vlen(foe.origin - self.origin); + if (flen < avdist) + { + avdist = flen; + self.avoid = foe; + } + } + foe = find(foe, classname, "missile"); + } + if (!self.avoid) + { + foe = find(world, classname, "spike"); + while(foe) + { + if (foe.owner != self) + { + flen = vlen(foe.origin - self.origin); + if (flen < avdist) + { + avdist = flen; + self.avoid = foe; + } + } + foe = find(foe, classname, "spike"); + } + } + } + if (coop) + { + if (!self.enemy) + { + foe = findradius(self.origin, 9999); + while(foe) + { + if(foe.flags & FL_MONSTER) + { + if(foe.health > 0) + { + tsz = bot_size_player(foe) + vlen(foe.origin - self.origin) * 0.5; + if (tsz < foesz) + { + if (fisible(foe)) + { + self.enemy = foe; + foesz = tsz; + } + } + } + } + foe = foe.chain; + } + } + } + else + { + head = findradius(self.origin, 9999); +while(head) +{ + if(head.classname == "Needle-spikes") + { + if(head.health > 0) + { + tsz = bot_size_player(head) + vlen(head.origin - self.origin) * 0.5; + if (tsz < foesz) + { + if (fov(head) || head.b_sound > time || self.b_skill == 3) + { + if (fisible(head)) + { + self.enemy = head; + foesz = tsz; + } + } + } + } + } + head = head.chain; +} + foe = player_head; + while(foe) + { + if(foe != self) + { + if (foe.modelindex != 0) + { + if (foe.health > 0) + { + if (!(teamplay && self.team == foe.team)) + { + tsz = bot_size_player(foe) + vlen(foe.origin - self.origin) * 0.5; + if (tsz < foesz) + { + if (fov(foe) || foe.b_sound > time || self.b_skill == 3) + { + if (fisible(foe)) + { + self.enemy = foe; + foesz = tsz; + } + } + } + } + } + } + } + foe = foe._next; + } + } +}; + + + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +weapon_range + +_x "sweet spot range" - try to maintain this range if possible +_y minimum range bot can be to be effective (rl/gl) (move away) +_z maximum range bot can be to be effective (lg/axe) (move in) +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +vector(float wep) weapon_range = +{ + if (wep == 4096) // IT_AXE + return '48 0 64'; + else if (wep == 1) // IT_SHOTGUN + return '128 0 99999'; + else if (wep == 2) // IT_SUPER_SHOTGUN + return '128 0 99999'; + else if (wep == 4) // IT_NAILGUN + return '180 0 3000'; + else if (wep == 8) // IT_SUPER_NAILGUN + return '180 0 3000'; + else if (wep == 16) // IT_GRENADE_LAUNCHER + return '180 48 3000'; + else if (wep == 32) // IT_ROCKET_LAUNCHER + return '180 48 3000'; + else if (wep == 64) // IT_LIGHTNING + return '350 0 512'; + return '128 0 99999'; + +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_weapon_switch + +Pick a weapon based on range / ammo + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(float brange) bot_weapon_switch = +{ + local float it, flag, pulse; + local vector v; + + it = self.items & 127; + + while(it) + { + if ((self.ammo_rockets >= 1) && (it & 32)) + { + flag = 32; + pulse = 7; + } + else if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & 64)) + { + flag = 64; + pulse = 8; + } + else if(self.ammo_nails >= 2 && (it & 8)) + { + flag = 8; + pulse = 5; + } + else if ((self.ammo_rockets >= 1) && (it & 16)) + { + flag = 16; + pulse = 6; + } + else if(self.ammo_shells >= 2 && (it & 2)) + { + flag = 2; + pulse = 3; + } + else if(self.ammo_nails >= 1 && (it & 4)) + { + flag = 4; + pulse = 4; + } + else if(self.ammo_shells >= 1 && (it & 1)) + { + flag = 1; + pulse = 2; + } + else + { + if (pulse) + self.impulse = pulse; + return; + } + + if (brange == -1) + { + if (pulse) + self.impulse = pulse; + return; + } + + v = weapon_range(flag); + if (brange < v_y || brange > v_z) + it = it - flag; + else + { + if (pulse) + self.impulse = pulse; + return; + } + } +}; + +void() bot_shoot = +{ + // quick little function to stop making him shoot the wrong way ! Argh + local float g; + g = angcomp(self.v_angle_x, self.b_angle_x); + if (fabs(g) > 30) + return; // argh, too far away + g = angcomp(self.v_angle_y, self.b_angle_y); + if (fabs(g) > 30) + return; // not again! + self.button0 = TRUE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot_fight_style + +This is the core of the bot's thinking when +attacking an enemy. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_fight_style = +{ + local vector v, v1, v2, org; + local float foedist, mysz, foesz; + + + if (self.enemy.health <= 0) + { + self.enemy = world; + return; + } + else if (!self.enemy.takedamage) + { + self.enemy = world; + return; + } + else if (!fisible(self.enemy)) + { + self.enemy = world; + return; + } + + org = realorigin(self.enemy); + makevectors(self.v_angle); + + // decide if I should shoot + + foedist = vlen(org - self.origin); + v = weapon_range(self.weapon); + if (foedist > v_y && foedist < v_z) + { + traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * v_z, FALSE, self); + if (vlen(trace_endpos - (self.origin + self.view_ofs)) >= v_y) + { + // try to avoid shooting teammates + if (trace_ent.classname == "player") + if ((trace_ent.team == self.team && teamplay) || (coop)) + return; + bot_shoot(); + } + } + else + bot_weapon_switch(foedist); + + if (!(self.b_aiflags & (AI_PRECISION | AI_BLIND | AI_OBSTRUCTED))) + { + foesz = bot_size_player(self.enemy); + mysz = bot_size_player(self) + 5; + + if (foesz > mysz) + { + if (teamplay) + { + if (random() < 0.02) + { + bot_start_topic(5); + self.b_chattime = 1; + } + } + + return; + } + else if (mysz < 140) + return; + else if (self.avoid) + { + if (self.avoid.velocity) + v = self.avoid.velocity; + else + v = normalize(self.avoid.origin - self.origin); + v1_x = v_y * -1; + v1_y = v_x; + v2_x = v_y; + v2_y = v_x * -1; + foedist = vlen(self.avoid.origin - (self.origin + v1)); + if (foedist < vlen(self.avoid.origin - (self.origin + v2))) + frik_walkmove(v2); + else + frik_walkmove(v1); + } + else if (!self.enemy.flags & FL_MONSTER) + { + if (foedist + 32 < v_x) + frik_walkmove(self.origin - org); + else if (foedist - 32 > v_x) + frik_walkmove(org - self.origin); + else if (self.wallhug) + frik_walkmove(v_right); + else + frik_walkmove(v_right * -1); + } + } + else + { + foesz = bot_size_player(self.enemy); + mysz = bot_size_player(self) + 5; + + if (foesz > mysz) + return; + else if (mysz < 140) + return; + self.keys = self.keys & 960; + } +}; + + diff --git a/r17/Revamped src/Revamped QC/frikbot/bot_misc.qc b/r17/Revamped src/Revamped QC/frikbot/bot_misc.qc new file mode 100755 index 00000000..7d01b5cf --- /dev/null +++ b/r17/Revamped src/Revamped QC/frikbot/bot_misc.qc @@ -0,0 +1,779 @@ +/*********************************************** +* * +* FrikBot Misc Code * +* "Because you can't name it anything else" * +* * +***********************************************/ + +/* +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotName + +Sets bot's name and colors + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +string(float r) BotName = +{ + self.b_num = r; + if (r == 1) + { + self.b_pants = 11; + self.b_shirt = 0; + return "Vincent"; + } + else if (r == 2) + { + self.b_pants = 1; + self.b_shirt = 3; + return "Bishop"; + } + else if (r == 3) + { + self.b_pants = 13; + self.b_shirt = 2; + return "Nomad"; + } + else if (r == 4) + { + self.b_pants = 7; + self.b_shirt = 6; + return "Hudson"; + } + else if (r == 5) + { + self.b_pants = 12; + self.b_shirt = 6; + return "Lore"; + } + else if (r == 6) + { + self.b_pants = 4; + self.b_shirt = 4; + return "Servo"; + } + else if (r == 7) + { + self.b_pants = 2; + self.b_shirt = 5; + return "Gort"; + } + else if (r == 8) + { + self.b_pants = 10; + self.b_shirt = 3; + return "Kryten"; + } + else if (r == 9) + { + self.b_pants = 9; + self.b_shirt = 4; + return "Pimp Bot"; + } + else if (r == 10) + { + self.b_pants = 4; + self.b_shirt = 7; + return "Max"; + } + else if (r == 11) + { + self.b_pants = 3; + self.b_shirt = 11; + return "Marvin"; + } + else if (r == 12) + { + self.b_pants = 13; + self.b_shirt = 12; + return "Erwin"; + } + else if (r == 13) + { + self.b_pants = 11; + self.b_shirt = 2; + return "FrikBot"; + } + else if (r == 14) + { + self.b_pants = 0; + self.b_shirt = 2; + return "Krosis"; + } + else if (r == 15) + { + self.b_pants = 8; + self.b_shirt = 9; + return "Gypsy"; + } + else if (r == 16) + { + self.b_pants = 5; + self.b_shirt = 10; + return "Hal"; + } + return "Noname"; +}; +string () PickARandomName = +{ + if (bot_count > 16) + return "player"; + + local float y, test; + local string h; + local entity t; + y = TRUE; + while(y) + { + test = ceil(random() * 16); + h = BotName(test); + t = find(world, netname, h); + if (t == world) + y = FALSE; + } + return h; +}; + + + +// I didn't like the old code so this is very stripped down + +entity b_originator; +float b_topic; +/* FBX Topics + +b_originator == self + 1 - sign on + 2 - killed targ + 3 - team message "friendly eyes" + 4 - team message "on your back" + 5 - team message "need back up" + 6 - excuses + ---- + 7 - gameover + ---- + 8 - welcoming someone onto server + 9 - ridicule lost frag (killed self?) + 10 - ridicule lost frag (lava) + 11 - lag +b_originator == targ + + +*/ +void(float tpic) bot_start_topic = +{ + if (random() < 0.2) + { + b_topic = tpic; + b_originator = self; + } + else + b_topic = 0; +}; + +void() bot_chat = +{ + local float r; + if (b_options & OPT_NOCHAT) + return; + r = ceil (random() * 6); + + if (self.b_chattime > time) + { + if (self.b_skill < 2) + self.keys = self.button0 = self.button2 = 0; + return; + } + else if (self.b_chattime) + { + if (b_topic == 1) + { + if (b_originator == self) + { + if (r == 1) + { + BotSay(": lo all\n"); + bot_start_topic(8); + } + else if (r == 2) + { + BotSay(": hey everyone\n"); + bot_start_topic(8); + } + else if (r == 3) + { + BotSay(": prepare to be fragged!\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSay(": boy this is laggy\n"); + bot_start_topic(11); + } + else if (r == 5) + { + BotSay(": #mm getting some lag here\n"); + bot_start_topic(11); + } + else + { + BotSay(": hi everyone\n"); + bot_start_topic(8); + } + } + } + else if (b_topic == 2) + { + if (b_originator == self) + { + if (r == 1) + BotSay(": take that\n"); + else if (r == 2) + BotSay(": yehaww!\n"); + else if (r == 3) + BotSay(": wh00p\n"); + else if (r == 4) + BotSay(": j00_sawk();\n"); + else if (r == 5) + BotSay(": i rule\n"); + else + BotSay(": eat that\n"); + bot_start_topic(0); + } + } + else if (b_topic == 3) + { + if (b_originator == self) + { + if (r < 3) + BotSayTeam(": friendly eyes\n"); + else + BotSayTeam(": team eyes\n"); + bot_start_topic(0); + } + } + else if (b_topic == 4) + { + if (b_originator == self) + { + if (r < 3) + BotSayTeam(": on your back\n"); + else + BotSayTeam(": I'm with you\n"); + bot_start_topic(0); + } + } + else if (b_topic == 5) + { + if (b_originator == self) + { + if (r < 3) + BotSayTeam(": I need help\n"); + else + BotSayTeam(": need backup\n"); + bot_start_topic(0); + } + } + else if (b_topic == 6) + { + if (b_originator == self) + { + if (r == 1) + { + BotSay(": sun got in my eyes\n"); + bot_start_topic(0); + } + else if (r == 2) + { + BotSay(": mouse needs cleaning\n"); + bot_start_topic(0); + } + else if (r == 3) + { + BotSay(": i meant to do that\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSay(": lag\n"); + bot_start_topic(11); + } + else if (r == 5) + { + BotSay(": killer lag\n"); + bot_start_topic(11); + } + else + { + BotSay(": 100% lag\n"); + bot_start_topic(11); + } + } + } + else if (b_topic == 7) + { + if (r == 1) + BotSay(": gg\n"); + else if (r == 2) + BotSay(": gg all\n"); + else if (r == 3) + BotSay(": that was fun\n"); + else if (r == 4) + BotSay(": good game\n"); + else if (r == 5) + BotSay(": pah\n"); + else + BotSay(": hrm\n"); + bot_start_topic(0); + } + else if (b_topic == 8) + { + if (b_originator != self) + { + if (r == 1) + { + BotSay(": heya\n"); + bot_start_topic(0); + } + else if (r == 2) + { + BotSay(": welcome\n"); + bot_start_topic(0); + } + else if (r == 3) + { + BotSayInit(); + BotSay2(": hi "); + BotSay2(b_originator.netname); + BotSay2("\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSayInit(); + BotSay2(": hey "); + BotSay2(b_originator.netname); + BotSay2("\n"); + bot_start_topic(0); + } + else if (r == 5) + { + BotSay(": howdy\n"); + bot_start_topic(0); + } + else + { + BotSay(": lo\n"); + bot_start_topic(0); + } + } + } + + else if (b_topic == 9) + { + if (b_originator != self) + { + if (r == 1) + BotSay(": hah\n"); + else if (r == 2) + BotSay(": heheh\n"); + else if (r == 3) + { + BotSayInit(); + BotSay2(": good work "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 4) + { + BotSayInit(); + BotSay2(": nice1 "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 5) + BotSay(": lol\n"); + else + BotSay(": :)\n"); + b_topic = 6; + } + } + else if (b_topic == 10) + { + if (b_originator != self) + { + if (r == 1) + BotSay(": have a nice dip?\n"); + else if (r == 2) + BotSay(": bah I hate levels with lava\n"); + else if (r == 3) + { + BotSayInit(); + BotSay2(": good job "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 4) + { + BotSayInit(); + BotSay2(": nice backflip "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 5) + BotSay(": watch your step\n"); + else + BotSay(": hehe\n"); + b_topic = 6; + } + } + + else if (b_topic == 11) + { + if (b_originator != self) + { + if (r == 1) + { + BotSayInit(); + BotSay2(": yeah right "); + BotSay2(b_originator.netname); + BotSay2("\n"); + bot_start_topic(0); + } + else if (r == 2) + { + BotSay(": ping\n"); + bot_start_topic(0); + } + else if (r == 3) + { + BotSay(": shuddup, you're an lpb\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSay(": lag my eye\n"); + bot_start_topic(0); + } + else if (r == 5) + { + BotSay(": yeah\n"); + bot_start_topic(11); + } + else + { + BotSay(": totally\n"); + bot_start_topic(11); + } + } + } + self.b_chattime = 0; + } + else if (b_topic) + { + if (random() < 0.5) + { + if (self == b_originator) + { + if (b_topic <= 7) + self.b_chattime = time + 2; + } + else + { + if (b_topic >= 7) + self.b_chattime = time + 2; + } + } + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Kick A Bot. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() KickABot = +{ + local entity ty; + ty = find(world, classname, "player"); + while (ty != world) + { + if (!(ty.ishuman)) + { + + BotDisconnect(ty); + ty.ishuman = TRUE; + ty = world; + } + else + ty = find(ty, classname, "player"); + } + +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Simplified origin checking. + +God, I wish I had inline + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +vector(entity ent) realorigin = +{ +// even more simplified... + return (ent.absmin + ent.absmax) * 0.5; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +fisible + +a version of visible that checks for corners +of the bounding boxes + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float (entity targ) fisible = +{ + local vector spot1, org; + local float thruwater, pc1, pc2; + + org = realorigin(targ); + spot1 = self.origin + self.view_ofs; + + if (targ.solid == SOLID_BSP) + { + traceline (spot1, org, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; + } + else + { + pc1 = pointcontents(org); + pc2 = pointcontents(spot1); + if (targ.classname == "player") + thruwater = FALSE; + else if (pc1 == CONTENT_LAVA) + return FALSE; + else + thruwater = TRUE; + } + + if (pc1 < -1) // targ's origin is in water or other liquid + { + if (pc2 != pc1) + { + // look for their head + traceline (spot1, org + targ.mins, TRUE, self); + // cross the water check + if (trace_inopen) + if (trace_inwater) + if (!thruwater) + return FALSE; + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; + } + } + else + { + if (pc2 != pc1) + { + traceline (spot1, org + targ.maxs, TRUE, self); + if (trace_inopen) + if (trace_inwater) + if (!thruwater) + return FALSE; + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; + } + } + traceline (spot1, org, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + traceline (spot1, org + targ.maxs, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + traceline (spot1, org + targ.mins, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Wisible + +goes through movable brushes/entities, used +for waypoints + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +// this is used for waypoint stuff.... +float (entity targ1, entity targ2) wisible = +{ + local vector spot1, spot2; + local entity ignore; + + spot1 = targ1.origin; + spot2 = realorigin(targ2); + + ignore = self; + do + { + traceline (spot1, spot2, TRUE, ignore); + spot1 = realorigin(trace_ent); + ignore = trace_ent; + } while ((trace_ent != world) && (trace_fraction != 1)); + if (trace_endpos == spot2) + return TRUE; + else + return FALSE; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +sisible + +Now this is getting ridiculous. Simple visible, +used when we need just a simple traceline nothing else + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float (entity targ) sisible = +{ + traceline (self.origin, targ.origin, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return TRUE; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +angcomp + +subtracts one angle from another + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float (float y1, float y2) angcomp = +{ + y1 = frik_anglemod(y1); + y2 = frik_anglemod(y2); + + local float answer; + answer = y1 - y2; + if (answer > 180) + answer = answer - 360; + else if (answer < -180) + answer = answer + 360; + return answer; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +fov + +is the entity in the bot's field of view + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float (entity targ) fov = +{ + local vector yawn; + local float g; + yawn = realorigin(targ); + yawn = (yawn + targ.view_ofs) - (self.origin + self.view_ofs); + yawn = normalize(yawn); + yawn = vectoangles(yawn); + g = angcomp(self.v_angle_x, yawn_x); + if (fabs(g) > 45) + return FALSE; + g = angcomp(self.v_angle_y, yawn_y); + if (fabs(g) > 60) + return FALSE; + + return TRUE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +frik_anglemod + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float(float v) frik_anglemod = +{ + return v - floor(v/360) * 360; +} \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/frikbot/bot_move.qc b/r17/Revamped src/Revamped QC/frikbot/bot_move.qc new file mode 100755 index 00000000..cc1e3d9c --- /dev/null +++ b/r17/Revamped src/Revamped QC/frikbot/bot_move.qc @@ -0,0 +1,520 @@ +/*********************************************** +* * +* FrikBot Movement AI * +* "The slightly better movement AI" * +* * +***********************************************/ + +/* + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + +void() bot_jump = +{ + // TODO check for precision, etc. + self.button2 = TRUE; +}; + +float(entity e) bot_can_rj = +{ + // this returns true of the bot can rocket/superjump/hook + // if your mod doesn't have an RL you can just return FALSE all the time + // if it has a hook or some other means for the bot to get to high places + // you can check here for that capability + + // am I dumb? + if (e.b_skill == 0) + return FALSE; + + // quad = bad + if (e.items & 4194304) + return FALSE; + + // do I have rockets & RL? + if (!((e.items & 32) && (e.ammo_rockets > 0))) + return FALSE; + + // do I have pent? + if (e.items & 1048576) + return TRUE; + + if (e.health > 50) + return TRUE; + else + return FALSE; +}; + +float(float flag) frik_recognize_plat = +{ + if ((self.classname != "waypoint") && !(self.flags & FL_ONGROUND)) + return FALSE; + traceline(self.origin, self.origin - '0 0 64', TRUE, self); + if (trace_ent != world) + { + if (flag) // afect bot movement too + { + if (self.keys & KEY_MOVEUP) + { + if (trace_ent.velocity_z > 0) + self.keys = self.keys & 960; // 960 is all view keys + } + else if (self.keys & KEY_MOVEDOWN) + { + if (trace_ent.velocity_z < 0) + self.keys = self.keys & 960; + } + } + return TRUE; + } + else + return FALSE; +}; + +float(vector sdir) frik_KeysForDir = +{ + + local vector keydir; + local float outkeys, tang; + outkeys = 0; + if (sdir_x || sdir_y) + { + // Everything is tested against 60 degrees, + // this allows the bot to overlap the keys + // 30 degrees on each diagonal 45 degrees + // might look more realistic + + keydir = vectoangles(sdir); + tang = angcomp(keydir_y, self.v_angle_y); + if ((tang <= 150) && (tang >= 30)) + outkeys = outkeys + KEY_MOVELEFT; + else if ((tang >= -150) && (tang <= -30)) + outkeys = outkeys + KEY_MOVERIGHT; + if (fabs(tang) <= 60) + outkeys = outkeys + KEY_MOVEFORWARD; + else if (fabs(tang) >= 120) + outkeys = outkeys + KEY_MOVEBACK; + } + if (sdir_z > 0) + outkeys = outkeys + KEY_MOVEUP; + else if (sdir_z < 0) + outkeys = outkeys + KEY_MOVEDOWN; + return outkeys; + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +frik_obstructed + +Bot has hit a ledge or wall that he should +manuever around. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(vector whichway, float danger) frik_obstructed = +{ + local float dist; + local vector disway, org; +// TODO: something + if (self.b_aiflags & AI_BLIND) + return; + org = realorigin(self.target1); + + if (danger) + { + self.b_aiflags = self.b_aiflags | AI_DANGER; + self.keys = frik_KeysForDir('0 0 0' - whichway); + } + if (self.b_aiflags & AI_PRECISION) + return; + + + if (self.target1) + { + if (self.b_aiflags & AI_OBSTRUCTED) + { + if (!(self.b_aiflags & AI_DANGER)) + { + self.b_aiflags = self.b_aiflags - AI_OBSTRUCTED; + return; + } + else if (!danger) + return; + } + self.obs_dir = whichway; + disway_x = whichway_y * -1; + disway_y = whichway_x; + dist = vlen(org - (self.origin + disway)); + disway_x = whichway_y; + disway_y = whichway_x * -1; + self.wallhug = vlen(org - (self.origin + disway)) > dist; + self.b_aiflags = self.b_aiflags | AI_OBSTRUCTED; + + } + else + { + disway_x = whichway_y * -1; + disway_y = whichway_x; + dist = vlen(disway - self.obs_dir); + disway_x = whichway_y; + disway_y = whichway_x * -1; + self.wallhug = vlen(disway - self.obs_dir) < dist; + self.obs_dir = whichway; + + self.b_aiflags = self.b_aiflags | AI_OBSTRUCTED; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +frik_obstacles + +Detects small bumps the bot needs to jump over +or ledges the bot should avoid falling in. + +Also responsible for jumping gaps. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_obstacles = +{ + local vector start, stop, ang; + local float test, conts, dist, hgt; + + if (!(self.flags & FL_ONGROUND)) + return; + if (self.b_aiflags & AI_BLIND) + return; + + ang = normalize(self.velocity); + ang_z = 0; + start = self.origin + ang * 32; // ahem + start_z = self.origin_z + self.maxs_z; + stop = start; + stop_z = self.origin_z + self.mins_z; + traceline(start, stop - '0 0 256', TRUE, self); + if (trace_allsolid || trace_startsolid) + return; + hgt = trace_endpos_z - stop_z; + + if (hgt > 18) + { + bot_jump(); + return; + } + if (hgt >= 0) + return; + + conts = pointcontents(trace_endpos + '0 0 4'); + start = stop - '0 0 8'; + stop = start + ang * 256; + traceline(start, stop, TRUE, self); + test = vlen(trace_endpos - start); + if (test <= 20) + return; // it's a walkable gap, do nothing + ang_x = self.velocity_y * -1; + ang_y = self.velocity_x; + ang = normalize(ang); + traceline(start - (ang * 10), start + (ang * 10), TRUE, self); + if ((trace_fraction != 1) || trace_startsolid) + return; // gap is only 20 wide, walkable + ang = self.velocity; + ang_z = 0; + dist = ((540 / sv_gravity) * vlen(ang))/* + 32*/; + if (test > dist) // I can't make it + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + else + { + if (self.target1) + { + stop = realorigin(self.target1); + if ((stop_z - self.origin_z) < -32) + return; // safe to fall + } + frik_obstructed(ang, FALSE); + return; + } + } + else + { + ang = normalize(ang); + //look for a ledge + traceline(self.origin, self.origin + (ang * (test + 20)), TRUE, self); + if (trace_fraction != 1) + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + else + { + if (self.target1) + { + stop = realorigin(self.target1); + if ((stop_z - self.origin_z) < -32) + return; // safe to fall + } + frik_obstructed(ang, FALSE); + return; + } + } + + if (self.target1) + { + // getting furter away from my target? + test = vlen(self.target1.origin - (ang + self.origin)); + if (test > vlen(self.target1.origin - self.origin)) + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + else + { + frik_obstructed(ang, FALSE); + return; + } + } + } + } + if (hgt < -18) + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + if (self.target1) + { + stop = realorigin(self.target1); + if ((stop_z - self.origin_z) < -32) + { + + return; // safe to fall + } + } + bot_jump(); + } + // go for it +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +After frik_obstructed, the bot uses the +following funtion to move "around" the obstacle + +I have no idea how well it will work + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_dodge_obstruction = +{ + local vector way, org; + local float oflags, yaw; + + if (!(self.b_aiflags & AI_OBSTRUCTED)) + return; + if ((self.b_aiflags & (AI_BLIND | AI_PRECISION)) || !(self.flags & FL_ONGROUND)) + { + self.b_aiflags = self.b_aiflags - AI_OBSTRUCTED; + return; + } + + // perform a walkmove check to see if the obs_dir is still obstructed + // walkmove is less forgiving than frik_obstacles, so I dunno + // how well this will work + + oflags = self.flags; + org = self.origin; + + yaw = vectoyaw(self.obs_dir); + if (walkmove(yaw, 32)) + self.b_aiflags = self.b_aiflags - AI_OBSTRUCTED; + else + { + if (self.b_aiflags & AI_DANGER) + { + way = '0 0 0' - self.obs_dir; + } + else if (self.wallhug) + { + way_x = self.obs_dir_y * -1; + way_y = self.obs_dir_x; + } + else + { + way_x = self.obs_dir_y; + way_y = self.obs_dir_x * -1; + } + self.keys = self.keys & 960 + frik_KeysForDir(way); + } + + // fix the bot + + self.origin = org; + self.flags = oflags; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +movetogoal and walkmove replacements + +blah + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_movetogoal = +{ + local vector way/*, start, stop, ang*/; + local float g; + + if (self.target1 == world) + { + makevectors(self.v_angle); + frik_walkmove(v_forward); + return; + } + way = realorigin(self.target1) - self.origin; + if (vlen(way) < 25) + { + self.keys = self.keys & 960; + return; + } + + way = normalize(way); + self.keys = self.keys & 960 + frik_KeysForDir(way); + + frik_dodge_obstruction(); + frik_recognize_plat(TRUE); + + if (self.b_aiflags & AI_PRECISION) + { + g = angcomp(self.v_angle_x, self.b_angle_x); + if (fabs(g) > 10) + self.keys = self.keys & 960; + g = angcomp(self.v_angle_y, self.b_angle_y); + if (fabs(g) > 10) + self.keys = self.keys & 960; + } +}; + +float(vector weird) frik_walkmove = +{ + // okay so it's not walkmove + // sue me + self.keys = self.keys & 960 + frik_KeysForDir(weird); + + frik_dodge_obstruction(); + frik_recognize_plat(TRUE); + if (self.b_aiflags & AI_OBSTRUCTED) + return FALSE; + else + return TRUE; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +The "hook" method of navigation. This nav +system is copyrighted 1999 by Ryan "Frika C" +Smith, keep that in mind when you steal it. + +I brought this back because normal roaming +won't work - the bot gets distracted by it's +own waypoints. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_bot_roam = +{ + local vector org, ang, org1; + local float loopcount, flag, dist; + + loopcount = 26; + flag = FALSE; + while((loopcount > 0) && !flag) + { + loopcount = loopcount - 1; + org = self.origin + self.view_ofs; + ang = self.angles; + ang_y = frik_anglemod(ang_y - 90 + (random() * 180)); + ang_x = 0; // avoid upward sloping + makevectors(ang); + traceline(org, org + v_forward * 2300, TRUE, self); + if (trace_fraction != 1) + { + org1 = trace_endpos; + ang = normalize(trace_plane_normal); + ang_z = 0; // avoid upward sloping + traceline(org1, org1 + (ang * 2300), TRUE, self); + if ((trace_fraction != 1) && (vlen(trace_endpos - org1) >= 64)) + { + org = trace_endpos; + traceline(org, self.origin + self.view_ofs, TRUE, self); + if (trace_fraction != 1) + { + dist = vlen(org1 - org) /2; + org = org1 + (ang * dist); + traceline(org, org - '0 0 48', TRUE, self); + if (trace_fraction != 1) + { + SpawnTempWaypoint(org); + flag = TRUE; + } + } + } + } + } + self.b_angle_y = self.v_angle_y + 10; + frik_walkmove(v_forward); +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/frikbot/bot_phys.qc b/r17/Revamped src/Revamped QC/frikbot/bot_phys.qc new file mode 100755 index 00000000..3dc3c8d2 --- /dev/null +++ b/r17/Revamped src/Revamped QC/frikbot/bot_phys.qc @@ -0,0 +1,681 @@ +/*********************************************** +* * +* FrikBot Physics * +* The near-perfect emulation of * +* Client movement * +* * +* Special Thanks to: Asdf, Frog * +* Alan "Strider" Kivlin * +* * +* * +***********************************************/ + +/* + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + +/* +========================================= + +Stuff mimicking cl_input.c code + +========================================= +*/ +float(float key) CL_KeyState = +{ + return ((self.keys & key) > 0); +}; + +void() CL_KeyMove = // CL_BaseMove + CL_AdjustAngles +{ + local float anglespeed; + local vector view; + if (self.keys != self.oldkeys) + { + self.movevect = '0 0 0'; + self.movevect_y = self.movevect_y + (350 * CL_KeyState(KEY_MOVERIGHT)); + // 350 is the default cl_sidespeed + self.movevect_y = self.movevect_y - (350 * CL_KeyState(KEY_MOVELEFT)); + // 350 is the default cl_sidespeed + self.movevect_x = self.movevect_x + (200 * CL_KeyState(KEY_MOVEFORWARD)); + // 200 is the default cl_forwardspeed + self.movevect_x = self.movevect_x - (200 * CL_KeyState(KEY_MOVEBACK)); + // 200 is the default cl_backspeed + self.movevect_z = self.movevect_z + (200 * CL_KeyState(KEY_MOVEUP)); + // 200 is the default cl_upspeed + self.movevect_z = self.movevect_z - (200 * CL_KeyState(KEY_MOVEDOWN)); + // 200 is the default cl_upspeed + if (!self.b_aiflags & AI_PRECISION) + self.movevect = self.movevect * 2; + // 2 is the default cl_movespeedkey & bot always has +speed + } + self.oldkeys = self.keys; + + if (self.b_skill != 2) // use mouse emulation + { + anglespeed = 1.5 * real_frametime; + // 1.5 is the default cl_anglespeedkey & bot always has +speed + self.v_angle_y = self.v_angle_y + anglespeed * CL_KeyState(KEY_LOOKLEFT) * 140; + // 140 is default cl_yawspeed + self.v_angle_y = self.v_angle_y - anglespeed * CL_KeyState(KEY_LOOKRIGHT) * 140; + // 140 is default cl_yawspeed + self.v_angle_x = self.v_angle_x - anglespeed * CL_KeyState(KEY_LOOKUP) * 150; + // 150 is default cl_pitchspeed + self.v_angle_x = self.v_angle_x + anglespeed * CL_KeyState(KEY_LOOKDOWN) * 150; + // 150 is default cl_pitchspeed + } + else + { + view_x = angcomp(self.b_angle_x, self.v_angle_x); + view_y = angcomp(self.b_angle_y, self.v_angle_y); + if (vlen(view) > 30) + { + self.mouse_emu = self.mouse_emu + (view * 30); + if (vlen(self.mouse_emu) > 180) + self.mouse_emu = normalize(self.mouse_emu) * 180; + } + else + self.mouse_emu = view * (1 / real_frametime); + self.v_angle = self.v_angle + self.mouse_emu * real_frametime; + + + } + if (self.v_angle_x > 80) + self.v_angle_x = 80; + else if (self.v_angle_x < -70) + self.v_angle_x = -70; + + if (self.v_angle_z > 50) + self.v_angle_z = 50; + else if (self.v_angle_z < -50) + self.v_angle_z = -50; + self.v_angle_y = frik_anglemod(self.v_angle_y); + +}; + +/* +========================================= + +Stuff mimicking sv_user.c + +========================================= +*/ +void() SV_UserFriction = +{ + local vector vel, start, stop; + local float sped, friction, newspeed; + + vel = self.velocity; + vel_z =0; + sped = vlen(vel); + vel = self.velocity; + + if (!sped) + return; + +// if the leading edge is over a dropoff, increase friction + + start_x = stop_x = self.origin_x + vel_x / (sped * 16); + start_y = stop_y = self.origin_y + vel_y / (sped * 16); + start_z = self.origin_z + self.mins_z; + stop_z = start_z - 34; + + traceline(start, stop, TRUE, self); + + if (trace_fraction == 1) + friction = sv_friction * 2; // 2 is default edgefriction, removed for QW compatability + else + friction = sv_friction; + if (sped < sv_stopspeed) + newspeed = sped - real_frametime * sv_stopspeed * friction; + else + newspeed = sped - real_frametime * sped * friction; + + if (newspeed < 0) + newspeed = 0; + newspeed = newspeed / sped; + + self.velocity_y = vel_y * newspeed; + self.velocity_x = vel_x * newspeed; +}; +void() SV_WaterJump = +{ + if (time > self.teleport_time || !self.waterlevel) + { + self.flags = self.flags - (self.flags & FL_WATERJUMP); + self.teleport_time = 0; + } + self.velocity_x = self.movedir_x; + self.velocity_y = self.movedir_y; +}; + +void() DropPunchAngle = +{ + local float len; + len = vlen(self.punchangle); + self.punchangle = normalize(self.punchangle); + len = len - 10 * real_frametime; + if (len < 0) + len = 0; + self.punchangle = self.punchangle * len; +}; + + +void(vector wishvel) SV_AirAccelerate = +{ + local float addspeed, wishspd, accelspeed, currentspeed; + + wishspd = vlen(wishvel); + wishvel = normalize(wishvel); + if (wishspd > 30) + wishspd = 30; + currentspeed = self.velocity * wishvel; + addspeed = wishspd - currentspeed; + if (addspeed <= 0) + return; + accelspeed = 10 * sv_accelerate * wishspd * real_frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + self.velocity = self.velocity + accelspeed * wishvel; +}; + +void(vector wishvel) SV_Accelerate = +{ + local float addspeed, wishspd, accelspeed, currentspeed; + + wishspd = vlen(wishvel); + wishvel = normalize(wishvel); + + currentspeed = self.velocity * wishvel; + addspeed = wishspd - currentspeed; + if (addspeed <= 0) + return; + accelspeed = sv_accelerate * wishspd * real_frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + self.velocity = self.velocity + accelspeed * wishvel; +}; +void() SV_WaterMove = +{ + local vector wishvel; + local float wishspeed, addspeed, cspeed, newspeed; + makevectors(self.v_angle); + wishvel = v_right * self.movevect_y + v_forward * self.movevect_x; + + if (self.movevect == '0 0 0') + wishvel_z = wishvel_z - 60; + else + wishvel_z = wishvel_z + self.movevect_z; + wishspeed = vlen(wishvel); + + if (wishspeed > sv_maxspeed) + { + wishvel = (sv_maxspeed / wishspeed) * wishvel; + wishspeed = sv_maxspeed; + } + wishspeed = wishspeed * 0.7; + cspeed = vlen(self.velocity); + if (cspeed) + { + newspeed = cspeed - (real_frametime * cspeed * sv_friction); + if (newspeed < 0) + newspeed = 0; + self.velocity = self.velocity * (newspeed / cspeed); + + } + else + newspeed = 0; + + if (!wishspeed) + return; + addspeed = wishspeed - newspeed; + if (addspeed <= 0) + return; + wishvel = normalize(wishvel); + cspeed = sv_accelerate * wishspeed * real_frametime; + if (cspeed > addspeed) + cspeed = addspeed; + self.velocity = self.velocity + cspeed * wishvel; +}; +void() SV_AirMove = +{ + local vector wishvel, vangle; + + vangle = self.v_angle; + vangle_x = vangle_z = 0; + makevectors(vangle); + if (time < self.teleport_time && (self.movevect_x < 0)) + self.movevect_x = 0; + wishvel = v_right * self.movevect_y + v_forward * self.movevect_x; + + + if (self.movetype != MOVETYPE_WALK) + wishvel_z = self.movevect_z; + else + wishvel_z = 0; + if (vlen(wishvel) > sv_maxspeed) + wishvel = normalize(wishvel) * sv_maxspeed; + if (self.movetype == MOVETYPE_NOCLIP) + self.velocity = wishvel; + else if (self.flags & FL_ONGROUND) + { + SV_UserFriction(); + SV_Accelerate(wishvel); + } + else + SV_AirAccelerate (wishvel); +}; + +void() SV_ClientThink = +{ + local vector vangle; + + if (self.movetype == MOVETYPE_NONE) + return; + DropPunchAngle(); + if (self.health <= 0) + return; + self.v_angle_z = 0; // V_CalcRoll removed, sucks + self.angles_z = self.v_angle_z * 4; + vangle = self.v_angle + self.punchangle; + if (!self.fixangle) + { + self.angles_x = (vangle_x / -3); + self.angles_y = vangle_y; + } else + { + self.v_angle = self.angles; + self.fixangle = 0; + } + if (self.flags & FL_WATERJUMP) + { + SV_WaterJump(); + return; + } + if ((self.waterlevel >= 2) && (self.movetype != MOVETYPE_NOCLIP)) + { + SV_WaterMove(); + return; + } + SV_AirMove(); + +}; +/* +========================================= + +Stuff mimicking sv_phys.c + +========================================= +*/ + +float() SV_RunThink = +{ + local float thinktime, bkuptime; + thinktime = self.nextthink; + bkuptime = time; + if (thinktime <= 0 || thinktime > (time + real_frametime)) + return TRUE; + if (thinktime < time) + thinktime = time; + self.nextthink = 0; + time = thinktime; + other = world; + makevectors(self.v_angle); // hack + self.think(); + time = bkuptime; + return TRUE; +}; + +void(float scale) SV_AddGravity = +{ + self.velocity_z = self.velocity_z - (scale * sv_gravity * real_frametime); +}; + +float() SV_CheckWater = +{ + local vector point; + local float cont; + + point_x = self.origin_x; + point_y = self.origin_y; + self.waterlevel = 0; + self.watertype = CONTENT_EMPTY; + point_z = self.origin_z + self.mins_z + 1; + cont = pointcontents(point); + if (cont <= CONTENT_WATER) + { + self.watertype = cont; + self.waterlevel = 1; + point_z = self.origin_z + (self.mins_z + self.maxs_z) * 0.5; + cont = pointcontents(point); + if (cont <= CONTENT_WATER) + { + self.waterlevel = 2; + point_z = self.origin_z + self.view_ofs_z; + cont = pointcontents(point); + if (cont <= CONTENT_WATER) + self.waterlevel = 3; + } + } + return (self.waterlevel > 1); + +}; +void() RemoveThud = // well sometimes +{ + local entity oself; + if (other == world) + { + if (self.flags & FL_ONGROUND) + { + self.flags = self.flags - FL_ONGROUND; + } + } + else + { + if (other.solid == SOLID_BSP && (self.flags & FL_ONGROUND)) + { + // RM: Does this break anything? + // If not, then some more thuds have been removed. + self.flags = self.flags - FL_ONGROUND; + } + if (other == self.owner) + return; + if (self.owner.solid == SOLID_NOT) + return; + oself = other; + other = self.owner; + self = oself; + if (self.solid == SOLID_BSP) + if (self.touch) + self.touch(); + } + +}; +void() SV_CheckOnGround = +{ + local vector org, v; + org = self.origin; + local float currentflags; + currentflags = self.flags; + self.flags = self.flags | FL_ONGROUND | FL_PARTIALGROUND; + walkmove(0,0); // perform C touch function + self.flags = currentflags | FL_ONGROUND; + if ((org_x != self.origin_x) || (org_y != self.origin_y)) + org = self.origin; + else + self.origin = org; + v = org; + v_z = self.maxs_z + org_z + 1; + traceline (org, v, TRUE, self); + if ((self.waterlevel == 3) && (self.movetype == MOVETYPE_WALK)) + self.flags = self.flags - FL_ONGROUND; + else if ((trace_plane_normal_z <= 0.7) && (trace_fraction != 1)) + self.flags = self.flags - FL_ONGROUND; + else if (!droptofloor(/*0,0*/)) + self.flags = self.flags - FL_ONGROUND; + else if (org_z - self.origin_z < 2) + self.flags = self.flags | FL_ONGROUND; + else + self.flags = self.flags - FL_ONGROUND; + setorigin(self, org); +}; +// Thanks to Alan Kivlin for this function +// modified heavily by me +float(vector dir) botCheckForStep = +{ + local vector currentorigin, v; + local float currentflags, yaw, stepdistance, movedistance; + currentorigin = self.origin; + currentflags = self.flags; + self.flags = FL_ONGROUND | FL_PARTIALGROUND; + dir = normalize(dir); + dir_z = 0; + yaw = vectoyaw(dir); + if(walkmove(yaw, 3)) + { + if(droptofloor(/*0,0*/)) + { + stepdistance = self.origin_z - currentorigin_z; + v = self.origin - currentorigin; + v_z = 0; + movedistance = vlen(v); + if((stepdistance > 0 && stepdistance <= 16) && movedistance != 0) + { + self.flags = currentflags | FL_PARTIALGROUND; + return 1; + } + } + } + self.flags = currentflags; + v = currentorigin; + v_z = self.origin_z; + if (vlen(v - self.origin) <= 4) + setorigin(self, currentorigin); + return 0; +}; +// this is merely here to fix a problem with e3m5 +void(vector dir) BruteForceStep = +{ + local vector currentorigin; + local float currentflags, i, len; + + currentorigin = self.origin; + currentflags = self.flags; + len = vlen(dir); + if (len > 16) + dir = normalize(dir) * 16; + + setorigin(self, currentorigin + dir); + + while(i < 18 && !walkmove(0, 0)) + { + self.origin_z = currentorigin_z + i; + i = i + 2; + } + self.flags = currentflags; + if (i >=18) + setorigin(self, currentorigin); +}; + +void() PostPhysics = +{ + local vector obstr, org; + local float back, dst,cflags; + + self = self.owner; + + self.velocity = self.velocity - self.phys_obj.dest1 + self.phys_obj.velocity; + if (self.phys_obj.dest2 == self.origin) + { + setorigin(self, self.phys_obj.origin); + // might've been moved during other person's physics + // (teleporters / plats) + + if (self.movetype == MOVETYPE_WALK) + { + + if (self.phys_obj.dest1_x || self.phys_obj.dest1_y) + { + if ((self.flags & FL_ONGROUND) || (self.waterlevel <= 2)) + { + obstr = self.phys_obj.movedir - self.origin; + obstr_z = 0; + if (vlen(obstr) > 0.1) + { + dst = vlen(obstr); + back = vectoyaw(obstr); + cflags = self.flags; + self.flags = self.flags | FL_PARTIALGROUND; + if(walkmove(back, dst)) + { + self.flags = cflags; + self.phys_obj.dest1_z = 0; + self.velocity = self.velocity + self.phys_obj.dest1 - self.phys_obj.velocity; + } + else + { + if (dst > 1) + frik_obstructed(obstr, FALSE); + + org = self.origin; + self.flags = cflags; + obstr = self.phys_obj.dest1; + obstr_x = 0; + if (!botCheckForStep(obstr)) + { + obstr = self.phys_obj.dest1; + obstr_y = 0; + if (!botCheckForStep(obstr)) + { + // if no steps were found, bot is really obstucted + BruteForceStep(self.phys_obj.dest1); + } + } + } + } + } + } + } + } + + SV_CheckOnGround(); + + PlayerPostThink(); + BotAI(); + self.dmg_take = self.dmg_save = 0; + +}; +// Avoid calling BotAI and the physics at the same time +// Can trip the runaway loop counter + +void() SV_FlyMove = +{ + // This is nothing like the Quake function. + + if (self.phys_obj == world) + { + self.phys_obj = find(world,classname,"phys_obj"); + while (self.phys_obj.owner != self) + { + self.phys_obj = find(self.phys_obj,classname,"phys_obj"); + if (self.phys_obj == world) + { + error("No physics entity spawned!\nMake sure BotInit was called\n"); + } + } + } + + setmodel (self.phys_obj, string_null); + self.phys_obj.movetype = MOVETYPE_STEP; + + self.phys_obj.solid = SOLID_TRIGGER; + self.phys_obj.touch = RemoveThud; + setsize(self.phys_obj, self.mins, self.maxs); + self.phys_obj.dest2 = self.phys_obj.origin = self.origin; + self.phys_obj.watertype = 0; + self.phys_obj.movedir = self.origin + real_frametime * self.velocity; + self.phys_obj.dest1 = self.phys_obj.velocity = self.velocity; + self.phys_obj.velocity_z = self.phys_obj.velocity_z + sv_gravity * real_frametime; + self.phys_obj.flags = 0; + self.phys_obj.think = PostPhysics; + self.phys_obj.nextthink = time; +}; + + +void() SV_Physics_Toss = +{ + if (!SV_RunThink()) + return; + if (self.flags & FL_ONGROUND) + { + self.velocity = '0 0 0'; + BotAI(); + return; + } + if (self.movetype != MOVETYPE_FLY) + SV_AddGravity(1); + self.angles = self.angles + real_frametime * self.avelocity; + SV_FlyMove(); + +}; +void() SV_Physics_Client = +{ + + PlayerPreThink(); + + if (self.movetype == MOVETYPE_NONE) + { + if (!SV_RunThink()) + return; + PlayerPostThink(); + BotAI(); + + } + else if ((self.movetype == MOVETYPE_WALK) || (self.movetype == MOVETYPE_STEP)) + { + if (!SV_RunThink()) + return; + if (!(SV_CheckWater()) && (!(self.flags & FL_WATERJUMP))) + SV_AddGravity(1); + SV_FlyMove(); + } + else if ((self.movetype == MOVETYPE_TOSS) || (self.movetype == MOVETYPE_BOUNCE)) + { + SV_Physics_Toss(); + } + else if (self.movetype == MOVETYPE_FLY) + { + if (!SV_RunThink()) + return; + SV_FlyMove(); + } + else if (self.movetype == MOVETYPE_NOCLIP) + { + if (!SV_RunThink()) + return; + self.origin = self.origin + real_frametime * self.velocity; + + PlayerPostThink(); + BotAI(); + } + else + error ("SV_Physics_Client: Bad Movetype (BOT)"); + +}; + + \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/frikbot/bot_qw.qc b/r17/Revamped src/Revamped QC/frikbot/bot_qw.qc new file mode 100755 index 00000000..fc5798b6 --- /dev/null +++ b/r17/Revamped src/Revamped QC/frikbot/bot_qw.qc @@ -0,0 +1,964 @@ + +/* +====================================== +FrikBot X (Version 0.10.2) QW +====================================== + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + + +====================================== +These installation instructions only apply to QuakeWorld (as does this entire +file). For Normal Quake, please refer to bot.qc + +-------------------------------------- +To install on a new mod, do all this: +-------------------------------------- +Place all included bot*.qc files in the subdirectory "frikbot" +in your source folder, then... + +* Add the following lines to progs.src right after the defs.qc line +frikbot/bot_qw.qc +frikbot/bot_way.qc +frikbot/bot_fight.qc +frikbot/bot_ai.qc +frikbot/bot_misc.qc +frikbot/bot_phys.qc +frikbot/bot_move.qc +-------------------------------------- +* Comment out the following functions in defs.qc +sound, stuffcmd, sprint, aim, centerprint, setspawnparms +WriteByte, WriteChar, WriteShort, WriteLong, WriteCoord +WriteAngle, WriteString, WriteEntity +-------------------------------------- +* Add this to worldspawn() in world.qc, right at the very top, before InitBodyQue(); +BotInit(); // FrikBot +-------------------------------------- +* add this line to StartFrame() in world.qc, at the very top +BotFrame(); // FrikBot +-------------------------------------- +* Add these two lines to PlayerPreThink in client.qc at the very top +if (BotPreFrame()) // FrikBot + return; +-------------------------------------- +* Add this line to PlayerPostThink in client.qc at the very top +if (BotPostFrame()) // FrikBot + return; +-------------------------------------- +* Add the following line to the very top of Client Connect in client.qc +ClientInRankings(); // FrikBot +-------------------------------------- +* Add these lines to the very top of ClientDisconnect in client.qc +ClientDisconnected(); // FrikBot +-------------------------------------- +* Add these lines to the very top of SpectatorConnect in spectate.qc +ClientFixRankings(); // FrikBot +-------------------------------------- + +To install the waypoints: + +add + +waypoints/map_dm1.qc +waypoints/map_dm2.qc +waypoints/map_dm3.qc +waypoints/map_dm4.qc +waypoints/map_dm5.qc +waypoints/map_dm6.qc + +To progs.src, immediately after defs.qc + +To remove these waypoints: + +Delete the code in bot_map_load, located below. +*/ + +void() bot_map_load = +{ + // place your qc loaded waypoints here + + if (mapname == "dm1") + map_dm1(); + else if (mapname == "dm2") + map_dm2(); + else if (mapname == "dm3") + map_dm3(); + else if (mapname == "dm4") + map_dm4(); + else if (mapname == "dm5") + map_dm5(); + else if (mapname == "dm6") + map_dm6(); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Variables and shtuff + +bot.qc has become pretty much a header file +for all variable in the bot... + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +// ----- entity fields --- +.float wallhug, keys, oldkeys, ishuman; +.float b_frags, b_clientno, b_shirt, b_pants; +.float priority, ai_time, b_sound, missile_speed; +.float portal_time, b_skill, switch_wallhug; +.float b_aiflags, b_num, b_chattime; +.float b_entertime, b_userid; // QW shtuff +.float b_menu, b_menu_time, b_menu_value; +.float route_failed, dyn_flags, dyn_time; +.float dyn_plat; +.entity temp_way, last_way, phys_obj; +.entity target1, target2, target3, target4; +.entity _next, _last; +.entity current_way; +.vector b_angle, b_dest, mouse_emu, obs_dir; +.vector movevect, b_dir; +.vector dyn_dest; +.vector punchangle; // HACK - Don't want to screw with bot_phys + +// --------defines----- +float SVC_UPDATENAME = 13; +float SVC_UPDATEFRAGS = 14; +float SVC_UPDATECOLORS = 17; + +// used for the physics & movement AI +float KEY_MOVEUP = 1; +float KEY_MOVEDOWN = 2; +float KEY_MOVELEFT = 4; +float KEY_MOVERIGHT = 8; +float KEY_MOVEFORWARD = 16; +float KEY_MOVEBACK = 32; +float KEY_LOOKUP = 64; +float KEY_LOOKDOWN = 128; +float KEY_LOOKLEFT = 256; +float KEY_LOOKRIGHT = 512; + +// these are aiflags for waypoints +// some overlap to the bot +float AI_TELELINK_1 = 1; // link type +float AI_TELELINK_2 = 2; // link type +float AI_TELELINK_3 = 4; // link type +float AI_TELELINK_4 = 8; // link type +float AI_DOORFLAG = 16; // read ahead +float AI_PRECISION = 32; // read ahead + point +float AI_SURFACE = 64; // point +float AI_BLIND = 128; // read ahead + point +float AI_JUMP = 256; // point + ignore +float AI_DIRECTIONAL = 512; // read ahead + ignore +float AI_PLAT_BOTTOM = 1024; // read ahead +float AI_RIDE_TRAIN = 2048; // read ahead +float AI_SUPER_JUMP = 4096; // point + ignore + route test +float AI_SNIPER = 8192; // point type +float AI_AMBUSH = 16384; // point type +float AI_DOOR_NO_OPEN = 32768; // read ahead +float AI_DIFFICULT = 65536; // route test +float AI_TRACE_TEST = 131072; // route test + +// these are flags for bots/players (dynamic/editor flags) +float AI_OBSTRUCTED = 1; +float AI_HOLD_SELECT = 2; +float AI_ROUTE_FAILED = 2; +float AI_WAIT = 4; +float AI_DANGER = 8; + +// addition masks +float AI_POINT_TYPES = 29152; +float AI_READAHEAD_TYPES = 36528; +float AI_IGNORE_TYPES = 4864; + +float WM_UNINIT = 0; +float WM_DYNAMIC = 1; +float WM_LOADING = 2; +float WM_LOADED = 3; +// editor modes aren't available in QW, but we retain support of them +// since the editor is still built into the AI in places +float WM_EDITOR = 4; +float WM_EDITOR_DYNAMIC = 5; +float WM_EDITOR_DYNLINK = 6; + +float OPT_NOCHAT = 2; + +// -------globals----- +float active_clients1, active_clients2; +float max_clients, real_frametime; +float bot_count, b_options, lasttime; +float waypoint_mode, dump_mode; +float waypoints, direct_route, userid; +float sv_friction, sv_gravity; +float sv_accelerate, sv_maxspeed, sv_stopspeed; +entity fixer; +entity route_table; +entity b_temp1, b_temp2, b_temp3; +entity player_head, phys_head, way_head; +float busy_waypoints; + +float coop = 0; // hack + +// -------ProtoTypes------ +// external +void() ClientConnect; +void() ClientDisconnect; +void() SetNewParms; + +// rankings +float(float clientno) ClientBitFlag; +float() ClientNextAvailable; +void(float whatbot, float whatskill) BotConnect; +void(entity bot) BotDisconnect; +void(float clientno) BotInvalidClientNo; +void(entity who) UpdateClient; + +// waypointing +void() DynamicWaypoint; +entity(vector org) make_waypoint; +void() ClearAllWays; +void() FixWaypoints; +float() begin_route; +void(entity this, float direct) bot_get_path; +void() WaypointThink; +entity(entity start) FindWayPoint; + +// physics & movement +float(entity e) bot_can_rj; +void() bot_jump; +void() frik_bot_roam; +float(vector weird) frik_walkmove; +void() frik_movetogoal; +void() frik_obstacles; +float(float flag) frik_recognize_plat; +float(vector sdir) frik_KeysForDir; +void(vector whichway, float danger) frik_obstructed; +void() SV_Physics_Client; +void() SV_ClientThink; +void() CL_KeyMove; + +// ai & misc +string() PickARandomName; +float(entity targ) fov; +float(float y1, float y2) angcomp; +float(entity targ1, entity targ2) wisible; +float(entity targ) sisible; +float(entity targ) fisible; +vector(entity ent) realorigin; +void(entity ent) target_drop; +void(entity ent) target_add; +void() KickABot; +void() BotImpulses; +void(entity targ, float success) bot_lost; +string(float r) BotName; +float(float v) frik_anglemod; +void() bot_chat; +void(float tpic) bot_start_topic; + + +// ----------Commands--------- +void(entity e, float chan, string samp, float vol, float atten) frik_sound = #8; +void(entity client, string s) frik_stuffcmd = #21; +void(entity client, float level, string s) frik_sprint = #24; +vector(entity e, float sped) frik_aim = #44; +void(entity client, string s) frik_centerprint = #73; +void(entity e) frik_setspawnparms = #78; +void(float to, float f) frik_WriteByte = #52; +void(float to, float f) frik_WriteChar = #53; +void(float to, float f) frik_WriteShort = #54; +void(float to, float f) frik_WriteLong = #55; +void(float to, float f) frik_WriteCoord = #56; +void(float to, float f) frik_WriteAngle = #57; +void(float to, string s) frik_WriteString = #58; +void(float to, entity s) frik_WriteEntity = #59; + +//---------------------------------------------------------------------------- + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Function redclarations. These allow function +designed to work for clients (sprint, so forth) +to mainly not complain when working with a bot + +Although these shouldn't be needed anymore, +as the bots truly are clients now, if you don't +stop the SZ_ buffer from filling up by disabling +direct messages to the bots, it crashes quake :-( + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(entity client, string s) stuffcmd = +{ + if (client.ishuman) + frik_stuffcmd(client, s); +}; + +void(entity e) setspawnparms = +{ + if (e.ishuman) + frik_setspawnparms(e); + else + SetNewParms(); +}; +void(entity client, float level, string s) sprint = +{ + if (client.ishuman) + frik_sprint(client, level, s); +}; +void(entity client, string s) centerprint = +{ + if (client.ishuman) + frik_centerprint(client, s); +}; + +vector(entity e, float sped) aim = +{ + e.missile_speed = sped; + return frik_aim(e, sped); +}; + +void(entity e, float chan, string samp, float vol, float atten) sound = +{ + frik_sound(e, chan, samp, vol, atten); + if (samp == "items/inv3.wav") + return; + else if (e.classname == "player") + e.b_sound = time + 1; + else if (other.classname == "player") + other.b_sound = time + 1; +}; +void(float to, float f) WriteByte = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteByte(to, f); +}; +void(float to, float f) WriteChar = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteChar(to, f); +}; +void(float to, float f) WriteShort = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteShort(to, f); +}; +void(float to, float f) WriteLong = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteLong(to, f); +}; +void(float to, float f) WriteCoord = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteCoord(to, f); +}; +void(float to, float f) WriteAngle = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteAngle(to, f); +}; +void(float to, string s) WriteString = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteString(to, s); +}; +void(float to, entity s) WriteEntity = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteEntity(to, s); +}; + + +float(float clientno) ClientIsActive = +{ + if(clientno > 16) + { + if(active_clients2 & ClientBitFlag(clientno - 16)) + return TRUE; + else + return FALSE; + } + else + { + if(active_clients1 & ClientBitFlag(clientno)) + return TRUE; + else + return FALSE; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Stuff mentioned up top +it just links the bot into the mod + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClientFixRankings = +{ + local float cno; + if (self.switch_wallhug > time) + return; + self.switch_wallhug = 0; + + b_temp2 = nextent(world); + cno = 0; + + while (cno < max_clients) + { + if (!b_temp2.ishuman) + { + if (ClientIsActive(cno)) + UpdateClient(b_temp2); + } + cno = cno + 1; + b_temp2 = nextent(b_temp2); + } +}; + +void() ClientInRankings = +{ + local float cno; + + cno = self.colormap - 1; + BotInvalidClientNo (cno); + + if (player_head) + player_head._last = self; + self._next = player_head; + player_head = self; + userid = userid + 1; + self.b_userid = userid; + + if (!self.phys_obj) + { + b_temp2 = phys_head; + while (b_temp2 != world && b_temp2.owner != self) + b_temp2 = b_temp2._next; + self.phys_obj = b_temp2; + } + + if (self.ishuman == 2) + { + self.ishuman = FALSE; + return; + } + if(cno > 16) + active_clients2 = active_clients2 | ClientBitFlag(cno - 16); + else + active_clients1 = active_clients1 | ClientBitFlag(cno); + self.b_clientno = cno; + self.ishuman = TRUE; + self.switch_wallhug = time + 1; +}; + + +void() ClientDisconnected = +{ + if (player_head == self) + player_head = self._next; + if (self._next) + self._next._last = self._last; + if (self._last) + self._last._next = self._next; + if(self.b_clientno > 16) + active_clients2 = active_clients2 - (active_clients2 & ClientBitFlag(self.b_clientno - 16)); + else + active_clients1 = active_clients1 - (active_clients1 & ClientBitFlag(self.b_clientno)); +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotPreFrame & BotPostFrame, used to make the +bot easier to install + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float () BotPreFrame = +{ + if (self.b_clientno == -1) + return TRUE; + if (self.ishuman) + if (self.switch_wallhug) + ClientFixRankings(); + if (self.b_frags != self.frags) + { + if (self.b_frags > self.frags) + { + if (pointcontents(self.origin) == CONTENT_LAVA) + bot_start_topic(10); + else + bot_start_topic(9); + } + else + bot_start_topic(2); + self.b_frags = self.frags; + if (!self.ishuman) + { + WriteByte(2, 14); + WriteByte(2, self.b_clientno); + WriteShort(2, self.frags); + } + } + DynamicWaypoint(); + return FALSE; +}; +float () BotPostFrame = +{ + if (self.b_clientno == -1) + return TRUE; + if (self.ishuman) + BotImpulses(); + return FALSE; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Chat code + +The rest of this code is in bot_rank.qc + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(string h) BotSay = // simulate talking by composing a 'chat' message +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 3); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, self.netname); + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 3); + WriteByte(MSG_ALL, 2); + WriteString(MSG_ALL, h); +}; +void() BotSayInit = +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 3); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, self.netname); +}; +void(string h) BotSay2 = +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 3); + WriteByte(MSG_ALL, 2); + WriteString(MSG_ALL, h); +}; +void(string h) BotSayTeam = +{ + // FBX QW doesn't support teamplay...yet +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotInit + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void() BotInit = +{ + local entity ent, fisent; + local float numents; + + // spawn entities for the physics + ent = nextent(world); + max_clients = 0; + + while(ent != world) + { + max_clients = max_clients + 1; + ent = nextent(ent); + } + + ent = nextent(world); + fisent = world; + while (numents < max_clients) + { + + phys_head = spawn(); + if (fisent) + fisent._next = phys_head; + phys_head._last = fisent; + fisent = phys_head; + ent.phys_obj = phys_head; + phys_head.classname = "phys_obj"; + phys_head.owner = ent; + numents = numents + 1; + ent = nextent(ent); + } + bot_map_load(); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Rankings 'utilities'. Written by Alan Kivlin, +this code just fools clients by sending precisely +the same network messages as when a real player +signs on to the server. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void(entity who) UpdateClient = +{ + WriteByte(2, 14 ); + WriteByte(2, who.b_clientno); + WriteShort(2, who.frags); + WriteByte(2, 36); + WriteByte(2, who.b_clientno); + WriteShort(2, 100 * (3 - who.b_skill)); + WriteByte(2, 37); // update entertime + WriteByte(2, who.b_clientno); // client number + WriteLong(2, time - who.b_entertime); // client entertime + WriteByte(2, 40 ); // update userinfo + WriteByte(2, who.b_clientno); // client number + WriteLong(2, who.b_userid); // client userid + WriteByte(2, 92); // \ + WriteByte(2, 98); // b + WriteByte(2, 111); // o + WriteByte(2, 116); // t + WriteByte(2, 116); // t + WriteByte(2, 111); // o + WriteByte(2, 109); // m + WriteByte(2, 99); // c + WriteByte(2, 111); // o + WriteByte(2, 108); // l + WriteByte(2, 111); // o + WriteByte(2, 114); // r + WriteByte(2, 92); // \ + if(who.b_pants > 9) + { + WriteByte(2, 49); + WriteByte(2, 38 + who.b_pants); + } + else + WriteByte(2, 48 + who.b_pants); + WriteByte(2, 92); // \ + WriteByte(2, 116); // t + WriteByte(2, 111); // o + WriteByte(2, 112); // p + WriteByte(2, 99); // c + WriteByte(2, 111); // o + WriteByte(2, 108); // l + WriteByte(2, 111); // o + WriteByte(2, 114); // r + WriteByte(2, 92); // \ + if(who.b_shirt > 9) + { + WriteByte(2, 49); + WriteByte(2, 38 + who.b_shirt); + } + else + WriteByte(2, 48 + who.b_shirt); + WriteByte(2, 92); // \ + WriteByte(2, 116); // t + WriteByte(2, 101); // e + WriteByte(2, 97); // a + WriteByte(2, 109); // m + WriteByte(2, 92); // \ + WriteByte(2, 98); // b + WriteByte(2, 111); // o + WriteByte(2, 116); // t + // FIXME: do teams properly + // note this has no effect on infokey + WriteByte(2, 92 ); // \ + WriteByte(2, 115); // s + WriteByte(2, 107); // k + WriteByte(2, 105); // i + WriteByte(2, 110); // n + WriteByte(2, 92); // \ + WriteByte(2, 98); // b + WriteByte(2, 97); // a + WriteByte(2, 115); // s + WriteByte(2, 101); // e + WriteByte(2, 92); // \ + WriteByte(2, 110); // n + WriteByte(2, 97); // a + WriteByte(2, 109); // m + WriteByte(2, 101); // e + WriteByte(2, 92); // \ + WriteString( 2, who.netname); +}; + +float(float clientno) ClientBitFlag = +{ + local float bitflag; + bitflag = 1; + while(clientno > 0) + { + bitflag = bitflag * 2; + clientno = clientno - 1; + } + return bitflag; +}; + +float() ClientNextAvailable = +{ + local float clientno; + // I want to do this top down, but QW won't let me + clientno = 0; + while(clientno < max_clients) + { + clientno = clientno + 1; + + if(!ClientIsActive(clientno)) + return clientno; + } + return -1; +}; + + +void(entity e1, entity e2, float flag) DeveloperLightning = {}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotConnect and related functions. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +entity(float num) GetClientEntity = +{ + local entity upsy; + upsy = world; + num = num + 1; + while (num > 0) + { + num = num - 1; + upsy = nextent(upsy); + } + return upsy; +}; + +void(float whatbot, float whatskill) BotConnect = +{ + local float f; + local string h; + local entity uself; + + f = ClientNextAvailable(); + uself = self; + if(f == -1) + { + bprint(PRINT_HIGH, "Unable to connect a bot, server is full.\n"); + return; + } + + bot_count = bot_count + 1; + self = GetClientEntity(f); + bot_start_topic(1); + self.b_clientno = f; + self.colormap = f + 1; + if (whatbot) + self.netname = BotName(whatbot); + else + self.netname = PickARandomName(); + // players can set skill all weird, so leave these checks in + whatskill = rint(whatskill); + if (whatskill > 3) + whatskill = 3; + else if (whatskill < 0) + whatskill = 0; + self.b_skill = whatskill; + self.b_entertime = time; + self.team = self.b_pants + 1; + UpdateClient(self); + SetNewParms(); + self.ishuman = 2; + ClientConnect(); + PutClientInServer(); + if(f > 16) + active_clients2 = active_clients2 | ClientBitFlag(f - 16); + else + active_clients1 = active_clients1 | ClientBitFlag(f); + self = uself; +}; + +void(entity bot) BotDisconnect = +{ + local string h; + local entity uself; + uself = self; + self = bot; + + bot_count = bot_count - 1; + + ClientDisconnect(); + + //if (self.b_clientno != -1) + //{ + // the bot's client number is not in use by a real player so we + // must remove it's entry in the rankings + // Quake engine sets all fields to 0, can only do the most important here + self.b_frags = self.frags = 0; + self.netname = ""; + self.classname = ""; + self.health = 0; + self.items = 0; + self.armorvalue = 0; + self.weaponmodel = ""; + self.b_pants = 0; + self.b_shirt = 0; + self.ammo_shells = self.ammo_nails = self.ammo_rockets = self.ammo_cells = 0; + UpdateClient(self); + if(self.b_clientno > 16) + active_clients2 = active_clients2 - (active_clients2 & ClientBitFlag(self.b_clientno - 16)); + else + active_clients1 = active_clients1 - (active_clients1 & ClientBitFlag(self.b_clientno)); + self.b_clientno = -1; + //} + self = uself; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotInvalidClientNo +kicks a bot if a player connects and takes the bot's space + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(float clientno) BotInvalidClientNo = +{ + local entity bot; + + if (ClientIsActive(clientno)) + { + bot = GetClientEntity (clientno); + + if (bot.b_clientno == clientno) + { + bot.b_clientno = -1; + BotDisconnect(bot); + if(clientno > 16) + active_clients2 = active_clients2 | (active_clients2 & ClientBitFlag(clientno - 16)); + else + active_clients1 = active_clients1 | (active_clients1 & ClientBitFlag(clientno)); + BotConnect(self.b_num, self.b_skill); + return; + } + } +}; + +void() BotFrame = +{ + local float num; + local string h; + + h = infokey(world, "bot_options"); + b_options = stof(h); + + // for the sake of speed + sv_maxspeed = cvar("sv_maxspeed"); + sv_gravity = cvar("sv_gravity"); + sv_friction = cvar("sv_friction"); + sv_accelerate = cvar("sv_accelerate"); + sv_stopspeed = cvar("sv_stopspeed"); + real_frametime = time - lasttime; // in QW frametime is fuxx0red + lasttime = time; + + self = nextent(world); + num = 0; + while (num < max_clients) + { + if (self.ishuman == FALSE) + { + if (self.b_clientno > 0) + { + frik_obstacles(); + CL_KeyMove(); + SV_ClientThink(); + SV_Physics_Client(); + // this is sickening + if (self.phys_obj) + { + if (self.phys_obj.modelindex != self.modelindex) + { + setmodel(self.phys_obj, "progs/player.mdl"); + self.phys_obj.modelindex = self.modelindex; + } + self.phys_obj.frame = self.frame; + self.phys_obj.angles = self.angles; + self.phys_obj.colormap = self.colormap; + self.phys_obj.effects = self.effects; + } + } + } + self = nextent(self); + num = num + 1; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Impulses. Allows the player to perform bot +related functions. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() BotImpulses = +{ + local float f; + local string h; + + if (self.impulse == 100) + { + h = infokey(world, "skill"); + f = stof(h); + BotConnect(0, f); + } + else if (self.impulse == 102) + KickABot(); + else + return; + self.impulse = 0; +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/frikbot/bot_way.qc b/r17/Revamped src/Revamped QC/frikbot/bot_way.qc new file mode 100755 index 00000000..5dfc841e --- /dev/null +++ b/r17/Revamped src/Revamped QC/frikbot/bot_way.qc @@ -0,0 +1,1007 @@ + /*********************************************** +* * +* FrikBot Waypoints * +* "The better than roaming AI" * +* * +***********************************************/ + +/* + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Linking code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +float (entity e1, entity e2) CheckLinked = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return FALSE; + else if (e1.target1 == e2) + { + if (e1.b_aiflags & AI_TELELINK_1) + return 2; + else return TRUE; + } + else if (e1.target2 == e2) + { + if (e1.b_aiflags & AI_TELELINK_2) + return 2; + else return TRUE; + } + else if (e1.target3 == e2) + { + if (e1.b_aiflags & AI_TELELINK_3) + return 2; + else return TRUE; + } + else if (e1.target4 == e2) + { + if (e1.b_aiflags & AI_TELELINK_4) + return 2; + else return TRUE; + } + + else return FALSE; +}; + + +float (entity e1, entity e2) LinkWays = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return FALSE; + else if (CheckLinked(e1, e2)) + return FALSE; // already linked!!! + + if (e1.target1 == world) + { + e1.target1 = e2; + return TRUE; + } + else if (e1.target2 == world) + { + e1.target2 = e2; + return TRUE; + } + else if (e1.target3 == world) + { + e1.target3 = e2; + return TRUE; + } + else if (e1.target4 == world) + { + e1.target4 = e2; + return TRUE; + } + else return FALSE; + +}; +// Link Ways part 2, used only for teleporters + +float (entity e1, entity e2) TeleLinkWays = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return FALSE; + else if (CheckLinked(e1, e2)) + return FALSE; // already linked!!! + + if (e1.target1 == world) + { + e1.target1 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_1; + return TRUE; + } + else if (e1.target2 == world) + { + e1.target2 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_2; + return TRUE; + } + else if (e1.target3 == world) + { + e1.target3 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_3; + return TRUE; + } + else if (e1.target4 == world) + { + e1.target4 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_4; + return TRUE; + } + else + return FALSE; + +}; + +void (entity e1, entity e2) UnlinkWays = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return; + else if (!CheckLinked(e1, e2)) + return; + + if (e1.target1 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_1); + e1.target1 = world; + } + if (e1.target2 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_2); + e1.target2 = world; + } + if (e1.target3 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_3); + e1.target3 = world; + } + if (e1.target4 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_4); + e1.target4 = world; + } + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +FindWaypoint + +This is used quite a bit, by many different +functions big lag causer + +Finds the closest, fisible, waypoint to e + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +entity(entity start) FindWayPoint = +{ + local entity t; + local vector org; + local float dst, tdst; + local entity best; + + org = realorigin(self); + + t = way_head; + if (start != world) + { + dst = vlen(start.origin - org); + best = start; + } + else + { + dst = 100000; + best = world; + } + while(t) + { + // real players cut through ignore types + if (dst < 20) + return best; + if (!(t.b_aiflags & AI_IGNORE_TYPES) || self.ishuman) + { + tdst = vlen(t.origin - org); + if (tdst < dst) + { + if (sisible(t)) + { + dst = tdst; + best = t; + } + } + } + t = t._next; + } + return best; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Spawning Code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +entity way_foot; // Ugh. Do I need a foot for this or not? + +entity(vector org) make_waypoint = +{ + local entity point; + point = spawn(); + point.classname = "waypoint"; + point.solid = SOLID_TRIGGER; + point.movetype = MOVETYPE_NONE; + point.items = -1; + setorigin(point, org); + + setsize(point, VEC_HULL_MIN, VEC_HULL_MAX); + waypoints = waypoints + 1; + if (!way_head) + { + way_head = point; + way_foot = point; + } + else + { + way_foot._next = point; + point._last = way_foot; + way_foot = point; + } + + point.count = waypoints; + if (waypoint_mode > WM_LOADED) // editor modes + setmodel(point, "progs/s_bubble.spr"); + return point; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Dynamic Waypoint spawning and linking. Not +very good all things considered. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() DynamicWaypoint = +{ + local entity t; + local float dist, dynlink, dynpoint, editor; + + if (self.teleport_time > self.portal_time) + { + if (!self.flags & FL_WATERJUMP) + { + self.dyn_flags = 2; + if (!self.ishuman) + { + bot_lost(self.target1, TRUE); + self.enemy = world; + } + } + self.portal_time = self.teleport_time; + } +// stacking everything on waypoint_mode might've been good for the editor, +// but it sucks to beat hell for this code. + + +// convert waypoint_mode to something more usable.. + if (waypoint_mode > WM_LOADED) + { + if (self.ishuman) + { + if (waypoint_mode == WM_EDITOR_DYNLINK) + dynlink = 1; + else if (waypoint_mode == WM_EDITOR_DYNAMIC) + dynlink = dynpoint = 1; + editor = 1; + } + } + else if (waypoint_mode == WM_DYNAMIC) + dynlink = dynpoint = 1; + +// if there's nothing for dynamic to do.. + if (!dynpoint) + { + if (!editor) + return; + } +// for speed sake, I won't have bots dynamic waypoint in coop + if (!self.ishuman) + if (coop) + return; + +// don't waypoint in single player + if (max_clients < 2) + return; +// if you're dead + else if (self.health <= 0) + { + if (dynpoint) + { + if (self.current_way) + { + if (pointcontents(self.origin) < -4) + { + if (self.current_way.b_aiflags & AI_BLIND) + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_PRECISION; + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_BLIND; + } + } + } + self.dyn_dest = '0 0 0'; + self.current_way = world; + self.dyn_flags = 0; + return; + } + +// you shouldn't be making waypoints mid air + if (dynpoint) + { + if (!((self.flags & FL_ONGROUND) || self.waterlevel == 3)) + { + if (self.dyn_flags != 2) + { + self.dyn_flags = 1; + } + return; + } + } +// keep from doing the rest of this every frame + if (self.dyn_time > time) + return; + self.dyn_time = time + 0.2; + +// display the links for editor mode + if (editor) + { + if (self.current_way) + { + if (self.current_way.target1) + DeveloperLightning(self.current_way, self.current_way.target1, self.current_way.b_aiflags & AI_TELELINK_1); + if (self.current_way.target2) + DeveloperLightning(self.current_way, self.current_way.target2, self.current_way.b_aiflags & AI_TELELINK_2); + if (self.current_way.target3) + DeveloperLightning(self.current_way, self.current_way.target3, self.current_way.b_aiflags & AI_TELELINK_3); + if (self.current_way.target4) + DeveloperLightning(self.current_way, self.current_way.target4, self.current_way.b_aiflags & AI_TELELINK_4); + } + if (self.b_aiflags & AI_HOLD_SELECT) + return; + } + + t = FindWayPoint(self.current_way); + if (t) + { + dist = vlen(self.origin - t.origin); + if (dist < 192) + { + if (dist < 64) + { + + if (t != self.current_way) + { + if (dynlink) + { + if (!self.dyn_flags) + { + if (wisible(t, self.current_way)) + LinkWays(t, self.current_way); + } + if (self.dyn_flags == 2) + TeleLinkWays(self.current_way, t); + else if (wisible(t, self.current_way)) + LinkWays(self.current_way, t); + } + if (editor) + { + setmodel(t, "progs/s_light.spr"); + if (self.current_way) + setmodel(self.current_way, "progs/s_bubble.spr"); + } + } + self.current_way = t; + self.dyn_flags = 0; + } + self.dyn_dest = self.origin + self.view_ofs; + return; + } + } + + if (frik_recognize_plat(FALSE)) + { + if (vlen(trace_ent.velocity) > 0) + { + if (self.dyn_plat) + return; + self.dyn_plat = TRUE; + if (!self.dyn_flags) + self.dyn_flags = 1; + //bprint("on a plat!!!!!\n"); + } + else + self.dyn_plat = FALSE; + } + else + self.dyn_plat = FALSE; + + if (self.dyn_flags == 2) + self.dyn_dest = self.origin + self.view_ofs; + else if (self.dyn_dest == '0 0 0') + self.dyn_dest = self.origin + self.view_ofs; + if (!dynpoint) + return; + t = make_waypoint(self.dyn_dest); + + if (!self.dyn_flags) + { + if (wisible(t, self.current_way)) + LinkWays(t, self.current_way); + } + if (self.dyn_flags == 2) + TeleLinkWays(self.current_way, t); + else if (wisible(t, self.current_way)) + LinkWays(self.current_way, t); + + if (editor) + { + setmodel(t, "progs/s_light.spr"); + if (self.current_way) + setmodel(self.current_way, "progs/s_bubble.spr"); + } + self.current_way = t; + self.dyn_flags = 0; + + self.dyn_dest = self.origin + self.view_ofs; + + if (frik_recognize_plat(FALSE)) + { + if (trace_ent.classname == "door") + t.b_aiflags = t.b_aiflags | AI_DOORFLAG; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Loading from file + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClearAllWays = +{ + + local entity t, n; + t = way_head; + while(t) + { + n = t._next; + remove(t); + t = n; + } + way_head = world; + way_foot = world; + waypoints = 0; +}; + +entity(float num) WaypointForNum = +{ + local entity t; + if (!num) + return world; + + t = way_head; + while (t) + { + if (t.count == num) + return t; + t = t._next; + } + return world; +}; + +void() FixThisWaypoint = +{ + self.enemy.target1 = WaypointForNum(self.enemy.b_pants); + self.enemy.target2 = WaypointForNum(self.enemy.b_skill); + self.enemy.target3 = WaypointForNum(self.enemy.b_shirt); + self.enemy.target4 = WaypointForNum(self.enemy.b_frags); + self.enemy = self.enemy._next; + self.nextthink = time; + if (self.enemy == world) + { + remove(self); + fixer = world; + } +}; + +void() FixWaypoints = +{ + if (!fixer) + fixer = spawn(); + fixer.nextthink = time; + fixer.think = FixThisWaypoint; + fixer.enemy = way_head; +}; + + + +void(entity what) delete_waypoint = +{ + local entity t; + + if (way_head == what) + way_head = what._next; + if (way_foot == what) + way_foot = what._last; + if (what._last) + what._last._next = what._next; + if (what._next) + what._next._last = what._last; + waypoints = 0; + t = way_head; + while(t) + { + t.count = waypoints = waypoints + 1; + if (CheckLinked(t, what)) + UnlinkWays(t, what); + t = t._next; + } + if (self.current_way == what) + self.current_way = world; + remove(what); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +FindRoute & FindThing used by the pathing code +in bot_ai.qc + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +entity(string s) FindThing = +{ + local entity t; + local float tdst, dst; + local entity best; + dst = 100000; + best = world; + t = find (world, classname, s); + while (t != world) + { + tdst = vlen(((t.absmin + t.absmax) * 0.5) - self.origin); + if (tdst < dst) + { + dst = tdst; + best = t; + } + t = find(t, classname, s); + } + return best; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +FindRoute, this is a key function in the +pathing. The name is a bit misleading, this +code finds the closest waypoint that is part +of a route calculated by the begin_route and +end_route routines This is a definite path to +an object. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +entity(entity lastone) FindRoute = +{ + // kinda like FindWaypoint, only of this bots route though + local entity t, best; + local float dst, tdst, flag; + flag = ClientBitFlag(self.b_clientno); + + if (lastone) + { + if (lastone.target1.b_sound & flag) + return lastone.target1; + else if (lastone.target2.b_sound & flag) + return lastone.target2; + else if (lastone.target3.b_sound & flag) + return lastone.target3; + else if (lastone.target4.b_sound & flag) + return lastone.target4; + } + + t = way_head; + dst = 100000; + best = world; + while(t) + { + tdst = vlen(t.origin - self.origin); + if ((tdst < dst) && (t.b_sound & flag)) + { + dst = tdst; + best = t; + } + t = t._next; + } + return best; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Route & path table management + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClearRouteTable = +{ + // cleans up route table + + local entity t; + t = way_head; + while (t) + { + t. keys = FALSE; + t.enemy = world; + t.items = -1; // not in table + t = t._next; + } +}; + +void() ClearMyRoute = +{ + local float flag; + local entity t; + + flag = ClientBitFlag(self.b_clientno); + + t = way_head; + while (t) + { + t.b_sound = t.b_sound - (t.b_sound & flag); + t = t._next; + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Mark_path + +After the route has been found, mark it with +bitflags so the table can be used for a +different bot. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void(entity this) mark_path = +{ + local entity t, oself; + local float flag; + + ClearMyRoute(); + + oself = self; + self = this; + t = FindWayPoint(this.current_way); + self = oself; + // FIXME + // ugh, better way to find players please!!! + if (this.classname != "player") + this.current_way = t; + + if (t.enemy == world) + { + bot_lost(this, FALSE); + self.route_failed = TRUE; + return; + } + + flag = ClientBitFlag(self.b_clientno); + + while(t) + { + if (t.b_sound & flag) + return; + if (t == self.last_way) + return; + t.b_sound = t.b_sound | flag; + t = t.enemy; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +WaypointThink + +Calculates the routes. We use thinks to avoid +tripping the runaway loop counter + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity e2, float b_bit) FollowLink = +{ + local float dist; + + if (self.b_aiflags & b_bit) + dist = self.items; + else + dist = vlen(self.origin - e2.origin) + self.items; + + // check if this is an RJ link + if (e2.b_aiflags & AI_SUPER_JUMP) + { + if (!bot_can_rj(route_table)) + return; + } + if (e2.b_aiflags & AI_DIFFICULT) + dist = dist + 1000; + + if ((dist < e2.items) || (e2.items == -1)) + { + if (!e2.keys) + busy_waypoints = busy_waypoints + 1; + e2.keys = TRUE; + e2.items = dist; + e2.think = WaypointThink; + e2.nextthink = time; + e2.enemy = self; + } +}; + +void() WaypointThink = +{ + local entity oself; + + if (self.items == -1) + return; + // can you say ugly? + if (self.b_aiflags & AI_TRACE_TEST) + { + if (self.target1) + { + traceline(self.origin, self.target1.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target1, AI_TELELINK_1); + } + if (self.target2) + { + traceline(self.origin, self.target2.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target2, AI_TELELINK_2); + } + if (self.target3) + { + traceline(self.origin, self.target3.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target3, AI_TELELINK_3); + } + if (self.target4) + { + traceline(self.origin, self.target4.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target4, AI_TELELINK_4); + } + } + else + { + if (self.target1) + FollowLink(self.target1, AI_TELELINK_1); + if (self.target2) + FollowLink(self.target2, AI_TELELINK_2); + if (self.target3) + FollowLink(self.target3, AI_TELELINK_3); + if (self.target4) + FollowLink(self.target4, AI_TELELINK_4); + } + + busy_waypoints = busy_waypoints - 1; + self.keys = FALSE; + + if (busy_waypoints <= 0) + { + if (direct_route) + { + oself = self; + self = route_table; + bot_get_path(self.target1, FALSE); + self = oself; + direct_route = FALSE; + } + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +begin_route and bot_get_path + +PLEASE NOTE: bot_get_path replaces the old +calls to begin_route. + +Routing isn't done all at once now, but in two +stages, the bot will calc a route *THEN* +choose a target, *THEN* mark a path. + +Boy it's confusing. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float() begin_route = +{ + if (busy_waypoints > 0) + return FALSE; + + if (route_table != world) + { + if (!route_table.ishuman) + { + if (route_table.b_clientno != -1) + return FALSE; + } + } + + route_table = self; + ClearRouteTable(); + self.last_way = FindWayPoint(self.current_way); + + if (self.last_way != world) + { + self.last_way.items = vlen(self.last_way.origin - self.origin); + self.last_way.nextthink = time; + self.last_way.think = WaypointThink; + self.last_way.keys = TRUE; + busy_waypoints = 1; + return TRUE; + } + else + { + route_table = world; + busy_waypoints = 0; + return FALSE; + } +}; + +void(entity this, float direct) bot_get_path = +{ + if (this == world) + return; + + if (route_table == self) + { + if (busy_waypoints <= 0) + { + route_table = world; + mark_path(this); + } + return; + } + if (direct) + { + if(begin_route()) + direct_route = TRUE; + else + bot_lost(this, FALSE); + return; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BSP/QC Waypoint loading + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() waypoint = +{ + self.solid = SOLID_TRIGGER; + self.movetype = MOVETYPE_NONE; + setorigin(self, self.origin); + + setsize(self, VEC_HULL_MIN, VEC_HULL_MAX); + waypoints = waypoints + 1; + if (!way_head) + { + way_head = self; + way_foot = self; + } + else + { + way_foot._next = self; + self._last = way_foot; + way_foot = self; + } + + self.count = waypoints; + waypoint_mode = WM_LOADED; + if (self.count == 1) + { + localcmd("echo BSP waypoints detected\n"); + self.think = FixWaypoints; // wait until all bsp loaded points are spawned + self.nextthink = time; + } +}; + +void(vector org, vector bit1, float bit4, float flargs) make_way = +{ + local entity y; + waypoint_mode = WM_LOADED; + y = make_waypoint(org); + y.b_aiflags = flargs; + y.b_pants = bit1_x; + y.b_skill = bit1_y; + y.b_shirt = bit1_z; + y.b_frags = bit4; + if (y.count == 1) + { + localcmd("echo QuakeC waypoints detected\n"); + y.think = FixWaypoints; // wait until all qc loaded points are spawned + y.nextthink = time; + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Temporary Marker code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(vector org) SpawnTempWaypoint = +{ + local entity tep; + + if (!self.temp_way) + self.temp_way = tep = spawn(); + else + tep = self.temp_way; + + tep.classname = "temp_waypoint"; + tep.solid = SOLID_TRIGGER; + tep.movetype = MOVETYPE_NOCLIP; + setorigin(tep, org); + target_add(tep); + setsize(tep, VEC_HULL_MIN, VEC_HULL_MAX); // FIXME: convert these to numerical +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/fteqccgui.exe b/r17/Revamped src/Revamped QC/fteqccgui.exe new file mode 100755 index 00000000..03ae0933 Binary files /dev/null and b/r17/Revamped src/Revamped QC/fteqccgui.exe differ diff --git a/r17/Revamped src/Revamped QC/items.qc b/r17/Revamped src/Revamped QC/items.qc new file mode 100755 index 00000000..989313ee --- /dev/null +++ b/r17/Revamped src/Revamped QC/items.qc @@ -0,0 +1,1503 @@ +/* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD +BE .8 .3 .4 IN COLOR */ +void () W_SetCurrentAmmo; +void (float weap) W_WeaponSwitch; +void (entity ent) W_UpdateAmmoCounts; + +void() SUB_regen = +{ + self.model = self.mdl; // restore original model + self.solid = SOLID_TRIGGER; // allow it to be touched again + sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM); // play respawn sound + setorigin (self, self.origin); +}; + + + +/*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8) +prints a warning message when spawned +*/ +void() noclass = +{ + dprint ("noclass spawned at"); + dprint (vtos(self.origin)); + dprint ("\n"); + remove (self); +}; + +// names of weapons function +string(float weap) I_WeaponName = +{ + switch (weap) + { + case IT_AXE: + return "Axe"; + case IT_SHOTGUN: + return "Shotgun"; + case IT_SUPER_SHOTGUN: + return "Double-barrelled Shotgun"; + case IT_NAILGUN: + return "Nailgun"; + case IT_SUPER_NAILGUN: + return "Super Nailgun"; + case IT_GRENADE_LAUNCHER: + return "Grenade Launcher"; + case IT_ROCKET_LAUNCHER: + return "Rocket Launcher"; + case IT_LIGHTNING: + return "Thunderbolt"; + } + + return ""; +} + + + +void() q_touch; + +void() q_touch = +{ + local string s, t; + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + self.mdl = self.model; + + sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + other.items = other.items | IT_QUAD; + self.model = string_null; + if (deathmatch == 4) + { + other.armortype = 0; + other.armorvalue = 0; + other.ammo_cells_real = 0; + W_UpdateAmmoCounts(other); + } + +// do the apropriate action + other.super_time = 1; + other.super_damage_finished = self.cnt; + + s=ftos(rint(other.super_damage_finished - time)); + t = " recovered a Quad with "; + if (deathmatch == 4) + t = " recovered an OctaPower with "; + + bprint4 (PRINT_LOW, other.netname, t, s, " seconds remaining!\n"); + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +void(float timeleft) DropQuad = +{ + local entity item; + + item = spawn(); + item.origin = self.origin; + + item.velocity_z = 300; + item.velocity_x = -100 + (random() * 200); + item.velocity_y = -100 + (random() * 200); + + item.flags = FL_ITEM; + item.solid = SOLID_TRIGGER; + item.movetype = MOVETYPE_TOSS; + item.noise = "items/damage.wav"; + setmodel (item, "progs/quaddama.mdl"); + setsize (item, '-16 -16 -24', '16 16 32'); + item.cnt = time + timeleft; + item.touch = q_touch; + item.nextthink = time + timeleft; // remove it with the time left on it + item.think = SUB_Remove; +}; + + +void() r_touch; + +void() r_touch = +{ +local string s; + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + self.mdl = self.model; + + sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + other.items = other.items | IT_INVISIBILITY; + self.model = string_null; + +// do the apropriate action + other.invisible_time = 1; + other.invisible_finished = self.cnt; + s=ftos(rint(other.invisible_finished - time)); + bprint4 (PRINT_LOW, other.netname, " recovered a Ring with ", s, " seconds remaining!\n"); + + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +void(float timeleft) DropRing = +{ + local entity item; + + item = spawn(); + item.origin = self.origin; + + item.velocity_z = 300; + item.velocity_x = -100 + (random() * 200); + item.velocity_y = -100 + (random() * 200); + + item.flags = FL_ITEM; + item.solid = SOLID_TRIGGER; + item.movetype = MOVETYPE_TOSS; + item.noise = "items/inv1.wav"; + setmodel (item, "progs/invisibl.mdl"); + setsize (item, '-16 -16 -24', '16 16 32'); + item.cnt = time + timeleft; + item.touch = r_touch; + item.nextthink = time + timeleft; // remove after 30 seconds + item.think = SUB_Remove; +}; + +/* +============ +PlaceItem + +plants the object on the floor +============ +*/ +void() PlaceItem = +{ + local float oldz; + + self.mdl = self.model; // so it can be restored on respawn + self.flags = FL_ITEM; // make extra wide + self.solid = SOLID_TRIGGER; + self.movetype = MOVETYPE_TOSS; + self.velocity = '0 0 0'; + self.origin_z = self.origin_z + 6; + oldz = self.origin_z; + if (!droptofloor()) + { + dprint ("Bonus item fell out of level at "); + dprint (vtos(self.origin)); + dprint ("\n"); + remove(self); + return; + } +}; + +/* +============ +StartItem + +Sets the clipping size and plants the object on the floor +============ +*/ +void() StartItem = +{ + self.nextthink = time + 0.2; // items start after other solids + self.think = PlaceItem; +}; + +/* +========================================================================= + +HEALTH BOX + +========================================================================= +*/ +// +// T_Heal: add health to an entity, limiting health to max_health +// "ignore" will ignore max_health limit +// +float (entity e, float hamount, float ignore) T_Heal = +{ + if (e.health <= 0) + return 0; + if ((!ignore) && (e.health >= other.max_health)) + return 0; + hamount = ceil(hamount); + + e.health = e.health + hamount; + if ((!ignore) && (e.health >= other.max_health)) + e.health = other.max_health; + + + if (e.health > e.max_health + 150) + e.health = e.max_health + 150; + + e.healdecay = time + 5; + return 1; +}; + +/*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth +Health box. Normally gives 25 points. +Rotten box heals 5-10 points, +megahealth will add 100 health, then +rot you down to your maximum health limit, +one point per second. +*/ + +void() health_touch; + +void() item_health = +{ + self.touch = health_touch; + + if (self.spawnflags & H_ROTTEN) + { + precache_model("progs/health.mdl"); + + precache_sound("items/r_item1.wav"); + setmodel(self, "progs/health.mdl"); + self.noise = "items/r_item1.wav"; + self.healamount = 15; + self.healtype = 0; + } + else + if (self.spawnflags & H_MEGA) + { + precache_model("progs/health.mdl"); + precache_sound("items/r_item2.wav"); + setmodel(self, "progs/health.mdl"); + self.noise = "items/r_item2.wav"; + self.healamount = 100; + self.healtype = 2; + } + else + { + precache_model("progs/health.mdl"); + precache_sound("items/health1.wav"); + setmodel(self, "progs/health.mdl"); + self.noise = "items/health1.wav"; + self.healamount = 25; + self.healtype = 1; + } + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; + + +void() health_touch = +{ + local string s; + + if (deathmatch == 4) + if (other.invincible_time > time) + return; + + if (other.classname != "player") + return; + + if (self.healtype == H_MEGA) // Megahealth? Ignore max_health... + { + if (other.health >= other.max_health + 150) + return; + if (!T_Heal(other, self.healamount, 1)) + return; + } + else + { + if (!T_Heal(other, self.healamount, 0)) + return; + } + + s = ftos(self.healamount); + sprint3(other, PRINT_LOW, "You receive ", s, " health\n"); + +// health touch sound + sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM); + + stuffcmd (other, "bf\n"); + + self.model = string_null; + self.solid = SOLID_NOT; + + // Megahealth = rot down the player's super health + if (deathmatch) // TODO: are these rules right? + { + if (deathmatch != 2) // deathmatch 2 is the silly old rules + { + if (self.healtype == H_MEGA) + self.nextthink = time + 45; // should I account for health healed instead? + else + self.nextthink = time + 20; + self.think = SUB_regen; + } + } + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + +/* +=============================================================================== + +ARMOR + +=============================================================================== +*/ + +void() armor_touch; + +void() armor_touch = +{ + local float type, value, bit; + + if (other.health <= 0) + return; + if (other.classname != "player") + return; + + if (deathmatch == 4) + + if (other.invincible_time > 0) + return; + + switch (self.classname) + { + case "item_armor1": + type = 0.3; + value = 100; + bit = IT_ARMOR1; + break; + case "item_armor2": + type = 0.6; + value = 150; + bit = IT_ARMOR2; + break; + case "item_armorInv": + type = 0.8; + value = 200; + bit = IT_ARMOR3; + break; + } + + if (other.armortype*other.armorvalue >= type*value) + return; + + other.armortype = type; + other.armorvalue = value; + other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit; + + self.solid = SOLID_NOT; + self.model = string_null; + if (deathmatch && deathmatch != 2) + { + self.nextthink = time + 20; + self.think = SUB_regen; + } + + sprint1(other, PRINT_LOW, "You got armor\n"); +// armor touch sound + sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +/*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() item_armor1 = +{ + self.touch = armor_touch; + precache_model ("progs/armor.mdl"); + setmodel (self, "progs/armor.mdl"); + self.skin = 0; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() item_armor2 = +{ + self.touch = armor_touch; + precache_model ("progs/armor.mdl"); + setmodel (self, "progs/armor.mdl"); + self.skin = 1; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() item_armorInv = +{ + self.touch = armor_touch; + precache_model ("progs/armor.mdl"); + setmodel (self, "progs/armor.mdl"); + self.skin = 2; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/* +=============================================================================== + +WEAPONS + +=============================================================================== +*/ + +void() bound_other_ammo = +{ + if (other.ammo_shells_real > 100) + other.ammo_shells_real = 100; + if (other.ammo_nails_real > 200) + other.ammo_nails_real = 200; + if (other.ammo_rockets_real > 100) + other.ammo_rockets_real = 100; + if (other.ammo_cells_real > 100) + other.ammo_cells_real = 100; + + if ((other.exshells > 100)) + { + other.exshells = 100; + } + if ((other.exnails > 200)) + { + other.exnails = 200; + } + if ((other.exrockets > 100)) + { + other.exrockets = 100; + } + if ((other.excells > 100)) + { + other.excells = 100; + } +}; + + +float(float w) RankForWeapon = +{ + if (w == IT_LIGHTNING) + return 1; + if (w == IT_ROCKET_LAUNCHER) + return 2; + if (w == IT_SUPER_NAILGUN) + return 3; + if (w == IT_GRENADE_LAUNCHER) + return 4; + if (w == IT_SUPER_SHOTGUN) + return 5; + if (w == IT_NAILGUN) + return 6; + return 7; +}; + +float (float w) WeaponCode = +{ + if (w == IT_SUPER_SHOTGUN) + return 3; + if (w == IT_NAILGUN) + return 4; + if (w == IT_SUPER_NAILGUN) + return 5; + if (w == IT_GRENADE_LAUNCHER) + return 6; + if (w == IT_ROCKET_LAUNCHER) + return 7; + if (w == IT_LIGHTNING) + return 8; + return 1; +}; + +/* +============= +Deathmatch_Weapon + +Deathmatch weapon change rules for picking up a weapon + +.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells; +============= +*/ +void(float old, float new) Deathmatch_Weapon = +{ + local float or, nr; + +// change self.weapon if desired + or = RankForWeapon (self.weapon); + nr = RankForWeapon (new); + + if ( nr == IT_LIGHTNING && self.waterlevel > 1 ) + return; + + if ( nr < or ) + W_WeaponSwitch (new); +}; + +/* +============= +weapon_touch +============= +*/ +float() W_BestWeapon; +void() weapon_touch; // sol_items.qc + + + + +/* +=============================================================================== + +AMMO + +=============================================================================== +*/ + +void () ammo_touch = +{ + local entity stemp; + local float best; + + if ((other.classname != "player")) + { + return; + } + if ((other.health <= MSG_BROADCAST)) + { + return; + } + stemp = self; + self = other; + best = W_BestWeapon (); + self = stemp; + if ((self.weapon == H_ROTTEN)) + { + if ((other.exshells >= 100)) + { + return; + } + other.exshells = (other.exshells + self.aflag); + } + if ((self.weapon == H_MEGA)) + { + if ((other.exnails >= 200)) + { + return; + } + other.exnails = (other.exnails + self.aflag); + } + if ((self.weapon == AS_MELEE)) + { + if ((other.exrockets >= 100)) + { + return; + } + other.exrockets = (other.exrockets + self.aflag); + } + if ((self.weapon == AS_MISSILE)) + { + if ((other.excells >= 100)) + { + return; + } + other.excells = (other.excells + self.aflag); + } + bound_other_ammo (); + sprint (other, "You got the "); + sprint (other, self.netname); + sprint (other, "\n"); + sound (other, CHAN_ITEM, "weapons/lock4.wav", H_ROTTEN, ATTN_NORM); + stuffcmd (other, "bf\n"); + stemp = self; + self = other; + self = stemp; + self.model = string_null; + self.solid = SOLID_NOT; + if ((deathmatch == H_ROTTEN)) + { + self.nextthink = (time + SVC_INTERMISSION); + } + self.think = SUB_regen; + activator = other; + SUB_UseTargets (); +}; +/* +void() ammo_touch = +{ +local entity stemp; +local float best; + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + +// if the player was using his best weapon, change up to the new one if better + stemp = self; + self = other; + best = W_BestWeapon(); + self = stemp; + + + switch (self.weapon) + { + case 1: // shotgun + if (other.ammo_shells_real >= 100) + return; + other.ammo_shells_real = other.ammo_shells_real + self.ammo_count; + break; + case 2: // spikes + if (other.ammo_nails_real >= 200) + return; + other.ammo_nails_real = other.ammo_nails_real + self.ammo_count; + break; + case 3: // rockets + if (other.ammo_rockets_real >= 100) + return; + other.ammo_rockets_real = other.ammo_rockets_real + self.ammo_count; + break; + case 4: // cells + if (other.ammo_cells_real >= 100) + return; + other.ammo_cells_real = other.ammo_cells_real + self.ammo_count; + break; + } + + bound_other_ammo (); + + sprint3 (other, PRINT_LOW, "You got the ", self.netname, "\n"); +// ammo touch sound + sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + +// change to a better weapon if appropriate + + stemp = self; + self = other; + + if ( self.weapon == best ) + W_WeaponSwitch (W_BestWeapon ()); + else + W_UpdateAmmoCounts (self); + + self = stemp; + +// remove it in single player, or setup for respawning in deathmatch + self.model = string_null; + self.solid = SOLID_NOT; + if (deathmatch) + { + if (deathmatch != 2) + self.nextthink = time + 30; + + // Xian -- If playing in DM 3.0 mode, halve the time ammo respawns + if (deathmatch == 3 || deathmatch == 5) + self.nextthink = time + 15; + + self.think = SUB_regen; + } + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; +*/ + + + +float WEAPON_BIG2 = 1; + +void () item_shells = +{ + self.touch = ammo_touch; + if ((self.spawnflags & WEAPON_BIG2)) + { + precache_model ("maps/b_shell1.bsp"); + setmodel (self, "maps/b_shell1.bsp"); + self.aflag = 40; + } + else + { + precache_model ("maps/b_shell0.bsp"); + setmodel (self, "maps/b_shell0.bsp"); + self.aflag = 20; + } + self.weapon = WEAPON_BIG2; + self.netname = "shells"; + setsize (self, VEC_ORIGIN, '32 32 56'); + StartItem (); +}; + +void () item_spikes = +{ + self.touch = ammo_touch; + if ((self.spawnflags & WEAPON_BIG2)) + { + precache_model ("maps/b_nail1.bsp"); + setmodel (self, "maps/b_nail1.bsp"); + self.aflag = 50; + } + else + { + precache_model ("maps/b_nail0.bsp"); + setmodel (self, "maps/b_nail0.bsp"); + self.aflag = 25; + } + self.weapon = H_MEGA; + self.netname = "nails"; + setsize (self, VEC_ORIGIN, '32 32 56'); + StartItem (); +}; + +void () item_rockets = +{ + self.touch = ammo_touch; + if ((self.spawnflags & WEAPON_BIG2)) + { + precache_model ("maps/b_rock1.bsp"); + setmodel (self, "maps/b_rock1.bsp"); + self.aflag = TE_LAVASPLASH; + } + else + { + precache_model ("maps/b_rock0.bsp"); + setmodel (self, "maps/b_rock0.bsp"); + self.aflag = TE_LIGHTNING1; + } + self.weapon = AS_MELEE; + self.netname = "rockets"; + setsize (self, VEC_ORIGIN, '32 32 56'); + StartItem (); +}; + +void () item_cells = +{ + self.touch = ammo_touch; + if ((self.spawnflags & WEAPON_BIG2)) + { + precache_model ("maps/b_batt1.bsp"); + setmodel (self, "maps/b_batt1.bsp"); + self.aflag = 12; + } + else + { + precache_model ("maps/b_batt0.bsp"); + setmodel (self, "maps/b_batt0.bsp"); + self.aflag = TE_LIGHTNING2; + } + self.weapon = AS_MISSILE; + self.netname = "cells"; + setsize (self, VEC_ORIGIN, '32 32 56'); + StartItem (); +}; + + +/*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big +DO NOT USE THIS!!!! IT WILL BE REMOVED! +*/ + +#define WEAPON_SHOTGUN 1 +float WEAPON_ROCKET = 2; +float WEAPON_SPIKES = 4; +float WEAPON_MASK = 7; +float WEAPON_BIG = 8; +void () item_weapon = +{ + self.touch = ammo_touch; + if ((self.spawnflags & WEAPON_SHOTGUN)) + { + if ((self.spawnflags & WEAPON_BIG)) + { + precache_model ("maps/b_shell1.bsp"); + setmodel (self, "maps/b_shell1.bsp"); + self.aflag = 40; + } + else + { + precache_model ("maps/b_shell0.bsp"); + setmodel (self, "maps/b_shell0.bsp"); + self.aflag = 20; + } + self.weapon = WEAPON_SHOTGUN; + self.netname = "shells"; + } + if ((self.spawnflags & WEAPON_SPIKES)) + { + if ((self.spawnflags & WEAPON_BIG)) + { + precache_model ("maps/b_nail1.bsp"); + setmodel (self, "maps/b_nail1.bsp"); + self.aflag = 40; + } + else + { + precache_model ("maps/b_nail0.bsp"); + setmodel (self, "maps/b_nail0.bsp"); + self.aflag = 20; + } + self.weapon = WEAPON_ROCKET; + self.netname = "spikes"; + } + if ((self.spawnflags & WEAPON_ROCKET)) + { + if ((self.spawnflags & WEAPON_BIG)) + { + precache_model ("maps/b_rock1.bsp"); + setmodel (self, "maps/b_rock1.bsp"); + self.aflag = TE_LAVASPLASH; + } + else + { + precache_model ("maps/b_rock0.bsp"); + setmodel (self, "maps/b_rock0.bsp"); + self.aflag = TE_LIGHTNING1; + } + self.weapon = AS_MELEE; + self.netname = "rockets"; + } + setsize (self, VEC_ORIGIN, '32 32 56'); + StartItem (); +}; + + +/* +=============================================================================== + +KEYS + +=============================================================================== +*/ + +void() key_touch = +{ + if (other.classname != "player") + return; + if (other.health <= 0) + return; + if (other.items & self.items) + return; + + sprint3 (other, PRINT_LOW, "You got the ", self.netname, "\n"); + + sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + other.items = other.items | self.items; + + self.solid = SOLID_NOT; + self.model = string_null; + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +void() key_setsounds = +{ + switch (world.worldtype) + { + case WT_MEDIEVAL: + precache_sound ("misc/medkey.wav"); + self.noise = "misc/medkey.wav"; + break; + case WT_METAL: + precache_sound ("misc/runekey.wav"); + self.noise = "misc/runekey.wav"; + break; + case WT_BASE: + precache_sound2 ("misc/basekey.wav"); + self.noise = "misc/basekey.wav"; + break; + } +}; + +/*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) +SILVER key +In order for keys to work +you MUST set your maps +worldtype to one of the +following: +0: medieval +1: metal +2: base +*/ + +void() item_key1 = +{ + if (deathmatch) + { + remove(self); + return; + } + + switch (world.worldtype) + { + case WT_MEDIEVAL: + precache_model ("progs/w_s_key.mdl"); + setmodel (self, "progs/w_s_key.mdl"); + self.netname = "silver key"; + break; + case WT_METAL: + precache_model ("progs/m_s_key.mdl"); + setmodel (self, "progs/m_s_key.mdl"); + self.netname = "silver runekey"; + break; + case WT_BASE: + precache_model2 ("progs/b_s_key.mdl"); + setmodel (self, "progs/b_s_key.mdl"); + self.netname = "silver keycard"; + break; + } + + key_setsounds(); + self.touch = key_touch; + self.items = IT_KEY1; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + +/*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) +GOLD key +In order for keys to work +you MUST set your maps +worldtype to one of the +following: +0: medieval +1: metal +2: base +*/ + +void() item_key2 = +{ + if (deathmatch) + { + remove(self); + return; + } + + switch (world.worldtype) + { + case WT_MEDIEVAL: + precache_model ("progs/w_g_key.mdl"); + setmodel (self, "progs/w_g_key.mdl"); + self.netname = "gold key"; + break; + case WT_METAL: + precache_model ("progs/m_g_key.mdl"); + setmodel (self, "progs/m_g_key.mdl"); + self.netname = "gold runekey"; + break; + case WT_BASE: + precache_model2 ("progs/b_g_key.mdl"); + setmodel (self, "progs/b_g_key.mdl"); + self.netname = "gold keycard"; + break; + } + key_setsounds(); + self.touch = key_touch; + self.items = IT_KEY2; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + + +/* +=============================================================================== + +END OF LEVEL RUNES + +=============================================================================== +*/ + +void() sigil_touch = +{ + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + centerprint (other, "You got the rune!"); + + sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + self.model = string_null; + serverflags = serverflags | (self.spawnflags & 15); + self.classname = ""; // so rune doors won't find it + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +/*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4 +End of level sigil, pick up to end episode and return to jrstart. +*/ + +void() item_sigil = +{ + if (deathmatch) + { + remove(self); + return; + } + + if (!self.spawnflags) + objerror ("no spawnflags"); + + precache_sound ("misc/runekey.wav"); + self.noise = "misc/runekey.wav"; + + switch (self.spawnflags & 15) + { + case 1: + precache_model ("progs/end1.mdl"); + setmodel (self, "progs/end1.mdl"); + break; + case 2: + precache_model2 ("progs/end2.mdl"); + setmodel (self, "progs/end2.mdl"); + break; + case 4: + precache_model2 ("progs/end3.mdl"); + setmodel (self, "progs/end3.mdl"); + break; + case 8: + precache_model2 ("progs/end4.mdl"); + setmodel (self, "progs/end4.mdl"); + break; + } + + self.touch = sigil_touch; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + +/* +=============================================================================== + +POWERUPS + +=============================================================================== +*/ + +void() powerup_touch = +{ + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + sprint3 (other, PRINT_LOW, "You got the ", self.netname, "\n"); + + self.mdl = self.model; + + if (deathmatch) + { + if (self.items & (IT_INVULNERABILITY | IT_INVISIBILITY)) + self.nextthink = time + 60*5; + else + self.nextthink = time + 60; + + self.think = SUB_regen; + } + + sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + other.items = other.items | self.items; + self.model = string_null; + +// do the apropriate action + switch (self.items) + { + case IT_SUIT: + other.rad_time = 1; + other.radsuit_finished = time + 30; + break; + case IT_INVULNERABILITY: + other.invincible_time = 1; + other.invincible_finished = time + 30; + break; + case IT_INVISIBILITY: + other.invisible_time = 1; + other.invisible_finished = time + 30; + break; + case IT_QUAD: + if (deathmatch == 4) + { + other.armortype = 0; + other.armorvalue = 0; + other.ammo_cells_real = 0; + W_UpdateAmmoCounts(other); + } + other.super_time = 1; + other.super_damage_finished = time + 30; + break; + } + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + + +/*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32) +Player is invulnerable for 30 seconds +*/ +void() item_artifact_invulnerability = +{ + self.touch = powerup_touch; + + precache_model ("progs/invulner.mdl"); + precache_sound ("items/protect.wav"); + precache_sound ("items/protect2.wav"); + precache_sound ("items/protect3.wav"); + self.noise = "items/protect.wav"; + setmodel (self, "progs/invulner.mdl"); + self.netname = "Pentagram of Protection"; + self.effects = self.effects | ef_red; + self.items = IT_INVULNERABILITY; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + +/*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32) +Player takes no damage from water or slime for 30 seconds +*/ +void() item_artifact_envirosuit = +{ + self.touch = powerup_touch; + + precache_model ("progs/suit.mdl"); + precache_sound ("items/suit.wav"); + precache_sound ("items/suit2.wav"); + self.noise = "items/suit.wav"; + setmodel (self, "progs/suit.mdl"); + self.netname = "Biosuit"; + self.items = IT_SUIT; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + +/*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32) +Player is invisible for 30 seconds +*/ +void() item_artifact_invisibility = +{ + self.touch = powerup_touch; + + precache_model ("progs/invisibl.mdl"); + precache_sound ("items/inv1.wav"); + precache_sound ("items/inv2.wav"); + precache_sound ("items/inv3.wav"); + self.noise = "items/inv1.wav"; + setmodel (self, "progs/invisibl.mdl"); + self.netname = "Ring of Shadows"; + self.items = IT_INVISIBILITY; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + +/*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32) +The next attack from the player will do 4x damage +*/ +void() item_artifact_super_damage = +{ + self.touch = powerup_touch; + + precache_model ("progs/quaddama.mdl"); + precache_sound ("items/damage.wav"); + precache_sound ("items/damage2.wav"); + precache_sound ("items/damage3.wav"); + self.noise = "items/damage.wav"; + setmodel (self, "progs/quaddama.mdl"); + if (deathmatch == 4) + self.netname = "OctaPower"; + else + self.netname = "Quad Damage"; + self.items = IT_QUAD; + self.effects = self.effects | ef_blue; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + + +/* +=============================================================================== + +PLAYER BACKPACKS + +=============================================================================== +*/ + +void () BackpackTouch = +{ + local string s; + local float best; + local float old; + local float new; + local entity stemp; + local float acount; + + if ((other.classname != "player")) + { + return; + } + if ((other.health <= MSG_BROADCAST)) + { + return; + } + acount = MSG_BROADCAST; + sprint (other, "You get "); + if (self.items) + { + if (((other.items & self.items) == MSG_BROADCAST)) + { + acount = WEAPON_SHOTGUN; + sprint (other, "the "); + sprint (other, self.netname); + } + } + stemp = self; + self = other; + best = W_BestWeapon (); + self = stemp; + other.exshells = (other.exshells + self.exshells); + other.exnails = (other.exnails + self.exnails); + other.exrockets = (other.exrockets + self.exrockets); + other.excells = (other.excells + self.excells); + new = self.items; + if (!new) + { + new = other.weapon; + } + old = other.items; + other.items = (other.items | new); + bound_other_ammo (); + if (self.exshells) + { + if (acount) + { + sprint (other, ", "); + } + acount = WEAPON_SHOTGUN; + s = ftos (self.exshells); + sprint (other, s); + sprint (other, " shells"); + } + if (self.exnails) + { + if (acount) + { + sprint (other, ", "); + } + acount = WEAPON_SHOTGUN; + s = ftos (self.exnails); + sprint (other, s); + sprint (other, " nails"); + } + if (self.exrockets) + { + if (acount) + { + sprint (other, ", "); + } + acount = WEAPON_SHOTGUN; + s = ftos (self.exrockets); + sprint (other, s); + sprint (other, " rockets"); + } + if (self.excells) + { + if (acount) + { + sprint (other, ", "); + } + acount = WEAPON_SHOTGUN; + s = ftos (self.excells); + sprint (other, s); + sprint (other, " cells"); + } + sprint (other, "\n"); + sound (other, CHAN_ITEM, "weapons/lock4.wav", WEAPON_SHOTGUN, ATTN_NORM); + stuffcmd (other, "bf\n"); + remove (self); + self = other; +}; + +void () DropBackpack = +{ + local entity item; + + if (!(((self.exshells + self.exnails) + self.exrockets) + self.excells)) + { + return; + } + item = spawn (); + item.origin = (self.origin - '0 0 24'); + item.items = self.weapon; + if ((item.items == IT_AXE)) + { + item.netname = "Axe"; + } + else + { + if ((item.items == IT_SHOTGUN)) + { + item.netname = "Pistol"; + } + else + { + if ((item.items == IT_SUPER_SHOTGUN)) + { + item.netname = "SMG"; + } + else + { + if ((item.items == IT_NAILGUN)) + { + item.netname = "Rifle"; + } + else + { + if ((item.items == IT_SUPER_NAILGUN)) + { + item.netname = "Super Nailgun"; + } + else + { + if ((item.items == IT_GRENADE_LAUNCHER)) + { + item.netname = "Grenade Launcher"; + } + else + { + if ((item.items == IT_ROCKET_LAUNCHER)) + { + item.netname = "Rocket Launcher"; + } + else + { + if ((item.items == IT_LIGHTNING)) + { + item.netname = "Thunderbolt"; + } + else + { + item.netname = ""; + } + } + } + } + } + } + } + } + item.exshells = self.exshells; + item.exnails = self.exnails; + item.exrockets = self.exrockets; + item.excells = self.excells; + item.velocity_z = 300; + item.velocity_x = (-100 + (random () * 200)); + item.velocity_y = (-100 + (random () * 200)); + item.flags = FL_ITEM; + item.solid = SOLID_TRIGGER; + item.movetype = MOVETYPE_TOSS; + setmodel (item, "progs/backpack.mdl"); + setsize (item, '-16 -16 0', '16 16 56'); + item.touch = BackpackTouch; + item.nextthink = (time + 120); + item.think = SUB_Remove; +}; + +/* +======================== +Grenades By mexicouger +------------------------ +*/ +void() plasma_nade_touch = +{ +if (other.classname != "player") + return; + + if (other.plasma_lives >= 4) { + } + + else { + other.plasma_lives += 1; + sprint (other, "picked up a Plasma grenade\n"); + sound (self, CHAN_WEAPON, "weapons/pbounce.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.mdl = self.model; + self.model = string_null; + self.solid = SOLID_NOT; + + if (deathmatch) { + self.nextthink = time + 20; + self.think = SUB_regen; + } + activator = other; + SUB_UseTargets(); +} +}; + +void() nade_touch = +{ +if (other.classname != "player") + return; + + if (other.nade_lives >= 4) { + } + + else { + other.nade_lives += 1; + sprint (other, "picked up a Frag grenade\n"); + sound (self, CHAN_WEAPON, "weapons/grenpick.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.mdl = self.model; + self.model = string_null; + self.solid = SOLID_NOT; + + if (deathmatch) { + self.nextthink = time + 20; + self.think = SUB_regen; + } + activator = other; + SUB_UseTargets(); +} +}; + +void() item_nade = +{ + self.touch = nade_touch; + setmodel(self, "progs/fraggren.mdl"); + precache_sound ("weapons/grenpick.wav"); + setsize (self, '0 0 0', ' 2 2 2'); + StartItem(); +}; + +void() item_plasma_nade = +{ + self.touch = plasma_nade_touch; + setmodel(self, "progs/plasgren.mdl"); + setsize (self, '0 0 0', ' 2 2 2'); + StartItem(); +}; + diff --git a/r17/Revamped src/Revamped QC/misc.qc b/r17/Revamped src/Revamped QC/misc.qc new file mode 100755 index 00000000..c8bdf218 --- /dev/null +++ b/r17/Revamped src/Revamped QC/misc.qc @@ -0,0 +1,612 @@ + +/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4) +Used as a positional target for spotlights, etc. +*/ +var void() info_null = SUB_Remove; + +/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4) +Used as a positional target for lightning. +*/ +void() info_notnull = +{ +}; + +//============================================================================ + +float START_OFF = 1; + +void() light_use = +{ + if (self.spawnflags & START_OFF) + { + lightstyle(self.style, "m"); + self.spawnflags = self.spawnflags - START_OFF; + } + else + { + lightstyle(self.style, "a"); + self.spawnflags = self.spawnflags | START_OFF; + } +}; + +/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF +Non-displayed light. +Default light value is 300 +Default style is 0 +If targeted, it will toggle between on or off. +*/ +void() light = +{ + if (!self.targetname) + { // inert light + remove(self); + return; + } + + if (self.style >= 32) + { + self.use = light_use; + if (self.spawnflags & START_OFF) + lightstyle(self.style, "a"); + else + lightstyle(self.style, "m"); + } +}; + +/*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF +Non-displayed light. +Default light value is 300 +Default style is 0 +If targeted, it will toggle between on or off. +Makes steady fluorescent humming sound +*/ +void() light_fluoro = +{ + if (self.style >= 32) + { + self.use = light_use; + if (self.spawnflags & START_OFF) + lightstyle(self.style, "a"); + else + lightstyle(self.style, "m"); + } + + precache_sound ("ambience/fl_hum1.wav"); + ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8) +Non-displayed light. +Default light value is 300 +Default style is 10 +Makes sparking, broken fluorescent sound +*/ +void() light_fluorospark = +{ + if (!self.style) + self.style = 10; + + precache_sound ("ambience/buzz1.wav"); + ambientsound (self.origin, "ambience/buzz1.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8) +Sphere globe light. +Default light value is 300 +Default style is 0 +*/ +void() light_globe = +{ + precache_model ("progs/s_light.spr"); + setmodel (self, "progs/s_light.spr"); + self.alpha = 0.5; + makestatic (self); +}; + +void() FireAmbient = +{ + precache_sound ("ambience/fire1.wav"); +// attenuate fast + ambientsound (self.origin, "ambience/fire1.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20) +Short wall torch +Default light value is 200 +Default style is 0 +*/ +void() light_torch_small_walltorch = +{ + precache_model ("progs/flame.mdl"); + setmodel (self, "progs/flame.mdl"); + FireAmbient (); + makestatic (self); +}; + +/*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18) +Large yellow flame ball +*/ +void() light_flame_large_yellow = +{ + precache_model ("progs/flame2.mdl"); + setmodel (self, "progs/flame2.mdl"); + self.frame = 1; + self.alpha = 0.5; + FireAmbient (); + makestatic (self); +}; + +/*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) START_OFF +Small yellow flame ball +*/ +void() light_flame_small_yellow = +{ + precache_model ("progs/flame2.mdl"); + setmodel (self, "progs/flame2.mdl"); + self.alpha = 0.5; + FireAmbient (); + makestatic (self); +}; + +/*QUAKED light_flame_small_white (0 1 0) (-10 -10 -40) (10 10 40) START_OFF +Small white flame ball +*/ +void() light_flame_small_white = +{ + precache_model ("progs/flame2.mdl"); + setmodel (self, "progs/flame2.mdl"); + self.alpha = 0.5; + FireAmbient (); + makestatic (self); +}; + +//============================================================================ + + +/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8) +Lava Balls +*/ + +void() fire_fly = +{ + local vector vel; + + vel_x = (random() * 100) - 50; + vel_y = (random() * 100) - 50; + vel_z = self.speed + (random() * 200); + + PRJ_FireProjectile (world, "progs/lavaball.mdl", self.origin, vel, PE_NONE, 20, MOD_FIREBALL, 5); + newmis.movetype = MOVETYPE_BOUNCE; + newmis.alpha = 0.9; + + self.nextthink = time + (random() * 5) + 3; + self.think = fire_fly; +}; + +void() misc_fireball = +{ + + precache_model ("progs/lavaball.mdl"); + self.classname = "fireball"; + self.nextthink = time + 0.1 + (random() * 4.9); + self.think = fire_fly; + if (!self.speed) + self.speed = 1000; +}; + +//============================================================================ + + +void() barrel_explode = +{ + self.takedamage = DAMAGE_NO; + self.classname = "explo_box"; + // did say self.owner, self.enemy should be set by Killed function + T_RadiusDamage (self, self.enemy, 160, 200, self, MOD_EXPLOBOX); + TE_explosion(self.origin + '0 0 32'); + remove (self); +}; + + + +/*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64) +TESTING THING +*/ + +void() misc_explobox = +{ + local float oldz; + + self.solid = SOLID_BBOX; + self.movetype = MOVETYPE_NONE; + precache_model ("maps/b_explob.bsp"); + setmodel (self, "maps/b_explob.bsp"); + setsize (self, '0 0 0', '32 32 64'); + precache_sound ("weapons/r_exp3.wav"); + self.health = 20; + self.th_die = barrel_explode; + self.takedamage = DAMAGE_AIM; + + self.origin_z = self.origin_z + 2; + oldz = self.origin_z; + droptofloor(); + if (oldz - self.origin_z > 250) + { + dprint ("item fell out of level at "); + dprint (vtos(self.origin)); + dprint ("\n"); + remove(self); + } +}; + + + + +/*QUAKED misc_explobox2 (0 .5 .8) (0 0 0) (32 32 64) +Smaller exploding box, REGISTERED ONLY +*/ + +void() misc_explobox2 = +{ + local float oldz; + + self.solid = SOLID_BBOX; + self.movetype = MOVETYPE_NONE; + precache_model2 ("maps/b_exbox2.bsp"); + setmodel (self, "maps/b_exbox2.bsp"); + setsize (self, '0 0 0', '32 32 32'); + precache_sound ("weapons/r_exp3.wav"); + self.health = 20; + self.th_die = barrel_explode; + self.takedamage = DAMAGE_AIM; + + self.origin_z = self.origin_z + 2; + oldz = self.origin_z; + droptofloor(); + if (oldz - self.origin_z > 250) + { + dprint ("item fell out of level at "); + dprint (vtos(self.origin)); + dprint ("\n"); + remove(self); + } +}; + +//============================================================================ + +float SPAWNFLAG_SUPERSPIKE = 1; +float SPAWNFLAG_LASER = 2; + +void() spikeshooter_use = +{ + if (self.spawnflags & SPAWNFLAG_LASER) + { + sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM); + PRJ_FireProjectile(self, + "progs/laser.mdl", + self.origin, + self.movedir * 600, + PE_LASER, + 15, + MOD_LASER, + 5); + newmis.effects |= EF_DIMLIGHT; + newmis.alpha = 0.5; + } + else + { + sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM); + if (self.spawnflags & SPAWNFLAG_SUPERSPIKE) + { + PRJ_FireProjectile(self, + "progs/s_spike.mdl", + self.origin, + self.movedir * 500, + PE_SUPERSPIKE, + 18, + MOD_SUPERSPIKE, + 6); + } + else + { + PRJ_FireProjectile(self, + "progs/spike.mdl", + self.origin, + self.movedir * 500, + PE_SPIKE, + 9, + MOD_SPIKE, + 6); + } + } +}; + +void() shooter_think = +{ + spikeshooter_use (); + self.nextthink = time + self.wait; + newmis.velocity = self.movedir * 500; +}; + + +/*QUAKED trap_spikeshooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser +When triggered, fires a spike in the direction set in QuakeEd. +Laser is only for REGISTERED. +*/ + +void() trap_spikeshooter = +{ + SetMovedir (); + self.use = spikeshooter_use; + if (self.spawnflags & SPAWNFLAG_LASER) + { + precache_model2 ("progs/laser.mdl"); + + precache_sound2 ("enforcer/enfire.wav"); + precache_sound2 ("enforcer/enfstop.wav"); + } + else + precache_sound ("weapons/spike2.wav"); +}; + + +/*QUAKED trap_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser +Continuously fires spikes. +"wait" time between spike (1.0 default) +"nextthink" delay before firing first spike, so multiple shooters can be stagered. +*/ +void() trap_shooter = +{ + trap_spikeshooter (); + + if (self.wait == 0) + self.wait = 1; + self.nextthink = time + self.wait; + self.think = shooter_think; +}; + + + +/* +=============================================================================== + + +=============================================================================== +*/ + +void() make_bubbles; +void() bubble_bob; + +/*QUAKED air_bubbles (0 .5 .8) (-8 -8 -8) (8 8 8) + +testing air bubbles +*/ + +noref var void() air_bubbles = SUB_Remove; + +void() make_bubbles = +{ +local entity bubble; + + bubble = spawn(); + setmodel (bubble, "progs/s_bubble.spr"); + setorigin (bubble, self.origin); + bubble.movetype = MOVETYPE_NOCLIP; + bubble.solid = SOLID_NOT; + bubble.velocity = '0 0 15'; + bubble.nextthink = time + 0.5; + bubble.think = bubble_bob; + bubble.classname = "bubble"; + bubble.frame = 0; + bubble.bubble_state = 0; + bubble.alpha = 0.4; + setsize (bubble, '-8 -8 -8', '8 8 8'); + self.nextthink = time + random() + 0.5; + self.think = make_bubbles; +}; + +void() bubble_split = +{ +local entity bubble; + bubble = spawn(); + setmodel (bubble, "progs/s_bubble.spr"); + setorigin (bubble, self.origin); + bubble.movetype = MOVETYPE_NOCLIP; + bubble.solid = SOLID_NOT; + bubble.velocity = self.velocity; + bubble.nextthink = time + 0.5; + bubble.think = bubble_bob; + bubble.classname = "bubble"; + bubble.frame = 1; + bubble.bubble_state = 10; + setsize (bubble, '-8 -8 -8', '8 8 8'); + self.frame = 1; + self.bubble_state = 10; + if (self.waterlevel != 3) + remove (self); +}; + +void() bubble_bob = +{ +local float rnd1, rnd2, rnd3; + + self.bubble_state = self.bubble_state + 1; + if (self.bubble_state == 4) + bubble_split(); + if (self.bubble_state == 20) + remove(self); + + rnd1 = self.velocity_x + (-10 + (random() * 20)); + rnd2 = self.velocity_y + (-10 + (random() * 20)); + rnd3 = self.velocity_z + 10 + random() * 10; + + if (rnd1 > 10) + rnd1 = 5; + if (rnd1 < -10) + rnd1 = -5; + + if (rnd2 > 10) + rnd2 = 5; + if (rnd2 < -10) + rnd2 = -5; + + if (rnd3 < 10) + rnd3 = 15; + if (rnd3 > 30) + rnd3 = 25; + + self.velocity_x = rnd1; + self.velocity_y = rnd2; + self.velocity_z = rnd3; + + self.nextthink = time + 0.5; + self.think = bubble_bob; +}; + +/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~> +~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/ + +/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8) + +Just for the debugging level. Don't use +*/ + +noref var void() viewthing = SUB_Remove; + +/* +============================================================================== + +SIMPLE BMODELS + +============================================================================== +*/ + +void() func_wall_use = +{ // change to alternate textures + self.frame = 1 - self.frame; +}; + +/*QUAKED func_wall (0 .5 .8) ? +This is just a solid wall if not inhibitted +*/ +void() func_wall = +{ + self.angles = '0 0 0'; + self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything + self.solid = SOLID_BSP; + self.use = func_wall_use; + setmodel (self, self.model); +}; + + +/*QUAKED func_illusionary (0 .5 .8) ? +A simple entity that looks solid but lets you walk through it. +*/ +void() func_illusionary = +{ + self.angles = '0 0 0'; + self.movetype = MOVETYPE_NONE; + self.solid = SOLID_NOT; + setmodel (self, self.model); + makestatic (self); +}; + +/*QUAKED func_episodegate (0 .5 .8) ? E1 E2 E3 E4 +This bmodel will appear if the episode has allready been completed, so players can't reenter it. +*/ +void() func_episodegate = +{ + if (!(serverflags & self.spawnflags)) + return; // can still enter episode + + self.angles = '0 0 0'; + self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything + self.solid = SOLID_BSP; + self.use = func_wall_use; + setmodel (self, self.model); +}; + +/*QUAKED func_bossgate (0 .5 .8) ? +This bmodel appears unless players have all of the episode sigils. +*/ +void() func_bossgate = +{ + if ( (serverflags & 15) == 15) + { + remove(self); + return; // all episodes completed + } + self.angles = '0 0 0'; + self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything + self.solid = SOLID_BSP; + self.use = func_wall_use; + setmodel (self, self.model); +}; + +//============================================================================ +/*QUAKED ambient_suck_wind (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_suck_wind = +{ + precache_sound ("ambience/suck1.wav"); + ambientsound (self.origin, "ambience/suck1.wav", 1, ATTN_STATIC); +}; + +/*QUAKED ambient_drone (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_drone = +{ + precache_sound ("ambience/drone6.wav"); + ambientsound (self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED ambient_flouro_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_flouro_buzz = +{ + precache_sound ("ambience/buzz1.wav"); + ambientsound (self.origin, "ambience/buzz1.wav", 1, ATTN_STATIC); +}; +/*QUAKED ambient_drip (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_drip = +{ + precache_sound ("ambience/drip1.wav"); + ambientsound (self.origin, "ambience/drip1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_comp_hum (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_comp_hum = +{ + precache_sound ("ambience/comp1.wav"); + ambientsound (self.origin, "ambience/comp1.wav", 1, ATTN_STATIC); +}; +/*QUAKED ambient_thunder (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_thunder = +{ + precache_sound ("ambience/thunder1.wav"); + ambientsound (self.origin, "ambience/thunder1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_light_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_light_buzz = +{ + precache_sound ("ambience/fl_hum1.wav"); + ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_swamp1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_swamp1 = +{ + precache_sound ("ambience/swamp1.wav"); + ambientsound (self.origin, "ambience/swamp1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_swamp2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_swamp2 = +{ + precache_sound ("ambience/swamp2.wav"); + ambientsound (self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC); +}; + \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/monsters.qc b/r17/Revamped src/Revamped QC/monsters.qc new file mode 100755 index 00000000..9e261688 --- /dev/null +++ b/r17/Revamped src/Revamped QC/monsters.qc @@ -0,0 +1,217 @@ +/* ALL MONSTERS SHOULD BE 1 0 0 IN COLOR */ + +/* +================ +monster_use + +Using a monster makes it angry at the current activator +================ +*/ +void() monster_use = +{ + if (self.enemy) + return; + if (self.health <= 0) + return; + if (activator.items & IT_INVISIBILITY) + return; + if (activator.flags & FL_NOTARGET) + return; + if (activator.flags & FL_CLIENT) + return; + + // delay reaction so if the monster is teleported, its sound is still + // heard + self.enemy = activator; + self.nextthink = time + 0.1; + self.think = FoundTarget; +}; + +/* +================ +monster_death_use + +When a mosnter dies, it fires all of its targets with the current +enemy as activator. +================ +*/ +void() monster_death_use = +{ + // fall to ground + if (self.flags & FL_FLY) + self.flags = self.flags - FL_FLY; + if (self.flags & FL_SWIM) + self.flags = self.flags - FL_SWIM; + + if (!self.target) + return; + + activator = self.enemy; + SUB_UseTargets (); +}; + +//============================================================================ + +void() walkmonster_start_go = +{ + self.origin_z = self.origin_z + 1; // raise off floor a bit + droptofloor(); + + if (!walkmove(0,0)) + { + dprint ("walkmonster in wall at: "); + dprint (vtos(self.origin)); + dprint ("\n"); + } + + self.takedamage = DAMAGE_AIM; + + self.ideal_yaw = self.angles * '0 1 0'; + if (!self.yaw_speed) + self.yaw_speed = 20; + self.view_ofs = '0 0 25'; + self.use = monster_use; + + self.flags = self.flags | FL_MONSTER; + + if (self.target) + { + self.goalentity = self.movetarget = find(world, targetname, self.target); + self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); + if (!self.movetarget) + { + dprint ("Monster can't find target at "); + dprint (vtos(self.origin)); + dprint ("\n"); + } +// this used to be an objerror + if (self.movetarget.classname == "path_corner") + self.th_walk (); + else + self.pausetime = 99999999; + self.th_stand (); + } + else + { + self.pausetime = 99999999; + self.th_stand (); + } + +// spread think times so they don't all happen at same time + self.nextthink = time + 0.1 + random()*0.5; +}; + + +void() walkmonster_start = +{ +// delay drop to floor to make sure all doors have been spawned +// spread think times so they don't all happen at same time + self.nextthink = time + 0.1 + random()*0.5; + self.think = walkmonster_start_go; + total_monsters = total_monsters + 1; +}; + + + +void() flymonster_start_go = +{ + self.takedamage = DAMAGE_AIM; + + self.ideal_yaw = self.angles * '0 1 0'; + if (!self.yaw_speed) + self.yaw_speed = 10; + self.view_ofs = '0 0 25'; + self.use = monster_use; + + self.flags = self.flags | FL_FLY | FL_MONSTER; + + if (!walkmove(0,0)) + { + dprint ("flymonster in wall at: "); + dprint (vtos(self.origin)); + dprint ("\n"); + } + + if (self.target) + { + self.goalentity = self.movetarget = find(world, targetname, self.target); + if (!self.movetarget) + { + dprint ("Monster can't find target at "); + dprint (vtos(self.origin)); + dprint ("\n"); + } +// this used to be an objerror + if (self.movetarget.classname == "path_corner") + self.th_walk (); + else + self.pausetime = 99999999; + self.th_stand (); + } + else + { + self.pausetime = 99999999; + self.th_stand (); + } +}; + +void() flymonster_start = +{ +// spread think times so they don't all happen at same time + self.nextthink = time + 0.1 + random()*0.5; + self.think = flymonster_start_go; + total_monsters = total_monsters + 1; +}; + + +void() swimmonster_start_go = +{ + if (deathmatch) + { + remove(self); + return; + } + + self.takedamage = DAMAGE_AIM; +// total_monsters = total_monsters + 1; + + self.ideal_yaw = self.angles * '0 1 0'; + if (!self.yaw_speed) + self.yaw_speed = 10; + self.view_ofs = '0 0 10'; + self.use = monster_use; + + self.flags = self.flags | FL_SWIM | FL_MONSTER; + + if (self.target) + { + self.goalentity = self.movetarget = find(world, targetname, self.target); + if (!self.movetarget) + { + dprint ("Monster can't find target at "); + dprint (vtos(self.origin)); + dprint ("\n"); + } +// this used to be an objerror + self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); + self.th_walk (); + } + else + { + self.pausetime = 99999999; + self.th_stand (); + } + +// spread think times so they don't all happen at same time + self.nextthink = time + 0.1 + random()*0.5; +}; + +void() swimmonster_start = +{ +// spread think times so they don't all happen at same time + self.nextthink = time + 0.1 + random()*0.5; + self.think = swimmonster_start_go; + total_monsters = total_monsters + 1; +}; + + diff --git a/r17/Revamped src/Revamped QC/nomonst.qc b/r17/Revamped src/Revamped QC/nomonst.qc new file mode 100755 index 00000000..21a6d6b2 --- /dev/null +++ b/r17/Revamped src/Revamped QC/nomonst.qc @@ -0,0 +1,20 @@ + +// QC for a monsterless compile + +var void() monster_ogre = SUB_Remove; +var void() monster_demon1 = SUB_Remove; +var void() monster_shambler = SUB_Remove; +var void() monster_knight = SUB_Remove; +var void() monster_army = SUB_Remove; +var void() monster_wizard = SUB_Remove; +var void() monster_dog = SUB_Remove; +var void() monster_zombie = SUB_Remove; +var void() monster_boss = SUB_Remove; +var void() monster_tarbaby = SUB_Remove; +var void() monster_hell_knight = SUB_Remove; +var void() monster_fish = SUB_Remove; +var void() monster_shalrath = SUB_Remove; +var void() monster_enforcer = SUB_Remove; +var void() monster_oldone = SUB_Remove; +var void() event_lightning = SUB_Remove; +var void() path_corner = SUB_Remove; diff --git a/r17/Revamped src/Revamped QC/obituary.qc b/r17/Revamped src/Revamped QC/obituary.qc new file mode 100755 index 00000000..d9249cea --- /dev/null +++ b/r17/Revamped src/Revamped QC/obituary.qc @@ -0,0 +1,359 @@ +// client death messages +enum { + MOD_NONE, + MOD_AXE, + MOD_SHOTGUN, + MOD_SUPERSHOTGUN, + MOD_SPIKE, + MOD_SUPERSPIKE, + MOD_GRENADE, + MOD_ROCKET, + MOD_ROCKETRADIUS, + MOD_SHAFT, + MOD_SHAFTWATER, + MOD_SHAFTSLIME, + MOD_SHAFTLAVA, + MOD_TELEFRAG, + MOD_TELEFRAGDEFLECT, + MOD_SQUISH, + MOD_DROWN, + MOD_SLIME, + MOD_LAVA, + MOD_EXPLOBOX, + MOD_FALL, + MOD_FIREBALL, + MOD_EXIT, + MOD_LASER, + MOD_SELFWATER, + MOD_HURT, + MOD_DOG, + MOD_SOLDIER, + MOD_ENFORCER, + MOD_OGRE, + MOD_WIZARD, + MOD_DEMON, + MOD_KNIGHT, + MOD_HKNIGHT, + MOD_SHALRATH, + MOD_SHAMBLER, + MOD_FISH, + MOD_TARBABY, + MOD_ZOMBIE, + MOD_CHTHON +}; + +void(string targ, INTEGER mod) SuicideMessage = +{ + string s, t, u; + + s = ""; + t = ""; + u = ""; + + switch (mod) + { + case MOD_GRENADE: + s = targ; + t = " tries to put the pin back in"; + break; + case MOD_SHAFTWATER: + s = targ; + t = " discharges into the water."; + break; + case MOD_SHAFTSLIME: + s = targ; + t = " discharges into the slime"; + break; + case MOD_SHAFTLAVA: + s = targ; + t = " discharges into the lava"; + break; + case MOD_TELEFRAGDEFLECT: + s = "Satan's power deflects "; + t = targ; + u = "'s telefrag"; + break; + case MOD_SELFWATER: + s = targ; + t = " electrocutes himself."; + break; + case MOD_EXPLOBOX: + s = targ; + t = " blew himself up"; + break; + default: + s = targ; + t = " becomes bored with life"; + } + + bprint4(PRINT_MEDIUM, s, t, u, "\n"); +} + +void(string targ, string attacker, INTEGER mod) KillMessage = +{ + string s, t, u, v, w; + + s = ""; + t = ""; + u = ""; + v = ""; + w = ""; + + switch (mod) + { + case MOD_AXE: + s = targ; + t = " was ax-murdered by "; + u = attacker; + break; + case MOD_SHOTGUN: + s = targ; + t = " chewed on "; + u = attacker; + v = "'s boomstick"; + break; + case MOD_SUPERSHOTGUN: + s = targ; + t = " ate two loads of "; + u = attacker; + v = "'s buckshot"; + break; + case MOD_SPIKE: + s = targ; + t = " was nailed by "; + u = attacker; + break; + case MOD_SUPERSPIKE: + s = targ; + t = " was punctured by "; + u = attacker; + break; + case MOD_GRENADE: + s = targ; + t = " eats "; + u = attacker; + v = "'s pineapple"; + break; + case MOD_ROCKET: + case MOD_ROCKETRADIUS: + s = targ; + t = " rides "; + u = attacker; + v = "'s rocket"; + break; + case MOD_SHAFT: + s = targ; + t = " accepts "; + u = attacker; + v = "'s shaft"; + break; + case MOD_SHAFTWATER: + case MOD_SHAFTSLIME: + case MOD_SHAFTLAVA: + s = targ; + t = " accepts "; + u = attacker; + v = "'s discharge"; + break; + case MOD_TELEFRAG: + s = targ; + t = " was telefragged by "; + u = attacker; + break; + case MOD_TELEFRAGDEFLECT: + s = targ; + t = " was telefragged by "; + u = attacker; + v = "'s Satan's power"; + break; + case MOD_SQUISH: + s = attacker; + t = " squishes "; + u = targ; + break; + case MOD_EXPLOBOX: + s = targ; + t = " was blown up by "; + u = attacker; + break; + default: + s = targ; + t = " was killed by "; + u = attacker; + } + + bprint6(PRINT_MEDIUM, s, t, u, v, w, "\n"); +} + +void(string targ, string attacker, INTEGER mod) TeamKillMessage = +{ + string s, t, u, v, w; + float rnum; + + s = ""; + t = ""; + u = ""; + v = ""; + w = ""; + + switch (mod) + { + case MOD_SQUISH: + s = attacker; + t = " squishes teammate "; + u = targ; + break; + default: + rnum = random(); + + s = attacker; + + if (rnum < 0.25) + t = " mows down teammate "; + else if (rnum < 0.5) + { + t = " checks his glasses and sees "; + v = " dead"; + } + else if (rnum < 0.75) + { + t = " frags "; + v = " for the other team"; + } + else + t = " loses his friend "; + + u = targ; + } + + bprint6(PRINT_MEDIUM, s, t, u, v, w, "\n"); +} + +void(string targ, INTEGER mod) WorldKillMessage = +{ + string s, t, u; + + s = ""; + t = ""; + u = ""; + + switch (mod) + { + case MOD_SPIKE: + case MOD_SUPERSPIKE: + s = targ; + t = " was spiked"; + break; + case MOD_SQUISH: + s = targ; + t = " was squished"; + break; + case MOD_DROWN: + s = targ; + + if (random() < 0.5) + t = " sleeps with the fishes"; + else + t = " sucks it down"; + break; + case MOD_SLIME: + s = targ; + + if (random() < 0.5) + t = " gulped a load of slime"; + else + t = " can't exist on slime alone"; + break; + case MOD_LAVA: + s = targ; + + if (random() < 0.5) + t = " turned into hot slag"; + else + t = " visits the Volcano God"; + break; + case MOD_EXPLOBOX: + s = targ; + t = " blew up"; + break; + case MOD_FALL: + s = targ; + t = " fell to his death"; + break; + case MOD_FIREBALL: + s = targ; + t = " ate a lavaball"; + break; + case MOD_EXIT: + s = targ; + t = " tried to leave"; + break; + case MOD_LASER: + s = targ; + t = " was zapped"; + break; +#ifdef MONSTERS + case MOD_DOG: + s = targ; + t = " was mauled by a Rottweiler"; + break; + case MOD_SOLDIER: + s = targ; + t = " was shot by a Grunt"; + break; + case MOD_ENFORCER: + s = targ; + t = " was blasted by an Enforcer"; + break; + case MOD_OGRE: + s = targ; + t = " was destroyed by an Ogre"; + break; + case MOD_WIZARD: + s = targ; + t = " was scragged by a Scrag"; + break; + case MOD_DEMON: + s = targ; + t = " was eviscerated by a Fiend"; + break; + case MOD_KNIGHT: + s = targ; + t = " was slashed by a Knight"; + break; + case MOD_HKNIGHT: + s = targ; + t = " was slain by a Death Knight"; + break; + case MOD_SHALRATH: + s = targ; + t = " was exploded by a Vore"; + break; + case MOD_SHAMBLER: + s = targ; + t = " was smashed by a Shambler"; + break; + case MOD_FISH: + s = targ; + t = " was fed to the Rotfish"; + break; + case MOD_TARBABY: + s = targ; + t = " was slimed by a Spawn"; + break; + case MOD_ZOMBIE: + s = targ; + t = " joins the Zombies"; + break; + case MOD_CHTHON: + s = targ; + t = " fell to Chthon's wrath"; + break; +#endif + default: + s = targ; + t = " died"; + } + + bprint4(PRINT_MEDIUM, s, t, u, "\n"); +} \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/plats.qc b/r17/Revamped src/Revamped QC/plats.qc new file mode 100755 index 00000000..1c739d7f --- /dev/null +++ b/r17/Revamped src/Revamped QC/plats.qc @@ -0,0 +1,363 @@ + + +void() plat_center_touch; +void() plat_outside_touch; +void() plat_trigger_use; +void() plat_go_up; +void() plat_go_down; +void() plat_crush; +float PLAT_LOW_TRIGGER = 1; + +void() plat_spawn_inside_trigger = +{ + local entity trigger; + local vector tmin, tmax; + +// +// middle trigger +// + trigger = spawn(); + trigger.touch = plat_center_touch; + trigger.movetype = MOVETYPE_NONE; + trigger.solid = SOLID_TRIGGER; + trigger.enemy = self; + + tmin = self.mins + '25 25 0'; + tmax = self.maxs - '25 25 -8'; + tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8); + if (self.spawnflags & PLAT_LOW_TRIGGER) + tmax_z = tmin_z + 8; + + if (self.size_x <= 50) + { + tmin_x = (self.mins_x + self.maxs_x) / 2; + tmax_x = tmin_x + 1; + } + if (self.size_y <= 50) + { + tmin_y = (self.mins_y + self.maxs_y) / 2; + tmax_y = tmin_y + 1; + } + + setsize (trigger, tmin, tmax); +}; + +void() plat_hit_top = +{ + sound (self, chan_no_phs_add|CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_TOP; + self.think = plat_go_down; + self.nextthink = self.ltime + 3; +}; + +void() plat_hit_bottom = +{ + sound (self, chan_no_phs_add|CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_BOTTOM; +}; + +void() plat_go_down = +{ + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + self.state = STATE_DOWN; + SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom); +}; + +void() plat_go_up = +{ + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + self.state = STATE_UP; + SUB_CalcMove (self.pos1, self.speed, plat_hit_top); +}; + +void() plat_center_touch = +{ + if (other.classname != "player") + return; + + if (other.health <= 0) + return; + + self = self.enemy; + if (self.state == STATE_BOTTOM) + plat_go_up (); + else if (self.state == STATE_TOP) + self.nextthink = self.ltime + 1; // delay going down +}; + +void() plat_outside_touch = +{ + if (other.classname != "player") + return; + + if (other.health <= 0) + return; + +//dprint ("plat_outside_touch\n"); + self = self.enemy; + if (self.state == STATE_TOP) + plat_go_down (); +}; + +void() plat_trigger_use = +{ + if (self.think) + return; // allready activated + plat_go_down(); +}; + + +void() plat_crush = +{ +//dprint ("plat_crush\n"); + + T_Damage (other, self, self, 1, MOD_SQUISH); + + if (self.state == STATE_UP) + plat_go_down (); + else if (self.state == STATE_DOWN) + plat_go_up (); + else + objerror ("plat_crush: bad self.state\n"); +}; + +void() plat_use = +{ + self.use = SUB_Null; + if (self.state != STATE_UP) + objerror ("plat_use: not in up state"); + plat_go_down(); +}; + + +/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER +speed default 150 + +Plats are always drawn in the extended position, so they will light correctly. + +If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat. + +If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height. +Set "sounds" to one of the following: +1) base fast +2) chain slow +*/ + + +void() func_plat = + +{ + + if (!self.t_length) + self.t_length = 80; + if (!self.t_width) + self.t_width = 10; + + if (self.sounds == 0) + self.sounds = 2; +// FIX THIS TO LOAD A GENERIC PLAT SOUND + + if (self.sounds == 1) + { + precache_sound ("plats/plat1.wav"); + precache_sound ("plats/plat2.wav"); + self.noise = "plats/plat1.wav"; + self.noise1 = "plats/plat2.wav"; + } + else if (self.sounds == 2) + { + precache_sound ("plats/medplat1.wav"); + precache_sound ("plats/medplat2.wav"); + self.noise = "plats/medplat1.wav"; + self.noise1 = "plats/medplat2.wav"; + } + + + self.mangle = self.angles; + self.angles = '0 0 0'; + + self.classname = "plat"; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + setorigin (self, self.origin); + setmodel (self, self.model); + setsize (self, self.mins , self.maxs); + + self.blocked = plat_crush; + if (!self.speed) + self.speed = 150; + +// pos1 is the top position, pos2 is the bottom + self.pos1 = self.origin; + self.pos2 = self.origin; + if (self.height) + self.pos2_z = self.origin_z - self.height; + else + self.pos2_z = self.origin_z - self.size_z + 8; + + self.use = plat_trigger_use; + + plat_spawn_inside_trigger (); // the "start moving" trigger + + if (self.targetname) + { + self.state = STATE_UP; + self.use = plat_use; + } + else + { + setorigin (self, self.pos2); + self.state = STATE_BOTTOM; + } +}; + +//============================================================================ + +void() train_next; +void() func_train_find; + +void() train_blocked = +{ + if (time < self.attack_finished) + return; + self.attack_finished = time + 0.5; + T_Damage (other, self, self, self.dmg, MOD_SQUISH); +}; + +void() train_use = +{ + if (self.think != func_train_find) + return; // already activated + train_next(); +}; + +void() train_wait = +{ + if (self.wait) + { + self.nextthink = self.ltime + self.wait; + sound (self, chan_no_phs_add|CHAN_VOICE, self.noise, 1, ATTN_NORM); + } + else + self.nextthink = self.ltime + 0.1; + + self.think = train_next; +}; + +void() train_next = +{ + local entity targ; + + targ = find (world, targetname, self.target); + self.target = targ.target; + if (!self.target) + objerror ("train_next: no next target"); + if (targ.wait) + self.wait = targ.wait; + else + self.wait = 0; + sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + SUB_CalcMove (targ.origin - self.mins, self.speed, train_wait); +}; + +void() func_train_find = + +{ + local entity targ; + + targ = find (world, targetname, self.target); + self.target = targ.target; + setorigin (self, targ.origin - self.mins); + if (!self.targetname) + { // not triggered, so start immediately + self.nextthink = self.ltime + 0.1; + self.think = train_next; + } +}; + +/*QUAKED func_train (0 .5 .8) ? +Trains are moving platforms that players can ride. +The targets origin specifies the min point of the train at each corner. +The train spawns at the first target it is pointing at. +If the train is the target of a button or trigger, it will not begin moving until activated. +speed default 100 +dmg default 2 +sounds +1) ratchet metal + +*/ +void() func_train = +{ + if (!self.speed) + self.speed = 100; + if (!self.target) + objerror ("func_train without a target"); + if (!self.dmg) + self.dmg = 2; + + if (self.sounds == 0) + { + self.noise = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + self.noise1 = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + } + + if (self.sounds == 1) + { + self.noise = ("plats/train2.wav"); + precache_sound ("plats/train2.wav"); + self.noise1 = ("plats/train1.wav"); + precache_sound ("plats/train1.wav"); + } + + self.cnt = 1; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + self.blocked = train_blocked; + self.use = train_use; + self.classname = "train"; + + setmodel (self, self.model); + setsize (self, self.mins , self.maxs); + setorigin (self, self.origin); + +// start trains on the second frame, to make sure their targets have had +// a chance to spawn + self.nextthink = self.ltime + 0.1; + self.think = func_train_find; +}; + +/*QUAKED misc_teleporttrain (0 .5 .8) (-8 -8 -8) (8 8 8) +This is used for the final bos +*/ +void() misc_teleporttrain = +{ + if (!self.speed) + self.speed = 100; + if (!self.target) + objerror ("func_train without a target"); + + self.cnt = 1; + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_PUSH; + self.blocked = train_blocked; + self.use = train_use; + self.avelocity = '100 200 300'; + + self.noise = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + self.noise1 = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + + precache_model2 ("progs/teleport.mdl"); + setmodel (self, "progs/teleport.mdl"); + setsize (self, self.mins , self.maxs); + setorigin (self, self.origin); + +// start trains on the second frame, to make sure their targets have had +// a chance to spawn + self.nextthink = self.ltime + 0.1; + self.think = func_train_find; +}; + diff --git a/r17/Revamped src/Revamped QC/player.qc b/r17/Revamped src/Revamped QC/player.qc new file mode 100755 index 00000000..ceb46cad --- /dev/null +++ b/r17/Revamped src/Revamped QC/player.qc @@ -0,0 +1,1741 @@ +/* +============================================================================== + +SOLITUDE PLAYER ANIMATIONS + +============================================================================== +*/ + +void() bubble_bob; +$cd /raid/quake/id1/models/player_4 +$origin 0 -6 24 +$base base +$skin skin + +#define PLAYER_GUN_IDLE 0 +#define PLAYER_RUN 1 +#define PLAYER_ATTACK1 2 +#define PLAYER_DIE1 3 +#define PLAYER_AXE_IDLE 4 +#define PLAYER_WALK 5 +#define PLAYER_SWIM 6 +#define PLAYER_JUMP 7 +#define PLAYER_ATTACK_STAND 8 +#define PLAYER_ATTACK_SIT 9 +#define PLAYER_THROW_NADE 10 +#define PLAYER_ATTACK_MELEE 11 +#define PLAYER_ATTACK_RUN 12 +#define PLAYER_DEATH1 13 +#define PLAYER_DEATH2 14 +#define PLAYER_RELOAD 15 +#define PLAYER_PAIN 16 // HACK!! (uses death 1 anims) +#define PLAYER_PULL 17 +float (float anim_type, float endframe) Player_GetFrame = +{ + switch (anim_type) + { + case PLAYER_GUN_IDLE: + if (endframe) + return 8; + return 0; + break; + case PLAYER_AXE_IDLE: + return 0; + break; + case PLAYER_RUN: + if (endframe) + return 14; + return 9; + break; + case PLAYER_WALK: + if (endframe) + return 19; + return 15; + break; + case PLAYER_SWIM: + if (endframe) + return 26; + return 19; + break; + case PLAYER_JUMP: + if (endframe) + return 22; + return 20; + break; + case PLAYER_ATTACK_STAND: + if (endframe) + return 25; + return 23; + break; + case PLAYER_ATTACK_SIT: + if (endframe) + return 28; + return 26; + break; + case PLAYER_THROW_NADE: + if (endframe) + return 35; + return 29; + break; + case PLAYER_ATTACK_MELEE: + if (endframe) + return 41; + return 36; + break; + case PLAYER_ATTACK_RUN: + if (endframe) + return 48; + return 42; + break; + case PLAYER_DEATH1: + if (endframe) + return 60; + return 49; + break; + case PLAYER_DEATH2: + if (endframe) + return 71; + return 61; + break; + case PLAYER_RELOAD: + if (endframe) + return 79; + return 70; + break; + case PLAYER_PAIN: + if (endframe) + return 51; + return 49; + break; + case PLAYER_PULL: + if (endframe) + return 79; + return 70; + break; + default: + return 0; + break; + } + + return 0; +}; + +void (entity t_plyr, float t_frame) startwframe = +{ + if (t_plyr.weaponframe < t_frame) + t_plyr.weaponframe = t_frame; +}; + +/* +============================================================================== +PLAYER +============================================================================== +*/ + +void() player_run; + +void() player_stand1 =[ 0, player_stand1 ] +{ + player_run (); // player_run handles most animations. +}; + +void() player_run =[ 0, player_run ] +{ + local float ftype; + + if (vlen(self.velocity) < 150) + ftype = PLAYER_WALK; + else + ftype = PLAYER_RUN; + +// if (self.waterlevel > 0) +// ftype = PLAYER_SWIM; + + if (!self.velocity_x && !self.velocity_y) + { + ftype = PLAYER_GUN_IDLE; + } + + if (self.jump_time > time) + ftype = PLAYER_JUMP; + + if (self.pain_time > time) + ftype = PLAYER_PAIN; + + if (self.weaponstate == WS_FIRING1 && self.weaponframe > 0) { + if (vlen(self.velocity) < 20) + ftype = PLAYER_ATTACK_STAND; + else + ftype = PLAYER_ATTACK_RUN; + } + + self.frame = Player_GetFrame(ftype, 0); + + + if ((self.frame + self.walkframe) > Player_GetFrame(ftype, 1)) + self.walkframe = 0; + + self.frame = self.frame + self.walkframe; + + self.walkframe = self.walkframe + 1; + + //_bprint(ftos(self.frame)," firing anim\n"); +}; + +void () player_shot1 = [ 113, player_shot2 ] +{ + self.weaponframe = 1; + self.effects = (self.effects | EF_MUZZLEFLASH); +}; + +void () player_shot2 = [ 114, player_shot3 ] +{ + self.weaponframe = 2; +}; + +void () player_shot3 = [ 115, player_shot4 ] +{ + self.weaponframe = 3; +}; + +void () player_shot4 = [ 116, player_run ] +{ + self.weaponframe = 0; +}; + +void () player_shot5 = [ 117, player_shot6 ] +{ + self.weaponframe = 5; +}; + +void () player_shot6 = [ 118, player_run ] +{ + self.weaponframe = 6; +}; + +void () player_pistol_reload = +{ + local float amt; + + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if (self.weaponframe == 29) + { + player_run (); + amt = (12 - self.ammo_shells); + if ((self.exshells < amt)) + { + amt = self.exshells; + } + self.exshells = (self.exshells - amt); + self.ammo_shells = (self.ammo_shells + amt); + self.armorvalue = self.exshells; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void () player_skull_reload = +{ + local float amt; + + self.weaponframe = (self.weaponframe + WEAPON_SKULL); + if (self.weaponframe == 29) + { + player_run (); + amt = (12 - self.ammo_shells); + if ((self.exshells < amt)) + { + amt = self.exshells; + } + self.exshells = (self.exshells - amt); + self.ammo_shells = (self.ammo_shells + amt); + self.armorvalue = self.exshells; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +/* +void () player_shotgun_drop = [ 143, player_shotgun_drop ] +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe == SVC_KILLEDMONSTER)) + { + self.weaponframe = 0; + player_run (); + return; + } + self.impulse = MSG_BROADCAST; +}; + +void () player_shotgun_reload = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + + if ((self.weaponframe == 17)) + { + self.exshells2 = (self.exshells2 - 1); + self.ammo_shells2 = (self.ammo_shells2 + 1); + self.armorvalue = self.exshells2; + W_SetCurrentAmmo (); + if ( ((self.ammo_shells2 < W_GetMaxClip( self.weapon, 1 )) || (self.exshells2 == MSG_BROADCAST)) && self.exshells2 > 0) + { + self.weaponframe = 13; + player_shotgun_reload (); + } + else + { + self.weaponframe = 17; + player_shotgun_drop (); + return; + } + } + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +*/ + +void () player_shotgun_reload = +{ + if (self.button0 && self.currentammo > 0) { // Interrupt reload + player_run (); + return; + } + + self.weaponframe += 1; + if (self.weaponframe == 17) + { + self.exshells2 = (self.exshells2 - 1); + self.ammo_shells2 = (self.ammo_shells2 + 1); + self.armorvalue = self.exshells2; + W_UpdateAmmoCounts(self); + if (self.currentammo == W_GetMaxClip( self.weapon, 1 ) || self.armorvalue == 0) { + self.weaponframe = 18; + } + else { + + self.weaponframe = 13; + } + } + else if (self.weaponframe > 17) { + if (self.weaponframe > 20) { + player_run (); + W_SetCurrentAmmo (); + return; + } + } + + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_uzi_reload = +{ + local float amt; + + self.weaponframe += 1; + if ((self.weaponframe > 19)) + { + player_run (); + amt = (W_GetMaxClip(self.weapon, 1) - self.ammo_hshells); + if ((self.exhshells < amt)) + { + amt = self.exhshells; + } + self.exhshells = (self.exhshells - amt); + self.ammo_hshells = (self.ammo_hshells + amt); + self.armorvalue = self.exhshells; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_rl_reload = +{ + local float amt; + + self.weaponframe += 1; + if ((self.weaponframe > 50)) + { + player_run (); + amt = (W_GetMaxClip(self.weapon, 1) - self.ammo_rockets); + if ((self.exrockets < amt)) + { + amt = self.exrockets; + } + self.exrockets = (self.exrockets - amt); + self.ammo_rockets = (self.ammo_rockets + amt); + self.armorvalue = self.exrockets; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_ar_reload = +{ + local float amt; + + self.weaponframe += 1; + if ((self.weaponframe == 29)) + { + player_run (); + amt = (W_GetMaxClip(self.weapon, 1) - self.ammo_nails); + if ((self.exnails < amt)) + { + amt = self.exnails; + } + self.exnails = (self.exnails - amt); + self.ammo_nails = (self.ammo_nails + amt); + self.armorvalue = self.exnails; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_sniper_reload = +{ + local float amt; + + self.weaponframe += 1; + if (self.weaponframe > 27) + { + player_run (); + amt = (W_GetMaxClip(self.weapon, 1) - self.ammo_sniper); + if ((self.exsniper < amt)) + { + amt = self.exsniper; + } + self.exsniper -= amt; + self.ammo_sniper += amt; + self.armorvalue = self.exsniper; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_ppistol_reload = +{ + if (self.weaponframe < 15) // fixme: shouldn't be necessary :\ + self.weaponframe = 15; + self.weaponframe += 1; + if (self.weaponframe > 35) + { + player_run (); + self.exppistol = 0; + self.weaponheat = 0; + W_SetCurrentAmmo (); + return; + } + //self.weaponframe_time = time + 0.1; + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_needler_reload = +{ + local float amt; + + self.weaponframe += 1; + if (self.weaponframe > 29) + { + player_run (); + amt = (W_GetMaxClip(self.weapon, 1) - self.ammo_needler); + if ((self.exneedler < amt)) + { + amt = self.exneedler; + } + self.exneedler -= amt; + self.ammo_needler += amt; + self.armorvalue = self.exneedler; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_generic_reload = +{ + local float rld_amt; + rld_amt = self.armorvalue; + + if ((Player_GetFrame(PLAYER_RELOAD, 0) + self.fireframe) > Player_GetFrame(PLAYER_RELOAD, 1)) { + + rld_amt = (W_GetMaxClip(self.weapon, 1) - self.currentammo); + if ((self.armorvalue < rld_amt)) + { + rld_amt = self.armorvalue; + } + player_run (); + SetAmmoFor( self, self.weapon, 1, rld_amt ); + SetAmmoFor( self, self.weapon, 0, (-1 * rld_amt) ); + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +// Primary player reload function (handles all reloading) +void () player_reload1 = [ 0, player_reload1 ] +{ + // allow players to interrupt reload for melee/nade throw + if (self.impulse == 29) { + pre_player_melee (); + return; + } + else if (self.impulse == 28) { + pre_player_throw_grenade (); + return; + } + else if (self.reload_time == -1) { + self.reload_time = 1; + player_run(); + return; + } + + switch (self.weapon) { + case WEAPON_PISTOL: + player_pistol_reload (); + break; + case WEAPON_SKULL: + player_skull_reload (); + break; + case WEAPON_SHOT: + player_shotgun_reload (); + break; + case WEAPON_AR: + player_ar_reload (); + break; + case WEAPON_UZI: + player_uzi_reload (); + break; + case WEAPON_RL: + player_rl_reload (); + break; + case WEAPON_SNIPER: + player_sniper_reload (); + break; + case WEAPON_PPISTOL: + player_ppistol_reload (); + break; + case WEAPON_NEEDLER: + player_needler_reload (); + break; + default: + player_generic_reload (); + break; + } + self.reload_time = time + .1; + + self.frame = Player_GetFrame(PLAYER_RELOAD, 0); + if ((self.frame + self.fireframe) > Player_GetFrame(PLAYER_RELOAD, 1)) { + if (self.weaponframe == 0) { + self.melee_time = 0; + self.donefire = 0; + self.fireframe = 0; + player_run(); + return; + } + else { + self.fireframe = 5; + //self.frame = Player_GetFrame(PLAYER_RELOAD, 0) + 3; + } + + } + + self.frame = self.frame + self.fireframe; + + self.fireframe = self.fireframe + 1; +}; + +void () player_hshot = [ 103, player_hshot ] +{ + if (!W_CheckNoAmmo ()) + { + return; + } + self.effects = (self.effects | EF_MUZZLEFLASH); + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe == TE_LAVASPLASH)) + { + self.weaponframe = WEAPON_SHOTGUN; + player_run (); + return; + } + self.attack_finished = (time + 0.5); +}; + +void () Melee_Finished = +{ + self.donefire = 1; + self.weaponframe = 0; + player_run (); +}; + +void () player_shot_melee = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 41)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 33)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_skull_melee = +{ + self.weaponframe = (self.weaponframe + WEAPON_SKULL); + if ((self.weaponframe >= 16)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 1)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_rl_melee = +{ + self.weaponframe += 1; + if ( self.weaponframe > 65 ) + { + Melee_Finished (); + return; + } + if ( self.weaponframe == 62 ) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_hshot_melee = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 26)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 23)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_shot2_melee = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 33)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 30)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_nail_melee = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 34)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == SVC_FINALE)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_sniper_melee = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 34)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 32)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_ppistol_melee = +{ + self.weaponframe += 1; + if ((self.weaponframe >= 43)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 38)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_needler_melee = +{ + self.weaponframe += 1; + if ((self.weaponframe >= 47)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 34)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_melee = [ 0, player_melee ] +{ + local float ftype; + ftype = PLAYER_ATTACK_MELEE; + + self.melee_time = time + .6; + switch (self.weapon) { + case WEAPON_SHOT: + startwframe(self, 28); + player_shot2_melee (); + break; + case WEAPON_PISTOL: + startwframe(self, 30); + player_shot_melee (); + break; + case WEAPON_SKULL: + startwframe(self, 1); + player_skull_melee (); + break; + case WEAPON_AR: + startwframe(self, 29); + player_nail_melee (); + break; + case WEAPON_UZI: + startwframe(self, 21); + player_hshot_melee (); + break; + case WEAPON_RL: + startwframe(self, 58); + player_rl_melee (); + break; + case WEAPON_SNIPER: + startwframe(self, 29); + player_sniper_melee (); + break; + case WEAPON_PPISTOL: + startwframe(self, 36); + player_ppistol_melee (); + break; + case WEAPON_NEEDLER: + startwframe(self, 30); + player_needler_melee (); + break; + default: + self.melee_time = 0; + return; + } + + self.frame = Player_GetFrame(ftype, 0); + + if ((self.frame + self.fireframe) > Player_GetFrame(ftype, 1)) { + if (self.weaponframe == 0) { + self.melee_time = 0; + self.donefire = 0; + self.fireframe = 0; + player_run(); + } + else { + self.frame = Player_GetFrame(ftype, 1); + } + return; + } + + self.frame = self.frame + self.fireframe; + + self.fireframe = self.fireframe + 1; +}; + +void () pre_player_melee = +{ + player_melee (); + self.weaponframe = 0; + self.fireframe = 1; + self.frame = Player_GetFrame(PLAYER_ATTACK_MELEE, 0); +}; + +void () Throw_Finished = +{ + self.donefire = 1; + self.weaponframe = 0; + player_run (); +}; + +void () player_shot_throw = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 51)) + { + Throw_Finished (); + return; + } + if ((self.weaponframe == 47)) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_skull_throw = +{ + self.weaponframe = (self.weaponframe + WEAPON_SKULL); + if ((self.weaponframe >= 16)) + { + Throw_Finished (); + return; + } + //if ((self.weaponframe == 47)) + //{ + // W_ThrowGrenade (); + //} + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_shot2_throw = +{ + self.weaponframe += 1; + if (self.weaponframe >= 41) + { + Throw_Finished (); + return; + } + if (self.weaponframe == 39) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_nail_throw = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 42)) + { + Throw_Finished (); + return; + } + if ((self.weaponframe == 39)) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_uzi_throw = +{ + self.weaponframe += 1; + + if (self.weaponframe >= 33) + { + Throw_Finished (); + return; + } + if (self.weaponframe == 30) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_sniper_throw = +{ + self.weaponframe += 1; + + if (self.weaponframe >= 42) + { + Throw_Finished (); + return; + } + if (self.weaponframe == 39) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_rl_throw = +{ + self.weaponframe += 1; + + if (self.weaponframe >= 58) + { + Throw_Finished (); + return; + } + if (self.weaponframe == 55) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_ppistol_throw = +{ + self.weaponframe += 1; + + if (self.weaponframe >= 50) + { + Throw_Finished (); + return; + } + if (self.weaponframe == 46) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_needler_throw = +{ + self.weaponframe += 1; + + if (self.weaponframe >= 56) + { + Throw_Finished (); + return; + } + if (self.weaponframe == 52) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_throw_grenade = [ 0, player_throw_grenade ] +{ + local float ftype; + ftype = PLAYER_THROW_NADE; + + self.nade_time = time + .8; + switch (self.weapon) { + case WEAPON_PISTOL: + startwframe(self, 44); + player_shot_throw (); + break; + case WEAPON_SHOT: + startwframe(self, 34); + player_shot2_throw (); + break; + case WEAPON_AR: + startwframe(self, 34); + player_nail_throw (); + break; + case WEAPON_UZI: + startwframe(self, 26); + player_uzi_throw (); + break; + case WEAPON_RL: + startwframe(self, 51); + player_rl_throw (); + break; + case WEAPON_SNIPER: + startwframe(self, 35); + player_sniper_throw (); + break; + case WEAPON_PPISTOL: + startwframe(self, 43); + player_ppistol_throw (); + break; + case WEAPON_NEEDLER: + startwframe(self, 48); + player_needler_throw (); + break; + default: + self.nade_time = 0; + return; + } + + self.frame = Player_GetFrame(ftype, 0); + + if ((self.frame + self.fireframe) > Player_GetFrame(ftype, 1)) { + if (self.weaponframe == 0) { + self.donefire = 0; + self.fireframe = 0; + player_run(); + } + else { + self.frame = Player_GetFrame(ftype, 1); + } + return; + } + + self.frame = self.frame + self.fireframe; + + self.fireframe = self.fireframe + 1; +}; + +void () pre_player_throw_grenade = +{ + player_throw_grenade (); + self.weaponframe = 0; + self.fireframe = 0; + self.frame = Player_GetFrame(PLAYER_THROW_NADE, 0); +}; + +//============================================================================ + +void () player_nail2 = [ 103, player_nail2 ] +{ + if (!W_CheckNoAmmo ()) + { + return; + } + self.effects = (self.effects | EF_MUZZLEFLASH); + if (!self.button0) + { + player_run (); + return; + } + /* + self.weaponframe += 1; + if (self.weaponframe > 3) + { + self.weaponframe = 1; + } + */ + SuperDamageSound (); + W_FireNail2 (); + //self.attack_finished = (time + 0.1); +}; + +void () player_ar1 = [ 103, player_ar1 ] +{ + if (!W_CheckNoAmmo ()) + { + return; + } + self.effects = (self.effects | EF_MUZZLEFLASH); + if (!self.button0) + { + player_run (); + return; + } + + self.weaponframe += 1; + if (self.weaponframe > 3) + { + self.weaponframe = 1; + } + + SuperDamageSound (); + //W_FireNail2 (); + //self.attack_finished = (time + 0.1); +}; + +void(float num_bubbles) DeathBubbles; + +void() PainSound = +{ + + + if (self.health < 0) + return; + + if (self.pain_finished > time) + return; + + // change pain sound depending on means of death + switch (damage_mod) + { + case MOD_TELEFRAG: + case MOD_TELEFRAGDEFLECT: + sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE); + return; + case MOD_DROWN: + DeathBubbles(1); + if (random() > 0.5) + sound (self, CHAN_VOICE, "player/drown1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "player/drown2.wav", 1, ATTN_NORM); + return; + case MOD_SLIME: + // FIX ME: put in some steam here + if (self.waterlevel == 3) + DeathBubbles(1); + case MOD_LAVA: + if (random() > 0.5) + sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM); + return; + default: + if (self.health >= 40) + stuffcmd(self,"play player/hit1.wav\n"); + //else + //stuffcmd(self,"play player/pain1.wav\n"); + + } +}; +void() Player_PainAnimation = +{ + self.pain_time = time + .4; + PainSound(); +}; + +void() player_pain = +{ + if (self.weaponstate != WS_IDLE) + return; + + if (self.invisible_finished > time) + return; // eyes don't have pain frames + + Player_PainAnimation (); +}; + +void() DeathBubblesSpawn = +{ +local entity bubble; + if (self.owner.waterlevel != 3) + { + remove(self); + return; + } + bubble = spawn(); + setmodel (bubble, "progs/s_bubble.spr"); + setorigin (bubble, self.owner.origin + '0 0 24'); + bubble.movetype = MOVETYPE_NOCLIP; + bubble.solid = SOLID_NOT; + bubble.velocity = '0 0 15'; + bubble.nextthink = time + 0.5; + bubble.think = bubble_bob; + bubble.classname = "bubble"; + bubble.frame = 0; + bubble.bubble_state = 0; + setsize (bubble, '-8 -8 -8', '8 8 8'); + self.nextthink = time + 0.1; + self.think = DeathBubblesSpawn; + self.bubble_count = self.bubble_count - 1; + if (self.bubble_count <= 0) + remove(self); +}; + +void(float num_bubbles) DeathBubbles = +{ +local entity bubble_spawner; + + bubble_spawner = spawn(); + setorigin (bubble_spawner, self.origin); + bubble_spawner.movetype = MOVETYPE_NONE; + bubble_spawner.solid = SOLID_NOT; + bubble_spawner.nextthink = time + 0.1; + bubble_spawner.think = DeathBubblesSpawn; + bubble_spawner.owner = self; + bubble_spawner.bubble_count = num_bubbles; +}; + + +void() DeathSound = +{ +local float rs; + + // water death sounds + if (self.waterlevel == 3) + { + DeathBubbles(5); + sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE); + return; + } + + rs = rint ((random() * 1) + 1); + if (rs == 1) + stuffcmd (self, "play player/death1.wav\n"); + if (rs == 2) + stuffcmd (self, "play player/death1.wav\n"); + +}; + +void() PlayerDead = +{ + self.nextthink = -1; +// allow respawn after a certain time + self.deadflag = DEAD_DEAD; +}; + +vector(float dm) VelocityForDamage = +{ + local vector v; + + if (vlen(damage_inflictor.velocity)>0) + { + v = 0.5 * damage_inflictor.velocity; + v = v + (25 * normalize(self.origin-damage_inflictor.origin)); + v_z = 100 + 240 * random(); + v_x = v_x + (200 * crandom()); + v_y = v_y + (200 * crandom()); + //dprint ("Velocity gib\n"); + } + else + { + v_x = 100 * crandom(); + v_y = 100 * crandom(); + v_z = 200 + 100 * random(); + } + + //v_x = 100 * crandom(); + //v_y = 100 * crandom(); + //v_z = 200 + 100 * random(); + + if (dm > -50) + { + // dprint ("level 1\n"); + v = v * 0.7; + } + else if (dm > -200) + { + // dprint ("level 3\n"); + v = v * 2; + } + else + v = v * 10; + + return v; +}; + +void(string gibname, float dm) ThrowGib = +{ + local entity new; + + new = spawn(); + new.origin = self.origin; + setmodel (new, gibname); + setsize (new, '0 0 0', '0 0 0'); + new.velocity = VelocityForDamage (dm); + new.movetype = MOVETYPE_BOUNCE; + new.solid = SOLID_NOT; + new.avelocity_x = random()*600; + new.avelocity_y = random()*600; + new.avelocity_z = random()*600; + new.think = SUB_Remove; + new.nextthink = time + 10 + random()*10; + new.frame = 0; + new.flags = 0; +}; + +void(string gibname, float dm) ThrowHead = +{ + setmodel (self, gibname); + self.frame = 0; + self.nextthink = -1; + self.movetype = MOVETYPE_BOUNCE; + self.takedamage = DAMAGE_NO; + self.solid = SOLID_NOT; + self.view_ofs = '0 0 8'; + setsize (self, '-16 -16 0', '16 16 56'); + self.velocity = VelocityForDamage (dm); + self.origin_z = self.origin_z - 24; + self.flags = self.flags - (self.flags & FL_ONGROUND); + self.avelocity = crandom() * '0 600 0'; +}; + + +void() GibPlayer = +{ + ThrowHead ("progs/h_player.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + + self.deadflag = DEAD_DEAD; + + if (damage_attacker.classname == "teledeath") + { + sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE); + return; + } + + if (random() < 0.5) + sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NONE); + else + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NONE); + + stuffcmd(self,"chase_active 1\n"); + self.setup_death = #TRUE; +}; + +void() PlayerDropStuff = +{ + local string s, t; + + if (numberserverinfokey("dq") != 0) + { + if (self.super_damage_finished > time) + { + DropQuad (self.super_damage_finished - time); + s = ftos(rint(self.super_damage_finished - time)); + t = " lost a quad with "; + if (deathmatch == 4) + t = " lost an OctaPower with "; + bprint4 (PRINT_LOW, self.netname, t, s, " seconds remaining\n"); + } + } + + if (numberserverinfokey("dr") != 0) + { + if (self.invisible_finished > time) + { + s = ftos(rint(self.invisible_finished - time)); + bprint4 (PRINT_LOW, self.netname, " lost a ring with ", s, " seconds remaining\n"); + DropRing (self.invisible_finished - time); + } + } + + //DropBackpack(); + ThrowWeapon(self.weapon, 1); +} + +void () Player_RunDeath = [ 0, Player_RunDeath ] +{ + self.walkframe++; + self.frame = (Player_GetFrame(self.death_type, 0) - 1) + self.walkframe; + if (self.frame >= (Player_GetFrame(self.death_type, 1) - 1)) + { + PlayerDead(); + return; + } +}; + +void () Player_AnimateDeath = +{ + local float i, dtype; + + i = random(); + + if (i < 0.5) + dtype = PLAYER_DEATH1; + else + dtype = PLAYER_DEATH2; + + self.death_type = dtype; + self.walkframe = 0; + self.frame = Player_GetFrame(self.death_type, 0) - 1; + Player_RunDeath (); +}; + + +void() PlayerDie = +{ + self.items = self.items - (self.items & IT_INVISIBILITY); + +CTF_Flag_Drop(); + + PlayerDropStuff(); + + self.invisible_finished = 0; // don't die as eyes + self.invincible_finished = 0; + self.super_damage_finished = 0; + self.radsuit_finished = 0; + self.modelindex = modelindex_player; // don't use eyes + + self.weaponmodel=""; + self.view_ofs = '0 0 -8'; + self.deadflag = DEAD_DYING; + self.solid = SOLID_NOT; + self.flags = self.flags - (self.flags & FL_ONGROUND); + self.movetype = MOVETYPE_TOSS; + if (self.velocity_z < 10) + self.velocity_z = self.velocity_z + random()*300; + /* + if (self.nade_lives == 4) + { + DeathNade(self.origin) + DeathNade(self.origin) + DeathNade(self.origin) + DeathNade(self.origin) + } + if (self.nade_lives == 3) + { + DeathNade(self.origin) + DeathNade(self.origin) + DeathNade(self.origin) + } + if (self.nade_lives == 2) + { + DeathNade(self.origin) + DeathNade(self.origin) + } + if (self.nade_lives == 1) + { + DeathNade(self.origin) + } + */ + DeathSound(); + + self.angles_x = 0; + self.angles_z = 0; + + Set_FOV( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + + stuffcmd(self,"chase_active 1\n"); + self.setup_death = #TRUE; + + Player_AnimateDeath (); +}; + +void() set_suicide_frame = +{ // used by klill command and diconnect command + PlayerDie(); + + /* + if (self.model != "progs/player.mdl") + return; // allready gibbed + self.frame = 0;//$deatha11; // XAVIOR: FIXME + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_TOSS; + self.deadflag = DEAD_DEAD; + self.nextthink = -1; + */ +} + +void () pull_finished = +{ + self.donefire = 1; + self.weaponframe = 0; + player_run (); +}; + +void() player_generic_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 1) + { + pull_finished(); + return; + } +if (self.weaponframe == 2) + { + sound (self, CHAN_WEAPON, "weapons/equip/ppist.wav", 1, ATTN_NORM); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void() player_needler_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 68) + { + pull_finished(); + return; + } +if (self.weaponframe == 59) + { + sound (self, CHAN_WEAPON, "weapons/equip/needler.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void() player_ppist_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 56) + { + pull_finished(); + return; + } +if (self.weaponframe == 51) + { + sound (self, CHAN_WEAPON, "weapons/equip/ppist.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void() player_sniper_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 53) + { + pull_finished(); + return; + } +if (self.weaponframe == 46) + { + sound (self, CHAN_WEAPON, "weapons/equip/sniper.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void() player_rl_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 79) + { + pull_finished(); + return; + } +if (self.weaponframe == 70) + { + sound (self, CHAN_WEAPON, "weapons/equip/rocket.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void() player_uzi_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 40) + { + pull_finished(); + return; + } +if (self.weaponframe == 36) + { + sound (self, CHAN_WEAPON, "weapons/equip/smg.wav", 1, ATTN_NORM); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void() player_shotgun_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 48) + { + pull_finished(); + return; + } +if (self.weaponframe == 46) + { + sound (self, CHAN_WEAPON, "weapons/equip/shotgun.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void() player_ar_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 55) + { + pull_finished(); + return; + } +if (self.weaponframe == 46) + { + sound (self, CHAN_WEAPON, "weapons/equip/ar.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void() player_shot_pull = +{ + +self.weaponframe += 1; + +if (self.weaponframe >= 62) + { + pull_finished(); + return; + } +if (self.weaponframe == 53) + { + sound (self, CHAN_WEAPON, "weapons/equip/pistol.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void() player_pull = [ 0, player_pull ] +{ + local float ftype; + ftype = PLAYER_PULL; + + // allow players to interrupt reload for melee/nade throw + if (self.impulse == 29) { + pre_player_melee (); + return; + } + else if (self.impulse == 28) { + + { + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + if (self.selnade == GRENADE_REGULAR) + { + if (self.nade_lives > 0) { + pre_player_throw_grenade (); + self.nade_lives -= 1; + sprint (self, ftos(self.nade_lives)); + sprint (self, " grenades\n"); + return; } + else + centerprint (self, "No Grenades\n"); + } + else + { + if (self.plasma_lives > 0) { + pre_player_throw_grenade (); + self.plasma_lives -= 1; + sprint (self, ftos(self.plasma_lives)); + sprint (self, " Plasma grenades\n"); + return; } + else + centerprint (self, "No Plasma Grenades\n"); + } + } +} + else if (self.pull_time == -1) { + self.pull_time = time + .6; + player_run(); + return; + } + + switch (self.weapon) { + case WEAPON_PISTOL: + startwframe(self, 52); + player_shot_pull (); + break; + case WEAPON_SHOT: + startwframe(self, 41); + player_shotgun_pull (); + break; + case WEAPON_AR: + startwframe(self, 45); + player_ar_pull (); + break; + case WEAPON_UZI: + startwframe (self, 34); + player_uzi_pull (); + break; + case WEAPON_RL: + startwframe (self, 69); + player_rl_pull (); + break; + case WEAPON_SNIPER: + startwframe (self, 43); + player_sniper_pull (); + break; + case WEAPON_PPISTOL: + startwframe (self, 50); + player_ppist_pull (); + break; + case WEAPON_NEEDLER: + startwframe (self, 58); + player_needler_pull (); + break; + default: + startwframe (self, 1); + player_generic_pull (); + break; + } + + self.frame = Player_GetFrame(ftype, 0); + if ((self.frame + self.fireframe) > Player_GetFrame(ftype, 1)) { + if (self.weaponframe == 0) { + self.melee_time = 0; + self.donefire = 0; + self.fireframe = 0; + player_run(); + return; + } + else { + self.fireframe = 5; + //self.frame = Player_GetFrame(ftype, 0) + 3; + } + + } + + self.frame = self.frame + self.fireframe; + + self.fireframe = self.fireframe + 1; +}; + +void () pre_player_pull = +{ + player_pull (); + self.weaponframe = 0; + self.fireframe = 0; + self.frame = Player_GetFrame(PLAYER_PULL, 0); +}; diff --git a/r17/Revamped src/Revamped QC/progs.src b/r17/Revamped src/Revamped QC/progs.src new file mode 100755 index 00000000..d37120e0 --- /dev/null +++ b/r17/Revamped src/Revamped QC/progs.src @@ -0,0 +1,88 @@ +// First non-comment character must be # to use +// "new style" progs.src +#pragma PROGS_DAT ../qwprogs.dat + +// uncomment based on desired compile +#define NETQUAKE +// #define FTE +#define MONSTERS +#define REPLACEMENTS + +// compile options +#ifdef NETQUAKE +// if netquake, use progs.dat file name +#pragma PROGS_DAT ../progs.dat +#endif + +#ifdef FTE +// if FTE, use FTE style progs and use fteprogs.dat file name +#pragma target fte +#pragma PROGS_DAT fteprogs.dat +#endif + +// includes +#include "defs.qc" +#include "sol_defs.qc" +#include "engine.qc" + +// frikbot +#include "frikbot/bot.qc" +#include "frikbot/bot_way.qc" +#include "frikbot/bot_fight.qc" +#include "frikbot/bot_ai.qc" +#include "frikbot/bot_misc.qc" +#include "frikbot/bot_phys.qc" +#include "frikbot/bot_move.qc" +#include "frikbot/bot_ed.qc" + +#include "subs.qc" +#include "effects.qc" +#include "obituary.qc" +#include "combat.qc" +#include "items.qc" +#include "proj.qc" +#include "weapons.qc" +#include "NeedleAI.qc" + + + +#include "world.qc" +#include "ctf.qc" +#include "client.qc" +#include "spectate.qc" +#include "player.qc" +#include "doors.qc" +#include "buttons.qc" +#include "triggers.qc" +#include "plats.qc" +#include "misc.qc" + +#include "sol_items.qc" +#include "sol_misc.qc" + +#ifdef MONSTERS +#include "fight.qc" +#include "ai.qc" +#include "monsters.qc" +#include "quakemons/dog.qc" +#include "quakemons/soldier.qc" +#include "quakemons/enforcer.qc" +#include "quakemons/ogre.qc" +#include "quakemons/wizard.qc" +#include "quakemons/demon.qc" +#include "quakemons/knight.qc" +#include "quakemons/hknight.qc" +#include "quakemons/shalrath.qc" +#include "quakemons/shambler.qc" +#include "quakemons/fish.qc" +#include "quakemons/tarbaby.qc" +#include "quakemons/zombie.qc" +#include "quakemons/boss.qc" +#include "quakemons/oldone.qc" +#else +#include "nomonst.qc" +#endif + +#ifdef REPLACEMENTS +#include "replace.qc" +#endif \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/proj.qc b/r17/Revamped src/Revamped QC/proj.qc new file mode 100755 index 00000000..1d2f5e98 --- /dev/null +++ b/r17/Revamped src/Revamped QC/proj.qc @@ -0,0 +1,220 @@ + +// Generic projectile spawning code (PRJ) --- +// projectile effect enumerator +enum { + PE_NONE, + PE_SPIKE, + PE_SUPERSPIKE, + PE_WIZSPIKE, + PE_KNIGHTSPIKE, + PE_GUNSHOT, + PE_EXPLOSION, + PE_EXPLOSIONGROUND, + PE_LASER, + PE_ZOMBIEGIB +}; + +// functions used only by this QC file +float() _PRJ_Bounce = +{ + if (other.takedamage == DAMAGE_AIM) + return 0; // explode + + sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound + if (self.velocity == '0 0 0') + self.avelocity = '0 0 0'; + + return 1; // keep bouncing +}; + +float() _PRJ_Remove = +{ + remove(self); + return 1; // stop execution within touch function +}; + +float() _PRJ_Stop = +{ + if (other.takedamage) + return 0; + + sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound + self.velocity = '0 0 0'; + self.avelocity = '0 0 0'; + self.proj_touch = _PRJ_Remove; + return 1; // keep the entity alive +}; + +void() _PRJ_Touch = +{ + local entity ignore; + + // check validity of projectile + if (other == self.owner) + return; // don't explode on owner + + if (self.voided) { + return; + } + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + + // handle custom touch + if (other != self) // didn't expire + if (self.proj_touch) // is valid function + if (self.proj_touch()) + return; + + // void projectile + self.voided = 1; + + // do projectile damage + ignore = self; + + if (other.health >= 1 && self.damage_direct) + { + T_Damage (other, self, self.owner, self.damage_direct, self.mod_direct); + ignore = other; + } + + if (self.radius_exp) + T_RadiusDamage (self, self.owner, self.damage_exp, self.radius_exp, ignore, self.mod_exp); + + // run projectile effect + switch (self.proj_effect) + { + case PE_SPIKE: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_spike(self.origin); + break; + case PE_SUPERSPIKE: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_superspike(self.origin); + break; + case PE_WIZSPIKE: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_wizspike(self.origin); + break; + case PE_KNIGHTSPIKE: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_knightspike(self.origin); + break; + case PE_LASER: + if (other != self) + sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); + self.origin = self.origin - 8 * normalize(self.velocity); + case PE_GUNSHOT: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_gunshot(self.origin); + break; + case PE_EXPLOSION: + self.origin = self.origin - 8 * normalize(self.velocity); + case PE_EXPLOSIONGROUND: + TE_explosion(self.origin); + break; + case PE_ZOMBIEGIB: + sound (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM); + break; + } + + remove(self); +}; + +void() _PRJ_Expire = +{ + other = self; + _PRJ_Touch(); +}; + +void() _PRJ_Think = +{ + if (self.expire_time > time) + { + _PRJ_Expire(); + return; + } + + self.nextthink = time + self.proj_think_time; + self.proj_think(); // projectile could remove itself here +}; + +// functions used by outside QC files +// set bouncy projectile function +void() PRJ_SetBouncyProjectile = +{ + newmis.proj_touch = _PRJ_Bounce; + newmis.movetype = MOVETYPE_BOUNCE; + newmis.avelocity = '300 300 300'; +}; + +// set tossed projectile (zombie gib) function +void() PRJ_SetTossedProjectile = +{ + newmis.proj_touch = _PRJ_Stop; + newmis.movetype = MOVETYPE_BOUNCE; + newmis.avelocity = '3000 1000 2000'; +}; + +// set radius damage function +void(INTEGER damg, INTEGER damgrad, INTEGER damgmod) PRJ_SetRadiusDamage = +{ + newmis.damage_exp = damg; + newmis.radius_exp = damgrad; + newmis.mod_exp = damgmod; +}; + +// extra think function, should always be called ONCE after the main spawn function +void(void() thinkfunc, float thinktimeinit, float thinkres) PRJ_SetThink = +{ + newmis.think = _PRJ_Think; + newmis.nextthink = time + thinktimeinit; + newmis.proj_think = thinkfunc; + newmis.proj_think_time = thinkres; +}; + +// extra touch function +void(float() touchfunc) PRJ_SetTouch = +{ + newmis.proj_touch = touchfunc; +}; + +// main spawning function +void(entity parent, string modl, vector org, vector vel, INTEGER effect, INTEGER damg, INTEGER damgmod, float expiretime) PRJ_FireProjectile = +{ + newmis = spawn (); + newmis.owner = parent; + newmis.movetype = MOVETYPE_FLYMISSILE; + newmis.solid = SOLID_BBOX; +// newmis.classname = class; + newmis.velocity = vel; + + newmis.damage_direct = damg; + newmis.mod_direct = damgmod; + newmis.proj_effect = effect; + + newmis.touch = _PRJ_Touch; + newmis.expire_time = time + expiretime; + + newmis.think = _PRJ_Expire; + newmis.nextthink = time + expiretime; + + newmis.angles = vectoangles(newmis.velocity); + + setmodel (newmis, modl); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + setorigin (newmis, org); +}; diff --git a/r17/Revamped src/Revamped QC/quakemons/Elite.qc b/r17/Revamped src/Revamped QC/quakemons/Elite.qc new file mode 100755 index 00000000..7e7aaeae --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/Elite.qc @@ -0,0 +1,83 @@ + +//Credit to Frag.machine for partial code! +void () info_elite_think = +{ + local float r; + r = floor(random()*4); + + if (TOTAL_MONS <= MAX_MONS) //Prevents spawning, so Waves can be set. + { + if (r == 0) + { + normal_elite(); + } + else if (r == 1) + { + normal_grunt(); + } + else if (r == 2) + { + if (round < 3) + normal_elite() || normal_grunt(); + else + red_elite(); //Sets a limitation, so Red Elites don't appear until Round 3 + } + else if (r == 3) + { + if (round < 4) + normal_elite() || normal_grunt() || red_elite(); //Randomly picks an enemy to spawn. + else + white_elite(); + } + } + + // finally, let's schedule the execution of our "think" function + self.think = info_elite_think; + self.nextthink = (time + 5); +}; + +void () info_elite_start = +{ + + kill_count(); + FIREFIGHT = 1; //Sets Firefight to 1, so there are lives in play. + localcmd ("teamplay 1\n"); + F_LIVES = 7; + localcmd ("cl_life 8\n"); + + precache_sound ("firefight.wav"); + + precache_model ("progs/elite.mdl"); + precache_model ("progs/h_elite.mdl"); + precache_model ("progs/grenade.mdl"); + + precache_sound ("elite/ogdrag.wav"); + precache_sound ("elite/ogdth.wav"); + precache_sound ("elite/ogpain1.wav"); + precache_sound ("elite/ogsawatk.wav"); + precache_sound ("elite/ogwake.wav"); + precache_sound ("elite/laugh1.wav"); + precache_sound ("elite/laugh2.wav"); + + //Grunts + precache_model ("progs/soldier.mdl"); + precache_model ("progs/h_guard.mdl"); + + precache_sound ("soldier/death1.wav"); + precache_sound ("soldier/idle.wav"); + precache_sound ("soldier/pain1.wav"); + precache_sound ("soldier/pain2.wav"); + precache_sound ("soldier/sight1.wav"); + precache_sound ("soldier/laugh1.wav"); + precache_sound ("soldier/laugh2.wav"); + + precache_sound ("soldier/unstoppable.wav"); + precache_sound ("soldier/kill_all.wav"); + + + self.enemy = world; + + + self.think = info_elite_think; + self.nextthink = time + 5; +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/quakemons/Firefight_random.qc b/r17/Revamped src/Revamped QC/quakemons/Firefight_random.qc new file mode 100755 index 00000000..8ad538cc --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/Firefight_random.qc @@ -0,0 +1,192 @@ + + +void() normal_elite = +{ + local entity oldself; + + if (self.enemy != world) + { + if (self.enemy.health <= 0) + { + self.enemy = world; + } + } + + if (self.enemy == world) + { + oldself = self; + self = spawn (); + self.classname = "Needle-spikes"; + setorigin (self, oldself.origin); + self.origin_z = self.origin_z + 2; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + setmodel (self, "progs/elite.mdl"); + self.skin = 0; + setsize (self, VEC_HULL_MIN, VEC_HULL_MAX); + self.health = 200; + self.elite = 0; + self.th_stand = elite_stand1; + self.th_walk = elite_walk1; + self.th_run = elite_run1; + self.th_die = elite_die; + self.th_melee = elite_melee; + self.th_missile = elite_nail1; + self.th_pain = elite_pain; + + if (oldself.target != string_null) + { + self.target = oldself.target; + } + + walkmonster_start(); + + oldself.enemy = self; + self = oldself; + TOTAL_MONS += 1; //Adds a monster to the world, so that waves can be set. + } + +}; + +void() red_elite = +{ + local entity oldself; + + if (self.enemy != world) + { + if (self.enemy.health <= 0) + { + self.enemy = world; + } + } + + if (self.enemy == world) + { + oldself = self; + self = spawn (); + self.classname = "Needle-spikes"; + setorigin (self, oldself.origin); + self.origin_z = self.origin_z + 2; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + setmodel (self, "progs/elite.mdl"); + self.skin = 1; + setsize (self, VEC_HULL_MIN, VEC_HULL_MAX); + self.health = 300; + self.elite = 1; //States what Elite type it is, so Different stats/weapons can be set. + self.th_stand = elite_stand1; + self.th_walk = elite_walk1; + self.th_run = elite_run1; + self.th_die = elite_die; + self.th_melee = elite_melee; + self.th_missile = elite_nail1; + self.th_pain = elite_pain; + + if (oldself.target != string_null) + { + self.target = oldself.target; + } + + walkmonster_start(); + + oldself.enemy = self; + self = oldself; + TOTAL_MONS += 1; + } + +}; +void() white_elite = +{ + local entity oldself; + + if (self.enemy != world) + { + if (self.enemy.health <= 0) + { + self.enemy = world; + } + } + + if (self.enemy == world) + { + oldself = self; + self = spawn (); + self.classname = "Needle-spikes"; + setorigin (self, oldself.origin); + self.origin_z = self.origin_z + 2; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + setmodel (self, "progs/elite.mdl"); + self.skin = 3; + setsize (self, VEC_HULL_MIN, VEC_HULL_MAX); + self.health = 400; + self.elite = 2; + self.th_stand = elite_stand1; + self.th_walk = elite_walk1; + self.th_run = elite_run1; + self.th_die = elite_die; + self.th_melee = elite_melee; + self.th_missile = elite_nail1; + self.th_pain = elite_pain; + + if (oldself.target != string_null) + { + self.target = oldself.target; + } + + walkmonster_start(); + + oldself.enemy = self; + self = oldself; + TOTAL_MONS += 1; + } + +}; + +void() normal_grunt = +{ + local entity oldself; + + if (self.enemy != world) + { + if (self.enemy.health <= 0) + { + self.enemy = world; + } + } + + if (self.enemy == world) + { + oldself = self; + self = spawn (); + self.classname = "Needle-spikes"; + setorigin (self, oldself.origin); + self.origin_z = self.origin_z + 2; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + setmodel (self, "progs/soldier.mdl"); + self.skin = 0; + self.elite = 1; //For Melee damage + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 40 * round/1.5; + self.th_stand = army_stand1; + self.th_walk = army_walk1; + self.th_run = army_run1; + self.th_missile = army_atk1; + self.th_pain = army_pain; + self.th_die = army_die; + self.th_melee = grunt_melee1; + + if (oldself.target != string_null) + { + self.target = oldself.target; + } + + walkmonster_start(); + + oldself.enemy = self; + self = oldself; + TOTAL_MONS += 1; + } + +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/quakemons/ai_anims.qc b/r17/Revamped src/Revamped QC/quakemons/ai_anims.qc new file mode 100755 index 00000000..a4e2b7ce --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/ai_anims.qc @@ -0,0 +1,685 @@ +void() info_elite_think; + +void() kill_count = +{ +if (round_kills == 0) +{ +localcmd ("cl_round 1\n"); +TOTAL_MONS = 0; +MAX_MONS = 3; //4 Max Monsters. 0-1-2-3 +round = 1; +} + +if (round_kills == 4) +{ +localcmd ("cl_round 2\n"); +TOTAL_MONS = 0; +MAX_MONS = 5; +round = 2; +} + +if (round_kills == 10) +{ +localcmd ("cl_round 3\n"); +TOTAL_MONS = 0; +MAX_MONS = 9; +round = 3; +} + +if (round_kills == 20) +{ +localcmd ("skill 2\n"); +localcmd ("cl_round 4\n"); +TOTAL_MONS = 0; +MAX_MONS = 9; +round = 4; + +} + +if (round_kills == 30) +{ +F_LIVES += 1; //Increase the players life for making it this far. +localcmd ("cl_round 5\n"); +TOTAL_MONS = 0; +MAX_MONS = 14; +round = 5; +} + +if (round_kills == 45) +{ +localcmd ("cl_round 6\n"); +TOTAL_MONS = 0; +MAX_MONS = 19; +round = 6; +} + +if (round_kills == 65) +{ +localcmd ("skill 3\n"); +localcmd ("cl_round 7\n"); +TOTAL_MONS = 0; +MAX_MONS = 34; +round = 7; +} + +if (round_kills == 100) +{ +TOTAL_MONS = 0; +MAX_MONS = 34; +localcmd ("cl_round 8\n"); +round = 8; +} +if (round_kills == 150) +{ +TOTAL_MONS = 0; +MAX_MONS = 49; +localcmd ("cl_round 8\n"); +round = 9; +centerprint (self, "Congrats! You have completed Firefight! Shoot to Retry.\n"); +if (self.button0) +localcmd ("map spawn\n"); +} + +}; + +/* +=========================================================== + +WEAPON SHOOTING +This Enables Various Weapons to be used by Monster AI +============================================================ +*/ +//Shoot the Plasma Pistol +void() Enemy_Fire_PPist = +{ + local vector dir; + local entity en; + + ai_face(); + + //sound (self, CHAN_WEAPON, "soldier/.wav", 1,ATTN_NORM); + en = self.enemy; + dir = en.origin - en.velocity*0.2; + dir = normalize (dir - self.origin); + + W_FirePPistol( self.weaponheat ); +}; + +//Shoot the Needler +void() Enemy_Fire_Needler = +{ + local vector dir; + local entity en; + + ai_face(); + + //sound (self, CHAN_WEAPON, "soldier/.wav", 1,ATTN_NORM); + en = self.enemy; + dir = en.origin - en.velocity*0.2; + dir = normalize (dir - self.origin); + + W_FireNeedler(); +}; +/* +============================================================================== + +ELITE + +============================================================================== +*/ + +$cd id1/models/elite_c +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 +$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7 +$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 +$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14 + +$frame melee1 melee2 melee3 melee4 melee5 melee6 melee7 +$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 shoot7 shoot8 shoot9 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame painb1 painb2 painb3 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10 +$frame paind11 paind12 paind13 paind14 paind15 paind16 + +$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10 +$frame paine11 paine12 paine13 paine14 paine15 + +$frame death1 death2 death3 death4 death5 death6 +$frame death7 death8 death9 death10 death11 death12 +$frame death13 death14 + +$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6 +$frame bdeath7 bdeath8 bdeath9 bdeath10 + +$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11 + +//============================================================================= + +//============================================================================= + +void() laugh = +{ +local float r; +r = random(); +if (r <= 0.025) +sound (self, CHAN_AUTO, "elite/laugh1.wav", 1, ATTN_NORM); +else if ( r <= 0.05) +sound (self, CHAN_AUTO, "elite/laugh2.wav", 1, ATTN_NORM); +else +{} +}; +/* +================ +Elite Melee + +FIXME +================ +*/ +void(float side) chainsaw = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + if (!CanDamage (self.enemy, self)) + return; + + ai_charge(10); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + if (self.elite == 0) + ldmg = (random() + random() + random()) * 10; + else if (self.elite == 1) + ldmg = (random() + random() + random()) * 15; + else if (self.elite == 2) + ldmg = (random() + random() + random()) * 20; + T_Damage (self.enemy, self, self, ldmg, MOD_OGRE); +}; + + +void() elite_stand1 =[ $stand1, elite_stand2 ] {ai_stand();}; +void() elite_stand2 =[ $stand2, elite_stand3 ] {ai_stand();}; +void() elite_stand3 =[ $stand3, elite_stand4 ] {ai_stand(); laugh();}; +void() elite_stand4 =[ $stand4, elite_stand5 ] {ai_stand();}; +void() elite_stand5 =[ $stand5, elite_stand6 ] { +ai_stand(); +}; +void() elite_stand6 =[ $stand6, elite_stand7 ] {ai_stand();}; +void() elite_stand7 =[ $stand7, elite_stand8 ] {ai_stand();}; +void() elite_stand8 =[ $stand8, elite_stand9 ] {ai_stand();}; +void() elite_stand9 =[ $stand9, elite_stand1 ] {ai_stand();}; + +void() elite_walk1 =[ $walk1, elite_walk2 ] {ai_walk(3);}; +void() elite_walk2 =[ $walk2, elite_walk3 ] {ai_walk(2);}; +void() elite_walk3 =[ $walk3, elite_walk4 ] { +ai_walk(2); +}; +void() elite_walk4 =[ $walk4, elite_walk5 ] {ai_walk(2);}; +void() elite_walk5 =[ $walk5, elite_walk6 ] {ai_walk(2);}; +void() elite_walk6 =[ $walk6, elite_walk7 ] { +ai_walk(5); +if (random() < 0.1) + sound (self, CHAN_VOICE, "elite/ogdrag.wav", 1, ATTN_IDLE); +}; +void() elite_walk7 =[ $walk7, elite_walk8 ] {ai_walk(6);}; +void() elite_walk8 =[ $walk8, elite_walk9 ] {ai_walk(4);}; +void() elite_walk9 =[ $walk9, elite_walk10 ] {ai_walk(6);}; +void() elite_walk10 =[ $walk10, elite_walk11 ] {ai_walk(2);}; +void() elite_walk11 =[ $walk11, elite_walk12 ] {ai_walk(4);}; +void() elite_walk12 =[ $walk12, elite_walk13 ] {ai_walk(6);}; +void() elite_walk13 =[ $walk13, elite_walk14 ] {ai_walk(6);}; +void() elite_walk14 =[ $walk14, elite_walk15 ] {ai_walk(6);}; +void() elite_walk15 =[ $walk15, elite_walk16 ] {ai_walk(6);}; +void() elite_walk16 =[ $walk16, elite_walk1 ] {ai_walk(8);}; + +void() elite_run1 =[ $run1, elite_run2 ] {ai_run(18); +}; +void() elite_run2 =[ $run2, elite_run3 ] {ai_run(15);}; +void() elite_run3 =[ $run3, elite_run4 ] {ai_run(15);}; +void() elite_run4 =[ $run4, elite_run5 ] {ai_run(15);}; +void() elite_run5 =[ $run5, elite_run6 ] {ai_run(15);}; +void() elite_run6 =[ $run6, elite_run7 ] {ai_run(15);}; +void() elite_run7 =[ $run7, elite_run8 ] {ai_run(15);}; +void() elite_run8 =[ $run8, elite_run1 ] {ai_run(15);}; + +void() elite_swing1 =[ $swing1, elite_swing2 ] {ai_charge(11); +sound (self, CHAN_WEAPON, "elite/ogsawatk.wav", 1, ATTN_NORM); +}; +void() elite_swing2 =[ $swing2, elite_swing3 ] {ai_charge(1);}; +void() elite_swing3 =[ $swing3, elite_swing4 ] {ai_charge(4);}; +void() elite_swing4 =[ $swing4, elite_swing5 ] {ai_charge(13);}; +void() elite_swing5 =[ $swing5, elite_swing6 ] {ai_charge(9); }; +void() elite_swing6 =[ $swing6, elite_swing7 ] {}; +void() elite_swing7 =[ $swing7, elite_swing8 ] {}; +void() elite_swing8 =[ $swing8, elite_swing9 ] {}; +void() elite_swing9 =[ $swing9, elite_swing10 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 10;}; +void() elite_swing10 =[ $swing10, elite_swing11 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 10;}; +void() elite_swing11 =[ $swing11, elite_swing12 ] {}; +void() elite_swing12 =[ $swing12, elite_swing13 ] {ai_charge(3);}; +void() elite_swing13 =[ $swing13, elite_swing14 ] {ai_charge(8);}; +void() elite_swing14 =[ $swing14, elite_run1 ] {ai_charge(9);}; + +void() elite_smash1 =[ $smash1, elite_smash2 ] {ai_charge(6); +sound (self, CHAN_WEAPON, "elite/ogsawatk.wav", 1, ATTN_NORM); +}; +void() elite_smash2 =[ $smash2, elite_smash3 ] {ai_charge(0);}; +void() elite_smash3 =[ $smash3, elite_smash4 ] {ai_charge(0);}; +void() elite_smash4 =[ $smash4, elite_smash5 ] {ai_charge(1);}; +void() elite_smash5 =[ $smash5, elite_smash6 ] {ai_charge(4);}; +void() elite_smash6 =[ $smash6, elite_smash7 ] {ai_charge(4); chainsaw(0);}; +void() elite_smash7 =[ $smash7, elite_smash8 ] {ai_charge(4);}; +void() elite_smash8 =[ $smash8, elite_smash9 ] {ai_charge(10);}; +void() elite_smash9 =[ $smash9, elite_smash10 ] {ai_charge(13);}; +void() elite_smash10 =[ $smash10, elite_smash11 ] {chainsaw(1);}; +void() elite_smash11 =[ $smash11, elite_smash12 ] {ai_charge(2); +self.nextthink = time + 0.1 + random()*0.1;}; // slight variation +//void() elite_smash12 =[ $smash12, elite_smash13 ] {ai_charge();}; +void() elite_smash12 =[$smash12, elite_smash13] {ai_charge(0);}; +void() elite_smash13 =[ $smash13, elite_smash14 ] {ai_charge(4);}; +void() elite_smash14 =[ $smash14, elite_run1 ] {ai_charge(12);}; + +void() elite_nail1 =[ $run1, elite_nail2 ] {ai_face();}; +void() elite_nail2 =[ $run2, elite_nail3 ] {ai_face();}; +void() elite_nail3 =[ $run2, elite_nail4 ] {ai_face();}; +void() elite_nail4 =[ $run3, elite_nail5 ] {ai_face(); +if (self.elite == 0 || self.elite == 2) +Enemy_Fire_PPist(); +if (self.elite == 1) +Enemy_Fire_Needler(); +}; +void() elite_nail5 =[ $run4, elite_nail6 ] {ai_face();}; +void() elite_nail6 =[ $run5, elite_nail7 ] {ai_face();}; +void() elite_nail7 =[ $run6, elite_run1 ] {ai_face();}; + +void() elite_pain1 =[ $pain1, elite_pain2 ] {}; +void() elite_pain2 =[ $pain2, elite_pain3 ] {}; +void() elite_pain3 =[ $pain3, elite_pain4 ] {}; +void() elite_pain4 =[ $pain4, elite_pain5 ] {}; +void() elite_pain5 =[ $pain5, elite_run1 ] {}; + + +void() elite_painb1 =[ $painb1, elite_painb2 ] {}; +void() elite_painb2 =[ $painb2, elite_painb3 ] {}; +void() elite_painb3 =[ $painb3, elite_run1 ] {}; + + +void() elite_painc1 =[ $painc1, elite_painc2 ] {}; +void() elite_painc2 =[ $painc2, elite_painc3 ] {}; +void() elite_painc3 =[ $painc3, elite_painc4 ] {}; +void() elite_painc4 =[ $painc4, elite_painc5 ] {}; +void() elite_painc5 =[ $painc5, elite_painc6 ] {}; +void() elite_painc6 =[ $painc6, elite_run1 ] {}; + + +void() elite_paind1 =[ $paind1, elite_paind2 ] {}; +void() elite_paind2 =[ $paind2, elite_paind3 ] {ai_pain(10);}; +void() elite_paind3 =[ $paind3, elite_paind4 ] {ai_pain(9);}; +void() elite_paind4 =[ $paind4, elite_paind5 ] {ai_pain(4);}; +void() elite_paind5 =[ $paind5, elite_paind6 ] {}; +void() elite_paind6 =[ $paind6, elite_paind7 ] {}; +void() elite_paind7 =[ $paind7, elite_paind8 ] {}; +void() elite_paind8 =[ $paind8, elite_paind9 ] {}; +void() elite_paind9 =[ $paind9, elite_paind10 ] {}; +void() elite_paind10=[ $paind10, elite_paind11 ] {}; +void() elite_paind11=[ $paind11, elite_paind12 ] {}; +void() elite_paind12=[ $paind12, elite_paind13 ] {}; +void() elite_paind13=[ $paind13, elite_paind14 ] {}; +void() elite_paind14=[ $paind14, elite_paind15 ] {}; +void() elite_paind15=[ $paind15, elite_paind16 ] {}; +void() elite_paind16=[ $paind16, elite_run1 ] {}; + +void() elite_paine1 =[ $paine1, elite_paine2 ] {}; +void() elite_paine2 =[ $paine2, elite_paine3 ] {ai_pain(10);}; +void() elite_paine3 =[ $paine3, elite_paine4 ] {ai_pain(9);}; +void() elite_paine4 =[ $paine4, elite_paine5 ] {ai_pain(4);}; +void() elite_paine5 =[ $paine5, elite_paine6 ] {}; +void() elite_paine6 =[ $paine6, elite_paine7 ] {}; +void() elite_paine7 =[ $paine7, elite_paine8 ] {}; +void() elite_paine8 =[ $paine8, elite_paine9 ] {}; +void() elite_paine9 =[ $paine9, elite_paine10 ] {}; +void() elite_paine10=[ $paine10, elite_paine11 ] {}; +void() elite_paine11=[ $paine11, elite_paine12 ] {}; +void() elite_paine12=[ $paine12, elite_paine13 ] {}; +void() elite_paine13=[ $paine13, elite_paine14 ] {}; +void() elite_paine14=[ $paine14, elite_paine15 ] {}; +void() elite_paine15=[ $paine15, elite_run1 ] {}; + + +void(entity attacker, float damage) elite_pain = +{ + local float r; + +// don't make multiple pain sounds right after each other + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "elite/ogpain1.wav", 1, ATTN_NORM); + + r = random(); + + if (r < 0.25) + { + elite_pain1 (); + self.pain_finished = time + 1; + } + else if (r < 0.5) + { + elite_painb1 (); + self.pain_finished = time + 1; + } + else if (r < 0.75) + { + elite_painc1 (); + self.pain_finished = time + 1; + } + else if (r < 0.88) + { + elite_paind1 (); + self.pain_finished = time + 2; + } + else + { + elite_paine1 (); + self.pain_finished = time + 2; + } +}; + +void() elite_die1 =[ $death1, elite_die2 ] {}; +void() elite_die2 =[ $death2, elite_die3 ] {}; +void() elite_die3 =[ $death3, elite_die4 ] +{self.solid = SOLID_NOT;DropBackpack();}; +void() elite_die4 =[ $death4, elite_die5 ] {}; +void() elite_die5 =[ $death5, elite_die6 ] {}; +void() elite_die6 =[ $death6, elite_die7 ] {}; +void() elite_die7 =[ $death7, elite_die8 ] {}; +void() elite_die8 =[ $death8, elite_die9 ] {}; +void() elite_die9 =[ $death9, elite_die10 ] {}; +void() elite_die10 =[ $death10, elite_die11 ] {}; +void() elite_die11 =[ $death11, elite_die12 ] {}; +void() elite_die12 =[ $death12, elite_die13 ] {}; +void() elite_die13 =[ $death13, elite_die14 ] {}; +void() elite_die14 =[ $death14, elite_die14 ] {remove(self); round_kills += 1; kill_count();}; + +void() elite_bdie1 =[ $bdeath1, elite_bdie2 ] {}; +void() elite_bdie2 =[ $bdeath2, elite_bdie3 ] {ai_forward(5);}; +void() elite_bdie3 =[ $bdeath3, elite_bdie4 ] +{self.solid = SOLID_NOT;DropBackpack();}; +void() elite_bdie4 =[ $bdeath4, elite_bdie5 ] {ai_forward(1);}; +void() elite_bdie5 =[ $bdeath5, elite_bdie6 ] {ai_forward(3);}; +void() elite_bdie6 =[ $bdeath6, elite_bdie7 ] {ai_forward(7);}; +void() elite_bdie7 =[ $bdeath7, elite_bdie8 ] {ai_forward(25);}; +void() elite_bdie8 =[ $bdeath8, elite_bdie9 ] {}; +void() elite_bdie9 =[ $bdeath9, elite_bdie10 ] {}; +void() elite_bdie10 =[ $bdeath10, elite_bdie10 ] {remove(self); round_kills += 1; kill_count();}; + +void() elite_die = +{ + + sound (self, CHAN_VOICE, "elite/ogdth.wav", 1, ATTN_NORM); + + if (random() < 0.5) + elite_die1 (); + else + elite_bdie1 (); +}; + +void() elite_melee = +{ + if (random() > 0.5) + elite_smash1 (); + else + elite_swing1 (); +}; + + +/* +============================================================================== + +SOLDIER / PLAYER + +============================================================================== +*/ + +$cd id1/models/soldier3 +$origin 0 -6 24 +$base base +$skin skin + +$frame prowl_1 prowl_2 prowl_3 prowl_4 prowl_5 prowl_6 prowl_7 prowl_8 +$frame prowl_9 prowl_10 prowl_11 prowl_12 prowl_13 prowl_14 prowl_15 prowl_16 +$frame prowl_17 prowl_18 prowl_19 prowl_20 prowl_21 prowl_22 prowl_23 prowl_24 + +/* +============================================================================== +SOLDIER CODE +============================================================================== +*/ + +void() laughs = +{ +local float r; +r = random(); +if (r <= 0.025) +{ +self.attack_finished = time + 0.6; +sound (self, CHAN_AUTO, "soldier/laugh1.wav", 0.8, ATTN_NORM); +} +else if ( r <= 0.05) +{ +self.attack_finished = time + 0.6; +sound (self, CHAN_AUTO, "soldier/laugh2.wav", 0.8, ATTN_NORM); +} +else +{} +}; +//For randomy playing a grunt sound +void() g_attack = +{ +local float r; +r = random(); +if (r <= 0.005) +{ +self.attack_finished = time + 0.6; +sound (self, CHAN_AUTO, "soldier/unstoppable.wav", 0.9, ATTN_NORM); +} +else if ( r <= 0.01) +{ +self.attack_finished = time + 0.6; +sound (self, CHAN_AUTO, "soldier/kill_it.wav", 0.9, ATTN_NORM); +} +else {} +}; +void() army_fire; + +void() army_stand1 =[ $stand1, army_stand2 ] {ai_stand();}; +void() army_stand2 =[ $stand2, army_stand3 ] {ai_stand();}; +void() army_stand3 =[ $stand3, army_stand4 ] {ai_stand();}; +void() army_stand4 =[ $stand4, army_stand5 ] {ai_stand();}; +void() army_stand5 =[ $stand5, army_stand6 ] {ai_stand();}; +void() army_stand6 =[ $stand6, army_stand7 ] {ai_stand();laughs();}; +void() army_stand7 =[ $stand7, army_stand8 ] {ai_stand();}; +void() army_stand8 =[ $stand8, army_stand1 ] {ai_stand();}; + +void() army_walk1 =[ $prowl_1, army_walk2 ] { +ai_walk(1);}; +void() army_walk2 =[ $prowl_2, army_walk3 ] {ai_walk(1);}; +void() army_walk3 =[ $prowl_3, army_walk4 ] {ai_walk(1);}; +void() army_walk4 =[ $prowl_4, army_walk5 ] {ai_walk(1);}; +void() army_walk5 =[ $prowl_5, army_walk6 ] {ai_walk(2);}; +void() army_walk6 =[ $prowl_6, army_walk7 ] {ai_walk(3);}; +void() army_walk7 =[ $prowl_7, army_walk8 ] {ai_walk(4);}; +void() army_walk8 =[ $prowl_8, army_walk9 ] {ai_walk(4);}; +void() army_walk9 =[ $prowl_9, army_walk10 ] {ai_walk(2);}; +void() army_walk10 =[ $prowl_10, army_walk11 ] {ai_walk(2);}; +void() army_walk11 =[ $prowl_11, army_walk12 ] {ai_walk(2);}; +void() army_walk12 =[ $prowl_12, army_walk13 ] {ai_walk(1);}; +void() army_walk13 =[ $prowl_13, army_walk14 ] {ai_walk(0);}; +void() army_walk14 =[ $prowl_14, army_walk15 ] {ai_walk(1);}; +void() army_walk15 =[ $prowl_15, army_walk16 ] {ai_walk(1);}; +void() army_walk16 =[ $prowl_16, army_walk17 ] {ai_walk(1);}; +void() army_walk17 =[ $prowl_17, army_walk18 ] {ai_walk(3);}; +void() army_walk18 =[ $prowl_18, army_walk19 ] {ai_walk(3);}; +void() army_walk19 =[ $prowl_19, army_walk20 ] {ai_walk(3);}; +void() army_walk20 =[ $prowl_20, army_walk21 ] {ai_walk(3);}; +void() army_walk21 =[ $prowl_21, army_walk22 ] {ai_walk(2);}; +void() army_walk22 =[ $prowl_22, army_walk23 ] {ai_walk(1);}; +void() army_walk23 =[ $prowl_23, army_walk24 ] {ai_walk(1);}; +void() army_walk24 =[ $prowl_24, army_walk1 ] {ai_walk(1);}; + +void() army_run1 =[ $run1, army_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE); +ai_run(11);}; +void() army_run2 =[ $run2, army_run3 ] {ai_run(15);}; +void() army_run3 =[ $run3, army_run4 ] {ai_run(10);}; +void() army_run4 =[ $run4, army_run5 ] {ai_run(10);}; +void() army_run5 =[ $run5, army_run6 ] {ai_run(8);}; +void() army_run6 =[ $run6, army_run7 ] {ai_run(15);}; +void() army_run7 =[ $run7, army_run8 ] {ai_run(10);}; +void() army_run8 =[ $run8, army_run1 ] {ai_run(8);}; + +void() army_atk1 =[ $shoot1, army_atk2 ] {ai_face();}; +void() army_atk2 =[ $shoot2, army_atk3 ] {ai_face();}; +void() army_atk3 =[ $shoot3, army_atk4 ] {ai_face();}; +void() army_atk4 =[ $shoot4, army_atk5 ] {ai_face();}; +void() army_atk5 =[ $shoot5, army_atk6 ] {ai_face(); Enemy_Fire_PPist();}; +void() army_atk6 =[ $shoot6, army_atk7 ] {ai_face();}; +void() army_atk7 =[ $shoot7, army_atk8 ] {ai_face();SUB_CheckRefire (army_atk1);}; +void() army_atk8 =[ $shoot8, army_atk9 ] {ai_face();}; +void() army_atk9 =[ $shoot9, army_run1 ] {ai_face();}; + +void() grunt_melee1 =[ $melee1, grunt_melee2 ] {ai_charge(1); }; +void() grunt_melee2 =[ $melee2, grunt_melee3 ] {ai_charge(1);}; +void() grunt_melee3 =[ $melee3, grunt_melee4 ] {ai_charge(4); chainsaw(0);self.angles_y = self.angles_y + random()* 10;}; +void() grunt_melee4 =[ $melee4, grunt_melee5 ] {ai_charge(13);}; +void() grunt_melee5 =[ $melee5, grunt_melee6 ] {ai_charge(9); }; +void() grunt_melee6 =[ $melee6, grunt_melee7 ] {}; +void() grunt_melee7 =[ $melee7, army_run1 ] {}; + +void() army_pain1 =[ $pain1, army_pain2 ] {}; +void() army_pain2 =[ $pain2, army_pain3 ] {}; +void() army_pain3 =[ $pain3, army_pain4 ] {}; +void() army_pain4 =[ $pain4, army_pain5 ] {g_attack();}; +void() army_pain5 =[ $pain5, army_pain6 ] {}; +void() army_pain6 =[ $pain6, army_run1 ] {ai_pain(1);}; + +void() army_painb1 =[ $painb1, army_painb2 ] {}; +void() army_painb2 =[ $painb2, army_painb3 ] {ai_painforward(13);}; +void() army_painb3 =[ $painb3, army_painb4 ] {ai_painforward(9);}; +void() army_painb4 =[ $painb4, army_painb5 ] {}; +void() army_painb5 =[ $painb5, army_painb6 ] {}; +void() army_painb6 =[ $painb6, army_painb7 ] {}; +void() army_painb7 =[ $painb7, army_painb8 ] {}; +void() army_painb8 =[ $painb8, army_painb9 ] {}; +void() army_painb9 =[ $painb9, army_painb10] {}; +void() army_painb10=[ $painb10, army_painb11] {}; +void() army_painb11=[ $painb11, army_painb12] {}; +void() army_painb12=[ $painb12, army_painb13] {ai_pain(2);}; +void() army_painb13=[ $painb13, army_painb14] {}; +void() army_painb14=[ $painb14, army_run1 ] {}; + +void() army_painc1 =[ $painc1, army_painc2 ] {}; +void() army_painc2 =[ $painc2, army_painc3 ] {ai_pain(1);}; +void() army_painc3 =[ $painc3, army_painc4 ] {}; +void() army_painc4 =[ $painc4, army_painc5 ] {}; +void() army_painc5 =[ $painc5, army_painc6 ] {ai_painforward(1);}; +void() army_painc6 =[ $painc6, army_painc7 ] {ai_painforward(1);}; +void() army_painc7 =[ $painc7, army_painc8 ] {}; +void() army_painc8 =[ $painc8, army_painc9 ] {ai_pain(1);}; +void() army_painc9 =[ $painc9, army_painc10] {ai_painforward(4);}; +void() army_painc10=[ $painc10, army_painc11] {ai_painforward(3);}; +void() army_painc11=[ $painc11, army_painc12] {ai_painforward(6);}; +void() army_painc12=[ $painc12, army_painc13] {ai_painforward(8);}; +void() army_painc13=[ $painc13, army_run1] {}; + +void(entity attacker, float damage) army_pain = +{ + local float r; + + if (self.pain_finished > time) + return; + + r = random(); + + if (r < 0.2) + { + self.pain_finished = time + 0.6; + army_pain1 (); + sound (self, CHAN_VOICE, "soldier/pain1.wav", 1, ATTN_NORM); + } + else if (r < 0.6) + { + self.pain_finished = time + 1.1; + army_painb1 (); + sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM); + } + else + { + self.pain_finished = time + 1.1; + army_painc1 (); + sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM); + } +}; + + +void() army_fire = +{ + local vector dir; + local entity en; + + ai_face(); + + sound (self, CHAN_WEAPON, "weapons/ppist.wav", 1, ATTN_NORM); + +// fire somewhat behind the player, so a dodging player is harder to hit + en = self.enemy; + + dir = en.origin - en.velocity*0.2; + dir = normalize (dir - self.origin); + + FireBullets (1, dir, '0.1 0.1 0', MOD_SOLDIER); +}; + + + +void() army_die1 =[ $death1, army_die2 ] {remove(self); round_kills += 1; kill_count();}; +void() army_die2 =[ $death2, army_die3 ] {}; +void() army_die3 =[ $death3, army_die4 ] {self.solid = SOLID_NOT;DropBackpack();}; +void() army_die4 =[ $death4, army_die5 ] {}; +void() army_die5 =[ $death5, army_die6 ] {}; +void() army_die6 =[ $death6, army_die7 ] {}; +void() army_die7 =[ $death7, army_die8 ] {}; +void() army_die8 =[ $death8, army_die9 ] {}; +void() army_die9 =[ $death9, army_die10 ] {}; +void() army_die10 =[ $death10, army_die10 ] {}; + + +void() army_die = +{ + +// regular death + sound (self, CHAN_VOICE, "soldier/death1.wav", 1, ATTN_NORM); + army_die1 (); +}; diff --git a/r17/Revamped src/Revamped QC/quakemons/boss.qc b/r17/Revamped src/Revamped QC/quakemons/boss.qc new file mode 100755 index 00000000..caebe26f --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/boss.qc @@ -0,0 +1,373 @@ +/* +============================================================================== + +BOSS-ONE + +============================================================================== +*/ +$cd id1/models/boss1 +$origin 0 0 -15 +$base base +$skin skin +$scale 5 + +$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9 rise10 +$frame rise11 rise12 rise13 rise14 rise15 rise16 rise17 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 +$frame walk9 walk10 walk11 walk12 walk13 walk14 walk15 +$frame walk16 walk17 walk18 walk19 walk20 walk21 walk22 +$frame walk23 walk24 walk25 walk26 walk27 walk28 walk29 walk30 walk31 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 + +$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 +$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15 +$frame attack16 attack17 attack18 attack19 attack20 attack21 attack22 +$frame attack23 + +$frame shocka1 shocka2 shocka3 shocka4 shocka5 shocka6 shocka7 shocka8 +$frame shocka9 shocka10 + +$frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6 + +$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8 +$frame shockc9 shockc10 + + +void(vector p) boss_missile; + +void() boss_face = +{ + +// go for another player if multi player + if (self.enemy.health <= 0 || random() < 0.02) + { + self.enemy = find(self.enemy, classname, "player"); + if (!self.enemy) + self.enemy = find(self.enemy, classname, "player"); + } + ai_face(); +}; + +void() boss_rise1 =[ $rise1, boss_rise2 ] { +sound (self, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM); +}; +void() boss_rise2 =[ $rise2, boss_rise3 ] { +sound (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM); +}; +void() boss_rise3 =[ $rise3, boss_rise4 ] {}; +void() boss_rise4 =[ $rise4, boss_rise5 ] {}; +void() boss_rise5 =[ $rise5, boss_rise6 ] {}; +void() boss_rise6 =[ $rise6, boss_rise7 ] {}; +void() boss_rise7 =[ $rise7, boss_rise8 ] {}; +void() boss_rise8 =[ $rise8, boss_rise9 ] {}; +void() boss_rise9 =[ $rise9, boss_rise10 ] {}; +void() boss_rise10 =[ $rise10, boss_rise11 ] {}; +void() boss_rise11 =[ $rise11, boss_rise12 ] {}; +void() boss_rise12 =[ $rise12, boss_rise13 ] {}; +void() boss_rise13 =[ $rise13, boss_rise14 ] {}; +void() boss_rise14 =[ $rise14, boss_rise15 ] {}; +void() boss_rise15 =[ $rise15, boss_rise16 ] {}; +void() boss_rise16 =[ $rise16, boss_rise17 ] {}; +void() boss_rise17 =[ $rise17, boss_missile1 ] {}; + +void() boss_idle1 =[ $walk1, boss_idle2 ] +{ +// look for other players +}; +void() boss_idle2 =[ $walk2, boss_idle3 ] {boss_face();}; +void() boss_idle3 =[ $walk3, boss_idle4 ] {boss_face();}; +void() boss_idle4 =[ $walk4, boss_idle5 ] {boss_face();}; +void() boss_idle5 =[ $walk5, boss_idle6 ] {boss_face();}; +void() boss_idle6 =[ $walk6, boss_idle7 ] {boss_face();}; +void() boss_idle7 =[ $walk7, boss_idle8 ] {boss_face();}; +void() boss_idle8 =[ $walk8, boss_idle9 ] {boss_face();}; +void() boss_idle9 =[ $walk9, boss_idle10 ] {boss_face();}; +void() boss_idle10 =[ $walk10, boss_idle11 ] {boss_face();}; +void() boss_idle11 =[ $walk11, boss_idle12 ] {boss_face();}; +void() boss_idle12 =[ $walk12, boss_idle13 ] {boss_face();}; +void() boss_idle13 =[ $walk13, boss_idle14 ] {boss_face();}; +void() boss_idle14 =[ $walk14, boss_idle15 ] {boss_face();}; +void() boss_idle15 =[ $walk15, boss_idle16 ] {boss_face();}; +void() boss_idle16 =[ $walk16, boss_idle17 ] {boss_face();}; +void() boss_idle17 =[ $walk17, boss_idle18 ] {boss_face();}; +void() boss_idle18 =[ $walk18, boss_idle19 ] {boss_face();}; +void() boss_idle19 =[ $walk19, boss_idle20 ] {boss_face();}; +void() boss_idle20 =[ $walk20, boss_idle21 ] {boss_face();}; +void() boss_idle21 =[ $walk21, boss_idle22 ] {boss_face();}; +void() boss_idle22 =[ $walk22, boss_idle23 ] {boss_face();}; +void() boss_idle23 =[ $walk23, boss_idle24 ] {boss_face();}; +void() boss_idle24 =[ $walk24, boss_idle25 ] {boss_face();}; +void() boss_idle25 =[ $walk25, boss_idle26 ] {boss_face();}; +void() boss_idle26 =[ $walk26, boss_idle27 ] {boss_face();}; +void() boss_idle27 =[ $walk27, boss_idle28 ] {boss_face();}; +void() boss_idle28 =[ $walk28, boss_idle29 ] {boss_face();}; +void() boss_idle29 =[ $walk29, boss_idle30 ] {boss_face();}; +void() boss_idle30 =[ $walk30, boss_idle31 ] {boss_face();}; +void() boss_idle31 =[ $walk31, boss_idle1 ] {boss_face();}; + +void() boss_missile1 =[ $attack1, boss_missile2 ] {boss_face();}; +void() boss_missile2 =[ $attack2, boss_missile3 ] {boss_face();}; +void() boss_missile3 =[ $attack3, boss_missile4 ] {boss_face();}; +void() boss_missile4 =[ $attack4, boss_missile5 ] {boss_face();}; +void() boss_missile5 =[ $attack5, boss_missile6 ] {boss_face();}; +void() boss_missile6 =[ $attack6, boss_missile7 ] {boss_face();}; +void() boss_missile7 =[ $attack7, boss_missile8 ] {boss_face();}; +void() boss_missile8 =[ $attack8, boss_missile9 ] {boss_face();}; +void() boss_missile9 =[ $attack9, boss_missile10 ] {boss_missile('100 100 200');}; +void() boss_missile10 =[ $attack10, boss_missile11 ] {boss_face();}; +void() boss_missile11 =[ $attack11, boss_missile12 ] {boss_face();}; +void() boss_missile12 =[ $attack12, boss_missile13 ] {boss_face();}; +void() boss_missile13 =[ $attack13, boss_missile14 ] {boss_face();}; +void() boss_missile14 =[ $attack14, boss_missile15 ] {boss_face();}; +void() boss_missile15 =[ $attack15, boss_missile16 ] {boss_face();}; +void() boss_missile16 =[ $attack16, boss_missile17 ] {boss_face();}; +void() boss_missile17 =[ $attack17, boss_missile18 ] {boss_face();}; +void() boss_missile18 =[ $attack18, boss_missile19 ] {boss_face();}; +void() boss_missile19 =[ $attack19, boss_missile20 ] {boss_face();}; +void() boss_missile20 =[ $attack20, boss_missile21 ] {boss_missile('100 -100 200');}; +void() boss_missile21 =[ $attack21, boss_missile22 ] {boss_face();}; +void() boss_missile22 =[ $attack22, boss_missile23 ] {boss_face();}; +void() boss_missile23 =[ $attack23, boss_missile1 ] {boss_face();}; + +void() boss_shocka1 =[ $shocka1, boss_shocka2 ] {}; +void() boss_shocka2 =[ $shocka2, boss_shocka3 ] {}; +void() boss_shocka3 =[ $shocka3, boss_shocka4 ] {}; +void() boss_shocka4 =[ $shocka4, boss_shocka5 ] {}; +void() boss_shocka5 =[ $shocka5, boss_shocka6 ] {}; +void() boss_shocka6 =[ $shocka6, boss_shocka7 ] {}; +void() boss_shocka7 =[ $shocka7, boss_shocka8 ] {}; +void() boss_shocka8 =[ $shocka8, boss_shocka9 ] {}; +void() boss_shocka9 =[ $shocka9, boss_shocka10 ] {}; +void() boss_shocka10 =[ $shocka10, boss_missile1 ] {}; + +void() boss_shockb1 =[ $shockb1, boss_shockb2 ] {}; +void() boss_shockb2 =[ $shockb2, boss_shockb3 ] {}; +void() boss_shockb3 =[ $shockb3, boss_shockb4 ] {}; +void() boss_shockb4 =[ $shockb4, boss_shockb5 ] {}; +void() boss_shockb5 =[ $shockb5, boss_shockb6 ] {}; +void() boss_shockb6 =[ $shockb6, boss_shockb7 ] {}; +void() boss_shockb7 =[ $shockb1, boss_shockb8 ] {}; +void() boss_shockb8 =[ $shockb2, boss_shockb9 ] {}; +void() boss_shockb9 =[ $shockb3, boss_shockb10 ] {}; +void() boss_shockb10 =[ $shockb4, boss_missile1 ] {}; + +void() boss_shockc1 =[ $shockc1, boss_shockc2 ] {}; +void() boss_shockc2 =[ $shockc2, boss_shockc3 ] {}; +void() boss_shockc3 =[ $shockc3, boss_shockc4 ] {}; +void() boss_shockc4 =[ $shockc4, boss_shockc5 ] {}; +void() boss_shockc5 =[ $shockc5, boss_shockc6 ] {}; +void() boss_shockc6 =[ $shockc6, boss_shockc7 ] {}; +void() boss_shockc7 =[ $shockc7, boss_shockc8 ] {}; +void() boss_shockc8 =[ $shockc8, boss_shockc9 ] {}; +void() boss_shockc9 =[ $shockc9, boss_shockc10 ] {}; +void() boss_shockc10 =[ $shockc10, boss_death1 ] {}; + +void() boss_death1 = [$death1, boss_death2] { +sound (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM); +}; +void() boss_death2 = [$death2, boss_death3] {}; +void() boss_death3 = [$death3, boss_death4] {}; +void() boss_death4 = [$death4, boss_death5] {}; +void() boss_death5 = [$death5, boss_death6] {}; +void() boss_death6 = [$death6, boss_death7] {}; +void() boss_death7 = [$death7, boss_death8] {}; +void() boss_death8 = [$death8, boss_death9] {}; +void() boss_death9 = [$death9, boss_death10] +{ + sound (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM); + TE_lavasplash(self.origin); +}; + +void() boss_death10 = [$death9, boss_death10] +{ + killed_monsters = killed_monsters + 1; + WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast + SUB_UseTargets (); + remove (self); +}; + +void(vector p) boss_missile = +{ + local vector offang; + local vector org, vec, d; + local float t; + + offang = vectoangles (self.enemy.origin - self.origin); + makevectors (offang); + + org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1'; + +// lead the player on hard mode + if (skill > 1) + { + t = vlen(self.enemy.origin - org) / 300; + vec = self.enemy.velocity; + vec_z = 0; + d = self.enemy.origin + t * vec; + } + else + { + d = self.enemy.origin; + } + + vec = normalize(d - org) * 300; + + PRJ_FireProjectile(self, "progs/lavaball.mdl", org, vec, PE_EXPLOSION, 100+random()*20, MOD_CHTHON, 5); + PRJ_SetRadiusDamage(120, 160, MOD_CHTHON); + newmis.avelocity = '200 100 300'; + + sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM); + +// check for dead enemy + if (self.enemy.health <= 0) + boss_idle1 (); +}; + + +void() boss_awake = +{ + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + self.takedamage = DAMAGE_NO; + + setmodel (self, "progs/boss.mdl"); + setsize (self, '-128 -128 -24', '128 128 256'); + + if (skill == 0) + self.health = 1; + else + self.health = 3; + + self.enemy = activator; + + TE_lavasplash(self.origin); + + self.yaw_speed = 20; + boss_rise1 (); +}; + + +/*QUAKED monster_boss (1 0 0) (-128 -128 -24) (128 128 256) +*/ +void() monster_boss = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/boss.mdl"); + precache_model ("progs/lavaball.mdl"); + + precache_sound ("weapons/rocket1i.wav"); + precache_sound ("boss1/out1.wav"); + precache_sound ("boss1/sight1.wav"); + precache_sound ("misc/power.wav"); + precache_sound ("boss1/throw.wav"); + precache_sound ("boss1/pain.wav"); + precache_sound ("boss1/death.wav"); + + total_monsters = total_monsters + 1; + + self.use = boss_awake; +}; + +//=========================================================================== + +entity le1, le2; +float lightning_end; + +void() lightning_fire = +{ + local vector p1, p2; + + if (time >= lightning_end) + { // done here, put the terminals back up + self = le1; + door_go_down (); + self = le2; + door_go_down (); + return; + } + + p1 = (le1.mins + le1.maxs) * 0.5; + p1_z = le1.absmin_z - 16; + + p2 = (le2.mins + le2.maxs) * 0.5; + p2_z = le2.absmin_z - 16; + + // compensate for length of bolt + p2 = p2 - normalize(p2-p1)*100; + + self.nextthink = time + 0.1; + self.think = lightning_fire; + + TE_lightning3(world, p1, p2); +}; + +void() lightning_use = +{ + if (lightning_end >= time + 1) + return; + + le1 = find( world, target, "lightning"); + le2 = find( le1, target, "lightning"); + if (!le1 || !le2) + { + dprint ("missing lightning targets\n"); + return; + } + + if ( + (le1.state != STATE_TOP && le1.state != STATE_BOTTOM) + || (le2.state != STATE_TOP && le2.state != STATE_BOTTOM) + || (le1.state != le2.state) ) + { +// dprint ("not aligned\n"); + return; + } + +// don't let the electrodes go back up until the bolt is done + le1.nextthink = -1; + le2.nextthink = -1; + lightning_end = time + 1; + + sound (self, CHAN_VOICE, "misc/power.wav", 1, ATTN_NORM); + lightning_fire (); + +// advance the boss pain if down + self = find (world, classname, "monster_boss"); + if (!self) + return; + self.enemy = activator; + if (le1.state == STATE_TOP && self.health > 0) + { + sound (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM); + self.health = self.health - 1; + if (self.health >= 2) + boss_shocka1(); + else if (self.health == 1) + boss_shockb1(); + else if (self.health == 0) + boss_shockc1(); + } +}; + + +/*QUAKED event_lightning (0 1 1) (-16 -16 -16) (16 16 16) +Just for boss level. +*/ +void() event_lightning = +{ + if (deathmatch) + { + remove(self); + return; + } + + self.use = lightning_use; +}; + + diff --git a/r17/Revamped src/Revamped QC/quakemons/demon.qc b/r17/Revamped src/Revamped QC/quakemons/demon.qc new file mode 100755 index 00000000..cb1394e9 --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/demon.qc @@ -0,0 +1,357 @@ +/* +============================================================================== + +DEMON + +============================================================================== +*/ + +$cd id1/models/demon3 +$scale 0.8 +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 +$frame stand10 stand11 stand12 stand13 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 + +$frame run1 run2 run3 run4 run5 run6 + +$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 leap10 +$frame leap11 leap12 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 + +$frame attacka1 attacka2 attacka3 attacka4 attacka5 attacka6 attacka7 attacka8 +$frame attacka9 attacka10 attacka11 attacka12 attacka13 attacka14 attacka15 + +//============================================================================ + +void() Demon_JumpTouch; +void(float side) Demon_Melee; + +void() demon1_stand1 =[ $stand1, demon1_stand2 ] {ai_stand();}; +void() demon1_stand2 =[ $stand2, demon1_stand3 ] {ai_stand();}; +void() demon1_stand3 =[ $stand3, demon1_stand4 ] {ai_stand();}; +void() demon1_stand4 =[ $stand4, demon1_stand5 ] {ai_stand();}; +void() demon1_stand5 =[ $stand5, demon1_stand6 ] {ai_stand();}; +void() demon1_stand6 =[ $stand6, demon1_stand7 ] {ai_stand();}; +void() demon1_stand7 =[ $stand7, demon1_stand8 ] {ai_stand();}; +void() demon1_stand8 =[ $stand8, demon1_stand9 ] {ai_stand();}; +void() demon1_stand9 =[ $stand9, demon1_stand10 ] {ai_stand();}; +void() demon1_stand10 =[ $stand10, demon1_stand11 ] {ai_stand();}; +void() demon1_stand11 =[ $stand11, demon1_stand12 ] {ai_stand();}; +void() demon1_stand12 =[ $stand12, demon1_stand13 ] {ai_stand();}; +void() demon1_stand13 =[ $stand13, demon1_stand1 ] {ai_stand();}; + +void() demon1_walk1 =[ $walk1, demon1_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE); +ai_walk(8); +}; +void() demon1_walk2 =[ $walk2, demon1_walk3 ] {ai_walk(6);}; +void() demon1_walk3 =[ $walk3, demon1_walk4 ] {ai_walk(6);}; +void() demon1_walk4 =[ $walk4, demon1_walk5 ] {ai_walk(7);}; +void() demon1_walk5 =[ $walk5, demon1_walk6 ] {ai_walk(4);}; +void() demon1_walk6 =[ $walk6, demon1_walk7 ] {ai_walk(6);}; +void() demon1_walk7 =[ $walk7, demon1_walk8 ] {ai_walk(10);}; +void() demon1_walk8 =[ $walk8, demon1_walk1 ] {ai_walk(10);}; + +void() demon1_run1 =[ $run1, demon1_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE); +ai_run(20);}; +void() demon1_run2 =[ $run2, demon1_run3 ] {ai_run(15);}; +void() demon1_run3 =[ $run3, demon1_run4 ] {ai_run(36);}; +void() demon1_run4 =[ $run4, demon1_run5 ] {ai_run(20);}; +void() demon1_run5 =[ $run5, demon1_run6 ] {ai_run(15);}; +void() demon1_run6 =[ $run6, demon1_run1 ] {ai_run(36);}; + +void() demon1_jump1 =[ $leap1, demon1_jump2 ] {ai_face();}; +void() demon1_jump2 =[ $leap2, demon1_jump3 ] {ai_face();}; +void() demon1_jump3 =[ $leap3, demon1_jump4 ] {ai_face();}; +void() demon1_jump4 =[ $leap4, demon1_jump5 ] +{ + ai_face(); + + self.touch = Demon_JumpTouch; + makevectors (self.angles); + self.origin_z = self.origin_z + 1; + self.velocity = v_forward * 600 + '0 0 250'; + if (self.flags & FL_ONGROUND) + self.flags = self.flags - FL_ONGROUND; +}; +void() demon1_jump5 =[ $leap5, demon1_jump6 ] {}; +void() demon1_jump6 =[ $leap6, demon1_jump7 ] {}; +void() demon1_jump7 =[ $leap7, demon1_jump8 ] {}; +void() demon1_jump8 =[ $leap8, demon1_jump9 ] {}; +void() demon1_jump9 =[ $leap9, demon1_jump10 ] {}; +void() demon1_jump10 =[ $leap10, demon1_jump1 ] { +self.nextthink = time + 3; +// if three seconds pass, assume demon is stuck and jump again +}; + +void() demon1_jump11 =[ $leap11, demon1_jump12 ] {}; +void() demon1_jump12 =[ $leap12, demon1_run1 ] {}; + + +void() demon1_atta1 =[ $attacka1, demon1_atta2 ] {ai_charge(4);}; +void() demon1_atta2 =[ $attacka2, demon1_atta3 ] {ai_charge(0);}; +void() demon1_atta3 =[ $attacka3, demon1_atta4 ] {ai_charge(0);}; +void() demon1_atta4 =[ $attacka4, demon1_atta5 ] {ai_charge(1);}; +void() demon1_atta5 =[ $attacka5, demon1_atta6 ] {ai_charge(2); Demon_Melee(200);}; +void() demon1_atta6 =[ $attacka6, demon1_atta7 ] {ai_charge(1);}; +void() demon1_atta7 =[ $attacka7, demon1_atta8 ] {ai_charge(6);}; +void() demon1_atta8 =[ $attacka8, demon1_atta9 ] {ai_charge(8);}; +void() demon1_atta9 =[ $attacka9, demon1_atta10] {ai_charge(4);}; +void() demon1_atta10 =[ $attacka10, demon1_atta11] {ai_charge(2);}; +void() demon1_atta11 =[ $attacka11, demon1_atta12] {Demon_Melee(-200);}; +void() demon1_atta12 =[ $attacka12, demon1_atta13] {ai_charge(5);}; +void() demon1_atta13 =[ $attacka13, demon1_atta14] {ai_charge(8);}; +void() demon1_atta14 =[ $attacka14, demon1_atta15] {ai_charge(4);}; +void() demon1_atta15 =[ $attacka15, demon1_run1] {ai_charge(4);}; + +void() demon1_pain1 =[ $pain1, demon1_pain2 ] {}; +void() demon1_pain2 =[ $pain2, demon1_pain3 ] {}; +void() demon1_pain3 =[ $pain3, demon1_pain4 ] {}; +void() demon1_pain4 =[ $pain4, demon1_pain5 ] {}; +void() demon1_pain5 =[ $pain5, demon1_pain6 ] {}; +void() demon1_pain6 =[ $pain6, demon1_run1 ] {}; + +void(entity attacker, float damage) demon1_pain = +{ + if (self.touch == Demon_JumpTouch) + return; + + if (self.pain_finished > time) + return; + + self.pain_finished = time + 1; + sound (self, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM); + + if (random()*200 > damage) + return; // didn't flinch + + demon1_pain1 (); +}; + +void() demon1_die1 =[ $death1, demon1_die2 ] { +sound (self, CHAN_VOICE, "demon/ddeath.wav", 1, ATTN_NORM);}; +void() demon1_die2 =[ $death2, demon1_die3 ] {}; +void() demon1_die3 =[ $death3, demon1_die4 ] {}; +void() demon1_die4 =[ $death4, demon1_die5 ] {}; +void() demon1_die5 =[ $death5, demon1_die6 ] {}; +void() demon1_die6 =[ $death6, demon1_die7 ] +{self.solid = SOLID_NOT;}; +void() demon1_die7 =[ $death7, demon1_die8 ] {}; +void() demon1_die8 =[ $death8, demon1_die9 ] {}; +void() demon1_die9 =[ $death9, demon1_die9 ] {}; + +void() demon_die = +{ +// check for gib + if (self.health < -80) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_demon.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + return; + } + +// regular death + demon1_die1 (); +}; + + +void() Demon_MeleeAttack = +{ + demon1_atta1 (); +}; + + +/*QUAKED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) Ambush + +*/ +void() monster_demon1 = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/demon.mdl"); + precache_model ("progs/h_demon.mdl"); + + precache_sound ("demon/ddeath.wav"); + precache_sound ("demon/dhit2.wav"); + precache_sound ("demon/djump.wav"); + precache_sound ("demon/dpain1.wav"); + precache_sound ("demon/idle1.wav"); + precache_sound ("demon/sight2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/demon.mdl"); + + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 300; + + self.th_stand = demon1_stand1; + self.th_walk = demon1_walk1; + self.th_run = demon1_run1; + self.th_die = demon_die; + self.th_melee = Demon_MeleeAttack; // one of two attacks + self.th_missile = demon1_jump1; // jump attack + self.th_pain = demon1_pain; + + walkmonster_start(); +}; + + +/* +============================================================================== + +DEMON + +============================================================================== +*/ + +/* +============== +CheckDemonMelee + +Returns TRUE if a melee attack would hit right now +============== +*/ +BOOL(float enemy_range) CheckDemonMelee = +{ + if (enemy_range == RANGE_MELEE) + { // FIXME: check canreach + self.attack_state = AS_MELEE; + return TRUE; + } + return FALSE; +}; + +/* +============== +CheckDemonJump + +============== +*/ +BOOL() CheckDemonJump = +{ + local vector dist; + local float d; + + if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z + + 0.75 * self.enemy.size_z) + return FALSE; + + if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z + + 0.25 * self.enemy.size_z) + return FALSE; + + dist = self.enemy.origin - self.origin; + dist_z = 0; + + d = vlen(dist); + + if (d < 100) + return FALSE; + + if (d > 200) + { + if (random() < 0.9) + return FALSE; + } + + return TRUE; +}; + +BOOL(float enemy_range) DemonCheckAttack = +{ +// if close enough for slashing, go for it + if (CheckDemonMelee (enemy_range)) + { + self.attack_state = AS_MELEE; + return TRUE; + } + + if (CheckDemonJump ()) + { + self.attack_state = AS_MISSILE; + sound (self, CHAN_VOICE, "demon/djump.wav", 1, ATTN_NORM); + return TRUE; + } + + return FALSE; +}; + + +//=========================================================================== + +void(float side) Demon_Melee = +{ + local float ldmg; + local vector delta; + + ai_face (); + walkmove (self.ideal_yaw, 12); // allow a little closing + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + if (!CanDamage (self.enemy, self)) + return; + + sound (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM); + ldmg = 10 + 5*random(); + T_Damage (self.enemy, self, self, ldmg, MOD_DEMON); + + makevectors (self.angles); + SpawnMeatSpray (self.origin + v_forward*16, side * v_right); +}; + + +void() Demon_JumpTouch = +{ + local float ldmg; + + if (self.health <= 0) + return; + + if (other.takedamage) + { + if ( vlen(self.velocity) > 400 ) + { + ldmg = 40 + 10*random(); + T_Damage (other, self, self, ldmg, MOD_DEMON); + } + } + + if (!checkbottom(self)) + { + if (self.flags & FL_ONGROUND) + { // jump randomly to not get hung up + self.touch = SUB_Null; + self.think = demon1_jump1; + self.nextthink = time + 0.1; + } + return; // not on ground yet + } + + self.touch = SUB_Null; + self.think = demon1_jump11; + self.nextthink = time + 0.1; +}; + + \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/quakemons/dog.qc b/r17/Revamped src/Revamped QC/quakemons/dog.qc new file mode 100755 index 00000000..155cb850 --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/dog.qc @@ -0,0 +1,357 @@ +/* +============================================================================== + +DOG + +============================================================================== +*/ +$cd id1/models/dog +$origin 0 0 24 +$base base +$skin skin + +$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10 +$frame painb11 painb12 painb13 painb14 painb15 painb16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 + +$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 + + +void() dog_leap1; +void() dog_run1; + +/* +================ +dog_bite + +================ +*/ +void() dog_bite = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + + ai_charge(10); + + if (!CanDamage (self.enemy, self)) + return; + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + ldmg = (random() + random() + random()) * 8; + T_Damage (self.enemy, self, self, ldmg, MOD_DOG); +}; + +void() Dog_JumpTouch = +{ + local float ldmg; + + if (self.health <= 0) + return; + + if (other.takedamage) + { + if ( vlen(self.velocity) > 300 ) + { + ldmg = 10 + 10*random(); + T_Damage (other, self, self, ldmg, MOD_DOG); + } + } + + if (!checkbottom(self)) + { + if (self.flags & FL_ONGROUND) + { + // jump randomly to not get hung up + self.touch = SUB_Null; + self.think = dog_leap1; + self.nextthink = time + 0.1; + } + return; // not on ground yet + } + + self.touch = SUB_Null; + self.think = dog_run1; + self.nextthink = time + 0.1; +}; + + +void() dog_stand1 =[ $stand1, dog_stand2 ] {ai_stand();}; +void() dog_stand2 =[ $stand2, dog_stand3 ] {ai_stand();}; +void() dog_stand3 =[ $stand3, dog_stand4 ] {ai_stand();}; +void() dog_stand4 =[ $stand4, dog_stand5 ] {ai_stand();}; +void() dog_stand5 =[ $stand5, dog_stand6 ] {ai_stand();}; +void() dog_stand6 =[ $stand6, dog_stand7 ] {ai_stand();}; +void() dog_stand7 =[ $stand7, dog_stand8 ] {ai_stand();}; +void() dog_stand8 =[ $stand8, dog_stand9 ] {ai_stand();}; +void() dog_stand9 =[ $stand9, dog_stand1 ] {ai_stand();}; + +void() dog_walk1 =[ $walk1 , dog_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); +ai_walk(8);}; +void() dog_walk2 =[ $walk2 , dog_walk3 ] {ai_walk(8);}; +void() dog_walk3 =[ $walk3 , dog_walk4 ] {ai_walk(8);}; +void() dog_walk4 =[ $walk4 , dog_walk5 ] {ai_walk(8);}; +void() dog_walk5 =[ $walk5 , dog_walk6 ] {ai_walk(8);}; +void() dog_walk6 =[ $walk6 , dog_walk7 ] {ai_walk(8);}; +void() dog_walk7 =[ $walk7 , dog_walk8 ] {ai_walk(8);}; +void() dog_walk8 =[ $walk8 , dog_walk1 ] {ai_walk(8);}; + +void() dog_run1 =[ $run1 , dog_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); +ai_run(16);}; +void() dog_run2 =[ $run2 , dog_run3 ] {ai_run(32);}; +void() dog_run3 =[ $run3 , dog_run4 ] {ai_run(32);}; +void() dog_run4 =[ $run4 , dog_run5 ] {ai_run(20);}; +void() dog_run5 =[ $run5 , dog_run6 ] {ai_run(64);}; +void() dog_run6 =[ $run6 , dog_run7 ] {ai_run(32);}; +void() dog_run7 =[ $run7 , dog_run8 ] {ai_run(16);}; +void() dog_run8 =[ $run8 , dog_run9 ] {ai_run(32);}; +void() dog_run9 =[ $run9 , dog_run10 ] {ai_run(32);}; +void() dog_run10 =[ $run10 , dog_run11 ] {ai_run(20);}; +void() dog_run11 =[ $run11 , dog_run12 ] {ai_run(64);}; +void() dog_run12 =[ $run12 , dog_run1 ] {ai_run(32);}; + +void() dog_atta1 =[ $attack1, dog_atta2 ] {ai_charge(10);}; +void() dog_atta2 =[ $attack2, dog_atta3 ] {ai_charge(10);}; +void() dog_atta3 =[ $attack3, dog_atta4 ] {ai_charge(10);}; +void() dog_atta4 =[ $attack4, dog_atta5 ] { +sound (self, CHAN_VOICE, "dog/dattack1.wav", 1, ATTN_NORM); +dog_bite();}; +void() dog_atta5 =[ $attack5, dog_atta6 ] {ai_charge(10);}; +void() dog_atta6 =[ $attack6, dog_atta7 ] {ai_charge(10);}; +void() dog_atta7 =[ $attack7, dog_atta8 ] {ai_charge(10);}; +void() dog_atta8 =[ $attack8, dog_run1 ] {ai_charge(10);}; + +void() dog_leap1 =[ $leap1, dog_leap2 ] {ai_face();}; +void() dog_leap2 =[ $leap2, dog_leap3 ] +{ + ai_face(); + + self.touch = Dog_JumpTouch; + makevectors (self.angles); + self.origin_z = self.origin_z + 1; + self.velocity = v_forward * 300 + '0 0 200'; + if (self.flags & FL_ONGROUND) + self.flags = self.flags - FL_ONGROUND; +}; + +void() dog_leap3 =[ $leap3, dog_leap4 ] {}; +void() dog_leap4 =[ $leap4, dog_leap5 ] {}; +void() dog_leap5 =[ $leap5, dog_leap6 ] {}; +void() dog_leap6 =[ $leap6, dog_leap7 ] {}; +void() dog_leap7 =[ $leap7, dog_leap8 ] {}; +void() dog_leap8 =[ $leap8, dog_leap9 ] {}; +void() dog_leap9 =[ $leap9, dog_leap9 ] {}; + +void() dog_pain1 =[ $pain1 , dog_pain2 ] {}; +void() dog_pain2 =[ $pain2 , dog_pain3 ] {}; +void() dog_pain3 =[ $pain3 , dog_pain4 ] {}; +void() dog_pain4 =[ $pain4 , dog_pain5 ] {}; +void() dog_pain5 =[ $pain5 , dog_pain6 ] {}; +void() dog_pain6 =[ $pain6 , dog_run1 ] {}; + +void() dog_painb1 =[ $painb1 , dog_painb2 ] {}; +void() dog_painb2 =[ $painb2 , dog_painb3 ] {}; +void() dog_painb3 =[ $painb3 , dog_painb4 ] {ai_pain(4);}; +void() dog_painb4 =[ $painb4 , dog_painb5 ] {ai_pain(12);}; +void() dog_painb5 =[ $painb5 , dog_painb6 ] {ai_pain(12);}; +void() dog_painb6 =[ $painb6 , dog_painb7 ] {ai_pain(2);}; +void() dog_painb7 =[ $painb7 , dog_painb8 ] {}; +void() dog_painb8 =[ $painb8 , dog_painb9 ] {ai_pain(4);}; +void() dog_painb9 =[ $painb9 , dog_painb10 ] {}; +void() dog_painb10 =[ $painb10 , dog_painb11 ] {ai_pain(10);}; +void() dog_painb11 =[ $painb11 , dog_painb12 ] {}; +void() dog_painb12 =[ $painb12 , dog_painb13 ] {}; +void() dog_painb13 =[ $painb13 , dog_painb14 ] {}; +void() dog_painb14 =[ $painb14 , dog_painb15 ] {}; +void() dog_painb15 =[ $painb15 , dog_painb16 ] {}; +void() dog_painb16 =[ $painb16 , dog_run1 ] {}; + +void() dog_pain = +{ + sound (self, CHAN_VOICE, "dog/dpain1.wav", 1, ATTN_NORM); + + if (random() > 0.5) + dog_pain1 (); + else + dog_painb1 (); +}; + +void() dog_die1 =[ $death1, dog_die2 ] {}; +void() dog_die2 =[ $death2, dog_die3 ] {}; +void() dog_die3 =[ $death3, dog_die4 ] {}; +void() dog_die4 =[ $death4, dog_die5 ] {}; +void() dog_die5 =[ $death5, dog_die6 ] {}; +void() dog_die6 =[ $death6, dog_die7 ] {}; +void() dog_die7 =[ $death7, dog_die8 ] {}; +void() dog_die8 =[ $death8, dog_die9 ] {}; +void() dog_die9 =[ $death9, dog_die9 ] {}; + +void() dog_dieb1 =[ $deathb1, dog_dieb2 ] {}; +void() dog_dieb2 =[ $deathb2, dog_dieb3 ] {}; +void() dog_dieb3 =[ $deathb3, dog_dieb4 ] {}; +void() dog_dieb4 =[ $deathb4, dog_dieb5 ] {}; +void() dog_dieb5 =[ $deathb5, dog_dieb6 ] {}; +void() dog_dieb6 =[ $deathb6, dog_dieb7 ] {}; +void() dog_dieb7 =[ $deathb7, dog_dieb8 ] {}; +void() dog_dieb8 =[ $deathb8, dog_dieb9 ] {}; +void() dog_dieb9 =[ $deathb9, dog_dieb9 ] {}; + + +void() dog_die = +{ +// check for gib + if (self.health < -35) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowHead ("progs/h_dog.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "dog/ddeath.wav", 1, ATTN_NORM); + self.solid = SOLID_NOT; + + if (random() > 0.5) + dog_die1 (); + else + dog_dieb1 (); +}; + +//============================================================================ + +/* +============== +CheckDogMelee + +Returns TRUE if a melee attack would hit right now +============== +*/ +BOOL(float enemy_range) CheckDogMelee = +{ + if (enemy_range == RANGE_MELEE) + { // FIXME: check canreach + self.attack_state = AS_MELEE; + return TRUE; + } + return FALSE; +}; + +/* +============== +CheckDogJump + +============== +*/ +BOOL() CheckDogJump = +{ + local vector dist; + local float d; + + if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z + + 0.75 * self.enemy.size_z) + return FALSE; + + if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z + + 0.25 * self.enemy.size_z) + return FALSE; + + dist = self.enemy.origin - self.origin; + dist_z = 0; + + d = vlen(dist); + + if (d < 80) + return FALSE; + + if (d > 150) + return FALSE; + + return TRUE; +}; + +BOOL(float enemy_range) DogCheckAttack = +{ +// if close enough for slashing, go for it + if (CheckDogMelee (enemy_range)) + { + self.attack_state = AS_MELEE; + return TRUE; + } + + if (CheckDogJump ()) + { + self.attack_state = AS_MISSILE; + return TRUE; + } + + return FALSE; +}; + + +//=========================================================================== + +/*QUAKED monster_dog (1 0 0) (-32 -32 -24) (32 32 40) Ambush + +*/ +void() monster_dog = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/h_dog.mdl"); + precache_model ("progs/dog.mdl"); + + precache_sound ("dog/dattack1.wav"); + precache_sound ("dog/ddeath.wav"); + precache_sound ("dog/dpain1.wav"); + precache_sound ("dog/dsight.wav"); + precache_sound ("dog/idle.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/dog.mdl"); + + setsize (self, '-32 -32 -24', '32 32 40'); + self.health = 25; + + self.th_stand = dog_stand1; + self.th_walk = dog_walk1; + self.th_run = dog_run1; + self.th_pain = dog_pain; + self.th_die = dog_die; + self.th_melee = dog_atta1; + self.th_missile = dog_leap1; + + walkmonster_start(); +}; + \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/quakemons/enforcer.qc b/r17/Revamped src/Revamped QC/quakemons/enforcer.qc new file mode 100755 index 00000000..4f93900d --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/enforcer.qc @@ -0,0 +1,282 @@ +/* +============================================================================== + +SOLDIER / PLAYER + +============================================================================== +*/ + +$cd id1/models/enforcer +$origin 0 -6 24 +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 +$frame walk11 walk12 walk13 walk14 walk15 walk16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame attack1 attack2 attack3 attack4 attack5 attack6 +$frame attack7 attack8 attack9 attack10 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 death11 death12 death13 death14 + +$frame fdeath1 fdeath2 fdeath3 fdeath4 fdeath5 fdeath6 fdeath7 fdeath8 +$frame fdeath9 fdeath10 fdeath11 + +$frame paina1 paina2 paina3 paina4 + +$frame painb1 painb2 painb3 painb4 painb5 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 +$frame paind9 paind10 paind11 paind12 paind13 paind14 paind15 paind16 +$frame paind17 paind18 paind19 + +void() enforcer_fire = +{ + local vector org, vec; + + muzzleflash(); + makevectors (self.angles); + + org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16'; + vec = normalize(self.enemy.origin - self.origin) * 600; + + sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM); + PRJ_FireProjectile(self, "progs/laser.mdl", org, vec, PE_LASER, 15, MOD_ENFORCER, 5); + newmis.effects |= EF_DIMLIGHT; + newmis.alpha = 0.5; +}; + +//============================================================================ + +void() enf_stand1 =[ $stand1, enf_stand2 ] {ai_stand();}; +void() enf_stand2 =[ $stand2, enf_stand3 ] {ai_stand();}; +void() enf_stand3 =[ $stand3, enf_stand4 ] {ai_stand();}; +void() enf_stand4 =[ $stand4, enf_stand5 ] {ai_stand();}; +void() enf_stand5 =[ $stand5, enf_stand6 ] {ai_stand();}; +void() enf_stand6 =[ $stand6, enf_stand7 ] {ai_stand();}; +void() enf_stand7 =[ $stand7, enf_stand1 ] {ai_stand();}; + +void() enf_walk1 =[ $walk1 , enf_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); +ai_walk(2);}; +void() enf_walk2 =[ $walk2 , enf_walk3 ] {ai_walk(4);}; +void() enf_walk3 =[ $walk3 , enf_walk4 ] {ai_walk(4);}; +void() enf_walk4 =[ $walk4 , enf_walk5 ] {ai_walk(3);}; +void() enf_walk5 =[ $walk5 , enf_walk6 ] {ai_walk(1);}; +void() enf_walk6 =[ $walk6 , enf_walk7 ] {ai_walk(2);}; +void() enf_walk7 =[ $walk7 , enf_walk8 ] {ai_walk(2);}; +void() enf_walk8 =[ $walk8 , enf_walk9 ] {ai_walk(1);}; +void() enf_walk9 =[ $walk9 , enf_walk10 ] {ai_walk(2);}; +void() enf_walk10 =[ $walk10, enf_walk11 ] {ai_walk(4);}; +void() enf_walk11 =[ $walk11, enf_walk12 ] {ai_walk(4);}; +void() enf_walk12 =[ $walk12, enf_walk13 ] {ai_walk(1);}; +void() enf_walk13 =[ $walk13, enf_walk14 ] {ai_walk(2);}; +void() enf_walk14 =[ $walk14, enf_walk15 ] {ai_walk(3);}; +void() enf_walk15 =[ $walk15, enf_walk16 ] {ai_walk(4);}; +void() enf_walk16 =[ $walk16, enf_walk1 ] {ai_walk(2);}; + +void() enf_run1 =[ $run1 , enf_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); +ai_run(18);}; +void() enf_run2 =[ $run2 , enf_run3 ] {ai_run(14);}; +void() enf_run3 =[ $run3 , enf_run4 ] {ai_run(7);}; +void() enf_run4 =[ $run4 , enf_run5 ] {ai_run(12);}; +void() enf_run5 =[ $run5 , enf_run6 ] {ai_run(14);}; +void() enf_run6 =[ $run6 , enf_run7 ] {ai_run(14);}; +void() enf_run7 =[ $run7 , enf_run8 ] {ai_run(7);}; +void() enf_run8 =[ $run8 , enf_run1 ] {ai_run(11);}; + +void() enf_atk1 =[ $attack1, enf_atk2 ] {ai_face();}; +void() enf_atk2 =[ $attack2, enf_atk3 ] {ai_face();}; +void() enf_atk3 =[ $attack3, enf_atk4 ] {ai_face();}; +void() enf_atk4 =[ $attack4, enf_atk5 ] {ai_face();}; +void() enf_atk5 =[ $attack5, enf_atk6 ] {ai_face();}; +void() enf_atk6 =[ $attack6, enf_atk7 ] {enforcer_fire();}; +void() enf_atk7 =[ $attack7, enf_atk8 ] {ai_face();}; +void() enf_atk8 =[ $attack8, enf_atk9 ] {ai_face();}; +void() enf_atk9 =[ $attack5, enf_atk10 ] {ai_face();}; +void() enf_atk10 =[ $attack6, enf_atk11 ] {enforcer_fire();}; +void() enf_atk11 =[ $attack7, enf_atk12 ] {ai_face();}; +void() enf_atk12 =[ $attack8, enf_atk13 ] {ai_face();}; +void() enf_atk13 =[ $attack9, enf_atk14 ] {ai_face();}; +void() enf_atk14 =[ $attack10, enf_run1 ] {ai_face(); +SUB_CheckRefire (enf_atk1); +}; + +void() enf_paina1 =[ $paina1, enf_paina2 ] {}; +void() enf_paina2 =[ $paina2, enf_paina3 ] {}; +void() enf_paina3 =[ $paina3, enf_paina4 ] {}; +void() enf_paina4 =[ $paina4, enf_run1 ] {}; + +void() enf_painb1 =[ $painb1, enf_painb2 ] {}; +void() enf_painb2 =[ $painb2, enf_painb3 ] {}; +void() enf_painb3 =[ $painb3, enf_painb4 ] {}; +void() enf_painb4 =[ $painb4, enf_painb5 ] {}; +void() enf_painb5 =[ $painb5, enf_run1 ] {}; + +void() enf_painc1 =[ $painc1, enf_painc2 ] {}; +void() enf_painc2 =[ $painc2, enf_painc3 ] {}; +void() enf_painc3 =[ $painc3, enf_painc4 ] {}; +void() enf_painc4 =[ $painc4, enf_painc5 ] {}; +void() enf_painc5 =[ $painc5, enf_painc6 ] {}; +void() enf_painc6 =[ $painc6, enf_painc7 ] {}; +void() enf_painc7 =[ $painc7, enf_painc8 ] {}; +void() enf_painc8 =[ $painc8, enf_run1 ] {}; + +void() enf_paind1 =[ $paind1, enf_paind2 ] {}; +void() enf_paind2 =[ $paind2, enf_paind3 ] {}; +void() enf_paind3 =[ $paind3, enf_paind4 ] {}; +void() enf_paind4 =[ $paind4, enf_paind5 ] {ai_painforward(2);}; +void() enf_paind5 =[ $paind5, enf_paind6 ] {ai_painforward(1);}; +void() enf_paind6 =[ $paind6, enf_paind7 ] {}; +void() enf_paind7 =[ $paind7, enf_paind8 ] {}; +void() enf_paind8 =[ $paind8, enf_paind9 ] {}; +void() enf_paind9 =[ $paind9, enf_paind10 ] {}; +void() enf_paind10 =[ $paind10, enf_paind11 ] {}; +void() enf_paind11 =[ $paind11, enf_paind12 ] {ai_painforward(1);}; +void() enf_paind12 =[ $paind12, enf_paind13 ] {ai_painforward(1);}; +void() enf_paind13 =[ $paind13, enf_paind14 ] {ai_painforward(1);}; +void() enf_paind14 =[ $paind14, enf_paind15 ] {}; +void() enf_paind15 =[ $paind15, enf_paind16 ] {}; +void() enf_paind16 =[ $paind16, enf_paind17 ] {ai_pain(1);}; +void() enf_paind17 =[ $paind17, enf_paind18 ] {ai_pain(1);}; +void() enf_paind18 =[ $paind18, enf_paind19 ] {}; +void() enf_paind19 =[ $paind19, enf_run1 ] {}; + +void(entity attacker, float damage) enf_pain = +{ + local float r; + + if (self.pain_finished > time) + return; + + r = random (); + if (r < 0.5) + sound (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM); + + self.pain_finished = time + 1; + if (r < 0.2) + enf_paina1 (); + else if (r < 0.4) + enf_painb1 (); + else if (r < 0.7) + enf_painc1 (); + else + enf_paind1 (); +}; + +//============================================================================ + + + + +void() enf_die1 =[ $death1, enf_die2 ] {}; +void() enf_die2 =[ $death2, enf_die3 ] {}; +void() enf_die3 =[ $death3, enf_die4 ] +{self.solid = SOLID_NOT;DropBackpack();}; +void() enf_die4 =[ $death4, enf_die5 ] {ai_forward(14);}; +void() enf_die5 =[ $death5, enf_die6 ] {ai_forward(2);}; +void() enf_die6 =[ $death6, enf_die7 ] {}; +void() enf_die7 =[ $death7, enf_die8 ] {}; +void() enf_die8 =[ $death8, enf_die9 ] {}; +void() enf_die9 =[ $death9, enf_die10 ] {ai_forward(3);}; +void() enf_die10 =[ $death10, enf_die11 ] {ai_forward(5);}; +void() enf_die11 =[ $death11, enf_die12 ] {ai_forward(5);}; +void() enf_die12 =[ $death12, enf_die13 ] {ai_forward(5);}; +void() enf_die13 =[ $death13, enf_die14 ] {}; +void() enf_die14 =[ $death14, enf_die14 ] {}; + +void() enf_fdie1 =[ $fdeath1, enf_fdie2 ] { + +}; +void() enf_fdie2 =[ $fdeath2, enf_fdie3 ] {}; +void() enf_fdie3 =[ $fdeath3, enf_fdie4 ] +{self.solid = SOLID_NOT;DropBackpack();}; +void() enf_fdie4 =[ $fdeath4, enf_fdie5 ] {}; +void() enf_fdie5 =[ $fdeath5, enf_fdie6 ] {}; +void() enf_fdie6 =[ $fdeath6, enf_fdie7 ] {}; +void() enf_fdie7 =[ $fdeath7, enf_fdie8 ] {}; +void() enf_fdie8 =[ $fdeath8, enf_fdie9 ] {}; +void() enf_fdie9 =[ $fdeath9, enf_fdie10 ] {}; +void() enf_fdie10 =[ $fdeath10, enf_fdie11 ] {}; +void() enf_fdie11 =[ $fdeath11, enf_fdie11 ] {}; + + +void() enf_die = +{ +// check for gib + if (self.health < -35) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_mega.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM); + if (random() > 0.5) + enf_die1 (); + else + enf_fdie1 (); +}; + + +/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) Ambush + +*/ +void() monster_enforcer = +{ + if (deathmatch) + { + remove(self); + return; + } + + precache_model2 ("progs/enforcer.mdl"); + precache_model2 ("progs/h_mega.mdl"); + precache_model2 ("progs/laser.mdl"); + + precache_sound2 ("enforcer/death1.wav"); + precache_sound2 ("enforcer/enfire.wav"); + precache_sound2 ("enforcer/enfstop.wav"); + precache_sound2 ("enforcer/idle1.wav"); + precache_sound2 ("enforcer/pain1.wav"); + precache_sound2 ("enforcer/pain2.wav"); + precache_sound2 ("enforcer/sight1.wav"); + precache_sound2 ("enforcer/sight2.wav"); + precache_sound2 ("enforcer/sight3.wav"); + precache_sound2 ("enforcer/sight4.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/enforcer.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 80; + + self.th_stand = enf_stand1; + self.th_walk = enf_walk1; + self.th_run = enf_run1; + self.th_pain = enf_pain; + self.th_die = enf_die; + self.th_missile = enf_atk1; + + self.ammo_cells_real = 5; // drop 5 cells on death + + walkmonster_start(); +}; diff --git a/r17/Revamped src/Revamped QC/quakemons/fish.qc b/r17/Revamped src/Revamped QC/quakemons/fish.qc new file mode 100755 index 00000000..22d2bc51 --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/fish.qc @@ -0,0 +1,186 @@ +$cd id1/models/fish +$origin 0 0 24 +$base base +$skin skin + +$frame attack1 attack2 attack3 attack4 attack5 attack6 +$frame attack7 attack8 attack9 attack10 attack11 attack12 attack13 +$frame attack14 attack15 attack16 attack17 attack18 + +$frame death1 death2 death3 death4 death5 death6 death7 +$frame death8 death9 death10 death11 death12 death13 death14 death15 +$frame death16 death17 death18 death19 death20 death21 + +$frame swim1 swim2 swim3 swim4 swim5 swim6 swim7 swim8 +$frame swim9 swim10 swim11 swim12 swim13 swim14 swim15 swim16 swim17 +$frame swim18 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8 +$frame pain9 + +void() swimmonster_start; + +void() f_stand1 =[ $swim1, f_stand2 ] {ai_stand();}; +void() f_stand2 =[ $swim2, f_stand3 ] {ai_stand();}; +void() f_stand3 =[ $swim3, f_stand4 ] {ai_stand();}; +void() f_stand4 =[ $swim4, f_stand5 ] {ai_stand();}; +void() f_stand5 =[ $swim5, f_stand6 ] {ai_stand();}; +void() f_stand6 =[ $swim6, f_stand7 ] {ai_stand();}; +void() f_stand7 =[ $swim7, f_stand8 ] {ai_stand();}; +void() f_stand8 =[ $swim8, f_stand9 ] {ai_stand();}; +void() f_stand9 =[ $swim9, f_stand10 ] {ai_stand();}; +void() f_stand10 =[ $swim10, f_stand11 ] {ai_stand();}; +void() f_stand11 =[ $swim11, f_stand12 ] {ai_stand();}; +void() f_stand12 =[ $swim12, f_stand13 ] {ai_stand();}; +void() f_stand13 =[ $swim13, f_stand14 ] {ai_stand();}; +void() f_stand14 =[ $swim14, f_stand15 ] {ai_stand();}; +void() f_stand15 =[ $swim15, f_stand16 ] {ai_stand();}; +void() f_stand16 =[ $swim16, f_stand17 ] {ai_stand();}; +void() f_stand17 =[ $swim17, f_stand18 ] {ai_stand();}; +void() f_stand18 =[ $swim18, f_stand1 ] {ai_stand();}; + +void() f_walk1 =[ $swim1, f_walk2 ] {ai_walk(8);}; +void() f_walk2 =[ $swim2, f_walk3 ] {ai_walk(8);}; +void() f_walk3 =[ $swim3, f_walk4 ] {ai_walk(8);}; +void() f_walk4 =[ $swim4, f_walk5 ] {ai_walk(8);}; +void() f_walk5 =[ $swim5, f_walk6 ] {ai_walk(8);}; +void() f_walk6 =[ $swim6, f_walk7 ] {ai_walk(8);}; +void() f_walk7 =[ $swim7, f_walk8 ] {ai_walk(8);}; +void() f_walk8 =[ $swim8, f_walk9 ] {ai_walk(8);}; +void() f_walk9 =[ $swim9, f_walk10 ] {ai_walk(8);}; +void() f_walk10 =[ $swim10, f_walk11 ] {ai_walk(8);}; +void() f_walk11 =[ $swim11, f_walk12 ] {ai_walk(8);}; +void() f_walk12 =[ $swim12, f_walk13 ] {ai_walk(8);}; +void() f_walk13 =[ $swim13, f_walk14 ] {ai_walk(8);}; +void() f_walk14 =[ $swim14, f_walk15 ] {ai_walk(8);}; +void() f_walk15 =[ $swim15, f_walk16 ] {ai_walk(8);}; +void() f_walk16 =[ $swim16, f_walk17 ] {ai_walk(8);}; +void() f_walk17 =[ $swim17, f_walk18 ] {ai_walk(8);}; +void() f_walk18 =[ $swim18, f_walk1 ] {ai_walk(8);}; + +void() f_run1 =[ $swim1, f_run2 ] {ai_run(12); + if (random() < 0.5) + sound (self, CHAN_VOICE, "fish/idle.wav", 1, ATTN_NORM); +}; +void() f_run2 =[ $swim3, f_run3 ] {ai_run(12);}; +void() f_run3 =[ $swim5, f_run4 ] {ai_run(12);}; +void() f_run4 =[ $swim7, f_run5 ] {ai_run(12);}; +void() f_run5 =[ $swim9, f_run6 ] {ai_run(12);}; +void() f_run6 =[ $swim11, f_run7 ] {ai_run(12);}; +void() f_run7 =[ $swim13, f_run8 ] {ai_run(12);}; +void() f_run8 =[ $swim15, f_run9 ] {ai_run(12);}; +void() f_run9 =[ $swim17, f_run1 ] {ai_run(12);}; + +void() fish_melee = +{ + local vector delta; + local float ldmg; + + if (!self.enemy) + return; // removed before stroke + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 60) + return; + + sound (self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM); + ldmg = (random() + random()) * 3; + T_Damage (self.enemy, self, self, ldmg, MOD_FISH); +}; + +void() f_attack1 =[ $attack1, f_attack2 ] {ai_charge(10);}; +void() f_attack2 =[ $attack2, f_attack3 ] {ai_charge(10);}; +void() f_attack3 =[ $attack3, f_attack4 ] {fish_melee();}; +void() f_attack4 =[ $attack4, f_attack5 ] {ai_charge(10);}; +void() f_attack5 =[ $attack5, f_attack6 ] {ai_charge(10);}; +void() f_attack6 =[ $attack6, f_attack7 ] {ai_charge(10);}; +void() f_attack7 =[ $attack7, f_attack8 ] {ai_charge(10);}; +void() f_attack8 =[ $attack8, f_attack9 ] {ai_charge(10);}; +void() f_attack9 =[ $attack9, f_attack10] {fish_melee();}; +void() f_attack10 =[ $attack10, f_attack11] {ai_charge(10);}; +void() f_attack11 =[ $attack11, f_attack12] {ai_charge(10);}; +void() f_attack12 =[ $attack12, f_attack13] {ai_charge(10);}; +void() f_attack13 =[ $attack13, f_attack14] {ai_charge(10);}; +void() f_attack14 =[ $attack14, f_attack15] {ai_charge(10);}; +void() f_attack15 =[ $attack15, f_attack16] {fish_melee();}; +void() f_attack16 =[ $attack16, f_attack17] {ai_charge(10);}; +void() f_attack17 =[ $attack17, f_attack18] {ai_charge(10);}; +void() f_attack18 =[ $attack18, f_run1 ] {ai_charge(10);}; + +void() f_death1 =[ $death1, f_death2 ] { +sound (self, CHAN_VOICE, "fish/death.wav", 1, ATTN_NORM); +}; +void() f_death2 =[ $death2, f_death3 ] {}; +void() f_death3 =[ $death3, f_death4 ] {self.solid = SOLID_NOT;}; +void() f_death4 =[ $death4, f_death5 ] {}; +void() f_death5 =[ $death5, f_death6 ] {}; +void() f_death6 =[ $death6, f_death7 ] {}; +void() f_death7 =[ $death7, f_death8 ] {}; +void() f_death8 =[ $death8, f_death9 ] {}; +void() f_death9 =[ $death9, f_death10 ] {}; +void() f_death10 =[ $death10, f_death11 ] {}; +void() f_death11 =[ $death11, f_death12 ] {}; +void() f_death12 =[ $death12, f_death13 ] {}; +void() f_death13 =[ $death13, f_death14 ] {}; +void() f_death14 =[ $death14, f_death15 ] {}; +void() f_death15 =[ $death15, f_death16 ] {}; +void() f_death16 =[ $death16, f_death17 ] {}; +void() f_death17 =[ $death17, f_death18 ] {}; +void() f_death18 =[ $death18, f_death19 ] {}; +void() f_death19 =[ $death19, f_death20 ] {}; +void() f_death20 =[ $death20, f_death21 ] {}; +void() f_death21 =[ $death21, f_death21 ] {}; + +void() f_pain1 =[ $pain1, f_pain2 ] {}; +void() f_pain2 =[ $pain2, f_pain3 ] {ai_pain(6);}; +void() f_pain3 =[ $pain3, f_pain4 ] {ai_pain(6);}; +void() f_pain4 =[ $pain4, f_pain5 ] {ai_pain(6);}; +void() f_pain5 =[ $pain5, f_pain6 ] {ai_pain(6);}; +void() f_pain6 =[ $pain6, f_pain7 ] {ai_pain(6);}; +void() f_pain7 =[ $pain7, f_pain8 ] {ai_pain(6);}; +void() f_pain8 =[ $pain8, f_pain9 ] {ai_pain(6);}; +void() f_pain9 =[ $pain9, f_run1 ] {ai_pain(6);}; + +void(entity attacker, float damage) fish_pain = +{ + +// fish allways do pain frames + f_pain1 (); +}; + + + +/*QUAKED monster_fish (1 0 0) (-16 -16 -24) (16 16 24) Ambush +*/ +void() monster_fish = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/fish.mdl"); + + precache_sound2 ("fish/death.wav"); + precache_sound2 ("fish/bite.wav"); + precache_sound2 ("fish/idle.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/fish.mdl"); + + setsize (self, '-16 -16 -24', '16 16 24'); + self.health = 25; + + self.th_stand = f_stand1; + self.th_walk = f_walk1; + self.th_run = f_run1; + self.th_die = f_death1; + self.th_pain = fish_pain; + self.th_melee = f_attack1; + + swimmonster_start (); +}; + diff --git a/r17/Revamped src/Revamped QC/quakemons/hknight.qc b/r17/Revamped src/Revamped QC/quakemons/hknight.qc new file mode 100755 index 00000000..84ae0295 --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/hknight.qc @@ -0,0 +1,442 @@ +/* +============================================================================== + +KNIGHT + +============================================================================== +*/ + +$cd id1/models/knight2 +$origin 0 0 24 +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 +$frame walk10 walk11 walk12 walk13 walk14 walk15 walk16 walk17 +$frame walk18 walk19 walk20 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 death11 death12 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 + +$frame char_a1 char_a2 char_a3 char_a4 char_a5 char_a6 char_a7 char_a8 +$frame char_a9 char_a10 char_a11 char_a12 char_a13 char_a14 char_a15 char_a16 + +$frame magica1 magica2 magica3 magica4 magica5 magica6 magica7 magica8 +$frame magica9 magica10 magica11 magica12 magica13 magica14 + +$frame magicb1 magicb2 magicb3 magicb4 magicb5 magicb6 magicb7 magicb8 +$frame magicb9 magicb10 magicb11 magicb12 magicb13 + +$frame char_b1 char_b2 char_b3 char_b4 char_b5 char_b6 + +$frame slice1 slice2 slice3 slice4 slice5 slice6 slice7 slice8 slice9 slice10 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 smash8 smash9 smash10 +$frame smash11 + +$frame w_attack1 w_attack2 w_attack3 w_attack4 w_attack5 w_attack6 w_attack7 +$frame w_attack8 w_attack9 w_attack10 w_attack11 w_attack12 w_attack13 w_attack14 +$frame w_attack15 w_attack16 w_attack17 w_attack18 w_attack19 w_attack20 +$frame w_attack21 w_attack22 + +$frame magicc1 magicc2 magicc3 magicc4 magicc5 magicc6 magicc7 magicc8 +$frame magicc9 magicc10 magicc11 + + +void() hknight_char_a1; +void() hknight_run1; +void() hk_idle_sound; + +void(float offset) hknight_shot = +{ + local vector offang; + local vector org, vec; + + offang = vectoangles (self.enemy.origin - self.origin); + offang_y = offang_y + offset * 6; + + makevectors (offang); + + org = self.origin + self.mins + self.size*0.5 + v_forward * 20; + +// set missile speed + vec = normalize (v_forward); + vec_z = 0 - vec_z + (random() - 0.5)*0.1; + + sound (self, CHAN_WEAPON, "hknight/attack1.wav", 1, ATTN_NORM); + PRJ_FireProjectile(self, "progs/k_spike.mdl", org, vec * 300, PE_KNIGHTSPIKE, 9, MOD_HKNIGHT, 6); +}; + +void() CheckForCharge = +{ + // check for mad charge + if (!visible(self.enemy)) + return; + if (time < self.attack_finished) + return; + if ( fabs(self.origin_z - self.enemy.origin_z) > 20) + return; // too much height change + if ( vlen (self.origin - self.enemy.origin) < 80) + return; // use regular attack + + // charge + SUB_AttackFinished (2); + hknight_char_a1 (); +}; + +void() CheckContinueCharge = +{ + if (time > self.attack_finished) + { + SUB_AttackFinished (3); + hknight_run1 (); + return; // done charging + } + if (random() > 0.5) + sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM); + else + sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +}; + +//=========================================================================== + +void() hknight_stand1 =[ $stand1, hknight_stand2 ] {ai_stand();}; +void() hknight_stand2 =[ $stand2, hknight_stand3 ] {ai_stand();}; +void() hknight_stand3 =[ $stand3, hknight_stand4 ] {ai_stand();}; +void() hknight_stand4 =[ $stand4, hknight_stand5 ] {ai_stand();}; +void() hknight_stand5 =[ $stand5, hknight_stand6 ] {ai_stand();}; +void() hknight_stand6 =[ $stand6, hknight_stand7 ] {ai_stand();}; +void() hknight_stand7 =[ $stand7, hknight_stand8 ] {ai_stand();}; +void() hknight_stand8 =[ $stand8, hknight_stand9 ] {ai_stand();}; +void() hknight_stand9 =[ $stand9, hknight_stand1 ] {ai_stand();}; + +//=========================================================================== + +void() hknight_walk1 =[ $walk1, hknight_walk2 ] { +hk_idle_sound(); +ai_walk(2);}; +void() hknight_walk2 =[ $walk2, hknight_walk3 ] {ai_walk(5);}; +void() hknight_walk3 =[ $walk3, hknight_walk4 ] {ai_walk(5);}; +void() hknight_walk4 =[ $walk4, hknight_walk5 ] {ai_walk(4);}; +void() hknight_walk5 =[ $walk5, hknight_walk6 ] {ai_walk(4);}; +void() hknight_walk6 =[ $walk6, hknight_walk7 ] {ai_walk(2);}; +void() hknight_walk7 =[ $walk7, hknight_walk8 ] {ai_walk(2);}; +void() hknight_walk8 =[ $walk8, hknight_walk9 ] {ai_walk(3);}; +void() hknight_walk9 =[ $walk9, hknight_walk10 ] {ai_walk(3);}; +void() hknight_walk10 =[ $walk10, hknight_walk11 ] {ai_walk(4);}; +void() hknight_walk11 =[ $walk11, hknight_walk12 ] {ai_walk(3);}; +void() hknight_walk12 =[ $walk12, hknight_walk13 ] {ai_walk(4);}; +void() hknight_walk13 =[ $walk13, hknight_walk14 ] {ai_walk(6);}; +void() hknight_walk14 =[ $walk14, hknight_walk15 ] {ai_walk(2);}; +void() hknight_walk15 =[ $walk15, hknight_walk16 ] {ai_walk(2);}; +void() hknight_walk16 =[ $walk16, hknight_walk17 ] {ai_walk(4);}; +void() hknight_walk17 =[ $walk17, hknight_walk18 ] {ai_walk(3);}; +void() hknight_walk18 =[ $walk18, hknight_walk19 ] {ai_walk(3);}; +void() hknight_walk19 =[ $walk19, hknight_walk20 ] {ai_walk(3);}; +void() hknight_walk20 =[ $walk20, hknight_walk1 ] {ai_walk(2);}; + +//=========================================================================== + +void() hknight_run1 =[ $run1, hknight_run2 ] { +hk_idle_sound(); +ai_run (20); CheckForCharge (); }; +void() hknight_run2 =[ $run2, hknight_run3 ] {ai_run(25);}; +void() hknight_run3 =[ $run3, hknight_run4 ] {ai_run(18);}; +void() hknight_run4 =[ $run4, hknight_run5 ] {ai_run(16);}; +void() hknight_run5 =[ $run5, hknight_run6 ] {ai_run(14);}; +void() hknight_run6 =[ $run6, hknight_run7 ] {ai_run(25);}; +void() hknight_run7 =[ $run7, hknight_run8 ] {ai_run(21);}; +void() hknight_run8 =[ $run8, hknight_run1 ] {ai_run(13);}; + +//============================================================================ + +void() hknight_pain1 =[ $pain1, hknight_pain2 ] {sound (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);}; +void() hknight_pain2 =[ $pain2, hknight_pain3 ] {}; +void() hknight_pain3 =[ $pain3, hknight_pain4 ] {}; +void() hknight_pain4 =[ $pain4, hknight_pain5 ] {}; +void() hknight_pain5 =[ $pain5, hknight_run1 ] {}; + +//============================================================================ + +void() hknight_die1 =[ $death1, hknight_die2 ] {ai_forward(10);}; +void() hknight_die2 =[ $death2, hknight_die3 ] {ai_forward(8);}; +void() hknight_die3 =[ $death3, hknight_die4 ] +{self.solid = SOLID_NOT; ai_forward(7);}; +void() hknight_die4 =[ $death4, hknight_die5 ] {}; +void() hknight_die5 =[ $death5, hknight_die6 ] {}; +void() hknight_die6 =[ $death6, hknight_die7 ] {}; +void() hknight_die7 =[ $death7, hknight_die8 ] {}; +void() hknight_die8 =[ $death8, hknight_die9 ] {ai_forward(10);}; +void() hknight_die9 =[ $death9, hknight_die10 ] {ai_forward(11);}; +void() hknight_die10 =[ $death10, hknight_die11 ] {}; +void() hknight_die11 =[ $death11, hknight_die12 ] {}; +void() hknight_die12 =[ $death12, hknight_die12 ] {}; + +void() hknight_dieb1 =[ $deathb1, hknight_dieb2 ] {}; +void() hknight_dieb2 =[ $deathb2, hknight_dieb3 ] {}; +void() hknight_dieb3 =[ $deathb3, hknight_dieb4 ] +{self.solid = SOLID_NOT;}; +void() hknight_dieb4 =[ $deathb4, hknight_dieb5 ] {}; +void() hknight_dieb5 =[ $deathb5, hknight_dieb6 ] {}; +void() hknight_dieb6 =[ $deathb6, hknight_dieb7 ] {}; +void() hknight_dieb7 =[ $deathb7, hknight_dieb8 ] {}; +void() hknight_dieb8 =[ $deathb8, hknight_dieb9 ] {}; +void() hknight_dieb9 =[ $deathb9, hknight_dieb9 ] {}; + +void() hknight_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_hellkn.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "hknight/death1.wav", 1, ATTN_NORM); + if (random() > 0.5) + hknight_die1 (); + else + hknight_dieb1 (); +}; + + +//============================================================================ +#ifdef 0 +// Not used +void() hknight_magica1 =[ $magica1, hknight_magica2 ] {ai_face();}; +void() hknight_magica2 =[ $magica2, hknight_magica3 ] {ai_face();}; +void() hknight_magica3 =[ $magica3, hknight_magica4 ] {ai_face();}; +void() hknight_magica4 =[ $magica4, hknight_magica5 ] {ai_face();}; +void() hknight_magica5 =[ $magica5, hknight_magica6 ] {ai_face();}; +void() hknight_magica6 =[ $magica6, hknight_magica7 ] {ai_face();}; +void() hknight_magica7 =[ $magica7, hknight_magica8 ] {hknight_shot(-2);}; +void() hknight_magica8 =[ $magica8, hknight_magica9 ] {hknight_shot(-1);}; +void() hknight_magica9 =[ $magica9, hknight_magica10] {hknight_shot(0);}; +void() hknight_magica10 =[ $magica10, hknight_magica11] {hknight_shot(1);}; +void() hknight_magica11 =[ $magica11, hknight_magica12] {hknight_shot(2);}; +void() hknight_magica12 =[ $magica12, hknight_magica13] {hknight_shot(3);}; +void() hknight_magica13 =[ $magica13, hknight_magica14] {ai_face();}; +void() hknight_magica14 =[ $magica14, hknight_run1 ] {ai_face();}; + +//============================================================================ + +void() hknight_magicb1 =[ $magicb1, hknight_magicb2 ] {ai_face();}; +void() hknight_magicb2 =[ $magicb2, hknight_magicb3 ] {ai_face();}; +void() hknight_magicb3 =[ $magicb3, hknight_magicb4 ] {ai_face();}; +void() hknight_magicb4 =[ $magicb4, hknight_magicb5 ] {ai_face();}; +void() hknight_magicb5 =[ $magicb5, hknight_magicb6 ] {ai_face();}; +void() hknight_magicb6 =[ $magicb6, hknight_magicb7 ] {ai_face();}; +void() hknight_magicb7 =[ $magicb7, hknight_magicb8 ] {hknight_shot(-2);}; +void() hknight_magicb8 =[ $magicb8, hknight_magicb9 ] {hknight_shot(-1);}; +void() hknight_magicb9 =[ $magicb9, hknight_magicb10] {hknight_shot(0);}; +void() hknight_magicb10 =[ $magicb10, hknight_magicb11] {hknight_shot(1);}; +void() hknight_magicb11 =[ $magicb11, hknight_magicb12] {hknight_shot(2);}; +void() hknight_magicb12 =[ $magicb12, hknight_magicb13] {hknight_shot(3);}; +void() hknight_magicb13 =[ $magicb13, hknight_run1] {ai_face();}; +#endif + +//============================================================================ + +void() hknight_magicc1 =[ $magicc1, hknight_magicc2 ] {ai_face();}; +void() hknight_magicc2 =[ $magicc2, hknight_magicc3 ] {ai_face();}; +void() hknight_magicc3 =[ $magicc3, hknight_magicc4 ] {ai_face();}; +void() hknight_magicc4 =[ $magicc4, hknight_magicc5 ] {ai_face();}; +void() hknight_magicc5 =[ $magicc5, hknight_magicc6 ] {ai_face();}; +void() hknight_magicc6 =[ $magicc6, hknight_magicc7 ] {hknight_shot(-2);}; +void() hknight_magicc7 =[ $magicc7, hknight_magicc8 ] {hknight_shot(-1);}; +void() hknight_magicc8 =[ $magicc8, hknight_magicc9 ] {hknight_shot(0);}; +void() hknight_magicc9 =[ $magicc9, hknight_magicc10] {hknight_shot(1);}; +void() hknight_magicc10 =[ $magicc10, hknight_magicc11] {hknight_shot(2);}; +void() hknight_magicc11 =[ $magicc11, hknight_run1] {hknight_shot(3);}; + +//=========================================================================== + +void() hknight_char_a1 =[ $char_a1, hknight_char_a2 ] {ai_charge(20);}; +void() hknight_char_a2 =[ $char_a2, hknight_char_a3 ] {ai_charge(25);}; +void() hknight_char_a3 =[ $char_a3, hknight_char_a4 ] {ai_charge(18);}; +void() hknight_char_a4 =[ $char_a4, hknight_char_a5 ] {ai_charge(16);}; +void() hknight_char_a5 =[ $char_a5, hknight_char_a6 ] {ai_charge(14);}; +void() hknight_char_a6 =[ $char_a6, hknight_char_a7 ] {ai_charge(20); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_a7 =[ $char_a7, hknight_char_a8 ] {ai_charge(21); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_a8 =[ $char_a8, hknight_char_a9 ] {ai_charge(13); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_a9 =[ $char_a9, hknight_char_a10 ] {ai_charge(20); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_a10=[ $char_a10, hknight_char_a11 ] {ai_charge(20); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_a11=[ $char_a11, hknight_char_a12 ] {ai_charge(18); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_a12=[ $char_a12, hknight_char_a13 ] {ai_charge(16);}; +void() hknight_char_a13=[ $char_a13, hknight_char_a14 ] {ai_charge(14);}; +void() hknight_char_a14=[ $char_a14, hknight_char_a15 ] {ai_charge(25);}; +void() hknight_char_a15=[ $char_a15, hknight_char_a16 ] {ai_charge(21);}; +void() hknight_char_a16=[ $char_a16, hknight_run1 ] {ai_charge(13);}; + +//=========================================================================== + +#ifdef 0 +// Not used +void() hknight_char_b1 =[ $char_b1, hknight_char_b2 ] +{CheckContinueCharge (); ai_charge(23); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_b2 =[ $char_b2, hknight_char_b3 ] {ai_charge(17); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_b3 =[ $char_b3, hknight_char_b4 ] {ai_charge(12); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_b4 =[ $char_b4, hknight_char_b5 ] {ai_charge(22); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_b5 =[ $char_b5, hknight_char_b6 ] {ai_charge(18); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_b6 =[ $char_b6, hknight_char_b1 ] {ai_charge(8); ai_melee(MOD_HKNIGHT);}; +#endif + +//=========================================================================== + +void() hknight_slice1 =[ $slice1, hknight_slice2 ] {ai_charge(9);}; +void() hknight_slice2 =[ $slice2, hknight_slice3 ] {ai_charge(6);}; +void() hknight_slice3 =[ $slice3, hknight_slice4 ] {ai_charge(13);}; +void() hknight_slice4 =[ $slice4, hknight_slice5 ] {ai_charge(4);}; +void() hknight_slice5 =[ $slice5, hknight_slice6 ] {ai_charge(7); ai_melee(MOD_HKNIGHT);}; +void() hknight_slice6 =[ $slice6, hknight_slice7 ] {ai_charge(15); ai_melee(MOD_HKNIGHT);}; +void() hknight_slice7 =[ $slice7, hknight_slice8 ] {ai_charge(8); ai_melee(MOD_HKNIGHT);}; +void() hknight_slice8 =[ $slice8, hknight_slice9 ] {ai_charge(2); ai_melee(MOD_HKNIGHT);}; +void() hknight_slice9 =[ $slice9, hknight_slice10 ] {ai_melee(MOD_HKNIGHT);}; +void() hknight_slice10 =[ $slice10, hknight_run1 ] {ai_charge(3);}; + +//=========================================================================== + +void() hknight_smash1 =[ $smash1, hknight_smash2 ] {ai_charge(1);}; +void() hknight_smash2 =[ $smash2, hknight_smash3 ] {ai_charge(13);}; +void() hknight_smash3 =[ $smash3, hknight_smash4 ] {ai_charge(9);}; +void() hknight_smash4 =[ $smash4, hknight_smash5 ] {ai_charge(11);}; +void() hknight_smash5 =[ $smash5, hknight_smash6 ] {ai_charge(10); ai_melee(MOD_HKNIGHT);}; +void() hknight_smash6 =[ $smash6, hknight_smash7 ] {ai_charge(7); ai_melee(MOD_HKNIGHT);}; +void() hknight_smash7 =[ $smash7, hknight_smash8 ] {ai_charge(12); ai_melee(MOD_HKNIGHT);}; +void() hknight_smash8 =[ $smash8, hknight_smash9 ] {ai_charge(2); ai_melee(MOD_HKNIGHT);}; +void() hknight_smash9 =[ $smash9, hknight_smash10 ] {ai_charge(3); ai_melee(MOD_HKNIGHT);}; +void() hknight_smash10 =[ $smash10, hknight_smash11 ] {ai_charge(0);}; +void() hknight_smash11 =[ $smash11, hknight_run1 ] {ai_charge(0);}; + +//============================================================================ + +void() hknight_watk1 =[ $w_attack1, hknight_watk2 ] {ai_charge(2);}; +void() hknight_watk2 =[ $w_attack2, hknight_watk3 ] {ai_charge(0);}; +void() hknight_watk3 =[ $w_attack3, hknight_watk4 ] {ai_charge(0);}; +void() hknight_watk4 =[ $w_attack4, hknight_watk5 ] {ai_melee(MOD_HKNIGHT);}; +void() hknight_watk5 =[ $w_attack5, hknight_watk6 ] {ai_melee(MOD_HKNIGHT);}; +void() hknight_watk6 =[ $w_attack6, hknight_watk7 ] {ai_melee(MOD_HKNIGHT);}; +void() hknight_watk7 =[ $w_attack7, hknight_watk8 ] {ai_charge(1);}; +void() hknight_watk8 =[ $w_attack8, hknight_watk9 ] {ai_charge(4);}; +void() hknight_watk9 =[ $w_attack9, hknight_watk10 ] {ai_charge(5);}; +void() hknight_watk10 =[ $w_attack10, hknight_watk11 ] {ai_charge(3); ai_melee(MOD_HKNIGHT);}; +void() hknight_watk11 =[ $w_attack11, hknight_watk12 ] {ai_charge(2); ai_melee(MOD_HKNIGHT);}; +void() hknight_watk12 =[ $w_attack12, hknight_watk13 ] {ai_charge(2); ai_melee(MOD_HKNIGHT);}; +void() hknight_watk13 =[ $w_attack13, hknight_watk14 ] {ai_charge(0);}; +void() hknight_watk14 =[ $w_attack14, hknight_watk15 ] {ai_charge(0);}; +void() hknight_watk15 =[ $w_attack15, hknight_watk16 ] {ai_charge(0);}; +void() hknight_watk16 =[ $w_attack16, hknight_watk17 ] {ai_charge(1);}; +void() hknight_watk17 =[ $w_attack17, hknight_watk18 ] {ai_charge(1); ai_melee(MOD_HKNIGHT);}; +void() hknight_watk18 =[ $w_attack18, hknight_watk19 ] {ai_charge(3); ai_melee(MOD_HKNIGHT);}; +void() hknight_watk19 =[ $w_attack19, hknight_watk20 ] {ai_charge(4); ai_melee(MOD_HKNIGHT);}; +void() hknight_watk20 =[ $w_attack20, hknight_watk21 ] {ai_charge(6);}; +void() hknight_watk21 =[ $w_attack21, hknight_watk22 ] {ai_charge(7);}; +void() hknight_watk22 =[ $w_attack22, hknight_run1 ] {ai_charge(3);}; + +//============================================================================ + +void() hk_idle_sound = +{ + if (random() < 0.2) + sound (self, CHAN_VOICE, "hknight/idle.wav", 1, ATTN_NORM); +}; + +void(entity attacker, float damage) hknight_pain = +{ + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM); + + if (time - self.pain_finished > 5) + { // allways go into pain frame if it has been a while + hknight_pain1 (); + self.pain_finished = time + 1; + return; + } + + if ((random()*30 > damage) ) + return; // didn't flinch + + self.pain_finished = time + 1; + hknight_pain1 (); +}; + +void() hknight_melee = +{ + self.hknightattack += 1; + + sound (self, CHAN_WEAPON, "hknight/slash1.wav", 1, ATTN_NORM); + switch (self.hknightattack) + { + case 1: + hknight_slice1 (); + break; + case 2: + hknight_smash1 (); + break; + default: + hknight_watk1 (); + self.hknightattack = 0; + } +}; + +/*QUAKED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_hell_knight = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/hknight.mdl"); + precache_model2 ("progs/k_spike.mdl"); + precache_model2 ("progs/h_hellkn.mdl"); + + precache_sound2 ("hknight/attack1.wav"); + precache_sound2 ("hknight/death1.wav"); + precache_sound2 ("hknight/pain1.wav"); + precache_sound2 ("hknight/sight1.wav"); + precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2 + precache_sound2 ("hknight/slash1.wav"); + precache_sound2 ("hknight/idle.wav"); + precache_sound2 ("hknight/grunt.wav"); + + precache_sound ("knight/sword1.wav"); + precache_sound ("knight/sword2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/hknight.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 250; + + self.th_stand = hknight_stand1; + self.th_walk = hknight_walk1; + self.th_run = hknight_run1; + self.th_melee = hknight_melee; + self.th_missile = hknight_magicc1; + self.th_pain = hknight_pain; + self.th_die = hknight_die; + + self.hknightattack = floor(random() * 2.99); + + walkmonster_start (); +}; diff --git a/r17/Revamped src/Revamped QC/quakemons/knight.qc b/r17/Revamped src/Revamped QC/quakemons/knight.qc new file mode 100755 index 00000000..257b35bf --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/knight.qc @@ -0,0 +1,278 @@ +/* +============================================================================== + +KNIGHT + +============================================================================== +*/ + +$cd id1/models/knight +$origin 0 0 24 +$base base +$skin badass3 + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame runb1 runb2 runb3 runb4 runb5 runb6 runb7 runb8 + +//frame runc1 runc2 runc3 runc4 runc5 runc6 + +$frame runattack1 runattack2 runattack3 runattack4 runattack5 +$frame runattack6 runattack7 runattack8 runattack9 runattack10 +$frame runattack11 + +$frame pain1 pain2 pain3 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 +$frame painb10 painb11 + +//frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 +//frame attack8 attack9 attack10 attack11 + +$frame attackb0 attackb1 attackb2 attackb3 attackb4 attackb5 +$frame attackb6 attackb7 attackb8 attackb9 attackb10 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 +$frame walk10 walk11 walk12 walk13 walk14 + +$frame kneel1 kneel2 kneel3 kneel4 kneel5 + +$frame standing2 standing3 standing4 standing5 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 deathb10 deathb11 + +void() knight_stand1 =[ $stand1, knight_stand2 ] {ai_stand();}; +void() knight_stand2 =[ $stand2, knight_stand3 ] {ai_stand();}; +void() knight_stand3 =[ $stand3, knight_stand4 ] {ai_stand();}; +void() knight_stand4 =[ $stand4, knight_stand5 ] {ai_stand();}; +void() knight_stand5 =[ $stand5, knight_stand6 ] {ai_stand();}; +void() knight_stand6 =[ $stand6, knight_stand7 ] {ai_stand();}; +void() knight_stand7 =[ $stand7, knight_stand8 ] {ai_stand();}; +void() knight_stand8 =[ $stand8, knight_stand9 ] {ai_stand();}; +void() knight_stand9 =[ $stand9, knight_stand1 ] {ai_stand();}; + +void() knight_walk1 =[ $walk1, knight_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE); +ai_walk(3);}; +void() knight_walk2 =[ $walk2, knight_walk3 ] {ai_walk(2);}; +void() knight_walk3 =[ $walk3, knight_walk4 ] {ai_walk(3);}; +void() knight_walk4 =[ $walk4, knight_walk5 ] {ai_walk(4);}; +void() knight_walk5 =[ $walk5, knight_walk6 ] {ai_walk(3);}; +void() knight_walk6 =[ $walk6, knight_walk7 ] {ai_walk(3);}; +void() knight_walk7 =[ $walk7, knight_walk8 ] {ai_walk(3);}; +void() knight_walk8 =[ $walk8, knight_walk9 ] {ai_walk(4);}; +void() knight_walk9 =[ $walk9, knight_walk10 ] {ai_walk(3);}; +void() knight_walk10 =[ $walk10, knight_walk11 ] {ai_walk(3);}; +void() knight_walk11 =[ $walk11, knight_walk12 ] {ai_walk(2);}; +void() knight_walk12 =[ $walk12, knight_walk13 ] {ai_walk(3);}; +void() knight_walk13 =[ $walk13, knight_walk14 ] {ai_walk(4);}; +void() knight_walk14 =[ $walk14, knight_walk1 ] {ai_walk(3);}; + + +void() knight_run1 =[ $runb1, knight_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE); +ai_run(16);}; +void() knight_run2 =[ $runb2, knight_run3 ] {ai_run(20);}; +void() knight_run3 =[ $runb3, knight_run4 ] {ai_run(13);}; +void() knight_run4 =[ $runb4, knight_run5 ] {ai_run(7);}; +void() knight_run5 =[ $runb5, knight_run6 ] {ai_run(16);}; +void() knight_run6 =[ $runb6, knight_run7 ] {ai_run(20);}; +void() knight_run7 =[ $runb7, knight_run8 ] {ai_run(14);}; +void() knight_run8 =[ $runb8, knight_run1 ] {ai_run(6);}; + + +void() knight_runatk1 =[ $runattack1, knight_runatk2 ] +{ +if (random() > 0.5) + sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM); +else + sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +ai_charge(20); +}; +void() knight_runatk2 =[ $runattack2, knight_runatk3 ] {ai_charge_side();}; +void() knight_runatk3 =[ $runattack3, knight_runatk4 ] {ai_charge_side();}; +void() knight_runatk4 =[ $runattack4, knight_runatk5 ] {ai_charge_side();}; +void() knight_runatk5 =[ $runattack5, knight_runatk6 ] {ai_melee_side(MOD_KNIGHT);}; +void() knight_runatk6 =[ $runattack6, knight_runatk7 ] {ai_melee_side(MOD_KNIGHT);}; +void() knight_runatk7 =[ $runattack7, knight_runatk8 ] {ai_melee_side(MOD_KNIGHT);}; +void() knight_runatk8 =[ $runattack8, knight_runatk9 ] {ai_melee_side(MOD_KNIGHT);}; +void() knight_runatk9 =[ $runattack9, knight_runatk10 ] {ai_melee_side(MOD_KNIGHT);}; +void() knight_runatk10 =[ $runattack10, knight_runatk11 ] {ai_charge_side();}; +void() knight_runatk11 =[ $runattack11, knight_run1 ] {ai_charge(10);}; + +void() knight_atk1 =[ $attackb1, knight_atk2 ] +{ +sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +ai_charge(0);}; +void() knight_atk2 =[ $attackb2, knight_atk3 ] {ai_charge(7);}; +void() knight_atk3 =[ $attackb3, knight_atk4 ] {ai_charge(4);}; +void() knight_atk4 =[ $attackb4, knight_atk5 ] {ai_charge(0);}; +void() knight_atk5 =[ $attackb5, knight_atk6 ] {ai_charge(3);}; +void() knight_atk6 =[ $attackb6, knight_atk7 ] {ai_charge(4); ai_melee(MOD_KNIGHT);}; +void() knight_atk7 =[ $attackb7, knight_atk8 ] {ai_charge(1); ai_melee(MOD_KNIGHT);}; +void() knight_atk8 =[ $attackb8, knight_atk9 ] {ai_charge(3); ai_melee(MOD_KNIGHT);}; +void() knight_atk9 =[ $attackb9, knight_atk10] {ai_charge(1);}; +void() knight_atk10=[ $attackb10, knight_run1 ] {ai_charge(5);}; + +//void() knight_atk9 =[ $attack9, knight_atk10 ] {}; +//void() knight_atk10 =[ $attack10, knight_atk11 ] {}; +//void() knight_atk11 =[ $attack11, knight_run1 ] {}; + +//=========================================================================== + +void() knight_pain1 =[ $pain1, knight_pain2 ] {}; +void() knight_pain2 =[ $pain2, knight_pain3 ] {}; +void() knight_pain3 =[ $pain3, knight_run1 ] {}; + +void() knight_painb1 =[ $painb1, knight_painb2 ] {ai_painforward(0);}; +void() knight_painb2 =[ $painb2, knight_painb3 ] {ai_painforward(3);}; +void() knight_painb3 =[ $painb3, knight_painb4 ] {}; +void() knight_painb4 =[ $painb4, knight_painb5 ] {}; +void() knight_painb5 =[ $painb5, knight_painb6 ] {ai_painforward(2);}; +void() knight_painb6 =[ $painb6, knight_painb7 ] {ai_painforward(4);}; +void() knight_painb7 =[ $painb7, knight_painb8 ] {ai_painforward(2);}; +void() knight_painb8 =[ $painb8, knight_painb9 ] {ai_painforward(5);}; +void() knight_painb9 =[ $painb9, knight_painb10 ] {ai_painforward(5);}; +void() knight_painb10 =[ $painb10, knight_painb11 ] {ai_painforward(0);}; +void() knight_painb11 =[ $painb11, knight_run1 ] {}; + +void(entity attacker, float damage) knight_pain = +{ + local float r; + + if (self.pain_finished > time) + return; + + r = random(); + + sound (self, CHAN_VOICE, "knight/khurt.wav", 1, ATTN_NORM); + self.pain_finished = time + 1; + + if (r < 0.85) + knight_pain1 (); + else + knight_painb1 (); + +}; + +//=========================================================================== + +#ifdef 0 +// Not used +void() knight_bow1 =[ $kneel1, knight_bow2 ] {ai_turn();}; +void() knight_bow2 =[ $kneel2, knight_bow3 ] {ai_turn();}; +void() knight_bow3 =[ $kneel3, knight_bow4 ] {ai_turn();}; +void() knight_bow4 =[ $kneel4, knight_bow5 ] {ai_turn();}; + +void() knight_bow5 =[ $kneel5, knight_bow5 ] {ai_turn();}; + +void() knight_bow6 =[ $kneel4, knight_bow7 ] {ai_turn();}; +void() knight_bow7 =[ $kneel3, knight_bow8 ] {ai_turn();}; +void() knight_bow8 =[ $kneel2, knight_bow9 ] {ai_turn();}; +void() knight_bow9 =[ $kneel1, knight_bow10 ] {ai_turn();}; +void() knight_bow10 =[ $walk1, knight_walk1 ] {ai_turn();}; +#endif + +void() knight_die1 =[ $death1, knight_die2 ] {}; +void() knight_die2 =[ $death2, knight_die3 ] {}; +void() knight_die3 =[ $death3, knight_die4 ] +{self.solid = SOLID_NOT;}; +void() knight_die4 =[ $death4, knight_die5 ] {}; +void() knight_die5 =[ $death5, knight_die6 ] {}; +void() knight_die6 =[ $death6, knight_die7 ] {}; +void() knight_die7 =[ $death7, knight_die8 ] {}; +void() knight_die8 =[ $death8, knight_die9 ] {}; +void() knight_die9 =[ $death9, knight_die10] {}; +void() knight_die10=[ $death10, knight_die10] {}; + + +void() knight_dieb1 =[ $deathb1, knight_dieb2 ] {}; +void() knight_dieb2 =[ $deathb2, knight_dieb3 ] {}; +void() knight_dieb3 =[ $deathb3, knight_dieb4 ] +{self.solid = SOLID_NOT;}; +void() knight_dieb4 =[ $deathb4, knight_dieb5 ] {}; +void() knight_dieb5 =[ $deathb5, knight_dieb6 ] {}; +void() knight_dieb6 =[ $deathb6, knight_dieb7 ] {}; +void() knight_dieb7 =[ $deathb7, knight_dieb8 ] {}; +void() knight_dieb8 =[ $deathb8, knight_dieb9 ] {}; +void() knight_dieb9 =[ $deathb9, knight_dieb10] {}; +void() knight_dieb10 = [ $deathb10, knight_dieb11] {}; +void() knight_dieb11 = [ $deathb11, knight_dieb11] {}; + + +void() knight_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_knight.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "knight/kdeath.wav", 1, ATTN_NORM); + if (random() < 0.5) + knight_die1 (); + else + knight_dieb1 (); +}; + +void() knight_attack = +{ + local float len; + +// decide if now is a good swing time + len = vlen(self.enemy.origin+self.enemy.view_ofs - (self.origin+self.view_ofs)); + + if (len<80) + knight_atk1 (); + else + knight_runatk1 (); +}; + +/*QUAKED monster_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_knight = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/knight.mdl"); + precache_model ("progs/h_knight.mdl"); + + precache_sound ("knight/kdeath.wav"); + precache_sound ("knight/khurt.wav"); + precache_sound ("knight/ksight.wav"); + precache_sound ("knight/sword1.wav"); + precache_sound ("knight/sword2.wav"); + precache_sound ("knight/idle.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/knight.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 75; + + self.th_stand = knight_stand1; + self.th_walk = knight_walk1; + self.th_run = knight_run1; + self.th_melee = knight_attack; + self.th_pain = knight_pain; + self.th_die = knight_die; + + walkmonster_start (); +}; diff --git a/r17/Revamped src/Revamped QC/quakemons/ogre.qc b/r17/Revamped src/Revamped QC/quakemons/ogre.qc new file mode 100755 index 00000000..441a4845 --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/ogre.qc @@ -0,0 +1,397 @@ +/* +============================================================================== + +OGRE + +============================================================================== +*/ + +$cd id1/models/ogre_c +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 +$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7 +$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 +$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14 + +$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame painb1 painb2 painb3 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10 +$frame paind11 paind12 paind13 paind14 paind15 paind16 + +$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10 +$frame paine11 paine12 paine13 paine14 paine15 + +$frame death1 death2 death3 death4 death5 death6 +$frame death7 death8 death9 death10 death11 death12 +$frame death13 death14 + +$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6 +$frame bdeath7 bdeath8 bdeath9 bdeath10 + +$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11 + +//============================================================================= + + +void() ogre_fire = +{ + local vector dir; + local entity en; + + ai_face(); + + sound (self, CHAN_WEAPON, "weapons/ppist.wav", 1, ATTN_NORM); + +// fire somewhat behind the player, so a dodging player is harder to hit + en = self.enemy; + + dir = en.origin - en.velocity*0.2; + dir = normalize (dir - self.origin); + + FireBullets (1, dir, '0.1 0.1 0', MOD_OGRE); +}; +//============================================================================= + +void() laugh = +{ +local float r; +r = random(); +if (r <= 0.5) +sound (self, CHAN_AUTO, "ogre/laugh1.wav", 1, ATTN_NORM); +else if ( r <= 0.10) +sound (self, CHAN_AUTO, "ogre/laugh2.wav", 1, ATTN_NORM); +else +{} +}; +/* +================ +chainsaw + +FIXME +================ +*/ +void(float side) chainsaw = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + if (!CanDamage (self.enemy, self)) + return; + + ai_charge(10); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + ldmg = (random() + random() + random()) * 25; + T_Damage (self.enemy, self, self, ldmg, MOD_OGRE); +}; + + +void() ogre_stand1 =[ $stand1, ogre_stand2 ] {ai_stand();}; +void() ogre_stand2 =[ $stand2, ogre_stand3 ] {ai_stand();}; +void() ogre_stand3 =[ $stand3, ogre_stand4 ] {ai_stand(); laugh();}; +void() ogre_stand4 =[ $stand4, ogre_stand5 ] {ai_stand();}; +void() ogre_stand5 =[ $stand5, ogre_stand6 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE); +ai_stand(); +}; +void() ogre_stand6 =[ $stand6, ogre_stand7 ] {ai_stand();}; +void() ogre_stand7 =[ $stand7, ogre_stand8 ] {ai_stand();}; +void() ogre_stand8 =[ $stand8, ogre_stand9 ] {ai_stand();}; +void() ogre_stand9 =[ $stand9, ogre_stand1 ] {ai_stand();}; + +void() ogre_walk1 =[ $walk1, ogre_walk2 ] {ai_walk(3);}; +void() ogre_walk2 =[ $walk2, ogre_walk3 ] {ai_walk(2);}; +void() ogre_walk3 =[ $walk3, ogre_walk4 ] { +ai_walk(2); +if (random() < 0.2) + sound (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE); +}; +void() ogre_walk4 =[ $walk4, ogre_walk5 ] {ai_walk(2);}; +void() ogre_walk5 =[ $walk5, ogre_walk6 ] {ai_walk(2);}; +void() ogre_walk6 =[ $walk6, ogre_walk7 ] { +ai_walk(5); +if (random() < 0.1) + sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE); +}; +void() ogre_walk7 =[ $walk7, ogre_walk8 ] {ai_walk(3);}; +void() ogre_walk8 =[ $walk8, ogre_walk9 ] {ai_walk(2);}; +void() ogre_walk9 =[ $walk9, ogre_walk10 ] {ai_walk(3);}; +void() ogre_walk10 =[ $walk10, ogre_walk11 ] {ai_walk(1);}; +void() ogre_walk11 =[ $walk11, ogre_walk12 ] {ai_walk(2);}; +void() ogre_walk12 =[ $walk12, ogre_walk13 ] {ai_walk(3);}; +void() ogre_walk13 =[ $walk13, ogre_walk14 ] {ai_walk(3);}; +void() ogre_walk14 =[ $walk14, ogre_walk15 ] {ai_walk(3);}; +void() ogre_walk15 =[ $walk15, ogre_walk16 ] {ai_walk(3);}; +void() ogre_walk16 =[ $walk16, ogre_walk1 ] {ai_walk(4);}; + +void() ogre_run1 =[ $run1, ogre_run2 ] {ai_run(9); +if (random() < 0.2) + sound (self, CHAN_VOICE, "ogre/ogidle2.wav", 1, ATTN_IDLE); +}; +void() ogre_run2 =[ $run2, ogre_run3 ] {ai_run(12);}; +void() ogre_run3 =[ $run3, ogre_run4 ] {ai_run(8);}; +void() ogre_run4 =[ $run4, ogre_run5 ] {ai_run(22);}; +void() ogre_run5 =[ $run5, ogre_run6 ] {ai_run(16);}; +void() ogre_run6 =[ $run6, ogre_run7 ] {ai_run(4);}; +void() ogre_run7 =[ $run7, ogre_run8 ] {ai_run(13);}; +void() ogre_run8 =[ $run8, ogre_run1 ] {ai_run(24);}; + +void() ogre_swing1 =[ $swing1, ogre_swing2 ] {ai_charge(11); +sound (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM); +}; +void() ogre_swing2 =[ $swing2, ogre_swing3 ] {ai_charge(1);}; +void() ogre_swing3 =[ $swing3, ogre_swing4 ] {ai_charge(4);}; +void() ogre_swing4 =[ $swing4, ogre_swing5 ] {ai_charge(13);}; +void() ogre_swing5 =[ $swing5, ogre_swing6 ] {ai_charge(9); chainsaw(0);self.angles_y = self.angles_y + random()*25;}; +void() ogre_swing6 =[ $swing6, ogre_swing7 ] {chainsaw(200);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing7 =[ $swing7, ogre_swing8 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing8 =[ $swing8, ogre_swing9 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing9 =[ $swing9, ogre_swing10 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing10 =[ $swing10, ogre_swing11 ] {chainsaw(-200);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing11 =[ $swing11, ogre_swing12 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing12 =[ $swing12, ogre_swing13 ] {ai_charge(3);}; +void() ogre_swing13 =[ $swing13, ogre_swing14 ] {ai_charge(8);}; +void() ogre_swing14 =[ $swing14, ogre_run1 ] {ai_charge(9);}; + +void() ogre_smash1 =[ $smash1, ogre_smash2 ] {ai_charge(6); +sound (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM); +}; +void() ogre_smash2 =[ $smash2, ogre_smash3 ] {ai_charge(0);}; +void() ogre_smash3 =[ $smash3, ogre_smash4 ] {ai_charge(0);}; +void() ogre_smash4 =[ $smash4, ogre_smash5 ] {ai_charge(1);}; +void() ogre_smash5 =[ $smash5, ogre_smash6 ] {ai_charge(4);}; +void() ogre_smash6 =[ $smash6, ogre_smash7 ] {ai_charge(4); chainsaw(0);}; +void() ogre_smash7 =[ $smash7, ogre_smash8 ] {ai_charge(4); chainsaw(0);}; +void() ogre_smash8 =[ $smash8, ogre_smash9 ] {ai_charge(10); chainsaw(0);}; +void() ogre_smash9 =[ $smash9, ogre_smash10 ] {ai_charge(13); chainsaw(0);}; +void() ogre_smash10 =[ $smash10, ogre_smash11 ] {chainsaw(1);}; +void() ogre_smash11 =[ $smash11, ogre_smash12 ] {ai_charge(2); chainsaw(0); +self.nextthink = time + 0.1 + random()*0.1;}; // slight variation +//void() ogre_smash12 =[ $smash12, ogre_smash13 ] {ai_charge();}; +void() ogre_smash12 =[$smash12, ogre_smash13] {ai_charge(0);}; +void() ogre_smash13 =[ $smash13, ogre_smash14 ] {ai_charge(4);}; +void() ogre_smash14 =[ $smash14, ogre_run1 ] {ai_charge(12);}; + +void() ogre_nail1 =[ $run1, ogre_nail2 ] {ai_face();}; +void() ogre_nail2 =[ $run2, ogre_nail3 ] {ai_face();}; +void() ogre_nail3 =[ $run2, ogre_nail4 ] {ai_face();}; +void() ogre_nail4 =[ $run3, ogre_nail5 ] {ai_face(); ogre_fire();}; +void() ogre_nail5 =[ $run4, ogre_nail6 ] {ai_face();}; +void() ogre_nail6 =[ $run5, ogre_nail7 ] {ai_face();}; +void() ogre_nail7 =[ $run6, ogre_run1 ] {ai_face();}; + +void() ogre_pain1 =[ $pain1, ogre_pain2 ] {}; +void() ogre_pain2 =[ $pain2, ogre_pain3 ] {}; +void() ogre_pain3 =[ $pain3, ogre_pain4 ] {}; +void() ogre_pain4 =[ $pain4, ogre_pain5 ] {}; +void() ogre_pain5 =[ $pain5, ogre_run1 ] {}; + + +void() ogre_painb1 =[ $painb1, ogre_painb2 ] {}; +void() ogre_painb2 =[ $painb2, ogre_painb3 ] {}; +void() ogre_painb3 =[ $painb3, ogre_run1 ] {}; + + +void() ogre_painc1 =[ $painc1, ogre_painc2 ] {}; +void() ogre_painc2 =[ $painc2, ogre_painc3 ] {}; +void() ogre_painc3 =[ $painc3, ogre_painc4 ] {}; +void() ogre_painc4 =[ $painc4, ogre_painc5 ] {}; +void() ogre_painc5 =[ $painc5, ogre_painc6 ] {}; +void() ogre_painc6 =[ $painc6, ogre_run1 ] {}; + + +void() ogre_paind1 =[ $paind1, ogre_paind2 ] {}; +void() ogre_paind2 =[ $paind2, ogre_paind3 ] {ai_pain(10);}; +void() ogre_paind3 =[ $paind3, ogre_paind4 ] {ai_pain(9);}; +void() ogre_paind4 =[ $paind4, ogre_paind5 ] {ai_pain(4);}; +void() ogre_paind5 =[ $paind5, ogre_paind6 ] {}; +void() ogre_paind6 =[ $paind6, ogre_paind7 ] {}; +void() ogre_paind7 =[ $paind7, ogre_paind8 ] {}; +void() ogre_paind8 =[ $paind8, ogre_paind9 ] {}; +void() ogre_paind9 =[ $paind9, ogre_paind10 ] {}; +void() ogre_paind10=[ $paind10, ogre_paind11 ] {}; +void() ogre_paind11=[ $paind11, ogre_paind12 ] {}; +void() ogre_paind12=[ $paind12, ogre_paind13 ] {}; +void() ogre_paind13=[ $paind13, ogre_paind14 ] {}; +void() ogre_paind14=[ $paind14, ogre_paind15 ] {}; +void() ogre_paind15=[ $paind15, ogre_paind16 ] {}; +void() ogre_paind16=[ $paind16, ogre_run1 ] {}; + +void() ogre_paine1 =[ $paine1, ogre_paine2 ] {}; +void() ogre_paine2 =[ $paine2, ogre_paine3 ] {ai_pain(10);}; +void() ogre_paine3 =[ $paine3, ogre_paine4 ] {ai_pain(9);}; +void() ogre_paine4 =[ $paine4, ogre_paine5 ] {ai_pain(4);}; +void() ogre_paine5 =[ $paine5, ogre_paine6 ] {}; +void() ogre_paine6 =[ $paine6, ogre_paine7 ] {}; +void() ogre_paine7 =[ $paine7, ogre_paine8 ] {}; +void() ogre_paine8 =[ $paine8, ogre_paine9 ] {}; +void() ogre_paine9 =[ $paine9, ogre_paine10 ] {}; +void() ogre_paine10=[ $paine10, ogre_paine11 ] {}; +void() ogre_paine11=[ $paine11, ogre_paine12 ] {}; +void() ogre_paine12=[ $paine12, ogre_paine13 ] {}; +void() ogre_paine13=[ $paine13, ogre_paine14 ] {}; +void() ogre_paine14=[ $paine14, ogre_paine15 ] {}; +void() ogre_paine15=[ $paine15, ogre_run1 ] {}; + + +void(entity attacker, float damage) ogre_pain = +{ + local float r; + +// don't make multiple pain sounds right after each other + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "ogre/ogpain1.wav", 1, ATTN_NORM); + + r = random(); + + if (r < 0.25) + { + ogre_pain1 (); + self.pain_finished = time + 1; + } + else if (r < 0.5) + { + ogre_painb1 (); + self.pain_finished = time + 1; + } + else if (r < 0.75) + { + ogre_painc1 (); + self.pain_finished = time + 1; + } + else if (r < 0.88) + { + ogre_paind1 (); + self.pain_finished = time + 2; + } + else + { + ogre_paine1 (); + self.pain_finished = time + 2; + } +}; + +void() ogre_die1 =[ $death1, ogre_die2 ] {}; +void() ogre_die2 =[ $death2, ogre_die3 ] {}; +void() ogre_die3 =[ $death3, ogre_die4 ] +{self.solid = SOLID_NOT;DropBackpack();}; +void() ogre_die4 =[ $death4, ogre_die5 ] {}; +void() ogre_die5 =[ $death5, ogre_die6 ] {}; +void() ogre_die6 =[ $death6, ogre_die7 ] {}; +void() ogre_die7 =[ $death7, ogre_die8 ] {}; +void() ogre_die8 =[ $death8, ogre_die9 ] {}; +void() ogre_die9 =[ $death9, ogre_die10 ] {}; +void() ogre_die10 =[ $death10, ogre_die11 ] {}; +void() ogre_die11 =[ $death11, ogre_die12 ] {}; +void() ogre_die12 =[ $death12, ogre_die13 ] {}; +void() ogre_die13 =[ $death13, ogre_die14 ] {}; +void() ogre_die14 =[ $death14, ogre_die14 ] {}; + +void() ogre_bdie1 =[ $bdeath1, ogre_bdie2 ] {}; +void() ogre_bdie2 =[ $bdeath2, ogre_bdie3 ] {ai_forward(5);}; +void() ogre_bdie3 =[ $bdeath3, ogre_bdie4 ] +{self.solid = SOLID_NOT;DropBackpack();}; +void() ogre_bdie4 =[ $bdeath4, ogre_bdie5 ] {ai_forward(1);}; +void() ogre_bdie5 =[ $bdeath5, ogre_bdie6 ] {ai_forward(3);}; +void() ogre_bdie6 =[ $bdeath6, ogre_bdie7 ] {ai_forward(7);}; +void() ogre_bdie7 =[ $bdeath7, ogre_bdie8 ] {ai_forward(25);}; +void() ogre_bdie8 =[ $bdeath8, ogre_bdie9 ] {}; +void() ogre_bdie9 =[ $bdeath9, ogre_bdie10 ] {}; +void() ogre_bdie10 =[ $bdeath10, ogre_bdie10 ] {}; + +void() ogre_die = +{ + + sound (self, CHAN_VOICE, "ogre/ogdth.wav", 1, ATTN_NORM); + + if (random() < 0.5) + ogre_die1 (); + else + ogre_bdie1 (); +}; + +void() ogre_melee = +{ + if (random() > 0.5) + ogre_smash1 (); + else + ogre_swing1 (); +}; + + +/*QUAKED monster_ogre (1 0 0) (-32 -32 -24) (32 32 64) Ambush + +*/ +void() monster_ogre = +{ + if (deathmatch) + { + remove(self); + } + precache_model ("progs/ogre.mdl"); + precache_model ("progs/h_ogre.mdl"); + precache_model ("progs/grenade.mdl"); + + precache_sound ("ogre/laugh1.wav"); + precache_sound ("ogre/laugh2.wav"); + precache_sound ("ogre/ogdrag.wav"); + precache_sound ("ogre/ogdth.wav"); + precache_sound ("ogre/ogidle.wav"); + precache_sound ("ogre/ogidle2.wav"); + precache_sound ("ogre/ogpain1.wav"); + precache_sound ("ogre/ogsawatk.wav"); + precache_sound ("ogre/ogwake.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/ogre.mdl"); + + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 800; + + self.th_stand = ogre_stand1; + self.th_walk = ogre_walk1; + self.th_run = ogre_run1; + self.th_die = ogre_die; + self.th_melee = ogre_melee; + self.th_missile = ogre_nail1; + self.th_pain = ogre_pain; + + self.ammo_rockets_real = 2; // drop 2 rockets on death + + walkmonster_start(); +}; + +void() monster_ogre_marksman = +{ + monster_ogre (); +}; + + diff --git a/r17/Revamped src/Revamped QC/quakemons/oldone.qc b/r17/Revamped src/Revamped QC/quakemons/oldone.qc new file mode 100755 index 00000000..386c11ac --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/oldone.qc @@ -0,0 +1,278 @@ +/* +============================================================================== + +OLD ONE + +============================================================================== +*/ +$cd id1/models/old_one +$origin 0 0 24 +$base base +$skin skin +$scale 1 + +void() finale_1; +void() finale_2; +void() finale_3; +void() finale_4; + +$frame old1 old2 old3 old4 old5 old6 old7 old8 old9 +$frame old10 old11 old12 old13 old14 old15 old16 old17 old18 old19 +$frame old20 old21 old22 old23 old24 old25 old26 old27 old28 old29 +$frame old30 old31 old32 old33 old34 old35 old36 old37 old38 old39 +$frame old40 old41 old42 old43 old44 old45 old46 + +$frame shake1 shake2 shake3 shake4 shake5 shake6 shake7 shake8 +$frame shake9 shake10 shake11 shakex shake12 shake13 shake14 +$frame shake15 shake16 shake17 shake18 shake19 shake20 + +//void() old_stand =[ $old1, old_stand ] {}; + +void() old_idle1 =[ $old1, old_idle2 ] {}; +void() old_idle2 =[ $old2, old_idle3 ] {}; +void() old_idle3 =[ $old3, old_idle4 ] {}; +void() old_idle4 =[ $old4, old_idle5 ] {}; +void() old_idle5 =[ $old5, old_idle6 ] {}; +void() old_idle6 =[ $old6, old_idle7 ] {}; +void() old_idle7 =[ $old7, old_idle8 ] {}; +void() old_idle8 =[ $old8, old_idle9 ] {}; +void() old_idle9 =[ $old9, old_idle10 ] {}; +void() old_idle10 =[ $old10, old_idle11 ] {}; +void() old_idle11 =[ $old11, old_idle12 ] {}; +void() old_idle12 =[ $old12, old_idle13 ] {}; +void() old_idle13 =[ $old13, old_idle14 ] {}; +void() old_idle14 =[ $old14, old_idle15 ] {}; +void() old_idle15 =[ $old15, old_idle16 ] {}; +void() old_idle16 =[ $old16, old_idle17 ] {}; +void() old_idle17 =[ $old17, old_idle18 ] {}; +void() old_idle18 =[ $old18, old_idle19 ] {}; +void() old_idle19 =[ $old19, old_idle20 ] {}; +void() old_idle20 =[ $old20, old_idle21 ] {}; +void() old_idle21 =[ $old21, old_idle22 ] {}; +void() old_idle22 =[ $old22, old_idle23 ] {}; +void() old_idle23 =[ $old23, old_idle24 ] {}; +void() old_idle24 =[ $old24, old_idle25 ] {}; +void() old_idle25 =[ $old25, old_idle26 ] {}; +void() old_idle26 =[ $old26, old_idle27 ] {}; +void() old_idle27 =[ $old27, old_idle28 ] {}; +void() old_idle28 =[ $old28, old_idle29 ] {}; +void() old_idle29 =[ $old29, old_idle30 ] {}; +void() old_idle30 =[ $old30, old_idle31 ] {}; +void() old_idle31 =[ $old31, old_idle32 ] {}; +void() old_idle32 =[ $old32, old_idle33 ] {}; +void() old_idle33 =[ $old33, old_idle34 ] {}; +void() old_idle34 =[ $old34, old_idle35 ] {}; +void() old_idle35 =[ $old35, old_idle36 ] {}; +void() old_idle36 =[ $old36, old_idle37 ] {}; +void() old_idle37 =[ $old37, old_idle38 ] {}; +void() old_idle38 =[ $old38, old_idle39 ] {}; +void() old_idle39 =[ $old39, old_idle40 ] {}; +void() old_idle40 =[ $old40, old_idle41 ] {}; +void() old_idle41 =[ $old41, old_idle42 ] {}; +void() old_idle42 =[ $old42, old_idle43 ] {}; +void() old_idle43 =[ $old43, old_idle44 ] {}; +void() old_idle44 =[ $old44, old_idle45 ] {}; +void() old_idle45 =[ $old45, old_idle46 ] {}; +void() old_idle46 =[ $old46, old_idle1 ] {}; + + +void() old_thrash1 =[ $shake1, old_thrash2 ] {lightstyle(0, "m");}; +void() old_thrash2 =[ $shake2, old_thrash3 ] {lightstyle(0, "k");}; +void() old_thrash3 =[ $shake3, old_thrash4 ] {lightstyle(0, "k");}; +void() old_thrash4 =[ $shake4, old_thrash5 ] {lightstyle(0, "i");}; +void() old_thrash5 =[ $shake5, old_thrash6 ] {lightstyle(0, "g");}; +void() old_thrash6 =[ $shake6, old_thrash7 ] {lightstyle(0, "e");}; +void() old_thrash7 =[ $shake7, old_thrash8 ] {lightstyle(0, "c");}; +void() old_thrash8 =[ $shake8, old_thrash9 ] {lightstyle(0, "a");}; +void() old_thrash9 =[ $shake9, old_thrash10 ] {lightstyle(0, "c");}; +void() old_thrash10 =[ $shake10, old_thrash11 ] {lightstyle(0, "e");}; +void() old_thrash11 =[ $shake11, old_thrash12 ] {lightstyle(0, "g");}; +void() old_thrash12 =[ $shake12, old_thrash13 ] {lightstyle(0, "i");}; +void() old_thrash13 =[ $shake13, old_thrash14 ] {lightstyle(0, "k");}; +void() old_thrash14 =[ $shake14, old_thrash15 ] {lightstyle(0, "m");}; +void() old_thrash15 =[ $shake15, old_thrash16 ] {lightstyle(0, "m"); +self.cnt = self.cnt + 1; +if (self.cnt < 3) + self.think = old_thrash1; +}; +void() old_thrash16 =[ $shake16, old_thrash17 ] {lightstyle(0, "g");}; +void() old_thrash17 =[ $shake17, old_thrash18 ] {lightstyle(0, "c");}; +void() old_thrash18 =[ $shake18, old_thrash19 ] {lightstyle(0, "b");}; +void() old_thrash19 =[ $shake19, old_thrash20 ] {lightstyle(0, "a");}; +void() old_thrash20 =[ $shake20, old_thrash20 ] {finale_4();}; + +//============================================================================ + +void() finale_1 = +{ + local entity pos, pl; + local entity timer; + + // TODO: Coop friendly finale goes here + + killed_monsters = killed_monsters + 1; + WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast + + intermission_exittime = time + 10000000; // never allow exit + intermission_running = 1; + + // find the intermission spot + pos = find (world, classname, "info_intermission"); + if (!pos) + error ("no info_intermission"); + pl = find (world, classname, "misc_teleporttrain"); + if (!pl) + error ("no teleporttrain"); + remove (pl); + + ENG_Finale(""); + + pl = find (world, classname, "player"); + while (pl != world) + { + pl.view_ofs = '0 0 0'; + pl.angles = other.v_angle = pos.mangle; + pl.fixangle = TRUE; // turn this way immediately + pl.map = self.map; + pl.nextthink = time + 0.5; + pl.takedamage = DAMAGE_NO; + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NONE; + pl.modelindex = 0; + setorigin (pl, pos.origin); + pl = find (pl, classname, "player"); + } + + // make fake versions of all players as standins, and move the real + // players to the intermission spot + + // wait for 1 second + timer = spawn(); + timer.nextthink = time + 1; + timer.think = finale_2; +}; + +void() finale_2 = +{ + local vector o; + + // start a teleport splash inside shub + + o = shub.origin - '0 100 0'; + TE_teleport(o); + + sound (shub, CHAN_VOICE, "misc/r_tele1.wav", 1, ATTN_NORM); + + self.nextthink = time + 2; + self.think = finale_3; +}; + +void() finale_3 = +{ + // start shub thrashing wildly + lightstyle(0, "a"); + shub.think = old_thrash1; + sound (shub, CHAN_VOICE, "boss2/death.wav", 1, ATTN_NORM); + remove(self); +}; + +void() finale_4 = +{ + // throw tons of meat chunks + local vector oldo; + local float x, y, z; + local float r; + local entity n; + + sound (self, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NORM); + + oldo = self.origin; + + z = 16; + while (z <= 144) + { + x = -64; + while (x <= 64) + { + y = -64; + while (y <= 64) + { + self.origin_x = oldo_x + x; + self.origin_y = oldo_y + y; + self.origin_z = oldo_z + z; + + r = random(); + if (r < 0.3) + ThrowGib ("progs/gib1.mdl", -999); + else if (r < 0.6) + ThrowGib ("progs/gib2.mdl", -999); + else + ThrowGib ("progs/gib3.mdl", -999); + y = y + 32; + } + x = x + 32; + } + z = z + 96; + } + // start the end text + ENG_Finale("Congratulations and well done! You have\nbeaten the hideous Shub-Niggurath, and\nher hundreds of ugly changelings and\nmonsters. You have proven that your\nskill and your cunning are greater than\nall the powers of Quake. You are the\nmaster now. Id Software salutes you."); + +// put a player model down + n = spawn(); + setmodel (n, "progs/player.mdl"); + oldo = oldo - '32 264 0'; + setorigin (n, oldo); + n.angles = '0 290 0'; + n.frame = 1; + + remove (self); + +// switch cd track + ENG_SwitchTrack(3, 3); + lightstyle(0, "m"); +}; + +//============================================================================ + +void () nopain = +{ + self.health = 40000; +}; + +//============================================================================ + + +/*QUAKED monster_oldone (1 0 0) (-16 -16 -24) (16 16 32) +*/ +void() monster_oldone = +{ + if (deathmatch) + { + remove(self); + return; + } + + precache_model2 ("progs/oldone.mdl"); + + precache_sound2 ("boss2/death.wav"); + precache_sound2 ("boss2/idle.wav"); + precache_sound2 ("boss2/sight.wav"); + precache_sound2 ("boss2/pop2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/oldone.mdl"); + setsize (self, '-160 -128 -24', '160 128 256'); + + self.health = 40000; // kill by telefrag + self.think = old_idle1; + self.nextthink = time + 0.1; + self.takedamage = DAMAGE_YES; + self.th_pain = nopain; + self.th_die = finale_1; + shub = self; + + total_monsters = total_monsters + 1; +}; + diff --git a/r17/Revamped src/Revamped QC/quakemons/shalrath.qc b/r17/Revamped src/Revamped QC/quakemons/shalrath.qc new file mode 100755 index 00000000..6629c718 --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/shalrath.qc @@ -0,0 +1,219 @@ +/* +============================================================================== + +SHAL-RATH + +============================================================================== +*/ +$cd id1/models/shalrath +$origin 0 0 24 +$base base +$skin skin +$scale 0.7 + +$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 +$frame attack9 attack10 attack11 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame death1 death2 death3 death4 death5 death6 death7 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 +$frame walk11 walk12 + +void() shalrath_pain; +void() ShalMissile; +void() shal_stand =[ $walk1, shal_stand ] {ai_stand();}; + +void() shal_walk1 =[ $walk2, shal_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE); +ai_walk(6);}; +void() shal_walk2 =[ $walk3, shal_walk3 ] {ai_walk(4);}; +void() shal_walk3 =[ $walk4, shal_walk4 ] {ai_walk(0);}; +void() shal_walk4 =[ $walk5, shal_walk5 ] {ai_walk(0);}; +void() shal_walk5 =[ $walk6, shal_walk6 ] {ai_walk(0);}; +void() shal_walk6 =[ $walk7, shal_walk7 ] {ai_walk(0);}; +void() shal_walk7 =[ $walk8, shal_walk8 ] {ai_walk(5);}; +void() shal_walk8 =[ $walk9, shal_walk9 ] {ai_walk(6);}; +void() shal_walk9 =[ $walk10, shal_walk10 ] {ai_walk(5);}; +void() shal_walk10 =[ $walk11, shal_walk11 ] {ai_walk(0);}; +void() shal_walk11 =[ $walk12, shal_walk12 ] {ai_walk(4);}; +void() shal_walk12 =[ $walk1, shal_walk1 ] {ai_walk(5);}; + +void() shal_run1 =[ $walk2, shal_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE); +ai_run(6);}; +void() shal_run2 =[ $walk3, shal_run3 ] {ai_run(4);}; +void() shal_run3 =[ $walk4, shal_run4 ] {ai_run(0);}; +void() shal_run4 =[ $walk5, shal_run5 ] {ai_run(0);}; +void() shal_run5 =[ $walk6, shal_run6 ] {ai_run(0);}; +void() shal_run6 =[ $walk7, shal_run7 ] {ai_run(0);}; +void() shal_run7 =[ $walk8, shal_run8 ] {ai_run(5);}; +void() shal_run8 =[ $walk9, shal_run9 ] {ai_run(6);}; +void() shal_run9 =[ $walk10, shal_run10 ] {ai_run(5);}; +void() shal_run10 =[ $walk11, shal_run11 ] {ai_run(0);}; +void() shal_run11 =[ $walk12, shal_run12 ] {ai_run(4);}; +void() shal_run12 =[ $walk1, shal_run1 ] {ai_run(5);}; + +void() shal_attack1 =[ $attack1, shal_attack2 ] { +sound (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM); +ai_face(); +}; +void() shal_attack2 =[ $attack2, shal_attack3 ] {ai_face();}; +void() shal_attack3 =[ $attack3, shal_attack4 ] {ai_face();}; +void() shal_attack4 =[ $attack4, shal_attack5 ] {ai_face();}; +void() shal_attack5 =[ $attack5, shal_attack6 ] {ai_face();}; +void() shal_attack6 =[ $attack6, shal_attack7 ] {ai_face();}; +void() shal_attack7 =[ $attack7, shal_attack8 ] {ai_face();}; +void() shal_attack8 =[ $attack8, shal_attack9 ] {ai_face();}; +void() shal_attack9 =[ $attack9, shal_attack10 ] {ShalMissile();}; +void() shal_attack10 =[ $attack10, shal_attack11 ] {ai_face();}; +void() shal_attack11 =[ $attack11, shal_run1 ] {}; + +void() shal_pain1 =[ $pain1, shal_pain2 ] {}; +void() shal_pain2 =[ $pain2, shal_pain3 ] {}; +void() shal_pain3 =[ $pain3, shal_pain4 ] {}; +void() shal_pain4 =[ $pain4, shal_pain5 ] {}; +void() shal_pain5 =[ $pain5, shal_run1 ] {}; + +void() shal_death1 =[ $death1, shal_death2 ] {}; +void() shal_death2 =[ $death2, shal_death3 ] {}; +void() shal_death3 =[ $death3, shal_death4 ] {}; +void() shal_death4 =[ $death4, shal_death5 ] {}; +void() shal_death5 =[ $death5, shal_death6 ] {}; +void() shal_death6 =[ $death6, shal_death7 ] {}; +void() shal_death7 =[ $death7, shal_death7 ] {}; + + +void() shalrath_pain = +{ + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "shalrath/pain.wav", 1, ATTN_NORM); + shal_pain1(); + self.pain_finished = time + 3; +}; + +void() shalrath_die = +{ +// check for gib + if (self.health < -90) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_shal.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + + sound (self, CHAN_VOICE, "shalrath/death.wav", 1, ATTN_NORM); + shal_death1(); + self.solid = SOLID_NOT; + // insert death sounds here +}; + +/* +================ +ShalMissile +================ +*/ +float() ShalMissileTouch; +void() ShalHome; +void() ShalMissile = +{ + local vector dir; + local float dist, flytime; + + dir = normalize((self.enemy.origin + '0 0 10') - self.origin); + dist = vlen (self.enemy.origin - self.origin); + flytime = dist * 0.002; + if (flytime < 0.1) + flytime = 0.1; + + muzzleflash(); + sound (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); + + PRJ_FireProjectile(self, + "progs/v_spike.mdl", + self.origin + '0 0 10', + dir * 400, + PE_EXPLOSION, + 0, + 0, + 30); + PRJ_SetRadiusDamage(40, 80, MOD_SHALRATH); + PRJ_SetThink(ShalHome, flytime, 0.2); + PRJ_SetTouch(ShalMissileTouch); + newmis.avelocity = '300 300 300'; + newmis.enemy = self.enemy; +}; + +void() ShalHome = +{ + local vector dir, vtemp; + vtemp = self.enemy.origin + '0 0 10'; + if (self.enemy.health < 1) + { + remove(self); + return; + } + + dir = normalize(vtemp - self.origin); + if (skill > 2) + self.velocity = dir * 350; + else + self.velocity = dir * 250; +}; + +float() ShalMissileTouch = +{ + if (other.classname == "monster_zombie") + T_Damage (other, self, self, 110, MOD_SHALRATH); + + return 0; // always explode on touch +}; + +//================================================================= + +/*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) Ambush +*/ +void() monster_shalrath = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/shalrath.mdl"); + precache_model2 ("progs/h_shal.mdl"); + precache_model2 ("progs/v_spike.mdl"); + + precache_sound2 ("shalrath/attack.wav"); + precache_sound2 ("shalrath/attack2.wav"); + precache_sound2 ("shalrath/death.wav"); + precache_sound2 ("shalrath/idle.wav"); + precache_sound2 ("shalrath/pain.wav"); + precache_sound2 ("shalrath/sight.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/shalrath.mdl"); + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 400; + + self.th_stand = shal_stand; + self.th_walk = shal_walk1; + self.th_run = shal_run1; + self.th_die = shalrath_die; + self.th_pain = shalrath_pain; + self.th_missile = shal_attack1; + + self.think = walkmonster_start; + self.nextthink = time + 0.1 + random ()*0.1; + +}; diff --git a/r17/Revamped src/Revamped QC/quakemons/shambler.qc b/r17/Revamped src/Revamped QC/quakemons/shambler.qc new file mode 100755 index 00000000..d90eb38f --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/shambler.qc @@ -0,0 +1,339 @@ +/* +============================================================================== + +SHAMBLER + +============================================================================== +*/ + +$cd id1/models/shams +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 +$frame stand10 stand11 stand12 stand13 stand14 stand15 stand16 stand17 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 +$frame walk8 walk9 walk10 walk11 walk12 + +$frame run1 run2 run3 run4 run5 run6 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 +$frame smash8 smash9 smash10 smash11 smash12 + +$frame swingr1 swingr2 swingr3 swingr4 swingr5 +$frame swingr6 swingr7 swingr8 swingr9 + +$frame swingl1 swingl2 swingl3 swingl4 swingl5 +$frame swingl6 swingl7 swingl8 swingl9 + +$frame magic1 magic2 magic3 magic4 magic5 +$frame magic6 magic7 magic8 magic9 magic10 magic11 magic12 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame death1 death2 death3 death4 death5 death6 +$frame death7 death8 death9 death10 death11 + +void(float chrg, float damage, float side, float crnd) ShamClaw = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + ai_charge(chrg); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + ldmg = (random() + random() + random()) * damage; + T_Damage (self.enemy, self, self, ldmg, MOD_SHAMBLER); + sound (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM); + + if (side) + { + makevectors (self.angles); + SpawnMeatSpray (self.origin + v_forward*16, (crandom() * crnd + side) * v_right); + } +}; + + +void() sham_stand1 =[ $stand1, sham_stand2 ] {ai_stand();}; +void() sham_stand2 =[ $stand2, sham_stand3 ] {ai_stand();}; +void() sham_stand3 =[ $stand3, sham_stand4 ] {ai_stand();}; +void() sham_stand4 =[ $stand4, sham_stand5 ] {ai_stand();}; +void() sham_stand5 =[ $stand5, sham_stand6 ] {ai_stand();}; +void() sham_stand6 =[ $stand6, sham_stand7 ] {ai_stand();}; +void() sham_stand7 =[ $stand7, sham_stand8 ] {ai_stand();}; +void() sham_stand8 =[ $stand8, sham_stand9 ] {ai_stand();}; +void() sham_stand9 =[ $stand9, sham_stand10] {ai_stand();}; +void() sham_stand10 =[ $stand10, sham_stand11] {ai_stand();}; +void() sham_stand11 =[ $stand11, sham_stand12] {ai_stand();}; +void() sham_stand12 =[ $stand12, sham_stand13] {ai_stand();}; +void() sham_stand13 =[ $stand13, sham_stand14] {ai_stand();}; +void() sham_stand14 =[ $stand14, sham_stand15] {ai_stand();}; +void() sham_stand15 =[ $stand15, sham_stand16] {ai_stand();}; +void() sham_stand16 =[ $stand16, sham_stand17] {ai_stand();}; +void() sham_stand17 =[ $stand17, sham_stand1 ] {ai_stand();}; + +void() sham_walk1 =[ $walk1, sham_walk2 ] {ai_walk(10);}; +void() sham_walk2 =[ $walk2, sham_walk3 ] {ai_walk(9);}; +void() sham_walk3 =[ $walk3, sham_walk4 ] {ai_walk(9);}; +void() sham_walk4 =[ $walk4, sham_walk5 ] {ai_walk(5);}; +void() sham_walk5 =[ $walk5, sham_walk6 ] {ai_walk(6);}; +void() sham_walk6 =[ $walk6, sham_walk7 ] {ai_walk(12);}; +void() sham_walk7 =[ $walk7, sham_walk8 ] {ai_walk(8);}; +void() sham_walk8 =[ $walk8, sham_walk9 ] {ai_walk(3);}; +void() sham_walk9 =[ $walk9, sham_walk10] {ai_walk(13);}; +void() sham_walk10 =[ $walk10, sham_walk11] {ai_walk(9);}; +void() sham_walk11 =[ $walk11, sham_walk12] {ai_walk(7);}; +void() sham_walk12 =[ $walk12, sham_walk1 ] {ai_walk(7); +if (random() > 0.8) + sound (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);}; + +void() sham_run1 =[ $run1, sham_run2 ] {ai_run(20);}; +void() sham_run2 =[ $run2, sham_run3 ] {ai_run(24);}; +void() sham_run3 =[ $run3, sham_run4 ] {ai_run(20);}; +void() sham_run4 =[ $run4, sham_run5 ] {ai_run(20);}; +void() sham_run5 =[ $run5, sham_run6 ] {ai_run(24);}; +void() sham_run6 =[ $run6, sham_run1 ] {ai_run(20); +if (random() > 0.8) + sound (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE); +}; + +void() sham_smash1 =[ $smash1, sham_smash2 ] { +sound (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); +ai_charge(2);}; +void() sham_smash2 =[ $smash2, sham_smash3 ] {ai_charge(6);}; +void() sham_smash3 =[ $smash3, sham_smash4 ] {ai_charge(6);}; +void() sham_smash4 =[ $smash4, sham_smash5 ] {ai_charge(5);}; +void() sham_smash5 =[ $smash5, sham_smash6 ] {ai_charge(4);}; +void() sham_smash6 =[ $smash6, sham_smash7 ] {ai_charge(1);}; +void() sham_smash7 =[ $smash7, sham_smash8 ] {ai_charge(0);}; +void() sham_smash8 =[ $smash8, sham_smash9 ] {ai_charge(0);}; +void() sham_smash9 =[ $smash9, sham_smash10 ] {ai_charge(0);}; +void() sham_smash10 =[ $smash10, sham_smash11 ] {ShamClaw(0, 40, 0, 100);}; +void() sham_smash11 =[ $smash11, sham_smash12 ] {ai_charge(5);}; +void() sham_smash12 =[ $smash12, sham_run1 ] {ai_charge(4);}; + +void() sham_swingr1; + +void() sham_swingl1 =[ $swingl1, sham_swingl2 ] { +sound (self, CHAN_VOICE, "shambler/melee2.wav", 1, ATTN_NORM); +ai_charge(5);}; +void() sham_swingl2 =[ $swingl2, sham_swingl3 ] {ai_charge(3);}; +void() sham_swingl3 =[ $swingl3, sham_swingl4 ] {ai_charge(7);}; +void() sham_swingl4 =[ $swingl4, sham_swingl5 ] {ai_charge(3);}; +void() sham_swingl5 =[ $swingl5, sham_swingl6 ] {ai_charge(7);}; +void() sham_swingl6 =[ $swingl6, sham_swingl7 ] {ai_charge(9);}; +void() sham_swingl7 =[ $swingl7, sham_swingl8 ] {ai_charge(5); ShamClaw(10, 20, 250, 0);}; +void() sham_swingl8 =[ $swingl8, sham_swingl9 ] {ai_charge(4);}; +void() sham_swingl9 =[ $swingl9, sham_run1 ] { +ai_charge(8); +if (random()<0.5) + self.think = sham_swingr1; +}; + +void() sham_swingr1 =[ $swingr1, sham_swingr2 ] { +sound (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); +ai_charge(1);}; +void() sham_swingr2 =[ $swingr2, sham_swingr3 ] {ai_charge(8);}; +void() sham_swingr3 =[ $swingr3, sham_swingr4 ] {ai_charge(14);}; +void() sham_swingr4 =[ $swingr4, sham_swingr5 ] {ai_charge(7);}; +void() sham_swingr5 =[ $swingr5, sham_swingr6 ] {ai_charge(3);}; +void() sham_swingr6 =[ $swingr6, sham_swingr7 ] {ai_charge(6);}; +void() sham_swingr7 =[ $swingr7, sham_swingr8 ] {ai_charge(6); ShamClaw(10, 20, -250, 0);}; +void() sham_swingr8 =[ $swingr8, sham_swingr9 ] {ai_charge(3);}; +void() sham_swingr9 =[ $swingr9, sham_run1 ] {ai_charge(1); +ai_charge(10); +if (random()<0.5) + self.think = sham_swingl1; +}; + +void() sham_melee = +{ + local float chance; + + chance = random(); + if (chance > 0.6 || self.health == 600) + sham_smash1 (); + else if (chance > 0.3) + sham_swingr1 (); + else + sham_swingl1 (); +}; + + +//============================================================================ + +void() CastLightning = +{ + local vector org, dir; + + muzzleflash(); + ai_face (); + + org = self.origin + '0 0 40'; + + dir = self.enemy.origin + '0 0 16' - org; + dir = normalize (dir); + + traceline (org, self.origin + dir*600, TRUE, self); + + TE_lightning1(self, org, trace_endpos); + + LightningDamage (org, trace_endpos, self, 10, MOD_SHAMBLER); +}; + +void() sham_magic1 =[ $magic1, sham_magic2 ] {ai_face(); + sound (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM); +}; +void() sham_magic2 =[ $magic2, sham_magic3 ] {ai_face();}; +void() sham_magic3 =[ $magic3, sham_magic4 ] {ai_face();self.nextthink = time + 0.2; +local entity o; + +muzzleflash(); +ai_face(); +// TODO: Spawn as an effect +self.owner = spawn(); +o = self.owner; +setmodel (o, "progs/s_light.mdl"); +setorigin (o, self.origin); +o.angles = self.angles; +o.nextthink = time + 0.7; +o.think = SUB_Remove; +}; +void() sham_magic4 =[ $magic4, sham_magic5 ] +{ +self.effects = self.effects | EF_MUZZLEFLASH; +self.owner.frame = 1; +}; +void() sham_magic5 =[ $magic5, sham_magic6 ] +{ +self.effects = self.effects | EF_MUZZLEFLASH; +self.owner.frame = 2; +}; +void() sham_magic6 =[ $magic6, sham_magic9 ] +{ +remove (self.owner); +CastLightning(); +sound (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM); +}; +void() sham_magic9 =[ $magic9, sham_magic10 ] +{CastLightning();}; +void() sham_magic10 =[ $magic10, sham_magic11 ] +{CastLightning();}; +void() sham_magic11 =[ $magic11, sham_magic12 ] +{ +if (skill > 2) + CastLightning(); +}; +void() sham_magic12 =[ $magic12, sham_run1 ] {}; + + + +void() sham_pain1 =[ $pain1, sham_pain2 ] {}; +void() sham_pain2 =[ $pain2, sham_pain3 ] {}; +void() sham_pain3 =[ $pain3, sham_pain4 ] {}; +void() sham_pain4 =[ $pain4, sham_pain5 ] {}; +void() sham_pain5 =[ $pain5, sham_pain6 ] {}; +void() sham_pain6 =[ $pain6, sham_run1 ] {}; + +void(entity attacker, float damage) sham_pain = +{ + sound (self, CHAN_VOICE, "shambler/shurt2.wav", 1, ATTN_NORM); + + if (self.health <= 0) + return; // allready dying, don't go into pain frame + + if (random()*400 > damage) + return; // didn't flinch + + if (self.pain_finished > time) + return; + self.pain_finished = time + 2; + + sham_pain1 (); +}; + + +//============================================================================ + +void() sham_death1 =[ $death1, sham_death2 ] {}; +void() sham_death2 =[ $death2, sham_death3 ] {}; +void() sham_death3 =[ $death3, sham_death4 ] {self.solid = SOLID_NOT;}; +void() sham_death4 =[ $death4, sham_death5 ] {}; +void() sham_death5 =[ $death5, sham_death6 ] {}; +void() sham_death6 =[ $death6, sham_death7 ] {}; +void() sham_death7 =[ $death7, sham_death8 ] {}; +void() sham_death8 =[ $death8, sham_death9 ] {}; +void() sham_death9 =[ $death9, sham_death10 ] {}; +void() sham_death10 =[ $death10, sham_death11 ] {}; +void() sham_death11 =[ $death11, sham_death11 ] {}; + +void() sham_die = +{ +// check for gib + if (self.health < -60) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_shams.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "shambler/sdeath.wav", 1, ATTN_NORM); + sham_death1 (); +}; + +//============================================================================ + + +/*QUAKED monster_shambler (1 0 0) (-32 -32 -24) (32 32 64) Ambush +*/ +void() monster_shambler = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/shambler.mdl"); + precache_model ("progs/s_light.mdl"); + precache_model ("progs/h_shams.mdl"); + precache_model ("progs/bolt.mdl"); + + precache_sound ("shambler/sattck1.wav"); + precache_sound ("shambler/sboom.wav"); + precache_sound ("shambler/sdeath.wav"); + precache_sound ("shambler/shurt2.wav"); + precache_sound ("shambler/sidle.wav"); + precache_sound ("shambler/ssight.wav"); + precache_sound ("shambler/melee1.wav"); + precache_sound ("shambler/melee2.wav"); + precache_sound ("shambler/smack.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + setmodel (self, "progs/shambler.mdl"); + + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 600; + + self.th_stand = sham_stand1; + self.th_walk = sham_walk1; + self.th_run = sham_run1; + self.th_die = sham_die; + self.th_melee = sham_melee; + self.th_missile = sham_magic1; + self.th_pain = sham_pain; + + walkmonster_start(); +}; diff --git a/r17/Revamped src/Revamped QC/quakemons/soldier.qc b/r17/Revamped src/Revamped QC/quakemons/soldier.qc new file mode 100755 index 00000000..e9e31158 --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/soldier.qc @@ -0,0 +1,281 @@ +/* +============================================================================== + +SOLDIER / PLAYER + +============================================================================== +*/ + +$cd id1/models/soldier3 +$origin 0 -6 24 +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 + +$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8 +$frame deathc9 deathc10 deathc11 + +$frame load1 load2 load3 load4 load5 load6 load7 load8 load9 load10 load11 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10 +$frame painb11 painb12 painb13 painb14 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10 +$frame painc11 painc12 painc13 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 shoot7 shoot8 shoot9 + +$frame prowl_1 prowl_2 prowl_3 prowl_4 prowl_5 prowl_6 prowl_7 prowl_8 +$frame prowl_9 prowl_10 prowl_11 prowl_12 prowl_13 prowl_14 prowl_15 prowl_16 +$frame prowl_17 prowl_18 prowl_19 prowl_20 prowl_21 prowl_22 prowl_23 prowl_24 + +/* +============================================================================== +SOLDIER CODE +============================================================================== +*/ + +void() laughs = +{ +local float r; +r = random(); +if (r <= 0.5) +sound (self, CHAN_AUTO, "soldier/laugh1.wav", 0.8, ATTN_NORM); +else if ( r <= 0.10) +sound (self, CHAN_AUTO, "soldier/laugh2.wav", 0.8, ATTN_NORM); +else +{} +}; +void() army_fire; + +void() army_stand1 =[ $stand1, army_stand2 ] {ai_stand();}; +void() army_stand2 =[ $stand2, army_stand3 ] {ai_stand();}; +void() army_stand3 =[ $stand3, army_stand4 ] {ai_stand();}; +void() army_stand4 =[ $stand4, army_stand5 ] {ai_stand();}; +void() army_stand5 =[ $stand5, army_stand6 ] {ai_stand();}; +void() army_stand6 =[ $stand6, army_stand7 ] {ai_stand();laughs();}; +void() army_stand7 =[ $stand7, army_stand8 ] {ai_stand();}; +void() army_stand8 =[ $stand8, army_stand1 ] {ai_stand();}; + +void() army_walk1 =[ $prowl_1, army_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE); +ai_walk(1);}; +void() army_walk2 =[ $prowl_2, army_walk3 ] {ai_walk(1);}; +void() army_walk3 =[ $prowl_3, army_walk4 ] {ai_walk(1);}; +void() army_walk4 =[ $prowl_4, army_walk5 ] {ai_walk(1);}; +void() army_walk5 =[ $prowl_5, army_walk6 ] {ai_walk(2);}; +void() army_walk6 =[ $prowl_6, army_walk7 ] {ai_walk(3);}; +void() army_walk7 =[ $prowl_7, army_walk8 ] {ai_walk(4);}; +void() army_walk8 =[ $prowl_8, army_walk9 ] {ai_walk(4);}; +void() army_walk9 =[ $prowl_9, army_walk10 ] {ai_walk(2);}; +void() army_walk10 =[ $prowl_10, army_walk11 ] {ai_walk(2);}; +void() army_walk11 =[ $prowl_11, army_walk12 ] {ai_walk(2);}; +void() army_walk12 =[ $prowl_12, army_walk13 ] {ai_walk(1);}; +void() army_walk13 =[ $prowl_13, army_walk14 ] {ai_walk(0);}; +void() army_walk14 =[ $prowl_14, army_walk15 ] {ai_walk(1);}; +void() army_walk15 =[ $prowl_15, army_walk16 ] {ai_walk(1);}; +void() army_walk16 =[ $prowl_16, army_walk17 ] {ai_walk(1);}; +void() army_walk17 =[ $prowl_17, army_walk18 ] {ai_walk(3);}; +void() army_walk18 =[ $prowl_18, army_walk19 ] {ai_walk(3);}; +void() army_walk19 =[ $prowl_19, army_walk20 ] {ai_walk(3);}; +void() army_walk20 =[ $prowl_20, army_walk21 ] {ai_walk(3);}; +void() army_walk21 =[ $prowl_21, army_walk22 ] {ai_walk(2);}; +void() army_walk22 =[ $prowl_22, army_walk23 ] {ai_walk(1);}; +void() army_walk23 =[ $prowl_23, army_walk24 ] {ai_walk(1);}; +void() army_walk24 =[ $prowl_24, army_walk1 ] {ai_walk(1);}; + +void() army_run1 =[ $run1, army_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE); +ai_run(11);}; +void() army_run2 =[ $run2, army_run3 ] {ai_run(15);}; +void() army_run3 =[ $run3, army_run4 ] {ai_run(10);}; +void() army_run4 =[ $run4, army_run5 ] {ai_run(10);}; +void() army_run5 =[ $run5, army_run6 ] {ai_run(8);}; +void() army_run6 =[ $run6, army_run7 ] {ai_run(15);}; +void() army_run7 =[ $run7, army_run8 ] {ai_run(10);}; +void() army_run8 =[ $run8, army_run1 ] {ai_run(8);}; + +void() army_atk1 =[ $shoot1, army_atk2 ] {ai_face();}; +void() army_atk2 =[ $shoot2, army_atk3 ] {ai_face();}; +void() army_atk3 =[ $shoot3, army_atk4 ] {ai_face();}; +void() army_atk4 =[ $shoot4, army_atk5 ] {ai_face();}; +void() army_atk5 =[ $shoot5, army_atk6 ] {ai_face(); army_fire(); muzzleflash();}; +void() army_atk6 =[ $shoot6, army_atk7 ] {ai_face();}; +void() army_atk7 =[ $shoot7, army_atk8 ] {ai_face();SUB_CheckRefire (army_atk1);}; +void() army_atk8 =[ $shoot8, army_atk9 ] {ai_face();}; +void() army_atk9 =[ $shoot9, army_run1 ] {ai_face();}; + + +void() army_pain1 =[ $pain1, army_pain2 ] {}; +void() army_pain2 =[ $pain2, army_pain3 ] {}; +void() army_pain3 =[ $pain3, army_pain4 ] {}; +void() army_pain4 =[ $pain4, army_pain5 ] {}; +void() army_pain5 =[ $pain5, army_pain6 ] {}; +void() army_pain6 =[ $pain6, army_run1 ] {ai_pain(1);}; + +void() army_painb1 =[ $painb1, army_painb2 ] {}; +void() army_painb2 =[ $painb2, army_painb3 ] {ai_painforward(13);}; +void() army_painb3 =[ $painb3, army_painb4 ] {ai_painforward(9);}; +void() army_painb4 =[ $painb4, army_painb5 ] {}; +void() army_painb5 =[ $painb5, army_painb6 ] {}; +void() army_painb6 =[ $painb6, army_painb7 ] {}; +void() army_painb7 =[ $painb7, army_painb8 ] {}; +void() army_painb8 =[ $painb8, army_painb9 ] {}; +void() army_painb9 =[ $painb9, army_painb10] {}; +void() army_painb10=[ $painb10, army_painb11] {}; +void() army_painb11=[ $painb11, army_painb12] {}; +void() army_painb12=[ $painb12, army_painb13] {ai_pain(2);}; +void() army_painb13=[ $painb13, army_painb14] {}; +void() army_painb14=[ $painb14, army_run1 ] {}; + +void() army_painc1 =[ $painc1, army_painc2 ] {}; +void() army_painc2 =[ $painc2, army_painc3 ] {ai_pain(1);}; +void() army_painc3 =[ $painc3, army_painc4 ] {}; +void() army_painc4 =[ $painc4, army_painc5 ] {}; +void() army_painc5 =[ $painc5, army_painc6 ] {ai_painforward(1);}; +void() army_painc6 =[ $painc6, army_painc7 ] {ai_painforward(1);}; +void() army_painc7 =[ $painc7, army_painc8 ] {}; +void() army_painc8 =[ $painc8, army_painc9 ] {ai_pain(1);}; +void() army_painc9 =[ $painc9, army_painc10] {ai_painforward(4);}; +void() army_painc10=[ $painc10, army_painc11] {ai_painforward(3);}; +void() army_painc11=[ $painc11, army_painc12] {ai_painforward(6);}; +void() army_painc12=[ $painc12, army_painc13] {ai_painforward(8);}; +void() army_painc13=[ $painc13, army_run1] {}; + +void(entity attacker, float damage) army_pain = +{ + local float r; + + if (self.pain_finished > time) + return; + + r = random(); + + if (r < 0.2) + { + self.pain_finished = time + 0.6; + army_pain1 (); + sound (self, CHAN_VOICE, "soldier/pain1.wav", 1, ATTN_NORM); + } + else if (r < 0.6) + { + self.pain_finished = time + 1.1; + army_painb1 (); + sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM); + } + else + { + self.pain_finished = time + 1.1; + army_painc1 (); + sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM); + } +}; + + +void() army_fire = +{ + local vector dir; + local entity en; + + ai_face(); + + sound (self, CHAN_WEAPON, "weapons/ppist.wav", 1, ATTN_NORM); + +// fire somewhat behind the player, so a dodging player is harder to hit + en = self.enemy; + + dir = en.origin - en.velocity*0.2; + dir = normalize (dir - self.origin); + + FireBullets (1, dir, '0.1 0.1 0', MOD_SOLDIER); +}; + + + +void() army_die1 =[ $death1, army_die2 ] {}; +void() army_die2 =[ $death2, army_die3 ] {}; +void() army_die3 =[ $death3, army_die4 ] {self.solid = SOLID_NOT;DropBackpack();}; +void() army_die4 =[ $death4, army_die5 ] {}; +void() army_die5 =[ $death5, army_die6 ] {}; +void() army_die6 =[ $death6, army_die7 ] {}; +void() army_die7 =[ $death7, army_die8 ] {}; +void() army_die8 =[ $death8, army_die9 ] {}; +void() army_die9 =[ $death9, army_die10 ] {}; +void() army_die10 =[ $death10, army_die10 ] {}; + +void() army_cdie1 =[ $deathc1, army_cdie2 ] {}; +void() army_cdie2 =[ $deathc2, army_cdie3 ] {ai_back(5);}; +void() army_cdie3 =[ $deathc3, army_cdie4 ] {self.solid = SOLID_NOT;DropBackpack();ai_back(4);remove(self);}; +void() army_cdie4 =[ $deathc4, army_cdie5 ] {ai_back(13);}; +void() army_cdie5 =[ $deathc5, army_cdie6 ] {ai_back(3);}; +void() army_cdie6 =[ $deathc6, army_cdie7 ] {ai_back(4);}; +void() army_cdie7 =[ $deathc7, army_cdie8 ] {}; +void() army_cdie8 =[ $deathc8, army_cdie9 ] {}; +void() army_cdie9 =[ $deathc9, army_cdie10 ] {}; +void() army_cdie10 =[ $deathc10, army_cdie11 ] {}; +void() army_cdie11 =[ $deathc11, army_cdie11 ] {}; + + +void() army_die = +{ +// check for gib + +// regular death + sound (self, CHAN_VOICE, "soldier/death1.wav", 1, ATTN_NORM); + if (random() < 0.5) + army_die1 (); + else + army_cdie1 (); +}; + + +/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_army = +{ + if (deathmatch) + { + remove(self); + } + precache_model ("progs/soldier.mdl"); + precache_model ("progs/h_guard.mdl"); + + precache_sound ("soldier/laugh1.wav"); + precache_sound ("soldier/laugh2.wav"); + precache_sound ("soldier/death1.wav"); + precache_sound ("soldier/idle.wav"); + precache_sound ("soldier/pain1.wav"); + precache_sound ("soldier/pain2.wav"); + precache_sound ("soldier/sight1.wav"); + + precache_sound ("player/udeath.wav"); // gib death + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/soldier.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 130; + + self.th_stand = army_stand1; + self.th_walk = army_walk1; + self.th_run = army_run1; + self.th_missile = army_atk1; + self.th_pain = army_pain; + self.th_die = army_die; + + self.ammo_shells_real = 5; // drop 5 shells on death + + walkmonster_start (); +}; diff --git a/r17/Revamped src/Revamped QC/quakemons/tarbaby.qc b/r17/Revamped src/Revamped QC/quakemons/tarbaby.qc new file mode 100755 index 00000000..430bdba2 --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/tarbaby.qc @@ -0,0 +1,212 @@ +/* +============================================================================== + +BLOB + +============================================================================== +*/ + +$cd id1/models/tarbaby +$origin 0 0 24 +$base base + +$skin skin + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 +$frame walk11 walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19 +$frame walk20 walk21 walk22 walk23 walk24 walk25 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 run13 +$frame run14 run15 run16 run17 run18 run19 run20 run21 run22 run23 +$frame run24 run25 + +$frame jump1 jump2 jump3 jump4 jump5 jump6 + +$frame fly1 fly2 fly3 fly4 + +$frame exp + +void() tbaby_stand1 =[ $walk1, tbaby_stand1 ] {ai_stand();}; + +void() tbaby_hang1 =[ $walk1, tbaby_hang1 ] {ai_stand();}; + +void() tbaby_walk1 =[ $walk1, tbaby_walk2 ] {ai_turn();}; +void() tbaby_walk2 =[ $walk2, tbaby_walk3 ] {ai_turn();}; +void() tbaby_walk3 =[ $walk3, tbaby_walk4 ] {ai_turn();}; +void() tbaby_walk4 =[ $walk4, tbaby_walk5 ] {ai_turn();}; +void() tbaby_walk5 =[ $walk5, tbaby_walk6 ] {ai_turn();}; +void() tbaby_walk6 =[ $walk6, tbaby_walk7 ] {ai_turn();}; +void() tbaby_walk7 =[ $walk7, tbaby_walk8 ] {ai_turn();}; +void() tbaby_walk8 =[ $walk8, tbaby_walk9 ] {ai_turn();}; +void() tbaby_walk9 =[ $walk9, tbaby_walk10 ] {ai_turn();}; +void() tbaby_walk10 =[ $walk10, tbaby_walk11 ] {ai_turn();}; +void() tbaby_walk11 =[ $walk11, tbaby_walk12 ] {ai_walk(2);}; +void() tbaby_walk12 =[ $walk12, tbaby_walk13 ] {ai_walk(2);}; +void() tbaby_walk13 =[ $walk13, tbaby_walk14 ] {ai_walk(2);}; +void() tbaby_walk14 =[ $walk14, tbaby_walk15 ] {ai_walk(2);}; +void() tbaby_walk15 =[ $walk15, tbaby_walk16 ] {ai_walk(2);}; +void() tbaby_walk16 =[ $walk16, tbaby_walk17 ] {ai_walk(2);}; +void() tbaby_walk17 =[ $walk17, tbaby_walk18 ] {ai_walk(2);}; +void() tbaby_walk18 =[ $walk18, tbaby_walk19 ] {ai_walk(2);}; +void() tbaby_walk19 =[ $walk19, tbaby_walk20 ] {ai_walk(2);}; +void() tbaby_walk20 =[ $walk20, tbaby_walk21 ] {ai_walk(2);}; +void() tbaby_walk21 =[ $walk21, tbaby_walk22 ] {ai_walk(2);}; +void() tbaby_walk22 =[ $walk22, tbaby_walk23 ] {ai_walk(2);}; +void() tbaby_walk23 =[ $walk23, tbaby_walk24 ] {ai_walk(2);}; +void() tbaby_walk24 =[ $walk24, tbaby_walk25 ] {ai_walk(2);}; +void() tbaby_walk25 =[ $walk25, tbaby_walk1 ] {ai_walk(2);}; + +void() tbaby_run1 =[ $run1, tbaby_run2 ] {ai_face();}; +void() tbaby_run2 =[ $run2, tbaby_run3 ] {ai_face();}; +void() tbaby_run3 =[ $run3, tbaby_run4 ] {ai_face();}; +void() tbaby_run4 =[ $run4, tbaby_run5 ] {ai_face();}; +void() tbaby_run5 =[ $run5, tbaby_run6 ] {ai_face();}; +void() tbaby_run6 =[ $run6, tbaby_run7 ] {ai_face();}; +void() tbaby_run7 =[ $run7, tbaby_run8 ] {ai_face();}; +void() tbaby_run8 =[ $run8, tbaby_run9 ] {ai_face();}; +void() tbaby_run9 =[ $run9, tbaby_run10 ] {ai_face();}; +void() tbaby_run10 =[ $run10, tbaby_run11 ] {ai_face();}; +void() tbaby_run11 =[ $run11, tbaby_run12 ] {ai_run(2);}; +void() tbaby_run12 =[ $run12, tbaby_run13 ] {ai_run(2);}; +void() tbaby_run13 =[ $run13, tbaby_run14 ] {ai_run(2);}; +void() tbaby_run14 =[ $run14, tbaby_run15 ] {ai_run(2);}; +void() tbaby_run15 =[ $run15, tbaby_run16 ] {ai_run(2);}; +void() tbaby_run16 =[ $run16, tbaby_run17 ] {ai_run(2);}; +void() tbaby_run17 =[ $run17, tbaby_run18 ] {ai_run(2);}; +void() tbaby_run18 =[ $run18, tbaby_run19 ] {ai_run(2);}; +void() tbaby_run19 =[ $run19, tbaby_run20 ] {ai_run(2);}; +void() tbaby_run20 =[ $run20, tbaby_run21 ] {ai_run(2);}; +void() tbaby_run21 =[ $run21, tbaby_run22 ] {ai_run(2);}; +void() tbaby_run22 =[ $run22, tbaby_run23 ] {ai_run(2);}; +void() tbaby_run23 =[ $run23, tbaby_run24 ] {ai_run(2);}; +void() tbaby_run24 =[ $run24, tbaby_run25 ] {ai_run(2);}; +void() tbaby_run25 =[ $run25, tbaby_run1 ] {ai_run(2);}; + + +//============================================================================ + + +void() tbaby_jump1; + +void() Tar_JumpTouch = +{ + local float ldmg; + + if (other.takedamage && other.classname != self.classname) + { + if ( vlen(self.velocity) > 400 ) + { + ldmg = 10 + 10*random(); + T_Damage (other, self, self, ldmg, MOD_TARBABY); + sound (self, CHAN_WEAPON, "blob/hit1.wav", 1, ATTN_NORM); + } + } + else + sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM); + + + if (!checkbottom(self)) + { + if (self.flags & FL_ONGROUND) + { // jump randomly to not get hung up + self.touch = SUB_Null; + self.think = tbaby_run1; + self.movetype = MOVETYPE_STEP; + self.nextthink = time + 0.1; + } + return; // not on ground yet + } + + self.touch = SUB_Null; + self.think = tbaby_jump1; + self.nextthink = time + 0.1; +}; + +void() tbaby_jump5; + +void() tbaby_fly1 =[ $fly1, tbaby_fly2 ] {}; +void() tbaby_fly2 =[ $fly2, tbaby_fly3 ] {}; +void() tbaby_fly3 =[ $fly3, tbaby_fly4 ] {}; +void() tbaby_fly4 =[ $fly4, tbaby_fly1 ] { +self.cnt = self.cnt + 1; +if (self.cnt == 4) +{ +//dprint ("spawn hop\n"); +tbaby_jump5 (); +} +}; + +void() tbaby_jump1 =[ $jump1, tbaby_jump2 ] {ai_face();}; +void() tbaby_jump2 =[ $jump2, tbaby_jump3 ] {ai_face();}; +void() tbaby_jump3 =[ $jump3, tbaby_jump4 ] {ai_face();}; +void() tbaby_jump4 =[ $jump4, tbaby_jump5 ] {ai_face();}; +void() tbaby_jump5 =[ $jump5, tbaby_jump6 ] +{ + self.movetype = MOVETYPE_BOUNCE; + self.touch = Tar_JumpTouch; + makevectors (self.angles); + self.origin_z = self.origin_z + 1; + self.velocity = v_forward * 600 + '0 0 200'; + self.velocity_z = self.velocity_z + random()*150; + if (self.flags & FL_ONGROUND) + self.flags = self.flags - FL_ONGROUND; + self.cnt = 0; +}; +void() tbaby_jump6 =[ $jump6,tbaby_fly1 ] {}; + + + +//============================================================================= + +void() tbaby_die1 =[ $exp, tbaby_die2 ] { +self.takedamage = DAMAGE_NO; +}; +void() tbaby_die2 =[ $exp, tbaby_run1 ] +{ + T_RadiusDamage (self, self, 120, 160, world, MOD_TARBABY); + + sound (self, CHAN_VOICE, "blob/death1.wav", 1, ATTN_NORM); + self.origin = self.origin - 8*normalize(self.velocity); + + TE_tarexplosion(self.origin); + CreateExplosion(self.origin); + remove(self); +}; + +//============================================================================= + + +/*QUAKED monster_tarbaby (1 0 0) (-16 -16 -24) (16 16 24) Ambush +*/ +void() monster_tarbaby = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/tarbaby.mdl"); + + precache_sound2 ("blob/death1.wav"); + precache_sound2 ("blob/hit1.wav"); + precache_sound2 ("blob/land1.wav"); + precache_sound2 ("blob/sight1.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/tarbaby.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 80; + + self.th_stand = tbaby_stand1; + self.th_walk = tbaby_walk1; + self.th_run = tbaby_run1; + self.th_missile = tbaby_jump1; + self.th_melee = tbaby_jump1; + self.th_die = tbaby_die1; + + walkmonster_start (); +}; + diff --git a/r17/Revamped src/Revamped QC/quakemons/wizard.qc b/r17/Revamped src/Revamped QC/quakemons/wizard.qc new file mode 100755 index 00000000..fa38681a --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/wizard.qc @@ -0,0 +1,320 @@ +/* +============================================================================== + +WIZARD + +============================================================================== +*/ + +$cd id1/models/a_wizard +$origin 0 0 24 +$base wizbase +$skin wizbase + +$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8 +$frame hover9 hover10 hover11 hover12 hover13 hover14 hover15 + +$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10 +$frame fly11 fly12 fly13 fly14 + +$frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7 +$frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13 + +$frame pain1 pain2 pain3 pain4 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 + +/* +============================================================================== + +WIZARD + +If the player moves behind cover before the missile is launched, launch it +at the last visible spot with no velocity leading, in hopes that the player +will duck back out and catch it. +============================================================================== +*/ + +void() wiz_run1; +void() wiz_side1; + +/* +================= +WizardCheckAttack +================= +*/ +BOOL(float enemy_range) WizardCheckAttack = +{ + local vector spot1, spot2; + local entity targ; + local float chance; + + if (time < self.attack_finished) + return FALSE; + + if (enemy_range == RANGE_FAR) + { + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + wiz_run1 (); + } + return FALSE; + } + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + traceline (spot1, spot2, FALSE, self); + + if (trace_ent != targ) + { // don't have a clear shot, so move to a side + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + wiz_run1 (); + } + return FALSE; + } + + if (enemy_range == RANGE_MELEE) + chance = 0.9; + else if (enemy_range == RANGE_NEAR) + chance = 0.6; + else if (enemy_range == RANGE_MID) + chance = 0.2; + else + chance = 0; + + if (random () < chance) + { + self.attack_state = AS_MISSILE; + return TRUE; + } + + if (enemy_range == RANGE_MID) + { + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + wiz_run1 (); + } + } + else + { + if (self.attack_state != AS_SLIDING) + { + self.attack_state = AS_SLIDING; + wiz_side1 (); + } + } + + return FALSE; +}; + +/* +================= +WizardAttackFinished +================= +*/ +void() WizardAttackFinished = +{ + if (range(self.enemy) >= RANGE_MID || !visible(self.enemy)) + { + self.attack_state = AS_STRAIGHT; + self.think = wiz_run1; + } + else + { + self.attack_state = AS_SLIDING; + self.think = wiz_side1; + } +}; + +/* +============================================================================== + +FAST ATTACKS + +============================================================================== +*/ + +void(float side) Wiz_FastFire = +{ + local vector org, vec; + + muzzleflash(); + sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM); + + makevectors (self.angles); + org = self.origin + '0 0 30' + v_forward*14 + v_right*side*14; + vec = normalize(self.enemy.origin - v_right*side*13 - org) * 600; + + PRJ_FireProjectile (self, "progs/w_spike.mdl", org, vec, PE_WIZSPIKE, 9, MOD_WIZARD, 6); +}; + +void() Wiz_idlesound = +{ + local float wr; + + if (self.wizardidle < time) + { + wr = random(); + + if (wr > 0.9) + sound (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE); + else if (wr < 0.3) + sound (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE); + + self.wizardidle = time + 2; + } + + return; +}; + +void() wiz_stand1 =[ $hover1, wiz_stand2 ] {ai_stand();}; +void() wiz_stand2 =[ $hover2, wiz_stand3 ] {ai_stand();}; +void() wiz_stand3 =[ $hover3, wiz_stand4 ] {ai_stand();}; +void() wiz_stand4 =[ $hover4, wiz_stand5 ] {ai_stand();}; +void() wiz_stand5 =[ $hover5, wiz_stand6 ] {ai_stand();}; +void() wiz_stand6 =[ $hover6, wiz_stand7 ] {ai_stand();}; +void() wiz_stand7 =[ $hover7, wiz_stand8 ] {ai_stand();}; +void() wiz_stand8 =[ $hover8, wiz_stand1 ] {ai_stand();}; + +void() wiz_walk1 =[ $hover1, wiz_walk2 ] {ai_walk(8); +Wiz_idlesound();}; +void() wiz_walk2 =[ $hover2, wiz_walk3 ] {ai_walk(8);}; +void() wiz_walk3 =[ $hover3, wiz_walk4 ] {ai_walk(8);}; +void() wiz_walk4 =[ $hover4, wiz_walk5 ] {ai_walk(8);}; +void() wiz_walk5 =[ $hover5, wiz_walk6 ] {ai_walk(8);}; +void() wiz_walk6 =[ $hover6, wiz_walk7 ] {ai_walk(8);}; +void() wiz_walk7 =[ $hover7, wiz_walk8 ] {ai_walk(8);}; +void() wiz_walk8 =[ $hover8, wiz_walk1 ] {ai_walk(8);}; + +void() wiz_side1 =[ $hover1, wiz_side2 ] {ai_run(8); +Wiz_idlesound();}; +void() wiz_side2 =[ $hover2, wiz_side3 ] {ai_run(8);}; +void() wiz_side3 =[ $hover3, wiz_side4 ] {ai_run(8);}; +void() wiz_side4 =[ $hover4, wiz_side5 ] {ai_run(8);}; +void() wiz_side5 =[ $hover5, wiz_side6 ] {ai_run(8);}; +void() wiz_side6 =[ $hover6, wiz_side7 ] {ai_run(8);}; +void() wiz_side7 =[ $hover7, wiz_side8 ] {ai_run(8);}; +void() wiz_side8 =[ $hover8, wiz_side1 ] {ai_run(8);}; + +void() wiz_run1 =[ $fly1, wiz_run2 ] {ai_run(16); +Wiz_idlesound(); +}; +void() wiz_run2 =[ $fly2, wiz_run3 ] {ai_run(16);}; +void() wiz_run3 =[ $fly3, wiz_run4 ] {ai_run(16);}; +void() wiz_run4 =[ $fly4, wiz_run5 ] {ai_run(16);}; +void() wiz_run5 =[ $fly5, wiz_run6 ] {ai_run(16);}; +void() wiz_run6 =[ $fly6, wiz_run7 ] {ai_run(16);}; +void() wiz_run7 =[ $fly7, wiz_run8 ] {ai_run(16);}; +void() wiz_run8 =[ $fly8, wiz_run9 ] {ai_run(16);}; +void() wiz_run9 =[ $fly9, wiz_run10 ] {ai_run(16);}; +void() wiz_run10 =[ $fly10, wiz_run11 ] {ai_run(16);}; +void() wiz_run11 =[ $fly11, wiz_run12 ] {ai_run(16);}; +void() wiz_run12 =[ $fly12, wiz_run13 ] {ai_run(16);}; +void() wiz_run13 =[ $fly13, wiz_run14 ] {ai_run(16);}; +void() wiz_run14 =[ $fly14, wiz_run1 ] {ai_run(16);}; + +void() wiz_fast1 =[ $magatt1, wiz_fast2 ] {ai_face();}; +void() wiz_fast2 =[ $magatt2, wiz_fast3 ] {ai_face();}; +void() wiz_fast3 =[ $magatt3, wiz_fast4 ] {ai_face();}; +void() wiz_fast4 =[ $magatt4, wiz_fast5 ] {ai_face();Wiz_FastFire(-1);}; +void() wiz_fast5 =[ $magatt5, wiz_fast6 ] {ai_face();}; +void() wiz_fast6 =[ $magatt6, wiz_fast7 ] {ai_face();}; +void() wiz_fast7 =[ $magatt5, wiz_fast8 ] {ai_face();}; +void() wiz_fast8 =[ $magatt4, wiz_fast9 ] {ai_face();}; +void() wiz_fast9 =[ $magatt3, wiz_fast10 ] {ai_face();Wiz_FastFire(1);}; +void() wiz_fast10 =[ $magatt2, wiz_run1 ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();}; + +void() wiz_pain1 =[ $pain1, wiz_pain2 ] {}; +void() wiz_pain2 =[ $pain2, wiz_pain3 ] {}; +void() wiz_pain3 =[ $pain3, wiz_pain4 ] {}; +void() wiz_pain4 =[ $pain4, wiz_run1 ] {}; + +void() wiz_death1 =[ $death1, wiz_death2 ] { + +self.velocity_x = -200 + 400*random(); +self.velocity_y = -200 + 400*random(); +self.velocity_z = 100 + 100*random(); +self.flags = self.flags - (self.flags & FL_ONGROUND); +sound (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM); +}; +void() wiz_death2 =[ $death2, wiz_death3 ] {}; +void() wiz_death3 =[ $death3, wiz_death4 ]{self.solid = SOLID_NOT;}; +void() wiz_death4 =[ $death4, wiz_death5 ] {}; +void() wiz_death5 =[ $death5, wiz_death6 ] {}; +void() wiz_death6 =[ $death6, wiz_death7 ] {}; +void() wiz_death7 =[ $death7, wiz_death8 ] {}; +void() wiz_death8 =[ $death8, wiz_death8 ] {}; + +void() wiz_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_wizard.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + return; + } + + wiz_death1 (); +}; + + +void(entity attacker, float damage) Wiz_Pain = +{ + sound (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM); + if (random()*70 > damage) + return; // didn't flinch + + wiz_pain1 (); +}; + +/*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_wizard = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/wizard.mdl"); + precache_model ("progs/h_wizard.mdl"); + precache_model ("progs/w_spike.mdl"); + + precache_sound ("wizard/hit.wav"); // used by c code + precache_sound ("wizard/wattack.wav"); + precache_sound ("wizard/wdeath.wav"); + precache_sound ("wizard/widle1.wav"); + precache_sound ("wizard/widle2.wav"); + precache_sound ("wizard/wpain.wav"); + precache_sound ("wizard/wsight.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/wizard.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 80; + + self.th_stand = wiz_stand1; + self.th_walk = wiz_walk1; + self.th_run = wiz_run1; + self.th_missile = wiz_fast1; + self.th_pain = Wiz_Pain; + self.th_die = wiz_die; + + flymonster_start (); +}; + \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/quakemons/zombie.qc b/r17/Revamped src/Revamped QC/quakemons/zombie.qc new file mode 100755 index 00000000..9a1c0a46 --- /dev/null +++ b/r17/Revamped src/Revamped QC/quakemons/zombie.qc @@ -0,0 +1,473 @@ +/* +============================================================================== + +ZOMBIE + +============================================================================== +*/ +$cd id1/models/zombie + +$origin 0 0 24 + +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 +$frame stand9 stand10 stand11 stand12 stand13 stand14 stand15 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11 +$frame walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 +$frame run13 run14 run15 run16 run17 run18 + +$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8 atta9 atta10 atta11 +$frame atta12 atta13 + +$frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8 attb9 attb10 attb11 +$frame attb12 attb13 attb14 + +$frame attc1 attc2 attc3 attc4 attc5 attc6 attc7 attc8 attc9 attc10 attc11 +$frame attc12 + +$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10 +$frame paina11 paina12 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10 +$frame painb11 painb12 painb13 painb14 painb15 painb16 painb17 painb18 painb19 +$frame painb20 painb21 painb22 painb23 painb24 painb25 painb26 painb27 painb28 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10 +$frame painc11 painc12 painc13 painc14 painc15 painc16 painc17 painc18 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10 +$frame paind11 paind12 paind13 + +$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10 +$frame paine11 paine12 paine13 paine14 paine15 paine16 paine17 paine18 paine19 +$frame paine20 paine21 paine22 paine23 paine24 paine25 paine26 paine27 paine28 +$frame paine29 paine30 + +$frame cruc_1 cruc_2 cruc_3 cruc_4 cruc_5 cruc_6 + +float SPAWN_CRUCIFIED = 1; + +//============================================================================= + +void() zombie_stand1 =[ $stand1, zombie_stand2 ] {ai_stand();}; +void() zombie_stand2 =[ $stand2, zombie_stand3 ] {ai_stand();}; +void() zombie_stand3 =[ $stand3, zombie_stand4 ] {ai_stand();}; +void() zombie_stand4 =[ $stand4, zombie_stand5 ] {ai_stand();}; +void() zombie_stand5 =[ $stand5, zombie_stand6 ] {ai_stand();}; +void() zombie_stand6 =[ $stand6, zombie_stand7 ] {ai_stand();}; +void() zombie_stand7 =[ $stand7, zombie_stand8 ] {ai_stand();}; +void() zombie_stand8 =[ $stand8, zombie_stand9 ] {ai_stand();}; +void() zombie_stand9 =[ $stand9, zombie_stand10 ] {ai_stand();}; +void() zombie_stand10 =[ $stand10, zombie_stand11 ] {ai_stand();}; +void() zombie_stand11 =[ $stand11, zombie_stand12 ] {ai_stand();}; +void() zombie_stand12 =[ $stand12, zombie_stand13 ] {ai_stand();}; +void() zombie_stand13 =[ $stand13, zombie_stand14 ] {ai_stand();}; +void() zombie_stand14 =[ $stand14, zombie_stand15 ] {ai_stand();}; +void() zombie_stand15 =[ $stand15, zombie_stand1 ] {ai_stand();}; + +void() zombie_cruc1 = [ $cruc_1, zombie_cruc2 ] { +if (random() < 0.1) + sound (self, CHAN_VOICE, "zombie/idle_w2.wav", 1, ATTN_STATIC);}; +void() zombie_cruc2 = [ $cruc_2, zombie_cruc3 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc3 = [ $cruc_3, zombie_cruc4 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc4 = [ $cruc_4, zombie_cruc5 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc5 = [ $cruc_5, zombie_cruc6 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc6 = [ $cruc_6, zombie_cruc1 ] {self.nextthink = time + 0.1 + random()*0.1;}; + +void() zombie_walk1 =[ $walk1, zombie_walk2 ] {ai_walk(0);}; +void() zombie_walk2 =[ $walk2, zombie_walk3 ] {ai_walk(2);}; +void() zombie_walk3 =[ $walk3, zombie_walk4 ] {ai_walk(3);}; +void() zombie_walk4 =[ $walk4, zombie_walk5 ] {ai_walk(2);}; +void() zombie_walk5 =[ $walk5, zombie_walk6 ] {ai_walk(1);}; +void() zombie_walk6 =[ $walk6, zombie_walk7 ] {ai_walk(0);}; +void() zombie_walk7 =[ $walk7, zombie_walk8 ] {ai_walk(0);}; +void() zombie_walk8 =[ $walk8, zombie_walk9 ] {ai_walk(0);}; +void() zombie_walk9 =[ $walk9, zombie_walk10 ] {ai_walk(0);}; +void() zombie_walk10 =[ $walk10, zombie_walk11 ] {ai_walk(0);}; +void() zombie_walk11 =[ $walk11, zombie_walk12 ] {ai_walk(2);}; +void() zombie_walk12 =[ $walk12, zombie_walk13 ] {ai_walk(2);}; +void() zombie_walk13 =[ $walk13, zombie_walk14 ] {ai_walk(1);}; +void() zombie_walk14 =[ $walk14, zombie_walk15 ] {ai_walk(0);}; +void() zombie_walk15 =[ $walk15, zombie_walk16 ] {ai_walk(0);}; +void() zombie_walk16 =[ $walk16, zombie_walk17 ] {ai_walk(0);}; +void() zombie_walk17 =[ $walk17, zombie_walk18 ] {ai_walk(0);}; +void() zombie_walk18 =[ $walk18, zombie_walk19 ] {ai_walk(0);}; +void() zombie_walk19 =[ $walk19, zombie_walk1 ] { +ai_walk(0); +if (random() < 0.2) + sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);}; + +void() zombie_run1 =[ $run1, zombie_run2 ] {ai_run(1);self.inpain = 0;}; +void() zombie_run2 =[ $run2, zombie_run3 ] {ai_run(1);}; +void() zombie_run3 =[ $run3, zombie_run4 ] {ai_run(0);}; +void() zombie_run4 =[ $run4, zombie_run5 ] {ai_run(1);}; +void() zombie_run5 =[ $run5, zombie_run6 ] {ai_run(2);}; +void() zombie_run6 =[ $run6, zombie_run7 ] {ai_run(3);}; +void() zombie_run7 =[ $run7, zombie_run8 ] {ai_run(4);}; +void() zombie_run8 =[ $run8, zombie_run9 ] {ai_run(4);}; +void() zombie_run9 =[ $run9, zombie_run10 ] {ai_run(2);}; +void() zombie_run10 =[ $run10, zombie_run11 ] {ai_run(0);}; +void() zombie_run11 =[ $run11, zombie_run12 ] {ai_run(0);}; +void() zombie_run12 =[ $run12, zombie_run13 ] {ai_run(0);}; +void() zombie_run13 =[ $run13, zombie_run14 ] {ai_run(2);}; +void() zombie_run14 =[ $run14, zombie_run15 ] {ai_run(4);}; +void() zombie_run15 =[ $run15, zombie_run16 ] {ai_run(6);}; +void() zombie_run16 =[ $run16, zombie_run17 ] {ai_run(7);}; +void() zombie_run17 =[ $run17, zombie_run18 ] {ai_run(3);}; +void() zombie_run18 =[ $run18, zombie_run1 ] { +ai_run(8); +if (random() < 0.2) + sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE); +if (random() > 0.8) + sound (self, CHAN_VOICE, "zombie/z_idle1.wav", 1, ATTN_IDLE); +}; + +/* +============================================================================= + +ATTACKS + +============================================================================= +*/ + +/* +================ +ZombieFireGrenade +================ +*/ +void(vector st) ZombieFireGrenade = +{ + local vector org, vel; + + sound (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM); + + org = self.origin + st_x * v_forward + st_y * v_right + (st_z - 24) * v_up; + vel = normalize(self.enemy.origin - org) * 600; + vel_z = 200; + PRJ_FireProjectile(self, "progs/zom_gib.mdl", org, vel, PE_ZOMBIEGIB, 10, MOD_ZOMBIE, 2.5); + PRJ_SetTossedProjectile(); +}; + + +void() zombie_atta1 =[ $atta1, zombie_atta2 ] {ai_face();}; +void() zombie_atta2 =[ $atta2, zombie_atta3 ] {ai_face();}; +void() zombie_atta3 =[ $atta3, zombie_atta4 ] {ai_face();}; +void() zombie_atta4 =[ $atta4, zombie_atta5 ] {ai_face();}; +void() zombie_atta5 =[ $atta5, zombie_atta6 ] {ai_face();}; +void() zombie_atta6 =[ $atta6, zombie_atta7 ] {ai_face();}; +void() zombie_atta7 =[ $atta7, zombie_atta8 ] {ai_face();}; +void() zombie_atta8 =[ $atta8, zombie_atta9 ] {ai_face();}; +void() zombie_atta9 =[ $atta9, zombie_atta10 ] {ai_face();}; +void() zombie_atta10 =[ $atta10, zombie_atta11 ] {ai_face();}; +void() zombie_atta11 =[ $atta11, zombie_atta12 ] {ai_face();}; +void() zombie_atta12 =[ $atta12, zombie_atta13 ] {ai_face();}; +void() zombie_atta13 =[ $atta13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -22 30');}; + +void() zombie_attb1 =[ $attb1, zombie_attb2 ] {ai_face();}; +void() zombie_attb2 =[ $attb2, zombie_attb3 ] {ai_face();}; +void() zombie_attb3 =[ $attb3, zombie_attb4 ] {ai_face();}; +void() zombie_attb4 =[ $attb4, zombie_attb5 ] {ai_face();}; +void() zombie_attb5 =[ $attb5, zombie_attb6 ] {ai_face();}; +void() zombie_attb6 =[ $attb6, zombie_attb7 ] {ai_face();}; +void() zombie_attb7 =[ $attb7, zombie_attb8 ] {ai_face();}; +void() zombie_attb8 =[ $attb8, zombie_attb9 ] {ai_face();}; +void() zombie_attb9 =[ $attb9, zombie_attb10 ] {ai_face();}; +void() zombie_attb10 =[ $attb10, zombie_attb11 ] {ai_face();}; +void() zombie_attb11 =[ $attb11, zombie_attb12 ] {ai_face();}; +void() zombie_attb12 =[ $attb12, zombie_attb13 ] {ai_face();}; +void() zombie_attb13 =[ $attb13, zombie_attb14 ] {ai_face();}; +void() zombie_attb14 =[ $attb13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -24 29');}; + +void() zombie_attc1 =[ $attc1, zombie_attc2 ] {ai_face();}; +void() zombie_attc2 =[ $attc2, zombie_attc3 ] {ai_face();}; +void() zombie_attc3 =[ $attc3, zombie_attc4 ] {ai_face();}; +void() zombie_attc4 =[ $attc4, zombie_attc5 ] {ai_face();}; +void() zombie_attc5 =[ $attc5, zombie_attc6 ] {ai_face();}; +void() zombie_attc6 =[ $attc6, zombie_attc7 ] {ai_face();}; +void() zombie_attc7 =[ $attc7, zombie_attc8 ] {ai_face();}; +void() zombie_attc8 =[ $attc8, zombie_attc9 ] {ai_face();}; +void() zombie_attc9 =[ $attc9, zombie_attc10 ] {ai_face();}; +void() zombie_attc10 =[ $attc10, zombie_attc11 ] {ai_face();}; +void() zombie_attc11 =[ $attc11, zombie_attc12 ] {ai_face();}; +void() zombie_attc12 =[ $attc12, zombie_run1 ] {ai_face();ZombieFireGrenade('-12 -19 29');}; + +void() zombie_missile = +{ + local float r; + + r = random(); + + if (r < 0.3) + zombie_atta1 (); + else if (r < 0.6) + zombie_attb1 (); + else + zombie_attc1 (); +}; + + +/* +============================================================================= + +PAIN + +============================================================================= +*/ + +void() zombie_paina1 =[ $paina1, zombie_paina2 ] {sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);}; +void() zombie_paina2 =[ $paina2, zombie_paina3 ] {ai_painforward(3);}; +void() zombie_paina3 =[ $paina3, zombie_paina4 ] {ai_painforward(1);}; +void() zombie_paina4 =[ $paina4, zombie_paina5 ] {ai_pain(1);}; +void() zombie_paina5 =[ $paina5, zombie_paina6 ] {ai_pain(3);}; +void() zombie_paina6 =[ $paina6, zombie_paina7 ] {ai_pain(1);}; +void() zombie_paina7 =[ $paina7, zombie_paina8 ] {}; +void() zombie_paina8 =[ $paina8, zombie_paina9 ] {}; +void() zombie_paina9 =[ $paina9, zombie_paina10 ] {}; +void() zombie_paina10 =[ $paina10, zombie_paina11 ] {}; +void() zombie_paina11 =[ $paina11, zombie_paina12 ] {}; +void() zombie_paina12 =[ $paina12, zombie_run1 ] {}; + +void() zombie_painb1 =[ $painb1, zombie_painb2 ] {sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);}; +void() zombie_painb2 =[ $painb2, zombie_painb3 ] {ai_pain(2);}; +void() zombie_painb3 =[ $painb3, zombie_painb4 ] {ai_pain(8);}; +void() zombie_painb4 =[ $painb4, zombie_painb5 ] {ai_pain(6);}; +void() zombie_painb5 =[ $painb5, zombie_painb6 ] {ai_pain(2);}; +void() zombie_painb6 =[ $painb6, zombie_painb7 ] {}; +void() zombie_painb7 =[ $painb7, zombie_painb8 ] {}; +void() zombie_painb8 =[ $painb8, zombie_painb9 ] {}; +void() zombie_painb9 =[ $painb9, zombie_painb10 ] {sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);}; +void() zombie_painb10 =[ $painb10, zombie_painb11 ] {}; +void() zombie_painb11 =[ $painb11, zombie_painb12 ] {}; +void() zombie_painb12 =[ $painb12, zombie_painb13 ] {}; +void() zombie_painb13 =[ $painb13, zombie_painb14 ] {}; +void() zombie_painb14 =[ $painb14, zombie_painb15 ] {}; +void() zombie_painb15 =[ $painb15, zombie_painb16 ] {}; +void() zombie_painb16 =[ $painb16, zombie_painb17 ] {}; +void() zombie_painb17 =[ $painb17, zombie_painb18 ] {}; +void() zombie_painb18 =[ $painb18, zombie_painb19 ] {}; +void() zombie_painb19 =[ $painb19, zombie_painb20 ] {}; +void() zombie_painb20 =[ $painb20, zombie_painb21 ] {}; +void() zombie_painb21 =[ $painb21, zombie_painb22 ] {}; +void() zombie_painb22 =[ $painb22, zombie_painb23 ] {}; +void() zombie_painb23 =[ $painb23, zombie_painb24 ] {}; +void() zombie_painb24 =[ $painb24, zombie_painb25 ] {}; +void() zombie_painb25 =[ $painb25, zombie_painb26 ] {ai_painforward(1);}; +void() zombie_painb26 =[ $painb26, zombie_painb27 ] {}; +void() zombie_painb27 =[ $painb27, zombie_painb28 ] {}; +void() zombie_painb28 =[ $painb28, zombie_run1 ] {}; + +void() zombie_painc1 =[ $painc1, zombie_painc2 ] {sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);}; +void() zombie_painc2 =[ $painc2, zombie_painc3 ] {}; +void() zombie_painc3 =[ $painc3, zombie_painc4 ] {ai_pain(3);}; +void() zombie_painc4 =[ $painc4, zombie_painc5 ] {ai_pain(1);}; +void() zombie_painc5 =[ $painc5, zombie_painc6 ] {}; +void() zombie_painc6 =[ $painc6, zombie_painc7 ] {}; +void() zombie_painc7 =[ $painc7, zombie_painc8 ] {}; +void() zombie_painc8 =[ $painc8, zombie_painc9 ] {}; +void() zombie_painc9 =[ $painc9, zombie_painc10 ] {}; +void() zombie_painc10 =[ $painc10, zombie_painc11 ] {}; +void() zombie_painc11 =[ $painc11, zombie_painc12 ] {ai_painforward(1);}; +void() zombie_painc12 =[ $painc12, zombie_painc13 ] {ai_painforward(1);}; +void() zombie_painc13 =[ $painc13, zombie_painc14 ] {}; +void() zombie_painc14 =[ $painc14, zombie_painc15 ] {}; +void() zombie_painc15 =[ $painc15, zombie_painc16 ] {}; +void() zombie_painc16 =[ $painc16, zombie_painc17 ] {}; +void() zombie_painc17 =[ $painc17, zombie_painc18 ] {}; +void() zombie_painc18 =[ $painc18, zombie_run1 ] {}; + +void() zombie_paind1 =[ $paind1, zombie_paind2 ] {sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);}; +void() zombie_paind2 =[ $paind2, zombie_paind3 ] {}; +void() zombie_paind3 =[ $paind3, zombie_paind4 ] {}; +void() zombie_paind4 =[ $paind4, zombie_paind5 ] {}; +void() zombie_paind5 =[ $paind5, zombie_paind6 ] {}; +void() zombie_paind6 =[ $paind6, zombie_paind7 ] {}; +void() zombie_paind7 =[ $paind7, zombie_paind8 ] {}; +void() zombie_paind8 =[ $paind8, zombie_paind9 ] {}; +void() zombie_paind9 =[ $paind9, zombie_paind10 ] {ai_pain(1);}; +void() zombie_paind10 =[ $paind10, zombie_paind11 ] {}; +void() zombie_paind11 =[ $paind11, zombie_paind12 ] {}; +void() zombie_paind12 =[ $paind12, zombie_paind13 ] {}; +void() zombie_paind13 =[ $paind13, zombie_run1 ] {}; + +void() zombie_paine1 =[ $paine1, zombie_paine2 ] { +sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM); +self.health = 60; +}; +void() zombie_paine2 =[ $paine2, zombie_paine3 ] {ai_pain(8);}; +void() zombie_paine3 =[ $paine3, zombie_paine4 ] {ai_pain(5);}; +void() zombie_paine4 =[ $paine4, zombie_paine5 ] {ai_pain(3);}; +void() zombie_paine5 =[ $paine5, zombie_paine6 ] {ai_pain(1);}; +void() zombie_paine6 =[ $paine6, zombie_paine7 ] {ai_pain(2);}; +void() zombie_paine7 =[ $paine7, zombie_paine8 ] {ai_pain(1);}; +void() zombie_paine8 =[ $paine8, zombie_paine9 ] {ai_pain(1);}; +void() zombie_paine9 =[ $paine9, zombie_paine10 ] {ai_pain(2);}; +void() zombie_paine10 =[ $paine10, zombie_paine11 ] { +sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM); +self.solid = SOLID_NOT; +}; +void() zombie_paine11 =[ $paine11, zombie_paine12 ] {self.nextthink = time + 5;self.health = 60;}; +void() zombie_paine12 =[ $paine12, zombie_paine13 ]{ +// see if ok to stand up +self.health = 60; +sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE); +self.solid = SOLID_SLIDEBOX; +if (!walkmove (0, 0)) +{ + self.think = zombie_paine11; + self.solid = SOLID_NOT; + return; +} +}; +void() zombie_paine13 =[ $paine13, zombie_paine14 ] {}; +void() zombie_paine14 =[ $paine14, zombie_paine15 ] {}; +void() zombie_paine15 =[ $paine15, zombie_paine16 ] {}; +void() zombie_paine16 =[ $paine16, zombie_paine17 ] {}; +void() zombie_paine17 =[ $paine17, zombie_paine18 ] {}; +void() zombie_paine18 =[ $paine18, zombie_paine19 ] {}; +void() zombie_paine19 =[ $paine19, zombie_paine20 ] {}; +void() zombie_paine20 =[ $paine20, zombie_paine21 ] {}; +void() zombie_paine21 =[ $paine21, zombie_paine22 ] {}; +void() zombie_paine22 =[ $paine22, zombie_paine23 ] {}; +void() zombie_paine23 =[ $paine23, zombie_paine24 ] {}; +void() zombie_paine24 =[ $paine24, zombie_paine25 ] {}; +void() zombie_paine25 =[ $paine25, zombie_paine26 ] {ai_painforward(5);}; +void() zombie_paine26 =[ $paine26, zombie_paine27 ] {ai_painforward(3);}; +void() zombie_paine27 =[ $paine27, zombie_paine28 ] {ai_painforward(1);}; +void() zombie_paine28 =[ $paine28, zombie_paine29 ] {ai_pain(1);}; +void() zombie_paine29 =[ $paine29, zombie_paine30 ] {}; +void() zombie_paine30 =[ $paine30, zombie_run1 ] {}; + +void() zombie_die = +{ + sound (self, CHAN_VOICE, "zombie/z_gib.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_zombie.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); +}; + +/* +================= +zombie_pain + +Zombies can only be killed (gibbed) by doing 60 hit points of damage +in a single frame (rockets, grenades, quad shotgun, quad nailgun). + +A hit of 25 points or more (super shotgun, quad nailgun) will allways put it +down to the ground. + +A hit of from 10 to 40 points in one frame will cause it to go down if it +has been twice in two seconds, otherwise it goes into one of the four +fast pain frames. + +A hit of less than 10 points of damage (winged by a shotgun) will be ignored. + +FIXME: don't use pain_finished because of nightmare hack +================= +*/ +void(entity attacker, float take) zombie_pain = +{ + local float r; + + self.health = 60; // allways reset health + + if (take < 9) + return; // totally ignore + + if (self.inpain == 2) + return; // down on ground, so don't reset any counters + +// go down immediately if a big enough hit + if (take >= 25) + { + self.inpain = 2; + zombie_paine1 (); + return; + } + + if (self.inpain) + { +// if hit again in next gre seconds while not in pain frames, definately drop + self.pain_finished = time + 3; + return; // currently going through an animation, don't change + } + + if (self.pain_finished > time) + { +// hit again, so drop down + self.inpain = 2; + zombie_paine1 (); + return; + } + +// gp into one of the fast pain animations + self.inpain = 1; + + r = random(); + if (r < 0.25) + zombie_paina1 (); + else if (r < 0.5) + zombie_painb1 (); + else if (r < 0.75) + zombie_painc1 (); + else + zombie_paind1 (); +}; + +//============================================================================ + +/*QUAKED monster_zombie (1 0 0) (-16 -16 -24) (16 16 32) Crucified ambush + +If crucified, stick the bounding box 12 pixels back into a wall to look right. +*/ +void() monster_zombie = +{ + if (deathmatch) + { + remove(self); + return; + } + + precache_model ("progs/zombie.mdl"); + precache_model ("progs/h_zombie.mdl"); + precache_model ("progs/zom_gib.mdl"); + + precache_sound ("zombie/z_idle.wav"); + precache_sound ("zombie/z_idle1.wav"); + precache_sound ("zombie/z_shot1.wav"); + precache_sound ("zombie/z_gib.wav"); + precache_sound ("zombie/z_pain.wav"); + precache_sound ("zombie/z_pain1.wav"); + precache_sound ("zombie/z_fall.wav"); + precache_sound ("zombie/z_miss.wav"); + precache_sound ("zombie/z_hit.wav"); + precache_sound ("zombie/idle_w2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/zombie.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 60; + + self.th_stand = zombie_stand1; + self.th_walk = zombie_walk1; + self.th_run = zombie_run1; + self.th_pain = zombie_pain; + self.th_die = zombie_die; + self.th_missile = zombie_missile; + + if (self.spawnflags & SPAWN_CRUCIFIED) + { + self.movetype = MOVETYPE_NONE; + zombie_cruc1 (); + } + else + walkmonster_start(); +}; diff --git a/r17/Revamped src/Revamped QC/replace.qc b/r17/Revamped src/Revamped QC/replace.qc new file mode 100755 index 00000000..849e4406 --- /dev/null +++ b/r17/Revamped src/Revamped QC/replace.qc @@ -0,0 +1,129 @@ + +// Basemod replacement ent defines +#define ENT_REPLACE(f,t) void(void) f = { self.classname = #t; t(); } +#define ENT_REPLACE_FUNC(f,t,x) void(void) f = { self.classname = #t; x(); t(); } + +// Replacement functions +void() health_setrotten = { self.spawnflags |= H_ROTTEN; }; +void() health_setmega = { self.spawnflags |= H_MEGA; }; +void() ammo_setlarge = { self.spawnflags |= WEAPON_BIG2; }; + +// -- Quake 3 entities +// weapons +ENT_REPLACE(weapon_gauntlet, weapon_supershotgun); // Gauntlet (not normally used) +ENT_REPLACE(weapon_machinegun, weapon_nailgun); // Machinegun (not normally used) +//ENT_REPLACE(weapon_shotgun, weapon_supershotgun); // Shotgun +ENT_REPLACE(weapon_plasmagun, weapon_supernailgun); // Plasma gun +ENT_REPLACE(weapon_railgun, weapon_rocketlauncher); // Railgun +ENT_REPLACE(weapon_bfg, weapon_lightning); // BFG +// holdables +ENT_REPLACE(holdable_medikit, item_health); // personal medikit +ENT_REPLACE(holdable_teleporter, info_null); // personal teleporter +// armor +ENT_REPLACE(item_armor_body, item_armorInv); // 100 armor +ENT_REPLACE(item_armor_combat, item_armor2); // 50 armor +ENT_REPLACE(item_armor_shard, info_null); // +5 armor shard +// powerups +ENT_REPLACE(item_enviro, item_artifact_envirosuit); // enviro powerup +ENT_REPLACE(item_flight, item_artifact_invisibility); // flight +ENT_REPLACE(item_haste, item_artifact_super_damage); // haste +ENT_REPLACE(item_quad, item_artifact_super_damage); // quad damage +ENT_REPLACE(item_invis, item_artifact_invisibility); // invisibility +ENT_REPLACE(item_regen, item_health); // regeneration +// health +ENT_REPLACE(item_health_large, item_health); // +50 health +ENT_REPLACE_FUNC(item_health_mega, item_health, health_setmega); // +100 health (ignore max) +ENT_REPLACE_FUNC(item_health_small, item_health, health_setrotten); // +5 health (ignore max) +// ammo +ENT_REPLACE(ammo_bullets, item_spikes); // Machinegun ammo +ENT_REPLACE(ammo_grenades, item_rockets); // Grenade launcher ammo +ENT_REPLACE(ammo_lightning, item_cells); // Lightning gun ammo +ENT_REPLACE_FUNC(ammo_slugs, item_rockets, ammo_setlarge); // Railgun ammo +ENT_REPLACE_FUNC(ammo_bfg, item_cells, ammo_setlarge); // BFG ammo +// other ents +ENT_REPLACE(misc_teleporter_dest, info_teleport_destination); // teleport destination +ENT_REPLACE(target_position, info_notnull); // "target" entity +ENT_REPLACE(info_player_intermission, info_intermission); // intermission + +// -- Quake 2 entities +// weapons +ENT_REPLACE(weapon_chaingun, weapon_supernailgun); // chaingun +ENT_REPLACE(weapon_hyperblaster, weapon_lightning); // hyperblaster +// armor +ENT_REPLACE(item_armor_jacket, item_armor1); +ENT_REPLACE(item_power_screen, item_armor2); // power screen (not used often) +ENT_REPLACE(item_power_shield, item_armorInv); // power shield + // powerups +ENT_REPLACE(item_bandolier, item_rockets, ammo_setlarge); // bandolier +ENT_REPLACE(item_breather, item_artifact_envirosuit); // underwater air breather +ENT_REPLACE(item_invulnerability, item_artifact_invulnerability); // invulnerable artifact +ENT_REPLACE(item_pack, item_rockets, ammo_setlarge); // ammo pack +ENT_REPLACE(item_silencer, item_artifact_invisibility); // weapon silencer +// health +ENT_REPLACE_FUNC(item_ancient_head, item_health, health_setmega); // ancient head (+2 max health) +ENT_REPLACE_FUNC(item_adrenaline, item_health, health_setmega); // adrenaline (+1 max health) + +// -- Half-life entities +// weapons +ENT_REPLACE(weapon_357, weapon_grenadelauncher); // 357 magnum +ENT_REPLACE(weapon_9mmAR, weapon_supernailgun); // mp5 +ENT_REPLACE(weapon_9mmhandgun, weapon_nailgun); // handgun +ENT_REPLACE(weapon_crossbow, weapon_grenadelauncher); // crossbow +ENT_REPLACE(weapon_crowbar, info_null); // crowbar +ENT_REPLACE(weapon_egon, weapon_lightning); // ghostbusters gun +ENT_REPLACE(weapon_gauss, weapon_lightning); // tau cannon +ENT_REPLACE(weapon_handgrenade, item_rockets); // hand grenades +ENT_REPLACE(weapon_hornetgun, info_null); // hornet gun +ENT_REPLACE(weapon_rpg, weapon_rocketlauncher); // rpg +ENT_REPLACE(weapon_satchel, item_rockets); // satchel charge +ENT_REPLACE(weapon_snark, item_cells); // snarks +ENT_REPLACE(weapon_tripmine, item_rockets); // tripmines +// armor +ENT_REPLACE(item_battery, info_null); // battery charge +// powerups +ENT_REPLACE(item_airtank, item_artifact_envirosuit); // air tank (not used often) +ENT_REPLACE(item_antidote, item_health); // antidote (not used often) +ENT_REPLACE(item_longjump, weapon_rocketlauncher); // long jump module +ENT_REPLACE(item_suit, item_artifact_envirosuit); // HEV suit +// health +ENT_REPLACE(item_healthkit, item_health); // floor health kit +// ammo +ENT_REPLACE(ammo_357, item_rockets); // 357 ammo +ENT_REPLACE(ammo_9mmAR, item_spikes); // mp5 clip +ENT_REPLACE(ammo_9mmbox, item_spikes, ammo_setlarge); // 9mm box +ENT_REPLACE(ammo_9mmclip, item_spikes); // 9mm clip +ENT_REPLACE(ammo_ARgrenades, item_rockets); // mp5 grenades +ENT_REPLACE(ammo_buckshot, item_shells); // shotgun shells +ENT_REPLACE(ammo_crossbow, item_rockets); // crossbow bolts +ENT_REPLACE(ammo_gaussclip, item_cells); // cells for gauss/egon +ENT_REPLACE(ammo_rpgclip, item_rockets, ammo_setlarge); // RPG ammo + +// special replace +void(void() func) CheckSpawn = +{ + // these ents conflict with q1 field names + switch (self.classname) + { + case "ammo_shells": + self.classname = "item_shells"; + item_shells(); + break; + case "ammo_nails": + self.classname = "item_spikes"; + item_spikes(); + break; + case "ammo_cells": + self.classname = "item_cells"; + item_cells(); + break; + default: + if (func) + func(); + else + { + dprint("Couldn't find spawn function "); + dprint(self.classname); + dprint("\n"); + } + } +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/sol_defs.qc b/r17/Revamped src/Revamped QC/sol_defs.qc new file mode 100755 index 00000000..06bbb88b --- /dev/null +++ b/r17/Revamped src/Revamped QC/sol_defs.qc @@ -0,0 +1,107 @@ +// Solitude defs +#define DEFAULT_GRAVITY 340 +#define DEFAULT_MAXSPEED 170 // max walk speed on ground + +.float next_jump_time; // next time the player can jump (usually after landing) +.float setup_death; // setup respawn timer on player death +void () Player_SetupDeath; + +.float needles; // how many needler needles a player has in him + +void () W_StartWeapon; +float (float wep, float cliptype) W_GetMaxClip; +void (float wtype, float ttype) ThrowWeapon; +void () player_throw_grenade; +void () pre_player_throw_grenade; +void () pre_player_melee; +void ( entity t_ent, float weptype, float cliptype, float newamt ) SetAmmoFor; +void () NeedlerHome; + +.float selnade; // the type of nade being thrown +#define GRENADE_REGULAR 0 +#define GRENADE_STICKY 1 + +.float weaponheat; + +.entity pp_cooldown; + +.float aflag; + +.float pickup_time, canpickup_time; + +.float lives; // times an item can respawn + +.float exshells; +.float exshells2; +.float exhshells; +.float exnails; +.float exrockets; +.float excells; + +//sniper rifle +.float ammo_sniper; +.float exsniper; + +// plasma pistol +.float ammo_ppistol; +.float exppistol; + +// plasma rifle +.float ammo_prifle; +.float exprifle; +.float prifle_heat; // plasma rifle fires faster the longer it's fired + +// energy sword +.float ammo_sword; +.float exsword; + +// needler +.float ammo_needler; +.float exneedler; +.float needler_heat; // needler fires faster the longer it's held down + +.float ammo_shells2; +.float ammo_hshells; + +.float axhitme; + +.float ohealth; // for regen +.float regen; /// + + +// animations +//weapon frame +.float donefire; +.float wepanim; +//player frame +.float fireframe; +.float jump_time; +.float pain_time; +.float reload_time; +.float pull_time; +.float nade_time, melee_time; +.float death_type; + +#define MOD_SOLITUDE 666 // undefined mode of death + +// weapons +#define WEAPON_SWORD IT_AXE +#define WEAPON_PISTOL IT_SHOTGUN +#define WEAPON_SHOT IT_SUPER_SHOTGUN +#define WEAPON_AR IT_NAILGUN +#define WEAPON_UZI IT_SUPER_NAILGUN +#define WEAPON_SNIPER IT_GRENADE_LAUNCHER +#define WEAPON_RL IT_ROCKET_LAUNCHER +#define WEAPON_PPISTOL IT_LIGHTNING +#define WEAPON_NEEDLER IT_EXTRA_WEAPON +#define WEAPON_PRIFLE IT_EXTRA_WEAPON2 +#define WEAPON_SKULL IT_SKULL + +// Zooming +.float pfov; +#define FOV_DEFAULT 90 + +// Frikbot +void(float to, float f) WriteByte; +void(float to, string s) WriteString; +void () reload; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/sol_items.qc b/r17/Revamped src/Revamped QC/sol_items.qc new file mode 100755 index 00000000..1b067396 --- /dev/null +++ b/r17/Revamped src/Revamped QC/sol_items.qc @@ -0,0 +1,565 @@ +// Solitude Items: weapons, ammo, misc. + +// GetPlayerWeapons: +// return how many weapons a player is holding. +// also used for finding out if the player is holding a certain weapon. +float (float pweapons) GetPlayerWeapons = +{ + local float i; + + if (pweapons & WEAPON_PISTOL) + i++; + if (pweapons & WEAPON_SKULL) + i++; + if (pweapons & WEAPON_SHOT) + i++; + if (pweapons & WEAPON_AR) + i++; + if (pweapons & WEAPON_UZI) + i++; + if (pweapons & WEAPON_RL) + i++; + if (pweapons & WEAPON_SNIPER) + i++; + if (pweapons & WEAPON_PPISTOL) + i++; + if (pweapons & WEAPON_SWORD) + i++; + if (pweapons & WEAPON_NEEDLER) + i++; + if (pweapons & WEAPON_PRIFLE) + i++; +/* + if (pweapons & WEAPON_PISTOL) + i++; + if (pweapons & WEAPON_PISTOL) + i++; +*/ + return i; +}; + +// Returns the amount of ammo an entity or player has either in the primary or secondary clip +// PS. It's hackish, but it works :) +float (entity t_plyr, float t_wep, float cliptype) GetAmmoCount = +{ + local float oldweapon, rtval; + + oldweapon = t_plyr.weapon; + t_plyr.weapon = t_wep; + W_UpdateAmmoCounts( t_plyr ); + if (cliptype) + rtval = t_plyr.currentammo; + else + rtval = t_plyr.armorvalue; + + t_plyr.weapon = oldweapon; + W_UpdateAmmoCounts( t_plyr ); + + return rtval; +}; + +// Sets the ammo of a new or dropped weapon, as opposed to the function below which... +void ( entity t_wep, float weptype ) SetWeaponAmmo = +{ + local float stammo; + stammo = W_GetMaxClip( weptype, 1 ); + + switch( weptype ) { + case WEAPON_PISTOL: + t_wep.exshells = 24; + t_wep.ammo_shells = stammo; + break; + case WEAPON_SKULL: + t_wep.exshells = 0; + t_wep.ammo_shells = stammo; + break; + case WEAPON_SHOT: + t_wep.exshells2 = 20; + t_wep.ammo_shells2 = stammo; + break; + case WEAPON_AR: + t_wep.exnails = 24; + t_wep.ammo_nails = stammo; + break; + case WEAPON_UZI: + t_wep.exhshells = 24; + t_wep.ammo_hshells = stammo; + break; + case WEAPON_RL: + t_wep.exrockets = 2; + t_wep.ammo_rockets = stammo; + break; + case WEAPON_SNIPER: + t_wep.exsniper = 10; + t_wep.ammo_sniper = stammo; + break; + case WEAPON_PPISTOL: + t_wep.exppistol = 0; + t_wep.ammo_ppistol = stammo; + break; + case WEAPON_SWORD: + t_wep.exppistol = 0; + t_wep.ammo_ppistol = stammo; + break; + case WEAPON_NEEDLER: + t_wep.exneedler = 90; + t_wep.ammo_needler = stammo; + break; + case WEAPON_PRIFLE: + t_wep.exprifle = 0; + t_wep.ammo_prifle = stammo; + break; + default: + break; + } +}; + +// sets ammo to a specific clip aspect of a weapon (current clip or extended clip) +void ( entity t_ent, float weptype, float cliptype, float newamt ) SetAmmoFor = +{ +/* +_bprint(ftos(GetAmmoCount(t_ent, weptype, cliptype)), "\n"); +_bprint(ftos(newamt), "\n"); +_bprint(ftos(W_GetMaxClip(weptype, cliptype)), "\n"); +*/ + if ( (GetAmmoCount(t_ent, weptype, cliptype)+newamt) > W_GetMaxClip(weptype, cliptype) ) { + newamt = W_GetMaxClip(weptype, cliptype) - GetAmmoCount(t_ent, weptype, cliptype); + if (newamt < 0) + newamt = 0; + } + + switch ( weptype ) { + case WEAPON_PISTOL: + if (!cliptype || cliptype > 1) + t_ent.exshells += newamt; + if (cliptype) + t_ent.ammo_shells += newamt; + break; + case WEAPON_SKULL: + if (!cliptype || cliptype > 1) + t_ent.exshells += newamt; + if (cliptype) + t_ent.ammo_shells += newamt; + break; + case WEAPON_SHOT: + if (!cliptype || cliptype > 1) + t_ent.exshells2 += newamt; + if (cliptype) + t_ent.ammo_shells2 += newamt; + break; + case WEAPON_AR: + if (!cliptype || cliptype > 1) + t_ent.exnails += newamt; + if (cliptype) + t_ent.ammo_nails += newamt; + break; + case WEAPON_UZI: + if (!cliptype || cliptype > 1) + t_ent.exhshells += newamt; + if (cliptype) + t_ent.ammo_hshells += newamt; + break; + case WEAPON_RL: + if (!cliptype || cliptype > 1) + t_ent.exrockets += newamt; + if (cliptype) + t_ent.ammo_rockets += newamt; + break; + case WEAPON_SNIPER: + if (!cliptype || cliptype > 1) + t_ent.exsniper += newamt; + if (cliptype) + t_ent.ammo_sniper += newamt; + break; + case WEAPON_PPISTOL: + if (!cliptype || cliptype > 1) + t_ent.exppistol += newamt; + if (cliptype) + t_ent.ammo_ppistol += newamt; + break; + case WEAPON_SWORD: + if (!cliptype || cliptype > 1) + t_ent.exsword += newamt; + if (cliptype) + t_ent.ammo_sword += newamt; + break; + case WEAPON_NEEDLER: + if (!cliptype || cliptype > 1) + t_ent.exneedler += newamt; + if (cliptype) + t_ent.ammo_needler += newamt; + break; + case WEAPON_PRIFLE: + if (!cliptype || cliptype > 1) + t_ent.exprifle += newamt; + if (cliptype) + t_ent.ammo_prifle += newamt; + break; + default: + _bprint("SetAmmoFor: invalid weapon type specified\n"); + break; + } +}; + +void ( entity t_from, entity t_to, float wtype, float aremove ) CopyAmmo = +{ + W_UpdateAmmoCounts( t_from ); + SetAmmoFor( t_to, wtype, 0, t_from.armorvalue ); + SetAmmoFor( t_to, wtype, 1, t_from.currentammo ); + + if (aremove == 1) { + SetAmmoFor( t_from, wtype, 0, (-1 * t_from.armorvalue) ); + SetAmmoFor( t_from, wtype, 1, (-1 * t_from.currentammo) ); + } +}; + +void () weapon_becometouch = +{ + self.think = SUB_Remove; + self.nextthink = time + 30; + self.touch = weapon_touch; +}; + +string ( float wtype ) weapon_getlaymodel = +{ + switch (wtype) + { + case WEAPON_SHOT: + return ("progs/g_shot.mdl"); + break; + case WEAPON_PISTOL: + return ("progs/g_pistol.mdl"); + break; + case WEAPON_SKULL: + //return ("GameTypes/OddBall/g_skull.mdl"); + break; + case WEAPON_AR: + return ("progs/g_nail.mdl"); + break; + case WEAPON_UZI: + return ("progs/g_uzi.mdl"); + break; + case WEAPON_RL: + return ("progs/g_rocket.mdl"); + break; + case WEAPON_SNIPER: + return ("progs/g_sniper.mdl"); + break; + case WEAPON_PPISTOL: + return ("progs/g_plpist.mdl"); + break; + case WEAPON_SWORD: + return ("progs/g_axe.mdl"); + break; + case WEAPON_NEEDLER: + return ("progs/g_needler.mdl"); + break; + case WEAPON_PRIFLE: + return ("progs/g_plrifl.mdl"); + break; + default: + return ("progs/player.mdl"); + break; + } +}; + +void (float wtype, float ttype) ThrowWeapon = +{ + local entity newthrow; + newthrow = spawn(); + newthrow.owner = self; + newthrow.movetype = MOVETYPE_BOUNCE; + newthrow.solid = SOLID_BBOX; + newthrow.classname = "weapon_pickup"; + newthrow.flags = FL_ITEM; + newthrow.think = weapon_becometouch; + newthrow.nextthink = time + 1; + + newthrow.weapon = wtype; + + if (ttype == 1) { // throwing an existing weapon + CopyAmmo(self, newthrow, wtype, 1); + newthrow.lives = 1; + } + else + SetWeaponAmmo(newthrow, wtype); + + makevectors (self.v_angle); + if (self.v_angle_x) + { + newthrow.velocity = ((((v_forward * 45) + (v_up * 200)) + ((crandom () * v_right) * TE_LAVASPLASH)) + ((crandom () * v_up) * TE_LAVASPLASH)); + } + else + { + newthrow.velocity = aim (self, 10000); + newthrow.velocity = (newthrow.velocity * 45); + newthrow.velocity_z = 200; + } + + newthrow.gravity = 3; + newthrow.solid = SOLID_TRIGGER; + + setsize (newthrow, '-16 -16 0', '16 16 56'); + + setmodel( newthrow, weapon_getlaymodel( wtype ) ); + + setorigin (newthrow, ((self.origin + '0 0 16') + (v_right * CONTENT_SKY))); +}; + +// respawn the weapon +void () weapon_activate = +{ + if (self.lives == 1) { + remove( self ); + return; + } + if (self.mdl) + setmodel(self, self.mdl); + self.touch = weapon_touch; +} + +void () weapon_touch = +{ + local entity oself; + local float addweapon, newweapon; + + oself = self; + // + if (!(other.flags & FL_CLIENT)) + return; + + if (other.ishuman != #TRUE) + if (other.attack_finished < time) + other.canpickup_time = time + .1; + + self.mdl = self.model; + + if ( (other.items & self.weapon) ) { + if (self.weapon & WEAPON_PPISTOL || self.weapon & WEAPON_PRIFLE) // weapons that don't have an extended clip + if ( W_GetMaxClip(self.weapon, 1) <= GetAmmoCount(other, self.weapon, 1) ) + return; + + if ( W_GetMaxClip(self.weapon, 0) <= GetAmmoCount(other, self.weapon, 0) ) + return; + + if (self.weapon & WEAPON_PPISTOL || self.weapon & WEAPON_PRIFLE) + SetAmmoFor( other, self.weapon, 1, self.currentammo ); + else + SetAmmoFor( other, self.weapon, 0, self.armorvalue ); + //SetAmmoFor( other, self.weapon, 1, self.currentammo ); + + W_UpdateAmmoCounts( other ); + self.touch = SUB_Null; + setmodel( self, string_null ); + self.nextthink = time + 30; + self.think = weapon_activate; + return; + } + + if (other.canpickup_time > time) { + if (other.weapon == self.weapon || GetPlayerWeapons(other.items) == 2 ) + addweapon = 2; // drop current weapon and replace it + else + { + addweapon = 1; // add other weapon and switch to it + } + + other.canpickup_time = 0; + } + else { + if (time > other.pickup_time) { + other.pickup_time = time + .5; + return; + } + } + + if (self.weapon == IT_NAILGUN) //Assault rifle + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 1\n"); + } + + else if (self.weapon == IT_LIGHTNING)//Plasma Pistol + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 2\n"); + } + + else if (self.weapon == IT_SUPER_SHOTGUN) //Shootie + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 3\n"); + } + + else if (self.weapon == IT_EXTRA_WEAPON) + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 4\n"); + } + + else if (self.weapon == IT_ROCKET_LAUNCHER) + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 5\n"); + } + + else if (self.weapon == IT_SHOTGUN) + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 6\n"); + } + + else if (self.weapon == IT_SUPER_NAILGUN) + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 7\n"); + } + + else if (self.weapon == IT_GRENADE_LAUNCHER) + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 8\n"); + } + + else + stuffcmd (other, "cl_ww 0\n"); + + if (addweapon) + { + other.attack_finished = time + .1; // so the player doesnt reload when picking up a new weapon + if (addweapon == 1) { + other.items = other.items | self.weapon; + sprint(other,"New weapon added to your inv\n"); + } + else if (addweapon == 2) { // replace current weapon + newweapon = self.weapon; + other.items = other.items - other.weapon; + other.items = other.items | self.weapon; + self = other; + ThrowWeapon(self.weapon, 1); + W_WeaponSwitch(newweapon); + W_SetCurrentAmmo(); + self = oself; + } + CopyAmmo( self, other, self.weapon, 0 ); + W_UpdateAmmoCounts(other); + self.touch = SUB_Null; + setmodel( self, string_null ); + self.nextthink = time + 30; + self.think = weapon_activate; + return; + } +}; + +void () weapon_start = +{ + if (!self.weapon) { + _bprint("weapon_start: weapon with no .weapon set!\n"); + remove(self); + } + + self.classname = "weapon_pickup"; // so bots can recognize it + self.flags = FL_ITEM; + + precache_model( weapon_getlaymodel( self.weapon ) ); + setmodel( self, weapon_getlaymodel( self.weapon ) ); + + self.gravity = 3; + self.solid = SOLID_TRIGGER; + + setsize (self, '-16 -16 0', '16 16 56'); + + SetWeaponAmmo( self, self.weapon ); + self.touch = weapon_touch; +}; + +// WEAPONS +void () weapon_shotgun = +{ + self.weapon = WEAPON_PISTOL; + weapon_start (); +}; +void () weapon_pistol = +{ + weapon_shotgun(); +}; +void() weapon_skull = +{ + self.weapon = WEAPON_SKULL; + weapon_start (); +}; +void() weapon_supershotgun = +{ + self.weapon = WEAPON_SHOT; + weapon_start (); +}; + +void() weapon_nailgun = +{ + self.weapon = WEAPON_AR; + weapon_start (); +}; +void() weapon_ar = +{ + weapon_nailgun(); +}; + +void() weapon_supernailgun = +{ + self.weapon = WEAPON_UZI; + weapon_start (); +}; +void() weapon_uzi = +{ + weapon_supernailgun (); +}; + +void() weapon_grenadelauncher = +{ + self.weapon = WEAPON_PPISTOL; + weapon_start (); +}; +void() weapon_ppistol = +{ + weapon_grenadelauncher (); +}; + +void() weapon_rocketlauncher = +{ + self.weapon = WEAPON_RL; + weapon_start (); +}; + +void() weapon_lightning = +{ + self.weapon = WEAPON_SNIPER; + weapon_start (); +}; +void() weapon_sniperrifle = +{ + weapon_lightning (); +}; + +void() weapon_sword = +{ + self.weapon = WEAPON_SWORD; + weapon_start (); +}; + +void() weapon_plasmapistol = +{ + self.weapon = WEAPON_PPISTOL; + weapon_start (); +}; + +void() weapon_plasmarifle = +{ + self.weapon = WEAPON_PRIFLE; + weapon_start (); +}; + +void() weapon_needler = +{ + self.weapon = WEAPON_NEEDLER; + weapon_start (); +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/sol_misc.qc b/r17/Revamped src/Revamped QC/sol_misc.qc new file mode 100755 index 00000000..fa822cd5 --- /dev/null +++ b/r17/Revamped src/Revamped QC/sol_misc.qc @@ -0,0 +1,13 @@ +// miscellaneous stuff + +// Spawn some model. +void() func_model = +{ + precache_model( self.model ); + setmodel( self, self.model ); + setorigin( self, self.origin ); + + self.movetype = MOVETYPE_NONE; + self.solid = SOLID_BBOX; + setsize(self, '-8 -8 -8', '8 8 8'); +}; \ No newline at end of file diff --git a/r17/Revamped src/Revamped QC/spectate.qc b/r17/Revamped src/Revamped QC/spectate.qc new file mode 100755 index 00000000..bdb8d58a --- /dev/null +++ b/r17/Revamped src/Revamped QC/spectate.qc @@ -0,0 +1,83 @@ +// Spectator functions +// Added Aug11'97 by Zoid +// +// These functions are called from the server if they exist. +// Note that Spectators only have one think since they movement code doesn't +// track them much. Impulse commands work as usual, but don't call +// the regular ImpulseCommand handler in weapons.qc since Spectators don't +// have any weapons and things can explode. +// +// --- Zoid. + +#ifndef NETQUAKE + +/* +=========== +SpectatorConnect + +called when a spectator connects to a server +============ +*/ +void() SpectatorConnect = +{ + bprint3 (PRINT_MEDIUM, "Spectator ", self.netname, " entered the game\n"); + + self.goalentity = world; // used for impulse 1 below +}; + +/* +=========== +SpectatorDisconnect + +called when a spectator disconnects from a server +============ +*/ +void() SpectatorDisconnect = +{ + bprint3 (PRINT_MEDIUM, "Spectator ", self.netname, " left the game\n"); +}; + +/* +================ +SpectatorImpulseCommand + +Called by SpectatorThink if the spectator entered an impulse +================ +*/ +void() SpectatorImpulseCommand = +{ + if (self.impulse == 1) { + // teleport the spectator to the next spawn point + // note that if the spectator is tracking, this doesn't do + // much + self.goalentity = find(self.goalentity, classname, "info_player_deathmatch"); + if (self.goalentity == world) + self.goalentity = find(self.goalentity, classname, "info_player_deathmatch"); + if (self.goalentity != world) { + setorigin(self, self.goalentity.origin); + self.angles = self.goalentity.angles; + self.fixangle = TRUE; // turn this way immediately + } + } + + self.impulse = 0; +}; + +/* +================ +SpectatorThink + +Called every frame after physics are run +================ +*/ +void() SpectatorThink = +{ + // self.origin, etc contains spectator position, so you could + // do some neat stuff here + + if (self.impulse) + SpectatorImpulseCommand(); +}; + +#endif + diff --git a/r17/Revamped src/Revamped QC/sprites.qc b/r17/Revamped src/Revamped QC/sprites.qc new file mode 100755 index 00000000..98fac355 --- /dev/null +++ b/r17/Revamped src/Revamped QC/sprites.qc @@ -0,0 +1,26 @@ + +// these are the only sprites still in the game... + +$spritename s_explod +$type vp_parallel +$load /raid/quake/id1/gfx/sprites/explod03.lbm +$frame 24 24 56 56 +$frame 120 24 56 56 +$frame 216 24 56 56 +$frame 24 88 56 56 +$frame 120 88 56 56 +$frame 216 88 56 56 + + +$spritename s_bubble +$type vp_parallel +$load /raid/quake/id1/gfx/sprites/bubble.lbm +$frame 16 16 16 16 +$frame 40 16 16 16 + + +$spritename s_light +$type vp_parallel +$load /raid/quake/id1/gfx/sprites/light.lbm +$frame 104 32 32 32 + diff --git a/r17/Revamped src/Revamped QC/subs.qc b/r17/Revamped src/Revamped QC/subs.qc new file mode 100755 index 00000000..c7a8a1ac Binary files /dev/null and b/r17/Revamped src/Revamped QC/subs.qc differ diff --git a/r17/Revamped src/Revamped QC/triggers.qc b/r17/Revamped src/Revamped QC/triggers.qc new file mode 100755 index 00000000..addf7ed0 --- /dev/null +++ b/r17/Revamped src/Revamped QC/triggers.qc @@ -0,0 +1,637 @@ +void() trigger_reactivate = +{ + self.solid = SOLID_TRIGGER; +}; + +//============================================================================= + +float SPAWNFLAG_NOMESSAGE = 1; +float SPAWNFLAG_NOTOUCH = 1; + +// the wait time has passed, so set back up for another activation +void() multi_wait = +{ + if (self.max_health) + { + self.health = self.max_health; + self.takedamage = DAMAGE_YES; + self.solid = SOLID_BBOX; + } +}; + + +// the trigger was just touched/killed/used +// self.enemy should be set to the activator so it can be held through a delay +// so wait for the delay time before firing +void() multi_trigger = +{ + if (self.nextthink > time) + { + return; // allready been triggered + } + + if (self.classname == "trigger_secret") + { + if (self.enemy.classname != "player") + return; + found_secrets = found_secrets + 1; + WriteByte (MSG_ALL, SVC_FOUNDSECRET); + } + + if (self.noise) + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + +// don't trigger again until reset + self.takedamage = DAMAGE_NO; + + activator = self.enemy; + + SUB_UseTargets(); + + if (self.wait > 0) + { + self.think = multi_wait; + self.nextthink = time + self.wait; + } + else + { // we can't just remove (self) here, because this is a touch function + // called wheil C code is looping through area links... + self.touch = SUB_Null; + self.nextthink = time + 0.1; + self.think = SUB_Remove; + } +}; + +void() multi_killed = +{ + self.enemy = damage_attacker; + multi_trigger(); +}; + +void() multi_use = +{ + self.enemy = activator; + multi_trigger(); +}; + +void() multi_touch = +{ + if (other.classname != "player") + return; + +// if the trigger has an angles field, check player's facing direction + if (self.movedir != '0 0 0') + { + makevectors (other.angles); + if (v_forward * self.movedir < 0) + return; // not facing the right way + } + + self.enemy = other; + multi_trigger (); +}; + +/*QUAKED trigger_multiple (.5 .5 .5) ? notouch +Variable sized repeatable trigger. Must be targeted at one or more entities. If "health" is set, the trigger must be killed to activate each time. +If "delay" is set, the trigger waits some time after activating before firing. +"wait" : Seconds between triggerings. (.2 default) +If notouch is set, the trigger is only fired by other entities, not by touching. +NOTOUCH has been obsoleted by trigger_relay! +sounds +1) secret +2) beep beep +3) large switch +4) +set "message" to text string +*/ +void() trigger_multiple = +{ + switch (self.sounds) + { + case 1: + precache_sound ("misc/secret.wav"); + self.noise = "misc/secret.wav"; + break; + case 2: + precache_sound ("misc/talk.wav"); + self.noise = "misc/talk.wav"; + break; + case 3: + precache_sound ("misc/trigger1.wav"); + self.noise = "misc/trigger1.wav"; + break; + } + + if (!self.wait) + self.wait = 0.2; + self.use = multi_use; + + InitTrigger (); + + if (self.health) + { + if (self.spawnflags & SPAWNFLAG_NOTOUCH) + objerror ("health and notouch don't make sense\n"); + self.max_health = self.health; + self.th_die = multi_killed; + self.takedamage = DAMAGE_YES; + self.solid = SOLID_BBOX; + setorigin (self, self.origin); // make sure it links into the world + } + else + { + if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) ) + { + self.touch = multi_touch; + } + } +}; + + +/*QUAKED trigger_once (.5 .5 .5) ? notouch +Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching +"targetname". If "health" is set, the trigger must be killed to activate. +If notouch is set, the trigger is only fired by other entities, not by touching. +if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired. +if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0. +sounds +1) secret +2) beep beep +3) large switch +4) +set "message" to text string +*/ +void() trigger_once = +{ + self.wait = -1; + trigger_multiple(); +}; + +//============================================================================= + +/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) +This fixed size trigger cannot be touched, it can only be fired by other events. It can contain killtargets, targets, delays, and messages. +*/ +void() trigger_relay = +{ + self.use = SUB_UseTargets; +}; + + +//============================================================================= + +/*QUAKED trigger_secret (.5 .5 .5) ? +secret counter trigger +sounds +1) secret +2) beep beep +3) +4) +set "message" to text string +*/ +void() trigger_secret = +{ + total_secrets = total_secrets + 1; + self.wait = -1; + if (!self.message) + self.message = "You found a secret area!"; + if (!self.sounds) + self.sounds = 1; + + if (self.sounds == 1) + { + precache_sound ("misc/secret.wav"); + self.noise = "misc/secret.wav"; + } + else if (self.sounds == 2) + { + precache_sound ("misc/talk.wav"); + self.noise = "misc/talk.wav"; + } + + trigger_multiple (); +}; + +//============================================================================= + + +void() counter_use = +{ + self.count = self.count - 1; + if (self.count < 0) + return; + + if (self.count != 0) + { + if (activator.classname == "player" + && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0) + { + if (self.count >= 4) + centerprint (activator, "There are more to go..."); + else if (self.count == 3) + centerprint (activator, "Only 3 more to go..."); + else if (self.count == 2) + centerprint (activator, "Only 2 more to go..."); + else + centerprint (activator, "Only 1 more to go..."); + } + return; + } + + if (activator.classname == "player" + && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0) + centerprint(activator, "Sequence completed!"); + self.enemy = activator; + multi_trigger (); +}; + +/*QUAKED trigger_counter (.5 .5 .5) ? nomessage +Acts as an intermediary for an action that takes multiple inputs. + +If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished. + +After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself. +*/ +void() trigger_counter = +{ + self.wait = -1; + if (!self.count) + self.count = 2; + + self.use = counter_use; +}; + + +/* +============================================================================== + +TELEPORT TRIGGERS + +============================================================================== +*/ + +float PLAYER_ONLY = 1; +float SILENT = 2; + +void() play_teleport = +{ + local float v; + local string tmpstr; + + v = random(); + if (v < 0.2) + tmpstr = "misc/r_tele1.wav"; + else if (v < 0.4) + tmpstr = "misc/r_tele2.wav"; + else if (v < 0.6) + tmpstr = "misc/r_tele3.wav"; + else if (v < 0.8) + tmpstr = "misc/r_tele4.wav"; + else + tmpstr = "misc/r_tele5.wav"; + + sound (self, CHAN_VOICE, tmpstr, 1, ATTN_NORM); + remove (self); +}; + +void(vector org) spawn_tfog = +{ + local entity s; + s = spawn (); + s.origin = org; + s.nextthink = time + 0.2; + s.think = play_teleport; + + TE_teleport(org); +}; + + +void() tdeath_touch = +{ + if (other == self.owner) + return; + +// frag anyone who teleports in on top of an invincible player + if (other.classname == "player") + { + if (other.invincible_finished > time && + self.owner.invincible_finished > time) { + other.invincible_finished = 0; + self.owner.invincible_finished = 0; + T_Damage (other, self, self.owner, 50000, MOD_TELEFRAGDEFLECT); + T_Damage (self.owner, self, other, 50000, MOD_TELEFRAGDEFLECT); + return; + } + + if (other.invincible_finished > time) + { + T_Damage (self.owner, self, self.owner, 50000, MOD_TELEFRAGDEFLECT); + return; + } + + } + + if (other.health) + { + T_Damage (other, self, self.owner, 50000, MOD_TELEFRAG); + } +}; + + +void(vector org, entity death_owner) spawn_tdeath = +{ +local entity death; + + death = spawn(); + death.classname = "teledeath"; + death.movetype = MOVETYPE_NONE; + death.solid = SOLID_TRIGGER; + death.angles = '0 0 0'; + setsize (death, death_owner.mins - '1 1 1', death_owner.maxs + '1 1 1'); + setorigin (death, org); + death.touch = tdeath_touch; + death.nextthink = time + 0.2; + death.think = SUB_Remove; + death.owner = death_owner; + + force_retouch = 2; // make sure even still objects get hit +}; + +void() teleport_touch = +{ +local entity t; +local vector org; + + if (self.targetname) + { + if (self.nextthink < time) + { + return; // not fired yet + } + } + + if (self.spawnflags & PLAYER_ONLY) + { + if (other.classname != "player") + return; + } + +// only teleport living creatures + if (other.health <= 0 || other.solid != SOLID_SLIDEBOX) + return; + + SUB_UseTargets (); + +// put a tfog where the player was + spawn_tfog (other.origin); + + t = find (world, targetname, self.target); + if (!t) + objerror ("couldn't find target"); + +// spawn a tfog flash in front of the destination + makevectors (t.mangle); + org = t.origin + 32 * v_forward; + + spawn_tfog (org); + spawn_tdeath(t.origin, other); + +// move the player and lock him down for a little while + if (!other.health) + { + other.origin = t.origin; + other.velocity = (v_forward * other.velocity_x) + (v_forward * other.velocity_y); + return; + } + + setorigin (other, t.origin); + other.angles = t.mangle; + if (other.classname == "player") + { + other.fixangle = 1; // turn this way immediately + other.teleport_time = time + 0.7; + if (other.flags & FL_ONGROUND) + other.flags = other.flags - FL_ONGROUND; + other.velocity = v_forward * 300; + } + other.flags = other.flags - other.flags & FL_ONGROUND; +}; + +/*QUAKED info_teleport_destination (.5 .5 .5) (-8 -8 -8) (8 8 32) +This is the destination marker for a teleporter. It should have a "targetname" field with the same value as a teleporter's "target" field. +*/ +void() info_teleport_destination = +{ +// this does nothing, just serves as a target spot + self.mangle = self.angles; + self.angles = '0 0 0'; + self.model = ""; + self.origin = self.origin + '0 0 27'; + if (!self.targetname) + objerror ("no targetname"); +}; + +void() teleport_use = +{ + self.nextthink = time + 0.2; + force_retouch = 2; // make sure even still objects get hit + self.think = SUB_Null; +}; + +/*QUAKED trigger_teleport (.5 .5 .5) ? PLAYER_ONLY SILENT +Any object touching this will be transported to the corresponding info_teleport_destination entity. You must set the "target" field, and create an object with a "targetname" field that matches. + +If the trigger_teleport has a targetname, it will only teleport entities when it has been fired. +*/ +void() trigger_teleport = +{ + local vector o; + + InitTrigger (); + self.touch = teleport_touch; + // find the destination + if (!self.target) + objerror ("no target"); + self.use = teleport_use; + + if (!(self.spawnflags & SILENT)) + { + precache_sound ("ambience/hum1.wav"); + o = (self.mins + self.maxs)*0.5; + ambientsound (o, "ambience/hum1.wav",0.5 , ATTN_STATIC); + } +}; + +/* +============================================================================== + +trigger_setskill + +============================================================================== +*/ + +/*QUAKED trigger_setskill (.5 .5 .5) ? +sets skill level to the value of "message". +Only used on start map. +*/ +void() trigger_setskill = +{ + remove (self); +}; + + +/* +============================================================================== + +ONLY REGISTERED TRIGGERS + +============================================================================== +*/ + +void() trigger_onlyregistered_touch = +{ + if (other.classname != "player") + return; + if (self.attack_finished > time) + return; + + self.attack_finished = time + 2; + if (cvar("registered")) + { + self.message = ""; + SUB_UseTargets (); + remove (self); + } + else + { + if (self.message != "") + { + centerprint (other, self.message); + sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM); + } + } +}; + +/*QUAKED trigger_onlyregistered (.5 .5 .5) ? +Only fires if playing the registered version, otherwise prints the message +*/ +void() trigger_onlyregistered = +{ + precache_sound ("misc/talk.wav"); + InitTrigger (); + self.touch = trigger_onlyregistered_touch; +}; + +//============================================================================ + +void() hurt_on = +{ + self.solid = SOLID_TRIGGER; + self.nextthink = -1; +}; + +void() hurt_touch = +{ + if (other.takedamage) + { + self.solid = SOLID_NOT; + T_Damage (other, self, self, self.dmg, MOD_HURT); + self.think = hurt_on; + self.nextthink = time + 1; + } + + return; +}; + +/*QUAKED trigger_hurt (.5 .5 .5) ? +Any object touching this will be hurt +set dmg to damage amount +defalt dmg = 5 +*/ +void() trigger_hurt = +{ + InitTrigger (); + self.touch = hurt_touch; + if (!self.dmg) + self.dmg = 5; +}; + +//============================================================================ + +float PUSH_ONCE = 1; + +void() trigger_push_touch = +{ + if (other.classname == "grenade") + other.velocity = self.speed * self.movedir * 10; + else if (other.health > 0) + { + 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); + } + } + } + if (self.spawnflags & PUSH_ONCE) + remove(self); +}; + + +/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE +Pushes the player +*/ +void() trigger_push = +{ + InitTrigger (); + precache_sound ("ambience/windfly.wav"); + self.touch = trigger_push_touch; + if (!self.speed) + self.speed = 1000; +}; + +//============================================================================ + +void() trigger_monsterjump_touch = +{ + if ( other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER ) + return; + +// set XY even if not on ground, so the jump will clear lips + other.velocity_x = self.movedir_x * self.speed; + other.velocity_y = self.movedir_y * self.speed; + + if ( !(other.flags & FL_ONGROUND) ) + return; + + other.flags = other.flags - FL_ONGROUND; + + other.velocity_z = self.height; +}; + +/*QUAKED trigger_monsterjump (.5 .5 .5) ? +Walking monsters that touch this will jump in the direction of the trigger's angle +"speed" default to 200, the speed thrown forward +"height" default to 200, the speed thrown upwards +*/ +void() trigger_monsterjump = +{ + if (deathmatch) + { + remove(self); + return; + } + + if (!self.speed) + self.speed = 200; + if (!self.height) + self.height = 200; + if (self.angles == '0 0 0') + self.angles = '0 360 0'; + InitTrigger (); + self.touch = trigger_monsterjump_touch; +}; + diff --git a/r17/Revamped src/Revamped QC/weapons.qc b/r17/Revamped src/Revamped QC/weapons.qc new file mode 100755 index 00000000..cb5faacb --- /dev/null +++ b/r17/Revamped src/Revamped QC/weapons.qc @@ -0,0 +1,3277 @@ +/* +*/ +vector puff_org; +void (entity targ, entity inflictor, entity attacker, float damage, INTEGER mod) T_Damage; +void () player_run; +void(entity inflictor, entity attacker, float damage, float radius, entity ignore, INTEGER mod) T_RadiusDamage; +void(vector org, float damage) SpawnBlood; +void() SuperDamageSound; +void () player_reload1; +void () player_stand1; +// called by worldspawn +void() W_Precache = +{ + precache_sound ("weapons/r_exp3.wav"); // new rocket explosion + precache_sound ("weapons/rocket1i.wav"); // spike gun + precache_sound ("weapons/uzi.wav"); // Uzi + precache_sound ("weapons/sgun1.wav"); //RL + precache_sound ("weapons/pistol.wav"); // player shotgun + precache_sound ("weapons/grenade.wav"); // grenade launcher + precache_sound ("weapons/bounce.wav"); // grenade bounce + precache_sound ("weapons/sniper.wav"); // sniperrifle + precache_sound ("weapons/shottie.wav"); // shottie + precache_sound ("weapons/shotgn2.wav"); // Ar2 + precache_sound ("weapons/needler.wav"); // needler + precache_sound ("weapons/ar1.wav"); //Sound effects for asault rifle + precache_model ("GFX/s_fblood.spr"); //Flood blood + precache_model ("progs/PL_BULL.spr"); //Flood blood + precache_model ("progs/h_dog.mdl"); // Head for floodpod + precache_model ("sprites/s_smoke2.spr"); //Flood blood + precache_sound ("weapons/bigneedler.wav"); // + precache_model ("progs/needler_dust.spr"); + + // Solitude precaches + + // Weapons (first-person) + precache_model ("progs/v_shotgun.mdl"); + precache_model ("progs/v_rocket.mdl"); + precache_model ("progs/v_uzi.mdl"); + precache_model ("progs/v_sniper.mdl"); + precache_model ("progs/v_plpist.mdl"); + precache_model ("progs/v_needle.mdl"); + precache_model ("progs/v_plrifle.mdl"); + + // Weapons sounds + //Reload + precache_sound ("weapons/reload/pistol.wav"); + precache_sound ("weapons/reload/needler.wav"); + precache_sound ("weapons/reload/ar.wav"); + precache_sound ("weapons/reload/sniper.wav"); + precache_sound ("weapons/reload/uzi.wav"); + precache_sound ("weapons/reload/rocket.wav"); + precache_sound ("weapons/reload/shottie.wav"); // reload sounds + + //melee + precache_sound ("weapons/melee/needler.wav"); + precache_sound ("weapons/melee/pistol.wav"); + + // Grenades + precache_model ("progs/fraggren.mdl"); + precache_model ("progs/plasgren.mdl"); + precache_model ("sprites/s_plasma4.spr"); + precache_model ("sprites/plasma3.spr"); + precache_sound ("weapons/plasma_blow.wav"); + precache_sound ("weapons/plasma_throw.wav"); + precache_sound ("weapons/pbounce.wav"); + precache_model ("progs/s_smoke1.spr"); // Smoke from explosion + + + // Dropped weapons + precache_model ("progs/g_shot.mdl"); + precache_model ("progs/g_pistol.mdl"); + precache_model ("progs/g_nail.mdl"); + precache_model ("progs/g_uzi.mdl"); + precache_model ("progs/g_rocket.mdl"); + precache_model ("progs/g_sniper.mdl"); + precache_model ("progs/g_needler.mdl"); + precache_model ("progs/g_plpist.mdl"); + precache_sound ("weapons/ppist.wav"); + + // projectiles + precache_model ("progs/sniperbullet.mdl"); + precache_model ("progs/needproy.mdl"); // Needler Projectile + precache_model ("progs/Bigneedproy.mdl"); // Needler Projectile + precache_model ("progs/needpro2.mdl"); // Embedded needle + precache_model ("sprites/muzzleflash.spr"); + precache_model ("sprites/muzzleflash1.spr"); //ar original flash + precache_model ("sprites/muzzleflash2.spr"); + precache_model ("sprites/pistolmuzzleflash.spr"); + precache_model ("sprites/muzzleN.spr"); // Needler Muzzle flash + precache_model ("progs/plasma.spr"); + + //misc precaches + precache_sound ("weapons/zoom.wav"); + precache_sound ("weapons/zoom2.wav"); + precache_sound ("weapons/coil.wav"); + + + //Needler Extra + precache_sound ("weapons/nb.wav"); + precache_sound ("weapons/crystal.wav"); + precache_sound ("weapons/coil.wav"); + + //Equip sounds + precache_sound ("weapons/equip/ar.wav"); + precache_sound ("weapons/equip/needler.wav"); + precache_sound ("weapons/equip/rocket.wav"); + precache_sound ("weapons/equip/pistol.wav"); + precache_sound ("weapons/equip/shotgun.wav"); + precache_sound ("weapons/equip/sniper.wav"); + precache_sound ("weapons/equip/ppist.wav"); + precache_sound ("weapons/equip/smg.wav"); + + + //Shells + precache_model ("progs/shell.mdl"); + precache_model ("progs/shellshot.mdl"); + + + + +}; + + + +/* +=================================== +Muzzle flashes +================================== +*/ + +void() muzzleflash_think = { +self.frame = self.frame + 1; +self.think = SUB_Remove; +self.nextthink = time + 0.02; +}; + +void() muzzleflash2 = { +local entity muzzle; +muzzle = spawn(); +muzzle.owner = self; + + +muzzle.solid = SOLID_NOT; + +setmodel(muzzle,"sprites/muzzleflash1.spr"); +setorigin(muzzle,self.origin + v_forward * 23 + v_right * 6 + '0 0 19'); +muzzle.think = muzzleflash_think; +muzzle.nextthink = time + 0.01; +};void() muzzleflash_think1 = { +self.frame = self.frame + 1; +self.think = SUB_Remove; +self.nextthink = time + 0.01; +}; + +void() muzzleflash3 = { +local entity muzzle; +muzzle = spawn(); +muzzle.owner = self; + + +muzzle.solid = SOLID_NOT; +muzzle.movetype = MOVETYPE_NONE; + + +setmodel(muzzle,"sprites/muzzleflash.spr"); +setorigin(muzzle,self.origin + v_forward * 35 + v_right * 6 + '0 0 15'); +muzzle.think = muzzleflash_think1; +muzzle.nextthink = time + 0.01; +};void() muzzleflash_think2 = { +self.frame = self.frame + 1; +self.think = SUB_Remove; +self.nextthink = time + 0.02; +}; + +void() muzzleflash4 = { +local entity muzzle; +muzzle = spawn(); +muzzle.owner = self; + + +muzzle.solid = SOLID_NOT; +muzzle.movetype = MOVETYPE_NONE; + + +setmodel(muzzle,"sprites/muzzleflash2.spr"); +setorigin(muzzle,self.origin + v_forward * 55 + v_right * 10 + '0 0 13'); +muzzle.think = muzzleflash_think1; +muzzle.nextthink = time + 0.01; +}; + +void() muzzleflash5 = { +local entity muzzle; +muzzle = spawn(); +muzzle.owner = self; + + +muzzle.solid = SOLID_NOT; +muzzle.movetype = MOVETYPE_NONE; + + +setmodel(muzzle,"sprites/pistolmuzzleflash.spr"); +setorigin(muzzle,self.origin + v_forward * 30 + v_right * 8 + '0 0 20'); +muzzle.think = muzzleflash_think2; +muzzle.nextthink = time + 0.01; +};void() muzzleflash_think3 = { +self.frame = self.frame + 1; +self.think = SUB_Remove; +self.nextthink = time + 0.01; +}; +void() muzzleflash_think6 = { +self.frame = self.frame + 2; +self.think = SUB_Remove; +self.nextthink = time + 0.02; +}; +void() muzzleflash6 = { +local entity muzzle; +muzzle = spawn(); +muzzle.owner = self; + + +muzzle.solid = SOLID_NOT; +muzzle.movetype = MOVETYPE_NONE; + + +setmodel(muzzle,"sprites/muzzleN.spr"); +setorigin(muzzle,self.origin + v_forward * 35 + v_right * 10 + '0 0 17'); +muzzle.think = muzzleflash_think6; +muzzle.nextthink = time + 0.01; +}; + +void() muzzleflash7 = { +local entity muzzle; +muzzle = spawn(); +muzzle.owner = self; + + +muzzle.solid = SOLID_NOT; +muzzle.movetype = MOVETYPE_NONE; + + +setmodel(muzzle,"sprites/muzzleflash.spr"); +setorigin(muzzle,self.origin + v_forward * 45 + v_right * 2 + '0 0 17'); +muzzle.think = muzzleflash_think1; +muzzle.nextthink = time + 0.01; +}; + +#define crandom() (2*(random()-0.5)) + +void() W_UpdateWeapon; + +// The weapon the player spawns with +void () W_StartWeapon = +{ + self.items = WEAPON_AR + WEAPON_PPISTOL; + self.ammo_nails = W_GetMaxClip(self.weapon, 4); + self.exnails = 560; + self.ammo_ppistol = 100; + self.currentammo = W_GetMaxClip(self.weapon, 4); + + self.weapon = WEAPON_AR; + W_UpdateWeapon(); + + W_UpdateAmmoCounts(self); +}; +/* +Ammo update functions +*/ +// xavior: FIXME instead of using W_SetCurrentAmmo! +//Mexicouger: Handle the Ammo count HUD here, rather than PlayerPreThink. It is way more efficient Memory wise.(10-15 fps) +void(entity ent) W_UpdateAmmoCounts = +{ + AmmoCounter(); + // solitude + switch (ent.weapon) + { + case WEAPON_PISTOL: + ent.currentammo = ent.ammo_shells; + ent.armorvalue = ent.exshells; + break; + case WEAPON_SKULL: + ent.currentammo = ent.ammo_shells; + ent.armorvalue = ent.exshells; + break; + case WEAPON_SHOT: + ent.currentammo = ent.ammo_shells2; + ent.armorvalue = ent.exshells2; + break; + case WEAPON_AR: + ent.currentammo = ent.ammo_nails; + ent.armorvalue = ent.exnails; + break; + case WEAPON_UZI: + ent.currentammo = ent.ammo_hshells; + ent.armorvalue = ent.exhshells; + break; + case WEAPON_RL: + ent.currentammo = ent.ammo_rockets; + ent.armorvalue = ent.exrockets; + break; + case WEAPON_SNIPER: + ent.currentammo = ent.ammo_sniper; + ent.armorvalue = ent.exsniper; + break; + case WEAPON_PPISTOL: + ent.currentammo = ent.ammo_ppistol; + ent.armorvalue = ent.exppistol; + break; + case WEAPON_SWORD: + ent.currentammo = ent.ammo_sword; + ent.armorvalue = ent.exsword; + break; + case WEAPON_NEEDLER: + ent.currentammo = ent.ammo_needler; + ent.armorvalue = ent.exneedler; + break; + case WEAPON_PRIFLE: + ent.currentammo = ent.ammo_prifle; + ent.armorvalue = ent.exprifle; + break; + default: + ent.currentammo = 12; + break; + } +}; + +// Damage per individual bullets +float (float t_wep) W_BulletDamage = +{ + switch (t_wep) { + case WEAPON_SHOT: + return 8; + break; + default: + return 4; + break; + } + return 4; +}; + +// cliptype 1 = max size per clip +// cliptype 0 = max extra ammo the player can carry +float (float wep, float cliptype) W_GetMaxClip = +{ + // solitude + switch (wep) + { + case WEAPON_PISTOL: + if (cliptype) + return 12; + else + return 90; + break; + case WEAPON_SKULL: + if (cliptype) + return 12; + else + return 90; + break; + case WEAPON_SHOT: + if (cliptype) + return 6; + else + return 30; + break; + case WEAPON_AR: + if (cliptype) + return 32; + else + return 560; + break; + case WEAPON_UZI: + if (cliptype) + return 60; + else + return 560; + break; + case WEAPON_RL: + if (cliptype) + return 2; + else + return 6; + break; + case WEAPON_SNIPER: + if (cliptype) + return 4; + else + return 20; + break; + case WEAPON_PPISTOL: + if (cliptype) + return 100; + else + return 90; + break; + case WEAPON_SWORD: + if (cliptype) + return 0; // should be 0 - infinite + else + return 0; + break; + case WEAPON_NEEDLER: + if (cliptype) + return 20; + else + return 80; + break; + case WEAPON_PRIFLE: + if (cliptype) + return 100; + else + return 90; + break; + default: + if (cliptype) + return 1; + else + return 90; + break; + } + return 1; +}; + +float (entity ent) W_CanFire = +{ + switch (ent.weapon) + { + case IT_AXE: + return TRUE; + break; + case WEAPON_PISTOL: + if (ent.ammo_shells <= 0) + return FALSE; + break; + case WEAPON_SKULL: + if (ent.ammo_shells <= 0) + return TRUE; + break; + case WEAPON_SHOT: + if (ent.ammo_shells2 <= 0) + return FALSE; + break; + case WEAPON_AR: + if (ent.ammo_nails <= 0) + return FALSE; + break; + case WEAPON_UZI: + if (ent.ammo_hshells <= 0) + return FALSE; + break; + case WEAPON_RL: + if (ent.ammo_rockets <= 0) + return FALSE; + break; + case WEAPON_SNIPER: + if (ent.ammo_sniper <= 0) + return FALSE; + break; + case WEAPON_PPISTOL: + if (ent.ammo_ppistol <= 0) + return FALSE; + break; + case WEAPON_SWORD: + if (ent.ammo_sword <= 0) + return FALSE; + break; + case WEAPON_NEEDLER: + if (ent.ammo_needler <= 0) + return FALSE; + break; + case WEAPON_PRIFLE: + if (ent.ammo_prifle <= 0) + return FALSE; + break; + default: + return TRUE; + break; + } + return TRUE; +}; + +void ( float famt ) Set_FOV = +{ + stuffcmd( self, "fov " ); + stuffcmd( self, ftos( famt ) ); + stuffcmd( self, "\n" ); +}; + +void () WeaponZoom = +{ + float tozoom; + + if (self.health < 1) + return; + + switch (self.weapon) + { + case WEAPON_SNIPER: + if (self.pfov < FOV_DEFAULT) + { tozoom = 15; + sound (self, CHAN_AUTO, "weapons/zoom.wav", 1, ATTN_NORM); + } + else { + tozoom = 45; + sound (self, CHAN_AUTO, "weapons/zoom2.wav", 1, ATTN_NORM); + } + break; + default: + tozoom = 45; + break; + } + if (self.pfov == tozoom) + tozoom = FOV_DEFAULT; + + Set_FOV( tozoom ); + self.pfov = tozoom; +}; + +/* +================ +W_FireAxe +================ +*/ +void(float lunge) W_FireSword = +{ + local vector source; + local vector org; + + makevectors (self.v_angle); + source = self.origin + '0 0 16'; + traceline (source, source + v_forward*64, FALSE, self); + + if (trace_fraction == 1.0) + return; + + org = trace_endpos - v_forward*4; + + if (trace_ent.takedamage) + { + SpawnBlood (org, 20); + if (lunge) + T_Damage (trace_ent, self, self, 150, MOD_AXE); + else + T_Damage (trace_ent, self, self, 75, MOD_AXE); + + } + else + { // hit wall + + sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM); + + TE_gunshot(org); + } +}; + + +//============================================================================ + +/* +================ +SpawnMeatSpray +================ +*/ +void(vector org, vector vel) SpawnMeatSpray = +{ + local entity missile; + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_BOUNCE; + missile.solid = SOLID_NOT; + + makevectors (self.angles); + + missile.velocity = vel; + missile.velocity_z = missile.velocity_z + 250 + 50*random(); + + missile.avelocity = '3000 1000 2000'; + +// set missile duration + missile.nextthink = time + 1; + missile.think = SUB_Remove; + + setmodel (missile, "progs/zom_gib.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, org); +}; + +/* +============================================================================== + +MULTI-DAMAGE + +Collects multiple small damages into a single damage + +============================================================================== +*/ + +entity multi_ent; +float multi_damage; +INTEGER multi_mod; + +vector blood_org; +float blood_count; + + +float puff_count; + +void() ClearMultiDamage = +{ + multi_ent = world; + multi_damage = 0; + blood_count = 0; + puff_count = 0; + multi_mod = MOD_NONE; +}; + +void() ApplyMultiDamage = +{ + if (!multi_ent) + return; + T_Damage (multi_ent, self, self, multi_damage, multi_mod); +}; + +void(entity hit, float damage, INTEGER mod) AddMultiDamage = +{ + if (!hit) + return; + + if (hit != multi_ent || mod != multi_mod) + { + ApplyMultiDamage (); + multi_damage = damage; + multi_ent = hit; + } + else + multi_damage = multi_damage + damage; +}; + +void() Multi_Finish = +{ + if (puff_count) + TE_gunshot(puff_org); + + if (blood_count) + SpawnBlood(blood_org, blood_count); +}; + +/* +============================================================================== +BULLETS +============================================================================== +*/ + +/* +================ +TraceAttack +================ +*/ +void(float damage, vector dir, INTEGER mod) TraceAttack = +{ + local vector vel, org; + + vel = normalize(dir + v_up*crandom() + v_right*crandom()); + vel = vel + 2*trace_plane_normal; + vel = vel * 200; + + org = trace_endpos - dir*4; + + if (trace_ent.takedamage) + { + blood_count = blood_count + 1; + blood_org = org; + AddMultiDamage (trace_ent, damage, mod); + } + else + { + puff_count = puff_count + 1; + } +}; + +/* +================ +FireBullets + +Used by shotgun, super shotgun, and enemy soldier firing +Go to the trouble of combining multiple pellets into a single damage call. +================ +*/ +void(float shotcount, vector dir, vector spread, INTEGER mod) FireBullets = +{ + local vector direction; + local vector src; + + makevectors(self.v_angle); + + src = self.origin + v_forward*10; + src_z = self.absmin_z + self.size_z * 0.7; + + ClearMultiDamage (); + + traceline (src, src + dir*2048, FALSE, self); + puff_org = trace_endpos - dir*4; + + while (shotcount > 0) + { + direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + traceline (src, src + direction*2048, FALSE, self); + if (trace_fraction != 1.0) + TraceAttack (W_BulletDamage(self.weapon), direction, mod); + + shotcount = shotcount - 1; + } + ApplyMultiDamage (); + Multi_Finish (); +}; + +/* +======================================== +################################################### + +Touch Functions (explosions, Bullets, etc) + +################################################## +======================================== +*/ +/* +============================== + +Rocket Launcher Explosion + +============================== +*/ +void() Rocket_Explode0 = +{ + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + T_RadiusDamage (self, self.owner, 190, 160, world, MOD_ROCKET); + + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion (self.origin); + remove(self); +}; +/* +============================== + +Pistol Touch + +============================== +*/ +void(vector org) PistolTouch = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + if (other.health >= 30) + { + particle (self.origin, '0 4 5', 110, 6); + particle (self.origin, '0 4 5', 109, 6); + } + else + spawn_touchblood (8); + if (other.health <= 30) + T_Damage (other, self, self.owner, 15); + else + T_Damage (other, self, self.owner, 20); + + + } + else + { + particle (self.origin, '0 0 0', 6, 8); + particle (self.origin, '0 0 0', 11, 8); + puff_org = self.origin; + } + remove(self); +}; +/* +============================== + +Assault rifle Touch + +============================== +*/ +void(vector org) ARTouch = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + if (other.health >= 30) + { + particle (self.origin, '0 4 5', 110, 6); + particle (self.origin, '0 4 5', 109, 6); + } + else + spawn_touchblood (8); + if (other.health <= 30) + T_Damage (other, self, self.owner, 5); + else + T_Damage (other, self, self.owner, 5.3); + + + } + else + { + //particle (self.origin, '0 0 0', 6, 8); + particle (self.origin, '0 0 0', 11, 6); + puff_org = self.origin; + } + + remove(self); +}; + +/* +============================== + +SMG Touch + +============================== +*/ +void(vector org) SMGTouch = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + if (other.health >= 30) + { + particle (self.origin, '0 4 5', 110, 6); + particle (self.origin, '0 4 5', 109, 6); + } + else + spawn_touchblood (8); + if (other.health <= 30) + T_Damage (other, self, self.owner, 4); + else + T_Damage (other, self, self.owner, 4.8); + + + } + else + { + particle (self.origin, '0 0 0', 6, 8); + particle (self.origin, '0 0 0', 11, 8); + puff_org = self.origin; + } + remove(self); +}; + +void(vector org) shotshells = +{ +local entity rock; +local float rand; +local vector dir; +rand = random(); +rock = spawn (); +rock.classname = "gun_shells"; +rock.movetype = MOVETYPE_BOUNCE; +rock.owner = self; +// This is all about how fast the debris goes. (My biggest problem) +makevectors (self.v_angle); +rock.velocity = v_right; +rock.velocity = (rock.velocity * 50); + + +rock.angles = vectoangles (rock.velocity); +rock.avelocity = '300 300 300' * random(); + +rock.solid = SOLID_NOT; + +dir = aim (self, 1000); +// Rock duration (How long the rocks are alive until they disapear +//rock.touch = Debrisbounce; +rock.nextthink = time + 3; +rock.think = SUB_Remove; + +// The whole setting up the model thing. Sets up the sprite and location. +setorigin (rock, ((org + (v_forward * 5)) + '0 0 12')); +if (self.weapon == WEAPON_SHOT) { +setmodel (rock, "progs/shellshot.mdl"); +} +else +setmodel (rock, "progs/shell.mdl"); +}; +void() player_pull; +/* +================ +W_FirePistol +================ +*/ +void() W_FirePistol = +{ + local vector dir; + local entity missile; + + sound (self, CHAN_WEAPON, "weapons/pistol.wav", 1, ATTN_NORM); + + VK_smallkick(self); + + self.ammo_shells -= 1; + W_UpdateAmmoCounts(self); + shotshells(self.origin + (v_forward * 13) + '0 0 12'); + + dir = aim (self, 1000); + pistolsmoke (self.origin); + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_FLYMISSILE; + missile.solid = SOLID_BBOX; + missile.classname = "Pistol"; + +// set missile speed + + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = v_forward; + missile.velocity = missile.velocity * 100000; + missile.angles = vectoangles(missile.velocity); + + missile.touch = PistolTouch; + +// set missile duration + missile.nextthink = time + 5; + missile.think = SUB_Remove; + + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + v_forward*8 + '0 0 16'); + + + +}; +/* +================ +W_FireSkull +================ +*/ +void() W_FireSkull = +{ + local vector dir; + + sound (self, CHAN_WEAPON, "weapons/oddball.wav", 1, ATTN_NORM); + + VK_smallkick(self); + + self.ammo_shells -= 1; + W_UpdateAmmoCounts(self); + + dir = aim (self, 100000); + FireBullets (1, dir, '0 0 0', MOD_SOLITUDE); +}; + +void () Cooldown_Think = +{ + local entity oself; + oself = self; + + if (self.owner == world || self.owner.classname != "player") { + remove(self); + return; + } + if (self.owner.items & WEAPON_PPISTOL) { + if (self.owner.exppistol > 0) { + self.owner.exppistol -= 1; + W_UpdateAmmoCounts(self.owner); + } + } + if (self.owner.items & WEAPON_PRIFLE) { + if (self.owner.exprifle > 0) { + self.owner.exprifle -= 1; + W_UpdateAmmoCounts(self.owner); + } + } + + self.nextthink = time + .05; +}; + +void ( float t_weap, float w_heat ) W_AddHeat = +{ + if (self.pp_cooldown == world) { + self.pp_cooldown = spawn(); + self.pp_cooldown.owner = self; + self.pp_cooldown.weapon = t_weap; + self.pp_cooldown.think = Cooldown_Think; + self.pp_cooldown.nextthink = time + .05; + } + + switch ( t_weap ) { + case WEAPON_PPISTOL: + self.exppistol += w_heat; + break; + case WEAPON_PRIFLE: + self.exprifle += w_heat; + break; + } +}; + +void () Plasma_Diffuse = +{ + self.velocity = '0 0 0'; + self.think = SUB_Remove; + self.nextthink = time + .3; + self.touch = SUB_Null; + if (other.classname == "player") + { + if (other.health >= 30) + { + particle (self.origin, '0 0 0', 110, 6); + particle (self.origin, '0 0 0', 109, 6); + } + else + spawn_touchblood (8); + T_Damage (other, self, self.owner, 10*self.health, MOD_SOLITUDE); + self.nextthink = time + .15; + } +}; + +void( float w_heat ) W_FirePPistol = +{ + local entity plasma; + local float ptake; + local vector dir; + muzzleflash4(); + sound (self, CHAN_WEAPON, "weapons/ppist.wav", 1, ATTN_NORM); + + VK_smallkick(self); + + if (w_heat < 3) + ptake = 1; + else if (w_heat < 7) + ptake = 2; + else if (w_heat < 12) + ptake = 3; + else if (w_heat < 15) + ptake = 4; + else + ptake = 6; + + self.ammo_ppistol -= ptake; + if (self.ammo_ppistol < 0) + self.ammo_ppistol = 0; + W_UpdateAmmoCounts(self); + + plasma = spawn (); + plasma.health = ptake; + plasma.owner = self; + plasma.movetype = 9; + plasma.solid = 2; + makevectors (self.v_angle); + plasma.velocity = v_forward; + plasma.velocity = (plasma.velocity * 3000); // Note: needs sv_maxvelocity set to something like 10,000 at least! + plasma.angles = vectoangles (plasma.velocity); + plasma.touch = Plasma_Diffuse; + plasma.nextthink = (time + 5); + plasma.think = Plasma_Diffuse; + setmodel (plasma, "progs/plasma.spr"); + setsize (plasma, '0 0 0', '0 0 0'); + setorigin (plasma, ((self.origin + (v_forward * 8)) + '0 0 16')); //setorigin (plasma, ((self.origin + (v_forward * 8)) + '0 0 16')); + FireBullets(1, dir, '0.01 0.01 0', MOD_SOLITUDE); + if (ptake > 5) + ptake = 10; + + W_AddHeat ( self.weapon, ptake * 10); +}; + +/* +================================== +Fire The Shotgun +================================= +*/ +void () W_FireShotgun = +{ + local vector dir; + + sound (self, CHAN_WEAPON, "weapons/shottie.wav", 1, ATTN_NORM); + muzzleflash3(); // shottie flash + //self.punchangle_x = CONTENT_EMPTY; + self.ammo_shells2 -= 1; + self.currentammo -= 1; + W_UpdateAmmoCounts(self); + dir = aim (self, 100000); + FireBullets (10, dir, '0.15 0.15 0', MOD_SOLITUDE); + shotshells(self.origin); + pistolsmoke (self.origin + (v_forward * 13) + '0 0 14'); +}; + +/* +=============================== +Fire the Assault rifle +================================= +*/ +void () W_FireAR = +{ + local vector spread; + local entity missile; + local float r; + spread = '0.05 0.05 0.02'; + r = random(); + muzzleflash2(); //ar flash + + self.ammo_nails -= 1; + W_UpdateAmmoCounts(self); + if (r <= 0.5) +sound (self, CHAN_WEAPON, "weapons/ar1.wav", 1, ATTN_NORM); + else if (r <= 1) +sound (self, CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM); + self.punchangle_x = -2; + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_FLYMISSILE; + missile.solid = SOLID_BBOX; + missile.classname = "AR"; + +// set missile speed + + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = v_forward + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + missile.velocity = missile.velocity * 100000; + missile.angles = vectoangles(missile.velocity); + + missile.touch = ARTouch; + +// set missile duration + missile.nextthink = time + 5; + missile.think = SUB_Remove; + + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + v_forward*8 + '0 0 16'); + +}; + + +void (float int) W_FireSpikes; +/* +==================================== +Fire the SMG +==================================== +*/ +void() W_FireUzi = +{ + local vector dir, spread; + local float r; + local entity missile; + spread = '0.06 0.06 0.02'; + + r = random(); + muzzleflash3(); + sound (self, CHAN_WEAPON, "weapons/uzi.wav", 1, ATTN_NORM); + VK_smallkick(self); + self.punchangle_x = CONTENT_EMPTY; + self.ammo_hshells -= 1; + self.currentammo = self.ammo_hshells; + W_UpdateAmmoCounts(self); + dir = aim (self, 1000); +if (r <= 0.33) { +} +else if (r <= 0.66) { +} +else if (r <= 0.99) { +shotshells(self.origin); +} +else{} + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_FLYMISSILE; + missile.solid = SOLID_BBOX; + missile.classname = "SMG"; + +// set missile speed + + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = v_forward + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + missile.velocity = missile.velocity * 100000; + missile.angles = vectoangles(missile.velocity); + + missile.touch = SMGTouch; + +// set missile duration + missile.nextthink = time + 5; + missile.think = SUB_Remove; + + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + v_forward*8 + '0 0 16'); +}; + +void () W_FireNail2 = +{ + local vector dir; + + sound (self, CHAN_WEAPON, "weapons/shotgn2.wav", WEAPON_SHOTGUN, ATTN_NORM); + self.punchangle_x = CONTENT_EMPTY; + self.ammo_shells2 = (self.ammo_shells2 - WEAPON_SHOTGUN); + self.currentammo = (self.ammo_shells2 - WEAPON_SHOTGUN); + dir = aim (self, 100000); + FireBullets (WEAPON_SHOTGUN, dir, '0.07 0.07 0', MOD_SOLITUDE); +}; + +/* +============================ +What happens when the sniper bullet touches something +============================= +*/ +void () SB_Touch = +{ + local vector p_a, p_b; + local float zdif; + + self.velocity = '0 0 0'; + + if (other.takedamage) { + p_a_z = self.origin_z; + p_b_z = other.origin_z; + + zdif = vlen(p_a - p_b); + //_bprint(ftos(zdif),"\n"); + if (zdif > 20) { + T_Damage (other, self, self.owner, 150, MOD_SOLITUDE); + centerprint (self, "Headshot!\n"); } + else + { + if (other.health >= 30) + { + particle (self.origin, '0 0 0', 110, 6); + particle (self.origin, '0 0 0', 109, 6); + } + else + spawn_touchblood (8); + T_Damage (other, self, self.owner, 70, MOD_SOLITUDE); + } + } + else + { + particle (self.origin, '0 0 0', 6, 6); + particle (self.origin, '0 0 0', 11, 6); + puff_org = self.origin; + } + remove(self); +}; + +/* +==================================== +Fire the Sniper Rifle +===================================== +*/ +void() W_FireSniper = +{ + local entity fshell; + + sound (self, CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM); + + VK_bigkick(self); + shotshells(self.origin + (v_forward * 13) + '0 0 16'); + self.ammo_sniper -= 1; + W_UpdateAmmoCounts(self); + + muzzleflash2(); + fshell = spawn (); + fshell.owner = self; + fshell.movetype = 9; + fshell.solid = 2; + makevectors (self.v_angle); + fshell.velocity = v_forward; + fshell.velocity = (fshell.velocity * 999999); // Note: needs sv_maxvelocity set to something like 10,000 at least! + fshell.angles = vectoangles (fshell.velocity); + fshell.touch = SB_Touch; + fshell.nextthink = (time + 5); + fshell.think = SUB_Remove; + setmodel (fshell, "progs/sniperbullet.mdl"); + setsize (fshell, '0 0 0', '0 0 0'); + setorigin (fshell, ((self.origin + (v_forward * 8)) + '0 0 16')); //setorigin (fshell, ((self.origin + (v_forward * 8)) + '0 0 16')); + pistolsmoke (self.origin + (v_forward * 13) + '0 0 8'); +}; + +void () NeedleExplode = +{ + self.enemy.needles -= 1; + T_Damage (self.enemy, self, self.owner, 4, MOD_SOLITUDE); + sound (self, CHAN_WEAPON, "weapons/crystal.wav", 1, ATTN_NORM); + particle (self.origin, '6 6 6', 149, 20); + particle (self.origin, '12 12 0', 149, 20); + particle (self.origin, '-12 -12 0', 149, 20); + particle (self.origin, '-6 -6 -6', 149, 20); + createpinkdust(self.origin); + remove(self); +}; + +void () NeedlePreExplode = +{ + local vector m_height; + m_height_x = self.armorvalue; + + if (self.enemy.health <= 0) { + remove(self); + return; + } + + if (time > self.health) { + NeedleExplode(); + return; + } + + self.origin = self.enemy.origin + m_height; + + self.nextthink = time + .02; +}; + +void ( entity f_plyr, entity t_plyr, float at_height ) Add_Needle = +{ + local entity needle; + local float f_p_height; + f_p_height = at_height - t_plyr.origin_x; + + if (other == world) { + _bprint( "Add_Needle: Cannot assign to world! FIX!!\n"); + return; + } + + if (other.health <= 0) + return; + + t_plyr.needles += 1; + + if (t_plyr.needles >= 12) { + t_plyr.needles -= 7; + sound (self, CHAN_WEAPON, "weapons/crystal.wav", 1, ATTN_NORM); + particle (self.origin, '0 0 8', 149, 60); + createpinkdust(self.origin); + T_Damage (t_plyr, self, f_plyr, 150, MOD_SOLITUDE); + remove(self); + return; + } + + needle = spawn(); + needle.classname = "needle"; + needle.touch = SUB_Null; + needle.solid = SOLID_NOT; + needle.movetype = MOVETYPE_FLY; + needle.health = time + 3; + needle.armorvalue = f_p_height; + needle.enemy = t_plyr; + needle.owner = f_plyr; + setmodel (needle, "progs/needpro2.mdl"); + needle.think = NeedlePreExplode; + needle.nextthink = time; +}; + + +vector(entity proj) bounce_off_wall = // returns the velocity for bouncing off walls +{ + local vector vec; + local float backoff, change; + +// get the trace_plane_normal of the surface we hit + makevectors (proj.angles); + v_forward_z = v_forward_z * -1; + traceline (proj.origin, proj.origin + v_forward*64, FALSE, proj); + + if (trace_fraction == 1) + return proj.velocity; + +// the entity's velocity is not what we want, so set default + proj.velocity = v_forward * 500;//proj.old_velocity; + +// calculate dot product + backoff = (proj.velocity * trace_plane_normal); + backoff = backoff * 1.5; + +// finish + change = trace_plane_normal_x * backoff; + vec_x = proj.velocity_x - change; + + if (vec_x > -0.1 && vec_x < 0.1) + vec_x = 0; + + change = trace_plane_normal_y * backoff; + vec_y = proj.velocity_y - change; + + if (vec_y > -0.1 && vec_y < 0.1) + vec_y = 0; + + change = trace_plane_normal_z * backoff; + vec_z = proj.velocity_z - change; + + if (vec_z > -0.1 && vec_z < 0.1) + vec_z = 0; + sound (self, CHAN_WEAPON, "weapons/nb.wav", 1, ATTN_NORM); +// set correct angles of our new velocity + proj.angles = vectoangles (vec); + // this is required to make downward slopes not stop the projectile + proj.flags = proj.flags - ( proj.flags & FL_ONGROUND ); + return vec; +} + +void () bounce_a = +{ + self.velocity = bounce_off_wall( self ); + + self.nextthink = (time + 0.2); + self.think = NeedlerHome; +}; + +void () Bounce_Off_Walls = +{ + self.nextthink = time; + self.think = bounce_a; + + if (self.velocity == '0 0 0') + remove (self); +}; + + +void () Needler_Touch = +{ + if (other.takedamage != FALSE && other.health > 0) { + T_Damage (other, self, self.owner, 7, MOD_SOLITUDE); + Add_Needle(self.owner, other, self.origin_x); + } + else if (self.lives > 0) { + Bounce_Off_Walls (); + self.lives -= 1; + return; + } + + remove(self); +}; + +void() NeedlerHome = +{ + local vector dir, vtemp, wantdir; + local entity te; + local float maxmove; + maxmove = 55; // maximum xyz value we're allowed to change in mid-air + + if (self.enemy != world && self.enemy.health > 0) { + vtemp = (self.enemy.origin + '0 0 10'); + dir = normalize ((vtemp - self.origin)); + wantdir = (dir * 550); + wantdir_x = wantdir_x - self.velocity_x; + if (wantdir_x > maxmove) + wantdir_x = maxmove; + if (wantdir_x < -maxmove) + wantdir_x = -maxmove; + wantdir_y = wantdir_y - self.velocity_y; + if (wantdir_y > maxmove) + wantdir_y = maxmove; + if (wantdir_y < -maxmove) + wantdir_y = -maxmove; + wantdir_z = wantdir_z - self.velocity_z; + if (wantdir_z > maxmove) + wantdir_z = maxmove; + if (wantdir_z < -maxmove) + wantdir_z = -maxmove; + + + self.velocity += wantdir;//(dir * 550); + } + else { + te = findradius(self.origin, 950); + while (te) + { + if ( (te.classname == "player" || te.flags & FL_MONSTER) && te.health > 0 && te != self.owner) + { + self.enemy = te; + //bprint("found enemy!\n"); + } + te = te.chain; + } + } + self.angles = vectoangles (self.velocity); + + self.nextthink = (time + 0.5); + self.think = NeedlerHome; +}; + +void() W_FireNeedler = +{ + local entity fshell; + local float r; + local vector spread; + r = random(); + muzzleflash6(); + sound (self, CHAN_WEAPON, "weapons/needler.wav", 1, ATTN_NORM); + + spread = '0.04 0.04 0'; + + VK_smallkick(self); + + self.needler_heat += 1; + self.ammo_needler -= 1; + W_UpdateAmmoCounts(self); + + fshell = spawn (); + fshell.owner = self; + fshell.movetype = 9; + fshell.solid = 2; + makevectors (self.v_angle); + fshell.velocity = v_forward + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + fshell.velocity = (fshell.velocity * 550); + fshell.angles = vectoangles (fshell.velocity); + fshell.touch = Needler_Touch; + fshell.armorvalue = time + 15; // amount of time the needler projectile should stay alive + fshell.nextthink = (time + 0.2); + fshell.think = NeedlerHome; + fshell.lives = 1; + + setmodel (fshell, "progs/needproy.mdl"); + setsize (fshell, '0 0 0', '0 0 0'); + setorigin (fshell, ((self.origin + (v_forward * 8)) + '0 0 16')); //setorigin (fshell, ((self.origin + (v_forward * 8)) + '0 0 16')); + if (pointcontents(self.origin) == CONTENT_SKY) { + remove(self); + return; + } +}; + +void () W_FirePlasmaRifle = +{ + local entity plasma; + local vector spread; + spread = '0.02 0.02 0'; + + self.prifle_heat += 1; + sound (self, CHAN_WEAPON, "weapons/tink1.wav", 1, ATTN_NORM); + + + //VK_smallkick(self); + + self.ammo_prifle -= 1; + if (self.ammo_prifle < 0) + self.ammo_prifle = 0; + W_UpdateAmmoCounts(self); + + plasma = spawn (); + plasma.health = 1; + plasma.owner = self; + plasma.movetype = 9; + plasma.solid = 2; + makevectors (self.v_angle); + plasma.velocity = v_forward + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + plasma.velocity = (plasma.velocity * 6000); // Note: needs sv_maxvelocity set to something like 10,000 at least! + plasma.angles = vectoangles (plasma.velocity); + plasma.touch = Plasma_Diffuse; + plasma.nextthink = (time + 5); + plasma.think = Plasma_Diffuse; + setmodel (plasma, "progs/PL_BULL.spr"); + setsize (plasma, '0 0 0', '0 0 0'); + setorigin (plasma, ((self.origin + (v_forward * 8)) + '0 0 16')); //setorigin (plasma, ((self.origin + (v_forward * 8)) + '0 0 16')); + + W_AddHeat ( self.weapon, 10); +}; + +float(vector veca, vector vecb) crossproduct = +{ + local float result; + result = veca_x * vecb_y - vecb_x * veca_y; + return result; +}; + +void () W_Melee = +{ + local vector source; local vector org; + local vector def; + + makevectors (self.v_angle); + source = (self.origin + '0 0 16'); + traceline (source, (source + (v_forward * IT_LIGHTNING)), FALSE, self); + if ((trace_fraction == 1)) + { + self.punchangle_x = -2; + return; + } + self.punchangle_x = CONTENT_SOLID; + org = (trace_endpos - (v_forward * 2)); + + makevectors (trace_ent.v_angle); + def = v_right; + + if (trace_ent.takedamage) + { + trace_ent.axhitme = 1; + SpawnBlood (org, 20); + + makevectors (self.v_angle); + if (crossproduct (def, v_forward) > 0) + T_Damage (trace_ent, self, self, 100, MOD_SOLITUDE); + else + T_Damage (trace_ent, self, self, 50, MOD_SOLITUDE); + } + +}; + +/* +============================================================================== + +ROCKETS + +============================================================================== +*/ + +/* +================ +W_FireRocket +================ +*/ +void() W_FireRocket = +{ + + local entity missile; + + self.ammo_rockets -= 1; + W_UpdateAmmoCounts(self); + muzzleflash3(); + sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM); + + self.punchangle_x = -2; + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_FLYMISSILE; + missile.solid = SOLID_BBOX; + missile.classname = "Rocket"; + +// set missile speed + + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = missile.velocity * 1000; + missile.angles = vectoangles(missile.velocity); + + missile.touch = Rocket_Explode0; + +// set missile duration + missile.nextthink = time + 5; + missile.think = SUB_Remove; + + setmodel (missile, "progs/missile.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + v_forward*8 + '0 0 16'); + +}; + +/* +=============================================================================== +LIGHTNING +=============================================================================== +*/ + +void(entity from, float damage, INTEGER lmod) LightningHit = +{ + TE_lightningblood(trace_endpos); + + T_Damage (trace_ent, from, from, damage, lmod); +}; + +/* +================= +LightningDamage +================= +*/ +void(vector p1, vector p2, entity from, float damage, INTEGER lmod) LightningDamage = +{ + local entity e1, e2; + local vector f; + + f = p2 - p1; + f = normalize(f); + f_x = 0 - f_y; + f_y = f_x; + f_z = 0; + f = f*16; + + e1 = e2 = world; + + traceline (p1, p2, FALSE, self); + + if (trace_ent.takedamage) + LightningHit (from, damage, lmod); + e1 = trace_ent; + + traceline (p1 + f, p2 + f, FALSE, self); + if (trace_ent != e1 && trace_ent.takedamage) + LightningHit (from, damage, lmod); + e2 = trace_ent; + + traceline (p1 - f, p2 - f, FALSE, self); + if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage) + LightningHit (from, damage, lmod); +}; + + +void() W_FireLightning = +{ + local vector org; + local float cells; + local INTEGER expmod; + + if (self.ammo_cells_real < 1) + { + W_WeaponSwitch (W_BestWeapon ()); + return; + } + +// explode if under water + if (self.waterlevel > 1) + { + if (deathmatch > 3) + { + if (random() <= 0.5) + { + T_Damage (self, self, self.owner, 4000, MOD_SELFWATER); + return; + } + } + + cells = self.ammo_cells_real; + self.ammo_cells_real = 0; + W_WeaponSwitch (W_BestWeapon ()); + expmod = MOD_SHAFTWATER; + if (self.watertype == CONTENT_SLIME) + expmod = MOD_SHAFTSLIME; + else if (self.watertype == CONTENT_LAVA) + expmod = MOD_SHAFTLAVA; + T_RadiusDamage (self, self, 35*cells, 40+35*cells, world, expmod); + return; + } + + if (self.lightning_sound < time) + { + sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM); + self.lightning_sound = time + 0.6; + } + VK_smallkick(self); + + if (deathmatch != 4) + { + self.ammo_cells_real -= 1; + W_UpdateAmmoCounts(self); + } + + org = self.origin + '0 0 16'; + + traceline (org, org + v_forward*600, TRUE, self); + + TE_lightning2(self, org, trace_endpos); + + LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30, MOD_SHAFT); +}; + +void () GrenadeExplode = +{ + if (self.selnade == GRENADE_REGULAR) + CreateExplosion(self.origin); + + else { + plasmaexplo(self.origin); + sound (self, CHAN_WEAPON, "weapons/plasma_blow.wav", 1, ATTN_NORM); + } + + T_RadiusDamage (self, self.owner, 190, 160, world, MOD_SOLITUDE); + + remove(self); +}; + +void () Stick = +{ + if (((self.enemy != world) && (self.enemy.health > 1))) + { + self.think = Stick; + self.touch = Stick; + self.origin = self.enemy.origin; + } + else + { + GrenadeExplode (); + return; + } + self.exshells = (self.exshells + 1); + if ((self.exshells > 15)) + { + GrenadeExplode (); + return; + } + self.nextthink = (time + 0.1); +}; +void () StickyTouch = +{ + if (((other == self.owner) || (other == world))) + { + return; + } + self.exshells = MSG_BROADCAST; + self.movetype = MOVETYPE_NOCLIP; + self.think = Stick; + self.touch = Stick; + self.nextthink = (time + 0.1); + self.avelocity = VEC_ORIGIN; + self.velocity = VEC_ORIGIN; + self.enemy = other; +}; + +float (entity p1, entity p2) Get_ZDiff = +{ + local vector p_a, p_b; + local float zdif; + + p_a_z = p1.origin_z; + + p_b_z = p2.origin_z; + + zdif = vlen(p_a - p_b); + + return (zdif); +} + +void () StickyNade_Stick = +{ + local vector zd; + + if (self.enemy != world && self.enemy.health > 0) { + zd_z = self.armorvalue; + + self.origin = self.enemy.origin + zd; + } + + if (self.weapon < time) { + GrenadeExplode(); + return; + } + + self.nextthink = time + 0.1; +}; + +void () GrenadeBounce = +{ + local vector spot1; + local vector spot2; + + if (self.selnade == GRENADE_STICKY) + { + if ((pointcontents (self.origin) == -6.000000)) + { + remove (self); + return; + } + if (other.takedamage) + { + if (other.origin != '0 0 0') { + self.armorvalue = Get_ZDiff( self, other ); + self.weapon = self.nextthink; + self.think = StickyNade_Stick; + self.enemy = other; + self.nextthink = time; + } + else { + sound (self, 1, "effects/bodyhit2.wav", 1, 1); + } + return; + } + if (other.speed) + { + sound (self, 1, "weapons/bounce.wav", 1, 1); + return; + } + else + { + if (self.selnade == GRENADE_REGULAR) + sound (self, 1, "weapons/bounce.wav", 1, 1); + else + sound (self, 1, "weapons/pbounce.wav", 1, 1); + self.movetype = 0.000000; +// self.solid = 0.000000; + self.solid = 2.000000; // so they can be EMP'd + spot1 = self.origin - (normalize (self.velocity) * 20.000000); + spot2 = self.origin + (normalize (self.velocity) * 20.000000); + traceline (spot1, spot2, 0.000000, self); + self.angles = (vectoangles (trace_plane_normal) + '90.000000 0.000000 0.000000'); + setorigin (self, (self.origin + (trace_plane_normal * 6.000000))); + } + } + else + { + sound (self, 1.000000, "weapons/bounce.wav", 1.000000, 1.000000); + } + if ((self.velocity == '0.000000 0.000000 0.000000')) + { + self.avelocity = '0.000000 0.000000 0.000000'; + } + self.nextthink = (time + 1.5); + self.think = GrenadeExplode; +}; +void () W_ThrowGrenade = +{ + local entity missile; + //local entity mpuff; + local float vel_up; + if (self.selnade == GRENADE_REGULAR) + sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM); + else + sound (self, CHAN_WEAPON, "weapons/plasma_throw.wav", 1, ATTN_NORM); + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_BOUNCE; + missile.solid = SOLID_BBOX; + missile.classname = "grenade"; + makevectors (self.v_angle); + // looking straight up, don't do "up" velocity + if (self.v_angle_x <= -80) + vel_up = 150 + (self.v_angle_x * 2); + else + vel_up = 130; + + missile.velocity = (v_forward * 320) + (v_up * vel_up) + (v_right * 5); + + missile.avelocity = '300 300 300'; // FIXME: position your grenade model properly! it orbits instead of spinning! + missile.angles = vectoangles (missile.velocity); + missile.selnade = self.selnade; + missile.touch = GrenadeBounce; + //missile.nextthink = (time + 1.5); + //missile.think = GrenadeExplode; + if (self.selnade == GRENADE_STICKY) + setmodel (missile, "progs/plasgren.mdl"); + else + setmodel (missile, "progs/fraggren.mdl"); + + setsize (missile, VEC_ORIGIN, VEC_ORIGIN); + setorigin (missile, ((self.origin + '0 0 16') + (v_right * CONTENT_SKY))); +}; + +//============================================================================= +void(float ox) W_FireSpikes = +{ + if (self.ammo_nails_real < 1) + { + W_WeaponSwitch (W_BestWeapon ()); + return; + } + + sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM); + if (deathmatch != 4) + { + self.ammo_nails_real -= 1; + W_UpdateAmmoCounts(self); + } + + VK_smallkick(self); + PRJ_FireProjectile(self, + "progs/spike.mdl", + self.origin + '0 0 16' + v_right*ox, + aim(self, 1000) * 1000, + PE_SPIKE, + 9, + MOD_SPIKE, + 6); +}; + +void() W_FireSuperSpikes22 = +{ + if (self.ammo_nails_real < 2) + { + W_FireSpikes(0); + return; + } + + sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM); + if (deathmatch != 4) + { + //self.ammo_nails_real -= 2; + self.ammo_hshells -= 2; + W_UpdateAmmoCounts(self); + } + + VK_smallkick(self); + PRJ_FireProjectile(self, + "progs/s_spike.mdl", + self.origin + '0 0 16', + aim(self, 1000) * 1000, + PE_SUPERSPIKE, + 18, + MOD_SUPERSPIKE, + 6); +}; + +/* +=============================================================================== + +PLAYER WEAPON USE + +=============================================================================== +*/ +// different from W_CheckNoAmmo due to SSG/SNG being able to fire 1 shot instead of 2... +BOOL(float wep) W_HasAmmo = +{ + switch (wep) + { + case IT_SHOTGUN: + return self.ammo_shells_real >= 1; + case IT_SUPER_SHOTGUN: + return self.ammo_shells_real >= 2; + case IT_NAILGUN: + return self.ammo_nails_real >= 1; + case IT_SUPER_NAILGUN: + return self.ammo_nails_real >= 2; + case IT_GRENADE_LAUNCHER: + case IT_ROCKET_LAUNCHER: + return self.ammo_rockets_real >= 1; + case IT_LIGHTNING: + return self.ammo_cells_real >= 1; + } + + return TRUE; +}; + +void() W_UpdateWeapon = +{ + player_run (); // get out of any weapon firing states + + self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) ); + + switch (self.weapon) + { + case WEAPON_PISTOL: + self.weaponmodel = "progs/v_shot.mdl"; + self.items = self.items | IT_SHELLS; + self.ammo_type = AT_SHELLS; + break; + case WEAPON_SKULL: + self.weaponmodel = "GameTypes/OddBall/v_skull.mdl"; + self.items = self.items | IT_SHELLS; + self.ammo_type = AT_SHELLS; + break; + case WEAPON_SHOT: + self.weaponmodel = "progs/v_shot2.mdl"; + self.items = self.items | IT_SHELLS; + self.ammo_type = AT_SHELLS; + break; + case WEAPON_AR: + self.weaponmodel = "progs/v_nail.mdl"; + self.items = self.items | IT_NAILS; + self.ammo_type = AT_NAILS; + break; + case WEAPON_UZI: + self.weaponmodel = "progs/v_uzi.mdl"; + self.items = self.items | IT_NAILS; + self.ammo_type = AT_NAILS; // solitude: ammo_hshells + break; + case WEAPON_SNIPER: + self.weaponmodel = "progs/v_sniper.mdl"; + self.items = self.items | IT_SHELLS; + self.ammo_type = AT_SHELLS; + break; + case WEAPON_RL: + self.weaponmodel = "progs/v_rocket.mdl"; + self.items = self.items | IT_ROCKETS; + self.ammo_type = AT_ROCKETS; + break; + case WEAPON_PPISTOL: + self.weaponmodel = "progs/v_plpist.mdl"; + self.items = self.items | IT_CELLS; + self.ammo_type = AT_CELLS; + break; + case WEAPON_SWORD: + self.weaponmodel = "progs/v_axe.mdl"; + self.items = self.items | IT_CELLS; + self.ammo_type = AT_CELLS; + break; + case WEAPON_NEEDLER: + self.weaponmodel = "progs/v_needle.mdl"; + self.items = self.items | IT_CELLS; + self.ammo_type = AT_CELLS; + break; + case WEAPON_PRIFLE: + self.weaponmodel = "progs/v_plrifle.mdl"; + self.items = self.items | IT_CELLS; + self.ammo_type = AT_CELLS; + break; + default: + self.weaponmodel = ""; + } + + self.weaponframe = 0; +}; + +void(float weap) W_WeaponSwitch = +{ + if (self.weaponmodel != "" && self.weaponframe > 0 && self.weaponframe < 4) // xavior: hackish - may need other checks in the future (frames 1 - 4 are generally firing frames) + return; + + // skip weapon model/ammo_type update if this isn't a new weapon + if (self.weapon != weap) + { + self.weapon = weap; + W_UpdateWeapon(); + } + + // always update ammo count + W_UpdateAmmoCounts(self); + + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; +}; + +float() W_BestWeapon = +{ + float fl; + + if (cvar("nobest") == 0) // solitude: debug + return (self.weapon); + + if (self.waterlevel <= 1) + fl = IT_LIGHTNING; + else + fl = IT_SUPER_NAILGUN; + + while (1) + { + if ( (self.items & fl) && W_HasAmmo(fl) ) + return fl; + + // best weapon order + switch (fl) + { + case IT_SKULL: + fl = IT_LIGHTNING; + break; + case IT_LIGHTNING: + fl = IT_SUPER_NAILGUN; + break; + case IT_SUPER_NAILGUN: + fl = IT_SUPER_SHOTGUN; + break; + case IT_SUPER_SHOTGUN: + fl = IT_NAILGUN; + break; + case IT_NAILGUN: + fl = IT_SHOTGUN; + break; + case IT_SHOTGUN: + default: + return IT_AXE; // so we don't get an infinite loop with certain engines + } + } +}; + +BOOL() W_CheckNoAmmo = +{ + if (self.currentammo > 0) + return TRUE; + + if (self.weapon == IT_AXE) + return TRUE; + + W_WeaponSwitch (W_BestWeapon ()); + +// drop the weapon down + return FALSE; +}; + +/* +============ +W_Attack + +An attack impulse can be triggered now +============ +*/ +void() player_shot1; + +// Solitude stuff +void () player_hshot; +void () player_hshot_melee; +void () player_uzi_reload; +void () player_shot_melee; +void () player_shot2_melee; +void () player_nail_melee; +void () player_shot_throw; +void () player_shot2_throw; +void () player_nail_throw; + +void () player_rl_reload; +void () player_rl_throw; +void () player_rl_melee; + +void () player_uzi_throw; + +void () player_sniper_melee; +void () player_sniper_throw; + +//void() player_nail1; +void() player_nail2; +void() muzzleflash; + +void() W_Attack = +{ + float r; + local float heat_multi, i; + local vector source; + + if (!W_CanFire (self)) { + if (self.currentammo == 0) { + if (self.reload_time > time) + return; + reload (); + if (self.needler_heat > 0) + self.needler_heat = 0; + if (self.prifle_heat > 0) + self.prifle_heat = 0; + } + return; + } + + makevectors (self.v_angle); // calculate forward angle for velocity + self.show_hostile = time + 1; // wake monsters up + + if (self.weaponstate == WS_IDLE) // start delay + self.delay = time + 0.1; + + // animations are dealt with here + switch (self.weapon) + { + case WEAPON_PISTOL: + muzzleflash(); + //_bprint(ftos(self.weaponframe), "\n"); + self.weaponframe = 1; + self.wepanim = 1; + self.weaponframe_time = time + 0.1; + break; + case IT_SKULL: + muzzleflash(); + self.weaponframe = 1; + self.wepanim = 1; + break; + case IT_NAILGUN: + muzzleflash(); + self.weaponframe = 1; + self.wepanim = 1; + break; + case IT_SUPER_NAILGUN: + self.weaponframe = WEAPON_SHOTGUN; + player_nail2(); + /* + muzzleflash(); + if (self.weaponframe == 0) + self.weaponframe = 1; + + if (self.weaponframe & 1) + player_nail1(); + else + player_nail2(); + break; + */ + case IT_GRENADE_LAUNCHER: + case IT_ROCKET_LAUNCHER: + self.weaponframe = 1; + muzzleflash(); + //player_rocket1(); + break; + case WEAPON_PPISTOL: + heat_multi = 1; + + i = 0; + while (i < 8) { + i++; + if (self.weaponheat < i*heat_multi) { + self.weaponframe = 4 + i; + break; + } + } + + self.weaponheat++; + if (i >= 8) { + if (self.weaponframe > 13) + self.weaponframe = 12; + else + self.weaponframe++; + } + + if (self.weaponheat > 14) + self.weaponheat = 15; + if (!self.button0 || self.weaponheat > 15) { + muzzleflash(); + W_FirePPistol ( self.weaponheat ); + self.weaponheat = 0; + self.weaponframe_time = time + 0.1; + + if (self.exppistol >= 100) { + self.wepanim = 0; + self.exppistol = 99; + W_UpdateAmmoCounts(self); + self.weaponframe = 16; + player_reload1(); + } + else { + self.weaponframe = 1; + self.wepanim = 1; + } + } + else + self.weaponframe_time = time + 0.2; + + break; + case WEAPON_SWORD: + // See if we should perform a lunge + makevectors (self.v_angle); + source = self.origin + '0 0 16'; + traceline (source, source + v_forward*120, FALSE, self); + + if (trace_ent.classname == "player" && trace_ent.health > 0) { + self.weaponframe = 9; + self.velocity = v_forward*620; + } + else { + r = random(); + + if (r < 0.5) + self.weaponframe = 19; + else + self.weaponframe = 26; + } + self.wepanim = 1; + self.weaponframe_time = time + 0.1; + break; + case WEAPON_PRIFLE: + muzzleflash(); + self.weaponframe = 1; + self.wepanim = 1; + self.weaponframe_time = time + 0.065; + break; + case WEAPON_PISTOL: + muzzleflash(); + self.weaponframe = 1; + self.wepanim = 1; + self.weaponframe_time = time + 0.1; + break; + case WEAPON_SKULL: + muzzleflash(); + self.weaponframe = 1; + self.wepanim = 1; + self.weaponframe_time = time + 0.1; + break; + default: + muzzleflash(); + self.weaponframe = 1; + self.wepanim = 1; + self.weaponframe_time = time + 0.1; + break; + } + + SuperDamageSound(); + + // firing is done here (r is used for round time instead of a temp here) + switch (self.weapon) + { + case WEAPON_PISTOL: + W_FirePistol (); + r = 0.3; + break; + case WEAPON_SKULL: + W_FireSkull (); + r = 0.3; + break; + case WEAPON_SHOT: + W_FireShotgun (); + r = 0.65; + break; + case WEAPON_AR: + W_FireAR(); + r = 0.11; + break; + case WEAPON_RL: + W_FireRocket(); + r = 1.6; + break; + case WEAPON_UZI: + W_FireUzi(); + r = 0.06; + break; + case WEAPON_SNIPER: + W_FireSniper(); + r = 0.8; + break; + case WEAPON_PPISTOL: + //W_FirePPistol(); + r = 0.15; + break; + case WEAPON_SWORD: + //W_FireSword(0); + r = 0.6; + break; + case WEAPON_NEEDLER: + W_FireNeedler(); + if (self.needler_heat > 10) + r = 0.07; + else if (self.needler_heat > 5) + r = 0.12; + else + r = 0.17; + break; + case WEAPON_PRIFLE: + W_FirePlasmaRifle(); + if (self.prifle_heat > 8) + r = 0.125; + else if (self.prifle_heat > 3) + r = 0.15; + else + r = 0.175; + break; + } + + + if (self.weaponstate == WS_IDLE) + self.weaponstate = WS_FIRING1; + + // advance attack time + if (self.attack_finished <= time) + self.attack_finished = self.attack_finished + r; + + // Frikbot - reloading + if (self.ishuman != TRUE) { + //_bprint(ftos(self.currentammo),"\n"); + if (self.currentammo <= 0) { + reload (); + self.currentammo = 1; // so he doesn't run to the player + return; + } + } +}; + +/* +============ +W_ChangeWeapon + +============ +*/ +void() W_ChangeWeapon = +{ + local float fl; + + switch (self.impulse) + { + case 1: + fl = IT_AXE; + break; + case 2: + fl = IT_SHOTGUN; + break; + case 3: + fl = IT_SUPER_SHOTGUN; + break; + case 4: + fl = IT_NAILGUN; + break; + case 5: + fl = IT_SUPER_NAILGUN; + break; + case 6: + fl = IT_GRENADE_LAUNCHER; + break; + case 7: + fl = IT_ROCKET_LAUNCHER; + break; + case 8: + fl = IT_LIGHTNING; + break; + } + + + if (!(self.items & fl)) + { // don't have the weapon or the ammo + sprint1 (self, PRINT_HIGH, "no weapon.\n"); + return; + } + +/* if (!W_HasAmmo(fl)) + { // don't have the ammo + sprint1 (self, PRINT_HIGH, "not enough ammo.\n"); + return; + }*/ + +// +// set weapon, set ammo +// + W_WeaponSwitch (fl); +}; + +/* +============ +CheatCommand +============ +*/ +void() CheatCommand = +{ + if (deathmatch || coop) + return; + +#ifndef IMPULSE9 + bprint("Impulse 9 disabled. Use Impulses 14 through 26 to spawn all weapons.\n"); +#else + self.ammo_rockets_real = 100; + self.ammo_nails_real = 200; + self.ammo_shells_real = 100; + self.ammo_cells_real = 100; + self.items |= IT_AXE | + IT_SHOTGUN | + IT_SUPER_SHOTGUN | + IT_NAILGUN | + IT_SUPER_NAILGUN | + IT_GRENADE_LAUNCHER | + IT_ROCKET_LAUNCHER | + IT_LIGHTNING | + IT_AXE | + WEAPON_NEEDLER | + WEAPON_PRIFLE | + WEAPON_SKULL | + IT_KEY1 | IT_KEY2; + W_WeaponSwitch (IT_ROCKET_LAUNCHER); +#endif +}; + +/* +============ +CycleWeaponCommand + +Go to the next weapon with ammo +============ +*/ +void() CycleWeaponCommand = +{ + local float w; + w = self.weapon; + + while (1) + { + switch (w) + { + case IT_LIGHTNING: + w = IT_AXE; + break; + case IT_AXE: + w = IT_SHOTGUN; + break; + case IT_SHOTGUN: + w = IT_SUPER_SHOTGUN; + break; + case IT_SUPER_SHOTGUN: + w = IT_NAILGUN; + break; + case IT_NAILGUN: + w = IT_SUPER_NAILGUN; + break; + case IT_SUPER_NAILGUN: + w = IT_GRENADE_LAUNCHER; + break; + case IT_GRENADE_LAUNCHER: + w = IT_ROCKET_LAUNCHER; + break; + case IT_ROCKET_LAUNCHER: + w = WEAPON_NEEDLER; + break; + case WEAPON_NEEDLER: + w = WEAPON_PRIFLE; + break; + case WEAPON_PRIFLE: + w = WEAPON_SKULL; + break; + case WEAPON_SKULL: + w = IT_LIGHTNING; + break; + } + + if ( (self.items & w) /*&& W_HasAmmo(w)*/ ) + { + W_WeaponSwitch (w); + return; + } + } + +}; + + +/* +============ +CycleWeaponReverseCommand + +Go to the prev weapon with ammo +============ +*/ +void() CycleWeaponReverseCommand = +{ + local float w; + w = self.weapon; + + while (1) + { + switch (w) + { + case IT_LIGHTNING: + w = IT_ROCKET_LAUNCHER; + break; + case IT_ROCKET_LAUNCHER: + w = IT_GRENADE_LAUNCHER; + break; + case IT_GRENADE_LAUNCHER: + w = IT_SUPER_NAILGUN; + break; + case IT_SUPER_NAILGUN: + w = IT_NAILGUN; + break; + case IT_NAILGUN: + w = IT_SUPER_SHOTGUN; + break; + case IT_SUPER_SHOTGUN: + w = IT_SHOTGUN; + break; + case IT_SHOTGUN: + w = IT_AXE; + break; + case IT_AXE: + w = IT_LIGHTNING; + break; + } + + if ( (self.items & w) && W_HasAmmo(w) ) + { + W_WeaponSwitch (w); + return; + } + } + +}; + + +/* +============ +ServerflagsCommand + +Just for development +============ +*/ +void() ServerflagsCommand = +{ + if (deathmatch || coop) + return; + + serverflags = serverflags * 2 + 1; +}; + +// self heal +void () Heal = +{ +if (self.health >= 120) +particle (self.origin, '0 0 15',110, 10); +else +particle (self.origin, '0 0 10', 110, 1); + self.health = (self.health + 0.5); +}; + +// Solitude Reload +void () reload = +{ + if (self.reload_time > time) + return; + if ( (self.weapon == WEAPON_SHOT) && (self.weaponframe != 0) ) + return; + if (self.armorvalue > 0 && self.currentammo != W_GetMaxClip(self.weapon, 1)) { + switch (self.weapon) { + case WEAPON_PISTOL: + { + sound (self, CHAN_WEAPON, "weapons/reload/pistol.wav", 1, ATTN_NORM); + self.weaponframe = WEAPON_BIG; + break; + } + case WEAPON_SHOT: + { + sound (self, CHAN_WEAPON, "weapons/reload/shottie.wav", 1, ATTN_NORM); + self.weaponframe = 10; + break; + } + case WEAPON_AR: + { + sound (self, CHAN_WEAPON, "weapons/reload/ar.wav", 1, ATTN_NORM); + self.weaponframe = 5; + break; + } + case WEAPON_SNIPER: + { + sound (self, CHAN_WEAPON, "weapons/reload/sniper.wav", 1, ATTN_NORM); + self.weaponframe = 7; + break; + } + case WEAPON_RL: + { + sound (self, CHAN_WEAPON, "weapons/reload/rocket.wav", 1, ATTN_NORM); + self.weaponframe = 11; + break; + } + case WEAPON_NEEDLER: + { + sound (self, CHAN_WEAPON, "weapons/reload/needler.wav", 1, ATTN_NORM); + self.weaponframe = 5; + break; + } + case WEAPON_PPISTOL: + { + return; // No manual reload + } + default: + { + sound (self, CHAN_WEAPON, "weapons/reload/uzi.wav", 1, ATTN_NORM); + self.weaponframe = 4; + break; + } + } + self.attack_finished = (time + 0.2); + player_reload1 (); // now that we set the start frame, begin the reload + } +}; + +/* +============ +ImpulseCommands + +============ +*/ +void() ImpulseCommands = +{ + if (self.impulse == 106) + { + if (self.crouch == 0) + { + self.crouch = 1; + setsize (self, '-16 -16 -24', '16 16 0'); + self.view_ofs = '0 0 10'; + stuffcmd(self,"cl_forwardspeed 100 \n"); + stuffcmd(self,"cl_backspeed 90 \n"); + stuffcmd(self,"cl_sidespeed 100 \n"); + } + else if (self.crouch== 1) + { + self.crouch= 0; + setsize (self, '-16 -16 -24', '16 16 32'); + self.view_ofs = '0 0 22'; + stuffcmd(self,"cl_forwardspeed 200 \n"); + stuffcmd(self,"cl_backspeed 200 \n"); + stuffcmd(self,"cl_sidespeed 200 \n"); + player_stand1 (); + } + } + if (self.weaponheat) + return; + + switch (self.impulse) { + case 1 .. 8: + W_ChangeWeapon (); + break; + case 9: + CheatCommand (); + break; + case 10: + CycleWeaponCommand(); + player_pull(); + break; + case 11: + WeaponZoom (); + break; + case 13: + W_UpdateAmmoCounts(self); + if (self.pickup_time > time) { + self.canpickup_time = time + .1; + return; + } + if (self.pickup_time > time) { + self.canpickup_time = time + .1; + return; + } +// if (time < self.attack_finished) +// return; + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + reload (); + break; + case 14: + ThrowWeapon(WEAPON_PISTOL, 0); + break; + case 30: + ThrowWeapon(WEAPON_SKULL, 0); + break; + case 15: + ThrowWeapon(WEAPON_SHOT, 0); + break; + case 16: + ThrowWeapon(WEAPON_AR, 0); + break; + case 17: + ThrowWeapon(WEAPON_UZI, 0); + break; + case 18: + ThrowWeapon(WEAPON_RL, 0); + break; + case 19: + ThrowWeapon(WEAPON_SNIPER, 0); + break; + case 20: + ThrowWeapon(WEAPON_PPISTOL, 0); + break; + case 21: + ThrowWeapon(WEAPON_SWORD, 0); + break; + case 22: + ThrowWeapon(WEAPON_NEEDLER, 0); + break; + case 23: + ThrowWeapon(WEAPON_PRIFLE, 0); + break; + case 25: + ThrowWeapon(666, 0); + break; + case 26: + ThrowWeapon(667, 0); + break; + case 50: + stuffcmd( self, "play sound/music/Solitude_MainTheme_Low.wav\n" ); + break; + case 29: + { + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + pre_player_melee (); + break; + } + case 29: + { + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + pre_player_melee (); + break; + } + case 27: + { + if (self.selnade == 1) + { + if (self.nade_lives <= 0) + return; + self.nade_lives = self.nade_lives; + self.selnade = 0; + NadeCounter(); + sound (self, CHAN_WEAPON, "weapons/grenpick.wav", 1, ATTN_NORM); + + } + else + { + if (self.selnade == 0) + { + if (self.plasma_lives <= 0) + return; + self.plasma_lives = self.plasma_lives; + self.selnade = 1; + NadeCounter(); + sound (self, CHAN_WEAPON, "weapons/pbounce.wav", 1, ATTN_NORM); + } + } + break; + } + case 28: //Limiter for stopping a Nade throw if you don't have enough nades. + { + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + if (self.selnade == GRENADE_REGULAR) + { + if (self.nade_lives > 0) + { + pre_player_throw_grenade (); + self.nade_lives -= 1; + NadeCounter(); + return; + } + else + centerprint (self, "No Grenades\n"); + } + else + { + if (self.plasma_lives > 0) { + pre_player_throw_grenade (); + self.plasma_lives -= 1; + NadeCounter(); + return; } + else + centerprint (self, "No Plasma Grenades\n"); + } + break; + } + } + + + self.impulse = 0; +}; + +/* +============ +W_HandlePlayerFrame + +Handle player weapon model +============ +*/ +// ADDME: This function is actually very useful, but my lazy self is not making full use out of it. +// what shoudl be done in the future is allow this function to handle ALL first-person weapon anims +// including melee, throwgren, fire, etc. Right now it only handles a few weapons firing. The rest +// is done in player.qc >.< +// - avirox +void() W_HandlePlayerFrame = +{ + if (!self.weaponframe && !self.wepanim) + return; + + if (self.weaponframe_time >= time) + return; + + switch (self.weapon) + { + case WEAPON_PISTOL: + if (self.weaponframe > 3) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 3) + self.weaponframe = 0; + + //_bprint(ftos(self.weaponframe),"\n"); + break; + case WEAPON_SKULL: + self.wepanim = 0; // No Current Animations + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 16) + self.weaponframe = 0; + break; + case WEAPON_SHOT: + if (self.weaponframe > 9) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 9) + self.weaponframe = 0; + + //_bprint(ftos(self.weaponframe),"\n"); + break; + case WEAPON_AR: + if (self.weaponframe > 3) + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 3) + self.weaponframe = 0; + break; + + case WEAPON_UZI: + // cycle until fire button is released + if (self.weaponframe > 3) + return; + if (self.currentammo == 0) { + self.weaponframe = 0; + return; + } + if (self.weaponstate != WS_IDLE) + { + self.weaponframe_time = time + 0.1; + self.weaponframe = self.weaponframe + 1; + if (self.weaponframe > 2) + self.weaponframe = 1; + } + else + self.weaponframe = 0; + + break; + case WEAPON_RL: + if (self.weaponframe > 11) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 10) + self.weaponframe = 0; + break; + case WEAPON_SNIPER: + if (self.weaponframe > 3) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 3) + self.weaponframe = 0; + break; + case WEAPON_PPISTOL: + if (self.weaponframe > 3) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 3) + self.weaponframe = 0; + break; + case WEAPON_SWORD: + if (self.weaponframe > 18 && self.weaponframe < 25) { // Lunge attack + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe == 21) + W_FireSword(1); + if (self.weaponframe > 24) + self.weaponframe = 0; + } + else if (self.weaponframe > 25 && self.weaponframe < 32) { + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe == 29) + W_FireSword(0); + if (self.weaponframe > 31) + self.weaponframe = 0; + } + else { + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe == 15) + W_FireSword(0); + if (self.weaponframe > 18) + self.weaponframe = 0; + } + break; + case WEAPON_NEEDLER: + if (self.weaponframe > 3) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 3) + self.weaponframe = 0; + break; + case WEAPON_PRIFLE: + if (self.weaponframe > 3) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 3) + self.weaponframe = 0; + break; + default: + // Solitude + if (self.weaponframe > 4) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 6) + self.weaponframe = 0; + } + + self.wepanim = 0; // turn hack off +}; + +/* +============ +W_WeaponFrame + +Called every frame so impulse events can be handled as well as possible +============ +*/ +void() W_WeaponFrame = +{ + local INTEGER scount; + + W_HandlePlayerFrame(); + + + if ((self.health < self.ohealth)) + { + self.regen = (time + 3); + } + self.ohealth = self.health; + if (((time > self.regen) && (self.health < 130))) + { + Heal (); + } + + if (time < self.attack_finished) + return; + + if (self.impulse) + ImpulseCommands (); + + + +// check for attack + if (self.button0) + { + scount = 0; + // play catchup but don't allow more than 4 shots per frame + while (self.attack_finished <= time) + { + if (scount >= 4) + { + self.attack_finished = time; + break; + } + + W_Attack(); + scount++; + } + } + else + { + if (self.weaponheat > 0) { + W_Attack(); + } + if (self.needler_heat > 0) + self.needler_heat = 0; + if (self.prifle_heat > 0) + self.prifle_heat = 0; + self.attack_finished = time; + self.weaponstate = WS_IDLE; + } +}; + +/* +======== +SuperDamageSound + +Plays sound if needed +======== +*/ +void() SuperDamageSound = +{ + if (self.super_damage_finished > time) + { + if (self.super_sound < time) + { + self.super_sound = time + 1; + sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM); + } + } + return; +}; + +/* +void() testfunction = +{ + local vector v; + local float a, b, c; + + a = 2; + b = 4; + c = 6; + a *= 2; + b *= 2; + c *= 2; + v = '2 4 6'; + v *= 2; + if (!a && !b && !c) + return; + + if (!v) + return; + + v_x = 23; + + if (self.health && self.ammo_shells && self.ammo_cells) + return; +}; +*/ + +// GOLD: this is now a wrapper for W_UpdateAmmoCounts +void () W_SetCurrentAmmo = +{ + self.weaponframe = 0; + W_UpdateAmmoCounts(self); +/* + player_run (); + self.items = (self.items - (self.items & (((IT_SHELLS | IT_NAILS) | IT_ROCKETS) | IT_CELLS))); + if ((self.weapon == IT_AXE)) + { + self.currentammo = MSG_BROADCAST; + self.weaponmodel = "progs/v_axe.mdl"; + self.weaponframe = MSG_BROADCAST; + } + else + { + if ((self.weapon == IT_SHOTGUN)) + { + self.currentammo = self.ammo_shells; + self.weaponmodel = "progs/v_shot.mdl"; + self.weaponframe = MSG_BROADCAST; + self.items = (self.items | IT_SHELLS); + } + else + { + if ((self.weapon == IT_SUPER_SHOTGUN)) + { + self.currentammo = self.ammo_shells2; + self.weaponmodel = "progs/v_shot2.mdl"; + self.weaponframe = MSG_BROADCAST; + } + else + { + if ((self.weapon == IT_NAILGUN)) + { + self.currentammo = self.ammo_nails; + self.weaponmodel = "progs/v_nail.mdl"; + self.weaponframe = MSG_BROADCAST; + } + else + { + if ((self.weapon == IT_SUPER_NAILGUN)) + { + self.currentammo = self.ammo_hshells; + self.weaponmodel = "progs/v_shotgun.mdl"; + self.weaponframe = MSG_BROADCAST; + } + else + { + if ((self.weapon == IT_GRENADE_LAUNCHER)) + { + self.currentammo = self.ammo_rockets; + self.weaponmodel = "progs/v_rock.mdl"; + self.weaponframe = MSG_BROADCAST; + self.items = (self.items | IT_ROCKETS); + } + else + { + if ((self.weapon == IT_ROCKET_LAUNCHER)) + { + self.currentammo = self.ammo_rockets; + self.weaponmodel = "progs/v_rocket.mdl"; + self.weaponframe = MSG_BROADCAST; + self.items = (self.items | IT_ROCKETS); + } + else + { + if ((self.weapon == IT_LIGHTNING)) + { + self.currentammo = self.ammo_cells; + self.weaponmodel = "progs/v_light.mdl"; + self.weaponframe = MSG_BROADCAST; + self.items = (self.items | IT_CELLS); + } + else + { + self.currentammo = MSG_BROADCAST; + self.weaponmodel = ""; + self.weaponframe = MSG_BROADCAST; + } + } + } + } + } + } + } + } + */ +} + + diff --git a/r17/Revamped src/Revamped QC/world.qc b/r17/Revamped src/Revamped QC/world.qc new file mode 100755 index 00000000..3f2c31a7 --- /dev/null +++ b/r17/Revamped src/Revamped QC/world.qc @@ -0,0 +1,387 @@ + +void() main = +{ +// these are just commands the the prog compiler to copy these files + + precache_file ("progs.dat"); + precache_file ("gfx.wad"); + precache_file ("quake.rc"); + precache_file ("default.cfg"); + + precache_file ("end1.bin"); + precache_file2 ("end2.bin"); + + precache_file ("demo1.dem"); + precache_file ("demo2.dem"); + precache_file ("demo3.dem"); + +// +// these are all of the lumps from the cached.ls files +// + precache_file ("gfx/palette.lmp"); + precache_file ("gfx/colormap.lmp"); + + precache_file2 ("gfx/pop.lmp"); + + precache_file ("gfx/complete.lmp"); + precache_file ("gfx/inter.lmp"); + + precache_file ("gfx/ranking.lmp"); + precache_file ("gfx/vidmodes.lmp"); + precache_file ("gfx/finale.lmp"); + precache_file ("gfx/conback.lmp"); + precache_file ("gfx/qplaque.lmp"); + + precache_file ("gfx/menudot1.lmp"); + precache_file ("gfx/menudot2.lmp"); + precache_file ("gfx/menudot3.lmp"); + precache_file ("gfx/menudot4.lmp"); + precache_file ("gfx/menudot5.lmp"); + precache_file ("gfx/menudot6.lmp"); + + precache_file ("gfx/menuplyr.lmp"); + precache_file ("gfx/bigbox.lmp"); + precache_file ("gfx/dim_modm.lmp"); + precache_file ("gfx/dim_drct.lmp"); + precache_file ("gfx/dim_ipx.lmp"); + precache_file ("gfx/dim_tcp.lmp"); + precache_file ("gfx/dim_mult.lmp"); + precache_file ("gfx/mainmenu.lmp"); + + precache_file ("gfx/box_tl.lmp"); + precache_file ("gfx/box_tm.lmp"); + precache_file ("gfx/box_tr.lmp"); + + precache_file ("gfx/box_ml.lmp"); + precache_file ("gfx/box_mm.lmp"); + precache_file ("gfx/box_mm2.lmp"); + precache_file ("gfx/box_mr.lmp"); + + precache_file ("gfx/box_bl.lmp"); + precache_file ("gfx/box_bm.lmp"); + precache_file ("gfx/box_br.lmp"); + + precache_file ("gfx/sp_menu.lmp"); + precache_file ("gfx/ttl_sgl.lmp"); + precache_file ("gfx/ttl_main.lmp"); + precache_file ("gfx/ttl_cstm.lmp"); + + precache_file ("gfx/mp_menu.lmp"); + + precache_file ("gfx/netmen1.lmp"); + precache_file ("gfx/netmen2.lmp"); + precache_file ("gfx/netmen3.lmp"); + precache_file ("gfx/netmen4.lmp"); + precache_file ("gfx/netmen5.lmp"); + + precache_file ("gfx/sell.lmp"); + + precache_file ("gfx/help0.lmp"); + precache_file ("gfx/help1.lmp"); + precache_file ("gfx/help2.lmp"); + precache_file ("gfx/help3.lmp"); + precache_file ("gfx/help4.lmp"); + precache_file ("gfx/help5.lmp"); + + precache_file ("gfx/pause.lmp"); + precache_file ("gfx/loading.lmp"); + + precache_file ("gfx/p_option.lmp"); + precache_file ("gfx/p_load.lmp"); + precache_file ("gfx/p_save.lmp"); + precache_file ("gfx/p_multi.lmp"); + + + + +// sounds loaded by C code + precache_sound ("misc/menu1.wav"); + precache_sound ("misc/menu2.wav"); + precache_sound ("misc/menu3.wav"); + + precache_sound ("ambience/water1.wav"); + precache_sound ("ambience/wind2.wav"); + +// shareware + precache_file ("maps/start.bsp"); + +// registered + precache_file2 ("gfx/pop.lmp"); + + }; + +//======================= +/*QUAKED worldspawn (0 0 0) ? +Only used for the world entity. +Set message to the level name. +Set sounds to the cd track to play. + +World Types: +0: medieval +1: metal +2: base +*/ +//======================= +void() worldspawn = +{ + local float sol_grav, sol_ms; + + lastspawn = world; + spotspawn = 0; + + BotInit(); // FrikBot + ENG_Check(); + + sol_grav = cvar("sol_gravity"); + sol_ms = cvar("sol_maxspeed"); + + if (sol_grav) + cvar_set ("sv_gravity", ftos(sol_grav)); + else + cvar_set ("sv_gravity", "#DEFAULT_GRAVITY"); + + if (sol_ms) + cvar_set ("sv_maxspeed", ftos(sol_ms)); + else + cvar_set ("sv_maxspeed", "#DEFAULT_MAXSPEED"); + + cvar_set ("sv_maxvelocity", "10000"); // for the sniper projectile +#ifndef NETQUAKE +// custom map attributes + if (self.model == "maps/e1m8.bsp") + cvar_set ("sv_gravity", "100"); +#endif + +// the area based ambient sounds MUST be the first precache_sounds + +// player precaches + W_Precache (); // get weapon precaches + +// sounds used from C physics code + precache_sound ("demon/dland2.wav"); // landing thud + precache_sound ("misc/h2ohit1.wav"); // landing splash + +// setup precaches allways needed + precache_sound ("items/itembk2.wav"); // item respawn sound + precache_sound ("player/plyrjmp8.wav"); // player jump + precache_sound ("player/land.wav"); // player landing + precache_sound ("player/land2.wav"); // player hurt landing + precache_sound ("player/drown1.wav"); // drowning pain + precache_sound ("player/drown2.wav"); // drowning pain + precache_sound ("player/gasp1.wav"); // gasping for air + precache_sound ("player/gasp2.wav"); // taking breath + precache_sound ("player/h2odeath.wav"); // drowning death + + precache_sound ("misc/talk.wav"); // talk + precache_sound ("player/teledth1.wav"); // telefrag + precache_sound ("misc/r_tele1.wav"); // teleport sounds + precache_sound ("misc/r_tele4.wav"); // teleport sounds + precache_sound ("misc/r_tele5.wav"); // teleport sounds + precache_sound ("misc/r_tele2.wav"); // teleport sounds + precache_sound ("misc/r_tele3.wav"); // teleport sounds + precache_sound ("weapons/lock4.wav"); // ammo pick up + precache_sound ("weapons/pkup.wav"); // weapon up + precache_sound ("items/armor1.wav"); // armor up + precache_sound ("weapons/lhit.wav"); //lightning + precache_sound ("weapons/lstart.wav"); //lightning start + precache_sound ("items/damage3.wav"); + + precache_sound ("misc/power.wav"); //lightning for boss + +// player pain sounds + + precache_sound ("player/pain1.wav"); + +// player death sounds + precache_sound ("player/death1.wav"); + + precache_sound ("boss1/sight1.wav"); + +// ax sounds + precache_sound ("weapons/ax1.wav"); // ax swoosh + precache_sound ("player/axhit1.wav"); // ax hit meat + precache_sound ("player/axhit2.wav"); // ax hit world + + precache_sound ("player/h2ojump.wav"); // player jumping into water + precache_sound ("player/slimbrn2.wav"); // player enter slime + precache_sound ("player/inh2o.wav"); // player enter water + precache_sound ("player/inlava.wav"); // player enter lava + precache_sound ("misc/outwater.wav"); // leaving water sound + + precache_sound ("player/lburn1.wav"); // lava burn + precache_sound ("player/lburn2.wav"); // lava burn + + precache_sound ("misc/water1.wav"); // swimming + precache_sound ("misc/water2.wav"); // swimming + +// Invulnerability sounds + precache_sound ("items/protect.wav"); + precache_sound ("items/protect2.wav"); + precache_sound ("items/protect3.wav"); + + + precache_model ("progs/player.mdl"); + precache_model ("progs/eyes.mdl"); + precache_model ("progs/h_player.mdl"); + precache_sound ("player/tornoff2.wav"); + + precache_model ("progs/s_bubble.spr"); // drowning bubbles + precache_model ("progs/s_explod.spr"); // sprite explosion + + precache_model ("progs/v_axe.mdl"); + precache_model ("progs/v_shot.mdl"); + precache_model ("progs/v_nail.mdl"); + precache_model ("progs/v_rock.mdl"); + precache_model ("progs/v_shot2.mdl"); + precache_model ("progs/v_nail2.mdl"); + + precache_model ("progs/bolt.mdl"); // for lightning gun + precache_model ("progs/bolt2.mdl"); // for lightning gun + precache_model ("progs/bolt3.mdl"); // for boss shock + precache_model ("progs/lavaball.mdl"); // for testing + + precache_model ("progs/missile.mdl"); + precache_model ("progs/grenade.mdl"); + precache_model ("progs/spike.mdl"); + precache_model ("progs/s_spike.mdl"); + + precache_model ("progs/backpack.mdl"); + + precache_model ("progs/zom_gib.mdl"); + + precache_model ("progs/v_light.mdl"); + + +// +// Setup light animation tables. 'a' is total darkness, 'z' is maxbright. +// + + // 0 normal + lightstyle(0, "m"); + + // 1 FLICKER (first variety) + lightstyle(1, "mmnmmommommnonmmonqnmmo"); + + // 2 SLOW STRONG PULSE + lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); + + // 3 CANDLE (first variety) + lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); + + // 4 FAST STROBE + lightstyle(4, "mamamamamama"); + + // 5 GENTLE PULSE 1 + lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj"); + + // 6 FLICKER (second variety) + lightstyle(6, "nmonqnmomnmomomno"); + + // 7 CANDLE (second variety) + lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm"); + + // 8 CANDLE (third variety) + lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); + + // 9 SLOW STROBE (fourth variety) + lightstyle(9, "aaaaaaaazzzzzzzz"); + + // 10 FLUORESCENT FLICKER + lightstyle(10, "mmamammmmammamamaaamammma"); + + // 11 SLOW PULSE NOT FADE TO BLACK + lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba"); + + // styles 32-62 are assigned by the light program for switchable lights + + // 63 testing + lightstyle(63, "a"); +}; + +void() StartFrame = +{ + BotFrame(); // FrikBot + timelimit = cvar("timelimit") * 60; + fraglimit = cvar("fraglimit"); +#ifdef NETQUAKE + deathmatch = cvar("deathmatch"); + coop = cvar("coop"); + teamplay = cvar("teamplay"); +#endif + skill = cvar("skill"); + + framecount = framecount + 1; +}; +void() func_rotating = + +{ + + self.solid = SOLID_BSP; + + self.movetype = MOVETYPE_PUSH; + + setorigin (self, self.origin); + + setmodel (self, self.model); + + self.classname = "func_rotating"; + + setsize (self, self.mins, self.maxs); + + + + if (!self.speed) + + self.speed = 100; + + + + if (self.spawnflags & 2) // reverse direction + + self.speed = 0 - self.speed; + + + + if (self.spawnflags & 64) // not solid + + self.solid = SOLID_NOT; + + + + if (self.spawnflags & 4) + + { + + self.avelocity_z = self.speed; + + self.avelocity_x = 0; + + self.avelocity_y = 0; + + } + + else if (self.spawnflags & 8) + + { + + self.avelocity_z = 0; + + self.avelocity_x = self.speed; + + self.avelocity_y = 0; + + } + + else + + { + + self.avelocity_z = 0; + + self.avelocity_x = 0; + + self.avelocity_y = self.speed; + + } + +}; diff --git a/r17/Revamped src/revamped_src/Makefile b/r17/Revamped src/revamped_src/Makefile new file mode 100755 index 00000000..f9555d32 --- /dev/null +++ b/r17/Revamped src/revamped_src/Makefile @@ -0,0 +1,196 @@ +#================= +# ZQuake Makefile +#================= + +#============================================================================== +# Here are the targets: + +.PHONY: default all server gl soft null + +default: gl server soft +all: server gl soft null + +#============================================================================== +# Architecture detection +# +# MACHINE = i686-linux-gnu, etc +# ARCH = mingw32 x86-linux ppc-linux x86-darwin ppc-darwin +# OS = windows linux darwin + +MACHINE = $(shell $(CC) -dumpmachine) +ARCH = $(shell echo $(MACHINE) | sed -e 's/.*mingw32.*/mingw32/g' \ + -e 's/i.86/x86/g' -e 's/-gnu//' -e 's/powerpc/ppc/') + # -e 's/\-.*//g' - + +OS = $(shell echo $(ARCH) | sed -e 's/.*-//') +ifeq ($(OS),mingw32) +OS = windows +endif + +#============================================================================== + + +CC = gcc + + +PRODUCT_DIR=release +GL_OBJ_DIR=release/gl +SOFT_OBJ_DIR=release/soft +SERVER_OBJ_DIR=release/server +NULL_OBJ_DIR=release/null + + +#------------------------------------------------------------------------------ + +CFLAGS = -DVWEP_TEST -DHALFLIFEBSP +CFLAGS += -Wall -Wno-format-y2k + +# optimizations (should be only for release) +CFLAGS +=-ffast-math -fomit-frame-pointer -fexpensive-optimizations + +ifeq ($(ARCH),mingw32) + CFLAGS += -D_WIN32 -DMINGW32 +endif +ifeq ($(OS),linux) + CFLAGS += -DUSE_ALSA -DUSE_VMODE -DUSE_DGA +endif +ifeq ($(ARCH),ppc-linux) + CFLAGS += -DBIGENDIAN +endif +ifeq ($(OS),darwin) + CFLAGS += -DHAVE_STRLCPY -DHAVE_STRLCAT +endif +ifeq ($(ARCH),ppc-darwin) + CFLAGS += -DBIGENDIAN +endif + +SERVER_CFLAGS = -DSERVERONLY +GL_CFLAGS = -DGLQUAKE +SW_CFLAGS = +NULL_CFLAGS = + +#------------------------------------------------------------------------------ + +LDFLAGS = +GL_LDFLAGS = +SW_LDFLAGS = +ifeq ($(ARCH),mingw32) + LDFLAGS +=-lws2_32 -luser32 -lwinmm -ldxguid -lgdi32 + GL_LDFLAGS =-mwindows -lopengl32 + SW_LDFLAGS =-mwindows -lddraw +endif +ifeq ($(OS),darwin) + LDFLAGS +=-framework "CoreAudio" -framework OpenGL +endif +ifeq ($(OS),linux) + LDFLAGS +=-lm -lGL -lXxf86vm -lXxf86dga + # -L/usr/X11R6/lib -lX11 -lXext +endif + +#============================================================================== + +CLIENT_C_FILES = cl_cam cl_cmd cl_demo cl_draw cl_effects cl_ents cl_input \ + cl_main cl_nqdemo cl_parse cl_pred cl_sbar cl_screen cl_tent cl_view \ + console keys menu teamplay textencoding +GL_C_FILES = sv_save skin rc_wad rc_image rc_pixops \ + gl_draw gl_mesh gl_model gl_ngraph gl_ralias gl_refrag gl_rlight \ + gl_rmain gl_rmisc gl_rsprite gl_rsurf gl_texture gl_warp gl_sky +SW_C_FILES = sv_save skin rc_wad rc_image rc_pixops nonintel \ + d_edge d_fill d_init d_modech d_polyse d_sky d_sprite d_surf d_vars \ + d_zpoint r_aclip r_alias r_bsp r_draw r_edge r_efrag r_light r_main \ + r_misc r_model r_part r_rast r_scan r_sky r_sprite r_surf r_vars +SERVER_C_FILES = sv_bot sv_ccmds sv_ents sv_init sv_main sv_master \ + sv_move sv_nchan sv_phys sv_send sv_user sv_world \ + pr_cmds pr_edict pr_exec +COMMON_C_FILES = cmd cmodel com_msg com_mapcheck common crc cvar host mathlib mdfour \ + net_chan pmove pmovetst qlib q_shared version zone +NULL_C_FILES = sv_save rc_null vid_null snd_null cd_null in_null sys_null +ifeq ($(ARCH),mingw32) +ZQDS_PLATFORM_C_FILES = sys_win net_wins +ZQGL_PLATFORM_C_FILES = sys_win net_wins snd_dma snd_mem snd_mix snd_win cd_win in_win vid_wgl +ZQSW_PLATFORM_C_FILES = sys_win net_wins snd_dma snd_mem snd_mix snd_win cd_win in_win vid_ddraw +NULL_C_FILES += net_wins +else +ZQDS_PLATFORM_C_FILES = sv_sys_unix net_udp +ZQGL_PLATFORM_C_FILES = net_udp +ZQSW_PLATFORM_C_FILES = net_udp +NULL_C_FILES += net_udp +endif +ifeq ($(OS),darwin) +ZQGL_PLATFORM_C_FILES += snd_null cd_null +ZQSW_PLATFORM_C_FILES += snd_null cd_null +endif +ifeq ($(OS),linux) +ZQGL_PLATFORM_C_FILES += sys_linux cd_linux snd_dma snd_mem snd_mix snd_linux snd_oss snd_alsa vid_glx +ZQSW_PLATFORM_C_FILES += sys_linux cd_linux snd_dma snd_mem snd_mix snd_linux snd_oss snd_alsa vid_x +endif +ZQDS_C_FILES = $(SERVER_C_FILES) $(COMMON_C_FILES) $(ZQDS_PLATFORM_C_FILES) cl_null +ZQSW_C_FILES = $(CLIENT_C_FILES) $(ZQSW_PLATFORM_C_FILES) $(SW_C_FILES) $(SERVER_C_FILES) $(COMMON_C_FILES) +ZQGL_C_FILES = $(CLIENT_C_FILES) $(ZQGL_PLATFORM_C_FILES) $(GL_C_FILES) $(SERVER_C_FILES) $(COMMON_C_FILES) +ZQNULL_C_FILES = $(CLIENT_C_FILES) $(SERVER_C_FILES) $(COMMON_C_FILES) $(NULL_C_FILES) +ZQDS_C_OBJS = $(addprefix $(SERVER_OBJ_DIR)/, $(addsuffix .o, $(ZQDS_C_FILES))) +ZQGL_C_OBJS = $(addprefix $(GL_OBJ_DIR)/, $(addsuffix .o, $(ZQGL_C_FILES))) +ZQSW_C_OBJS = $(addprefix $(SOFT_OBJ_DIR)/, $(addsuffix .o, $(ZQSW_C_FILES))) +ZQNULL_C_OBJS = $(addprefix $(NULL_OBJ_DIR)/, $(addsuffix .o, $(ZQNULL_C_FILES))) + +#============================================================================== + +printvars: + @echo "MACHINE = $(MACHINE)" + @echo "ARCH = $(ARCH)" + @echo "OS = $(OS)" + @echo "" + @echo "PRODUCT_DIR = $(PRODUCT_DIR)" + @echo "" + @echo "CFLAGS = $(CFLAGS)" + @echo "LDFLAGS = $(LDFLAGS)" + +#.PHONY: server +#server: +# @echo [MAKE] server +# @make server_do +#server_do: $(PRODUCT_DIR)/zqds +server: $(PRODUCT_DIR)/zqds +$(PRODUCT_DIR)/zqds: $(ZQDS_C_OBJS) + @echo [LINK] $@ + @$(CC) -o $@ $(ZQDS_C_OBJS) $(LDFLAGS) +$(ZQDS_C_OBJS): $(SERVER_OBJ_DIR)/%.o: %.c + @-mkdir -p $(SERVER_OBJ_DIR) + @echo [CC] $< + @$(CC) $(CFLAGS) $(SERVER_CFLAGS) -c -o $@ $< +#------------------------------------------------------------------------------ +gl: $(PRODUCT_DIR)/zquake-gl +$(PRODUCT_DIR)/zquake-gl: $(ZQGL_C_OBJS) + @echo [LINK] $@ + @$(CC) -o $@ $(ZQGL_C_OBJS) $(LDFLAGS) $(GL_LDFLAGS) +$(ZQGL_C_OBJS): $(GL_OBJ_DIR)/%.o: %.c + @-mkdir -p $(GL_OBJ_DIR) + @echo [CC] $< + @$(CC) $(CFLAGS) $(GL_CFLAGS) -c -o $@ $< +#------------------------------------------------------------------------------ +soft: $(PRODUCT_DIR)/zquake +$(PRODUCT_DIR)/zquake: $(ZQSW_C_OBJS) + @echo [LINK] $@ + @$(CC) -o $@ $(ZQSW_C_OBJS) $(LDFLAGS) $(SW_LDFLAGS) +$(ZQSW_C_OBJS): $(SOFT_OBJ_DIR)/%.o: %.c + @-mkdir -p $(SOFT_OBJ_DIR) + @echo [CC] $< + @$(CC) $(CFLAGS) $(SW_CFLAGS) -c -o $@ $< +#------------------------------------------------------------------------------ +null: $(PRODUCT_DIR)/zquake-null +$(PRODUCT_DIR)/zquake-null: $(ZQNULL_C_OBJS) + @echo [LINK] $@ + @$(CC) -o $@ $(ZQNULL_C_OBJS) $(LDFLAGS) +$(ZQNULL_C_OBJS): $(NULL_OBJ_DIR)/%.o: %.c + @-mkdir -p $(NULL_OBJ_DIR) + @echo [CC] $< + @$(CC) $(CFLAGS) $(NULL_CFLAGS) -c -o $@ $< +#------------------------------------------------------------------------------ +clean: + @echo [CLEAN] + @-rm $(SERVER_OBJ_DIR)/*.o $(SOFT_OBJ_DIR)/*.o $(GL_OBJ_DIR)/*.o $(NULL_OBJ_DIR)/*.o 2>/dev/null + @-rmdir $(SERVER_OBJ_DIR) $(SOFT_OBJ_DIR) $(GL_OBJ_DIR) $(NULL_OBJ_DIR) 2>/dev/null + @-rm $(PRODUCT_DIR)/zqds $(PRODUCT_DIR)/zquake $(PRODUCT_DIR)/zquake-gl $(PRODUCT_DIR)/zquake-null 2>/dev/null + @-rm $(PRODUCT_DIR) 2>/dev/null + +#============================================================================== diff --git a/r17/Revamped src/revamped_src/Quake.sln b/r17/Revamped src/revamped_src/Quake.sln new file mode 100755 index 00000000..68f74fbc --- /dev/null +++ b/r17/Revamped src/revamped_src/Quake.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Quake_PSP", "psp\Quake_PSP.vcxproj", "{38B817AB-88C4-4ADA-8750-4187AB435363}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Quake_Win32Stubs", "win32_stubs\Quake_Win32Stubs.vcxproj", "{D94197A6-9EAA-452A-AA05-652C940D70A3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + PSP|Win32 = PSP|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {38B817AB-88C4-4ADA-8750-4187AB435363}.Debug|Win32.ActiveCfg = PSP|Win32 + {38B817AB-88C4-4ADA-8750-4187AB435363}.PSP|Win32.ActiveCfg = PSP|Win32 + {38B817AB-88C4-4ADA-8750-4187AB435363}.PSP|Win32.Build.0 = PSP|Win32 + {38B817AB-88C4-4ADA-8750-4187AB435363}.Release|Win32.ActiveCfg = PSP|Win32 + {D94197A6-9EAA-452A-AA05-652C940D70A3}.Debug|Win32.ActiveCfg = Debug|Win32 + {D94197A6-9EAA-452A-AA05-652C940D70A3}.Debug|Win32.Build.0 = Debug|Win32 + {D94197A6-9EAA-452A-AA05-652C940D70A3}.PSP|Win32.ActiveCfg = Debug|Win32 + {D94197A6-9EAA-452A-AA05-652C940D70A3}.Release|Win32.ActiveCfg = Release|Win32 + {D94197A6-9EAA-452A-AA05-652C940D70A3}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/r17/Revamped src/revamped_src/Quake.suo b/r17/Revamped src/revamped_src/Quake.suo new file mode 100755 index 00000000..034a2b86 Binary files /dev/null and b/r17/Revamped src/revamped_src/Quake.suo differ diff --git a/r17/Revamped src/revamped_src/UpgradeLog.XML b/r17/Revamped src/revamped_src/UpgradeLog.XML new file mode 100755 index 00000000..78359ca9 --- /dev/null +++ b/r17/Revamped src/revamped_src/UpgradeLog.XML @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/_UpgradeReport_Files/UpgradeReport.css b/r17/Revamped src/revamped_src/_UpgradeReport_Files/UpgradeReport.css new file mode 100755 index 00000000..3411f632 --- /dev/null +++ b/r17/Revamped src/revamped_src/_UpgradeReport_Files/UpgradeReport.css @@ -0,0 +1,207 @@ +BODY +{ + BACKGROUND-COLOR: white; + FONT-FAMILY: "Verdana", sans-serif; + FONT-SIZE: 100%; + MARGIN-LEFT: 0px; + MARGIN-TOP: 0px +} +P +{ + FONT-FAMILY: "Verdana", sans-serif; + FONT-SIZE: 70%; + LINE-HEIGHT: 12pt; + MARGIN-BOTTOM: 0px; + MARGIN-LEFT: 10px; + MARGIN-TOP: 10px +} +.note +{ + BACKGROUND-COLOR: #ffffff; + COLOR: #336699; + FONT-FAMILY: "Verdana", sans-serif; + FONT-SIZE: 100%; + MARGIN-BOTTOM: 0px; + MARGIN-LEFT: 0px; + MARGIN-TOP: 0px; + PADDING-RIGHT: 10px +} +.infotable +{ + BACKGROUND-COLOR: #f0f0e0; + BORDER-BOTTOM: #ffffff 0px solid; + BORDER-COLLAPSE: collapse; + BORDER-LEFT: #ffffff 0px solid; + BORDER-RIGHT: #ffffff 0px solid; + BORDER-TOP: #ffffff 0px solid; + FONT-SIZE: 70%; + MARGIN-LEFT: 10px +} +.issuetable +{ + BACKGROUND-COLOR: #ffffe8; + BORDER-COLLAPSE: collapse; + COLOR: #000000; + FONT-SIZE: 100%; + MARGIN-BOTTOM: 10px; + MARGIN-LEFT: 13px; + MARGIN-TOP: 0px +} +.issuetitle +{ + BACKGROUND-COLOR: #ffffff; + BORDER-BOTTOM: #dcdcdc 1px solid; + BORDER-TOP: #dcdcdc 1px; + COLOR: #003366; + FONT-WEIGHT: normal +} +.header +{ + BACKGROUND-COLOR: #cecf9c; + BORDER-BOTTOM: #ffffff 1px solid; + BORDER-LEFT: #ffffff 1px solid; + BORDER-RIGHT: #ffffff 1px solid; + BORDER-TOP: #ffffff 1px solid; + COLOR: #000000; + FONT-WEIGHT: bold +} +.issuehdr +{ + BACKGROUND-COLOR: #E0EBF5; + BORDER-BOTTOM: #dcdcdc 1px solid; + BORDER-TOP: #dcdcdc 1px solid; + COLOR: #000000; + FONT-WEIGHT: normal +} +.issuenone +{ + BACKGROUND-COLOR: #ffffff; + BORDER-BOTTOM: 0px; + BORDER-LEFT: 0px; + BORDER-RIGHT: 0px; + BORDER-TOP: 0px; + COLOR: #000000; + FONT-WEIGHT: normal +} +.content +{ + BACKGROUND-COLOR: #e7e7ce; + BORDER-BOTTOM: #ffffff 1px solid; + BORDER-LEFT: #ffffff 1px solid; + BORDER-RIGHT: #ffffff 1px solid; + BORDER-TOP: #ffffff 1px solid; + PADDING-LEFT: 3px +} +.issuecontent +{ + BACKGROUND-COLOR: #ffffff; + BORDER-BOTTOM: #dcdcdc 1px solid; + BORDER-TOP: #dcdcdc 1px solid; + PADDING-LEFT: 3px +} +A:link +{ + COLOR: #cc6633; + TEXT-DECORATION: underline +} +A:visited +{ + COLOR: #cc6633; +} +A:active +{ + COLOR: #cc6633; +} +A:hover +{ + COLOR: #cc3300; + TEXT-DECORATION: underline +} +H1 +{ + BACKGROUND-COLOR: #003366; + BORDER-BOTTOM: #336699 6px solid; + COLOR: #ffffff; + FONT-SIZE: 130%; + FONT-WEIGHT: normal; + MARGIN: 0em 0em 0em -20px; + PADDING-BOTTOM: 8px; + PADDING-LEFT: 30px; + PADDING-TOP: 16px +} +H2 +{ + COLOR: #000000; + FONT-SIZE: 80%; + FONT-WEIGHT: bold; + MARGIN-BOTTOM: 3px; + MARGIN-LEFT: 10px; + MARGIN-TOP: 20px; + PADDING-LEFT: 0px +} +H3 +{ + COLOR: #000000; + FONT-SIZE: 80%; + FONT-WEIGHT: bold; + MARGIN-BOTTOM: -5px; + MARGIN-LEFT: 10px; + MARGIN-TOP: 20px +} +H4 +{ + COLOR: #000000; + FONT-SIZE: 70%; + FONT-WEIGHT: bold; + MARGIN-BOTTOM: 0px; + MARGIN-TOP: 15px; + PADDING-BOTTOM: 0px +} +UL +{ + COLOR: #000000; + FONT-SIZE: 70%; + LIST-STYLE: square; + MARGIN-BOTTOM: 0pt; + MARGIN-TOP: 0pt +} +OL +{ + COLOR: #000000; + FONT-SIZE: 70%; + LIST-STYLE: square; + MARGIN-BOTTOM: 0pt; + MARGIN-TOP: 0pt +} +LI +{ + LIST-STYLE: square; + MARGIN-LEFT: 0px +} +.expandable +{ + CURSOR: hand +} +.expanded +{ + color: black +} +.collapsed +{ + DISPLAY: none +} +.foot +{ +BACKGROUND-COLOR: #ffffff; +BORDER-BOTTOM: #cecf9c 1px solid; +BORDER-TOP: #cecf9c 2px solid +} +.settings +{ +MARGIN-LEFT: 25PX; +} +.help +{ +TEXT-ALIGN: right; +margin-right: 10px; +} diff --git a/r17/Revamped src/revamped_src/_UpgradeReport_Files/UpgradeReport.xslt b/r17/Revamped src/revamped_src/_UpgradeReport_Files/UpgradeReport.xslt new file mode 100755 index 00000000..02de9d0e --- /dev/null +++ b/r17/Revamped src/revamped_src/_UpgradeReport_Files/UpgradeReport.xslt @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ Solution: + Project: + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + src + + + + + + + + + + + + +
FilenameStatusErrorsWarnings
+ javascript:document.images[''].click()src + + + + Converted + + + + Converted + +
+ + files + + + 1 file + + + Converted:
+ Not converted: +
+
+
+ + + + : + + + + + + + + + Conversion Report + <xsl:if test="Properties/Property[@Name='LogNumber']"> + <xsl:value-of select="Properties/Property[@Name='LogNumber']/@Value"/> + </xsl:if> + + + + +

Conversion Report -

+ +

+ Time of Conversion:
+

+ + + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + +
+ Conversion Settings +

+ + +
+
diff --git a/r17/Revamped src/revamped_src/_UpgradeReport_Files/UpgradeReport_Minus.gif b/r17/Revamped src/revamped_src/_UpgradeReport_Files/UpgradeReport_Minus.gif new file mode 100755 index 00000000..17751cb2 Binary files /dev/null and b/r17/Revamped src/revamped_src/_UpgradeReport_Files/UpgradeReport_Minus.gif differ diff --git a/r17/Revamped src/revamped_src/_UpgradeReport_Files/UpgradeReport_Plus.gif b/r17/Revamped src/revamped_src/_UpgradeReport_Files/UpgradeReport_Plus.gif new file mode 100755 index 00000000..f6009ca3 Binary files /dev/null and b/r17/Revamped src/revamped_src/_UpgradeReport_Files/UpgradeReport_Plus.gif differ diff --git a/r17/Revamped src/revamped_src/adivtab.h b/r17/Revamped src/revamped_src/adivtab.h new file mode 100755 index 00000000..57169066 --- /dev/null +++ b/r17/Revamped src/revamped_src/adivtab.h @@ -0,0 +1,1077 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// table of quotients and remainders for [-15...16] / [-15...16] + +// numerator = -15 +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{1, -6}, +{1, -7}, +{2, -1}, +{2, -3}, +{3, 0}, +{3, -3}, +{5, 0}, +{7, -1}, +{15, 0}, +{0, 0}, +{-15, 0}, +{-8, 1}, +{-5, 0}, +{-4, 1}, +{-3, 0}, +{-3, 3}, +{-3, 6}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-2, 9}, +{-2, 11}, +{-2, 13}, +{-1, 0}, +{-1, 1}, +// numerator = -14 +{0, -14}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{1, -6}, +{2, 0}, +{2, -2}, +{2, -4}, +{3, -2}, +{4, -2}, +{7, 0}, +{14, 0}, +{0, 0}, +{-14, 0}, +{-7, 0}, +{-5, 1}, +{-4, 2}, +{-3, 1}, +{-3, 4}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-2, 8}, +{-2, 10}, +{-2, 12}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +// numerator = -13 +{0, -13}, +{0, -13}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{1, -6}, +{2, -1}, +{2, -3}, +{3, -1}, +{4, -1}, +{6, -1}, +{13, 0}, +{0, 0}, +{-13, 0}, +{-7, 1}, +{-5, 2}, +{-4, 3}, +{-3, 2}, +{-3, 5}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-2, 9}, +{-2, 11}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +// numerator = -12 +{0, -12}, +{0, -12}, +{0, -12}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{2, 0}, +{2, -2}, +{3, 0}, +{4, 0}, +{6, 0}, +{12, 0}, +{0, 0}, +{-12, 0}, +{-6, 0}, +{-4, 0}, +{-3, 0}, +{-3, 3}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-2, 8}, +{-2, 10}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +// numerator = -11 +{0, -11}, +{0, -11}, +{0, -11}, +{0, -11}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{2, -1}, +{2, -3}, +{3, -2}, +{5, -1}, +{11, 0}, +{0, 0}, +{-11, 0}, +{-6, 1}, +{-4, 1}, +{-3, 1}, +{-3, 4}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-2, 9}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +// numerator = -10 +{0, -10}, +{0, -10}, +{0, -10}, +{0, -10}, +{0, -10}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{2, 0}, +{2, -2}, +{3, -1}, +{5, 0}, +{10, 0}, +{0, 0}, +{-10, 0}, +{-5, 0}, +{-4, 2}, +{-3, 2}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-2, 8}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +// numerator = -9 +{0, -9}, +{0, -9}, +{0, -9}, +{0, -9}, +{0, -9}, +{0, -9}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{2, -1}, +{3, 0}, +{4, -1}, +{9, 0}, +{0, 0}, +{-9, 0}, +{-5, 1}, +{-3, 0}, +{-3, 3}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +// numerator = -8 +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{2, 0}, +{2, -2}, +{4, 0}, +{8, 0}, +{0, 0}, +{-8, 0}, +{-4, 0}, +{-3, 1}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +// numerator = -7 +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{2, -1}, +{3, -1}, +{7, 0}, +{0, 0}, +{-7, 0}, +{-4, 1}, +{-3, 2}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +// numerator = -6 +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{1, 0}, +{1, -1}, +{1, -2}, +{2, 0}, +{3, 0}, +{6, 0}, +{0, 0}, +{-6, 0}, +{-3, 0}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +// numerator = -5 +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{1, 0}, +{1, -1}, +{1, -2}, +{2, -1}, +{5, 0}, +{0, 0}, +{-5, 0}, +{-3, 1}, +{-2, 1}, +{-2, 3}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +// numerator = -4 +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{1, 0}, +{1, -1}, +{2, 0}, +{4, 0}, +{0, 0}, +{-4, 0}, +{-2, 0}, +{-2, 2}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +// numerator = -3 +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{1, 0}, +{1, -1}, +{3, 0}, +{0, 0}, +{-3, 0}, +{-2, 1}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +{-1, 13}, +// numerator = -2 +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{1, 0}, +{2, 0}, +{0, 0}, +{-2, 0}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +{-1, 13}, +{-1, 14}, +// numerator = -1 +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{1, 0}, +{0, 0}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +{-1, 13}, +{-1, 14}, +{-1, 15}, +// numerator = 0 +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +// numerator = 1 +{-1, -14}, +{-1, -13}, +{-1, -12}, +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{0, 0}, +{1, 0}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +// numerator = 2 +{-1, -13}, +{-1, -12}, +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, 0}, +{0, 0}, +{2, 0}, +{1, 0}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +// numerator = 3 +{-1, -12}, +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -1}, +{-3, 0}, +{0, 0}, +{3, 0}, +{1, 1}, +{1, 0}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +// numerator = 4 +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -2}, +{-2, 0}, +{-4, 0}, +{0, 0}, +{4, 0}, +{2, 0}, +{1, 1}, +{1, 0}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +// numerator = 5 +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -3}, +{-2, -1}, +{-3, -1}, +{-5, 0}, +{0, 0}, +{5, 0}, +{2, 1}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +// numerator = 6 +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, 0}, +{-6, 0}, +{0, 0}, +{6, 0}, +{3, 0}, +{2, 0}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +// numerator = 7 +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -2}, +{-4, -1}, +{-7, 0}, +{0, 0}, +{7, 0}, +{3, 1}, +{2, 1}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +// numerator = 8 +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -1}, +{-4, 0}, +{-8, 0}, +{0, 0}, +{8, 0}, +{4, 0}, +{2, 2}, +{2, 0}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +// numerator = 9 +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -3}, +{-3, 0}, +{-5, -1}, +{-9, 0}, +{0, 0}, +{9, 0}, +{4, 1}, +{3, 0}, +{2, 1}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +// numerator = 10 +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -2}, +{-4, -2}, +{-5, 0}, +{-10, 0}, +{0, 0}, +{10, 0}, +{5, 0}, +{3, 1}, +{2, 2}, +{2, 0}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 10}, +{0, 10}, +{0, 10}, +{0, 10}, +{0, 10}, +{0, 10}, +// numerator = 11 +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -9}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -4}, +{-3, -1}, +{-4, -1}, +{-6, -1}, +{-11, 0}, +{0, 0}, +{11, 0}, +{5, 1}, +{3, 2}, +{2, 3}, +{2, 1}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 11}, +{0, 11}, +{0, 11}, +{0, 11}, +{0, 11}, +// numerator = 12 +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -10}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -3}, +{-3, 0}, +{-4, 0}, +{-6, 0}, +{-12, 0}, +{0, 0}, +{12, 0}, +{6, 0}, +{4, 0}, +{3, 0}, +{2, 2}, +{2, 0}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 12}, +{0, 12}, +{0, 12}, +{0, 12}, +// numerator = 13 +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -11}, +{-2, -9}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -5}, +{-3, -2}, +{-4, -3}, +{-5, -2}, +{-7, -1}, +{-13, 0}, +{0, 0}, +{13, 0}, +{6, 1}, +{4, 1}, +{3, 1}, +{2, 3}, +{2, 1}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 13}, +{0, 13}, +{0, 13}, +// numerator = 14 +{-1, -1}, +{-1, 0}, +{-2, -12}, +{-2, -10}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -4}, +{-3, -1}, +{-4, -2}, +{-5, -1}, +{-7, 0}, +{-14, 0}, +{0, 0}, +{14, 0}, +{7, 0}, +{4, 2}, +{3, 2}, +{2, 4}, +{2, 2}, +{2, 0}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 14}, +{0, 14}, +// numerator = 15 +{-1, 0}, +{-2, -13}, +{-2, -11}, +{-2, -9}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -6}, +{-3, -3}, +{-3, 0}, +{-4, -1}, +{-5, 0}, +{-8, -1}, +{-15, 0}, +{0, 0}, +{15, 0}, +{7, 1}, +{5, 0}, +{3, 3}, +{3, 0}, +{2, 3}, +{2, 1}, +{1, 7}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 15}, +// numerator = 16 +{-2, -14}, +{-2, -12}, +{-2, -10}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -5}, +{-3, -2}, +{-4, -4}, +{-4, 0}, +{-6, -2}, +{-8, 0}, +{-16, 0}, +{0, 0}, +{16, 0}, +{8, 0}, +{5, 1}, +{4, 0}, +{3, 1}, +{2, 4}, +{2, 2}, +{2, 0}, +{1, 7}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, diff --git a/r17/Revamped src/revamped_src/anorm_dots.h b/r17/Revamped src/revamped_src/anorm_dots.h new file mode 100755 index 00000000..2abea606 --- /dev/null +++ b/r17/Revamped src/revamped_src/anorm_dots.h @@ -0,0 +1,37 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +{ +{1.23,1.30,1.47,1.35,1.56,1.71,1.37,1.38,1.59,1.60,1.79,1.97,1.88,1.92,1.79,1.02,0.93,1.07,0.82,0.87,0.88,0.94,0.96,1.14,1.11,0.82,0.83,0.89,0.89,0.86,0.94,0.91,1.00,1.21,0.98,1.48,1.30,1.57,0.96,1.07,1.14,1.60,1.61,1.40,1.37,1.72,1.78,1.79,1.93,1.99,1.90,1.68,1.71,1.86,1.60,1.68,1.78,1.86,1.93,1.99,1.97,1.44,1.22,1.49,0.93,0.99,0.99,1.23,1.22,1.44,1.49,0.89,0.89,0.97,0.91,0.98,1.19,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.19,0.98,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.87,0.93,0.94,1.02,1.30,1.07,1.35,1.38,1.11,1.56,1.92,1.79,1.79,1.59,1.60,1.72,1.90,1.79,0.80,0.85,0.79,0.93,0.80,0.85,0.77,0.74,0.72,0.77,0.74,0.72,0.70,0.70,0.71,0.76,0.73,0.79,0.79,0.73,0.76,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.26,1.26,1.48,1.23,1.50,1.71,1.14,1.19,1.38,1.46,1.64,1.94,1.87,1.84,1.71,1.02,0.92,1.00,0.79,0.85,0.84,0.91,0.90,0.98,0.99,0.77,0.77,0.83,0.82,0.79,0.86,0.84,0.92,0.99,0.91,1.24,1.03,1.33,0.88,0.94,0.97,1.41,1.39,1.18,1.11,1.51,1.61,1.59,1.80,1.91,1.76,1.54,1.65,1.76,1.70,1.70,1.85,1.85,1.97,1.99,1.93,1.28,1.09,1.39,0.92,0.97,0.99,1.18,1.26,1.52,1.48,0.83,0.85,0.90,0.88,0.93,1.00,0.77,0.73,0.78,0.72,0.71,0.74,0.75,0.79,0.86,0.81,0.75,0.81,0.79,0.96,0.88,0.94,0.86,0.93,0.92,0.85,1.08,1.33,1.05,1.55,1.31,1.01,1.05,1.27,1.31,1.60,1.47,1.70,1.54,1.76,1.76,1.57,0.93,0.90,0.99,0.88,0.88,0.95,0.97,1.11,1.39,1.20,0.92,0.97,1.01,1.10,1.39,1.22,1.51,1.58,1.32,1.64,1.97,1.85,1.91,1.77,1.74,1.88,1.99,1.91,0.79,0.86,0.80,0.94,0.84,0.88,0.74,0.74,0.71,0.82,0.77,0.76,0.70,0.73,0.72,0.73,0.70,0.74,0.85,0.77,0.82,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.34,1.27,1.53,1.17,1.46,1.71,0.98,1.05,1.20,1.34,1.48,1.86,1.82,1.71,1.62,1.09,0.94,0.99,0.79,0.85,0.82,0.90,0.87,0.93,0.96,0.76,0.74,0.79,0.76,0.74,0.79,0.78,0.85,0.92,0.85,1.00,0.93,1.06,0.81,0.86,0.89,1.16,1.12,0.97,0.95,1.28,1.38,1.35,1.60,1.77,1.57,1.33,1.50,1.58,1.69,1.63,1.82,1.74,1.91,1.92,1.80,1.04,0.97,1.21,0.90,0.93,0.97,1.05,1.21,1.48,1.37,0.77,0.80,0.84,0.85,0.88,0.92,0.73,0.71,0.74,0.74,0.71,0.75,0.73,0.79,0.84,0.78,0.79,0.86,0.81,1.05,0.94,0.99,0.90,0.95,0.92,0.86,1.24,1.44,1.14,1.59,1.34,1.02,1.27,1.50,1.49,1.80,1.69,1.86,1.72,1.87,1.80,1.69,1.00,0.98,1.23,0.95,0.96,1.09,1.16,1.37,1.63,1.46,0.99,1.10,1.25,1.24,1.51,1.41,1.67,1.77,1.55,1.72,1.95,1.89,1.98,1.91,1.86,1.97,1.99,1.94,0.81,0.89,0.85,0.98,0.90,0.94,0.75,0.78,0.73,0.89,0.83,0.82,0.72,0.77,0.76,0.72,0.70,0.71,0.91,0.83,0.89,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.46,1.34,1.60,1.16,1.46,1.71,0.94,0.99,1.05,1.26,1.33,1.74,1.76,1.57,1.54,1.23,0.98,1.05,0.83,0.89,0.84,0.92,0.87,0.91,0.96,0.78,0.74,0.79,0.72,0.72,0.75,0.76,0.80,0.88,0.83,0.94,0.87,0.95,0.76,0.80,0.82,0.97,0.96,0.89,0.88,1.08,1.11,1.10,1.37,1.59,1.37,1.07,1.27,1.34,1.57,1.45,1.69,1.55,1.77,1.79,1.60,0.93,0.90,0.99,0.86,0.87,0.93,0.96,1.07,1.35,1.18,0.73,0.76,0.77,0.81,0.82,0.85,0.70,0.71,0.72,0.78,0.73,0.77,0.73,0.79,0.82,0.76,0.83,0.90,0.84,1.18,0.98,1.03,0.92,0.95,0.90,0.86,1.32,1.45,1.15,1.53,1.27,0.99,1.42,1.65,1.58,1.93,1.83,1.94,1.81,1.88,1.74,1.70,1.19,1.17,1.44,1.11,1.15,1.36,1.41,1.61,1.81,1.67,1.22,1.34,1.50,1.42,1.65,1.61,1.82,1.91,1.75,1.80,1.89,1.89,1.98,1.99,1.94,1.98,1.92,1.87,0.86,0.95,0.92,1.14,0.98,1.03,0.79,0.84,0.77,0.97,0.90,0.89,0.76,0.82,0.82,0.74,0.72,0.71,0.98,0.89,0.97,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.60,1.44,1.68,1.22,1.49,1.71,0.93,0.99,0.99,1.23,1.22,1.60,1.68,1.44,1.49,1.40,1.14,1.19,0.89,0.96,0.89,0.97,0.89,0.91,0.98,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.91,0.83,0.89,0.72,0.76,0.76,0.89,0.89,0.82,0.82,0.98,0.96,0.97,1.14,1.40,1.19,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.70,0.72,0.73,0.77,0.76,0.79,0.70,0.72,0.71,0.82,0.77,0.80,0.74,0.79,0.80,0.74,0.87,0.93,0.85,1.23,1.02,1.02,0.93,0.93,0.87,0.85,1.30,1.35,1.07,1.38,1.11,0.94,1.47,1.71,1.56,1.97,1.88,1.92,1.79,1.79,1.59,1.60,1.30,1.35,1.56,1.37,1.38,1.59,1.60,1.79,1.92,1.79,1.48,1.57,1.72,1.61,1.78,1.79,1.93,1.99,1.90,1.86,1.78,1.86,1.93,1.99,1.97,1.90,1.79,1.72,0.94,1.07,1.00,1.37,1.21,1.30,0.86,0.91,0.83,1.14,0.98,0.96,0.82,0.88,0.89,0.79,0.76,0.73,1.07,0.94,1.11,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.74,1.57,1.76,1.33,1.54,1.71,0.94,1.05,0.99,1.26,1.16,1.46,1.60,1.34,1.46,1.59,1.37,1.37,0.97,1.11,0.96,1.10,0.95,0.94,1.08,0.89,0.82,0.88,0.72,0.76,0.75,0.80,0.80,0.88,0.87,0.91,0.83,0.87,0.72,0.76,0.74,0.83,0.84,0.78,0.79,0.96,0.89,0.92,0.98,1.23,1.05,0.86,0.92,0.95,1.11,0.98,1.22,1.03,1.34,1.42,1.14,0.79,0.77,0.84,0.78,0.76,0.82,0.82,0.89,0.97,0.90,0.70,0.71,0.71,0.73,0.72,0.74,0.73,0.76,0.72,0.86,0.81,0.82,0.76,0.79,0.77,0.73,0.90,0.95,0.86,1.18,1.03,0.98,0.92,0.90,0.83,0.84,1.19,1.17,0.98,1.15,0.97,0.89,1.42,1.65,1.44,1.93,1.83,1.81,1.67,1.61,1.36,1.41,1.32,1.45,1.58,1.57,1.53,1.74,1.70,1.88,1.94,1.81,1.69,1.77,1.87,1.79,1.89,1.92,1.98,1.99,1.98,1.89,1.65,1.80,1.82,1.91,1.94,1.75,1.61,1.50,1.07,1.34,1.27,1.60,1.45,1.55,0.93,0.99,0.90,1.35,1.18,1.07,0.87,0.93,0.96,0.85,0.82,0.77,1.15,0.99,1.27,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.86,1.71,1.82,1.48,1.62,1.71,0.98,1.20,1.05,1.34,1.17,1.34,1.53,1.27,1.46,1.77,1.60,1.57,1.16,1.38,1.12,1.35,1.06,1.00,1.28,0.97,0.89,0.95,0.76,0.81,0.79,0.86,0.85,0.92,0.93,0.93,0.85,0.87,0.74,0.78,0.74,0.79,0.82,0.76,0.79,0.96,0.85,0.90,0.94,1.09,0.99,0.81,0.85,0.89,0.95,0.90,0.99,0.94,1.10,1.24,0.98,0.75,0.73,0.78,0.74,0.72,0.77,0.76,0.82,0.89,0.83,0.73,0.71,0.71,0.71,0.70,0.72,0.77,0.80,0.74,0.90,0.85,0.84,0.78,0.79,0.75,0.73,0.92,0.95,0.86,1.05,0.99,0.94,0.90,0.86,0.79,0.81,1.00,0.98,0.91,0.96,0.89,0.83,1.27,1.50,1.23,1.80,1.69,1.63,1.46,1.37,1.09,1.16,1.24,1.44,1.49,1.69,1.59,1.80,1.69,1.87,1.86,1.72,1.82,1.91,1.94,1.92,1.95,1.99,1.98,1.91,1.97,1.89,1.51,1.72,1.67,1.77,1.86,1.55,1.41,1.25,1.33,1.58,1.50,1.80,1.63,1.74,1.04,1.21,0.97,1.48,1.37,1.21,0.93,0.97,1.05,0.92,0.88,0.84,1.14,1.02,1.34,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.94,1.84,1.87,1.64,1.71,1.71,1.14,1.38,1.19,1.46,1.23,1.26,1.48,1.26,1.50,1.91,1.80,1.76,1.41,1.61,1.39,1.59,1.33,1.24,1.51,1.18,0.97,1.11,0.82,0.88,0.86,0.94,0.92,0.99,1.03,0.98,0.91,0.90,0.79,0.84,0.77,0.79,0.84,0.77,0.83,0.99,0.85,0.91,0.92,1.02,1.00,0.79,0.80,0.86,0.88,0.84,0.92,0.88,0.97,1.10,0.94,0.74,0.71,0.74,0.72,0.70,0.73,0.72,0.76,0.82,0.77,0.77,0.73,0.74,0.71,0.70,0.73,0.83,0.85,0.78,0.92,0.88,0.86,0.81,0.79,0.74,0.75,0.92,0.93,0.85,0.96,0.94,0.88,0.86,0.81,0.75,0.79,0.93,0.90,0.85,0.88,0.82,0.77,1.05,1.27,0.99,1.60,1.47,1.39,1.20,1.11,0.95,0.97,1.08,1.33,1.31,1.70,1.55,1.76,1.57,1.76,1.70,1.54,1.85,1.97,1.91,1.99,1.97,1.99,1.91,1.77,1.88,1.85,1.39,1.64,1.51,1.58,1.74,1.32,1.22,1.01,1.54,1.76,1.65,1.93,1.70,1.85,1.28,1.39,1.09,1.52,1.48,1.26,0.97,0.99,1.18,1.00,0.93,0.90,1.05,1.01,1.31,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.97,1.92,1.88,1.79,1.79,1.71,1.37,1.59,1.38,1.60,1.35,1.23,1.47,1.30,1.56,1.99,1.93,1.90,1.60,1.78,1.61,1.79,1.57,1.48,1.72,1.40,1.14,1.37,0.89,0.96,0.94,1.07,1.00,1.21,1.30,1.14,0.98,0.96,0.86,0.91,0.83,0.82,0.88,0.82,0.89,1.11,0.87,0.94,0.93,1.02,1.07,0.80,0.79,0.85,0.82,0.80,0.87,0.85,0.93,1.02,0.93,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.82,0.76,0.79,0.72,0.73,0.76,0.89,0.89,0.82,0.93,0.91,0.86,0.83,0.79,0.73,0.76,0.91,0.89,0.83,0.89,0.89,0.82,0.82,0.76,0.72,0.76,0.86,0.83,0.79,0.82,0.76,0.73,0.94,1.00,0.91,1.37,1.21,1.14,0.98,0.96,0.88,0.89,0.96,1.14,1.07,1.60,1.40,1.61,1.37,1.57,1.48,1.30,1.78,1.93,1.79,1.99,1.92,1.90,1.79,1.59,1.72,1.79,1.30,1.56,1.35,1.38,1.60,1.11,1.07,0.94,1.68,1.86,1.71,1.97,1.68,1.86,1.44,1.49,1.22,1.44,1.49,1.22,0.99,0.99,1.23,1.19,0.98,0.97,0.97,0.98,1.19,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.94,1.97,1.87,1.91,1.85,1.71,1.60,1.77,1.58,1.74,1.51,1.26,1.48,1.39,1.64,1.99,1.97,1.99,1.70,1.85,1.76,1.91,1.76,1.70,1.88,1.55,1.33,1.57,0.96,1.08,1.05,1.31,1.27,1.47,1.54,1.39,1.20,1.11,0.93,0.99,0.90,0.88,0.95,0.88,0.97,1.32,0.92,1.01,0.97,1.10,1.22,0.84,0.80,0.88,0.79,0.79,0.85,0.86,0.92,1.02,0.94,0.82,0.76,0.77,0.72,0.73,0.70,0.72,0.71,0.74,0.74,0.88,0.81,0.85,0.75,0.77,0.82,0.94,0.93,0.86,0.92,0.92,0.86,0.85,0.79,0.74,0.79,0.88,0.85,0.81,0.82,0.83,0.77,0.78,0.73,0.71,0.75,0.79,0.77,0.74,0.77,0.73,0.70,0.86,0.92,0.84,1.14,0.99,0.98,0.91,0.90,0.84,0.83,0.88,0.97,0.94,1.41,1.18,1.39,1.11,1.33,1.24,1.03,1.61,1.80,1.59,1.91,1.84,1.76,1.64,1.38,1.51,1.71,1.26,1.50,1.23,1.19,1.46,0.99,1.00,0.91,1.70,1.85,1.65,1.93,1.54,1.76,1.52,1.48,1.26,1.28,1.39,1.09,0.99,0.97,1.18,1.31,1.01,1.05,0.90,0.93,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.86,1.95,1.82,1.98,1.89,1.71,1.80,1.91,1.77,1.86,1.67,1.34,1.53,1.51,1.72,1.92,1.91,1.99,1.69,1.82,1.80,1.94,1.87,1.86,1.97,1.59,1.44,1.69,1.05,1.24,1.27,1.49,1.50,1.69,1.72,1.63,1.46,1.37,1.00,1.23,0.98,0.95,1.09,0.96,1.16,1.55,0.99,1.25,1.10,1.24,1.41,0.90,0.85,0.94,0.79,0.81,0.85,0.89,0.94,1.09,0.98,0.89,0.82,0.83,0.74,0.77,0.72,0.76,0.73,0.75,0.78,0.94,0.86,0.91,0.79,0.83,0.89,0.99,0.95,0.90,0.90,0.92,0.84,0.86,0.79,0.75,0.81,0.85,0.80,0.78,0.76,0.77,0.73,0.74,0.71,0.71,0.73,0.74,0.74,0.71,0.76,0.72,0.70,0.79,0.85,0.78,0.98,0.92,0.93,0.85,0.87,0.82,0.79,0.81,0.89,0.86,1.16,0.97,1.12,0.95,1.06,1.00,0.93,1.38,1.60,1.35,1.77,1.71,1.57,1.48,1.20,1.28,1.62,1.27,1.46,1.17,1.05,1.34,0.96,0.99,0.90,1.63,1.74,1.50,1.80,1.33,1.58,1.48,1.37,1.21,1.04,1.21,0.97,0.97,0.93,1.05,1.34,1.02,1.14,0.84,0.88,0.92,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.74,1.89,1.76,1.98,1.89,1.71,1.93,1.99,1.91,1.94,1.82,1.46,1.60,1.65,1.80,1.79,1.77,1.92,1.57,1.69,1.74,1.87,1.88,1.94,1.98,1.53,1.45,1.70,1.18,1.32,1.42,1.58,1.65,1.83,1.81,1.81,1.67,1.61,1.19,1.44,1.17,1.11,1.36,1.15,1.41,1.75,1.22,1.50,1.34,1.42,1.61,0.98,0.92,1.03,0.83,0.86,0.89,0.95,0.98,1.23,1.14,0.97,0.89,0.90,0.78,0.82,0.76,0.82,0.77,0.79,0.84,0.98,0.90,0.98,0.83,0.89,0.97,1.03,0.95,0.92,0.86,0.90,0.82,0.86,0.79,0.77,0.84,0.81,0.76,0.76,0.72,0.73,0.70,0.72,0.71,0.73,0.73,0.72,0.74,0.71,0.78,0.74,0.72,0.75,0.80,0.76,0.94,0.88,0.91,0.83,0.87,0.84,0.79,0.76,0.82,0.80,0.97,0.89,0.96,0.88,0.95,0.94,0.87,1.11,1.37,1.10,1.59,1.57,1.37,1.33,1.05,1.08,1.54,1.34,1.46,1.16,0.99,1.26,0.96,1.05,0.92,1.45,1.55,1.27,1.60,1.07,1.34,1.35,1.18,1.07,0.93,0.99,0.90,0.93,0.87,0.96,1.27,0.99,1.15,0.77,0.82,0.85,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.60,1.78,1.68,1.93,1.86,1.71,1.97,1.99,1.99,1.97,1.93,1.60,1.68,1.78,1.86,1.61,1.57,1.79,1.37,1.48,1.59,1.72,1.79,1.92,1.90,1.38,1.35,1.60,1.23,1.30,1.47,1.56,1.71,1.88,1.79,1.92,1.79,1.79,1.30,1.56,1.35,1.37,1.59,1.38,1.60,1.90,1.48,1.72,1.57,1.61,1.79,1.21,1.00,1.30,0.89,0.94,0.96,1.07,1.14,1.40,1.37,1.14,0.96,0.98,0.82,0.88,0.82,0.89,0.83,0.86,0.91,1.02,0.93,1.07,0.87,0.94,1.11,1.02,0.93,0.93,0.82,0.87,0.80,0.85,0.79,0.80,0.85,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.72,0.76,0.73,0.82,0.79,0.76,0.73,0.79,0.76,0.93,0.86,0.91,0.83,0.89,0.89,0.82,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.44,1.19,1.22,0.99,0.98,1.49,1.44,1.49,1.22,0.99,1.23,0.98,1.19,0.97,1.21,1.30,1.00,1.37,0.94,1.07,1.14,0.98,0.96,0.86,0.91,0.83,0.88,0.82,0.89,1.11,0.94,1.07,0.73,0.76,0.79,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.46,1.65,1.60,1.82,1.80,1.71,1.93,1.91,1.99,1.94,1.98,1.74,1.76,1.89,1.89,1.42,1.34,1.61,1.11,1.22,1.36,1.50,1.61,1.81,1.75,1.15,1.17,1.41,1.18,1.19,1.42,1.44,1.65,1.83,1.67,1.94,1.81,1.88,1.32,1.58,1.45,1.57,1.74,1.53,1.70,1.98,1.69,1.87,1.77,1.79,1.92,1.45,1.27,1.55,0.97,1.07,1.11,1.34,1.37,1.59,1.60,1.35,1.07,1.18,0.86,0.93,0.87,0.96,0.90,0.93,0.99,1.03,0.95,1.15,0.90,0.99,1.27,0.98,0.90,0.92,0.78,0.83,0.77,0.84,0.79,0.82,0.86,0.73,0.71,0.73,0.72,0.70,0.73,0.72,0.76,0.81,0.76,0.76,0.82,0.77,0.89,0.85,0.82,0.75,0.80,0.80,0.94,0.88,0.94,0.87,0.95,0.96,0.88,0.72,0.74,0.76,0.83,0.78,0.84,0.79,0.87,0.91,0.83,0.89,0.98,0.92,1.23,1.34,1.05,1.16,0.99,0.96,1.46,1.57,1.54,1.33,1.05,1.26,1.08,1.37,1.10,0.98,1.03,0.92,1.14,0.86,0.95,0.97,0.90,0.89,0.79,0.84,0.77,0.82,0.76,0.82,0.97,0.89,0.98,0.71,0.72,0.74,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.34,1.51,1.53,1.67,1.72,1.71,1.80,1.77,1.91,1.86,1.98,1.86,1.82,1.95,1.89,1.24,1.10,1.41,0.95,0.99,1.09,1.25,1.37,1.63,1.55,0.96,0.98,1.16,1.05,1.00,1.27,1.23,1.50,1.69,1.46,1.86,1.72,1.87,1.24,1.49,1.44,1.69,1.80,1.59,1.69,1.97,1.82,1.94,1.91,1.92,1.99,1.63,1.50,1.74,1.16,1.33,1.38,1.58,1.60,1.77,1.80,1.48,1.21,1.37,0.90,0.97,0.93,1.05,0.97,1.04,1.21,0.99,0.95,1.14,0.92,1.02,1.34,0.94,0.86,0.90,0.74,0.79,0.75,0.81,0.79,0.84,0.86,0.71,0.71,0.73,0.76,0.73,0.77,0.74,0.80,0.85,0.78,0.81,0.89,0.84,0.97,0.92,0.88,0.79,0.85,0.86,0.98,0.92,1.00,0.93,1.06,1.12,0.95,0.74,0.74,0.78,0.79,0.76,0.82,0.79,0.87,0.93,0.85,0.85,0.94,0.90,1.09,1.27,0.99,1.17,1.05,0.96,1.46,1.71,1.62,1.48,1.20,1.34,1.28,1.57,1.35,0.90,0.94,0.85,0.98,0.81,0.89,0.89,0.83,0.82,0.75,0.78,0.73,0.77,0.72,0.76,0.89,0.83,0.91,0.71,0.70,0.72,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.26,1.39,1.48,1.51,1.64,1.71,1.60,1.58,1.77,1.74,1.91,1.94,1.87,1.97,1.85,1.10,0.97,1.22,0.88,0.92,0.95,1.01,1.11,1.39,1.32,0.88,0.90,0.97,0.96,0.93,1.05,0.99,1.27,1.47,1.20,1.70,1.54,1.76,1.08,1.31,1.33,1.70,1.76,1.55,1.57,1.88,1.85,1.91,1.97,1.99,1.99,1.70,1.65,1.85,1.41,1.54,1.61,1.76,1.80,1.91,1.93,1.52,1.26,1.48,0.92,0.99,0.97,1.18,1.09,1.28,1.39,0.94,0.93,1.05,0.92,1.01,1.31,0.88,0.81,0.86,0.72,0.75,0.74,0.79,0.79,0.86,0.85,0.71,0.73,0.75,0.82,0.77,0.83,0.78,0.85,0.88,0.81,0.88,0.97,0.90,1.18,1.00,0.93,0.86,0.92,0.94,1.14,0.99,1.24,1.03,1.33,1.39,1.11,0.79,0.77,0.84,0.79,0.77,0.84,0.83,0.90,0.98,0.91,0.85,0.92,0.91,1.02,1.26,1.00,1.23,1.19,0.99,1.50,1.84,1.71,1.64,1.38,1.46,1.51,1.76,1.59,0.84,0.88,0.80,0.94,0.79,0.86,0.82,0.77,0.76,0.74,0.74,0.71,0.73,0.70,0.72,0.82,0.77,0.85,0.74,0.70,0.73,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00} +} diff --git a/r17/Revamped src/revamped_src/anorms.h b/r17/Revamped src/revamped_src/anorms.h new file mode 100755 index 00000000..88042267 --- /dev/null +++ b/r17/Revamped src/revamped_src/anorms.h @@ -0,0 +1,181 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +{-0.525731, 0.000000, 0.850651}, +{-0.442863, 0.238856, 0.864188}, +{-0.295242, 0.000000, 0.955423}, +{-0.309017, 0.500000, 0.809017}, +{-0.162460, 0.262866, 0.951056}, +{0.000000, 0.000000, 1.000000}, +{0.000000, 0.850651, 0.525731}, +{-0.147621, 0.716567, 0.681718}, +{0.147621, 0.716567, 0.681718}, +{0.000000, 0.525731, 0.850651}, +{0.309017, 0.500000, 0.809017}, +{0.525731, 0.000000, 0.850651}, +{0.295242, 0.000000, 0.955423}, +{0.442863, 0.238856, 0.864188}, +{0.162460, 0.262866, 0.951056}, +{-0.681718, 0.147621, 0.716567}, +{-0.809017, 0.309017, 0.500000}, +{-0.587785, 0.425325, 0.688191}, +{-0.850651, 0.525731, 0.000000}, +{-0.864188, 0.442863, 0.238856}, +{-0.716567, 0.681718, 0.147621}, +{-0.688191, 0.587785, 0.425325}, +{-0.500000, 0.809017, 0.309017}, +{-0.238856, 0.864188, 0.442863}, +{-0.425325, 0.688191, 0.587785}, +{-0.716567, 0.681718, -0.147621}, +{-0.500000, 0.809017, -0.309017}, +{-0.525731, 0.850651, 0.000000}, +{0.000000, 0.850651, -0.525731}, +{-0.238856, 0.864188, -0.442863}, +{0.000000, 0.955423, -0.295242}, +{-0.262866, 0.951056, -0.162460}, +{0.000000, 1.000000, 0.000000}, +{0.000000, 0.955423, 0.295242}, +{-0.262866, 0.951056, 0.162460}, +{0.238856, 0.864188, 0.442863}, +{0.262866, 0.951056, 0.162460}, +{0.500000, 0.809017, 0.309017}, +{0.238856, 0.864188, -0.442863}, +{0.262866, 0.951056, -0.162460}, +{0.500000, 0.809017, -0.309017}, +{0.850651, 0.525731, 0.000000}, +{0.716567, 0.681718, 0.147621}, +{0.716567, 0.681718, -0.147621}, +{0.525731, 0.850651, 0.000000}, +{0.425325, 0.688191, 0.587785}, +{0.864188, 0.442863, 0.238856}, +{0.688191, 0.587785, 0.425325}, +{0.809017, 0.309017, 0.500000}, +{0.681718, 0.147621, 0.716567}, +{0.587785, 0.425325, 0.688191}, +{0.955423, 0.295242, 0.000000}, +{1.000000, 0.000000, 0.000000}, +{0.951056, 0.162460, 0.262866}, +{0.850651, -0.525731, 0.000000}, +{0.955423, -0.295242, 0.000000}, +{0.864188, -0.442863, 0.238856}, +{0.951056, -0.162460, 0.262866}, +{0.809017, -0.309017, 0.500000}, +{0.681718, -0.147621, 0.716567}, +{0.850651, 0.000000, 0.525731}, +{0.864188, 0.442863, -0.238856}, +{0.809017, 0.309017, -0.500000}, +{0.951056, 0.162460, -0.262866}, +{0.525731, 0.000000, -0.850651}, +{0.681718, 0.147621, -0.716567}, +{0.681718, -0.147621, -0.716567}, +{0.850651, 0.000000, -0.525731}, +{0.809017, -0.309017, -0.500000}, +{0.864188, -0.442863, -0.238856}, +{0.951056, -0.162460, -0.262866}, +{0.147621, 0.716567, -0.681718}, +{0.309017, 0.500000, -0.809017}, +{0.425325, 0.688191, -0.587785}, +{0.442863, 0.238856, -0.864188}, +{0.587785, 0.425325, -0.688191}, +{0.688191, 0.587785, -0.425325}, +{-0.147621, 0.716567, -0.681718}, +{-0.309017, 0.500000, -0.809017}, +{0.000000, 0.525731, -0.850651}, +{-0.525731, 0.000000, -0.850651}, +{-0.442863, 0.238856, -0.864188}, +{-0.295242, 0.000000, -0.955423}, +{-0.162460, 0.262866, -0.951056}, +{0.000000, 0.000000, -1.000000}, +{0.295242, 0.000000, -0.955423}, +{0.162460, 0.262866, -0.951056}, +{-0.442863, -0.238856, -0.864188}, +{-0.309017, -0.500000, -0.809017}, +{-0.162460, -0.262866, -0.951056}, +{0.000000, -0.850651, -0.525731}, +{-0.147621, -0.716567, -0.681718}, +{0.147621, -0.716567, -0.681718}, +{0.000000, -0.525731, -0.850651}, +{0.309017, -0.500000, -0.809017}, +{0.442863, -0.238856, -0.864188}, +{0.162460, -0.262866, -0.951056}, +{0.238856, -0.864188, -0.442863}, +{0.500000, -0.809017, -0.309017}, +{0.425325, -0.688191, -0.587785}, +{0.716567, -0.681718, -0.147621}, +{0.688191, -0.587785, -0.425325}, +{0.587785, -0.425325, -0.688191}, +{0.000000, -0.955423, -0.295242}, +{0.000000, -1.000000, 0.000000}, +{0.262866, -0.951056, -0.162460}, +{0.000000, -0.850651, 0.525731}, +{0.000000, -0.955423, 0.295242}, +{0.238856, -0.864188, 0.442863}, +{0.262866, -0.951056, 0.162460}, +{0.500000, -0.809017, 0.309017}, +{0.716567, -0.681718, 0.147621}, +{0.525731, -0.850651, 0.000000}, +{-0.238856, -0.864188, -0.442863}, +{-0.500000, -0.809017, -0.309017}, +{-0.262866, -0.951056, -0.162460}, +{-0.850651, -0.525731, 0.000000}, +{-0.716567, -0.681718, -0.147621}, +{-0.716567, -0.681718, 0.147621}, +{-0.525731, -0.850651, 0.000000}, +{-0.500000, -0.809017, 0.309017}, +{-0.238856, -0.864188, 0.442863}, +{-0.262866, -0.951056, 0.162460}, +{-0.864188, -0.442863, 0.238856}, +{-0.809017, -0.309017, 0.500000}, +{-0.688191, -0.587785, 0.425325}, +{-0.681718, -0.147621, 0.716567}, +{-0.442863, -0.238856, 0.864188}, +{-0.587785, -0.425325, 0.688191}, +{-0.309017, -0.500000, 0.809017}, +{-0.147621, -0.716567, 0.681718}, +{-0.425325, -0.688191, 0.587785}, +{-0.162460, -0.262866, 0.951056}, +{0.442863, -0.238856, 0.864188}, +{0.162460, -0.262866, 0.951056}, +{0.309017, -0.500000, 0.809017}, +{0.147621, -0.716567, 0.681718}, +{0.000000, -0.525731, 0.850651}, +{0.425325, -0.688191, 0.587785}, +{0.587785, -0.425325, 0.688191}, +{0.688191, -0.587785, 0.425325}, +{-0.955423, 0.295242, 0.000000}, +{-0.951056, 0.162460, 0.262866}, +{-1.000000, 0.000000, 0.000000}, +{-0.850651, 0.000000, 0.525731}, +{-0.955423, -0.295242, 0.000000}, +{-0.951056, -0.162460, 0.262866}, +{-0.864188, 0.442863, -0.238856}, +{-0.951056, 0.162460, -0.262866}, +{-0.809017, 0.309017, -0.500000}, +{-0.864188, -0.442863, -0.238856}, +{-0.951056, -0.162460, -0.262866}, +{-0.809017, -0.309017, -0.500000}, +{-0.681718, 0.147621, -0.716567}, +{-0.681718, -0.147621, -0.716567}, +{-0.850651, 0.000000, -0.525731}, +{-0.688191, 0.587785, -0.425325}, +{-0.587785, 0.425325, -0.688191}, +{-0.425325, 0.688191, -0.587785}, +{-0.425325, -0.688191, -0.587785}, +{-0.587785, -0.425325, -0.688191}, +{-0.688191, -0.587785, -0.425325}, diff --git a/r17/Revamped src/revamped_src/asm_i386.h b/r17/Revamped src/revamped_src/asm_i386.h new file mode 100755 index 00000000..c7c7ca99 --- /dev/null +++ b/r17/Revamped src/revamped_src/asm_i386.h @@ -0,0 +1,97 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +#ifndef __ASM_I386__ +#define __ASM_I386__ + +#ifdef ELF +#define C(label) label +#else +#define C(label) _##label +#endif + +// +// !!! note that this file must match the corresponding C structures at all +// times !!! +// + +// plane_t structure +// !!! if this is changed, it must be changed in model.h too !!! +// !!! if the size of this is changed, the array lookup in SV_HullPointContents +// must be changed too !!! +#define pl_normal 0 +#define pl_dist 12 +#define pl_type 16 +#define pl_signbits 17 +#define pl_pad 18 +#define pl_size 20 + +// hull_t structure +// !!! if this is changed, it must be changed in model.h too !!! +#define hu_clipnodes 0 +#define hu_planes 4 +#define hu_firstclipnode 8 +#define hu_lastclipnode 12 +#define hu_clip_mins 16 +#define hu_clip_maxs 28 +#define hu_size 40 + +// dnode_t structure +// !!! if this is changed, it must be changed in bspfile.h too !!! +#define nd_planenum 0 +#define nd_children 4 +#define nd_mins 8 +#define nd_maxs 20 +#define nd_firstface 32 +#define nd_numfaces 36 +#define nd_size 40 + +// sfxcache_t structure +// !!! if this is changed, it much be changed in sound.h too !!! +#define sfxc_length 0 +#define sfxc_loopstart 4 +#define sfxc_speed 8 +#define sfxc_width 12 +#define sfxc_stereo 16 +#define sfxc_data 20 + +// channel_t structure +// !!! if this is changed, it much be changed in sound.h too !!! +#define ch_sfx 0 +#define ch_leftvol 4 +#define ch_rightvol 8 +#define ch_end 12 +#define ch_pos 16 +#define ch_looping 20 +#define ch_entnum 24 +#define ch_entchannel 28 +#define ch_origin 32 +#define ch_dist_mult 44 +#define ch_master_vol 48 +#define ch_size 52 + +// portable_samplepair_t structure +// !!! if this is changed, it much be changed in sound.h too !!! +#define psp_left 0 +#define psp_right 4 +#define psp_size 8 + +#endif + diff --git a/r17/Revamped src/revamped_src/block16.h b/r17/Revamped src/revamped_src/block16.h new file mode 100755 index 00000000..facc9329 --- /dev/null +++ b/r17/Revamped src/revamped_src/block16.h @@ -0,0 +1,142 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +LEnter16_16: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch0: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch1: + movw %cx,2(%edi) + addl $0x4,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch2: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch3: + movw %cx,2(%edi) + addl $0x4,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch4: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch5: + movw %cx,2(%edi) + addl $0x4,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch6: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch7: + movw %cx,2(%edi) + addl $0x4,%edi + +LEnter8_16: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch8: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch9: + movw %cx,2(%edi) + addl $0x4,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch10: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch11: + movw %cx,2(%edi) + addl $0x4,%edi + +LEnter4_16: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch12: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch13: + movw %cx,2(%edi) + addl $0x4,%edi + +LEnter2_16: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch14: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch15: + movw %cx,2(%edi) + addl $0x4,%edi diff --git a/r17/Revamped src/revamped_src/bspfile.h b/r17/Revamped src/revamped_src/bspfile.h new file mode 100755 index 00000000..91499c8a --- /dev/null +++ b/r17/Revamped src/revamped_src/bspfile.h @@ -0,0 +1,324 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + + +// upper design bounds + +#define MAX_MAP_HULLS 4 + +#define MAX_MAP_MODELS 256 +#define MAX_MAP_BRUSHES 4096 +#define MAX_MAP_ENTITIES 1024 +#define MAX_MAP_ENTSTRING 65536 + +#define MAX_MAP_PLANES 32767 +#define MAX_MAP_NODES 32767 // because negative shorts are contents +#define MAX_MAP_CLIPNODES 32767 // +#define MAX_MAP_LEAFS 8192 +#define MAX_MAP_VERTS 65535 +#define MAX_MAP_FACES 65535 +#define MAX_MAP_MARKSURFACES 65535 +#define MAX_MAP_TEXINFO 4096 +#define MAX_MAP_EDGES 256000 +#define MAX_MAP_SURFEDGES 512000 +#define MAX_MAP_TEXTURES 512 +#define MAX_MAP_MIPTEX 0x200000 +#define MAX_MAP_LIGHTING 0x100000 +#define MAX_MAP_VISIBILITY 0x100000 + +#define MAX_MAP_PORTALS 65536 + +// key / value pair sizes + +#define MAX_KEY 32 +#define MAX_VALUE 1024 + +//============================================================================= + + +#define BSPVERSION 29 +#define TOOLVERSION 2 + +typedef struct +{ + int fileofs, filelen; +} lump_t; + +#define LUMP_ENTITIES 0 +#define LUMP_PLANES 1 +#define LUMP_TEXTURES 2 +#define LUMP_VERTEXES 3 +#define LUMP_VISIBILITY 4 +#define LUMP_NODES 5 +#define LUMP_TEXINFO 6 +#define LUMP_FACES 7 +#define LUMP_LIGHTING 8 +#define LUMP_CLIPNODES 9 +#define LUMP_LEAFS 10 +#define LUMP_MARKSURFACES 11 +#define LUMP_EDGES 12 +#define LUMP_SURFEDGES 13 +#define LUMP_MODELS 14 + +#define HEADER_LUMPS 15 + +typedef struct +{ + float mins[3], maxs[3]; + float origin[3]; + int headnode[MAX_MAP_HULLS]; + int visleafs; // not including the solid leaf 0 + int firstface, numfaces; +} dmodel_t; + +typedef struct +{ + int version; + lump_t lumps[HEADER_LUMPS]; +} dheader_t; + +typedef struct +{ + int nummiptex; + int dataofs[4]; // [nummiptex] +} dmiptexlump_t; + +#define MIPLEVELS 4 +typedef struct miptex_s +{ + char name[16]; + unsigned width, height; + unsigned offsets[MIPLEVELS]; // four mip maps stored +} miptex_t; + + +typedef struct +{ + float point[3]; +} dvertex_t; + + +// 0-2 are axial planes +#define PLANE_X 0 +#define PLANE_Y 1 +#define PLANE_Z 2 + +// 3-5 are non-axial planes snapped to the nearest +#define PLANE_ANYX 3 +#define PLANE_ANYY 4 +#define PLANE_ANYZ 5 + +typedef struct +{ + float normal[3]; + float dist; + int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate +} dplane_t; + + + +#define CONTENTS_EMPTY -1 +#define CONTENTS_SOLID -2 +#define CONTENTS_WATER -3 +#define CONTENTS_SLIME -4 +#define CONTENTS_LAVA -5 +#define CONTENTS_SKY -6 +#define CONTENTS_ORIGIN -7 // removed at csg time +#define CONTENTS_CLIP -8 // changed to contents_solid + +#define CONTENTS_CURRENT_0 -9 +#define CONTENTS_CURRENT_90 -10 +#define CONTENTS_CURRENT_180 -11 +#define CONTENTS_CURRENT_270 -12 +#define CONTENTS_CURRENT_UP -13 +#define CONTENTS_CURRENT_DOWN -14 + + +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct +{ + int planenum; + short children[2]; // negative numbers are -(leafs+1), not nodes + short mins[3]; // for sphere culling + short maxs[3]; + unsigned short firstface; + unsigned short numfaces; // counting both sides +} dnode_t; + +typedef struct +{ + int planenum; + short children[2]; // negative numbers are contents +} dclipnode_t; + + +typedef struct texinfo_s +{ + float vecs[2][4]; // [s/t][xyz offset] + int miptex; + int flags; +} texinfo_t; +#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision + +// note that edge 0 is never used, because negative edge nums are used for +// counterclockwise use of the edge in a face +typedef struct +{ + unsigned short v[2]; // vertex numbers +} dedge_t; + +#define MAXLIGHTMAPS 4 +typedef struct +{ + short planenum; + short side; + + int firstedge; // we must support > 64k edges + short numedges; + short texinfo; + +// lighting info + byte styles[MAXLIGHTMAPS]; + int lightofs; // start of [numstyles*surfsize] samples +} dface_t; + + + +#define AMBIENT_WATER 0 +#define AMBIENT_SKY 1 +#define AMBIENT_SLIME 2 +#define AMBIENT_LAVA 3 + +#define NUM_AMBIENTS 4 // automatic ambient sounds + +// leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas +// all other leafs need visibility info +typedef struct +{ + int contents; + int visofs; // -1 = no visibility info + + short mins[3]; // for frustum culling + short maxs[3]; + + unsigned short firstmarksurface; + unsigned short nummarksurfaces; + + byte ambient_level[NUM_AMBIENTS]; +} dleaf_t; + + +//============================================================================ + +#ifndef QUAKE_GAME + +#define ANGLE_UP -1 +#define ANGLE_DOWN -2 + + +// the utilities get to be lazy and just use large static arrays + +extern int nummodels; +extern dmodel_t dmodels[MAX_MAP_MODELS]; + +extern int visdatasize; +extern byte dvisdata[MAX_MAP_VISIBILITY]; + +extern int lightdatasize; +extern byte dlightdata[MAX_MAP_LIGHTING]; + +extern int texdatasize; +extern byte dtexdata[MAX_MAP_MIPTEX]; // (dmiptexlump_t) + +extern int entdatasize; +extern char dentdata[MAX_MAP_ENTSTRING]; + +extern int numleafs; +extern dleaf_t dleafs[MAX_MAP_LEAFS]; + +extern int numplanes; +extern dplane_t dplanes[MAX_MAP_PLANES]; + +extern int numvertexes; +extern dvertex_t dvertexes[MAX_MAP_VERTS]; + +extern int numnodes; +extern dnode_t dnodes[MAX_MAP_NODES]; + +extern int numtexinfo; +extern texinfo_t texinfo[MAX_MAP_TEXINFO]; + +extern int numfaces; +extern dface_t dfaces[MAX_MAP_FACES]; + +extern int numclipnodes; +extern dclipnode_t dclipnodes[MAX_MAP_CLIPNODES]; + +extern int numedges; +extern dedge_t dedges[MAX_MAP_EDGES]; + +extern int nummarksurfaces; +extern unsigned short dmarksurfaces[MAX_MAP_MARKSURFACES]; + +extern int numsurfedges; +extern int dsurfedges[MAX_MAP_SURFEDGES]; + + +void DecompressVis (byte *in, byte *decompressed); +int CompressVis (byte *vis, byte *dest); + +void LoadBSPFile (char *filename); +void WriteBSPFile (char *filename); +void PrintBSPFileSizes (void); + +//=============== + + +typedef struct epair_s +{ + struct epair_s *next; + char *key; + char *value; +} epair_t; + +typedef struct +{ + vec3_t origin; + int firstbrush; + int numbrushes; + epair_t *epairs; +} entity_t; + +extern int num_entities; +extern entity_t entities[MAX_MAP_ENTITIES]; + +void ParseEntities (void); +void UnparseEntities (void); + +void SetKeyValue (entity_t *ent, char *key, char *value); +char *ValueForKey (entity_t *ent, char *key); +// will return "" if not present + +vec_t FloatForKey (entity_t *ent, char *key); +void GetVectorForKey (entity_t *ent, char *key, vec3_t vec); + +epair_t *ParseEpair (void); + +#endif diff --git a/r17/Revamped src/revamped_src/build.bat b/r17/Revamped src/revamped_src/build.bat new file mode 100755 index 00000000..8b033928 --- /dev/null +++ b/r17/Revamped src/revamped_src/build.bat @@ -0,0 +1,4 @@ +rem set PATH=C:/cygwin/usr/local/pspdev/bin;%PATH% +set PSPSDK=C:/cygwin/usr/local/pspdev +set PSP_MOUNT=/cygdrive/p +c:\cygwin\bin\bash -c 'export VS_PATH=`pwd`; /bin/bash --login -c "cd \"$VS_PATH\"; ./sed_make.sh %1 %2 %3 %4 %5 %6"' diff --git a/r17/Revamped src/revamped_src/cd_null.c b/r17/Revamped src/revamped_src/cd_null.c new file mode 100755 index 00000000..c78da42d --- /dev/null +++ b/r17/Revamped src/revamped_src/cd_null.c @@ -0,0 +1,55 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +#include "quakedef.h" + +void CDAudio_Play(byte track, qboolean looping) +{ +} + + +void CDAudio_Stop(void) +{ +} + + +void CDAudio_Pause(void) +{ +} + + +void CDAudio_Resume(void) +{ +} + + +void CDAudio_Update(void) +{ +} + + +int CDAudio_Init(void) +{ + return 0; +} + + +void CDAudio_Shutdown(void) +{ +} diff --git a/r17/Revamped src/revamped_src/cdaudio.h b/r17/Revamped src/revamped_src/cdaudio.h new file mode 100755 index 00000000..30dfd30a --- /dev/null +++ b/r17/Revamped src/revamped_src/cdaudio.h @@ -0,0 +1,27 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +int CDAudio_Init(void); +void CDAudio_Play(byte track, qboolean looping); +void CDAudio_Stop(void); +void CDAudio_Pause(void); +void CDAudio_Resume(void); +void CDAudio_Shutdown(void); +void CDAudio_Update(void); diff --git a/r17/Revamped src/revamped_src/chase.c b/r17/Revamped src/revamped_src/chase.c new file mode 100755 index 00000000..5a47c9f5 --- /dev/null +++ b/r17/Revamped src/revamped_src/chase.c @@ -0,0 +1,125 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// chase.c -- chase camera code + +#include "quakedef.h" + +cvar_t chase_back = {"chase_back", "100", true}; +cvar_t chase_up = {"chase_up", "16", true}; +cvar_t chase_right = {"chase_right", "0", true}; +cvar_t chase_active = {"chase_active", "0", false}; +cvar_t chase_roll = {"chase_roll", "0"}; +cvar_t chase_yaw = {"chase_yaw", "180"}; +cvar_t chase_pitch = {"chase_pitch", "45"}; + +vec3_t chase_pos; +vec3_t chase_angles; + +vec3_t chase_dest; +vec3_t chase_dest_angles; + + +void Chase_Init (void) +{ + Cvar_RegisterVariable (&chase_back); + Cvar_RegisterVariable (&chase_up); + Cvar_RegisterVariable (&chase_right); + Cvar_RegisterVariable (&chase_active); + Cvar_RegisterVariable (&chase_roll); + Cvar_RegisterVariable (&chase_yaw); + Cvar_RegisterVariable (&chase_pitch); + +} + +void Chase_Reset (void) +{ + // for respawning and teleporting +// start position 12 units behind head +} + +void TraceLine (vec3_t start, vec3_t end, vec3_t impact) +{ + trace_t trace; + + memset (&trace, 0, sizeof(trace)); + SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace); + + VectorCopy (trace.endpos, impact); +} + + +void Chase_Update (void) +{ + int i; + float dist; + vec3_t forward, up, right; + vec3_t dest, stop; + + if ((int)chase_active.value != 2) + { + // if can't see player, reset + AngleVectors (cl.viewangles, forward, right, up); + + // calc exact destination + for (i=0 ; i<3 ; i++) + chase_dest[i] = r_refdef.vieworg[i] + - forward[i]*chase_back.value + - right[i]*chase_right.value; + chase_dest[2] = r_refdef.vieworg[2] + chase_up.value; + + // find the spot the player is looking at + VectorMA (r_refdef.vieworg, 4096, forward, dest); + TraceLine (r_refdef.vieworg, dest, stop); + + // calculate pitch to look at the same spot from camera + VectorSubtract (stop, r_refdef.vieworg, stop); + dist = DotProduct (stop, forward); + if (dist < 1) + dist = 1; + + r_refdef.viewangles[PITCH] = -atan(stop[2] / dist) / M_PI * 180; + + TraceLine(r_refdef.vieworg, chase_dest, stop); + if (Length(stop) != 0) + VectorCopy(stop, chase_dest); + + // move towards destination + VectorCopy (chase_dest, r_refdef.vieworg); + } + else + { + chase_dest[0] = r_refdef.vieworg[0] + chase_back.value; + chase_dest[1] = r_refdef.vieworg[1] + chase_right.value; + chase_dest[2] = r_refdef.vieworg[2] + chase_up.value; + + // this is from the chasecam fix - start + TraceLine (r_refdef.vieworg, chase_dest, stop); + if (Length (stop) != 0) + { + VectorCopy (stop, chase_dest); + } + // this is from the chasecam fix - end + + VectorCopy (chase_dest, r_refdef.vieworg); + r_refdef.viewangles[ROLL] = chase_roll.value; + r_refdef.viewangles[YAW] = chase_yaw.value; + r_refdef.viewangles[PITCH] = chase_pitch.value; + } +} \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/cl_demo.c b/r17/Revamped src/revamped_src/cl_demo.c new file mode 100755 index 00000000..b82147f8 --- /dev/null +++ b/r17/Revamped src/revamped_src/cl_demo.c @@ -0,0 +1,380 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +#include "quakedef.h" + +void CL_FinishTimeDemo (void); + +/* +============================================================================== + +DEMO CODE + +When a demo is playing back, all NET_SendMessages are skipped, and +NET_GetMessages are read from the demo file. + +Whenever cl.time gets past the last received message, another message is +read from the demo file. +============================================================================== +*/ + +/* +============== +CL_StopPlayback + +Called when a demo file runs out, or the user starts a game +============== +*/ +void CL_StopPlayback (void) +{ + if (!cls.demoplayback) + return; + + Sys_FileClose(cls.demofile); + cls.demoplayback = false; + cls.demofile = -1; + cls.state = ca_disconnected; + + if (cls.timedemo) + CL_FinishTimeDemo (); +} + +/* +==================== +CL_WriteDemoMessage + +Dumps the current net message, prefixed by the length and view angles +==================== +*/ +void CL_WriteDemoMessage (void) +{ + int len; + int i; + float f; + + len = LittleLong (net_message.cursize); + Sys_FileWrite(cls.demofile, &len, 4); + for (i=0 ; i<3 ; i++) + { + f = LittleFloat (cl.viewangles[i]); + Sys_FileWrite(cls.demofile, &f, 4); + } + Sys_FileWrite(cls.demofile, net_message.data, net_message.cursize); +} + +/* +==================== +CL_GetMessage + +Handles recording and playback of demos, on top of NET_ code +==================== +*/ +int CL_GetMessage (void) +{ + int r, i; + float f; + + if (cls.demoplayback) + { + // decide if it is time to grab the next message + if (cls.signon == SIGNONS) // allways grab until fully connected + { + if (cls.timedemo) + { + if (host_framecount == cls.td_lastframe) + return 0; // allready read this frame's message + cls.td_lastframe = host_framecount; + // if this is the second frame, grab the real td_starttime + // so the bogus time on the first frame doesn't count + if (host_framecount == cls.td_startframe + 1) + cls.td_starttime = realtime; + } + else if ( /* cl.time > 0 && */ cl.time <= cl.mtime[0]) + { + return 0; // don't need another message yet + } + } + + // get the next message + Sys_FileRead(cls.demofile, &net_message.cursize, 4); + VectorCopy (cl.mviewangles[0], cl.mviewangles[1]); + for (i=0 ; i<3 ; i++) + { + r = Sys_FileRead(cls.demofile, &f, 4) / 4; + cl.mviewangles[0][i] = LittleFloat (f); + } + + net_message.cursize = LittleLong (net_message.cursize); + if (net_message.cursize > MAX_MSGLEN) + Sys_Error ("Demo message (0x%08x) > MAX_MSGLEN (%d)", net_message.cursize, MAX_MSGLEN); + r = Sys_FileRead(cls.demofile, net_message.data, net_message.cursize) / net_message.cursize; + if (r != 1) + { + CL_StopPlayback (); + return 0; + } + + return 1; + } + + while (1) + { + r = NET_GetMessage (cls.netcon); + + if (r != 1 && r != 2) + return r; + + // discard nop keepalive message + if (net_message.cursize == 1 && net_message.data[0] == svc_nop) + Con_Printf ("<-- server to client keepalive\n"); + else + break; + } + + if (cls.demorecording) + CL_WriteDemoMessage (); + + return r; +} + + +/* +==================== +CL_Stop_f + +stop recording a demo +==================== +*/ +void CL_Stop_f (void) +{ + if (cmd_source != src_command) + return; + + if (!cls.demorecording) + { + Con_Printf ("Not recording a demo.\n"); + return; + } + +// write a disconnect message to the demo file + SZ_Clear (&net_message); + MSG_WriteByte (&net_message, svc_disconnect); + CL_WriteDemoMessage (); + +// finish up + Sys_FileClose(cls.demofile); + cls.demofile = -1; + cls.demorecording = false; + Con_Printf ("Completed demo\n"); +} + +/* +==================== +CL_Record_f + +record [cd track] +==================== +*/ +void CL_Record_f (void) +{ + int c; + char name[MAX_OSPATH]; + int track; + char forcetrack[16]; + + if (cmd_source != src_command) + return; + + c = Cmd_Argc(); + if (c != 2 && c != 3 && c != 4) + { + Con_Printf ("record [ [cd track]]\n"); + return; + } + + if (strstr(Cmd_Argv(1), "..")) + { + Con_Printf ("Relative pathnames are not allowed.\n"); + return; + } + + if (c == 2 && cls.state == ca_connected) + { + Con_Printf("Can not record - already connected to server\nClient demo recording must be started before connecting\n"); + return; + } + +// write the forced cd track number, or -1 + if (c == 4) + { + track = atoi(Cmd_Argv(3)); + Con_Printf ("Forcing CD track to %i\n", cls.forcetrack); + } + else + track = -1; + + sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); + +// +// start the map up +// + if (c > 2) + Cmd_ExecuteString ( va("map %s", Cmd_Argv(2)), src_command); + +// +// open the demo file +// + COM_DefaultExtension (name, ".dem"); + + Con_Printf ("recording to %s.\n", name); + cls.demofile = Sys_FileOpenWrite(name); + if (cls.demofile < 0) + { + Con_Printf ("ERROR: couldn't open demo for writing.\n"); + return; + } + + cls.forcetrack = track; + sprintf(forcetrack, "%i\n", cls.forcetrack); + Sys_FileWrite(cls.demofile, forcetrack, strlen(forcetrack)); + + cls.demorecording = true; +} + + +/* +==================== +CL_PlayDemo_f + +play [demoname] +==================== +*/ +static int CL_FileGetChar(int handle) +{ + char c; + + if (Sys_FileRead(handle, &c, 1) != 1) + { + return EOF; + } + + return c; +} + +void CL_PlayDemo_f (void) +{ + char name[256]; + int c; + qboolean neg = false; + + if (cmd_source != src_command) + return; + + if (Cmd_Argc() != 2) + { + Con_Printf ("play : plays a demo\n"); + return; + } + +// +// disconnect from server +// + CL_Disconnect (); + +// +// open the demo file +// + strcpy (name, Cmd_Argv(1)); + COM_DefaultExtension (name, ".dem"); + + Con_Printf ("Playing demo from %s.\n", name); + COM_FOpenFile (name, &cls.demofile); + if (cls.demofile < 0) + { + Con_Printf ("ERROR: couldn't open demo for reading.\n"); + cls.demonum = -1; // stop demo loop + return; + } + + cls.demoplayback = true; + cls.state = ca_connected; + cls.forcetrack = 0; + + while ((c = CL_FileGetChar(cls.demofile)) != '\n') + if (c == '-') + neg = true; + else + cls.forcetrack = cls.forcetrack * 10 + (c - '0'); + + if (neg) + cls.forcetrack = -cls.forcetrack; +// ZOID, fscanf is evil +// fscanf (cls.demofile, "%i\n", &cls.forcetrack); +} + +/* +==================== +CL_FinishTimeDemo + +==================== +*/ +void CL_FinishTimeDemo (void) +{ + int frames; + double time; + + cls.timedemo = false; + +// the first frame didn't count + frames = (host_framecount - cls.td_startframe) - 1; + time = realtime - cls.td_starttime; + if (time < 1) + time = 1; + Con_Printf ("%i frames %5.1f seconds %5.1f fps\n", frames, time, frames/time); +} + +/* +==================== +CL_TimeDemo_f + +timedemo [demoname] +==================== +*/ +void CL_TimeDemo_f (void) +{ + if (cmd_source != src_command) + return; + + if (Cmd_Argc() != 2) + { + Con_Printf ("timedemo : gets demo speeds\n"); + return; + } + + CL_PlayDemo_f (); + +// cls.td_starttime will be grabbed at the second frame of the demo, so +// all the loading time doesn't get counted + + cls.timedemo = true; + cls.td_startframe = host_framecount; + cls.td_lastframe = -1; // get a new message this frame +} + diff --git a/r17/Revamped src/revamped_src/cl_input.c b/r17/Revamped src/revamped_src/cl_input.c new file mode 100755 index 00000000..46eae4a4 --- /dev/null +++ b/r17/Revamped src/revamped_src/cl_input.c @@ -0,0 +1,488 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// cl.input.c -- builds an intended movement command to send to the server + +// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All +// rights reserved. + +#include "quakedef.h" +#include +/* +=============================================================================== + +KEY BUTTONS + +Continuous button event tracking is complicated by the fact that two different +input sources (say, mouse button 1 and the control key) can both press the +same button, but the button should only be released when both of the +pressing key have been released. + +When a key event issues a button command (+forward, +attack, etc), it appends +its key number as a parameter to the command so it can be matched up with +the release. + +state bit 0 is the current state of the key +state bit 1 is edge triggered on the up to down transition +state bit 2 is edge triggered on the down to up transition + +=============================================================================== +*/ + + +kbutton_t in_mlook, in_klook; +kbutton_t in_left, in_right, in_forward, in_back; +kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright; +kbutton_t in_strafe, in_speed, in_use, in_jump, in_attack; +kbutton_t in_up, in_down; + +int in_impulse; + + + +void KeyDown (kbutton_t *b) +{ + int k; + char *c; + + c = Cmd_Argv(1); + if (c[0]) + k = atoi(c); + else + k = -1; // typed manually at the console for continuous down + + if (k == b->down[0] || k == b->down[1]) + return; // repeating key + + if (!b->down[0]) + b->down[0] = k; + else if (!b->down[1]) + b->down[1] = k; + else + { + Con_Printf ("Three keys down for a button!\n"); + return; + } + + if (b->state & 1) + return; // still down + b->state |= 1 + 2; // down + impulse down +} + +void KeyUp (kbutton_t *b) +{ + int k; + char *c; + + c = Cmd_Argv(1); + if (c[0]) + k = atoi(c); + else + { // typed manually at the console, assume for unsticking, so clear all + b->down[0] = b->down[1] = 0; + b->state = 4; // impulse up + return; + } + + if (b->down[0] == k) + b->down[0] = 0; + else if (b->down[1] == k) + b->down[1] = 0; + else + return; // key up without coresponding down (menu pass through) + if (b->down[0] || b->down[1]) + return; // some other key is still holding it down + + if (!(b->state & 1)) + return; // still up (this should not happen) + b->state &= ~1; // now up + b->state |= 4; // impulse up +} + +void IN_KLookDown (void) {KeyDown(&in_klook);} +void IN_KLookUp (void) {KeyUp(&in_klook);} +void IN_MLookDown (void) {KeyDown(&in_mlook);} +void IN_MLookUp (void) { +KeyUp(&in_mlook); +if ( !(in_mlook.state&1) && lookspring.value && !lookcenter.value) + V_StartPitchDrift(); +} +void IN_UpDown(void) {KeyDown(&in_up);} +void IN_UpUp(void) {KeyUp(&in_up);} +void IN_DownDown(void) {KeyDown(&in_down);} +void IN_DownUp(void) {KeyUp(&in_down);} +void IN_LeftDown(void) {KeyDown(&in_left);} +void IN_LeftUp(void) {KeyUp(&in_left);} +void IN_RightDown(void) {KeyDown(&in_right);} +void IN_RightUp(void) {KeyUp(&in_right);} +void IN_ForwardDown(void) {KeyDown(&in_forward);} +void IN_ForwardUp(void) {KeyUp(&in_forward);} +void IN_BackDown(void) {KeyDown(&in_back);} +void IN_BackUp(void) {KeyUp(&in_back);} +void IN_LookupDown(void) {KeyDown(&in_lookup);} +void IN_LookupUp(void) {KeyUp(&in_lookup);} +void IN_LookdownDown(void) {KeyDown(&in_lookdown);} +void IN_LookdownUp(void) {KeyUp(&in_lookdown);} +void IN_MoveleftDown(void) {KeyDown(&in_moveleft);} +void IN_MoveleftUp(void) {KeyUp(&in_moveleft);} +void IN_MoverightDown(void) {KeyDown(&in_moveright);} +void IN_MoverightUp(void) {KeyUp(&in_moveright);} + +void IN_SpeedDown(void) {KeyDown(&in_speed);} +void IN_SpeedUp(void) {KeyUp(&in_speed);} +void IN_StrafeDown(void) {KeyDown(&in_strafe);} +void IN_StrafeUp(void) {KeyUp(&in_strafe);} + +void IN_AttackDown(void) {KeyDown(&in_attack);} +void IN_AttackUp(void) {KeyUp(&in_attack);} + +void IN_UseDown (void) {KeyDown(&in_use);} +void IN_UseUp (void) {KeyUp(&in_use);} +void IN_JumpDown (void) {KeyDown(&in_jump);} +void IN_JumpUp (void) {KeyUp(&in_jump);} + +void IN_Impulse (void) {in_impulse=Q_atoi(Cmd_Argv(1));} + +/* +=============== +CL_KeyState + +Returns 0.25 if a key was pressed and released during the frame, +0.5 if it was pressed and held +0 if held then released, and +1.0 if held for the entire time +=============== +*/ +float CL_KeyState (kbutton_t *key) +{ + float val; + qboolean impulsedown, impulseup, down; + + impulsedown = key->state & 2; + impulseup = key->state & 4; + down = key->state & 1; + val = 0; + + if (impulsedown && !impulseup) + { + if (down) + val = 0.5; // pressed and held this frame + else + val = 0; // I_Error (); + } + if (impulseup && !impulsedown) + { + if (down) + val = 0; // I_Error (); + else + val = 0; // released this frame + } + if (!impulsedown && !impulseup) + { + if (down) + val = 1.0; // held the entire frame + else + val = 0; // up the entire frame + } + if (impulsedown && impulseup) + { + if (down) + val = 0.75; // released and re-pressed this frame + else + val = 0.25; // pressed and released this frame + } + + key->state &= 1; // clear impulses + + return val; +} + + + + +//========================================================================== + +cvar_t cl_upspeed = {"cl_upspeed","200"}; +cvar_t cl_forwardspeed = {"cl_forwardspeed","200", true}; +cvar_t cl_backspeed = {"cl_backspeed","200", true}; +cvar_t cl_sidespeed = {"cl_sidespeed","350"}; + +cvar_t cl_movespeedkey = {"cl_movespeedkey","2.0"}; + +cvar_t cl_yawspeed = {"cl_yawspeed","140"}; +cvar_t cl_pitchspeed = {"cl_pitchspeed","150"}; + +cvar_t cl_anglespeedkey = {"cl_anglespeedkey","1.5"}; + +extern cvar_t scr_fov; + +/* +================ +CL_AdjustAngles + +Moves the local angle positions +================ +*/ +void CL_AdjustAngles (void) +{ + float speed; + float up, down; + + if (in_speed.state & 1) + speed = host_frametime * cl_anglespeedkey.value; + else + speed = host_frametime; + + if (kurok) + { + if(scr_fov.value <= 25) + speed = speed / 4; + else if(scr_fov.value <= 50) + speed = speed / 3; + else if(scr_fov.value <= 75) + speed = speed / 2; + else + speed = speed; + } + + if (!(in_strafe.state & 1)) + { + cl.viewangles[YAW] -= speed*cl_yawspeed.value*CL_KeyState (&in_right); + cl.viewangles[YAW] += speed*cl_yawspeed.value*CL_KeyState (&in_left); + cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]); + } + if (in_klook.state & 1) + { + V_StopPitchDrift (); + cl.viewangles[PITCH] -= speed*cl_pitchspeed.value * CL_KeyState (&in_forward); + cl.viewangles[PITCH] += speed*cl_pitchspeed.value * CL_KeyState (&in_back); + } + + up = CL_KeyState (&in_lookup); + down = CL_KeyState(&in_lookdown); + + cl.viewangles[PITCH] -= speed*cl_pitchspeed.value * up; + cl.viewangles[PITCH] += speed*cl_pitchspeed.value * down; + + if (up || down) + V_StopPitchDrift (); + + if (cl.viewangles[PITCH] > 90) + cl.viewangles[PITCH] = 90; + if (cl.viewangles[PITCH] < -90) + cl.viewangles[PITCH] = -90; + + if (cl.viewangles[ROLL] > 50) + cl.viewangles[ROLL] = 50; + if (cl.viewangles[ROLL] < -50) + cl.viewangles[ROLL] = -50; + +} + +/* +================ +CL_BaseMove + +Send the intended movement message to the server +================ +*/ +void CL_BaseMove (usercmd_t *cmd) +{ + if (cls.signon != SIGNONS) + return; + + CL_AdjustAngles (); + + Q_memset (cmd, 0, sizeof(*cmd)); + + if (in_strafe.state & 1) + { + cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_right); + cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_left); + } + + cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_moveright); + cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_moveleft); + + cmd->upmove += cl_upspeed.value * CL_KeyState (&in_up); + cmd->upmove -= cl_upspeed.value * CL_KeyState (&in_down); + + if (! (in_klook.state & 1) ) + { + cmd->forwardmove += cl_forwardspeed.value * CL_KeyState (&in_forward); + cmd->forwardmove -= cl_backspeed.value * CL_KeyState (&in_back); + } + +// +// adjust for speed key +// + if (in_speed.state & 1) + { + cmd->forwardmove *= cl_movespeedkey.value; + cmd->sidemove *= cl_movespeedkey.value; + cmd->upmove *= cl_movespeedkey.value; + } + +#ifdef QUAKE2 + cmd->lightlevel = cl.light_level; +#endif +} + +/* +============== +CL_SendMove +============== +*/ +void CL_SendMove (usercmd_t *cmd) +{ + int i; + int bits; + sizebuf_t buf; + byte data[128]; + + buf.maxsize = 128; + buf.cursize = 0; + buf.data = data; + + cl.cmd = *cmd; + +// +// send the movement message +// + MSG_WriteByte (&buf, clc_move); + + MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times + + if (!cls.demoplayback) // JPG - precise aim for ProQuake! + { + for (i=0 ; i<3 ; i++) + MSG_WritePreciseAngle (&buf, cl.viewangles[i]); + } + else + { + for (i=0 ; i<3 ; i++) + MSG_WriteAngle (&buf, cl.viewangles[i]); + } + + +// for (i=0 ; i<3 ; i++) +// MSG_WriteAngle (&buf, cl.viewangles[i]); +/* + // Read the pad state. + SceCtrlData pad; + sceCtrlPeekBufferPositive(&pad, 1); + + MSG_WriteAngle (&buf, cl.viewangles[PITCH] + ((pad.Ly - 128))); + MSG_WriteAngle (&buf, cl.viewangles[YAW] + ((pad.Lx - 128))); + MSG_WriteAngle (&buf, cl.viewangles[ROLL]); +*/ + MSG_WriteShort (&buf, cmd->forwardmove); + MSG_WriteShort (&buf, cmd->sidemove); + MSG_WriteShort (&buf, cmd->upmove); + +// +// send button bits +// + bits = 0; + + if ( in_attack.state & 3 ) + bits |= 1; + in_attack.state &= ~2; + + if (in_jump.state & 3) + bits |= 2; + in_jump.state &= ~2; + + MSG_WriteByte (&buf, bits); + + MSG_WriteByte (&buf, in_impulse); + in_impulse = 0; + +#ifdef QUAKE2 +// +// light level +// + MSG_WriteByte (&buf, cmd->lightlevel); +#endif + +// +// deliver the message +// + if (cls.demoplayback) + return; + +// +// allways dump the first two message, because it may contain leftover inputs +// from the last level +// + if (++cl.movemessages <= 2) + return; + + if (NET_SendUnreliableMessage (cls.netcon, &buf) == -1) + { + Con_Printf ("CL_SendMove: lost server connection\n"); + CL_Disconnect (); + } +} + +/* +============ +CL_InitInput +============ +*/ +void CL_InitInput (void) +{ + Cmd_AddCommand ("+moveup",IN_UpDown); + Cmd_AddCommand ("-moveup",IN_UpUp); + Cmd_AddCommand ("+movedown",IN_DownDown); + Cmd_AddCommand ("-movedown",IN_DownUp); + Cmd_AddCommand ("+left",IN_LeftDown); + Cmd_AddCommand ("-left",IN_LeftUp); + Cmd_AddCommand ("+right",IN_RightDown); + Cmd_AddCommand ("-right",IN_RightUp); + Cmd_AddCommand ("+forward",IN_ForwardDown); + Cmd_AddCommand ("-forward",IN_ForwardUp); + Cmd_AddCommand ("+back",IN_BackDown); + Cmd_AddCommand ("-back",IN_BackUp); + Cmd_AddCommand ("+lookup", IN_LookupDown); + Cmd_AddCommand ("-lookup", IN_LookupUp); + Cmd_AddCommand ("+lookdown", IN_LookdownDown); + Cmd_AddCommand ("-lookdown", IN_LookdownUp); + Cmd_AddCommand ("+strafe", IN_StrafeDown); + Cmd_AddCommand ("-strafe", IN_StrafeUp); + Cmd_AddCommand ("+moveleft", IN_MoveleftDown); + Cmd_AddCommand ("-moveleft", IN_MoveleftUp); + Cmd_AddCommand ("+moveright", IN_MoverightDown); + Cmd_AddCommand ("-moveright", IN_MoverightUp); + Cmd_AddCommand ("+speed", IN_SpeedDown); + Cmd_AddCommand ("-speed", IN_SpeedUp); + Cmd_AddCommand ("+attack", IN_AttackDown); + Cmd_AddCommand ("-attack", IN_AttackUp); + Cmd_AddCommand ("+use", IN_UseDown); + Cmd_AddCommand ("-use", IN_UseUp); + Cmd_AddCommand ("+jump", IN_JumpDown); + Cmd_AddCommand ("-jump", IN_JumpUp); + Cmd_AddCommand ("impulse", IN_Impulse); + Cmd_AddCommand ("+klook", IN_KLookDown); + Cmd_AddCommand ("-klook", IN_KLookUp); + Cmd_AddCommand ("+mlook", IN_MLookDown); + Cmd_AddCommand ("-mlook", IN_MLookUp); + +} + diff --git a/r17/Revamped src/revamped_src/cl_main.c b/r17/Revamped src/revamped_src/cl_main.c new file mode 100755 index 00000000..570f9bc3 --- /dev/null +++ b/r17/Revamped src/revamped_src/cl_main.c @@ -0,0 +1,876 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// cl_main.c -- client main loop + +#include "quakedef.h" + +// we need to declare some mouse variables here, because the menu system +// references them even when on a unix system. + +// these two are not intended to be set directly +cvar_t cl_name = {"_cl_name", "player", true}; +cvar_t cl_color = {"_cl_color", "13", true}; + +cvar_t cl_shownet = {"cl_shownet","0"}; // can be 0, 1, or 2 +cvar_t cl_nolerp = {"cl_nolerp","0"}; + +cvar_t cl_autoaim = {"cl_autoaim", "1", true}; + +cvar_t lookspring = {"lookspring","0", true}; +cvar_t lookstrafe = {"lookstrafe","0", true}; +cvar_t lookcenter = {"lookcenter","1", true}; +cvar_t in_sensitivity = {"sensitivity","3", true}; +cvar_t in_tolerance = {"tolerance","0.25", true}; +cvar_t in_acceleration = {"acceleration","1.0", true}; + +cvar_t m_pitch = {"m_pitch","0.022", true}; +cvar_t m_yaw = {"m_yaw","0.022", true}; +cvar_t m_forward = {"m_forward","1", true}; +cvar_t m_side = {"m_side","0.8", true}; + +cvar_t in_freelook_analog = {"in_freelook_analog", "0", true}; +cvar_t in_disable_analog = {"in_disable_analog", "0", true}; +cvar_t in_analog_strafe = {"in_analog_strafe", "0", true}; + +cvar_t in_x_axis_adjust = {"in_x_axis_adjust", "0", true}; +cvar_t in_y_axis_adjust = {"in_y_axis_adjust", "0", true}; + +client_static_t cls; +client_state_t cl; +// FIXME: put these on hunk? +efrag_t cl_efrags[MAX_EFRAGS]; +entity_t cl_entities[MAX_EDICTS]; +entity_t cl_static_entities[MAX_STATIC_ENTITIES]; +lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; +dlight_t cl_dlights[MAX_DLIGHTS]; + +int cl_numvisedicts; +entity_t *cl_visedicts[MAX_VISEDICTS]; + +modelindex_t cl_modelindex[NUM_MODELINDEX]; +char *cl_modelnames[NUM_MODELINDEX]; + +/* +===================== +CL_ClearState + +===================== +*/ +void CL_ClearState (void) +{ + int i; + + if (!sv.active) + Host_ClearMemory (); + +// wipe the entire cl structure + memset (&cl, 0, sizeof(cl)); + + SZ_Clear (&cls.message); + +// clear other arrays + memset (cl_efrags, 0, sizeof(cl_efrags)); + memset (cl_entities, 0, sizeof(cl_entities)); + memset (cl_dlights, 0, sizeof(cl_dlights)); + memset (cl_lightstyle, 0, sizeof(cl_lightstyle)); + memset (cl_temp_entities, 0, sizeof(cl_temp_entities)); + memset (cl_beams, 0, sizeof(cl_beams)); + +// +// allocate the efrags and chain together into a free list +// + cl.free_efrags = cl_efrags; + for (i=0 ; i>4, ((int)cl_color.value)&15)); + + MSG_WriteByte (&cls.message, clc_stringcmd); + sprintf (str, "spawn %s", cls.spawnparms); + MSG_WriteString (&cls.message, str); + break; + + case 3: + MSG_WriteByte (&cls.message, clc_stringcmd); + MSG_WriteString (&cls.message, "begin"); + Cache_Report (); // print remaining memory + break; + + case 4: + SCR_EndLoadingPlaque (); // allow normal screen updates + break; + } +} + +/* +===================== +CL_NextDemo + +Called to play the next demo in the demo loop +===================== +*/ +void CL_NextDemo (void) +{ + char str[1024]; + + if (cls.demonum == -1) + return; // don't play demos + + SCR_BeginLoadingPlaque (); + + if (!cls.demos[cls.demonum][0] || cls.demonum == MAX_DEMOS) + { + cls.demonum = 0; + if (!cls.demos[cls.demonum][0]) + { + Con_Printf ("No demos listed with startdemos\n"); + cls.demonum = -1; + return; + } + } + + sprintf (str,"playdemo %s\n", cls.demos[cls.demonum]); + Cbuf_InsertText (str); + cls.demonum++; +} + +/* +============== +CL_PrintEntities_f +============== +*/ +void CL_PrintEntities_f (void) +{ + entity_t *ent; + int i; + + for (i=0,ent=cl_entities ; imodel) + { + Con_Printf ("EMPTY\n"); + continue; + } + Con_Printf ("%s:%2i (%5.1f,%5.1f,%5.1f) [%5.1f %5.1f %5.1f]\n" + ,ent->model->name,ent->frame, ent->origin[0], ent->origin[1], ent->origin[2], ent->angles[0], ent->angles[1], ent->angles[2]); + } +} + + +/* +=============== +SetPal + +Debugging tool, just flashes the screen +=============== +*/ +void SetPal (int i) +{ +#if 0 + static int old; + byte pal[768]; + int c; + + if (i == old) + return; + old = i; + + if (i==0) + VID_SetPalette (host_basepal); + else if (i==1) + { + for (c=0 ; c<768 ; c+=3) + { + pal[c] = 0; + pal[c+1] = 255; + pal[c+2] = 0; + } + VID_SetPalette (pal); + } + else + { + for (c=0 ; c<768 ; c+=3) + { + pal[c] = 0; + pal[c+1] = 0; + pal[c+2] = 255; + } + VID_SetPalette (pal); + } +#endif +} + +/* +=============== +CL_AllocDlight + +=============== +*/ +dlight_t *CL_AllocDlight (int key) +{ + int i; + dlight_t *dl; + +// first look for an exact key match + if (key) + { + dl = cl_dlights; + for (i=0 ; ikey == key) + { + memset (dl, 0, sizeof(*dl)); + dl->key = key; + dl->color[0] = dl->color[1] = dl->color[2] = 1; // LordHavoc: .lit support + return dl; + } + } + } + +// then look for anything else + dl = cl_dlights; + for (i=0 ; idie < cl.time) + { + memset (dl, 0, sizeof(*dl)); + dl->key = key; + dl->color[0] = dl->color[1] = dl->color[2] = 1; // LordHavoc: .lit support + return dl; + } + } + + dl = &cl_dlights[0]; + memset (dl, 0, sizeof(*dl)); + dl->key = key; + dl->color[0] = dl->color[1] = dl->color[2] = 1; // LordHavoc: .lit support + return dl; +} + + +/* +=============== +CL_DecayLights + +=============== +*/ +void CL_DecayLights (void) +{ + int i; + dlight_t *dl; + float time; + + time = cl.time - cl.oldtime; + + dl = cl_dlights; + for (i=0 ; idie < cl.time || !dl->radius) + continue; + + dl->radius -= time*dl->decay; + if (dl->radius < 0) + dl->radius = 0; + } +} + + +/* +=============== +CL_LerpPoint + +Determines the fraction between the last two messages that the objects +should be put at. +=============== +*/ +float CL_LerpPoint (void) +{ + float f, frac; + + f = cl.mtime[0] - cl.mtime[1]; + + if (!f || cl_nolerp.value || cls.timedemo || sv.active) + { + cl.time = cl.mtime[0]; + return 1; + } + + if (f > 0.1) + { // dropped packet, or start of demo + cl.mtime[1] = cl.mtime[0] - 0.1; + f = 0.1; + } + frac = (cl.time - cl.mtime[1]) / f; +// Con_Printf ("frac: %f\n",frac); + if (frac < 0) + { + if (frac < -0.01) + { +SetPal(1); + cl.time = cl.mtime[1]; +// Con_Printf ("low frac\n"); + } + frac = 0; + } + else if (frac > 1) + { + if (frac > 1.01) + { +SetPal(2); + cl.time = cl.mtime[0]; +// Con_Printf ("high frac\n"); + } + frac = 1; + } + else + SetPal(0); + + return frac; +} + + +/* +=============== +CL_RelinkEntities +=============== +*/ +void CL_RelinkEntities (void) +{ + entity_t *ent; + int i, j; + float frac, f, d; + vec3_t delta; + float bobjrotate; + vec3_t oldorg; + dlight_t *dl; + +// determine partial update time + frac = CL_LerpPoint (); + + cl_numvisedicts = 0; + +// +// interpolate player info +// + for (i=0 ; i<3 ; i++) + cl.velocity[i] = cl.mvelocity[1][i] + + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]); + + if (cls.demoplayback) + { + // interpolate the angles + for (j=0 ; j<3 ; j++) + { + d = cl.mviewangles[0][j] - cl.mviewangles[1][j]; + if (d > 180) + d -= 360; + else if (d < -180) + d += 360; + cl.viewangles[j] = cl.mviewangles[1][j] + frac*d; + } + } + + bobjrotate = anglemod(100*cl.time); + +// start on the entity after the world + for (i=1,ent=cl_entities+1 ; imodel) + { // empty slot + if (ent->forcelink) + R_RemoveEfrags (ent); // just became empty + continue; + } + +// if the object wasn't included in the last packet, remove it + if (ent->msgtime != cl.mtime[0]) + { + ent->model = NULL; + + // fenix@io.com: model transform interpolation + ent->frame_start_time = 0; + ent->translate_start_time = 0; + ent->rotate_start_time = 0; + + continue; + } + + VectorCopy (ent->origin, oldorg); + + if (ent->forcelink) + { // the entity was not updated in the last message + // so move to the final spot + VectorCopy (ent->msg_origins[0], ent->origin); + VectorCopy (ent->msg_angles[0], ent->angles); + } + else + { // if the delta is large, assume a teleport and don't lerp + f = frac; + for (j=0 ; j<3 ; j++) + { + delta[j] = ent->msg_origins[0][j] - ent->msg_origins[1][j]; + if (delta[j] > 100 || delta[j] < -100) + f = 1; // assume a teleportation, not a motion + } + // fenix@io.com: model transform interpolation + // interpolation should be reset in the event of a large delta + + if (f >= 1) + { +// ent->frame_start_time = 0; + ent->translate_start_time = 0; + ent->rotate_start_time = 0; + } + + // interpolate the origin and angles + for (j=0 ; j<3 ; j++) + { + ent->origin[j] = ent->msg_origins[1][j] + f*delta[j]; + + d = ent->msg_angles[0][j] - ent->msg_angles[1][j]; + if (d > 180) + d -= 360; + else if (d < -180) + d += 360; + ent->angles[j] = ent->msg_angles[1][j] + f*d; + } + + } + +// rotate binary objects locally + if (ent->model->flags & EF_ROTATE) + ent->angles[1] = bobjrotate; + + if (ent->effects & EF_BRIGHTFIELD) + R_EntityParticles (ent); +#ifdef QUAKE2 + if (ent->effects & EF_DARKFIELD) + R_DarkFieldParticles (ent); +#endif + if (ent->effects & EF_MUZZLEFLASH) + { + vec3_t fv, rv, uv; + + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->origin[2] += 16; + AngleVectors (ent->angles, fv, rv, uv); + + VectorMA (dl->origin, 18, fv, dl->origin); + dl->radius = 200 + (rand()&31); + dl->minlight = 32; + dl->die = cl.time + 0.1; + dl->minlight = 16; + dl->color[0] = 0.9; + dl->color[1] = 0.8; + dl->color[2] = 0.6; + } + if (ent->effects & EF_BRIGHTLIGHT) + { + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->origin[2] += 16; + dl->radius = 400 + (rand()&31); + dl->die = cl.time + 0.001; + dl->color[0] = 1; + dl->color[1] = 0.8; + dl->color[2] = 0.5; + } + if (ent->effects & EF_DIMLIGHT) + { + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->radius = 200 + (rand()&31); + dl->die = cl.time + 0.001; + dl->radius = 100 + (rand()&31); + dl->color[0] = 0.5; + dl->color[1] = 0.5; + dl->color[2] = 0.5; + } + + // Kurok effects + if (ent->effects & EF_REDLIGHT) + { + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->radius = 200 + (rand()&31); + dl->die = cl.time + 0.001; + dl->radius = 150 + (rand()&31); + dl->color[0] = 2; + dl->color[1] = 0.25; + dl->color[2] = 0.25; + } + if (ent->effects & EF_BLUELIGHT) + { + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->radius = 200 + (rand()&31); + dl->die = cl.time + 0.001; + dl->radius = 150 + (rand()&31); + dl->color[0] = 0.25; + dl->color[1] = 0.25; + dl->color[2] = 2; + } + //Revamped Effects + if (ent->effects & EF_PINKLIGHT) + { + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->radius = 200 + (rand()&31); + dl->die = cl.time + 0.001; + dl->radius = 150 + (rand()&31); + dl->color[0] = 2; + dl->color[1] = 1.4; + dl->color[2] = 1.8; + } + + if (ent->effects & EF_GREENLIGHT) + { + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->radius = 200 + (rand()&31); + dl->die = cl.time + 0.001; + dl->radius = 150 + (rand()&31); + dl->color[0] = 0; + dl->color[1] = 2; + dl->color[2] = 0; + } + +#ifdef QUAKE2 + if (ent->effects & EF_DARKLIGHT) + { + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->radius = 200.0 + (rand()&31); + dl->die = cl.time + 0.001; + dl->dark = true; + } + if (ent->effects & EF_LIGHT) + { + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->radius = 200; + dl->die = cl.time + 0.001; + } +#endif + + if (ent->model->flags & EF_GIB) + R_RocketTrail (oldorg, ent->origin, 2); + else if (ent->model->flags & EF_ZOMGIB) + R_RocketTrail (oldorg, ent->origin, 4); + else if (ent->model->flags & EF_TRACER) + R_RocketTrail (oldorg, ent->origin, 3); + else if (ent->model->flags & EF_TRACER2) + R_RocketTrail (oldorg, ent->origin, 5); + else if (ent->model->flags & EF_ROCKET) + { + R_RocketTrail (oldorg, ent->origin, 0); + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->radius = 200; + dl->die = cl.time + 0.01; + } + else if (ent->model->flags & EF_GRENADE) + R_RocketTrail (oldorg, ent->origin, 1); + else if (ent->model->flags & EF_TRACER3) + R_RocketTrail (oldorg, ent->origin, 6); + + // Tomaz - QC Glow Begin + + else if (ent->glow_size) + { + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->radius = ent->glow_size; + dl->die = cl.time + 0.001; + dl->color[0] = ent->glow_red; + dl->color[1] = ent->glow_green; + dl->color[2] = ent->glow_blue; + } + + // Tomaz - QC Glow End + + ent->forcelink = false; + + if (i == cl.viewentity && !chase_active.value) + continue; + +#ifdef QUAKE2 + if ( ent->effects & EF_NODRAW ) + continue; +#endif + if (cl_numvisedicts < MAX_VISEDICTS) + { + cl_visedicts[cl_numvisedicts] = ent; + cl_numvisedicts++; + } + } + +} + + +/* +=============== +CL_ReadFromServer + +Read all incoming data from the server +=============== +*/ +int CL_ReadFromServer (void) +{ + int ret; + + cl.oldtime = cl.time; + cl.time += host_frametime; + + do + { + ret = CL_GetMessage (); + if (ret == -1) + Host_Error ("CL_ReadFromServer: lost server connection"); + if (!ret) + break; + + cl.last_received_message = realtime; + CL_ParseServerMessage (); + } while (ret && cls.state == ca_connected); + + if (cl_shownet.value) + Con_Printf ("\n"); + + CL_RelinkEntities (); + CL_UpdateTEnts (); + +// +// bring the links up to date +// + return 0; +} + +/* +================= +CL_SendCmd +================= +*/ +void CL_SendCmd (void) +{ + usercmd_t cmd; + + if (cls.state != ca_connected) + return; + + if (cls.signon == SIGNONS) + { + // get basic movement from keyboard + CL_BaseMove (&cmd); + + // allow mice or other external controllers to add to the move + if (!in_disable_analog.value) + IN_Move (&cmd); + + // send the unreliable message + CL_SendMove (&cmd); + + } + + if (cls.demoplayback) + { + SZ_Clear (&cls.message); + return; + } + +// send the reliable message + if (!cls.message.cursize) + return; // no message at all + + if (!NET_CanSendMessage (cls.netcon)) + { + Con_DPrintf ("CL_WriteToServer: can't send\n"); + return; + } + + if (NET_SendMessage (cls.netcon, &cls.message) == -1) + Host_Error ("CL_WriteToServer: lost server connection"); + + SZ_Clear (&cls.message); +} + +/* +================= +CL_Init +================= +*/ +void CL_Init (void) +{ + SZ_Alloc (&cls.message, 1024); + + CL_InitInput (); + CL_InitTEnts (); + +// +// register our commands +// + Cvar_RegisterVariable (&cl_name); + Cvar_RegisterVariable (&cl_color); + Cvar_RegisterVariable (&cl_upspeed); + Cvar_RegisterVariable (&cl_forwardspeed); + Cvar_RegisterVariable (&cl_backspeed); + Cvar_RegisterVariable (&cl_sidespeed); + Cvar_RegisterVariable (&cl_movespeedkey); + Cvar_RegisterVariable (&cl_yawspeed); + Cvar_RegisterVariable (&cl_pitchspeed); + Cvar_RegisterVariable (&cl_anglespeedkey); + Cvar_RegisterVariable (&cl_shownet); + Cvar_RegisterVariable (&cl_nolerp); + Cvar_RegisterVariable (&cl_autoaim); + Cvar_RegisterVariable (&lookspring); + Cvar_RegisterVariable (&lookstrafe); + Cvar_RegisterVariable (&lookcenter); + + Cvar_RegisterVariable (&in_sensitivity); + Cvar_RegisterVariable (&in_tolerance); + Cvar_RegisterVariable (&in_acceleration); + Cvar_RegisterVariable (&in_freelook_analog); + Cvar_RegisterVariable (&in_disable_analog); + Cvar_RegisterVariable (&in_analog_strafe); + + Cvar_RegisterVariable (&in_x_axis_adjust); + Cvar_RegisterVariable (&in_y_axis_adjust); + + Cvar_RegisterVariable (&m_pitch); + Cvar_RegisterVariable (&m_yaw); + Cvar_RegisterVariable (&m_forward); + Cvar_RegisterVariable (&m_side); + +// Cvar_RegisterVariable (&cl_autofire); + + Cmd_AddCommand ("entities", CL_PrintEntities_f); + Cmd_AddCommand ("disconnect", CL_Disconnect_f); + Cmd_AddCommand ("record", CL_Record_f); + Cmd_AddCommand ("stop", CL_Stop_f); + Cmd_AddCommand ("playdemo", CL_PlayDemo_f); + Cmd_AddCommand ("timedemo", CL_TimeDemo_f); +} + diff --git a/r17/Revamped src/revamped_src/cl_parse.c b/r17/Revamped src/revamped_src/cl_parse.c new file mode 100755 index 00000000..64142dc2 --- /dev/null +++ b/r17/Revamped src/revamped_src/cl_parse.c @@ -0,0 +1,1030 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// cl_parse.c -- parse a message received from the server + +#include "quakedef.h" + +extern cvar_t bgmtype; + +char *svc_strings[] = +{ + "svc_bad", + "svc_nop", + "svc_disconnect", + "svc_updatestat", + "svc_version", // [long] server version + "svc_setview", // [short] entity number + "svc_sound", // + "svc_time", // [float] server time + "svc_print", // [string] null terminated string + "svc_stufftext", // [string] stuffed into client's console buffer + // the string should be \n terminated + "svc_setangle", // [vec3] set the view angle to this absolute value + + "svc_serverinfo", // [long] version + // [string] signon string + // [string]..[0]model cache [string]...[0]sounds cache + // [string]..[0]item cache + "svc_lightstyle", // [byte] [string] + "svc_updatename", // [byte] [string] + "svc_updatefrags", // [byte] [short] + "svc_clientdata", // + "svc_stopsound", // + "svc_updatecolors", // [byte] [byte] + "svc_particle", // [vec3] + "svc_damage", // [byte] impact [byte] blood [vec3] from + + "svc_spawnstatic", + "OBSOLETE svc_spawnbinary", + "svc_spawnbaseline", + + "svc_temp_entity", // + "svc_setpause", + "svc_signonnum", + "svc_centerprint", + "svc_killedmonster", + "svc_foundsecret", + "svc_spawnstaticsound", + "svc_intermission", + "svc_finale", // [string] music [string] text + "svc_cdtrack", // [byte] track [byte] looptrack + "svc_sellscreen", + "svc_cutscene", + "", + "", + "svc_skybox", // 37 // [string] skyname + "", + "", + "", + "svc_fog", // 41 // [byte] start [byte] end [byte] red [byte] green [byte] blue [float] time +}; + +//============================================================================= + +/* +=============== +CL_EntityNum + +This error checks and tracks the total number of entities +=============== +*/ +entity_t *CL_EntityNum (int num) +{ + if (num >= cl.num_entities) + { + if (num >= MAX_EDICTS) + Host_Error ("CL_EntityNum: %i is an invalid number",num); + while (cl.num_entities<=num) + { + cl_entities[cl.num_entities].colormap = vid.colormap; + cl.num_entities++; + } + } + + return &cl_entities[num]; +} + + +/* +================== +CL_ParseStartSoundPacket +================== +*/ +void CL_ParseStartSoundPacket(void) +{ + vec3_t pos; + int channel, ent; + int sound_num; + int volume; + int field_mask; + float attenuation; + int i; + + field_mask = MSG_ReadByte(); + + if (field_mask & SND_VOLUME) + volume = MSG_ReadByte (); + else + volume = DEFAULT_SOUND_PACKET_VOLUME; + + if (field_mask & SND_ATTENUATION) + attenuation = MSG_ReadByte () / 64.0; + else + attenuation = DEFAULT_SOUND_PACKET_ATTENUATION; + + channel = MSG_ReadShort (); + sound_num = MSG_ReadByte (); + + ent = channel >> 3; + channel &= 7; + + if (ent > MAX_EDICTS) + Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent); + + for (i=0 ; i<3 ; i++) + pos[i] = MSG_ReadCoord (); + + S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation); +} + +/* +================== +CL_KeepaliveMessage + +When the client is taking a long time to load stuff, send keepalive messages +so the server doesn't disconnect. +================== +*/ +void CL_KeepaliveMessage (void) +{ + double time; + static float lastmsg; + int ret; + sizebuf_t old; + byte olddata[8192]; + + if (sv.active) + return; // no need if server is local + if (cls.demoplayback) + return; + +// read messages from server, should just be nops + old = net_message; + memcpy (olddata, net_message.data, net_message.cursize); + + do + { + ret = CL_GetMessage (); + switch (ret) + { + default: + Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed"); + case 0: + break; // nothing waiting + case 1: + Host_Error ("CL_KeepaliveMessage: received a message"); + break; + case 2: + if (MSG_ReadByte() != svc_nop) + Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop"); + break; + } + } while (ret); + + net_message = old; + memcpy (net_message.data, olddata, net_message.cursize); + +// check time + time = Sys_FloatTime (); + if (time - lastmsg < 5) + return; + lastmsg = time; + +// write out a nop + Con_Printf ("--> client to server keepalive\n"); + + MSG_WriteByte (&cls.message, clc_nop); + NET_SendMessage (cls.netcon, &cls.message); + SZ_Clear (&cls.message); +} + +/* +================== +CL_ParseServerInfo +================== +*/ +void CL_ParseServerInfo (void) +{ + char *str; + int i; + int nummodels, numsounds; + char model_precache[MAX_MODELS][MAX_QPATH]; + char sound_precache[MAX_SOUNDS][MAX_QPATH]; + + Con_DPrintf ("Serverinfo packet received.\n"); +// +// wipe the client_state_t struct +// + CL_ClearState (); + +// parse protocol version number + i = MSG_ReadLong (); + if (i != PROTOCOL_VERSION) + { + Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION); + return; + } + +// parse maxclients + cl.maxclients = MSG_ReadByte (); + if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD) + { + Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients); + return; + } + cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores"); + +// parse gametype + cl.gametype = MSG_ReadByte (); + +// parse signon message + str = MSG_ReadString (); + strncpy (cl.levelname, str, sizeof(cl.levelname)-1); + +// seperate the printfs so the server message can have a color + Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n"); + Con_Printf ("%c%s\n", 2, str); + +// +// first we go through and touch all of the precache data that still +// happens to be in the cache, so precaching something else doesn't +// needlessly purge it +// + +// precache models + memset (cl.model_precache, 0, sizeof(cl.model_precache)); + for (nummodels=1 ; ; nummodels++) + { + str = MSG_ReadString (); + if (!str[0]) + break; + if (nummodels==MAX_MODELS) + { + Con_Printf ("Server sent too many model precaches\n"); + return; + } + strcpy (model_precache[nummodels], str); + Mod_TouchModel (str); + } + +// precache sounds + memset (cl.sound_precache, 0, sizeof(cl.sound_precache)); + for (numsounds=1 ; ; numsounds++) + { + str = MSG_ReadString (); + if (!str[0]) + break; + if (numsounds==MAX_SOUNDS) + { + Con_Printf ("Server sent too many sound precaches\n"); + return; + } + strcpy (sound_precache[numsounds], str); + S_TouchSound (str); + } + +// +// now we try to load everything else until a cache allocation fails +// + + for (i=1 ; imsgtime != cl.mtime[1]) + forcelink = true; // no previous frame to lerp from + else + forcelink = false; + + ent->msgtime = cl.mtime[0]; + + if (bits & U_MODEL) + { + modnum = MSG_ReadByte (); + if (modnum >= MAX_MODELS) + Host_Error ("CL_ParseModel: bad modnum"); + } + else + modnum = ent->baseline.modelindex; + + model = cl.model_precache[modnum]; + if (model != ent->model) + { + ent->model = model; + // automatic animation (torches, etc) can be either all together + // or randomized + if (model) + { + if (model->synctype == ST_RAND) + ent->syncbase = (float)(rand()&0x7fff) / 0x7fff; + else + ent->syncbase = 0.0; + } + else + forcelink = true; // hack to make null model players work +#if defined(GLQUAKE) //|| defined(PSP_HARDWARE_VIDEO) + if (num > 0 && num <= cl.maxclients) + R_TranslatePlayerSkin (num - 1); +#endif + } + + if (bits & U_FRAME) + ent->frame = MSG_ReadByte (); + else + ent->frame = ent->baseline.frame; + + if (bits & U_COLORMAP) + i = MSG_ReadByte(); + else + i = ent->baseline.colormap; + if (!i) + ent->colormap = vid.colormap; + else + { + if (i > cl.maxclients) + Sys_Error ("i >= cl.maxclients"); + ent->colormap = cl.scores[i-1].translations; + } + +#if defined(GLQUAKE) //|| defined(PSP_HARDWARE_VIDEO) + if (bits & U_SKIN) + skin = MSG_ReadByte(); + else + skin = ent->baseline.skin; + if (skin != ent->skinnum) { + ent->skinnum = skin; + if (num > 0 && num <= cl.maxclients) + R_TranslatePlayerSkin (num - 1); + } + +#else + + if (bits & U_SKIN) + ent->skinnum = MSG_ReadByte(); + else + ent->skinnum = ent->baseline.skin; +#endif + + if (bits & U_EFFECTS) + ent->effects = MSG_ReadByte(); + else + ent->effects = ent->baseline.effects; + +// shift the known values for interpolation + VectorCopy (ent->msg_origins[0], ent->msg_origins[1]); + VectorCopy (ent->msg_angles[0], ent->msg_angles[1]); + + if (bits & U_ORIGIN1) + ent->msg_origins[0][0] = MSG_ReadCoord (); + else + ent->msg_origins[0][0] = ent->baseline.origin[0]; + if (bits & U_ANGLE1) + ent->msg_angles[0][0] = MSG_ReadAngle(); + else + ent->msg_angles[0][0] = ent->baseline.angles[0]; + + if (bits & U_ORIGIN2) + ent->msg_origins[0][1] = MSG_ReadCoord (); + else + ent->msg_origins[0][1] = ent->baseline.origin[1]; + if (bits & U_ANGLE2) + ent->msg_angles[0][1] = MSG_ReadAngle(); + else + ent->msg_angles[0][1] = ent->baseline.angles[1]; + + if (bits & U_ORIGIN3) + ent->msg_origins[0][2] = MSG_ReadCoord (); + else + ent->msg_origins[0][2] = ent->baseline.origin[2]; + if (bits & U_ANGLE3) + ent->msg_angles[0][2] = MSG_ReadAngle(); + else + ent->msg_angles[0][2] = ent->baseline.angles[2]; + +// Tomaz - QC Alpha Scale Glow Begin + + if (bits & U_ALPHA) + ent->alpha = MSG_ReadFloat(); + else + ent->alpha = 1.0; + + if (bits & U_SCALE) + ent->scale = MSG_ReadFloat(); + else + ent->scale = 1.0; + + if (bits & U_GLOW_SIZE) + ent->glow_size = MSG_ReadFloat(); + else + ent->glow_size = 0; + + if (bits & U_GLOW_RED) + ent->glow_red = MSG_ReadFloat(); + else + ent->glow_red = 0; + + if (bits & U_GLOW_GREEN) + ent->glow_green = MSG_ReadFloat(); + else + ent->glow_green = 0; + + if (bits & U_GLOW_BLUE) + ent->glow_blue = MSG_ReadFloat(); + else + ent->glow_blue = 0; + +// Tomaz - QC Alpha Scale Glow End + + if ( bits & U_NOLERP ) + ent->forcelink = true; + + if ( forcelink ) + { // didn't have an update last message + VectorCopy (ent->msg_origins[0], ent->msg_origins[1]); + VectorCopy (ent->msg_origins[0], ent->origin); + VectorCopy (ent->msg_angles[0], ent->msg_angles[1]); + VectorCopy (ent->msg_angles[0], ent->angles); + ent->forcelink = true; + } +} + +/* +================== +CL_ParseBaseline +================== +*/ +void CL_ParseBaseline (entity_t *ent) +{ + int i; + + ent->baseline.modelindex = MSG_ReadByte (); + ent->baseline.frame = MSG_ReadByte (); + ent->baseline.colormap = MSG_ReadByte(); + ent->baseline.skin = MSG_ReadByte(); + for (i=0 ; i<3 ; i++) + { + ent->baseline.origin[i] = MSG_ReadCoord (); + ent->baseline.angles[i] = MSG_ReadAngle (); + } +} + + +/* +================== +CL_ParseClientdata + +Server information pertaining to this client only +================== +*/ +void CL_ParseClientdata (int bits) +{ + int i, j; + + if (bits & SU_VIEWHEIGHT) + cl.viewheight = MSG_ReadChar (); + else + cl.viewheight = DEFAULT_VIEWHEIGHT; + + if (bits & SU_IDEALPITCH) + cl.idealpitch = MSG_ReadChar (); + else + cl.idealpitch = 0; + + VectorCopy (cl.mvelocity[0], cl.mvelocity[1]); + for (i=0 ; i<3 ; i++) + { + if (bits & (SU_PUNCH1< cl.maxclients) + Sys_Error ("CL_NewTranslation: slot > cl.maxclients"); + dest = cl.scores[slot].translations; + source = vid.colormap; + memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations)); + top = cl.scores[slot].colors & 0xf0; + bottom = (cl.scores[slot].colors &15)<<4; + +#if defined(GLQUAKE) // || defined(PSP_HARDWARE_VIDEO) + R_TranslatePlayerSkin (slot); +#endif + + for (i=0 ; i= MAX_STATIC_ENTITIES) + Host_Error ("Too many static entities"); + ent = &cl_static_entities[i]; + cl.num_statics++; + CL_ParseBaseline (ent); + +// copy it to the current state + ent->model = cl.model_precache[ent->baseline.modelindex]; + ent->frame = ent->baseline.frame; + ent->colormap = vid.colormap; + ent->skinnum = ent->baseline.skin; + ent->effects = ent->baseline.effects; + + VectorCopy (ent->baseline.origin, ent->origin); + VectorCopy (ent->baseline.angles, ent->angles); + R_AddEfrags (ent); +} + +/* +=================== +CL_ParseStaticSound +=================== +*/ +void CL_ParseStaticSound (void) +{ + vec3_t org; + int sound_num, vol, atten; + int i; + + for (i=0 ; i<3 ; i++) + org[i] = MSG_ReadCoord (); + sound_num = MSG_ReadByte (); + vol = MSG_ReadByte (); + atten = MSG_ReadByte (); + + S_StaticSound (cl.sound_precache[sound_num], org, vol, atten); +} + + +#define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x); + +/* +===================== +CL_ParseServerMessage +===================== +*/ +void CL_ParseServerMessage (void) +{ + int cmd; + int i; + +// +// if recording demos, copy the message out +// + if (cl_shownet.value == 1) + Con_Printf ("%i ",net_message.cursize); + else if (cl_shownet.value == 2) + Con_Printf ("------------------\n"); + + cl.onground = false; // unless the server says otherwise +// +// parse the message +// + MSG_BeginReading (); + + while (1) + { + if (msg_badread) + Host_Error ("CL_ParseServerMessage: Bad server message"); + + cmd = MSG_ReadByte (); + + if (cmd == -1) + { + SHOWNET("END OF MESSAGE"); + return; // end of message + } + + // if the high bit of the command byte is set, it is a fast update + if (cmd & 128) + { + SHOWNET("fast update"); + CL_ParseUpdate (cmd&127); + continue; + } + + SHOWNET(svc_strings[cmd]); + + // other commands + switch (cmd) + { + default: + Host_Error ("CL_ParseServerMessage: Illegible server message\n"); + break; + + case svc_nop: +// Con_Printf ("svc_nop\n"); + break; + + case svc_time: + cl.mtime[1] = cl.mtime[0]; + cl.mtime[0] = MSG_ReadFloat (); + break; + + case svc_clientdata: + i = MSG_ReadShort (); + CL_ParseClientdata (i); + break; + + case svc_version: + i = MSG_ReadLong (); + if (i != PROTOCOL_VERSION) + Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION); + break; + + case svc_disconnect: + Host_EndGame ("Server disconnected\n"); + + case svc_print: + Con_Printf ("%s", MSG_ReadString ()); + break; + + case svc_centerprint: + SCR_CenterPrint (MSG_ReadString ()); + break; + + case svc_stufftext: + Cbuf_AddText (MSG_ReadString ()); + break; + + case svc_damage: + V_ParseDamage (); + break; + + case svc_serverinfo: + CL_ParseServerInfo (); + vid.recalc_refdef = true; // leave intermission full screen + break; + + case svc_setangle: + for (i=0 ; i<3 ; i++) + cl.viewangles[i] = MSG_ReadAngle (); + break; + + case svc_setview: + cl.viewentity = MSG_ReadShort (); + break; + + case svc_lightstyle: + i = MSG_ReadByte (); + if (i >= MAX_LIGHTSTYLES) + Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES"); + Q_strcpy (cl_lightstyle[i].map, MSG_ReadString()); + cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map); + break; + + case svc_sound: + CL_ParseStartSoundPacket(); + break; + + case svc_stopsound: + i = MSG_ReadShort(); + S_StopSound(i>>3, i&7); + break; + + case svc_updatename: + Sbar_Changed (); + i = MSG_ReadByte (); + if (i >= cl.maxclients) + Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD"); + strcpy (cl.scores[i].name, MSG_ReadString ()); + break; + + case svc_updatefrags: + Sbar_Changed (); + i = MSG_ReadByte (); + if (i >= cl.maxclients) + Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD"); + cl.scores[i].frags = MSG_ReadShort (); + break; + + case svc_updatecolors: + Sbar_Changed (); + i = MSG_ReadByte (); + if (i >= cl.maxclients) + Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD"); + cl.scores[i].colors = MSG_ReadByte (); + CL_NewTranslation (i); + break; + + case svc_particle: + R_ParseParticleEffect (); + break; + + case svc_spawnbaseline: + i = MSG_ReadShort (); + // must use CL_EntityNum() to force cl.num_entities up + CL_ParseBaseline (CL_EntityNum(i)); + break; + case svc_spawnstatic: + CL_ParseStatic (); + break; + case svc_temp_entity: + CL_ParseTEnt (); + break; + + case svc_setpause: + { + cl.paused = MSG_ReadByte (); + + if (cl.paused) + { + CDAudio_Pause (); +#ifdef WIN32 + VID_HandlePause (true); +#endif + } + else + { + CDAudio_Resume (); +#ifdef WIN32 + VID_HandlePause (false); +#endif + } + } + break; + + case svc_signonnum: + i = MSG_ReadByte (); + if (i <= cls.signon) + Host_Error ("Received signon %i when at %i", i, cls.signon); + cls.signon = i; + CL_SignonReply (); + break; + + case svc_killedmonster: + cl.stats[STAT_MONSTERS]++; + break; + + case svc_foundsecret: + cl.stats[STAT_SECRETS]++; + break; + + case svc_updatestat: + i = MSG_ReadByte (); + if (i < 0 || i >= MAX_CL_STATS) + Sys_Error ("svc_updatestat: %i is invalid", i); + cl.stats[i] = MSG_ReadLong ();; + break; + + case svc_spawnstaticsound: + CL_ParseStaticSound (); + break; + + case svc_cdtrack: + cl.cdtrack = MSG_ReadByte (); + cl.looptrack = MSG_ReadByte (); + + if (strcmpi(bgmtype.string,"cd") == 0) + { + if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) ) + CDAudio_Play ((byte)cls.forcetrack, true); + else + CDAudio_Play ((byte)cl.cdtrack, true); + } + else + CDAudio_Stop(); + break; + + case svc_intermission: + cl.intermission = 1; + cl.completed_time = cl.time; + vid.recalc_refdef = true; // go to full screen + break; + + case svc_finale: + cl.intermission = 2; + cl.completed_time = cl.time; + vid.recalc_refdef = true; // go to full screen + SCR_CenterPrint (MSG_ReadString ()); + break; + + case svc_cutscene: + cl.intermission = 3; + cl.completed_time = cl.time; + vid.recalc_refdef = true; // go to full screen + SCR_CenterPrint (MSG_ReadString ()); + break; + + case svc_sellscreen: + Cmd_ExecuteString ("help", src_command); + break; + + //johnfitz -- new svc types + case svc_skybox: + Sky_LoadSkyBox (MSG_ReadString()); + break; + + case svc_fog: + Fog_ParseServerMessage (); + break; + } + } +} + diff --git a/r17/Revamped src/revamped_src/cl_tent.c b/r17/Revamped src/revamped_src/cl_tent.c new file mode 100755 index 00000000..ea902a75 --- /dev/null +++ b/r17/Revamped src/revamped_src/cl_tent.c @@ -0,0 +1,411 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// cl_tent.c -- client side temporary entities + +#include "quakedef.h" + +int num_temp_entities; +entity_t cl_temp_entities[MAX_TEMP_ENTITIES]; +beam_t cl_beams[MAX_BEAMS]; + +sfx_t *cl_sfx_wizhit; +sfx_t *cl_sfx_knighthit; +sfx_t *cl_sfx_tink1; +sfx_t *cl_sfx_ric1; +sfx_t *cl_sfx_ric2; +sfx_t *cl_sfx_ric3; +sfx_t *cl_sfx_r_exp3; +#ifdef QUAKE2 +sfx_t *cl_sfx_imp; +sfx_t *cl_sfx_rail; +#endif + +/* +================= +CL_ParseTEnt +================= +*/ +void CL_InitTEnts (void) +{ + cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav"); + cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav"); + cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav"); + cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav"); + cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav"); + cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav"); + cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav"); +#ifdef QUAKE2 + cl_sfx_imp = S_PrecacheSound ("shambler/sattck1.wav"); + cl_sfx_rail = S_PrecacheSound ("weapons/lstart.wav"); +#endif +} + +/* +================= +CL_ParseBeam +================= +*/ +void CL_ParseBeam (model_t *m) +{ + int ent; + vec3_t start, end; + beam_t *b; + int i; + + ent = MSG_ReadShort (); + + start[0] = MSG_ReadCoord (); + start[1] = MSG_ReadCoord (); + start[2] = MSG_ReadCoord (); + + end[0] = MSG_ReadCoord (); + end[1] = MSG_ReadCoord (); + end[2] = MSG_ReadCoord (); + +// override any beam with the same entity + for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + if (b->entity == ent) + { + b->entity = ent; + b->model = m; + b->endtime = cl.time + 0.2; + VectorCopy (start, b->start); + VectorCopy (end, b->end); + return; + } + +// find a free beam + for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + { + if (!b->model || b->endtime < cl.time) + { + b->entity = ent; + b->model = m; + b->endtime = cl.time + 0.2; + VectorCopy (start, b->start); + VectorCopy (end, b->end); + return; + } + } + Con_Printf ("beam list overflow!\n"); +} + +/* +================= +CL_ParseTEnt +================= +*/ +void CL_ParseTEnt (void) +{ + int type; + vec3_t pos; +#ifdef QUAKE2 + vec3_t endpos; +#endif + dlight_t *dl; + int rnd; + int colorStart, colorLength; + + type = MSG_ReadByte (); + switch (type) + { + case TE_WIZSPIKE: // spike hitting wall + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_RunParticleEffect (pos, vec3_origin, 20, 30); + S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1); + break; + + case TE_KNIGHTSPIKE: // spike hitting wall + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_RunParticleEffect (pos, vec3_origin, 226, 20); + S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1); + break; + + case TE_SPIKE: // spike hitting wall + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); +#ifdef GLTEST + Test_Spawn (pos); +#else + R_RunParticleEffect (pos, vec3_origin, 0, 10); +#endif + if ( rand() % 5 ) + S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); + else + { + rnd = rand() & 3; + if (rnd == 1) + S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1); + else if (rnd == 2) + S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1); + else + S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); + } + break; + case TE_SUPERSPIKE: // super spike hitting wall + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_RunParticleEffect (pos, vec3_origin, 0, 20); + + if ( rand() % 5 ) + S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); + else + { + rnd = rand() & 3; + if (rnd == 1) + S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1); + else if (rnd == 2) + S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1); + else + S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); + } + break; + + case TE_GUNSHOT: // bullet hitting wall + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + if(!kurok) + R_RunParticleEffect (pos, vec3_origin, 0, 20); + break; + + case TE_EXPLOSION: // rocket explosion + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_ParticleExplosion (pos); + dl = CL_AllocDlight (0); + VectorCopy (pos, dl->origin); + dl->radius = 350; + dl->die = cl.time + 0.5; + dl->decay = 300; + if(kurok) + { + dl->color[0] = MSG_ReadCoord (); + dl->color[1] = MSG_ReadCoord (); + dl->color[2] = MSG_ReadCoord (); + } + S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); + break; + + case TE_TAREXPLOSION: // tarbaby explosion + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_BlobExplosion (pos); + if(kurok) + { + dl = CL_AllocDlight (0); + VectorCopy (pos, dl->origin); + dl->radius = 150; + dl->die = cl.time + 0.75; + dl->decay = 200; + dl->color[0] = MSG_ReadCoord (); + dl->color[1] = MSG_ReadCoord (); + dl->color[2] = MSG_ReadCoord (); + } + S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); + break; + + case TE_LIGHTNING1: // lightning bolts + CL_ParseBeam (Mod_ForName("progs/bolt.mdl", true)); + break; + + case TE_LIGHTNING2: // lightning bolts + CL_ParseBeam (Mod_ForName("progs/bolt2.mdl", true)); + break; + + case TE_LIGHTNING3: // lightning bolts + CL_ParseBeam (Mod_ForName("progs/bolt3.mdl", true)); + break; + +// PGM 01/21/97 + case TE_BEAM: // grappling hook beam + CL_ParseBeam (Mod_ForName("progs/beam.mdl", true)); + break; +// PGM 01/21/97 + + case TE_LAVASPLASH: + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_LavaSplash (pos); + break; + + case TE_TELEPORT: + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_TeleportSplash (pos); + break; + + case TE_EXPLOSION2: // color mapped explosion + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + colorStart = MSG_ReadByte (); + colorLength = MSG_ReadByte (); + R_ParticleExplosion2 (pos, colorStart, colorLength); + dl = CL_AllocDlight (0); + VectorCopy (pos, dl->origin); + dl->radius = 350; + dl->die = cl.time + 0.5; + dl->decay = 300; + S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); + break; + +#ifdef QUAKE2 + case TE_IMPLOSION: + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + S_StartSound (-1, 0, cl_sfx_imp, pos, 1, 1); + break; + + case TE_RAILTRAIL: + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + endpos[0] = MSG_ReadCoord (); + endpos[1] = MSG_ReadCoord (); + endpos[2] = MSG_ReadCoord (); + S_StartSound (-1, 0, cl_sfx_rail, pos, 1, 1); + S_StartSound (-1, 1, cl_sfx_r_exp3, endpos, 1, 1); + R_RocketTrail (pos, endpos, 0+128); + R_ParticleExplosion (endpos); + dl = CL_AllocDlight (-1); + VectorCopy (endpos, dl->origin); + dl->radius = 350; + dl->die = cl.time + 0.5; + dl->decay = 300; + break; +#endif + + default: + Sys_Error ("CL_ParseTEnt: bad type"); + } +} + + +/* +================= +CL_NewTempEntity +================= +*/ +entity_t *CL_NewTempEntity (void) +{ + entity_t *ent; + + if (cl_numvisedicts == MAX_VISEDICTS) + return NULL; + if (num_temp_entities == MAX_TEMP_ENTITIES) + return NULL; + ent = &cl_temp_entities[num_temp_entities]; + memset (ent, 0, sizeof(*ent)); + num_temp_entities++; + cl_visedicts[cl_numvisedicts] = ent; + cl_numvisedicts++; + + ent->colormap = vid.colormap; + return ent; +} + + +/* +================= +CL_UpdateTEnts +================= +*/ +void CL_UpdateTEnts (void) +{ + int i; + beam_t *b; + vec3_t dist, org; + float d; + entity_t *ent; + float yaw, pitch; + float forward; + + num_temp_entities = 0; + +// update lightning + for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + { + if (!b->model || b->endtime < cl.time) + continue; + + // if coming from the player, update the start position + if (b->entity == cl.viewentity) + { + VectorCopy (cl_entities[cl.viewentity].origin, b->start); + } + + // calculate pitch and yaw + VectorSubtract (b->end, b->start, dist); + + if (dist[1] == 0 && dist[0] == 0) + { + yaw = 0; + if (dist[2] > 0) + pitch = 90; + else + pitch = 270; + } + else + { + yaw = (int) (atan2f(dist[1], dist[0]) * 180 / M_PI); + if (yaw < 0) + yaw += 360; + + forward = sqrtf (dist[0]*dist[0] + dist[1]*dist[1]); + pitch = (int) (atan2f(dist[2], forward) * 180 / M_PI); + if (pitch < 0) + pitch += 360; + } + + // add new entities for the lightning + VectorCopy (b->start, org); + d = VectorNormalize(dist); + while (d > 0) + { + ent = CL_NewTempEntity (); + if (!ent) + return; + VectorCopy (org, ent->origin); + ent->model = b->model; + ent->angles[0] = pitch; + ent->angles[1] = yaw; + ent->angles[2] = rand()%360; + + for (i=0 ; i<3 ; i++) + org[i] += dist[i]*30; + d -= 30; + } + } + +} + + diff --git a/r17/Revamped src/revamped_src/client.h b/r17/Revamped src/revamped_src/client.h new file mode 100755 index 00000000..eaf2c761 --- /dev/null +++ b/r17/Revamped src/revamped_src/client.h @@ -0,0 +1,399 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// client.h + +typedef struct +{ + vec3_t viewangles; + +// intended velocities + float forwardmove; + float sidemove; + float upmove; +#ifdef QUAKE2 + byte lightlevel; +#endif +} usercmd_t; + +typedef struct +{ + int length; + char map[MAX_STYLESTRING]; +} lightstyle_t; + +typedef struct +{ + char name[MAX_SCOREBOARDNAME]; + float entertime; + int frags; + int colors; // two 4 bit fields + byte translations[VID_GRADES*256]; +} scoreboard_t; + +typedef struct +{ + int destcolor[3]; + int percent; // 0-256 +} cshift_t; + +#define CSHIFT_CONTENTS 0 +#define CSHIFT_DAMAGE 1 +#define CSHIFT_BONUS 2 +#define CSHIFT_POWERUP 3 +#define NUM_CSHIFTS 4 + +#define NAME_LENGTH 64 + + +// +// client_state_t should hold all pieces of the client state +// + +#define SIGNONS 4 // signon messages to receive before connected + +#define MAX_DLIGHTS 32 +typedef struct +{ + vec3_t origin; + float radius; + float die; // stop lighting after this time + float decay; // drop this each second + float minlight; // don't add when contributing less + int key; + vec3_t color; // LordHavoc: .lit support +#ifdef QUAKE2 + qboolean dark; // subtracts light instead of adding +#endif +} dlight_t; + + +#define MAX_BEAMS 24 +typedef struct +{ + int entity; + struct model_s *model; + float endtime; + vec3_t start, end; +} beam_t; + +#define MAX_EFRAGS 640 + +#define MAX_MAPSTRING 2048 +#define MAX_DEMOS 8 +#define MAX_DEMONAME 16 + +typedef enum { +ca_dedicated, // a dedicated server with no ability to start a client +ca_disconnected, // full screen console with no connection +ca_connected // valid netcon, talking to a server +} cactive_t; + +// +// the client_static_t structure is persistant through an arbitrary number +// of server connections +// +typedef struct +{ + cactive_t state; + +// personalization data sent to server + char mapstring[MAX_QPATH]; + char spawnparms[MAX_MAPSTRING]; // to restart a level + +// demo loop control + int demonum; // -1 = don't play demos + char demos[MAX_DEMOS][MAX_DEMONAME]; // when not playing + +// demo recording info must be here, because record is started before +// entering a map (and clearing client_state_t) + qboolean demorecording; + qboolean demoplayback; + qboolean timedemo; + int forcetrack; // -1 = use normal cd track + int demofile; + int td_lastframe; // to meter out one message a frame + int td_startframe; // host_framecount at start + float td_starttime; // realtime at second frame of timedemo + + +// connection information + int signon; // 0 to SIGNONS + struct qsocket_s *netcon; + sizebuf_t message; // writing buffer to send to server + +} client_static_t; + +extern client_static_t cls; + +// +// the client_state_t structure is wiped completely at every +// server signon +// +typedef struct +{ + int movemessages; // since connecting to this server + // throw out the first couple, so the player + // doesn't accidentally do something the + // first frame + usercmd_t cmd; // last command sent to the server + +// information for local display + int stats[MAX_CL_STATS]; // health, etc + int items; // inventory bit flags + float item_gettime[32]; // cl.time of aquiring item, for blinking + float faceanimtime; // use anim frame if cl.time < this + + cshift_t cshifts[NUM_CSHIFTS]; // color shifts for damage, powerups + cshift_t prev_cshifts[NUM_CSHIFTS]; // and content types + +// the client maintains its own idea of view angles, which are +// sent to the server each frame. The server sets punchangle when +// the view is temporarliy offset, and an angle reset commands at the start +// of each level and after teleporting. + vec3_t mviewangles[2]; // during demo playback viewangles is lerped + // between these + vec3_t viewangles; + + vec3_t mvelocity[2]; // update by server, used for lean+bob + // (0 is newest) + vec3_t velocity; // lerped between mvelocity[0] and [1] + + vec3_t punchangle; // temporary offset + +// pitch drifting vars + float idealpitch; + float pitchvel; + qboolean nodrift; + float driftmove; + double laststop; + + float viewheight; + float crouch; // local amount for smoothing stepups + + qboolean paused; // send over by server + qboolean onground; + qboolean inwater; + + int intermission; // don't change view angle, full screen, etc + int completed_time; // latched at intermission start + + double mtime[2]; // the timestamp of last two messages + double time; // clients view of time, should be between + // servertime and oldservertime to generate + // a lerp point for other data + double oldtime; // previous cl.time, time-oldtime is used + // to decay light values and smooth step ups + + + float last_received_message; // (realtime) for net trouble icon + +// +// information that is static for the entire time connected to a server +// + struct model_s *model_precache[MAX_MODELS]; + struct sfx_s *sound_precache[MAX_SOUNDS]; + + char levelname[40]; // for display on solo scoreboard + int viewentity; // cl_entitites[cl.viewentity] = player + int maxclients; + int gametype; + +// refresh related state + struct model_s *worldmodel; // cl_entitites[0].model + struct efrag_s *free_efrags; + int num_entities; // held in cl_entities array + int num_statics; // held in cl_staticentities array + entity_t viewent; // the gun model + + int cdtrack, looptrack; // cd audio + +// frag scoreboard + scoreboard_t *scores; // [cl.maxclients] + +#ifdef QUAKE2 +// light level at player's position including dlights +// this is sent back to the server each frame +// architectually ugly but it works + int light_level; +#endif +} client_state_t; + + +// +// cvars +// +extern cvar_t cl_name; +extern cvar_t cl_color; + +extern cvar_t max_fps; + +extern cvar_t cl_upspeed; +extern cvar_t cl_forwardspeed; +extern cvar_t cl_backspeed; +extern cvar_t cl_sidespeed; + +extern cvar_t cl_movespeedkey; + +extern cvar_t cl_yawspeed; +extern cvar_t cl_pitchspeed; + +extern cvar_t cl_anglespeedkey; + +extern cvar_t cl_autofire; + +extern cvar_t cl_shownet; +extern cvar_t cl_nolerp; + +extern cvar_t cl_pitchdriftspeed; +extern cvar_t lookspring; +extern cvar_t lookstrafe; +extern cvar_t lookcenter; +extern cvar_t in_sensitivity; +extern cvar_t in_tolerance; +extern cvar_t in_acceleration; + +extern cvar_t cl_autoaim; + +extern cvar_t m_pitch; +extern cvar_t m_yaw; +extern cvar_t m_forward; +extern cvar_t m_side; + +//#define MAX_TEMP_ENTITIES 128 // lightning bolts, etc +//#define MAX_STATIC_ENTITIES 128 // torches, etc +#define MAX_TEMP_ENTITIES 256 // lightning bolts, etc +#define MAX_STATIC_ENTITIES 256 // torches, etc + +extern client_state_t cl; + +// FIXME, allocate dynamically +extern efrag_t cl_efrags[MAX_EFRAGS]; +extern entity_t cl_entities[MAX_EDICTS]; +extern entity_t cl_static_entities[MAX_STATIC_ENTITIES]; +extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; +extern dlight_t cl_dlights[MAX_DLIGHTS]; +extern entity_t cl_temp_entities[MAX_TEMP_ENTITIES]; +extern beam_t cl_beams[MAX_BEAMS]; + +//============================================================================= + +// +// cl_main +// +dlight_t *CL_AllocDlight (int key); +void CL_DecayLights (void); + +void CL_Init (void); + +void CL_EstablishConnection (char *host); +void CL_Signon1 (void); +void CL_Signon2 (void); +void CL_Signon3 (void); +void CL_Signon4 (void); + +void CL_Disconnect (void); +void CL_Disconnect_f (void); +void CL_NextDemo (void); + +//#define MAX_VISEDICTS 256 +#define MAX_VISEDICTS 512 +extern int cl_numvisedicts; +extern entity_t *cl_visedicts[MAX_VISEDICTS]; + +// model indexes +typedef enum modelindex_s { + mi_player, mi_eyes, mi_rocket, mi_grenade, mi_flame0, mi_flame1, mi_flame2, + mi_explo1, mi_explo2, mi_bubble, + mi_fish, mi_dog, mi_soldier, mi_enforcer, mi_knight, mi_hknight, + mi_scrag, mi_ogre, mi_fiend, mi_vore, mi_shambler, + mi_h_dog, mi_h_soldier, mi_h_enforcer, mi_h_knight, mi_h_hknight, mi_h_scrag, + mi_h_ogre, mi_h_fiend, mi_h_vore, mi_h_shambler, mi_h_zombie, mi_h_player, + mi_gib1, mi_gib2, mi_gib3, NUM_MODELINDEX +} modelindex_t; + +extern modelindex_t cl_modelindex[NUM_MODELINDEX]; +extern char *cl_modelnames[NUM_MODELINDEX]; + +// +// cl_input +// +typedef struct +{ + int down[2]; // key nums holding it down + int state; // low bit is down state +} kbutton_t; + +extern kbutton_t in_mlook, in_klook; +extern kbutton_t in_strafe; +extern kbutton_t in_speed; + +void CL_InitInput (void); +void CL_SendCmd (void); +void CL_SendMove (usercmd_t *cmd); + +void CL_ParseTEnt (void); +void CL_UpdateTEnts (void); + +void CL_ClearState (void); + + +int CL_ReadFromServer (void); +void CL_WriteToServer (usercmd_t *cmd); +void CL_BaseMove (usercmd_t *cmd); + + +float CL_KeyState (kbutton_t *key); +char *Key_KeynumToString (int keynum); + +// +// cl_demo.c +// +void CL_StopPlayback (void); +int CL_GetMessage (void); + +void CL_Stop_f (void); +void CL_Record_f (void); +void CL_PlayDemo_f (void); +void CL_TimeDemo_f (void); + +// +// cl_parse.c +// +void CL_ParseServerMessage (void); +void CL_NewTranslation (int slot); + +// +// view +// +void V_StartPitchDrift (void); +void V_StopPitchDrift (void); + +void V_RenderView (void); +void V_UpdatePalette (void); +void V_Register (void); +void V_ParseDamage (void); +void V_SetContentsColor (int contents); + + +// +// cl_tent +// +void CL_InitTEnts (void); +void CL_SignonReply (void); diff --git a/r17/Revamped src/revamped_src/cmd.c b/r17/Revamped src/revamped_src/cmd.c new file mode 100755 index 00000000..db489241 --- /dev/null +++ b/r17/Revamped src/revamped_src/cmd.c @@ -0,0 +1,705 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// cmd.c -- Quake script command processing module + +#include "quakedef.h" + +void Cmd_ForwardToServer (void); + +#define MAX_ALIAS_NAME 32 + +typedef struct cmdalias_s +{ + struct cmdalias_s *next; + char name[MAX_ALIAS_NAME]; + char *value; +} cmdalias_t; + +cmdalias_t *cmd_alias; + +int trashtest; +int *trashspot; + +qboolean cmd_wait; + +//============================================================================= + +/* +============ +Cmd_Wait_f + +Causes execution of the remainder of the command buffer to be delayed until +next frame. This allows commands like: +bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2" +============ +*/ +void Cmd_Wait_f (void) +{ + cmd_wait = true; +} + +/* +============================================================================= + + COMMAND BUFFER + +============================================================================= +*/ + +sizebuf_t cmd_text; + +/* +============ +Cbuf_Init +============ +*/ +void Cbuf_Init (void) +{ + SZ_Alloc (&cmd_text, 8192); // space for commands and script files +} + + +/* +============ +Cbuf_AddText + +Adds command text at the end of the buffer +============ +*/ +void Cbuf_AddText (char *text) +{ + int l; + + l = Q_strlen (text); + + if (cmd_text.cursize + l >= cmd_text.maxsize) + { + Con_Printf ("Cbuf_AddText: overflow\n"); + return; + } + + SZ_Write (&cmd_text, text, Q_strlen (text)); +} + + +/* +============ +Cbuf_InsertText + +Adds command text immediately after the current command +Adds a \n to the text +FIXME: actually change the command buffer to do less copying +============ +*/ +void Cbuf_InsertText (char *text) +{ + char *temp; + int templen; + +// copy off any commands still remaining in the exec buffer + templen = cmd_text.cursize; + if (templen) + { + temp = Z_Malloc (templen); + Q_memcpy (temp, cmd_text.data, templen); + SZ_Clear (&cmd_text); + } + else + temp = NULL; // shut up compiler + +// add the entire text of the file + Cbuf_AddText (text); + +// add the copied off data + if (templen) + { + SZ_Write (&cmd_text, temp, templen); + Z_Free (temp); + } +} + +/* +============ +Cbuf_Execute +============ +*/ +void Cbuf_Execute (void) +{ + int i; + char *text; + char line[1024]; + int quotes; + + while (cmd_text.cursize) + { +// find a \n or ; line break + text = (char *)cmd_text.data; + + quotes = 0; + for (i=0 ; i< cmd_text.cursize ; i++) + { + if (text[i] == '"') + quotes++; + if ( !(quotes&1) && text[i] == ';') + break; // don't break if inside a quoted string + if (text[i] == '\n') + break; + } + + + memcpy (line, text, i); + line[i] = 0; + +// delete the text from the command buffer and move remaining commands down +// this is necessary because commands (exec, alias) can insert data at the +// beginning of the text buffer + + if (i == cmd_text.cursize) + cmd_text.cursize = 0; + else + { + i++; + cmd_text.cursize -= i; + Q_memcpy (text, text+i, cmd_text.cursize); + } + +// execute the command line + Cmd_ExecuteString (line, src_command); + + if (cmd_wait) + { // skip out while text still remains in buffer, leaving it + // for next frame + cmd_wait = false; + break; + } + } +} + +/* +============================================================================== + + SCRIPT COMMANDS + +============================================================================== +*/ + +/* +=============== +Cmd_StuffCmds_f + +Adds command line parameters as script statements +Commands lead with a +, and continue until a - or another + +quake +prog jctest.qp +cmd amlev1 +quake -nosound +cmd amlev1 +=============== +*/ +void Cmd_StuffCmds_f (void) +{ + int i, j; + int s; + char *text, *build, c; + + if (Cmd_Argc () != 1) + { + Con_Printf ("stuffcmds : execute command line parameters\n"); + return; + } + +// build the combined string to parse from + s = 0; + for (i=1 ; i : execute a script file\n"); + return; + } + + mark = Hunk_LowMark (); + f = (char *)COM_LoadHunkFile (Cmd_Argv(1)); + if (!f) + { + Con_Printf ("couldn't exec %s\n",Cmd_Argv(1)); + return; + } + Con_Printf ("execing %s\n",Cmd_Argv(1)); + + Cbuf_InsertText (f); + Hunk_FreeToLowMark (mark); +} + + +/* +=============== +Cmd_Echo_f + +Just prints the rest of the line to the console +=============== +*/ +void Cmd_Echo_f (void) +{ + int i; + + for (i=1 ; inext) + Con_Printf ("%s : %s\n", a->name, a->value); + return; + } + + s = Cmd_Argv(1); + if (strlen(s) >= MAX_ALIAS_NAME) + { + Con_Printf ("Alias name is too long\n"); + return; + } + + // if the alias allready exists, reuse it + for (a = cmd_alias ; a ; a=a->next) + { + if (!strcmp(s, a->name)) + { + Z_Free (a->value); + break; + } + } + + if (!a) + { + a = Z_Malloc (sizeof(cmdalias_t)); + a->next = cmd_alias; + cmd_alias = a; + } + strcpy (a->name, s); + +// copy the rest of the command line + cmd[0] = 0; // start out with a null string + c = Cmd_Argc(); + for (i=2 ; i< c ; i++) + { + strcat (cmd, Cmd_Argv(i)); + if (i != c) + strcat (cmd, " "); + } + strcat (cmd, "\n"); + + a->value = CopyString (cmd); +} + +/* +============================================================================= + + COMMAND EXECUTION + +============================================================================= +*/ + +typedef struct cmd_function_s +{ + struct cmd_function_s *next; + char *name; + xcommand_t function; +} cmd_function_t; + + +#define MAX_ARGS 80 + +static int cmd_argc; +static char *cmd_argv[MAX_ARGS]; +static char *cmd_null_string = ""; +static char *cmd_args = NULL; + +cmd_source_t cmd_source; + + +static cmd_function_t *cmd_functions; // possible commands to execute + +/* +============ +Cmd_Init +============ +*/ +void Cmd_Init (void) +{ +// +// register our commands +// + Cmd_AddCommand ("stuffcmds",Cmd_StuffCmds_f); + Cmd_AddCommand ("exec",Cmd_Exec_f); + Cmd_AddCommand ("echo",Cmd_Echo_f); + Cmd_AddCommand ("alias",Cmd_Alias_f); + Cmd_AddCommand ("cmd", Cmd_ForwardToServer); + Cmd_AddCommand ("wait", Cmd_Wait_f); +} + +/* +============ +Cmd_Argc +============ +*/ +int Cmd_Argc (void) +{ + return cmd_argc; +} + +/* +============ +Cmd_Argv +============ +*/ +char *Cmd_Argv (int arg) +{ + if ( (unsigned)arg >= cmd_argc ) + return cmd_null_string; + return cmd_argv[arg]; +} + +/* +============ +Cmd_Args +============ +*/ +char *Cmd_Args (void) +{ + return cmd_args; +} + + +/* +============ +Cmd_TokenizeString + +Parses the given string into command line tokens. +============ +*/ +void Cmd_TokenizeString (char *text) +{ + int i; + +// clear the args from the last string + for (i=0 ; inext) + { + if (!Q_strcmp (cmd_name, cmd->name)) + { + Con_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name); + return; + } + } + + cmd = Hunk_Alloc (sizeof(cmd_function_t)); + cmd->name = cmd_name; + cmd->function = function; + cmd->next = cmd_functions; + cmd_functions = cmd; +} + +/* +============ +Cmd_Exists +============ +*/ +qboolean Cmd_Exists (char *cmd_name) +{ + cmd_function_t *cmd; + + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) + { + if (!Q_strcmp (cmd_name,cmd->name)) + return true; + } + + return false; +} + + + +/* +============ +Cmd_CompleteCommand +============ +*/ +char *Cmd_CompleteCommand (char *partial) +{ + cmd_function_t *cmd; + int len; + + len = Q_strlen(partial); + + if (!len) + return NULL; + +// check functions + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) + if (!Q_strncmp (partial,cmd->name, len)) + return cmd->name; + + return NULL; +} + +/* +============ +Cmd_ExecuteString + +A complete command line has been parsed, so try to execute it +FIXME: lookupnoadd the token to speed search? +============ +*/ +void Cmd_ExecuteString (char *text, cmd_source_t src) +{ + cmd_function_t *cmd; + cmdalias_t *a; + + cmd_source = src; + Cmd_TokenizeString (text); + +// execute the command line + if (!Cmd_Argc()) + return; // no tokens + +// check functions + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) + { + if (!Q_strcasecmp (cmd_argv[0],cmd->name)) + { + cmd->function (); + return; + } + } + +// check alias + for (a=cmd_alias ; a ; a=a->next) + { + if (!Q_strcasecmp (cmd_argv[0], a->name)) + { + Cbuf_InsertText (a->value); + return; + } + } + +// check cvars + if (!Cvar_Command ()) + Con_Printf ("Unknown command \"%s\"\n", Cmd_Argv(0)); + +} + + +/* +=================== +Cmd_ForwardToServer + +Sends the entire command line over to the server +=================== +*/ +void Cmd_ForwardToServer (void) +{ + if (cls.state != ca_connected) + { + Con_Printf ("Can't \"%s\", not connected\n", Cmd_Argv(0)); + return; + } + + if (cls.demoplayback) + return; // not really connected + + MSG_WriteByte (&cls.message, clc_stringcmd); + if (Q_strcasecmp(Cmd_Argv(0), "cmd") != 0) + { + SZ_Print (&cls.message, Cmd_Argv(0)); + SZ_Print (&cls.message, " "); + } + if (Cmd_Argc() > 1) + SZ_Print (&cls.message, Cmd_Args()); + else + SZ_Print (&cls.message, "\n"); +} + + +/* +================ +Cmd_CheckParm + +Returns the position (1 to argc-1) in the command's argument list +where the given parameter apears, or 0 if not present +================ +*/ + +int Cmd_CheckParm (char *parm) +{ + int i; + + if (!parm) + Sys_Error ("Cmd_CheckParm: NULL"); + + for (i = 1; i < Cmd_Argc (); i++) + if (! Q_strcasecmp (parm, Cmd_Argv (i))) + return i; + + return 0; +} diff --git a/r17/Revamped src/revamped_src/cmd.h b/r17/Revamped src/revamped_src/cmd.h new file mode 100755 index 00000000..b2e9993c --- /dev/null +++ b/r17/Revamped src/revamped_src/cmd.h @@ -0,0 +1,121 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +// cmd.h -- Command buffer and command execution + +//=========================================================================== + +/* + +Any number of commands can be added in a frame, from several different sources. +Most commands come from either keybindings or console line input, but remote +servers can also send across commands and entire text files can be execed. + +The + command line options are also added to the command buffer. + +The game starts with a Cbuf_AddText ("exec quake.rc\n"); Cbuf_Execute (); + +*/ + + +void Cbuf_Init (void); +// allocates an initial text buffer that will grow as needed + +void Cbuf_AddText (char *text); +// as new commands are generated from the console or keybindings, +// the text is added to the end of the command buffer. + +void Cbuf_InsertText (char *text); +// when a command wants to issue other commands immediately, the text is +// inserted at the beginning of the buffer, before any remaining unexecuted +// commands. + +void Cbuf_Execute (void); +// Pulls off \n terminated lines of text from the command buffer and sends +// them through Cmd_ExecuteString. Stops when the buffer is empty. +// Normally called once per frame, but may be explicitly invoked. +// Do not call inside a command function! + +//=========================================================================== + +/* + +Command execution takes a null terminated string, breaks it into tokens, +then searches for a command or variable that matches the first token. + +Commands can come from three sources, but the handler functions may choose +to dissallow the action or forward it to a remote server if the source is +not apropriate. + +*/ + +typedef void (*xcommand_t) (void); + +typedef enum +{ + src_client, // came in over a net connection as a clc_stringcmd + // host_client will be valid during this state. + src_command // from the command buffer +} cmd_source_t; + +extern cmd_source_t cmd_source; + +void Cmd_Init (void); + +void Cmd_AddCommand (char *cmd_name, xcommand_t function); +// called by the init functions of other parts of the program to +// register commands and functions to call for them. +// The cmd_name is referenced later, so it should not be in temp memory + +qboolean Cmd_Exists (char *cmd_name); +// used by the cvar code to check for cvar / command name overlap + +char *Cmd_CompleteCommand (char *partial); +// attempts to match a partial command for automatic command line completion +// returns NULL if nothing fits + +int Cmd_Argc (void); +char *Cmd_Argv (int arg); +char *Cmd_Args (void); +// The functions that execute commands get their parameters with these +// functions. Cmd_Argv () will return an empty string, not a NULL +// if arg > argc, so string operations are allways safe. + +int Cmd_CheckParm (char *parm); +// Returns the position (1 to argc-1) in the command's argument list +// where the given parameter apears, or 0 if not present + +void Cmd_TokenizeString (char *text); +// Takes a null terminated string. Does not need to be /n terminated. +// breaks the string up into arg tokens. + +void Cmd_ExecuteString (char *text, cmd_source_t src); +// Parses a single line of text into arguments and tries to execute it. +// The text can come from the command buffer, a remote client, or stdin. + +void Cmd_ForwardToServer (void); +// adds the current command line as a clc_stringcmd to the client message. +// things like godmode, noclip, etc, are commands directed to the server, +// so when they are typed in at the console, they will need to be forwarded. + +void Cmd_Print (char *text); +// used by command functions to send output to either the graphics console or +// passed as a print message to the client + diff --git a/r17/Revamped src/revamped_src/common.c b/r17/Revamped src/revamped_src/common.c new file mode 100755 index 00000000..3aadb840 --- /dev/null +++ b/r17/Revamped src/revamped_src/common.c @@ -0,0 +1,1870 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// common.c -- misc functions used in client and server + +#include "quakedef.h" + +#define NUM_SAFE_ARGVS 7 + +static char *largv[MAX_NUM_ARGVS + NUM_SAFE_ARGVS + 1]; +static char *argvdummy = " "; + +static char *safeargvs[NUM_SAFE_ARGVS] = + {"-stdvid", "-nolan", "-nosound", "-nocdaudio", "-nojoy", "-nomouse", "-dibonly"}; + +cvar_t registered = {"registered","0"}; +cvar_t cmdline = {"cmdline","0", false, true}; + +qboolean com_modified; // set true if using non-id files + +qboolean proghack; + +int static_registered = 1; // only for startup check, then set + +qboolean msg_suppress_1 = 0; + +void COM_InitFilesystem (void); + +// if a packfile directory differs from this, it is assumed to be hacked +#define PAK0_COUNT 339 +#define PAK0_CRC 32981 + +char com_token[1024]; +int com_argc; +char **com_argv; + +#define CMDLINE_LENGTH 256 +char com_cmdline[CMDLINE_LENGTH]; + +qboolean standard_quake = true, rogue, hipnotic, kurok; + +// this graphic needs to be in the pak file to use registered features +unsigned short pop[] = +{ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 +,0x0000,0x0000,0x6600,0x0000,0x0000,0x0000,0x6600,0x0000 +,0x0000,0x0066,0x0000,0x0000,0x0000,0x0000,0x0067,0x0000 +,0x0000,0x6665,0x0000,0x0000,0x0000,0x0000,0x0065,0x6600 +,0x0063,0x6561,0x0000,0x0000,0x0000,0x0000,0x0061,0x6563 +,0x0064,0x6561,0x0000,0x0000,0x0000,0x0000,0x0061,0x6564 +,0x0064,0x6564,0x0000,0x6469,0x6969,0x6400,0x0064,0x6564 +,0x0063,0x6568,0x6200,0x0064,0x6864,0x0000,0x6268,0x6563 +,0x0000,0x6567,0x6963,0x0064,0x6764,0x0063,0x6967,0x6500 +,0x0000,0x6266,0x6769,0x6a68,0x6768,0x6a69,0x6766,0x6200 +,0x0000,0x0062,0x6566,0x6666,0x6666,0x6666,0x6562,0x0000 +,0x0000,0x0000,0x0062,0x6364,0x6664,0x6362,0x0000,0x0000 +,0x0000,0x0000,0x0000,0x0062,0x6662,0x0000,0x0000,0x0000 +,0x0000,0x0000,0x0000,0x0061,0x6661,0x0000,0x0000,0x0000 +,0x0000,0x0000,0x0000,0x0000,0x6500,0x0000,0x0000,0x0000 +,0x0000,0x0000,0x0000,0x0000,0x6400,0x0000,0x0000,0x0000 +}; + +/* + + +All of Quake's data access is through a hierchal file system, but the contents of the file system can be transparently merged from several sources. + +The "base directory" is the path to the directory holding the quake.exe and all game directories. The sys_* files pass this to host_init in quakeparms_t->basedir. This can be overridden with the "-basedir" command line parm to allow code debugging in a different directory. The base directory is +only used during filesystem initialization. + +The "game directory" is the first tree on the search path and directory that all generated files (savegames, screenshots, demos, config files) will be saved to. This can be overridden with the "-game" command line parameter. The game directory can never be changed while quake is executing. This is a precacution against having a malicious server instruct clients to write files over areas they shouldn't. + +The "cache directory" is only used during development to save network bandwidth, especially over ISDN / T1 lines. If there is a cache directory +specified, when a file is found by the normal search path, it will be mirrored +into the cache directory, then opened there. + + + +FIXME: +The file "parms.txt" will be read out of the game directory and appended to the current command line arguments to allow different games to initialize startup parms differently. This could be used to add a "-sspeed 22050" for the high quality sound edition. Because they are added at the end, they will not override an explicit setting on the original command line. + +*/ + +//============================================================================ + + +// ClearLink is used for new headnodes +void ClearLink (link_t *l) +{ + l->prev = l->next = l; +} + +void RemoveLink (link_t *l) +{ + l->next->prev = l->prev; + l->prev->next = l->next; +} + +void InsertLinkBefore (link_t *l, link_t *before) +{ + l->next = before; + l->prev = before->prev; + l->prev->next = l; + l->next->prev = l; +} +void InsertLinkAfter (link_t *l, link_t *after) +{ + l->next = after->next; + l->prev = after; + l->prev->next = l; + l->next->prev = l; +} + +/* +============================================================================ + + LIBRARY REPLACEMENT FUNCTIONS + +============================================================================ +*/ + +void Q_memset (void *dest, int fill, int count) +{ + int i; + + if ( (((long)dest | count) & 3) == 0) + { + count >>= 2; + fill = fill | (fill<<8) | (fill<<16) | (fill<<24); + for (i=0 ; i>=2; + for (i=0 ; i= 'a' && c1 <= 'z') + c1 -= ('a' - 'A'); + if (c2 >= 'a' && c2 <= 'z') + c2 -= ('a' - 'A'); + if (c1 != c2) + return -1; // strings not equal + } + if (!c1) + return 0; // strings are equal +// s1++; +// s2++; + } + + return -1; +} + +int Q_strcasecmp (char *s1, char *s2) +{ + return Q_strncasecmp (s1, s2, 99999); +} + +int Q_atoi (char *str) +{ + int val; + int sign; + int c; + + if (*str == '-') + { + sign = -1; + str++; + } + else + sign = 1; + + val = 0; + +// +// check for hex +// + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) + { + str += 2; + while (1) + { + c = *str++; + if (c >= '0' && c <= '9') + val = (val<<4) + c - '0'; + else if (c >= 'a' && c <= 'f') + val = (val<<4) + c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + val = (val<<4) + c - 'A' + 10; + else + return val*sign; + } + } + +// +// check for character +// + if (str[0] == '\'') + { + return sign * str[1]; + } + +// +// assume decimal +// + while (1) + { + c = *str++; + if (c <'0' || c > '9') + return val*sign; + val = val*10 + c - '0'; + } + + return 0; +} + + +float Q_atof (char *str) +{ + float val; + int sign; + int c; + int decimal, total; + + if (*str == '-') + { + sign = -1; + str++; + } + else + sign = 1; + + val = 0; + +// +// check for hex +// + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) + { + str += 2; + while (1) + { + c = *str++; + if (c >= '0' && c <= '9') + val = (val*16) + c - '0'; + else if (c >= 'a' && c <= 'f') + val = (val*16) + c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + val = (val*16) + c - 'A' + 10; + else + return val*sign; + } + } + +// +// check for character +// + if (str[0] == '\'') + { + return sign * str[1]; + } + +// +// assume decimal +// + decimal = -1; + total = 0; + while (1) + { + c = *str++; + if (c == '.') + { + decimal = total; + continue; + } + if (c <'0' || c > '9') + break; + val = val*10 + c - '0'; + total++; + } + + if (decimal == -1) + return val*sign; + while (total > decimal) + { + val /= 10; + total--; + } + + return val*sign; +} + +/* +============================================================================ + + BYTE ORDER FUNCTIONS + +============================================================================ +*/ + +qboolean bigendien; + +short (*BigShort) (short l); +short (*LittleShort) (short l); +int (*BigLong) (int l); +int (*LittleLong) (int l); +float (*BigFloat) (float l); +float (*LittleFloat) (float l); + +short ShortSwap (short l) +{ + byte b1,b2; + + b1 = l&255; + b2 = (l>>8)&255; + + return (b1<<8) + b2; +} + +short ShortNoSwap (short l) +{ + return l; +} + +int LongSwap (int l) +{ + byte b1,b2,b3,b4; + + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; + + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; +} + +int LongNoSwap (int l) +{ + return l; +} + +float FloatSwap (float f) +{ + union + { + float f; + byte b[4]; + } dat1, dat2; + + + dat1.f = f; + dat2.b[0] = dat1.b[3]; + dat2.b[1] = dat1.b[2]; + dat2.b[2] = dat1.b[1]; + dat2.b[3] = dat1.b[0]; + return dat2.f; +} + +float FloatNoSwap (float f) +{ + return f; +} + +/* +============================================================================== + + MESSAGE IO FUNCTIONS + +Handles byte ordering and avoids alignment errors +============================================================================== +*/ + +// +// writing functions +// + +void MSG_WriteChar (sizebuf_t *sb, int c) +{ + byte *buf; + +#ifdef PARANOID + if (c < -128 || c > 127) + Sys_Error ("MSG_WriteChar: range error"); +#endif + + buf = SZ_GetSpace (sb, 1); + buf[0] = c; +} + +void MSG_WriteByte (sizebuf_t *sb, int c) +{ + byte *buf; + +#ifdef PARANOID + if (c < 0 || c > 255) + Sys_Error ("MSG_WriteByte: range error"); +#endif + + buf = SZ_GetSpace (sb, 1); + buf[0] = c; +} + +void MSG_WriteShort (sizebuf_t *sb, int c) +{ + byte *buf; + +#ifdef PARANOID + if (c < ((short)0x8000) || c > (short)0x7fff) + Sys_Error ("MSG_WriteShort: range error"); +#endif + + buf = SZ_GetSpace (sb, 2); + buf[0] = c&0xff; + buf[1] = c>>8; +} + +void MSG_WriteLong (sizebuf_t *sb, int c) +{ + byte *buf; + + buf = SZ_GetSpace (sb, 4); + buf[0] = c&0xff; + buf[1] = (c>>8)&0xff; + buf[2] = (c>>16)&0xff; + buf[3] = c>>24; +} + +void MSG_WriteFloat (sizebuf_t *sb, float f) +{ + union + { + float f; + int l; + } dat; + + + dat.f = f; + dat.l = LittleLong (dat.l); + + SZ_Write (sb, &dat.l, 4); +} + +void MSG_WriteString (sizebuf_t *sb, char *s) +{ + if (!s) + SZ_Write (sb, "", 1); + else + SZ_Write (sb, s, Q_strlen(s)+1); +} + +void MSG_WriteCoord (sizebuf_t *sb, float f) +{ + MSG_WriteShort (sb, (int)(f*8)); +} + +void MSG_WriteAngle (sizebuf_t *sb, float f) +{ + MSG_WriteByte (sb, ((int)f*256/360) & 255); +} + +// JPG - precise aim for ProQuake! +void MSG_WritePreciseAngle (sizebuf_t *sb, float f) +{ + if (f >= 0) + MSG_WriteShort (sb, (int)(f*(65536.0/360.0) + 0.5) & 65535); + else + MSG_WriteShort (sb, (int)(f*(65536.0/360.0) - 0.5) & 65535); +// int val = (int)f*65536/360; +// MSG_WriteShort (sb, val & 65535); +} + +// +// reading functions +// +int msg_readcount; +qboolean msg_badread; + +void MSG_BeginReading (void) +{ + msg_readcount = 0; + msg_badread = false; +} + +// returns -1 and sets msg_badread if no more characters are available +int MSG_ReadChar (void) +{ + int c; + + if (msg_readcount+1 > net_message.cursize) + { + msg_badread = true; + return -1; + } + + c = (signed char)net_message.data[msg_readcount]; + msg_readcount++; + + return c; +} + +int MSG_ReadByte (void) +{ + int c; + + if (msg_readcount+1 > net_message.cursize) + { + msg_badread = true; + return -1; + } + + c = (unsigned char)net_message.data[msg_readcount]; + msg_readcount++; + + return c; +} + +int MSG_ReadShort (void) +{ + int c; + + if (msg_readcount+2 > net_message.cursize) + { + msg_badread = true; + return -1; + } + + c = (short)(net_message.data[msg_readcount] + + (net_message.data[msg_readcount+1]<<8)); + + msg_readcount += 2; + + return c; +} + +int MSG_ReadLong (void) +{ + int c; + + if (msg_readcount+4 > net_message.cursize) + { + msg_badread = true; + return -1; + } + + c = net_message.data[msg_readcount] + + (net_message.data[msg_readcount+1]<<8) + + (net_message.data[msg_readcount+2]<<16) + + (net_message.data[msg_readcount+3]<<24); + + msg_readcount += 4; + + return c; +} + +float MSG_ReadFloat (void) +{ + union + { + byte b[4]; + float f; + int l; + } dat; + + dat.b[0] = net_message.data[msg_readcount]; + dat.b[1] = net_message.data[msg_readcount+1]; + dat.b[2] = net_message.data[msg_readcount+2]; + dat.b[3] = net_message.data[msg_readcount+3]; + msg_readcount += 4; + + dat.l = LittleLong (dat.l); + + return dat.f; +} + +char *MSG_ReadString (void) +{ + static char string[2048]; + int l,c; + + l = 0; + do + { + c = MSG_ReadChar (); + if (c == -1 || c == 0) + break; + string[l] = c; + l++; + } while (l < sizeof(string)-1); + + string[l] = 0; + + return string; +} + +float MSG_ReadCoord (void) +{ + return MSG_ReadShort() * (1.0/8); +} + +float MSG_ReadAngle (void) +{ + return MSG_ReadChar() * (360.0/256); +} + +// JPG - exact aim for proquake! +float MSG_ReadPreciseAngle (void) +{ + return (signed short)MSG_ReadShort () * (360.0/65536.0); +// int val = MSG_ReadShort(); +// return val * (360.0/65536); +} + +//=========================================================================== + +void SZ_Alloc (sizebuf_t *buf, int startsize) +{ + if (startsize < 256) + startsize = 256; + buf->data = Hunk_AllocName (startsize, "sizebuf"); + buf->maxsize = startsize; + buf->cursize = 0; +} + + +void SZ_Free (sizebuf_t *buf) +{ +// Z_Free (buf->data); +// buf->data = NULL; +// buf->maxsize = 0; + buf->cursize = 0; +} + +void SZ_Clear (sizebuf_t *buf) +{ + buf->cursize = 0; +} + +void *SZ_GetSpace (sizebuf_t *buf, int length) +{ + void *data; + + if (buf->cursize + length > buf->maxsize) + { + if (!buf->allowoverflow) + Sys_Error ("SZ_GetSpace: overflow without allowoverflow set"); + + if (length > buf->maxsize) + Sys_Error ("SZ_GetSpace: %i is > full buffer size", length); + + buf->overflowed = true; + Con_Printf ("SZ_GetSpace: overflow"); + SZ_Clear (buf); + } + + data = buf->data + buf->cursize; + buf->cursize += length; + + return data; +} + +void SZ_Write (sizebuf_t *buf, void *data, int length) +{ + Q_memcpy (SZ_GetSpace(buf,length),data,length); +} + +void SZ_Print (sizebuf_t *buf, char *data) +{ + int len; + + len = Q_strlen(data)+1; + +// byte * cast to keep VC++ happy + if (buf->data[buf->cursize-1]) + Q_memcpy ((byte *)SZ_GetSpace(buf, len),data,len); // no trailing 0 + else + Q_memcpy ((byte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0 +} + + +//============================================================================ + + +/* +============ +COM_SkipPath +============ +*/ +char *COM_SkipPath (char *pathname) +{ + char *last; + + last = pathname; + while (*pathname) + { + if (*pathname=='/') + last = pathname+1; + pathname++; + } + return last; +} + +/* +============ +COM_StripExtension +============ +*/ +void COM_StripExtension (char *in, char *out) +{ + while (*in && *in != '.') + *out++ = *in++; + *out = 0; +} + +/* +============ +COM_FileExtension +============ +*/ +char *COM_FileExtension (char *in) +{ + static char exten[8]; + int i; + + while (*in && *in != '.') + in++; + if (!*in) + return ""; + in++; + for (i=0 ; i<7 && *in ; i++,in++) + exten[i] = *in; + exten[i] = 0; + return exten; +} + +/* +============ +COM_FileBase +============ +*/ +void COM_FileBase (char *in, char *out) +{ + char *s, *s2; + + s = in + strlen(in) - 1; + + while (s != in && *s != '.') + s--; + + for (s2 = s ; *s2 && *s2 != '/' ; s2--) + ; + + if (s-s2 < 2) + strcpy (out,"?model?"); + else + { + s--; + strncpy (out,s2+1, s-s2); + out[s-s2] = 0; + } +} + + +/* +================== +COM_DefaultExtension +================== +*/ +void COM_DefaultExtension (char *path, char *extension) +{ + char *src; +// +// if path doesn't have a .EXT, append extension +// (extension should include the .) +// + src = path + strlen(path) - 1; + + while (*src != '/' && src != path) + { + if (*src == '.') + return; // it has an extension + src--; + } + + strcat (path, extension); +} + + +/* +============== +COM_Parse + +Parse a token out of a string +============== +*/ +char *COM_Parse (char *data) +{ + int c; + int len; + + len = 0; + com_token[0] = 0; + + if (!data) + return NULL; + +// skip whitespace +skipwhite: + while ( (c = *data) <= ' ') + { + if (c == 0) + return NULL; // end of file; + data++; + } + +// skip // comments + if (c=='/' && data[1] == '/') + { + while (*data && *data != '\n') + data++; + goto skipwhite; + } + + +// handle quoted strings specially + if (c == '\"') + { + data++; + while (1) + { + c = *data++; + if (c=='\"' || !c) + { + com_token[len] = 0; + return data; + } + com_token[len] = c; + len++; + } + } + +// parse single characters + if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':') + { + com_token[len] = c; + len++; + com_token[len] = 0; + return data+1; + } + +// parse a regular word + do + { + com_token[len] = c; + data++; + len++; + c = *data; + if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':') + break; + } while (c>32); + + com_token[len] = 0; + return data; +} + + +/* +================ +COM_CheckParm + +Returns the position (1 to argc-1) in the program's argument list +where the given parameter apears, or 0 if not present +================ +*/ +int COM_CheckParm (char *parm) +{ + int i; + + for (i=1 ; inext) + { + if (s->pack) + { + Con_Printf ("%s (%i files)\n", s->pack->filename, s->pack->numfiles); + } + else + Con_Printf ("%s\n", s->filename); + } +} + +/* +============ +COM_WriteFile + +The filename will be prefixed by the current game directory +============ +*/ +void COM_WriteFile (char *filename, void *data, int len) +{ + int handle; + char name[MAX_OSPATH]; + + sprintf (name, "%s/%s", com_gamedir, filename); + + handle = Sys_FileOpenWrite (name); + if (handle == -1) + { + Sys_Printf ("COM_WriteFile: failed on %s\n", name); + return; + } + + Sys_Printf ("COM_WriteFile: %s\n", name); + Sys_FileWrite (handle, data, len); + Sys_FileClose (handle); +} + + +/* +============ +COM_CreatePath + +Only used for CopyFile +============ +*/ +void COM_CreatePath (char *path) +{ + char *ofs; + + for (ofs = path+1 ; *ofs ; ofs++) + { + if (*ofs == '/') + { // create the directory + *ofs = 0; + Sys_mkdir (path); + *ofs = '/'; + } + } +} + + +/* +=========== +COM_CopyFile + +Copies a file over from the net to the local cache, creating any directories +needed. This is for the convenience of developers using ISDN from home. +=========== +*/ +void COM_CopyFile (char *netpath, char *cachepath) +{ + int in, out; + int remaining, count; + char buf[4096]; + + remaining = Sys_FileOpenRead (netpath, &in); + COM_CreatePath (cachepath); // create directories up to the cache file + out = Sys_FileOpenWrite (cachepath); + + while (remaining) + { + if (remaining < sizeof(buf)) + count = remaining; + else + count = sizeof(buf); + Sys_FileRead (in, buf, count); + Sys_FileWrite (out, buf, count); + remaining -= count; + } + + Sys_FileClose (in); + Sys_FileClose (out); +} + +/* +=========== +COM_FindFile + +Finds the file in the search path. +Sets com_filesize and one of handle or file +=========== +*/ +int COM_FindFile (char *filename, int *handle, int *file) +{ + searchpath_t *search; + char netpath[MAX_OSPATH]; + char cachepath[MAX_OSPATH]; + pack_t *pak; + int i; + int findtime, cachetime; + + if (file && handle) + Sys_Error ("COM_FindFile: both handle and file set"); + if (!file && !handle) + Sys_Error ("COM_FindFile: neither handle or file set"); + +// +// search through the path, one element at a time +// + search = com_searchpaths; + if (proghack) + { // gross hack to use quake 1 progs with quake 2 maps + if (!strcmp(filename, "progs.dat")) + search = search->next; + } + + for ( ; search ; search = search->next) + { + // is the element a pak file? + if (search->pack) + { + // look through all the pak file elements + pak = search->pack; + for (i=0 ; inumfiles ; i++) + if (!strcmp (pak->files[i].name, filename)) + { // found it! + Sys_Printf ("PackFile: %s : %s\n",pak->filename, filename); + if (handle) + { + *handle = pak->handle; + Sys_FileSeek (pak->handle, pak->files[i].filepos); + } + else + { // open a new file on the pakfile + Sys_FileOpenRead(pak->filename, file); + if ((*file) >= 0) + Sys_FileSeek(*file, pak->files[i].filepos); + } + com_filesize = pak->files[i].filelen; + return com_filesize; + } + } + else + { + // check a file in the directory tree + if (!static_registered) + { // if not a registered version, don't ever go beyond base + if ( strchr (filename, '/') || strchr (filename,'\\')) + continue; + } + + sprintf (netpath, "%s/%s",search->filename, filename); + + findtime = Sys_FileTime (netpath); + if (findtime == -1) + continue; + + // see if the file needs to be updated in the cache + if (!com_cachedir[0]) + strcpy (cachepath, netpath); + else + { +#if defined(WIN32) + if ((strlen(netpath) < 2) || (netpath[1] != ':')) + sprintf (cachepath,"%s%s", com_cachedir, netpath); + else + sprintf (cachepath,"%s%s", com_cachedir, netpath+2); +#else + sprintf (cachepath,"%s%s", com_cachedir, netpath); +#endif + + cachetime = Sys_FileTime (cachepath); + + if (cachetime < findtime) + COM_CopyFile (netpath, cachepath); + strcpy (netpath, cachepath); + } + + Sys_Printf ("FindFile: %s\n",netpath); + com_filesize = Sys_FileOpenRead (netpath, &i); + if (handle) + *handle = i; + else + { + Sys_FileClose (i); + Sys_FileOpenRead(netpath, file); + } + return com_filesize; + } + + } + + Sys_Printf ("FindFile: can't find %s\n", filename); + + if (handle) + *handle = -1; + else + *file = -1; + com_filesize = -1; + return -1; +} + + +/* +=========== +COM_OpenFile + +filename never has a leading slash, but may contain directory walks +returns a handle and a length +it may actually be inside a pak file +=========== +*/ +int COM_OpenFile (char *filename, int *handle) +{ + return COM_FindFile (filename, handle, NULL); +} + +/* +=========== +COM_FOpenFile + +If the requested file is inside a packfile, a new file will be opened +into the file. +=========== +*/ +int COM_FOpenFile (char *filename, int *file) +{ + return COM_FindFile (filename, NULL, file); +} + +/* +============ +COM_CloseFile + +If it is a pak file handle, don't really close it +============ +*/ +void COM_CloseFile (int h) +{ + searchpath_t *s; + + for (s = com_searchpaths ; s ; s=s->next) + if (s->pack && s->pack->handle == h) + return; + + Sys_FileClose (h); +} + + +/* +============ +COM_LoadFile + +Filename are reletive to the quake directory. +Allways appends a 0 byte. +============ +*/ +cache_user_t *loadcache; +byte *loadbuf; +int loadsize; +byte *COM_LoadFile (char *path, int usehunk) +{ + int h; + byte *buf; + char base[32]; + int len; + + buf = NULL; // quiet compiler warning + +// look for it in the filesystem or pack files + len = COM_OpenFile (path, &h); + if (h == -1) + return NULL; + +// extract the filename base name for hunk tag + COM_FileBase (path, base); + + if (usehunk == 1) + buf = Hunk_AllocName (len+1, base); + else if (usehunk == 2) + buf = Hunk_TempAlloc (len+1); + else if (usehunk == 0) + buf = Z_Malloc (len+1); + else if (usehunk == 3) + buf = Cache_Alloc (loadcache, len+1, base); + else if (usehunk == 4) + { + if (len+1 > loadsize) + buf = Hunk_TempAlloc (len+1); + else + buf = loadbuf; + } + else + Sys_Error ("COM_LoadFile: bad usehunk"); + + if (!buf) + Sys_Error ("COM_LoadFile: not enough space for %s", path); + + ((byte *)buf)[len] = 0; + + Draw_BeginDisc (); + Sys_FileRead (h, buf, len); + COM_CloseFile (h); + Draw_EndDisc (); + + return buf; +} + +byte *COM_LoadHunkFile (char *path) +{ + return COM_LoadFile (path, 1); +} + +byte *COM_LoadTempFile (char *path) +{ + return COM_LoadFile (path, 2); +} + +void COM_LoadCacheFile (char *path, struct cache_user_s *cu) +{ + loadcache = cu; + COM_LoadFile (path, 3); +} + +// uses temp hunk if larger than bufsize +byte *COM_LoadStackFile (char *path, void *buffer, int bufsize) +{ + byte *buf; + + loadbuf = (byte *)buffer; + loadsize = bufsize; + buf = COM_LoadFile (path, 4); + + return buf; +} + +/* +================= +COM_LoadPackFile + +Takes an explicit (not game tree related) path to a pak file. + +Loads the header and directory, adding the files at the beginning +of the list so they override previous pack files. +================= +*/ +pack_t *COM_LoadPackFile (char *packfile) +{ + dpackheader_t header; + int i; + packfile_t *newfiles; + int numpackfiles; + pack_t *pack; + int packhandle; + dpackfile_t info[MAX_FILES_IN_PACK]; + unsigned short crc; + + if (Sys_FileOpenRead (packfile, &packhandle) == -1) + { +// Con_Printf ("Couldn't open %s\n", packfile); + return NULL; + } + Sys_FileRead (packhandle, (void *)&header, sizeof(header)); + if (header.id[0] != 'P' || header.id[1] != 'A' + || header.id[2] != 'C' || header.id[3] != 'K') + Sys_Error ("%s is not a packfile", packfile); + header.dirofs = LittleLong (header.dirofs); + header.dirlen = LittleLong (header.dirlen); + + numpackfiles = header.dirlen / sizeof(dpackfile_t); + + if (numpackfiles > MAX_FILES_IN_PACK) + Sys_Error ("%s has %i files", packfile, numpackfiles); + + if (numpackfiles != PAK0_COUNT) + com_modified = true; // not the original file + + newfiles = Hunk_AllocName (numpackfiles * sizeof(packfile_t), "packfile"); + + Sys_FileSeek (packhandle, header.dirofs); + Sys_FileRead (packhandle, (void *)info, header.dirlen); + +// crc the directory to check for modifications + CRC_Init (&crc); + for (i=0 ; ifilename, packfile); + pack->handle = packhandle; + pack->numfiles = numpackfiles; + pack->files = newfiles; + + Con_Printf ("Added packfile %s (%i files)\n", packfile, numpackfiles); + return pack; +} + + +/* +================ +COM_AddGameDirectory + +Sets com_gamedir, adds the directory to the head of the path, +then loads and adds pak1.pak pak2.pak ... +================ +*/ +void COM_AddGameDirectory (char *dir) +{ + int i; + searchpath_t *search; + pack_t *pak; + char pakfile[MAX_OSPATH]; + + strcpy (com_gamedir, dir); + +// +// add the directory to the search path +// + search = Hunk_Alloc (sizeof(searchpath_t)); + strcpy (search->filename, dir); + search->next = com_searchpaths; + com_searchpaths = search; + +// +// add any pak files in the format pak0.pak pak1.pak, ... +// + +// Changed so it will search for the next pak if one is missing which we need to do for +// Kurok to be standalone AND be able to run Quake alongside it. + + for (i=0 ; i<99; i++) + { + sprintf (pakfile, "%s/pak%i.pak", dir, i); + pak = COM_LoadPackFile (pakfile); + +// Don't stop if a pak is missing when running Kurok. +// if (!kurok) + if (!pak) + break; + + search = Hunk_Alloc (sizeof(searchpath_t)); + search->pack = pak; + search->next = com_searchpaths; + com_searchpaths = search; + } + +// +// add the contents of the parms.txt file to the end of the command line +// + +} + +/* +================ +COM_InitFilesystem +================ +*/ +void COM_InitFilesystem (void) +{ + int i, j; + char basedir[MAX_OSPATH]; + searchpath_t *search; + +// +// -basedir +// Overrides the system supplied base directory (under GAMENAME) +// + i = COM_CheckParm ("-basedir"); + if (i && i < com_argc-1) + strcpy (basedir, com_argv[i+1]); + else + strcpy (basedir, host_parms.basedir); + + j = strlen (basedir); + + if (j > 0) + { + if ((basedir[j-1] == '\\') || (basedir[j-1] == '/')) + basedir[j-1] = 0; + } + +// +// -cachedir +// Overrides the system supplied cache directory (NULL or /qcache) +// -cachedir - will disable caching. +// + i = COM_CheckParm ("-cachedir"); + if (i && i < com_argc-1) + { + if (com_argv[i+1][0] == '-') + com_cachedir[0] = 0; + else + strcpy (com_cachedir, com_argv[i+1]); + } + else if (host_parms.cachedir) + strcpy (com_cachedir, host_parms.cachedir); + else + com_cachedir[0] = 0; + +// +// start up with GAMENAME by default (id1) +// + COM_AddGameDirectory (va("%s/"GAMENAME, basedir) ); + + if (COM_CheckParm ("-rogue")) + COM_AddGameDirectory (va("%s/rogue", basedir) ); + if (COM_CheckParm ("-hipnotic")) + COM_AddGameDirectory (va("%s/hipnotic", basedir) ); + if (COM_CheckParm ("-kurok")) + COM_AddGameDirectory (va("%s/kurok", basedir) ); + +// +// -game +// Adds basedir/gamedir as an override game +// + i = COM_CheckParm ("-game"); + if (i && i < com_argc-1) + { + com_modified = true; + COM_AddGameDirectory (va("%s/%s", basedir, com_argv[i+1])); + } + +// +// -path [] ... +// Fully specifies the exact serach path, overriding the generated one +// + i = COM_CheckParm ("-path"); + if (i) + { + com_modified = true; + com_searchpaths = NULL; + while (++i < com_argc) + { + if (!com_argv[i] || com_argv[i][0] == '+' || com_argv[i][0] == '-') + break; + + search = Hunk_Alloc (sizeof(searchpath_t)); + if ( !strcmp(COM_FileExtension(com_argv[i]), "pak") ) + { + search->pack = COM_LoadPackFile (com_argv[i]); + if (!search->pack) + Sys_Error ("Couldn't load packfile: %s", com_argv[i]); + } + else + strcpy (search->filename, com_argv[i]); + search->next = com_searchpaths; + com_searchpaths = search; + } + } + + if (COM_CheckParm ("-proghack")) + proghack = true; +} + + diff --git a/r17/Revamped src/revamped_src/common.h b/r17/Revamped src/revamped_src/common.h new file mode 100755 index 00000000..f1307342 --- /dev/null +++ b/r17/Revamped src/revamped_src/common.h @@ -0,0 +1,199 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// comndef.h -- general definitions + +#if !defined BYTE_DEFINED +typedef unsigned char byte; +#define BYTE_DEFINED 1 +#endif + +#undef true +#undef false + +#ifdef __cplusplus +typedef enum {qfalse, qtrue} qboolean; +#else +typedef enum {false, true} qboolean; +#endif + +#ifndef min_b +#define min_b(a, b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef max_b +#define max_b(a, b) ((a) > (b) ? (a) : (b)) +#endif + +// by joe +#define bound(a, b, c) ((a) >= (c) ? (a) : (b) < (a) ? (a) : (b) > (c) ? (c) : (b)) + +//============================================================================ + +typedef struct sizebuf_s +{ + qboolean allowoverflow; // if false, do a Sys_Error + qboolean overflowed; // set to true if the buffer size failed + byte *data; + int maxsize; + int cursize; +} sizebuf_t; + +void SZ_Alloc (sizebuf_t *buf, int startsize); +void SZ_Free (sizebuf_t *buf); +void SZ_Clear (sizebuf_t *buf); +void *SZ_GetSpace (sizebuf_t *buf, int length); +void SZ_Write (sizebuf_t *buf, void *data, int length); +void SZ_Print (sizebuf_t *buf, char *data); // strcats onto the sizebuf + +//============================================================================ + +typedef struct link_s +{ + struct link_s *prev, *next; +} link_t; + + +void ClearLink (link_t *l); +void RemoveLink (link_t *l); +void InsertLinkBefore (link_t *l, link_t *before); +void InsertLinkAfter (link_t *l, link_t *after); + +// (type *)STRUCT_FROM_LINK(link_t *link, type, member) +// ent = STRUCT_FROM_LINK(link,entity_t,order) +// FIXME: remove this mess! +#define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (int)&(((t *)0)->m))) + +//============================================================================ + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#define Q_MAXCHAR ((char)0x7f) +#define Q_MAXSHORT ((short)0x7fff) +#define Q_MAXINT ((int)0x7fffffff) +#define Q_MAXLONG ((int)0x7fffffff) +#define Q_MAXFLOAT ((int)0x7fffffff) + +#define Q_MINCHAR ((char)0x80) +#define Q_MINSHORT ((short)0x8000) +#define Q_MININT ((int)0x80000000) +#define Q_MINLONG ((int)0x80000000) +#define Q_MINFLOAT ((int)0x7fffffff) + +//============================================================================ + +extern qboolean bigendien; + +extern short (*BigShort) (short l); +extern short (*LittleShort) (short l); +extern int (*BigLong) (int l); +extern int (*LittleLong) (int l); +extern float (*BigFloat) (float l); +extern float (*LittleFloat) (float l); + +//============================================================================ + +void MSG_WriteChar (sizebuf_t *sb, int c); +void MSG_WriteByte (sizebuf_t *sb, int c); +void MSG_WriteShort (sizebuf_t *sb, int c); +void MSG_WriteLong (sizebuf_t *sb, int c); +void MSG_WriteFloat (sizebuf_t *sb, float f); +void MSG_WriteString (sizebuf_t *sb, char *s); +void MSG_WriteCoord (sizebuf_t *sb, float f); +void MSG_WriteAngle (sizebuf_t *sb, float f); +void MSG_WritePreciseAngle (sizebuf_t *sb, float f); // JPG - precise aim!! + +extern int msg_readcount; +extern qboolean msg_badread; // set if a read goes beyond end of message + +void MSG_BeginReading (void); +int MSG_ReadChar (void); +int MSG_ReadByte (void); +int MSG_ReadShort (void); +int MSG_ReadLong (void); +float MSG_ReadFloat (void); +char *MSG_ReadString (void); + +float MSG_ReadCoord (void); +float MSG_ReadAngle (void); +float MSG_ReadPreciseAngle (void); // JPG - precise aim!! + +//============================================================================ + +void Q_memset (void *dest, int fill, int count); +void Q_memcpy (void *dest, void *src, int count); +int Q_memcmp (void *m1, void *m2, int count); +void Q_strcpy (char *dest, char *src); +void Q_strncpy (char *dest, char *src, int count); +int Q_strlen (char *str); +char *Q_strrchr (char *s, char c); +void Q_strcat (char *dest, char *src); +int Q_strcmp (char *s1, char *s2); +int Q_strncmp (char *s1, char *s2, int count); +int Q_strcasecmp (char *s1, char *s2); +int Q_strncasecmp (char *s1, char *s2, int n); +int Q_atoi (char *str); +float Q_atof (char *str); + +//============================================================================ + +extern char com_token[1024]; +extern qboolean com_eof; + +char *COM_Parse (char *data); + + +extern int com_argc; +extern char **com_argv; + +int COM_CheckParm (char *parm); +void COM_Init (char *path); +void COM_InitArgv (int argc, char **argv); + +char *COM_SkipPath (char *pathname); +void COM_StripExtension (char *in, char *out); +void COM_FileBase (char *in, char *out); +void COM_DefaultExtension (char *path, char *extension); + +char *va(char *format, ...); +// does a varargs printf into a temp buffer + + +//============================================================================ + +extern int com_filesize; +struct cache_user_s; + +extern char com_gamedir[MAX_OSPATH]; + +void COM_WriteFile (char *filename, void *data, int len); +int COM_OpenFile (char *filename, int *hndl); +int COM_FOpenFile (char *filename, int *file); +void COM_CloseFile (int h); + +byte *COM_LoadStackFile (char *path, void *buffer, int bufsize); +byte *COM_LoadTempFile (char *path); +byte *COM_LoadHunkFile (char *path); +void COM_LoadCacheFile (char *path, struct cache_user_s *cu); + + +extern struct cvar_s registered; + +extern qboolean standard_quake, rogue, hipnotic, kurok; diff --git a/r17/Revamped src/revamped_src/console.c b/r17/Revamped src/revamped_src/console.c new file mode 100755 index 00000000..de943726 --- /dev/null +++ b/r17/Revamped src/revamped_src/console.c @@ -0,0 +1,672 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// console.c + +#ifdef NeXT +#include +#endif +#ifndef _MSC_VER +#include +#endif +#include +#include "quakedef.h" + +int con_linewidth; + +float con_cursorspeed = 4; + +#define CON_TEXTSIZE 16384 + +qboolean con_forcedup; // because no entities to refresh + +int con_totallines; // total lines in console scrollback +int con_backscroll; // lines up from bottom to display +int con_current; // where next message will be printed +int con_x; // offset in current line for next print +char *con_text=0; + +cvar_t con_notifytime = {"con_notifytime","3"}; //seconds + +#define NUM_CON_TIMES 4 +float con_times[NUM_CON_TIMES]; // realtime time the line was generated + // for transparent notify lines + +int con_vislines; + +qboolean con_debuglog; + +#define MAXCMDLINE 256 +extern char key_lines[32][MAXCMDLINE]; +extern int edit_line; +extern int key_linepos; + + +qboolean con_initialized; + +int con_notifylines; // scan lines to clear for notify lines + +extern void M_Menu_Main_f (void); + +void M_OSK_Draw (void); +void Con_OSK_f (char *input, char *output, int outlen); +void Con_OSK_Key(int key); +void Con_DrawOSK(void); + +/* +================ +Con_ToggleConsole_f +================ +*/ +void Con_ToggleConsole_f (void) +{ + if (key_dest == key_console) + { + if (cls.state == ca_connected) + { + key_dest = key_game; + key_lines[edit_line][1] = 0; // clear any typing + key_linepos = 1; + } + else + { + M_Menu_Main_f (); + } + } + else + key_dest = key_console; + + SCR_EndLoadingPlaque (); + memset (con_times, 0, sizeof(con_times)); +} + +/* +================ +Con_Clear_f +================ +*/ +void Con_Clear_f (void) +{ + if (con_text) + Q_memset (con_text, ' ', CON_TEXTSIZE); +} + + +/* +================ +Con_ClearNotify +================ +*/ +void Con_ClearNotify (void) +{ + int i; + + for (i=0 ; i> 3) - 2; + + if (width == con_linewidth) + return; + + if (width < 1) // video hasn't been initialized yet + { + width = 38; + con_linewidth = width; + con_totallines = CON_TEXTSIZE / con_linewidth; + Q_memset (con_text, ' ', CON_TEXTSIZE); + } + else + { + oldwidth = con_linewidth; + con_linewidth = width; + oldtotallines = con_totallines; + con_totallines = CON_TEXTSIZE / con_linewidth; + numlines = oldtotallines; + + if (con_totallines < numlines) + numlines = con_totallines; + + numchars = oldwidth; + + if (con_linewidth < numchars) + numchars = con_linewidth; + + Q_memcpy (tbuf, con_text, CON_TEXTSIZE); + Q_memset (con_text, ' ', CON_TEXTSIZE); + + for (i=0 ; i con_linewidth) ) + con_x = 0; + + txt++; + + if (cr) + { + con_current--; + cr = false; + } + + + if (!con_x) + { + Con_Linefeed (); + // mark time for transparent overlay + if (con_current >= 0) + con_times[con_current % NUM_CON_TIMES] = realtime; + } + + switch (c) + { + case '\n': + con_x = 0; + break; + + case '\r': + con_x = 0; + cr = 1; + break; + + default: // display character and advance + y = con_current % con_totallines; + con_text[y*con_linewidth+con_x] = c | mask; + con_x++; + if (con_x >= con_linewidth) + con_x = 0; + break; + } + + } +} + + +/* +================ +Con_DebugLog +================ +*/ +void Con_DebugLog(char *file, char *fmt, ...) +{ + va_list argptr; + static char data[1024]; + int fd; + + va_start(argptr, fmt); + vsprintf(data, fmt, argptr); + va_end(argptr); + fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666); + write(fd, data, strlen(data)); + close(fd); +} + + +/* +================ +Con_Printf + +Handles cursor positioning, line wrapping, etc +================ +*/ +#define MAXPRINTMSG 4096 +// FIXME: make a buffer size safe vsprintf? +void Con_Printf (char *fmt, ...) +{ + va_list argptr; + char msg[MAXPRINTMSG]; + static qboolean inupdate; + + va_start (argptr,fmt); + vsprintf (msg,fmt,argptr); + va_end (argptr); + +// also echo to debugging console + Sys_Printf ("%s", msg); // also echo to debugging console + +// log all messages to file + if (con_debuglog) + Con_DebugLog(va("%s/qconsole.log",com_gamedir), "%s", msg); + + if (!con_initialized) + return; + + if (cls.state == ca_dedicated) + return; // no graphics mode + +// write it to the scrollable buffer + Con_Print (msg); + +// update the screen if the console is displayed + if (cls.signon != SIGNONS && !scr_disabled_for_loading ) + { + // protect against infinite loop if something in SCR_UpdateScreen calls + // Con_Printd + if (!inupdate) + { + inupdate = true; + SCR_UpdateScreen (); + inupdate = false; + } + } +} + +/* +================ +Con_DPrintf + +A Con_Printf that only shows up if the "developer" cvar is set +================ +*/ +void Con_DPrintf (char *fmt, ...) +{ + va_list argptr; + char msg[MAXPRINTMSG]; + + if (!developer.value) + return; // don't confuse non-developers with techie stuff... + + va_start (argptr,fmt); + vsprintf (msg,fmt,argptr); + va_end (argptr); + + Con_Printf ("%s", msg); +} + + +/* +================== +Con_SafePrintf + +Okay to call even when the screen can't be updated +================== +*/ +void Con_SafePrintf (char *fmt, ...) +{ + va_list argptr; + char msg[1024]; + int temp; + + va_start (argptr,fmt); + vsprintf (msg,fmt,argptr); + va_end (argptr); + + temp = scr_disabled_for_loading; + scr_disabled_for_loading = true; + Con_Printf ("%s", msg); + scr_disabled_for_loading = temp; +} + + +/* +============================================================================== + +DRAWING + +============================================================================== +*/ + + +/* +================ +Con_DrawInput + +The input line scrolls horizontally if typing goes beyond the right edge +================ +*/ +void Con_DrawInput (void) +{ + int y; + int i; + char *text; + + if (key_dest != key_console && !con_forcedup) + return; // don't draw anything + + text = key_lines[edit_line]; + +// add the cursor frame + text[key_linepos] = 10+((int)(realtime*con_cursorspeed)&1); + +// fill out remainder with spaces + for (i=key_linepos+1 ; i< con_linewidth ; i++) + text[i] = ' '; + +// prestep if horizontally scrolling + if (key_linepos >= con_linewidth) + text += 1 + key_linepos - con_linewidth; + +// draw it + y = con_vislines-16; + + for (i=0 ; i con_notifytime.value) + continue; + text = con_text + (i % con_totallines)*con_linewidth; + + clearnotify = 0; + scr_copytop = 1; + + for (x = 0 ; x < con_linewidth ; x++) + Draw_Character ( (x+1)<<3, v, text[x]); + + v += 8; + } + + + if (key_dest == key_message) + { + clearnotify = 0; + scr_copytop = 1; + + x = 0; + + Draw_String (8, v, "say:"); + while(chat_buffer[x]) + { + Draw_Character ( (x+5)<<3, v, chat_buffer[x]); + x++; + } + Draw_Character ( (x+5)<<3, v, 10+((int)(realtime*con_cursorspeed)&1)); + v += 8; + } + + if (v > con_notifylines) + con_notifylines = v; +} + +/* +================ +Con_DrawConsole + +Draws the console with the solid background +The typing input line at the bottom should only be drawn if typing is allowed +================ +*/ +void Con_DrawConsole (int lines, qboolean drawinput) +{ + int i, x, y; + int rows; + char *text; + int j; + + if (lines <= 0) + return; + +// draw the background + Draw_ConsoleBackground (lines); + +// draw the text + con_vislines = lines; + + rows = (lines-16)>>3; // rows of text to draw + y = lines - 16 - (rows<<3); // may start slightly negative + + for (i= con_current - rows + 1 ; i<=con_current ; i++, y+=8 ) + { + j = i - con_backscroll; + if (j<0) + j = 0; + text = con_text + (j % con_totallines)*con_linewidth; + + for (x=0 ; x> 8) ^ data]; +} + +unsigned short CRC_Value(unsigned short crcvalue) +{ + return crcvalue ^ CRC_XOR_VALUE; +} diff --git a/r17/Revamped src/revamped_src/crc.h b/r17/Revamped src/revamped_src/crc.h new file mode 100755 index 00000000..7cc779c1 --- /dev/null +++ b/r17/Revamped src/revamped_src/crc.h @@ -0,0 +1,24 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +/* crc.h */ + +void CRC_Init(unsigned short *crcvalue); +void CRC_ProcessByte(unsigned short *crcvalue, byte data); +unsigned short CRC_Value(unsigned short crcvalue); diff --git a/r17/Revamped src/revamped_src/cvar.c b/r17/Revamped src/revamped_src/cvar.c new file mode 100755 index 00000000..5548691b --- /dev/null +++ b/r17/Revamped src/revamped_src/cvar.c @@ -0,0 +1,227 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// cvar.c -- dynamic variable tracking + +#include "quakedef.h" + +cvar_t *cvar_vars; +char *cvar_null_string = ""; + +/* +============ +Cvar_FindVar +============ +*/ +cvar_t *Cvar_FindVar (char *var_name) +{ + cvar_t *var; + + for (var=cvar_vars ; var ; var=var->next) + if (!Q_strcmp (var_name, var->name)) + return var; + + return NULL; +} + +/* +============ +Cvar_VariableValue +============ +*/ +float Cvar_VariableValue (char *var_name) +{ + cvar_t *var; + + var = Cvar_FindVar (var_name); + if (!var) + return 0; + return Q_atof (var->string); +} + + +/* +============ +Cvar_VariableString +============ +*/ +char *Cvar_VariableString (char *var_name) +{ + cvar_t *var; + + var = Cvar_FindVar (var_name); + if (!var) + return cvar_null_string; + return var->string; +} + + +/* +============ +Cvar_CompleteVariable +============ +*/ +char *Cvar_CompleteVariable (char *partial) +{ + cvar_t *cvar; + int len; + + len = Q_strlen(partial); + + if (!len) + return NULL; + +// check functions + for (cvar=cvar_vars ; cvar ; cvar=cvar->next) + if (!Q_strncmp (partial,cvar->name, len)) + return cvar->name; + + return NULL; +} + + +/* +============ +Cvar_Set +============ +*/ +void Cvar_Set (char *var_name, char *value) +{ + cvar_t *var; + qboolean changed; + + var = Cvar_FindVar (var_name); + if (!var) + { // there is an error in C code if this happens + Con_Printf ("Cvar_Set: variable %s not found\n", var_name); + return; + } + + changed = Q_strcmp(var->string, value); + + Z_Free (var->string); // free the old value string + + var->string = Z_Malloc (Q_strlen(value)+1); + Q_strcpy (var->string, value); + var->value = Q_atof (var->string); + if (var->server && changed) + { + if (sv.active) + SV_BroadcastPrintf ("\"%s\" changed to \"%s\"\n", var->name, var->string); + } +} + +/* +============ +Cvar_SetValue +============ +*/ +void Cvar_SetValue (char *var_name, float value) +{ + char val[32]; + + if (value == (int)value) + sprintf (val, "%d", (int)value); + else + sprintf (val, "%f", value); + Cvar_Set (var_name, val); +} + + +/* +============ +Cvar_RegisterVariable + +Adds a freestanding variable to the variable list. +============ +*/ +void Cvar_RegisterVariable (cvar_t *variable) +{ + char *oldstr; + +// first check to see if it has allready been defined + if (Cvar_FindVar (variable->name)) + { + Con_Printf ("Can't register variable %s, allready defined\n", variable->name); + return; + } + +// check for overlap with a command + if (Cmd_Exists (variable->name)) + { + Con_Printf ("Cvar_RegisterVariable: %s is a command\n", variable->name); + return; + } + +// copy the value off, because future sets will Z_Free it + oldstr = variable->string; + variable->string = Z_Malloc (Q_strlen(variable->string)+1); + Q_strcpy (variable->string, oldstr); + variable->value = Q_atof (variable->string); + +// link the variable in + variable->next = cvar_vars; + cvar_vars = variable; +} + +/* +============ +Cvar_Command + +Handles variable inspection and changing from the console +============ +*/ +qboolean Cvar_Command (void) +{ + cvar_t *v; + +// check variables + v = Cvar_FindVar (Cmd_Argv(0)); + if (!v) + return false; + +// perform a variable print or set + if (Cmd_Argc() == 1) + { + Con_Printf ("\"%s\" is \"%s\"\n", v->name, v->string); + return true; + } + + Cvar_Set (v->name, Cmd_Argv(1)); + return true; +} + + +/* +============ +Cvar_WriteVariables + +Writes lines containing "set variable value" for all variables +with the archive flag set to true. +============ +*/ +void Cvar_WriteVariables (FILE *f) +{ + cvar_t *var; + + for (var = cvar_vars ; var ; var = var->next) + if (var->archive) + fprintf (f, "%s \"%s\"\n", var->name, var->string); +} + diff --git a/r17/Revamped src/revamped_src/cvar.h b/r17/Revamped src/revamped_src/cvar.h new file mode 100755 index 00000000..771b3404 --- /dev/null +++ b/r17/Revamped src/revamped_src/cvar.h @@ -0,0 +1,97 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// cvar.h + +/* + +cvar_t variables are used to hold scalar or string variables that can be changed or displayed at the console or prog code as well as accessed directly +in C code. + +it is sufficient to initialize a cvar_t with just the first two fields, or +you can add a ,true flag for variables that you want saved to the configuration +file when the game is quit: + +cvar_t r_draworder = {"r_draworder","1"}; +cvar_t scr_screensize = {"screensize","1",true}; + +Cvars must be registered before use, or they will have a 0 value instead of the float interpretation of the string. Generally, all cvar_t declarations should be registered in the apropriate init function before any console commands are executed: +Cvar_RegisterVariable (&host_framerate); + + +C code usually just references a cvar in place: +if ( r_draworder.value ) + +It could optionally ask for the value to be looked up for a string name: +if (Cvar_VariableValue ("r_draworder")) + +Interpreted prog code can access cvars with the cvar(name) or +cvar_set (name, value) internal functions: +teamplay = cvar("teamplay"); +cvar_set ("registered", "1"); + +The user can access cvars from the console in two ways: +r_draworder prints the current value +r_draworder 0 sets the current value to 0 +Cvars are restricted from having the same names as commands to keep this +interface from being ambiguous. +*/ + +typedef struct cvar_s +{ + char *name; + char *string; + qboolean archive; // set to true to cause it to be saved to vars.rc + qboolean server; // notifies players when changed + float value; + struct cvar_s *next; +} cvar_t; + +void Cvar_RegisterVariable (cvar_t *variable); +// registers a cvar that allready has the name, string, and optionally the +// archive elements set. + +void Cvar_Set (char *var_name, char *value); +// equivelant to " " typed at the console + +void Cvar_SetValue (char *var_name, float value); +// expands value to a string and calls Cvar_Set + +float Cvar_VariableValue (char *var_name); +// returns 0 if not defined or non numeric + +char *Cvar_VariableString (char *var_name); +// returns an empty string if not defined + +char *Cvar_CompleteVariable (char *partial); +// attempts to match a partial variable name for command line completion +// returns NULL if nothing fits + +qboolean Cvar_Command (void); +// called by Cmd_ExecuteString when Cmd_Argv(0) doesn't match a known +// command. Returns true if the command was a variable reference that +// was handled. (print or change) + +void Cvar_WriteVariables (FILE *f); +// Writes lines containing "set variable value" for all variables +// with the archive flag set to true. + +cvar_t *Cvar_FindVar (char *var_name); + +extern cvar_t *cvar_vars; diff --git a/r17/Revamped src/revamped_src/d_edge.c b/r17/Revamped src/revamped_src/d_edge.c new file mode 100755 index 00000000..bbd1c2c0 --- /dev/null +++ b/r17/Revamped src/revamped_src/d_edge.c @@ -0,0 +1,331 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// d_edge.c + +#include "quakedef.h" +#include "d_local.h" + +static int miplevel; + +float scale_for_mip; +int screenwidth; +int ubasestep, errorterm, erroradjustup, erroradjustdown; +int vstartscan; + +// FIXME: should go away +extern void R_RotateBmodel (void); +extern void R_TransformFrustum (void); + +vec3_t transformed_modelorg; + +/* +============== +D_DrawPoly + +============== +*/ +void D_DrawPoly (void) +{ +// this driver takes spans, not polygons +} + + +/* +============= +D_MipLevelForScale +============= +*/ +int D_MipLevelForScale (float scale) +{ + int lmiplevel; + + if (scale >= d_scalemip[0] ) + lmiplevel = 0; + else if (scale >= d_scalemip[1] ) + lmiplevel = 1; + else if (scale >= d_scalemip[2] ) + lmiplevel = 2; + else + lmiplevel = 3; + + if (lmiplevel < d_minmip) + lmiplevel = d_minmip; + + return lmiplevel; +} + + +/* +============== +D_DrawSolidSurface +============== +*/ + +// FIXME: clean this up + +void D_DrawSolidSurface (surf_t *surf, int color) +{ + espan_t *span; + byte *pdest; + int u, u2, pix; + + pix = (color<<24) | (color<<16) | (color<<8) | color; + for (span=surf->spans ; span ; span=span->pnext) + { + pdest = (byte *)d_viewbuffer + screenwidth*span->v; + u = span->u; + u2 = span->u + span->count - 1; + ((byte *)pdest)[u] = pix; + + if (u2 - u < 8) + { + for (u++ ; u <= u2 ; u++) + ((byte *)pdest)[u] = pix; + } + else + { + for (u++ ; u & 3 ; u++) + ((byte *)pdest)[u] = pix; + + u2 -= 4; + for ( ; u <= u2 ; u+=4) + *(int *)((byte *)pdest + u) = pix; + u2 += 4; + for ( ; u <= u2 ; u++) + ((byte *)pdest)[u] = pix; + } + } +} + + +/* +============== +D_CalcGradients +============== +*/ +void D_CalcGradients (msurface_t *pface) +{ + mplane_t *pplane; + float mipscale; + vec3_t p_temp1; + vec3_t p_saxis, p_taxis; + float t; + + pplane = pface->plane; + + mipscale = 1.0 / (float)(1 << miplevel); + + TransformVector (pface->texinfo->vecs[0], p_saxis); + TransformVector (pface->texinfo->vecs[1], p_taxis); + + t = xscaleinv * mipscale; + d_sdivzstepu = p_saxis[0] * t; + d_tdivzstepu = p_taxis[0] * t; + + t = yscaleinv * mipscale; + d_sdivzstepv = -p_saxis[1] * t; + d_tdivzstepv = -p_taxis[1] * t; + + d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu - + ycenter * d_sdivzstepv; + d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu - + ycenter * d_tdivzstepv; + + VectorScale (transformed_modelorg, mipscale, p_temp1); + + t = 0x10000*mipscale; + sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) - + ((pface->texturemins[0] << 16) >> miplevel) + + pface->texinfo->vecs[0][3]*t; + tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) - + ((pface->texturemins[1] << 16) >> miplevel) + + pface->texinfo->vecs[1][3]*t; + +// +// -1 (-epsilon) so we never wander off the edge of the texture +// + bbextents = ((pface->extents[0] << 16) >> miplevel) - 1; + bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1; +} + + +/* +============== +D_DrawSurfaces +============== +*/ +void D_DrawSurfaces (void) +{ + surf_t *s; + msurface_t *pface; + surfcache_t *pcurrentcache; + vec3_t world_transformed_modelorg; + vec3_t local_modelorg; + + currententity = &cl_entities[0]; + TransformVector (modelorg, transformed_modelorg); + VectorCopy (transformed_modelorg, world_transformed_modelorg); + +// TODO: could preset a lot of this at mode set time + if (r_drawflat.value) + { + for (s = &surfaces[1] ; sspans) + continue; + + d_zistepu = s->d_zistepu; + d_zistepv = s->d_zistepv; + d_ziorigin = s->d_ziorigin; + + D_DrawSolidSurface (s, (int)s->data & 0xFF); + D_DrawZSpans (s->spans); + } + } + else + { + for (s = &surfaces[1] ; sspans) + continue; + + r_drawnpolycount++; + + d_zistepu = s->d_zistepu; + d_zistepv = s->d_zistepv; + d_ziorigin = s->d_ziorigin; + + if (s->flags & SURF_DRAWSKY) + { + if (!r_skymade) + { + R_MakeSky (); + } + + D_DrawSkyScans8 (s->spans); + D_DrawZSpans (s->spans); + } + else if (s->flags & SURF_DRAWBACKGROUND) + { + // set up a gradient for the background surface that places it + // effectively at infinity distance from the viewpoint + d_zistepu = 0; + d_zistepv = 0; + d_ziorigin = -0.9; + + D_DrawSolidSurface (s, (int)r_clearcolor.value & 0xFF); + D_DrawZSpans (s->spans); + } + else if (s->flags & SURF_DRAWTURB) + { + pface = s->data; + miplevel = 0; + cacheblock = (pixel_t *) + ((byte *)pface->texinfo->texture + + pface->texinfo->texture->offsets[0]); + cachewidth = 64; + + if (s->insubmodel) + { + // FIXME: we don't want to do all this for every polygon! + // TODO: store once at start of frame + currententity = s->entity; //FIXME: make this passed in to + // R_RotateBmodel () + VectorSubtract (r_origin, currententity->origin, + local_modelorg); + TransformVector (local_modelorg, transformed_modelorg); + + R_RotateBmodel (); // FIXME: don't mess with the frustum, + // make entity passed in + } + + D_CalcGradients (pface); + Turbulent8 (s->spans); + D_DrawZSpans (s->spans); + + if (s->insubmodel) + { + // + // restore the old drawing state + // FIXME: we don't want to do this every time! + // TODO: speed up + // + currententity = &cl_entities[0]; + VectorCopy (world_transformed_modelorg, + transformed_modelorg); + VectorCopy (base_vpn, vpn); + VectorCopy (base_vup, vup); + VectorCopy (base_vright, vright); + VectorCopy (base_modelorg, modelorg); + R_TransformFrustum (); + } + } + else + { + if (s->insubmodel) + { + // FIXME: we don't want to do all this for every polygon! + // TODO: store once at start of frame + currententity = s->entity; //FIXME: make this passed in to + // R_RotateBmodel () + VectorSubtract (r_origin, currententity->origin, local_modelorg); + TransformVector (local_modelorg, transformed_modelorg); + + R_RotateBmodel (); // FIXME: don't mess with the frustum, + // make entity passed in + } + + pface = s->data; + miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip + * pface->texinfo->mipadjust); + + // FIXME: make this passed in to D_CacheSurface + pcurrentcache = D_CacheSurface (pface, miplevel); + + cacheblock = (pixel_t *)pcurrentcache->data; + cachewidth = pcurrentcache->width; + + D_CalcGradients (pface); + + (*d_drawspans) (s->spans); + + D_DrawZSpans (s->spans); + + if (s->insubmodel) + { + // + // restore the old drawing state + // FIXME: we don't want to do this every time! + // TODO: speed up + // + currententity = &cl_entities[0]; + VectorCopy (world_transformed_modelorg, + transformed_modelorg); + VectorCopy (base_vpn, vpn); + VectorCopy (base_vup, vup); + VectorCopy (base_vright, vright); + VectorCopy (base_modelorg, modelorg); + R_TransformFrustum (); + } + } + } + } +} + diff --git a/r17/Revamped src/revamped_src/d_fill.c b/r17/Revamped src/revamped_src/d_fill.c new file mode 100755 index 00000000..b1ebb5f1 --- /dev/null +++ b/r17/Revamped src/revamped_src/d_fill.c @@ -0,0 +1,88 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// d_clear: clears a specified rectangle to the specified color + +#include "quakedef.h" + + +/* +================ +D_FillRect +================ +*/ +void D_FillRect (vrect_t *rect, int color) +{ + int rx, ry, rwidth, rheight; + unsigned char *dest; + unsigned *ldest; + + rx = rect->x; + ry = rect->y; + rwidth = rect->width; + rheight = rect->height; + + if (rx < 0) + { + rwidth += rx; + rx = 0; + } + if (ry < 0) + { + rheight += ry; + ry = 0; + } + if (rx+rwidth > vid.width) + rwidth = vid.width - rx; + if (ry+rheight > vid.height) + rheight = vid.height - rx; + + if (rwidth < 1 || rheight < 1) + return; + + dest = ((byte *)vid.buffer + ry*vid.rowbytes + rx); + + if (((rwidth & 0x03) == 0) && (((long)dest & 0x03) == 0)) + { + // faster aligned dword clear + ldest = (unsigned *)dest; + color += color << 16; + + rwidth >>= 2; + color += color << 8; + + for (ry=0 ; ry 3) + d_minmip = 3; + else if (d_minmip < 0) + d_minmip = 0; + + for (i=0 ; i<(NUM_MIPS-1) ; i++) + d_scalemip[i] = basemip[i] * d_mipscale.value; + +#if id386 + if (d_subdiv16.value) + d_drawspans = D_DrawSpans16; + else + d_drawspans = D_DrawSpans8; +#else + d_drawspans = D_DrawSpans8; +#endif + + d_aflatcolor = 0; +} + + +/* +=============== +D_UpdateRects +=============== +*/ +void D_UpdateRects (vrect_t *prect) +{ + +// the software driver draws these directly to the vid buffer + + UNUSED(prect); +} + diff --git a/r17/Revamped src/revamped_src/d_local.h b/r17/Revamped src/revamped_src/d_local.h new file mode 100755 index 00000000..4636c459 --- /dev/null +++ b/r17/Revamped src/revamped_src/d_local.h @@ -0,0 +1,111 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// d_local.h: private rasterization driver defs + +#include "r_shared.h" + +// +// TODO: fine-tune this; it's based on providing some overage even if there +// is a 2k-wide scan, with subdivision every 8, for 256 spans of 12 bytes each +// +#define SCANBUFFERPAD 0x1000 + +#define R_SKY_SMASK 0x007F0000 +#define R_SKY_TMASK 0x007F0000 + +#define DS_SPAN_LIST_END -128 + +#define SURFCACHE_SIZE_AT_320X200 600*1024 + +typedef struct surfcache_s +{ + struct surfcache_s *next; + struct surfcache_s **owner; // NULL is an empty chunk of memory + int lightadj[MAXLIGHTMAPS]; // checked for strobe flush + int dlight; + int size; // including header + unsigned width; + unsigned height; // DEBUG only needed for debug + float mipscale; + struct texture_s *texture; // checked for animating textures + byte data[4]; // width*height elements +} surfcache_t; + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct sspan_s +{ + int u, v, count; +} sspan_t; + +extern cvar_t d_subdiv16; + +extern float scale_for_mip; + +extern qboolean d_roverwrapped; +extern surfcache_t *sc_rover; +extern surfcache_t *d_initial_rover; + +extern float d_sdivzstepu, d_tdivzstepu, d_zistepu; +extern float d_sdivzstepv, d_tdivzstepv, d_zistepv; +extern float d_sdivzorigin, d_tdivzorigin, d_ziorigin; + +fixed16_t sadjust, tadjust; +fixed16_t bbextents, bbextentt; + + +void D_DrawSpans8 (espan_t *pspans); +void D_DrawSpans16 (espan_t *pspans); +void D_DrawZSpans (espan_t *pspans); +void Turbulent8 (espan_t *pspan); +void D_SpriteDrawSpans (sspan_t *pspan); + +void D_DrawSkyScans8 (espan_t *pspan); +void D_DrawSkyScans16 (espan_t *pspan); + +void R_ShowSubDiv (void); +void (*prealspandrawer)(void); +surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel); + +extern int D_MipLevelForScale (float scale); + +#if id386 +extern void D_PolysetAff8Start (void); +extern void D_PolysetAff8End (void); +#endif + +extern short *d_pzbuffer; +extern unsigned int d_zrowbytes, d_zwidth; + +extern int *d_pscantable; +extern int d_scantable[MAXHEIGHT]; + +extern int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle; + +extern int d_y_aspect_shift, d_pix_min, d_pix_max, d_pix_shift; + +extern pixel_t *d_viewbuffer; + +extern short *zspantable[MAXHEIGHT]; + +extern int d_minmip; +extern float d_scalemip[3]; + +extern void (*d_drawspans) (espan_t *pspan); + diff --git a/r17/Revamped src/revamped_src/d_modech.c b/r17/Revamped src/revamped_src/d_modech.c new file mode 100755 index 00000000..f1162b4b --- /dev/null +++ b/r17/Revamped src/revamped_src/d_modech.c @@ -0,0 +1,107 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// d_modech.c: called when mode has just changed + +#include "quakedef.h" +#include "d_local.h" + +int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle; + +int d_y_aspect_shift, d_pix_min, d_pix_max, d_pix_shift; + +int d_scantable[MAXHEIGHT]; +short *zspantable[MAXHEIGHT]; + +/* +================ +D_Patch +================ +*/ +void D_Patch (void) +{ +#if id386 + + static qboolean protectset8 = false; + + if (!protectset8) + { + Sys_MakeCodeWriteable ((int)D_PolysetAff8Start, + (int)D_PolysetAff8End - (int)D_PolysetAff8Start); + protectset8 = true; + } + +#endif // id386 +} + + +/* +================ +D_ViewChanged +================ +*/ +void D_ViewChanged (void) +{ + int rowbytes; + + if (r_dowarp) + rowbytes = WARP_WIDTH; + else + rowbytes = vid.rowbytes; + + scale_for_mip = xscale; + if (yscale > xscale) + scale_for_mip = yscale; + + d_zrowbytes = vid.width * 2; + d_zwidth = vid.width; + + d_pix_min = r_refdef.vrect.width / 320; + if (d_pix_min < 1) + d_pix_min = 1; + + d_pix_max = (int)((float)r_refdef.vrect.width / (320.0 / 4.0) + 0.5); + d_pix_shift = 8 - (int)((float)r_refdef.vrect.width / 320.0 + 0.5); + if (d_pix_max < 1) + d_pix_max = 1; + + if (pixelAspect > 1.4) + d_y_aspect_shift = 1; + else + d_y_aspect_shift = 0; + + d_vrectx = r_refdef.vrect.x; + d_vrecty = r_refdef.vrect.y; + d_vrectright_particle = r_refdef.vrectright - d_pix_max; + d_vrectbottom_particle = + r_refdef.vrectbottom - (d_pix_max << d_y_aspect_shift); + + { + int i; + + for (i=0 ; iorg, r_origin, local); + + transformed[0] = DotProduct(local, r_pright); + transformed[1] = DotProduct(local, r_pup); + transformed[2] = DotProduct(local, r_ppn); + + if (transformed[2] < PARTICLE_Z_CLIP) + return; + +// project the point +// FIXME: preadjust xcenter and ycenter + zi = 1.0 / transformed[2]; + u = (int)(xcenter + zi * transformed[0] + 0.5); + v = (int)(ycenter - zi * transformed[1] + 0.5); + + if ((v > d_vrectbottom_particle) || + (u > d_vrectright_particle) || + (v < d_vrecty) || + (u < d_vrectx)) + { + return; + } + + pz = d_pzbuffer + (d_zwidth * v) + u; + pdest = d_viewbuffer + d_scantable[v] + u; + izi = (int)(zi * 0x8000); + + pix = izi >> d_pix_shift; + + if (pix < d_pix_min) + pix = d_pix_min; + else if (pix > d_pix_max) + pix = d_pix_max; + + switch (pix) + { + case 1: + count = 1 << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + if (pz[0] <= izi) + { + pz[0] = izi; + pdest[0] = pparticle->color; + } + } + break; + + case 2: + count = 2 << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + if (pz[0] <= izi) + { + pz[0] = izi; + pdest[0] = pparticle->color; + } + + if (pz[1] <= izi) + { + pz[1] = izi; + pdest[1] = pparticle->color; + } + } + break; + + case 3: + count = 3 << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + if (pz[0] <= izi) + { + pz[0] = izi; + pdest[0] = pparticle->color; + } + + if (pz[1] <= izi) + { + pz[1] = izi; + pdest[1] = pparticle->color; + } + + if (pz[2] <= izi) + { + pz[2] = izi; + pdest[2] = pparticle->color; + } + } + break; + + case 4: + count = 4 << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + if (pz[0] <= izi) + { + pz[0] = izi; + pdest[0] = pparticle->color; + } + + if (pz[1] <= izi) + { + pz[1] = izi; + pdest[1] = pparticle->color; + } + + if (pz[2] <= izi) + { + pz[2] = izi; + pdest[2] = pparticle->color; + } + + if (pz[3] <= izi) + { + pz[3] = izi; + pdest[3] = pparticle->color; + } + } + break; + + default: + count = pix << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + for (i=0 ; icolor; + } + } + } + break; + } +} + +#endif // !id386 + diff --git a/r17/Revamped src/revamped_src/d_polyse.c b/r17/Revamped src/revamped_src/d_polyse.c new file mode 100755 index 00000000..2d8614e7 --- /dev/null +++ b/r17/Revamped src/revamped_src/d_polyse.c @@ -0,0 +1,1111 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// d_polyset.c: routines for drawing sets of polygons sharing the same +// texture (used for Alias models) + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" + +// TODO: put in span spilling to shrink list size +// !!! if this is changed, it must be changed in d_polysa.s too !!! +#define DPS_MAXSPANS MAXHEIGHT+1 + // 1 extra for spanpackage that marks end + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct { + void *pdest; + short *pz; + int count; + byte *ptex; + int sfrac, tfrac, light, zi; +} spanpackage_t; + +typedef struct { + int isflattop; + int numleftedges; + int *pleftedgevert0; + int *pleftedgevert1; + int *pleftedgevert2; + int numrightedges; + int *prightedgevert0; + int *prightedgevert1; + int *prightedgevert2; +} edgetable; + +int r_p0[6], r_p1[6], r_p2[6]; + +byte *d_pcolormap; + +int d_aflatcolor; +int d_xdenom; + +edgetable *pedgetable; + +edgetable edgetables[12] = { + {0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 }, + {0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL}, + {1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL}, + {0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 }, + {0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL}, + {0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL}, + {0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 }, + {0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL}, + {0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL}, + {1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL}, + {1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL}, + {0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL}, +}; + +// FIXME: some of these can become statics +int a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole; +int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy; +int r_zistepx, r_zistepy; +int d_aspancount, d_countextrastep; + +spanpackage_t *a_spans; +spanpackage_t *d_pedgespanpackage; +static int ystart; +byte *d_pdest, *d_ptex; +short *d_pz; +int d_sfrac, d_tfrac, d_light, d_zi; +int d_ptexextrastep, d_sfracextrastep; +int d_tfracextrastep, d_lightextrastep, d_pdestextrastep; +int d_lightbasestep, d_pdestbasestep, d_ptexbasestep; +int d_sfracbasestep, d_tfracbasestep; +int d_ziextrastep, d_zibasestep; +int d_pzextrastep, d_pzbasestep; + +typedef struct { + int quotient; + int remainder; +} adivtab_t; + +static adivtab_t adivtab[32*32] = { +#include "adivtab.h" +}; + +byte *skintable[MAX_LBM_HEIGHT]; +int skinwidth; +byte *skinstart; + +void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage); +void D_PolysetCalcGradients (int skinwidth); +void D_DrawSubdiv (void); +void D_DrawNonSubdiv (void); +void D_PolysetRecursiveTriangle (int *p1, int *p2, int *p3); +void D_PolysetSetEdgeTable (void); +void D_RasterizeAliasPolySmooth (void); +void D_PolysetScanLeftEdge (int height); + +#if !id386 + +/* +================ +D_PolysetDraw +================ +*/ +void D_PolysetDraw (void) +{ + spanpackage_t spans[DPS_MAXSPANS + 1 + + ((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1]; + // one extra because of cache line pretouching + + a_spans = (spanpackage_t *) + (((long)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + + if (r_affinetridesc.drawtype) + { + D_DrawSubdiv (); + } + else + { + D_DrawNonSubdiv (); + } +} + + +/* +================ +D_PolysetDrawFinalVerts +================ +*/ +void D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts) +{ + int i, z; + short *zbuf; + + for (i=0 ; iv[0] < r_refdef.vrectright) && + (fv->v[1] < r_refdef.vrectbottom)) + { + z = fv->v[5]>>16; + zbuf = zspantable[fv->v[1]] + fv->v[0]; + if (z >= *zbuf) + { + int pix; + + *zbuf = z; + pix = skintable[fv->v[3]>>16][fv->v[2]>>16]; + pix = ((byte *)acolormap)[pix + (fv->v[4] & 0xFF00) ]; + d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = pix; + } + } + } +} + + +/* +================ +D_DrawSubdiv +================ +*/ +void D_DrawSubdiv (void) +{ + mtriangle_t *ptri; + finalvert_t *pfv, *index0, *index1, *index2; + int i; + int lnumtriangles; + + pfv = r_affinetridesc.pfinalverts; + ptri = r_affinetridesc.ptriangles; + lnumtriangles = r_affinetridesc.numtriangles; + + for (i=0 ; iv[1]-index1->v[1]) * + (index0->v[0]-index2->v[0]) - + (index0->v[0]-index1->v[0]) * + (index0->v[1]-index2->v[1])) >= 0) + { + continue; + } + + d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00]; + + if (ptri[i].facesfront) + { + D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); + } + else + { + int s0, s1, s2; + + s0 = index0->v[2]; + s1 = index1->v[2]; + s2 = index2->v[2]; + + if (index0->flags & ALIAS_ONSEAM) + index0->v[2] += r_affinetridesc.seamfixupX16; + if (index1->flags & ALIAS_ONSEAM) + index1->v[2] += r_affinetridesc.seamfixupX16; + if (index2->flags & ALIAS_ONSEAM) + index2->v[2] += r_affinetridesc.seamfixupX16; + + D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); + + index0->v[2] = s0; + index1->v[2] = s1; + index2->v[2] = s2; + } + } +} + + +/* +================ +D_DrawNonSubdiv +================ +*/ +void D_DrawNonSubdiv (void) +{ + mtriangle_t *ptri; + finalvert_t *pfv, *index0, *index1, *index2; + int i; + int lnumtriangles; + + pfv = r_affinetridesc.pfinalverts; + ptri = r_affinetridesc.ptriangles; + lnumtriangles = r_affinetridesc.numtriangles; + + for (i=0 ; ivertindex[0]; + index1 = pfv + ptri->vertindex[1]; + index2 = pfv + ptri->vertindex[2]; + + d_xdenom = (index0->v[1]-index1->v[1]) * + (index0->v[0]-index2->v[0]) - + (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]); + + if (d_xdenom >= 0) + { + continue; + } + + r_p0[0] = index0->v[0]; // u + r_p0[1] = index0->v[1]; // v + r_p0[2] = index0->v[2]; // s + r_p0[3] = index0->v[3]; // t + r_p0[4] = index0->v[4]; // light + r_p0[5] = index0->v[5]; // iz + + r_p1[0] = index1->v[0]; + r_p1[1] = index1->v[1]; + r_p1[2] = index1->v[2]; + r_p1[3] = index1->v[3]; + r_p1[4] = index1->v[4]; + r_p1[5] = index1->v[5]; + + r_p2[0] = index2->v[0]; + r_p2[1] = index2->v[1]; + r_p2[2] = index2->v[2]; + r_p2[3] = index2->v[3]; + r_p2[4] = index2->v[4]; + r_p2[5] = index2->v[5]; + + if (!ptri->facesfront) + { + if (index0->flags & ALIAS_ONSEAM) + r_p0[2] += r_affinetridesc.seamfixupX16; + if (index1->flags & ALIAS_ONSEAM) + r_p1[2] += r_affinetridesc.seamfixupX16; + if (index2->flags & ALIAS_ONSEAM) + r_p2[2] += r_affinetridesc.seamfixupX16; + } + + D_PolysetSetEdgeTable (); + D_RasterizeAliasPolySmooth (); + } +} + + +/* +================ +D_PolysetRecursiveTriangle +================ +*/ +void D_PolysetRecursiveTriangle (int *lp1, int *lp2, int *lp3) +{ + int *temp; + int d; + int new[6]; + int z; + short *zbuf; + + d = lp2[0] - lp1[0]; + if (d < -1 || d > 1) + goto split; + d = lp2[1] - lp1[1]; + if (d < -1 || d > 1) + goto split; + + d = lp3[0] - lp2[0]; + if (d < -1 || d > 1) + goto split2; + d = lp3[1] - lp2[1]; + if (d < -1 || d > 1) + goto split2; + + d = lp1[0] - lp3[0]; + if (d < -1 || d > 1) + goto split3; + d = lp1[1] - lp3[1]; + if (d < -1 || d > 1) + { +split3: + temp = lp1; + lp1 = lp3; + lp3 = lp2; + lp2 = temp; + + goto split; + } + + return; // entire tri is filled + +split2: + temp = lp1; + lp1 = lp2; + lp2 = lp3; + lp3 = temp; + +split: +// split this edge + new[0] = (lp1[0] + lp2[0]) >> 1; + new[1] = (lp1[1] + lp2[1]) >> 1; + new[2] = (lp1[2] + lp2[2]) >> 1; + new[3] = (lp1[3] + lp2[3]) >> 1; + new[5] = (lp1[5] + lp2[5]) >> 1; + +// draw the point if splitting a leading edge + if (lp2[1] > lp1[1]) + goto nodraw; + if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0])) + goto nodraw; + + + z = new[5]>>16; + zbuf = zspantable[new[1]] + new[0]; + if (z >= *zbuf) + { + int pix; + + *zbuf = z; + pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]]; + d_viewbuffer[d_scantable[new[1]] + new[0]] = pix; + } + +nodraw: +// recursively continue + D_PolysetRecursiveTriangle (lp3, lp1, new); + D_PolysetRecursiveTriangle (lp3, new, lp2); +} + +#endif // !id386 + + +/* +================ +D_PolysetUpdateTables +================ +*/ +void D_PolysetUpdateTables (void) +{ + int i; + byte *s; + + if (r_affinetridesc.skinwidth != skinwidth || + r_affinetridesc.pskin != skinstart) + { + skinwidth = r_affinetridesc.skinwidth; + skinstart = r_affinetridesc.pskin; + s = skinstart; + for (i=0 ; ipdest = d_pdest; + d_pedgespanpackage->pz = d_pz; + d_pedgespanpackage->count = d_aspancount; + d_pedgespanpackage->ptex = d_ptex; + + d_pedgespanpackage->sfrac = d_sfrac; + d_pedgespanpackage->tfrac = d_tfrac; + + // FIXME: need to clamp l, s, t, at both ends? + d_pedgespanpackage->light = d_light; + d_pedgespanpackage->zi = d_zi; + + d_pedgespanpackage++; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_pdest += d_pdestextrastep; + d_pz += d_pzextrastep; + d_aspancount += d_countextrastep; + d_ptex += d_ptexextrastep; + d_sfrac += d_sfracextrastep; + d_ptex += d_sfrac >> 16; + + d_sfrac &= 0xFFFF; + d_tfrac += d_tfracextrastep; + if (d_tfrac & 0x10000) + { + d_ptex += r_affinetridesc.skinwidth; + d_tfrac &= 0xFFFF; + } + d_light += d_lightextrastep; + d_zi += d_ziextrastep; + errorterm -= erroradjustdown; + } + else + { + d_pdest += d_pdestbasestep; + d_pz += d_pzbasestep; + d_aspancount += ubasestep; + d_ptex += d_ptexbasestep; + d_sfrac += d_sfracbasestep; + d_ptex += d_sfrac >> 16; + d_sfrac &= 0xFFFF; + d_tfrac += d_tfracbasestep; + if (d_tfrac & 0x10000) + { + d_ptex += r_affinetridesc.skinwidth; + d_tfrac &= 0xFFFF; + } + d_light += d_lightbasestep; + d_zi += d_zibasestep; + } + } while (--height); +} + +#endif // !id386 + + +/* +=================== +D_PolysetSetUpForLineScan +==================== +*/ +void D_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv, + fixed8_t endvertu, fixed8_t endvertv) +{ + float dm, dn; + int tm, tn; + adivtab_t *ptemp; + +// TODO: implement x86 version + + errorterm = -1; + + tm = endvertu - startvertu; + tn = endvertv - startvertv; + + if (((tm <= 16) && (tm >= -15)) && + ((tn <= 16) && (tn >= -15))) + { + ptemp = &adivtab[((tm+15) << 5) + (tn+15)]; + ubasestep = ptemp->quotient; + erroradjustup = ptemp->remainder; + erroradjustdown = tn; + } + else + { + dm = (float)tm; + dn = (float)tn; + + FloorDivMod (dm, dn, &ubasestep, &erroradjustup); + + erroradjustdown = dn; + } +} + + +#if !id386 + +/* +================ +D_PolysetCalcGradients +================ +*/ +void D_PolysetCalcGradients (int skinwidth) +{ + float xstepdenominv, ystepdenominv, t0, t1; + float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20; + + p00_minus_p20 = r_p0[0] - r_p2[0]; + p01_minus_p21 = r_p0[1] - r_p2[1]; + p10_minus_p20 = r_p1[0] - r_p2[0]; + p11_minus_p21 = r_p1[1] - r_p2[1]; + + xstepdenominv = 1.0 / (float)d_xdenom; + + ystepdenominv = -xstepdenominv; + +// ceilf () for light so positive steps are exaggerated, negative steps +// diminished, pushing us away from underflow toward overflow. Underflow is +// very visible, overflow is very unlikely, because of ambient lighting + t0 = r_p0[4] - r_p2[4]; + t1 = r_p1[4] - r_p2[4]; + r_lstepx = (int) + ceilf((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); + r_lstepy = (int) + ceilf((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); + + t0 = r_p0[2] - r_p2[2]; + t1 = r_p1[2] - r_p2[2]; + r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) * + ystepdenominv); + + t0 = r_p0[3] - r_p2[3]; + t1 = r_p1[3] - r_p2[3]; + r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * + ystepdenominv); + + t0 = r_p0[5] - r_p2[5]; + t1 = r_p1[5] - r_p2[5]; + r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * + ystepdenominv); + +#if id386 + a_sstepxfrac = r_sstepx << 16; + a_tstepxfrac = r_tstepx << 16; +#else + a_sstepxfrac = r_sstepx & 0xFFFF; + a_tstepxfrac = r_tstepx & 0xFFFF; +#endif + + a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16); +} + +#endif // !id386 + + +#if 0 +byte gelmap[256]; +void InitGel (byte *palette) +{ + int i; + int r; + + for (i=0 ; i<256 ; i++) + { +// r = (palette[i*3]>>4); + r = (palette[i*3] + palette[i*3+1] + palette[i*3+2])/(16*3); + gelmap[i] = /* 64 */ 0 + r; + } +} +#endif + + +#if !id386 + +/* +================ +D_PolysetDrawSpans8 +================ +*/ +void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage) +{ + int lcount; + byte *lpdest; + byte *lptex; + int lsfrac, ltfrac; + int llight; + int lzi; + short *lpz; + + do + { + lcount = d_aspancount - pspanpackage->count; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_aspancount += d_countextrastep; + errorterm -= erroradjustdown; + } + else + { + d_aspancount += ubasestep; + } + + if (lcount) + { + lpdest = pspanpackage->pdest; + lptex = pspanpackage->ptex; + lpz = pspanpackage->pz; + lsfrac = pspanpackage->sfrac; + ltfrac = pspanpackage->tfrac; + llight = pspanpackage->light; + lzi = pspanpackage->zi; + + do + { + if ((lzi >> 16) >= *lpz) + { + *lpdest = ((byte *)acolormap)[*lptex + (llight & 0xFF00)]; +// gel mapping *lpdest = gelmap[*lpdest]; + *lpz = lzi >> 16; + } + lpdest++; + lzi += r_zistepx; + lpz++; + llight += r_lstepx; + lptex += a_ststepxwhole; + lsfrac += a_sstepxfrac; + lptex += lsfrac >> 16; + lsfrac &= 0xFFFF; + ltfrac += a_tstepxfrac; + if (ltfrac & 0x10000) + { + lptex += r_affinetridesc.skinwidth; + ltfrac &= 0xFFFF; + } + } while (--lcount); + } + + pspanpackage++; + } while (pspanpackage->count != -999999); +} +#endif // !id386 + + +/* +================ +D_PolysetFillSpans8 +================ +*/ +void D_PolysetFillSpans8 (spanpackage_t *pspanpackage) +{ + int color; + +// FIXME: do z buffering + + color = d_aflatcolor++; + + while (1) + { + int lcount; + byte *lpdest; + + lcount = pspanpackage->count; + + if (lcount == -1) + return; + + if (lcount) + { + lpdest = pspanpackage->pdest; + + do + { + *lpdest++ = color; + } while (--lcount); + } + + pspanpackage++; + } +} + +/* +================ +D_RasterizeAliasPolySmooth +================ +*/ +void D_RasterizeAliasPolySmooth (void) +{ + int initialleftheight, initialrightheight; + int *plefttop, *prighttop, *pleftbottom, *prightbottom; + int working_lstepx, originalcount; + + plefttop = pedgetable->pleftedgevert0; + prighttop = pedgetable->prightedgevert0; + + pleftbottom = pedgetable->pleftedgevert1; + prightbottom = pedgetable->prightedgevert1; + + initialleftheight = pleftbottom[1] - plefttop[1]; + initialrightheight = prightbottom[1] - prighttop[1]; + +// +// set the s, t, and light gradients, which are consistent across the triangle +// because being a triangle, things are affine +// + D_PolysetCalcGradients (r_affinetridesc.skinwidth); + +// +// rasterize the polygon +// + +// +// scan out the top (and possibly only) part of the left edge +// + d_pedgespanpackage = a_spans; + + ystart = plefttop[1]; + d_aspancount = plefttop[0] - prighttop[0]; + + d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) + + (plefttop[3] >> 16) * r_affinetridesc.skinwidth; +#if id386 + d_sfrac = (plefttop[2] & 0xFFFF) << 16; + d_tfrac = (plefttop[3] & 0xFFFF) << 16; +#else + d_sfrac = plefttop[2] & 0xFFFF; + d_tfrac = plefttop[3] & 0xFFFF; +#endif + d_light = plefttop[4]; + d_zi = plefttop[5]; + + d_pdest = (byte *)d_viewbuffer + + ystart * screenwidth + plefttop[0]; + d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; + + if (initialleftheight == 1) + { + d_pedgespanpackage->pdest = d_pdest; + d_pedgespanpackage->pz = d_pz; + d_pedgespanpackage->count = d_aspancount; + d_pedgespanpackage->ptex = d_ptex; + + d_pedgespanpackage->sfrac = d_sfrac; + d_pedgespanpackage->tfrac = d_tfrac; + + // FIXME: need to clamp l, s, t, at both ends? + d_pedgespanpackage->light = d_light; + d_pedgespanpackage->zi = d_zi; + + d_pedgespanpackage++; + } + else + { + D_PolysetSetUpForLineScan(plefttop[0], plefttop[1], + pleftbottom[0], pleftbottom[1]); + + #if id386 + d_pzbasestep = (d_zwidth + ubasestep) << 1; + d_pzextrastep = d_pzbasestep + 2; + #else + d_pzbasestep = d_zwidth + ubasestep; + d_pzextrastep = d_pzbasestep + 1; + #endif + + d_pdestbasestep = screenwidth + ubasestep; + d_pdestextrastep = d_pdestbasestep + 1; + + // TODO: can reuse partial expressions here + + // for negative steps in x along left edge, bias toward overflow rather than + // underflow (sort of turning the floor () we did in the gradient calcs into + // ceilf (), but plus a little bit) + if (ubasestep < 0) + working_lstepx = r_lstepx - 1; + else + working_lstepx = r_lstepx; + + d_countextrastep = ubasestep + 1; + d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) + + ((r_tstepy + r_tstepx * ubasestep) >> 16) * + r_affinetridesc.skinwidth; + #if id386 + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16; + #else + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; + #endif + d_lightbasestep = r_lstepy + working_lstepx * ubasestep; + d_zibasestep = r_zistepy + r_zistepx * ubasestep; + + d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) + + ((r_tstepy + r_tstepx * d_countextrastep) >> 16) * + r_affinetridesc.skinwidth; + #if id386 + d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16; + d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16; + #else + d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF; + d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF; + #endif + d_lightextrastep = d_lightbasestep + working_lstepx; + d_ziextrastep = d_zibasestep + r_zistepx; + + D_PolysetScanLeftEdge (initialleftheight); + } + +// +// scan out the bottom part of the left edge, if it exists +// + if (pedgetable->numleftedges == 2) + { + int height; + + plefttop = pleftbottom; + pleftbottom = pedgetable->pleftedgevert2; + + height = pleftbottom[1] - plefttop[1]; + +// TODO: make this a function; modularize this function in general + + ystart = plefttop[1]; + d_aspancount = plefttop[0] - prighttop[0]; + d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) + + (plefttop[3] >> 16) * r_affinetridesc.skinwidth; + d_sfrac = 0; + d_tfrac = 0; + d_light = plefttop[4]; + d_zi = plefttop[5]; + + d_pdest = (byte *)d_viewbuffer + ystart * screenwidth + plefttop[0]; + d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; + + if (height == 1) + { + d_pedgespanpackage->pdest = d_pdest; + d_pedgespanpackage->pz = d_pz; + d_pedgespanpackage->count = d_aspancount; + d_pedgespanpackage->ptex = d_ptex; + + d_pedgespanpackage->sfrac = d_sfrac; + d_pedgespanpackage->tfrac = d_tfrac; + + // FIXME: need to clamp l, s, t, at both ends? + d_pedgespanpackage->light = d_light; + d_pedgespanpackage->zi = d_zi; + + d_pedgespanpackage++; + } + else + { + D_PolysetSetUpForLineScan(plefttop[0], plefttop[1], + pleftbottom[0], pleftbottom[1]); + + d_pdestbasestep = screenwidth + ubasestep; + d_pdestextrastep = d_pdestbasestep + 1; + + #if id386 + d_pzbasestep = (d_zwidth + ubasestep) << 1; + d_pzextrastep = d_pzbasestep + 2; + #else + d_pzbasestep = d_zwidth + ubasestep; + d_pzextrastep = d_pzbasestep + 1; + #endif + + if (ubasestep < 0) + working_lstepx = r_lstepx - 1; + else + working_lstepx = r_lstepx; + + d_countextrastep = ubasestep + 1; + d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) + + ((r_tstepy + r_tstepx * ubasestep) >> 16) * + r_affinetridesc.skinwidth; + #if id386 + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16; + #else + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; + #endif + d_lightbasestep = r_lstepy + working_lstepx * ubasestep; + d_zibasestep = r_zistepy + r_zistepx * ubasestep; + + d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) + + ((r_tstepy + r_tstepx * d_countextrastep) >> 16) * + r_affinetridesc.skinwidth; + #if id386 + d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16; + d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16; + #else + d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF; + d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF; + #endif + d_lightextrastep = d_lightbasestep + working_lstepx; + d_ziextrastep = d_zibasestep + r_zistepx; + + D_PolysetScanLeftEdge (height); + } + } + +// scan out the top (and possibly only) part of the right edge, updating the +// count field + d_pedgespanpackage = a_spans; + + D_PolysetSetUpForLineScan(prighttop[0], prighttop[1], + prightbottom[0], prightbottom[1]); + d_aspancount = 0; + d_countextrastep = ubasestep + 1; + originalcount = a_spans[initialrightheight].count; + a_spans[initialrightheight].count = -999999; // mark end of the spanpackages + D_PolysetDrawSpans8 (a_spans); + +// scan out the bottom part of the right edge, if it exists + if (pedgetable->numrightedges == 2) + { + int height; + spanpackage_t *pstart; + + pstart = a_spans + initialrightheight; + pstart->count = originalcount; + + d_aspancount = prightbottom[0] - prighttop[0]; + + prighttop = prightbottom; + prightbottom = pedgetable->prightedgevert2; + + height = prightbottom[1] - prighttop[1]; + + D_PolysetSetUpForLineScan(prighttop[0], prighttop[1], + prightbottom[0], prightbottom[1]); + + d_countextrastep = ubasestep + 1; + a_spans[initialrightheight + height].count = -999999; + // mark end of the spanpackages + D_PolysetDrawSpans8 (pstart); + } +} + + +/* +================ +D_PolysetSetEdgeTable +================ +*/ +void D_PolysetSetEdgeTable (void) +{ + int edgetableindex; + + edgetableindex = 0; // assume the vertices are already in + // top to bottom order + +// +// determine which edges are right & left, and the order in which +// to rasterize them +// + if (r_p0[1] >= r_p1[1]) + { + if (r_p0[1] == r_p1[1]) + { + if (r_p0[1] < r_p2[1]) + pedgetable = &edgetables[2]; + else + pedgetable = &edgetables[5]; + + return; + } + else + { + edgetableindex = 1; + } + } + + if (r_p0[1] == r_p2[1]) + { + if (edgetableindex) + pedgetable = &edgetables[8]; + else + pedgetable = &edgetables[9]; + + return; + } + else if (r_p1[1] == r_p2[1]) + { + if (edgetableindex) + pedgetable = &edgetables[10]; + else + pedgetable = &edgetables[11]; + + return; + } + + if (r_p0[1] > r_p2[1]) + edgetableindex += 2; + + if (r_p1[1] > r_p2[1]) + edgetableindex += 4; + + pedgetable = &edgetables[edgetableindex]; +} + + +#if 0 + +void D_PolysetRecursiveDrawLine (int *lp1, int *lp2) +{ + int d; + int new[6]; + int ofs; + + d = lp2[0] - lp1[0]; + if (d < -1 || d > 1) + goto split; + d = lp2[1] - lp1[1]; + if (d < -1 || d > 1) + goto split; + + return; // line is completed + +split: +// split this edge + new[0] = (lp1[0] + lp2[0]) >> 1; + new[1] = (lp1[1] + lp2[1]) >> 1; + new[5] = (lp1[5] + lp2[5]) >> 1; + new[2] = (lp1[2] + lp2[2]) >> 1; + new[3] = (lp1[3] + lp2[3]) >> 1; + new[4] = (lp1[4] + lp2[4]) >> 1; + +// draw the point + ofs = d_scantable[new[1]] + new[0]; + if (new[5] > d_pzbuffer[ofs]) + { + int pix; + + d_pzbuffer[ofs] = new[5]; + pix = skintable[new[3]>>16][new[2]>>16]; +// pix = ((byte *)acolormap)[pix + (new[4] & 0xFF00)]; + d_viewbuffer[ofs] = pix; + } + +// recursively continue + D_PolysetRecursiveDrawLine (lp1, new); + D_PolysetRecursiveDrawLine (new, lp2); +} + +void D_PolysetRecursiveTriangle2 (int *lp1, int *lp2, int *lp3) +{ + int d; + int new[4]; + + d = lp2[0] - lp1[0]; + if (d < -1 || d > 1) + goto split; + d = lp2[1] - lp1[1]; + if (d < -1 || d > 1) + goto split; + return; + +split: +// split this edge + new[0] = (lp1[0] + lp2[0]) >> 1; + new[1] = (lp1[1] + lp2[1]) >> 1; + new[5] = (lp1[5] + lp2[5]) >> 1; + new[2] = (lp1[2] + lp2[2]) >> 1; + new[3] = (lp1[3] + lp2[3]) >> 1; + new[4] = (lp1[4] + lp2[4]) >> 1; + + D_PolysetRecursiveDrawLine (new, lp3); + +// recursively continue + D_PolysetRecursiveTriangle (lp1, new, lp3); + D_PolysetRecursiveTriangle (new, lp2, lp3); +} + +#endif + diff --git a/r17/Revamped src/revamped_src/d_scan.c b/r17/Revamped src/revamped_src/d_scan.c new file mode 100755 index 00000000..fb5148f7 --- /dev/null +++ b/r17/Revamped src/revamped_src/d_scan.c @@ -0,0 +1,449 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// d_scan.c +// +// Portable C scan-level rasterization code, all pixel depths. + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" + +unsigned char *r_turb_pbase, *r_turb_pdest; +fixed16_t r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep; +int *r_turb_turb; +int r_turb_spancount; + +void D_DrawTurbulent8Span (void); + + +/* +============= +D_WarpScreen + +// this performs a slight compression of the screen at the same time as +// the sine warp, to keep the edges from wrapping +============= +*/ +void D_WarpScreen (void) +{ + int w, h; + int u,v; + byte *dest; + int *turb; + int *col; + byte **row; + byte *rowptr[MAXHEIGHT+(AMP2*2)]; + int column[MAXWIDTH+(AMP2*2)]; + float wratio, hratio; + + w = r_refdef.vrect.width; + h = r_refdef.vrect.height; + + wratio = w / (float)scr_vrect.width; + hratio = h / (float)scr_vrect.height; + + for (v=0 ; v>16)&(CYCLE-1)])>>16)&63; + tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63; + *r_turb_pdest++ = *(r_turb_pbase + (tturb<<6) + sturb); + r_turb_s += r_turb_sstep; + r_turb_t += r_turb_tstep; + } while (--r_turb_spancount > 0); +} + +#endif // !id386 + + +/* +============= +Turbulent8 +============= +*/ +void Turbulent8 (espan_t *pspan) +{ + int count; + fixed16_t snext, tnext; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz16stepu, tdivz16stepu, zi16stepu; + + r_turb_turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1)); + + r_turb_sstep = 0; // keep compiler happy + r_turb_tstep = 0; // ditto + + r_turb_pbase = (unsigned char *)cacheblock; + + sdivz16stepu = d_sdivzstepu * 16; + tdivz16stepu = d_tdivzstepu * 16; + zi16stepu = d_zistepu * 16; + + do + { + r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer + + (screenwidth * pspan->v) + pspan->u); + + count = pspan->count; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + r_turb_s = (int)(sdivz * z) + sadjust; + if (r_turb_s > bbextents) + r_turb_s = bbextents; + else if (r_turb_s < 0) + r_turb_s = 0; + + r_turb_t = (int)(tdivz * z) + tadjust; + if (r_turb_t > bbextentt) + r_turb_t = bbextentt; + else if (r_turb_t < 0) + r_turb_t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 16) + r_turb_spancount = 16; + else + r_turb_spancount = count; + + count -= r_turb_spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz16stepu; + tdivz += tdivz16stepu; + zi += zi16stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 16) + snext = 16; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 16) + tnext = 16; // guard against round-off error on <0 steps + + r_turb_sstep = (snext - r_turb_s) >> 4; + r_turb_tstep = (tnext - r_turb_t) >> 4; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(r_turb_spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 16) + snext = 16; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 16) + tnext = 16; // guard against round-off error on <0 steps + + if (r_turb_spancount > 1) + { + r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1); + r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1); + } + } + + r_turb_s = r_turb_s & ((CYCLE<<16)-1); + r_turb_t = r_turb_t & ((CYCLE<<16)-1); + + D_DrawTurbulent8Span (); + + r_turb_s = snext; + r_turb_t = tnext; + + } while (count > 0); + + } while ((pspan = pspan->pnext) != NULL); +} + + +#if !id386 + +/* +============= +D_DrawSpans8 +============= +*/ +void D_DrawSpans8 (espan_t *pspan) +{ + int count, spancount; + unsigned char *pbase, *pdest; + fixed16_t s, t, snext, tnext, sstep, tstep; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz8stepu, tdivz8stepu, zi8stepu; + + sstep = 0; // keep compiler happy + tstep = 0; // ditto + + pbase = (unsigned char *)cacheblock; + + sdivz8stepu = d_sdivzstepu * 8; + tdivz8stepu = d_tdivzstepu * 8; + zi8stepu = d_zistepu * 8; + + do + { + pdest = (unsigned char *)((byte *)d_viewbuffer + + (screenwidth * pspan->v) + pspan->u); + + count = pspan->count; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + s = (int)(sdivz * z) + sadjust; + if (s > bbextents) + s = bbextents; + else if (s < 0) + s = 0; + + t = (int)(tdivz * z) + tadjust; + if (t > bbextentt) + t = bbextentt; + else if (t < 0) + t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 8) + spancount = 8; + else + spancount = count; + + count -= spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz8stepu; + tdivz += tdivz8stepu; + zi += zi8stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + sstep = (snext - s) >> 3; + tstep = (tnext - t) >> 3; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + if (spancount > 1) + { + sstep = (snext - s) / (spancount - 1); + tstep = (tnext - t) / (spancount - 1); + } + } + + do + { + *pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth); + s += sstep; + t += tstep; + } while (--spancount > 0); + + s = snext; + t = tnext; + + } while (count > 0); + + } while ((pspan = pspan->pnext) != NULL); +} + +#endif + + +#if !id386 + +/* +============= +D_DrawZSpans +============= +*/ +void D_DrawZSpans (espan_t *pspan) +{ + int count, doublecount, izistep; + int izi; + short *pdest; + unsigned ltemp; + float zi; + float du, dv; + +// FIXME: check for clamping/range problems +// we count on FP exceptions being turned off to avoid range problems + izistep = (int)(d_zistepu * 0x8000 * 0x10000); + + do + { + pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; + + count = pspan->count; + + // calculate the initial 1/z + du = (float)pspan->u; + dv = (float)pspan->v; + + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + // we count on FP exceptions being turned off to avoid range problems + izi = (int)(zi * 0x8000 * 0x10000); + + if ((long)pdest & 0x02) + { + *pdest++ = (short)(izi >> 16); + izi += izistep; + count--; + } + + if ((doublecount = count >> 1) > 0) + { + do + { + ltemp = izi >> 16; + izi += izistep; + ltemp |= izi & 0xFFFF0000; + izi += izistep; + *(int *)pdest = ltemp; + pdest += 2; + } while (--doublecount > 0); + } + + if (count & 1) + *pdest = (short)(izi >> 16); + + } while ((pspan = pspan->pnext) != NULL); +} + +#endif + diff --git a/r17/Revamped src/revamped_src/d_sky.c b/r17/Revamped src/revamped_src/d_sky.c new file mode 100755 index 00000000..6007b6a6 --- /dev/null +++ b/r17/Revamped src/revamped_src/d_sky.c @@ -0,0 +1,138 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// d_sky.c + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" + +#define SKY_SPAN_SHIFT 5 +#define SKY_SPAN_MAX (1 << SKY_SPAN_SHIFT) + + +/* +================= +D_Sky_uv_To_st +================= +*/ +void D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t) +{ + float wu, wv, temp; + vec3_t end; + + if (r_refdef.vrect.width >= r_refdef.vrect.height) + temp = (float)r_refdef.vrect.width; + else + temp = (float)r_refdef.vrect.height; + + wu = 8192.0 * (float)(u-((int)vid.width>>1)) / temp; + wv = 8192.0 * (float)(((int)vid.height>>1)-v) / temp; + + end[0] = 4096*vpn[0] + wu*vright[0] + wv*vup[0]; + end[1] = 4096*vpn[1] + wu*vright[1] + wv*vup[1]; + end[2] = 4096*vpn[2] + wu*vright[2] + wv*vup[2]; + end[2] *= 3; + VectorNormalize (end); + + temp = skytime*skyspeed; // TODO: add D_SetupFrame & set this there + *s = (int)((temp + 6*(SKYSIZE/2-1)*end[0]) * 0x10000); + *t = (int)((temp + 6*(SKYSIZE/2-1)*end[1]) * 0x10000); +} + + +/* +================= +D_DrawSkyScans8 +================= +*/ +void D_DrawSkyScans8 (espan_t *pspan) +{ + int count, spancount, u, v; + unsigned char *pdest; + fixed16_t s, t, snext, tnext, sstep, tstep; + int spancountminus1; + + sstep = 0; // keep compiler happy + tstep = 0; // ditto + + do + { + pdest = (unsigned char *)((byte *)d_viewbuffer + + (screenwidth * pspan->v) + pspan->u); + + count = pspan->count; + + // calculate the initial s & t + u = pspan->u; + v = pspan->v; + D_Sky_uv_To_st (u, v, &s, &t); + + do + { + if (count >= SKY_SPAN_MAX) + spancount = SKY_SPAN_MAX; + else + spancount = count; + + count -= spancount; + + if (count) + { + u += spancount; + + // calculate s and t at far end of span, + // calculate s and t steps across span by shifting + D_Sky_uv_To_st (u, v, &snext, &tnext); + + sstep = (snext - s) >> SKY_SPAN_SHIFT; + tstep = (tnext - t) >> SKY_SPAN_SHIFT; + } + else + { + // calculate s and t at last pixel in span, + // calculate s and t steps across span by division + spancountminus1 = (float)(spancount - 1); + + if (spancountminus1 > 0) + { + u += spancountminus1; + D_Sky_uv_To_st (u, v, &snext, &tnext); + + sstep = (snext - s) / spancountminus1; + tstep = (tnext - t) / spancountminus1; + } + } + + do + { + *pdest++ = r_skysource[((t & R_SKY_TMASK) >> 8) + + ((s & R_SKY_SMASK) >> 16)]; + s += sstep; + t += tstep; + } while (--spancount > 0); + + s = snext; + t = tnext; + + } while (count > 0); + + } while ((pspan = pspan->pnext) != NULL); +} + diff --git a/r17/Revamped src/revamped_src/d_sprite.c b/r17/Revamped src/revamped_src/d_sprite.c new file mode 100755 index 00000000..7ddfc805 --- /dev/null +++ b/r17/Revamped src/revamped_src/d_sprite.c @@ -0,0 +1,442 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// d_sprite.c: software top-level rasterization driver module for drawing +// sprites + +#include "quakedef.h" +#include "d_local.h" + +static int sprite_height; +static int minindex, maxindex; +static sspan_t *sprite_spans; + +#if !id386 + +/* +===================== +D_SpriteDrawSpans +===================== +*/ +void D_SpriteDrawSpans (sspan_t *pspan) +{ + int count, spancount, izistep; + int izi; + byte *pbase, *pdest; + fixed16_t s, t, snext, tnext, sstep, tstep; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz8stepu, tdivz8stepu, zi8stepu; + byte btemp; + short *pz; + + sstep = 0; // keep compiler happy + tstep = 0; // ditto + + pbase = cacheblock; + + sdivz8stepu = d_sdivzstepu * 8; + tdivz8stepu = d_tdivzstepu * 8; + zi8stepu = d_zistepu * 8; + +// we count on FP exceptions being turned off to avoid range problems + izistep = (int)(d_zistepu * 0x8000 * 0x10000); + + do + { + pdest = (byte *)d_viewbuffer + (screenwidth * pspan->v) + pspan->u; + pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; + + count = pspan->count; + + if (count <= 0) + goto NextSpan; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + // we count on FP exceptions being turned off to avoid range problems + izi = (int)(zi * 0x8000 * 0x10000); + + s = (int)(sdivz * z) + sadjust; + if (s > bbextents) + s = bbextents; + else if (s < 0) + s = 0; + + t = (int)(tdivz * z) + tadjust; + if (t > bbextentt) + t = bbextentt; + else if (t < 0) + t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 8) + spancount = 8; + else + spancount = count; + + count -= spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz8stepu; + tdivz += tdivz8stepu; + zi += zi8stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + sstep = (snext - s) >> 3; + tstep = (tnext - t) >> 3; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + if (spancount > 1) + { + sstep = (snext - s) / (spancount - 1); + tstep = (tnext - t) / (spancount - 1); + } + } + + do + { + btemp = *(pbase + (s >> 16) + (t >> 16) * cachewidth); + if (btemp != 255) + { + if (*pz <= (izi >> 16)) + { + *pz = izi >> 16; + *pdest = btemp; + } + } + + izi += izistep; + pdest++; + pz++; + s += sstep; + t += tstep; + } while (--spancount > 0); + + s = snext; + t = tnext; + + } while (count > 0); + +NextSpan: + pspan++; + + } while (pspan->count != DS_SPAN_LIST_END); +} + +#endif + + +/* +===================== +D_SpriteScanLeftEdge +===================== +*/ +void D_SpriteScanLeftEdge (void) +{ + int i, v, itop, ibottom, lmaxindex; + emitpoint_t *pvert, *pnext; + sspan_t *pspan; + float du, dv, vtop, vbottom, slope; + fixed16_t u, u_step; + + pspan = sprite_spans; + i = minindex; + if (i == 0) + i = r_spritedesc.nump; + + lmaxindex = maxindex; + if (lmaxindex == 0) + lmaxindex = r_spritedesc.nump; + + vtop = ceilf (r_spritedesc.pverts[i].v); + + do + { + pvert = &r_spritedesc.pverts[i]; + pnext = pvert - 1; + + vbottom = ceilf (pnext->v); + + if (vtop < vbottom) + { + du = pnext->u - pvert->u; + dv = pnext->v - pvert->v; + slope = du / dv; + u_step = (int)(slope * 0x10000); + // adjust u to ceil the integer portion + u = (int)((pvert->u + (slope * (vtop - pvert->v))) * 0x10000) + + (0x10000 - 1); + itop = (int)vtop; + ibottom = (int)vbottom; + + for (v=itop ; vu = u >> 16; + pspan->v = v; + u += u_step; + pspan++; + } + } + + vtop = vbottom; + + i--; + if (i == 0) + i = r_spritedesc.nump; + + } while (i != lmaxindex); +} + + +/* +===================== +D_SpriteScanRightEdge +===================== +*/ +void D_SpriteScanRightEdge (void) +{ + int i, v, itop, ibottom; + emitpoint_t *pvert, *pnext; + sspan_t *pspan; + float du, dv, vtop, vbottom, slope, uvert, unext, vvert, vnext; + fixed16_t u, u_step; + + pspan = sprite_spans; + i = minindex; + + vvert = r_spritedesc.pverts[i].v; + if (vvert < r_refdef.fvrecty_adj) + vvert = r_refdef.fvrecty_adj; + if (vvert > r_refdef.fvrectbottom_adj) + vvert = r_refdef.fvrectbottom_adj; + + vtop = ceilf (vvert); + + do + { + pvert = &r_spritedesc.pverts[i]; + pnext = pvert + 1; + + vnext = pnext->v; + if (vnext < r_refdef.fvrecty_adj) + vnext = r_refdef.fvrecty_adj; + if (vnext > r_refdef.fvrectbottom_adj) + vnext = r_refdef.fvrectbottom_adj; + + vbottom = ceilf (vnext); + + if (vtop < vbottom) + { + uvert = pvert->u; + if (uvert < r_refdef.fvrectx_adj) + uvert = r_refdef.fvrectx_adj; + if (uvert > r_refdef.fvrectright_adj) + uvert = r_refdef.fvrectright_adj; + + unext = pnext->u; + if (unext < r_refdef.fvrectx_adj) + unext = r_refdef.fvrectx_adj; + if (unext > r_refdef.fvrectright_adj) + unext = r_refdef.fvrectright_adj; + + du = unext - uvert; + dv = vnext - vvert; + slope = du / dv; + u_step = (int)(slope * 0x10000); + // adjust u to ceil the integer portion + u = (int)((uvert + (slope * (vtop - vvert))) * 0x10000) + + (0x10000 - 1); + itop = (int)vtop; + ibottom = (int)vbottom; + + for (v=itop ; vcount = (u >> 16) - pspan->u; + u += u_step; + pspan++; + } + } + + vtop = vbottom; + vvert = vnext; + + i++; + if (i == r_spritedesc.nump) + i = 0; + + } while (i != maxindex); + + pspan->count = DS_SPAN_LIST_END; // mark the end of the span list +} + + +/* +===================== +D_SpriteCalculateGradients +===================== +*/ +void D_SpriteCalculateGradients (void) +{ + vec3_t p_normal, p_saxis, p_taxis, p_temp1; + float distinv; + + TransformVector (r_spritedesc.vpn, p_normal); + TransformVector (r_spritedesc.vright, p_saxis); + TransformVector (r_spritedesc.vup, p_taxis); + VectorInverse (p_taxis); + + distinv = 1.0 / (-DotProduct (modelorg, r_spritedesc.vpn)); + + d_sdivzstepu = p_saxis[0] * xscaleinv; + d_tdivzstepu = p_taxis[0] * xscaleinv; + + d_sdivzstepv = -p_saxis[1] * yscaleinv; + d_tdivzstepv = -p_taxis[1] * yscaleinv; + + d_zistepu = p_normal[0] * xscaleinv * distinv; + d_zistepv = -p_normal[1] * yscaleinv * distinv; + + d_sdivzorigin = p_saxis[2] - xcenter * d_sdivzstepu - + ycenter * d_sdivzstepv; + d_tdivzorigin = p_taxis[2] - xcenter * d_tdivzstepu - + ycenter * d_tdivzstepv; + d_ziorigin = p_normal[2] * distinv - xcenter * d_zistepu - + ycenter * d_zistepv; + + TransformVector (modelorg, p_temp1); + + sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) - + (-(cachewidth >> 1) << 16); + tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) - + (-(sprite_height >> 1) << 16); + +// -1 (-epsilon) so we never wander off the edge of the texture + bbextents = (cachewidth << 16) - 1; + bbextentt = (sprite_height << 16) - 1; +} + + +/* +===================== +D_DrawSprite +===================== +*/ +void D_DrawSprite (void) +{ + int i, nump; + float ymin, ymax; + emitpoint_t *pverts; + sspan_t spans[MAXHEIGHT+1]; + + sprite_spans = spans; + +// find the top and bottom vertices, and make sure there's at least one scan to +// draw + ymin = 999999.9; + ymax = -999999.9; + pverts = r_spritedesc.pverts; + + for (i=0 ; iv < ymin) + { + ymin = pverts->v; + minindex = i; + } + + if (pverts->v > ymax) + { + ymax = pverts->v; + maxindex = i; + } + + pverts++; + } + + ymin = ceilf (ymin); + ymax = ceilf (ymax); + + if (ymin >= ymax) + return; // doesn't cross any scans at all + + cachewidth = r_spritedesc.pspriteframe->width; + sprite_height = r_spritedesc.pspriteframe->height; + cacheblock = (byte *)&r_spritedesc.pspriteframe->pixels[0]; + +// copy the first vertex to the last vertex, so we don't have to deal with +// wrapping + nump = r_spritedesc.nump; + pverts = r_spritedesc.pverts; + pverts[nump] = pverts[0]; + + D_SpriteCalculateGradients (); + D_SpriteScanLeftEdge (); + D_SpriteScanRightEdge (); + D_SpriteDrawSpans (sprite_spans); +} + diff --git a/r17/Revamped src/revamped_src/d_surf.c b/r17/Revamped src/revamped_src/d_surf.c new file mode 100755 index 00000000..ac3d8442 --- /dev/null +++ b/r17/Revamped src/revamped_src/d_surf.c @@ -0,0 +1,335 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// d_surf.c: rasterization driver surface heap manager + +#include "quakedef.h" +#include "d_local.h" +#include "r_local.h" + +float surfscale; +qboolean r_cache_thrash; // set if surface cache is thrashing + +int sc_size; +surfcache_t *sc_rover, *sc_base; + +#define GUARDSIZE 4 + + +int D_SurfaceCacheForRes (int width, int height) +{ + int size, pix; + + if (COM_CheckParm ("-surfcachesize")) + { + size = Q_atoi(com_argv[COM_CheckParm("-surfcachesize")+1]) * 1024; + return size; + } + + size = SURFCACHE_SIZE_AT_320X200; + + pix = width*height; + if (pix > 64000) + size += (pix-64000)*3; + + + return size; +} + +void D_CheckCacheGuard (void) +{ + byte *s; + int i; + + s = (byte *)sc_base + sc_size; + for (i=0 ; inext = NULL; + sc_base->owner = NULL; + sc_base->size = sc_size; + + D_ClearCacheGuard (); +} + + +/* +================== +D_FlushCaches +================== +*/ +void D_FlushCaches (void) +{ + surfcache_t *c; + + if (!sc_base) + return; + + for (c = sc_base ; c ; c = c->next) + { + if (c->owner) + *c->owner = NULL; + } + + sc_rover = sc_base; + sc_base->next = NULL; + sc_base->owner = NULL; + sc_base->size = sc_size; +} + +/* +================= +D_SCAlloc +================= +*/ +surfcache_t *D_SCAlloc (int width, int size) +{ + surfcache_t *new; + qboolean wrapped_this_time; + + if ((width < 0) || (width > 256)) + Sys_Error ("D_SCAlloc: bad cache width %d\n", width); + + if ((size <= 0) || (size > 0x10000)) + Sys_Error ("D_SCAlloc: bad cache size %d\n", size); + + size = (int)&((surfcache_t *)0)->data[size]; + size = (size + 3) & ~3; + if (size > sc_size) + Sys_Error ("D_SCAlloc: %i > cache size",size); + +// if there is not size bytes after the rover, reset to the start + wrapped_this_time = false; + + if ( !sc_rover || (byte *)sc_rover - (byte *)sc_base > sc_size - size) + { + if (sc_rover) + { + wrapped_this_time = true; + } + sc_rover = sc_base; + } + +// colect and free surfcache_t blocks until the rover block is large enough + new = sc_rover; + if (sc_rover->owner) + *sc_rover->owner = NULL; + + while (new->size < size) + { + // free another + sc_rover = sc_rover->next; + if (!sc_rover) + Sys_Error ("D_SCAlloc: hit the end of memory"); + if (sc_rover->owner) + *sc_rover->owner = NULL; + + new->size += sc_rover->size; + new->next = sc_rover->next; + } + +// create a fragment out of any leftovers + if (new->size - size > 256) + { + sc_rover = (surfcache_t *)( (byte *)new + size); + sc_rover->size = new->size - size; + sc_rover->next = new->next; + sc_rover->width = 0; + sc_rover->owner = NULL; + new->next = sc_rover; + new->size = size; + } + else + sc_rover = new->next; + + new->width = width; +// DEBUG + if (width > 0) + new->height = (size - sizeof(*new) + sizeof(new->data)) / width; + + new->owner = NULL; // should be set properly after return + + if (d_roverwrapped) + { + if (wrapped_this_time || (sc_rover >= d_initial_rover)) + r_cache_thrash = true; + } + else if (wrapped_this_time) + { + d_roverwrapped = true; + } + +D_CheckCacheGuard (); // DEBUG + return new; +} + + +/* +================= +D_SCDump +================= +*/ +void D_SCDump (void) +{ + surfcache_t *test; + + for (test = sc_base ; test ; test = test->next) + { + if (test == sc_rover) + Sys_Printf ("ROVER:\n"); + printf ("%p : %i bytes %i width\n",test, test->size, test->width); + } +} + +//============================================================================= + +// if the num is not a power of 2, assume it will not repeat + +int MaskForNum (int num) +{ + if (num==128) + return 127; + if (num==64) + return 63; + if (num==32) + return 31; + if (num==16) + return 15; + return 255; +} + +int D_log2 (int num) +{ + int c; + + c = 0; + + while (num>>=1) + c++; + return c; +} + +//============================================================================= + +/* +================ +D_CacheSurface +================ +*/ +surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel) +{ + surfcache_t *cache; + +// +// if the surface is animating or flashing, flush the cache +// + r_drawsurf.texture = R_TextureAnimation (surface->texinfo->texture); + r_drawsurf.lightadj[0] = d_lightstylevalue[surface->styles[0]]; + r_drawsurf.lightadj[1] = d_lightstylevalue[surface->styles[1]]; + r_drawsurf.lightadj[2] = d_lightstylevalue[surface->styles[2]]; + r_drawsurf.lightadj[3] = d_lightstylevalue[surface->styles[3]]; + +// +// see if the cache holds apropriate data +// + cache = surface->cachespots[miplevel]; + + if (cache && !cache->dlight && surface->dlightframe != r_framecount + && cache->texture == r_drawsurf.texture + && cache->lightadj[0] == r_drawsurf.lightadj[0] + && cache->lightadj[1] == r_drawsurf.lightadj[1] + && cache->lightadj[2] == r_drawsurf.lightadj[2] + && cache->lightadj[3] == r_drawsurf.lightadj[3] ) + return cache; + +// +// determine shape of surface +// + surfscale = 1.0 / (1<extents[0] >> miplevel; + r_drawsurf.rowbytes = r_drawsurf.surfwidth; + r_drawsurf.surfheight = surface->extents[1] >> miplevel; + +// +// allocate memory if needed +// + if (!cache) // if a texture just animated, don't reallocate it + { + cache = D_SCAlloc (r_drawsurf.surfwidth, + r_drawsurf.surfwidth * r_drawsurf.surfheight); + surface->cachespots[miplevel] = cache; + cache->owner = &surface->cachespots[miplevel]; + cache->mipscale = surfscale; + } + + if (surface->dlightframe == r_framecount) + cache->dlight = 1; + else + cache->dlight = 0; + + r_drawsurf.surfdat = (pixel_t *)cache->data; + + cache->texture = r_drawsurf.texture; + cache->lightadj[0] = r_drawsurf.lightadj[0]; + cache->lightadj[1] = r_drawsurf.lightadj[1]; + cache->lightadj[2] = r_drawsurf.lightadj[2]; + cache->lightadj[3] = r_drawsurf.lightadj[3]; + +// +// draw and light the surface texture +// + r_drawsurf.surf = surface; + + c_surf++; + R_DrawSurface (); + + return surface->cachespots[miplevel]; +} + + diff --git a/r17/Revamped src/revamped_src/d_vars.c b/r17/Revamped src/revamped_src/d_vars.c new file mode 100755 index 00000000..38dbf33e --- /dev/null +++ b/r17/Revamped src/revamped_src/d_vars.c @@ -0,0 +1,50 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// r_vars.c: global refresh variables + +#if !id386 + +#include "quakedef.h" + +// all global and static refresh variables are collected in a contiguous block +// to avoid cache conflicts. + +//------------------------------------------------------- +// global refresh variables +//------------------------------------------------------- + +// FIXME: make into one big structure, like cl or sv +// FIXME: do separately for refresh engine and driver + +float d_sdivzstepu, d_tdivzstepu, d_zistepu; +float d_sdivzstepv, d_tdivzstepv, d_zistepv; +float d_sdivzorigin, d_tdivzorigin, d_ziorigin; + +fixed16_t sadjust, tadjust, bbextents, bbextentt; + +pixel_t *cacheblock; +int cachewidth; +pixel_t *d_viewbuffer; +short *d_pzbuffer; +unsigned int d_zrowbytes; +unsigned int d_zwidth; + +#endif // !id386 + diff --git a/r17/Revamped src/revamped_src/d_zpoint.c b/r17/Revamped src/revamped_src/d_zpoint.c new file mode 100755 index 00000000..4c38acf7 --- /dev/null +++ b/r17/Revamped src/revamped_src/d_zpoint.c @@ -0,0 +1,47 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// d_zpoint.c: software driver module for drawing z-buffered points + +#include "quakedef.h" +#include "d_local.h" + + +/* +===================== +D_DrawZPoint +===================== +*/ +void D_DrawZPoint (void) +{ + byte *pdest; + short *pz; + int izi; + + pz = d_pzbuffer + (d_zwidth * r_zpointdesc.v) + r_zpointdesc.u; + pdest = d_viewbuffer + d_scantable[r_zpointdesc.v] + r_zpointdesc.u; + izi = (int)(r_zpointdesc.zi * 0x8000); + + if (*pz <= izi) + { + *pz = izi; + *pdest = r_zpointdesc.color; + } +} + diff --git a/r17/Revamped src/revamped_src/draw.c b/r17/Revamped src/revamped_src/draw.c new file mode 100755 index 00000000..5c743ab2 --- /dev/null +++ b/r17/Revamped src/revamped_src/draw.c @@ -0,0 +1,911 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +// draw.c -- this is the only file outside the refresh that touches the +// vid buffer + +#include "quakedef.h" + +typedef struct { + vrect_t rect; + int width; + int height; + byte *ptexbytes; + int rowbytes; +} rectdesc_t; + +static rectdesc_t r_rectdesc; + +byte *draw_chars; // 8*8 graphic characters +qpic_t *draw_disc; +qpic_t *draw_backtile; + +//============================================================================= +/* Support Routines */ + +typedef struct cachepic_s +{ + char name[MAX_QPATH]; + cache_user_t cache; +} cachepic_t; + +#define MAX_CACHED_PICS 128 +cachepic_t menu_cachepics[MAX_CACHED_PICS]; +int menu_numcachepics; + + +qpic_t *Draw_PicFromWad (char *name) +{ + return W_GetLumpName (name); +} + +/* +================ +Draw_CachePic +================ +*/ +qpic_t *Draw_CachePic (char *path) +{ + cachepic_t *pic; + int i; + qpic_t *dat; + + for (pic=menu_cachepics, i=0 ; iname)) + break; + + if (i == menu_numcachepics) + { + if (menu_numcachepics == MAX_CACHED_PICS) + Sys_Error ("menu_numcachepics == MAX_CACHED_PICS"); + menu_numcachepics++; + strcpy (pic->name, path); + } + + dat = Cache_Check (&pic->cache); + + if (dat) + return dat; + +// +// load the pic from disk +// + COM_LoadCacheFile (path, &pic->cache); + + dat = (qpic_t *)pic->cache.data; + if (!dat) + { + Sys_Error ("Draw_CachePic: failed to load %s", path); + } + + SwapPic (dat); + + return dat; +} + + + +/* +=============== +Draw_Init +=============== +*/ +void Draw_Init (void) +{ + draw_chars = W_GetLumpName ("conchars"); + draw_disc = W_GetLumpName ("disc"); + draw_backtile = W_GetLumpName ("backtile"); + + r_rectdesc.width = draw_backtile->width; + r_rectdesc.height = draw_backtile->height; + r_rectdesc.ptexbytes = draw_backtile->data; + r_rectdesc.rowbytes = draw_backtile->width; +} + + + +/* +================ +Draw_Character + +Draws one 8*8 graphics character with 0 being transparent. +It can be clipped to the top of the screen to allow the console to be +smoothly scrolled off. +================ +*/ +void Draw_Character (int x, int y, int num) +{ + byte *dest; + byte *source; + unsigned short *pusdest; + int drawline; + int row, col; + + num &= 255; + + if (y <= -8) + return; // totally off screen + +#ifdef PARANOID + if (y > vid.height - 8 || x < 0 || x > vid.width - 8) + Sys_Error ("Con_DrawCharacter: (%i, %i)", x, y); + if (num < 0 || num > 255) + Sys_Error ("Con_DrawCharacter: char %i", num); +#endif + + row = num>>4; + col = num&15; + source = draw_chars + (row<<10) + (col<<3); + + if (y < 0) + { // clipped + drawline = 8 + y; + source -= 128*y; + y = 0; + } + else + drawline = 8; + + + if (r_pixbytes == 1) + { + dest = vid.conbuffer + y*vid.conrowbytes + x; + + while (drawline--) + { + if (source[0]) + dest[0] = source[0]; + if (source[1]) + dest[1] = source[1]; + if (source[2]) + dest[2] = source[2]; + if (source[3]) + dest[3] = source[3]; + if (source[4]) + dest[4] = source[4]; + if (source[5]) + dest[5] = source[5]; + if (source[6]) + dest[6] = source[6]; + if (source[7]) + dest[7] = source[7]; + source += 128; + dest += vid.conrowbytes; + } + } + else + { + // FIXME: pre-expand to native format? + pusdest = (unsigned short *) + ((byte *)vid.conbuffer + y*vid.conrowbytes + (x<<1)); + + while (drawline--) + { + if (source[0]) + pusdest[0] = d_8to16table[source[0]]; + if (source[1]) + pusdest[1] = d_8to16table[source[1]]; + if (source[2]) + pusdest[2] = d_8to16table[source[2]]; + if (source[3]) + pusdest[3] = d_8to16table[source[3]]; + if (source[4]) + pusdest[4] = d_8to16table[source[4]]; + if (source[5]) + pusdest[5] = d_8to16table[source[5]]; + if (source[6]) + pusdest[6] = d_8to16table[source[6]]; + if (source[7]) + pusdest[7] = d_8to16table[source[7]]; + + source += 128; + pusdest += (vid.conrowbytes >> 1); + } + } +} + +/* +================ +Draw_String +================ +*/ +void Draw_String (int x, int y, char *str) +{ + while (*str) + { + Draw_Character (x, y, *str); + str++; + x += 8; + } +} + +/* +================ +Draw_DebugChar + +Draws a single character directly to the upper right corner of the screen. +This is for debugging lockups by drawing different chars in different parts +of the code. +================ +*/ +void Draw_DebugChar (char num) +{ + byte *dest; + byte *source; + int drawline; + extern byte *draw_chars; + int row, col; + + if (!vid.direct) + return; // don't have direct FB access, so no debugchars... + + drawline = 8; + + row = num>>4; + col = num&15; + source = draw_chars + (row<<10) + (col<<3); + + dest = vid.direct + 312; + + while (drawline--) + { + dest[0] = source[0]; + dest[1] = source[1]; + dest[2] = source[2]; + dest[3] = source[3]; + dest[4] = source[4]; + dest[5] = source[5]; + dest[6] = source[6]; + dest[7] = source[7]; + source += 128; + dest += 320; + } +} + +/* +============= +Draw_Pic +============= +*/ +void Draw_Pic (int x, int y, qpic_t *pic) +{ + byte *dest, *source; + unsigned short *pusdest; + int v, u; + + if ((x < 0) || + (x + pic->width > vid.width) || + (y < 0) || + (y + pic->height > vid.height)) + { + Sys_Error ("Draw_Pic: bad coordinates"); + } + + source = pic->data; + + if (r_pixbytes == 1) + { + dest = vid.buffer + y * vid.rowbytes + x; + + for (v=0 ; vheight ; v++) + { + Q_memcpy (dest, source, pic->width); + dest += vid.rowbytes; + source += pic->width; + } + } + else + { + // FIXME: pretranslate at load time? + pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; + + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u++) + { + pusdest[u] = d_8to16table[source[u]]; + } + + pusdest += vid.rowbytes >> 1; + source += pic->width; + } + } +} + + +/* +============= +Draw_TransPic +============= +*/ +void Draw_TransPic (int x, int y, qpic_t *pic) +{ + byte *dest, *source, tbyte; + unsigned short *pusdest; + int v, u; + + if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 || + (unsigned)(y + pic->height) > vid.height) + { + Sys_Error ("Draw_TransPic: bad coordinates"); + } + + source = pic->data; + + if (r_pixbytes == 1) + { + dest = vid.buffer + y * vid.rowbytes + x; + + if (pic->width & 7) + { // general + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u++) + if ( (tbyte=source[u]) != TRANSPARENT_COLOR) + dest[u] = tbyte; + + dest += vid.rowbytes; + source += pic->width; + } + } + else + { // unwound + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u+=8) + { + if ( (tbyte=source[u]) != TRANSPARENT_COLOR) + dest[u] = tbyte; + if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR) + dest[u+1] = tbyte; + if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR) + dest[u+2] = tbyte; + if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR) + dest[u+3] = tbyte; + if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR) + dest[u+4] = tbyte; + if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR) + dest[u+5] = tbyte; + if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR) + dest[u+6] = tbyte; + if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR) + dest[u+7] = tbyte; + } + dest += vid.rowbytes; + source += pic->width; + } + } + } + else + { + // FIXME: pretranslate at load time? + pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; + + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u++) + { + tbyte = source[u]; + + if (tbyte != TRANSPARENT_COLOR) + { + pusdest[u] = d_8to16table[tbyte]; + } + } + + pusdest += vid.rowbytes >> 1; + source += pic->width; + } + } +} + + +/* +============= +Draw_TransPicTranslate +============= +*/ +void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation) +{ + byte *dest, *source, tbyte; + unsigned short *pusdest; + int v, u; + + if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 || + (unsigned)(y + pic->height) > vid.height) + { + Sys_Error ("Draw_TransPic: bad coordinates"); + } + + source = pic->data; + + if (r_pixbytes == 1) + { + dest = vid.buffer + y * vid.rowbytes + x; + + if (pic->width & 7) + { // general + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u++) + if ( (tbyte=source[u]) != TRANSPARENT_COLOR) + dest[u] = translation[tbyte]; + + dest += vid.rowbytes; + source += pic->width; + } + } + else + { // unwound + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u+=8) + { + if ( (tbyte=source[u]) != TRANSPARENT_COLOR) + dest[u] = translation[tbyte]; + if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR) + dest[u+1] = translation[tbyte]; + if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR) + dest[u+2] = translation[tbyte]; + if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR) + dest[u+3] = translation[tbyte]; + if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR) + dest[u+4] = translation[tbyte]; + if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR) + dest[u+5] = translation[tbyte]; + if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR) + dest[u+6] = translation[tbyte]; + if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR) + dest[u+7] = translation[tbyte]; + } + dest += vid.rowbytes; + source += pic->width; + } + } + } + else + { + // FIXME: pretranslate at load time? + pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; + + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u++) + { + tbyte = source[u]; + + if (tbyte != TRANSPARENT_COLOR) + { + pusdest[u] = d_8to16table[tbyte]; + } + } + + pusdest += vid.rowbytes >> 1; + source += pic->width; + } + } +} + + +void Draw_CharToConback (int num, byte *dest) +{ + int row, col; + byte *source; + int drawline; + int x; + + row = num>>4; + col = num&15; + source = draw_chars + (row<<10) + (col<<3); + + drawline = 8; + + while (drawline--) + { + for (x=0 ; x<8 ; x++) + if (source[x]) + dest[x] = 0x60 + source[x]; + source += 128; + dest += 320; + } + +} + +/* +================ +Draw_ConsoleBackground + +================ +*/ +void Draw_ConsoleBackground (int lines) +{ + int x, y, v; + byte *src, *dest; + unsigned short *pusdest; + int f, fstep; + qpic_t *conback; + char ver[100]; + + conback = Draw_CachePic ("gfx/conback.lmp"); + +// hack the version number directly into the pic +#ifdef _WIN32 + sprintf (ver, "(WinQuake) %4.2f", (float)VERSION); + dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); +#elif defined(X11) + sprintf (ver, "(X11 Quake %2.2f) %4.2f", (float)X11_VERSION, (float)VERSION); + dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); +#elif defined(__linux__) + sprintf (ver, "(Linux Quake %2.2f) %4.2f", (float)LINUX_VERSION, (float)VERSION); + dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); +#else + dest = conback->data + 320 - 43 + 320*186; + sprintf (ver, "%4.2f", VERSION); +#endif + + for (x=0 ; xdata + v*320; + if (vid.conwidth == 320) + memcpy (dest, src, vid.conwidth); + else + { + f = 0; + fstep = 320*0x10000/vid.conwidth; + for (x=0 ; x>16]; + f += fstep; + dest[x+1] = src[f>>16]; + f += fstep; + dest[x+2] = src[f>>16]; + f += fstep; + dest[x+3] = src[f>>16]; + f += fstep; + } + } + } + } + else + { + pusdest = (unsigned short *)vid.conbuffer; + + for (y=0 ; y> 1)) + { + // FIXME: pre-expand to native format? + // FIXME: does the endian switching go away in production? + v = (vid.conheight - lines + y)*200/vid.conheight; + src = conback->data + v*320; + f = 0; + fstep = 320*0x10000/vid.conwidth; + for (x=0 ; x>16]]; + f += fstep; + pusdest[x+1] = d_8to16table[src[f>>16]]; + f += fstep; + pusdest[x+2] = d_8to16table[src[f>>16]]; + f += fstep; + pusdest[x+3] = d_8to16table[src[f>>16]]; + f += fstep; + } + } + } +} + + +/* +============== +R_DrawRect8 +============== +*/ +void R_DrawRect8 (vrect_t *prect, int rowbytes, byte *psrc, + int transparent) +{ + byte t; + int i, j, srcdelta, destdelta; + byte *pdest; + + pdest = vid.buffer + (prect->y * vid.rowbytes) + prect->x; + + srcdelta = rowbytes - prect->width; + destdelta = vid.rowbytes - prect->width; + + if (transparent) + { + for (i=0 ; iheight ; i++) + { + for (j=0 ; jwidth ; j++) + { + t = *psrc; + if (t != TRANSPARENT_COLOR) + { + *pdest = t; + } + + psrc++; + pdest++; + } + + psrc += srcdelta; + pdest += destdelta; + } + } + else + { + for (i=0 ; iheight ; i++) + { + memcpy (pdest, psrc, prect->width); + psrc += rowbytes; + pdest += vid.rowbytes; + } + } +} + + +/* +============== +R_DrawRect16 +============== +*/ +void R_DrawRect16 (vrect_t *prect, int rowbytes, byte *psrc, + int transparent) +{ + byte t; + int i, j, srcdelta, destdelta; + unsigned short *pdest; + +// FIXME: would it be better to pre-expand native-format versions? + + pdest = (unsigned short *)vid.buffer + + (prect->y * (vid.rowbytes >> 1)) + prect->x; + + srcdelta = rowbytes - prect->width; + destdelta = (vid.rowbytes >> 1) - prect->width; + + if (transparent) + { + for (i=0 ; iheight ; i++) + { + for (j=0 ; jwidth ; j++) + { + t = *psrc; + if (t != TRANSPARENT_COLOR) + { + *pdest = d_8to16table[t]; + } + + psrc++; + pdest++; + } + + psrc += srcdelta; + pdest += destdelta; + } + } + else + { + for (i=0 ; iheight ; i++) + { + for (j=0 ; jwidth ; j++) + { + *pdest = d_8to16table[*psrc]; + psrc++; + pdest++; + } + + psrc += srcdelta; + pdest += destdelta; + } + } +} + + +/* +============= +Draw_TileClear + +This repeats a 64*64 tile graphic to fill the screen around a sized down +refresh window. +============= +*/ +void Draw_TileClear (int x, int y, int w, int h) +{ + int width, height, tileoffsetx, tileoffsety; + byte *psrc; + vrect_t vr; + + r_rectdesc.rect.x = x; + r_rectdesc.rect.y = y; + r_rectdesc.rect.width = w; + r_rectdesc.rect.height = h; + + vr.y = r_rectdesc.rect.y; + height = r_rectdesc.rect.height; + + tileoffsety = vr.y % r_rectdesc.height; + + while (height > 0) + { + vr.x = r_rectdesc.rect.x; + width = r_rectdesc.rect.width; + + if (tileoffsety != 0) + vr.height = r_rectdesc.height - tileoffsety; + else + vr.height = r_rectdesc.height; + + if (vr.height > height) + vr.height = height; + + tileoffsetx = vr.x % r_rectdesc.width; + + while (width > 0) + { + if (tileoffsetx != 0) + vr.width = r_rectdesc.width - tileoffsetx; + else + vr.width = r_rectdesc.width; + + if (vr.width > width) + vr.width = width; + + psrc = r_rectdesc.ptexbytes + + (tileoffsety * r_rectdesc.rowbytes) + tileoffsetx; + + if (r_pixbytes == 1) + { + R_DrawRect8 (&vr, r_rectdesc.rowbytes, psrc, 0); + } + else + { + R_DrawRect16 (&vr, r_rectdesc.rowbytes, psrc, 0); + } + + vr.x += vr.width; + width -= vr.width; + tileoffsetx = 0; // only the left tile can be left-clipped + } + + vr.y += vr.height; + height -= vr.height; + tileoffsety = 0; // only the top tile can be top-clipped + } +} + + +/* +============= +Draw_Fill + +Fills a box of pixels with a single color +============= +*/ +void Draw_Fill (int x, int y, int w, int h, int c) +{ + byte *dest; + unsigned short *pusdest; + unsigned uc; + int u, v; + + if (r_pixbytes == 1) + { + dest = vid.buffer + y*vid.rowbytes + x; + for (v=0 ; v> 1) + x; + for (v=0 ; v> 1)) + for (u=0 ; udata, 24, 24); +} + + +/* +================ +Draw_EndDisc + +Erases the disc icon. +Call after completing any disc IO +================ +*/ +void Draw_EndDisc (void) +{ + + D_EndDirectRect (vid.width - 24, 0, 24, 24); +} + diff --git a/r17/Revamped src/revamped_src/draw.h b/r17/Revamped src/revamped_src/draw.h new file mode 100755 index 00000000..d9386969 --- /dev/null +++ b/r17/Revamped src/revamped_src/draw.h @@ -0,0 +1,43 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +// draw.h -- these are the only functions outside the refresh allowed +// to touch the vid buffer + +extern qpic_t *draw_disc; // also used on sbar + +void Draw_Init (void); +void Draw_Character (int x, int y, int num); +void Draw_DebugChar (char num); +void Draw_Pic (int x, int y, qpic_t *pic); +void Draw_TransPic (int x, int y, qpic_t *pic); +void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation); +void Draw_ConsoleBackground (int lines); +void Draw_BeginDisc (void); +void Draw_EndDisc (void); +void Draw_TileClear (int x, int y, int w, int h); +void Draw_Fill (int x, int y, int w, int h, int c); +void Draw_FadeScreen (void); +void Draw_FadeScreen2 (void); +void Draw_FadeScreenColor (float r, float g, float b, float a); +void Draw_String (int x, int y, char *str); +void Draw_Crosshair(void); +qpic_t *Draw_PicFromWad (char *name); +qpic_t *Draw_CachePic (char *path); diff --git a/r17/Revamped src/revamped_src/gl_warp_sin.h b/r17/Revamped src/revamped_src/gl_warp_sin.h new file mode 100755 index 00000000..fa3e62a8 --- /dev/null +++ b/r17/Revamped src/revamped_src/gl_warp_sin.h @@ -0,0 +1,51 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + 0, 0.19633, 0.392541, 0.588517, 0.784137, 0.979285, 1.17384, 1.3677, + 1.56072, 1.75281, 1.94384, 2.1337, 2.32228, 2.50945, 2.69512, 2.87916, + 3.06147, 3.24193, 3.42044, 3.59689, 3.77117, 3.94319, 4.11282, 4.27998, + 4.44456, 4.60647, 4.76559, 4.92185, 5.07515, 5.22538, 5.37247, 5.51632, + 5.65685, 5.79398, 5.92761, 6.05767, 6.18408, 6.30677, 6.42566, 6.54068, + 6.65176, 6.75883, 6.86183, 6.9607, 7.05537, 7.14579, 7.23191, 7.31368, + 7.39104, 7.46394, 7.53235, 7.59623, 7.65552, 7.71021, 7.76025, 7.80562, + 7.84628, 7.88222, 7.91341, 7.93984, 7.96148, 7.97832, 7.99036, 7.99759, + 8, 7.99759, 7.99036, 7.97832, 7.96148, 7.93984, 7.91341, 7.88222, + 7.84628, 7.80562, 7.76025, 7.71021, 7.65552, 7.59623, 7.53235, 7.46394, + 7.39104, 7.31368, 7.23191, 7.14579, 7.05537, 6.9607, 6.86183, 6.75883, + 6.65176, 6.54068, 6.42566, 6.30677, 6.18408, 6.05767, 5.92761, 5.79398, + 5.65685, 5.51632, 5.37247, 5.22538, 5.07515, 4.92185, 4.76559, 4.60647, + 4.44456, 4.27998, 4.11282, 3.94319, 3.77117, 3.59689, 3.42044, 3.24193, + 3.06147, 2.87916, 2.69512, 2.50945, 2.32228, 2.1337, 1.94384, 1.75281, + 1.56072, 1.3677, 1.17384, 0.979285, 0.784137, 0.588517, 0.392541, 0.19633, + 9.79717e-16, -0.19633, -0.392541, -0.588517, -0.784137, -0.979285, -1.17384, -1.3677, + -1.56072, -1.75281, -1.94384, -2.1337, -2.32228, -2.50945, -2.69512, -2.87916, + -3.06147, -3.24193, -3.42044, -3.59689, -3.77117, -3.94319, -4.11282, -4.27998, + -4.44456, -4.60647, -4.76559, -4.92185, -5.07515, -5.22538, -5.37247, -5.51632, + -5.65685, -5.79398, -5.92761, -6.05767, -6.18408, -6.30677, -6.42566, -6.54068, + -6.65176, -6.75883, -6.86183, -6.9607, -7.05537, -7.14579, -7.23191, -7.31368, + -7.39104, -7.46394, -7.53235, -7.59623, -7.65552, -7.71021, -7.76025, -7.80562, + -7.84628, -7.88222, -7.91341, -7.93984, -7.96148, -7.97832, -7.99036, -7.99759, + -8, -7.99759, -7.99036, -7.97832, -7.96148, -7.93984, -7.91341, -7.88222, + -7.84628, -7.80562, -7.76025, -7.71021, -7.65552, -7.59623, -7.53235, -7.46394, + -7.39104, -7.31368, -7.23191, -7.14579, -7.05537, -6.9607, -6.86183, -6.75883, + -6.65176, -6.54068, -6.42566, -6.30677, -6.18408, -6.05767, -5.92761, -5.79398, + -5.65685, -5.51632, -5.37247, -5.22538, -5.07515, -4.92185, -4.76559, -4.60647, + -4.44456, -4.27998, -4.11282, -3.94319, -3.77117, -3.59689, -3.42044, -3.24193, + -3.06147, -2.87916, -2.69512, -2.50945, -2.32228, -2.1337, -1.94384, -1.75281, + -1.56072, -1.3677, -1.17384, -0.979285, -0.784137, -0.588517, -0.392541, -0.19633, diff --git a/r17/Revamped src/revamped_src/host.c b/r17/Revamped src/revamped_src/host.c new file mode 100755 index 00000000..a7397e9b --- /dev/null +++ b/r17/Revamped src/revamped_src/host.c @@ -0,0 +1,1018 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// host.c -- coordinates spawning and killing of local servers + +#include "quakedef.h" +#include "r_local.h" +#include "psp/module.h" + +/* + +A server can allways be started, even if the system started out as a client +to a remote system. + +A client can NOT be started if the system started as a dedicated server. + +Memory is cleared / released when a server or client begins, not when they end. + +*/ + +quakeparms_t host_parms; + +qboolean host_initialized; // true if into command execution + +double host_frametime; +double host_time; +double realtime; // without any filtering or bounding +double oldrealtime; // last frame run +int host_framecount; +int fps_count; + +int host_hunklevel; + +int minimum_memory; + +client_t *host_client; // current client + +jmp_buf host_abortserver; + +byte *host_basepal; +byte *host_colormap; + +cvar_t show_fps = {"show_fps","0", true}; // set for running times - muff +cvar_t max_fps = {"max_fps", "65", true}; // MrG - max_fps +cvar_t host_framerate = {"host_framerate","0"}; // set for slow motion +cvar_t host_speeds = {"host_speeds","0"}; // set for running times + +cvar_t sys_ticrate = {"sys_ticrate","0.05"}; +cvar_t serverprofile = {"serverprofile","0"}; + +cvar_t fraglimit = {"fraglimit","15",false,true}; +cvar_t timelimit = {"timelimit","15",false,true}; +cvar_t teamplay = {"teamplay","0",false,true}; + +cvar_t samelevel = {"samelevel","0"}; +cvar_t noexit = {"noexit","0",false,true}; + +#ifdef QUAKE2 +cvar_t developer = {"developer","1"}; // should be 0 for release! +#else +cvar_t developer = {"developer","0"}; +#endif + +cvar_t skill = {"skill","1"}; // 0 - 3 +cvar_t deathmatch = {"deathmatch","0"}; // 0, 1, or 2 +cvar_t coop = {"coop","0"}; // 0 or 1 + +cvar_t pausable = {"pausable","1"}; + +cvar_t temp1 = {"temp1","0"}; + +qboolean bmg_type_changed = false; + + +/* +================ +Host_EndGame +================ +*/ +void Host_EndGame (char *message, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr,message); + vsprintf (string,message,argptr); + va_end (argptr); + Con_DPrintf ("Host_EndGame: %s\n",string); + + if (sv.active) + Host_ShutdownServer (false); + + if (cls.state == ca_dedicated) + Sys_Error ("Host_EndGame: %s\n",string); // dedicated servers exit + + if (cls.demonum != -1) + CL_NextDemo (); + else + CL_Disconnect (); + + longjmp (host_abortserver, 1); +} + +/* +================ +Host_Error + +This shuts down both the client and server +================ +*/ +void Host_Error (char *error, ...) +{ + va_list argptr; + char string[1024]; + static qboolean inerror = false; + + if (inerror) + Sys_Error ("Host_Error: recursively entered"); + inerror = true; + + SCR_EndLoadingPlaque (); // reenable screen updates + + va_start (argptr,error); + vsprintf (string,error,argptr); + va_end (argptr); + Con_Printf ("Host_Error: %s\n",string); + + if (sv.active) + Host_ShutdownServer (false); + + if (cls.state == ca_dedicated) + Sys_Error ("Host_Error: %s\n",string); // dedicated servers exit + + CL_Disconnect (); + cls.demonum = -1; + + inerror = false; + + longjmp (host_abortserver, 1); +} + +/* +================ +Host_FindMaxClients +================ +*/ +void Host_FindMaxClients (void) +{ + int i; + + svs.maxclients = 1; + + i = COM_CheckParm ("-dedicated"); + if (i) + { + cls.state = ca_dedicated; + if (i != (com_argc - 1)) + { + svs.maxclients = Q_atoi (com_argv[i+1]); + } + else + svs.maxclients = 8; + } + else + cls.state = ca_disconnected; + + i = COM_CheckParm ("-listen"); + if (i) + { + if (cls.state == ca_dedicated) + Sys_Error ("Only one of -dedicated or -listen can be specified"); + if (i != (com_argc - 1)) + svs.maxclients = Q_atoi (com_argv[i+1]); + else + svs.maxclients = 8; + } + if (svs.maxclients < 1) + svs.maxclients = 8; + else if (svs.maxclients > MAX_SCOREBOARD) + svs.maxclients = MAX_SCOREBOARD; + + svs.maxclientslimit = svs.maxclients; + if (svs.maxclientslimit < 4) + svs.maxclientslimit = 4; + svs.clients = Hunk_AllocName (svs.maxclientslimit*sizeof(client_t), "clients"); + + if (svs.maxclients > 1) + { + if (deathmatch.value > 1) + Cvar_SetValue ("deathmatch", deathmatch.value); + else + Cvar_SetValue ("deathmatch", 1.0); + } + else + Cvar_SetValue ("deathmatch", 0.0); +} + + +/* +======================= +Host_InitLocal +====================== +*/ +void Host_InitLocal (void) +{ + Host_InitCommands (); + + Cvar_RegisterVariable (&show_fps); // muff + Cvar_RegisterVariable (&max_fps); // MrG - max_fps + Cvar_RegisterVariable (&host_framerate); + Cvar_RegisterVariable (&host_speeds); + + Cvar_RegisterVariable (&sys_ticrate); + Cvar_RegisterVariable (&serverprofile); + + Cvar_RegisterVariable (&fraglimit); + Cvar_RegisterVariable (&timelimit); + Cvar_RegisterVariable (&teamplay); + Cvar_RegisterVariable (&samelevel); + Cvar_RegisterVariable (&noexit); + Cvar_RegisterVariable (&skill); + Cvar_RegisterVariable (&developer); + Cvar_RegisterVariable (&deathmatch); + Cvar_RegisterVariable (&coop); + + Cvar_RegisterVariable (&pausable); + + Cvar_RegisterVariable (&temp1); + + Host_FindMaxClients (); + + host_time = 1.0; // so a think at time 0 won't get called +} + + +/* +=============== +Host_WriteConfiguration + +Writes key bindings and archived cvars to config.cfg +=============== +*/ +void Host_WriteConfiguration (void) +{ + FILE *f; + +// dedicated servers initialize the host but don't parse and set the +// config.cfg cvars + if (host_initialized & !isDedicated) + { + f = fopen (va("%s/config.cfg",com_gamedir), "w"); + if (!f) + { + Con_Printf ("Couldn't write config.cfg.\n"); + return; + } + + Key_WriteBindings (f); + Cvar_WriteVariables (f); + + fclose (f); + } +} + + +/* +================= +SV_ClientPrintf + +Sends text across to be displayed +FIXME: make this just a stuffed echo? +================= +*/ +void SV_ClientPrintf (char *fmt, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr,fmt); + vsprintf (string, fmt,argptr); + va_end (argptr); + + MSG_WriteByte (&host_client->message, svc_print); + MSG_WriteString (&host_client->message, string); +} + +/* +================= +SV_BroadcastPrintf + +Sends text to all active clients +================= +*/ +void SV_BroadcastPrintf (char *fmt, ...) +{ + va_list argptr; + char string[1024]; + int i; + + va_start (argptr,fmt); + vsprintf (string, fmt,argptr); + va_end (argptr); + + for (i=0 ; imessage, svc_stufftext); + MSG_WriteString (&host_client->message, string); +} + +/* +===================== +SV_DropClient + +Called when the player is getting totally kicked off the host +if (crash = true), don't bother sending signofs +===================== +*/ +void SV_DropClient (qboolean crash) +{ + int saveSelf; + int i; + client_t *client; + + if (!crash) + { + // send any final messages (don't check for errors) + if (NET_CanSendMessage (host_client->netconnection)) + { + MSG_WriteByte (&host_client->message, svc_disconnect); + NET_SendMessage (host_client->netconnection, &host_client->message); + } + + if (host_client->edict && host_client->spawned) + { + // call the prog function for removing a client + // this will set the body to a dead frame, among other things + saveSelf = pr_global_struct->self; + pr_global_struct->self = EDICT_TO_PROG(host_client->edict); + PR_ExecuteProgram (pr_global_struct->ClientDisconnect); + pr_global_struct->self = saveSelf; + } + + Sys_Printf ("Client %s removed\n",host_client->name); + } + +// break the net connection + NET_Close (host_client->netconnection); + host_client->netconnection = NULL; + +// free the client (the body stays around) + host_client->active = false; + host_client->name[0] = 0; + host_client->old_frags = -999999; + net_activeconnections--; + +// send notification to all clients + for (i=0, client = svs.clients ; iactive) + continue; + MSG_WriteByte (&client->message, svc_updatename); + MSG_WriteByte (&client->message, host_client - svs.clients); + MSG_WriteString (&client->message, ""); + MSG_WriteByte (&client->message, svc_updatefrags); + MSG_WriteByte (&client->message, host_client - svs.clients); + MSG_WriteShort (&client->message, 0); + MSG_WriteByte (&client->message, svc_updatecolors); + MSG_WriteByte (&client->message, host_client - svs.clients); + MSG_WriteByte (&client->message, 0); + } +} + +/* +================== +Host_ShutdownServer + +This only happens at the end of a game, not between levels +================== +*/ +void Host_ShutdownServer(qboolean crash) +{ + int i; + int count; + sizebuf_t buf; + char message[4]; + double start; + + if (!sv.active) + return; + + sv.active = false; + +// stop all client sounds immediately + if (cls.state == ca_connected) + CL_Disconnect (); + +// flush any pending messages - like the score!!! + start = Sys_FloatTime(); + do + { + count = 0; + for (i=0, host_client = svs.clients ; iactive && host_client->message.cursize) + { + if (NET_CanSendMessage (host_client->netconnection)) + { + NET_SendMessage(host_client->netconnection, &host_client->message); + SZ_Clear (&host_client->message); + } + else + { + NET_GetMessage(host_client->netconnection); + count++; + } + } + } + if ((Sys_FloatTime() - start) > 3.0) + break; + } + while (count); + +// make sure all the clients know we're disconnecting + buf.data = message; + buf.maxsize = 4; + buf.cursize = 0; + MSG_WriteByte(&buf, svc_disconnect); + count = NET_SendToAll(&buf, 5); + if (count) + Con_Printf("Host_ShutdownServer: NET_SendToAll failed for %u clients\n", count); + + for (i=0, host_client = svs.clients ; iactive) + SV_DropClient(crash); + +// +// clear structures +// + memset (&sv, 0, sizeof(sv)); + memset (svs.clients, 0, svs.maxclientslimit*sizeof(client_t)); +} + + +/* +================ +Host_ClearMemory + +This clears all the memory used by both the client and server, but does +not reinitialize anything. +================ +*/ +void Host_ClearMemory (void) +{ + Con_DPrintf ("Clearing memory\n"); + D_FlushCaches (); + Mod_ClearAll (); + if (host_hunklevel) + Hunk_FreeToLowMark (host_hunklevel); + + cls.signon = 0; + memset (&sv, 0, sizeof(sv)); + memset (&cl, 0, sizeof(cl)); +} + + +//============================================================================ + + +/* +=================== +Host_FilterTime + +Returns false if the time is too short to run a frame +=================== +*/ +qboolean Host_FilterTime (float time) +{ + realtime += time; + +// MrG - max_fps + + if (max_fps.value < 1) Cvar_SetValue("max_fps", 65); + if (!cls.timedemo && realtime - oldrealtime < 1.0/max_fps.value) + return false; // framerate is too high + + host_frametime = realtime - oldrealtime; + oldrealtime = realtime; + + if (host_framerate.value > 0) + host_frametime = host_framerate.value; + else + { // don't allow really long or short frames + if (host_frametime > 0.1) + host_frametime = 0.1; + if (host_frametime < 0.001) + host_frametime = 0.001; + } + + return true; +} + + +/* +=================== +Host_GetConsoleCommands + +Add them exactly as if they had been typed at the console +=================== +*/ +void Host_GetConsoleCommands (void) +{ + char *cmd; + + while (1) + { + cmd = Sys_ConsoleInput (); + if (!cmd) + break; + Cbuf_AddText (cmd); + } +} + + +/* +================== +Host_ServerFrame + +================== +*/ +#ifdef FPS_20 + +void _Host_ServerFrame (void) +{ +// run the world state + pr_global_struct->frametime = host_frametime; + +// read client messages + SV_RunClients (); + +// move things around and think +// always pause in single player if in console or menus + if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) ) + { + SV_Physics (); + + if(kurok) + { + Cvar_Set("bgmtype","cd"); + bmg_type_changed = true; + } + } + else + { + if(kurok) + { + Cvar_Set("bgmtype","none"); + bmg_type_changed = true; + } + } +} + +void Host_ServerFrame (void) +{ + float save_host_frametime; + float temp_host_frametime; + +// run the world state + pr_global_struct->frametime = host_frametime; + +// set the time and clear the general datagram + SV_ClearDatagram (); + +// check for new clients + SV_CheckForNewClients (); + + temp_host_frametime = save_host_frametime = host_frametime; + while(temp_host_frametime > (1.0/72.0)) + { + if (temp_host_frametime > 0.05) + host_frametime = 0.05; + else + host_frametime = temp_host_frametime; + temp_host_frametime -= host_frametime; + _Host_ServerFrame (); + } + host_frametime = save_host_frametime; + +// send all messages to the clients + SV_SendClientMessages (); +} + +#else + +void Host_ServerFrame (void) +{ +// run the world state + pr_global_struct->frametime = host_frametime; + +// set the time and clear the general datagram + SV_ClearDatagram (); + +// check for new clients + SV_CheckForNewClients (); + +// read client messages + SV_RunClients (); + +// move things around and think +// always pause in single player if in console or menus + if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) ) + SV_Physics (); + +// send all messages to the clients + SV_SendClientMessages (); +} + +#endif + + +/* +================== +Host_Frame + +Runs all active servers +================== +*/ +void _Host_Frame (float time) +{ + static double time1 = 0; + static double time2 = 0; + static double time3 = 0; + int pass1, pass2, pass3; + + if (setjmp (host_abortserver) ) + return; // something bad happened, or the server disconnected + +// keep the random time dependent + rand (); + +// decide the simulation time + if (!Host_FilterTime (time)) + return; // don't run too fast, or packets will flood out + +// get new key events + Sys_SendKeyEvents (); + +// allow mice or other external controllers to add commands + IN_Commands (); + +// process console commands + Cbuf_Execute (); + + NET_Poll(); + +// if running the server locally, make intentions now + if (sv.active) + CL_SendCmd (); + +//------------------- +// +// server operations +// +//------------------- + +// check for commands typed to the host + Host_GetConsoleCommands (); + + if (sv.active) + Host_ServerFrame (); + +//------------------- +// +// client operations +// +//------------------- + +// if running the server remotely, send intentions now after +// the incoming messages have been read + if (!sv.active) + CL_SendCmd (); + + host_time += host_frametime; + +// fetch results from server + if (cls.state == ca_connected) + { + CL_ReadFromServer (); + } + +// update video + if (host_speeds.value) + time1 = Sys_FloatTime (); + + SCR_UpdateScreen (); + + if (host_speeds.value) + time2 = Sys_FloatTime (); + +// update audio + if (cls.signon == SIGNONS) + { + S_Update (r_origin, vpn, vright, vup); + CL_DecayLights (); + } + else + S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin); + + if (bmg_type_changed == true) { + CDAudio_Update(); + bmg_type_changed = false; + } + + if (host_speeds.value) + { + pass1 = (time1 - time3)*1000; + time3 = Sys_FloatTime (); + pass2 = (time2 - time1)*1000; + pass3 = (time3 - time2)*1000; + Con_Printf ("%3i tot %3i server %3i gfx %3i snd\n", + pass1+pass2+pass3, pass1, pass2, pass3); + } + + host_framecount++; + //frame speed counter + fps_count++;//muff +} + +void Host_Frame (float time) +{ + double time1, time2; + static double timetotal; + static int timecount; + int i, c, m; + + if (!serverprofile.value) + { + _Host_Frame (time); + return; + } + + time1 = Sys_FloatTime (); + _Host_Frame (time); + time2 = Sys_FloatTime (); + + timetotal += time2 - time1; + timecount++; + + if (timecount < 1000) + return; + + m = timetotal*1000/timecount; + timecount = 0; + timetotal = 0; + c = 0; + for (i=0 ; iargv[0]; + for (i = 0; i < com_argc; i++) + { + Sys_FileRead (vcrFile, &len, sizeof(int)); + p = malloc(len); + Sys_FileRead (vcrFile, p, len); + com_argv[i+1] = p; + } + com_argc++; /* add one for arg[0] */ + parms->argc = com_argc; + parms->argv = com_argv; + } + + if ( (n = COM_CheckParm("-record")) != 0) + { + vcrFile = Sys_FileOpenWrite("quake.vcr"); + + i = VCR_SIGNATURE; + Sys_FileWrite(vcrFile, &i, sizeof(int)); + i = com_argc - 1; + Sys_FileWrite(vcrFile, &i, sizeof(int)); + for (i = 1; i < com_argc; i++) + { + if (i == n) + { + len = 10; + Sys_FileWrite(vcrFile, &len, sizeof(int)); + Sys_FileWrite(vcrFile, "-playback", len); + continue; + } + len = Q_strlen(com_argv[i]) + 1; + Sys_FileWrite(vcrFile, &len, sizeof(int)); + Sys_FileWrite(vcrFile, com_argv[i], len); + } + } + +} + +/* +==================== +Host_Init +==================== +*/ +void Host_Init (quakeparms_t *parms) +{ + scr_disabled_for_loading = true; + + if (standard_quake) + minimum_memory = MINIMUM_MEMORY; + else + minimum_memory = MINIMUM_MEMORY_LEVELPAK; + + if (COM_CheckParm ("-minmemory")) + parms->memsize = minimum_memory; + + host_parms = *parms; + + if (parms->memsize < minimum_memory) + Sys_Error ("Only %4.1f megs of memory available, can't execute game", parms->memsize / (float)0x100000); + + com_argc = parms->argc; + com_argv = parms->argv; + + Memory_Init (parms->membase, parms->memsize); + Cbuf_Init (); + Cmd_Init (); + V_Init (); + Chase_Init (); + Host_InitVCR (parms); + COM_Init (parms->basedir); + Host_InitLocal (); + W_LoadWadFile ("gfx.wad"); + Key_Init (); + Con_Init (); + M_Init (); + PR_Init (); + Mod_Init (); + NET_Init (); + SV_Init (); + + Con_Printf ("PSP Kurok Engine v 0.4\n"); //(EBOOT: "__TIME__" "__DATE__")\n"); + + int currentCPU = scePowerGetCpuClockFrequency(); + int currentVRAM = sceGeEdramGetSize(); + int currentVRAMADD = sceGeEdramGetAddr(); + +#ifdef NORMAL_MODEL + Con_Printf ("PSP Normal 32MB RAM Mode \n"); +#endif +#ifdef SLIM_MODEL + Con_Printf ("PSP Slim 64MB RAM Mode \n"); +#endif + + Con_Printf ("%4.1f megabyte heap \n",parms->memsize/ (1024*1024.0)); + Con_Printf ("%4.1f PSP application heap \n",1.0f*PSP_HEAP_SIZE_MB); + Con_Printf ("%d VRAM \n",currentVRAM); + Con_Printf ("%d VRAM Address \n",currentVRAMADD); + + Con_Printf ("CPU Speed %d MHz\n", currentCPU); + + R_InitTextures (); // needed even for dedicated servers + + if (cls.state != ca_dedicated) + { + host_basepal = (byte *)COM_LoadHunkFile ("gfx/palette.lmp"); + if (!host_basepal) + Sys_Error ("Couldn't load gfx/palette.lmp"); + host_colormap = (byte *)COM_LoadHunkFile ("gfx/colormap.lmp"); + if (!host_colormap) + Sys_Error ("Couldn't load gfx/colormap.lmp"); + +#ifndef WIN32 // on non win32, mouse comes before video for security reasons + IN_Init (); +#endif + VID_Init (host_basepal); + + Draw_Init (); + SCR_Init (); + R_Init (); + +#ifndef WIN32 + // on Win32, sound initialization has to come before video initialization, so we + // can put up a popup if the sound hardware is in use + S_Init (); +#else + +#ifdef GLQUAKE + // FIXME: doesn't use the new one-window approach yet + S_Init (); +#endif + +#endif // WIN32 + CDAudio_Init (); + Sbar_Init (); + CL_Init (); +#ifdef WIN32 // on non win32, mouse comes before video for security reasons + IN_Init (); +#endif + } + + Cbuf_InsertText ("exec quake.rc\n"); + + Hunk_AllocName (0, "-HOST_HUNKLEVEL-"); + host_hunklevel = Hunk_LowMark (); + + host_initialized = true; + + scr_disabled_for_loading = false; + + Con_Printf ("Loading ... Please wait ...\n"); + + Sys_Printf ("================ Kurok Initialized ===============\n"); +} + + +/* +=============== +Host_Shutdown + +FIXME: this is a callback from Sys_Quit and Sys_Error. It would be better +to run quit through here before the final handoff to the sys code. +=============== +*/ +void Host_Shutdown(void) +{ + static qboolean isdown = false; + + if (isdown) + { + printf ("recursive shutdown\n"); + return; + } + isdown = true; + +// keep Con_Printf from trying to update the screen + scr_disabled_for_loading = true; + + Host_WriteConfiguration (); + + CDAudio_Shutdown (); + NET_Shutdown (); + S_Shutdown(); + IN_Shutdown (); + + if (cls.state != ca_dedicated) + { + VID_Shutdown(); + } +} + diff --git a/r17/Revamped src/revamped_src/host_cmd.c b/r17/Revamped src/revamped_src/host_cmd.c new file mode 100755 index 00000000..f25fce83 --- /dev/null +++ b/r17/Revamped src/revamped_src/host_cmd.c @@ -0,0 +1,1932 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +#include "quakedef.h" + +extern cvar_t pausable; + +int current_skill; + +void Mod_Print (void); + +void VLight_ChangeLightAngle_f(); // RIOT - Vertex lights +void VLight_DumpLightTable_f(); + +/* +================== +Host_Quit_f +================== +*/ + +extern void M_Menu_Quit_f (void); + +void Host_Quit_f (void) +{ + if (key_dest != key_console && cls.state != ca_dedicated) + { + M_Menu_Quit_f (); + return; + } + CL_Disconnect (); + Host_ShutdownServer(false); + + Sys_Quit (); +} + + +/* +================== +Host_Status_f +================== +*/ +void Host_Status_f (void) +{ + client_t *client; + int seconds; + int minutes; + int hours = 0; + int j; + void (*print) (char *fmt, ...); + + if (cmd_source == src_command) + { + if (!sv.active) + { + Cmd_ForwardToServer (); + return; + } + print = Con_Printf; + } + else + print = SV_ClientPrintf; + + print ("host: %s\n", Cvar_VariableString ("hostname")); + print ("version: %4.2f\n", VERSION); + if (tcpipAvailable) + print ("tcp/ip: %s\n", my_tcpip_address); + if (ipxAvailable) + print ("ipx: %s\n", my_ipx_address); + print ("map: %s\n", sv.name); + print ("players: %i active (%i max)\n\n", net_activeconnections, svs.maxclients); + for (j=0, client = svs.clients ; jactive) + continue; + seconds = (int)(net_time - client->netconnection->connecttime); + minutes = seconds / 60; + if (minutes) + { + seconds -= (minutes * 60); + hours = minutes / 60; + if (hours) + minutes -= (hours * 60); + } + else + hours = 0; + print ("#%-2u %-16.16s %3i %2i:%02i:%02i\n", j+1, client->name, (int)client->edict->v.frags, hours, minutes, seconds); + print (" %s\n", client->netconnection->address); + } +} + + +/* +================== +Host_God_f + +Sets client to godmode +================== +*/ +void Host_God_f (void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (pr_global_struct->deathmatch && !host_client->privileged) + return; + + sv_player->v.flags = (int)sv_player->v.flags ^ FL_GODMODE; + if (!((int)sv_player->v.flags & FL_GODMODE) ) + SV_ClientPrintf ("godmode OFF\n"); + else + SV_ClientPrintf ("godmode ON\n"); +} + +void Host_Notarget_f (void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (pr_global_struct->deathmatch && !host_client->privileged) + return; + + sv_player->v.flags = (int)sv_player->v.flags ^ FL_NOTARGET; + if (!((int)sv_player->v.flags & FL_NOTARGET) ) + SV_ClientPrintf ("notarget OFF\n"); + else + SV_ClientPrintf ("notarget ON\n"); +} + +qboolean noclip_anglehack; + +void Host_Noclip_f (void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (pr_global_struct->deathmatch && !host_client->privileged) + return; + + if (sv_player->v.movetype != MOVETYPE_NOCLIP) + { + noclip_anglehack = true; + sv_player->v.movetype = MOVETYPE_NOCLIP; + SV_ClientPrintf ("noclip ON\n"); + } + else + { + noclip_anglehack = false; + sv_player->v.movetype = MOVETYPE_WALK; + SV_ClientPrintf ("noclip OFF\n"); + } +} + +/* +================== +Host_Fly_f + +Sets client to flymode +================== +*/ +void Host_Fly_f (void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (pr_global_struct->deathmatch && !host_client->privileged) + return; + + if (sv_player->v.movetype != MOVETYPE_FLY) + { + sv_player->v.movetype = MOVETYPE_FLY; + SV_ClientPrintf ("flymode ON\n"); + } + else + { + sv_player->v.movetype = MOVETYPE_WALK; + SV_ClientPrintf ("flymode OFF\n"); + } +} + + +/* +================== +Host_Ping_f + +================== +*/ +void Host_Ping_f (void) +{ + int i, j; + float total; + client_t *client; + + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + SV_ClientPrintf ("Client ping times:\n"); + for (i=0, client = svs.clients ; iactive) + continue; + total = 0; + for (j=0 ; jping_times[j]; + total /= NUM_PING_TIMES; + SV_ClientPrintf ("%4i %s\n", (int)(total*1000), client->name); + } +} + +/* +=============================================================================== + +SERVER TRANSITIONS + +=============================================================================== +*/ + + +/* +====================== +Host_Map_f + +handle a +map +command from the console. Active clients are kicked off. +====================== +*/ +void Host_Map_f (void) +{ + int i; + char name[MAX_QPATH]; + + if (cmd_source != src_command) + return; + + cls.demonum = -1; // stop demo loop in case this fails + + CL_Disconnect (); + Host_ShutdownServer(false); + + key_dest = key_game; // remove console or menu + SCR_BeginLoadingPlaque (); + + cls.mapstring[0] = 0; + for (i=0 ; i : continue game on a new level\n"); + return; + } + if (!sv.active || cls.demoplayback) + { + Con_Printf ("Only the server may changelevel\n"); + return; + } + + strcpy (level, Cmd_Argv(1)); + if (Cmd_Argc() == 2) + startspot = NULL; + else + { + strcpy (_startspot, Cmd_Argv(2)); + startspot = _startspot; + } + + SV_SaveSpawnparms (); + SV_SpawnServer (level, startspot); +#else + char level[MAX_QPATH]; + + if (Cmd_Argc() != 2) + { + Con_Printf ("changelevel : continue game on a new level\n"); + return; + } + if (!sv.active || cls.demoplayback) + { + Con_Printf ("Only the server may changelevel\n"); + return; + } + SV_SaveSpawnparms (); + strcpy (level, Cmd_Argv(1)); + SV_SpawnServer (level); +#endif +} + +/* +================== +Host_Restart_f + +Restarts the current server for a dead player +================== +*/ +void Host_Restart_f (void) +{ + char mapname[MAX_QPATH]; +#ifdef QUAKE2 + char startspot[MAX_QPATH]; +#endif + + if (cls.demoplayback || !sv.active) + return; + + if (cmd_source != src_command) + return; + strcpy (mapname, sv.name); // must copy out, because it gets cleared + // in sv_spawnserver +#ifdef QUAKE2 + strcpy(startspot, sv.startspot); + SV_SpawnServer (mapname, startspot); +#else + SV_SpawnServer (mapname); +#endif +} + +/* +================== +Host_Reconnect_f + +This command causes the client to wait for the signon messages again. +This is sent just before a server changes levels +================== +*/ +void Host_Reconnect_f (void) +{ + SCR_BeginLoadingPlaque (); + cls.signon = 0; // need new connection messages +} + +/* +===================== +Host_Connect_f + +User command to connect to server +===================== +*/ +void Host_Connect_f (void) +{ + char name[MAX_QPATH]; + + cls.demonum = -1; // stop demo loop in case this fails + if (cls.demoplayback) + { + CL_StopPlayback (); + CL_Disconnect (); + } + strcpy (name, Cmd_Argv(1)); + CL_EstablishConnection (name); + Host_Reconnect_f (); +} + + +/* +=============================================================================== + +LOAD / SAVE GAME + +=============================================================================== +*/ + +#define SAVEGAME_VERSION 5 + +/* +=============== +Host_SavegameComment + +Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current +=============== +*/ +void Host_SavegameComment (char *text) +{ + int i; + char kills[20]; + + for (i=0 ; i : save a game\n"); + return; + } + + if (strstr(Cmd_Argv(1), "..")) + { + Con_Printf ("Relative pathnames are not allowed.\n"); + return; + } + + for (i=0 ; iv.health <= 0) ) + { + Con_Printf ("Can't savegame with a dead player\n"); + return; + } + } + + sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); + COM_DefaultExtension (name, ".sav"); + + Con_Printf ("Saving game to %s...\n", name); + f = fopen (name, "w"); + if (!f) + { + Con_Printf ("ERROR: couldn't open save file for writing.\n"); + return; + } + + fprintf (f, "%i\n", SAVEGAME_VERSION); + Host_SavegameComment (comment); + fprintf (f, "%s\n", comment); + for (i=0 ; ispawn_parms[i]); + fprintf (f, "%d\n", current_skill); + fprintf (f, "%s\n", sv.name); + fprintf (f, "%f\n",sv.time); + +// write the light styles + + for (i=0 ; i : load a game\n"); + return; + } + + cls.demonum = -1; // stop demo loop in case this fails + + sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); + COM_DefaultExtension (name, ".sav"); + +// we can't call SCR_BeginLoadingPlaque, because too much stack space has +// been used. The menu calls it before stuffing loadgame command +// SCR_BeginLoadingPlaque (); + + Con_Printf ("Loading game from %s...\n", name); + f = fopen (name, "r"); + if (!f) + { + Con_Printf ("ERROR: couldn't open save file for reading.\n"); + return; + } + + fscanf (f, "%i\n", &version); + if (version != SAVEGAME_VERSION) + { + fclose (f); + Con_Printf ("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION); + return; + } + fscanf (f, "%s\n", str); + for (i=0 ; iv, 0, progs->entityfields * 4); + ent->free = false; + ED_ParseEdict (start, ent); + + // link it into the bsp tree + if (!ent->free) + SV_LinkEdict (ent, false); + } + + entnum++; + } + + sv.num_edicts = entnum; + sv.time = time; + + fclose (f); + + for (i=0 ; ispawn_parms[i] = spawn_parms[i]; + + if (cls.state != ca_dedicated) + { + CL_EstablishConnection ("local"); + Host_Reconnect_f (); + } +} + +#ifdef QUAKE2 +void SaveGamestate() +{ + char name[256]; + FILE *f; + int i; + char comment[SAVEGAME_COMMENT_LENGTH+1]; + edict_t *ent; + + sprintf (name, "%s/%s.gip", com_gamedir, sv.name); + + Con_Printf ("Saving game to %s...\n", name); + f = fopen (name, "w"); + if (!f) + { + Con_Printf ("ERROR: couldn't open saved game for writing.\n"); + return; + } + + fprintf (f, "%i\n", SAVEGAME_VERSION); + Host_SavegameComment (comment); + fprintf (f, "%s\n", comment); +// for (i=0 ; ispawn_parms[i]); + fprintf (f, "%f\n", skill.value); + fprintf (f, "%s\n", sv.name); + fprintf (f, "%f\n", sv.time); + +// write the light styles + + for (i=0 ; iv.flags & FL_ARCHIVE_OVERRIDE) + continue; + fprintf (f, "%i\n",i); + ED_Write (f, ent); + fflush (f); + } + fclose (f); + Con_Printf ("done.\n"); +} + +int LoadGamestate(char *level, char *startspot) +{ + char name[MAX_OSPATH]; + FILE *f; + char mapname[MAX_QPATH]; + float time, sk; + char str[32768], *start; + int i, r; + edict_t *ent; + int entnum; + int version; +// float spawn_parms[NUM_SPAWN_PARMS]; + + sprintf (name, "%s/%s.gip", com_gamedir, level); + + Con_Printf ("Loading game from %s...\n", name); + f = fopen (name, "r"); + if (!f) + { + Con_Printf ("ERROR: couldn't open saved game for reading.\n"); + return -1; + } + + fscanf (f, "%i\n", &version); + if (version != SAVEGAME_VERSION) + { + fclose (f); + Con_Printf ("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION); + return -1; + } + fscanf (f, "%s\n", str); +// for (i=0 ; iv, 0, progs->entityfields * 4); + ent->free = false; + ED_ParseEdict (start, ent); + + // link it into the bsp tree + if (!ent->free) + SV_LinkEdict (ent, false); + } + +// sv.num_edicts = entnum; + sv.time = time; + fclose (f); + +// for (i=0 ; ispawn_parms[i] = spawn_parms[i]; + + return 0; +} + +// changing levels within a unit +void Host_Changelevel2_f (void) +{ + char level[MAX_QPATH]; + char _startspot[MAX_QPATH]; + char *startspot; + + if (Cmd_Argc() < 2) + { + Con_Printf ("changelevel2 : continue game on a new level in the unit\n"); + return; + } + if (!sv.active || cls.demoplayback) + { + Con_Printf ("Only the server may changelevel\n"); + return; + } + + strcpy (level, Cmd_Argv(1)); + if (Cmd_Argc() == 2) + startspot = NULL; + else + { + strcpy (_startspot, Cmd_Argv(2)); + startspot = _startspot; + } + + SV_SaveSpawnparms (); + + // save the current level's state + SaveGamestate (); + + // try to restore the new level + if (LoadGamestate (level, startspot)) + SV_SpawnServer (level, startspot); +} +#endif + + +//============================================================================ + +/* +====================== +Host_Name_f +====================== +*/ +void Host_Name_f (void) +{ + char *newName; + + if (Cmd_Argc () == 1) + { + Con_Printf ("\"name\" is \"%s\"\n", cl_name.string); + return; + } + if (Cmd_Argc () == 2) + newName = Cmd_Argv(1); + else + newName = Cmd_Args(); + newName[15] = 0; + + if (cmd_source == src_command) + { + if (Q_strcmp(cl_name.string, newName) == 0) + return; + Cvar_Set ("_cl_name", newName); + if (cls.state == ca_connected) + Cmd_ForwardToServer (); + return; + } + + if (host_client->name[0] && strcmp(host_client->name, "unconnected") ) + if (Q_strcmp(host_client->name, newName) != 0) + Con_Printf ("%s renamed to %s\n", host_client->name, newName); + Q_strcpy (host_client->name, newName); + host_client->edict->v.netname = host_client->name - pr_strings; + +// send notification to all clients + + MSG_WriteByte (&sv.reliable_datagram, svc_updatename); + MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients); + MSG_WriteString (&sv.reliable_datagram, host_client->name); +} + + +void Host_Version_f (void) +{ + Con_Printf ("Version %4.2f\n", VERSION); + Con_Printf ("Exe: "__TIME__" "__DATE__"\n"); +} + +#ifdef IDGODS +void Host_Please_f (void) +{ + client_t *cl; + int j; + + if (cmd_source != src_command) + return; + + if ((Cmd_Argc () == 3) && Q_strcmp(Cmd_Argv(1), "#") == 0) + { + j = Q_atof(Cmd_Argv(2)) - 1; + if (j < 0 || j >= svs.maxclients) + return; + if (!svs.clients[j].active) + return; + cl = &svs.clients[j]; + if (cl->privileged) + { + cl->privileged = false; + cl->edict->v.flags = (int)cl->edict->v.flags & ~(FL_GODMODE|FL_NOTARGET); + cl->edict->v.movetype = MOVETYPE_WALK; + noclip_anglehack = false; + } + else + cl->privileged = true; + } + + if (Cmd_Argc () != 2) + return; + + for (j=0, cl = svs.clients ; jactive) + continue; + if (Q_strcasecmp(cl->name, Cmd_Argv(1)) == 0) + { + if (cl->privileged) + { + cl->privileged = false; + cl->edict->v.flags = (int)cl->edict->v.flags & ~(FL_GODMODE|FL_NOTARGET); + cl->edict->v.movetype = MOVETYPE_WALK; + noclip_anglehack = false; + } + else + cl->privileged = true; + break; + } + } +} +#endif + + +void Host_Say(qboolean teamonly) +{ + client_t *client; + client_t *save; + int j; + char *p; + unsigned char text[64]; + qboolean fromServer = false; + + if (cmd_source == src_command) + { + if (cls.state == ca_dedicated) + { + fromServer = true; + teamonly = false; + } + else + { + Cmd_ForwardToServer (); + return; + } + } + + if (Cmd_Argc () < 2) + return; + + save = host_client; + + p = Cmd_Args(); +// remove quotes if present + if (*p == '"') + { + p++; + p[Q_strlen(p)-1] = 0; + } + +// turn on color set 1 + if (!fromServer) + sprintf (text, "%c%s: ", 1, save->name); + else + sprintf (text, "%c<%s> ", 1, hostname.string); + + j = sizeof(text) - 2 - Q_strlen(text); // -2 for /n and null terminator + if (Q_strlen(p) > j) + p[j] = 0; + + strcat (text, p); + strcat (text, "\n"); + + for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++) + { + if (!client || !client->active || !client->spawned) + continue; + if (teamplay.value && teamonly && client->edict->v.team != save->edict->v.team) + continue; + host_client = client; + SV_ClientPrintf("%s", text); + } + host_client = save; + + Sys_Printf("%s", &text[1]); +} + + +void Host_Say_f(void) +{ + Host_Say(false); +} + + +void Host_Say_Team_f(void) +{ + Host_Say(true); +} + + +void Host_Tell_f(void) +{ + client_t *client; + client_t *save; + int j; + char *p; + char text[64]; + + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (Cmd_Argc () < 3) + return; + + Q_strcpy(text, host_client->name); + Q_strcat(text, ": "); + + p = Cmd_Args(); + +// remove quotes if present + if (*p == '"') + { + p++; + p[Q_strlen(p)-1] = 0; + } + +// check length & truncate if necessary + j = sizeof(text) - 2 - Q_strlen(text); // -2 for /n and null terminator + if (Q_strlen(p) > j) + p[j] = 0; + + strcat (text, p); + strcat (text, "\n"); + + save = host_client; + for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++) + { + if (!client->active || !client->spawned) + continue; + if (Q_strcasecmp(client->name, Cmd_Argv(1))) + continue; + host_client = client; + SV_ClientPrintf("%s", text); + break; + } + host_client = save; +} + + +/* +================== +Host_Color_f +================== +*/ +void Host_Color_f(void) +{ + int top, bottom; + int playercolor; + + if (Cmd_Argc() == 1) + { + Con_Printf ("\"color\" is \"%i %i\"\n", ((int)cl_color.value) >> 4, ((int)cl_color.value) & 0x0f); + Con_Printf ("color <0-13> [0-13]\n"); + return; + } + + if (Cmd_Argc() == 2) + top = bottom = atoi(Cmd_Argv(1)); + else + { + top = atoi(Cmd_Argv(1)); + bottom = atoi(Cmd_Argv(2)); + } + + top &= 15; + if (top > 13) + top = 13; + bottom &= 15; + if (bottom > 13) + bottom = 13; + + playercolor = top*16 + bottom; + + if (cmd_source == src_command) + { + Cvar_SetValue ("_cl_color", playercolor); + if (cls.state == ca_connected) + Cmd_ForwardToServer (); + return; + } + + host_client->colors = playercolor; + host_client->edict->v.team = bottom + 1; + +// send notification to all clients + MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors); + MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients); + MSG_WriteByte (&sv.reliable_datagram, host_client->colors); +} + +/* +================== +Host_Kill_f +================== +*/ +void Host_Kill_f (void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (sv_player->v.health <= 0) + { + SV_ClientPrintf ("Can't suicide -- allready dead!\n"); + return; + } + + pr_global_struct->time = sv.time; + pr_global_struct->self = EDICT_TO_PROG(sv_player); + PR_ExecuteProgram (pr_global_struct->ClientKill); +} + + +/* +================== +Host_Pause_f +================== +*/ +void Host_Pause_f (void) +{ + + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + if (!pausable.value) + SV_ClientPrintf ("Pause not allowed.\n"); + else + { + sv.paused ^= 1; + + if (sv.paused) + { + SV_BroadcastPrintf ("%s paused the game\n", pr_strings + sv_player->v.netname); + } + else + { + SV_BroadcastPrintf ("%s unpaused the game\n",pr_strings + sv_player->v.netname); + } + + // send notification to all clients + MSG_WriteByte (&sv.reliable_datagram, svc_setpause); + MSG_WriteByte (&sv.reliable_datagram, sv.paused); + } +} + +//=========================================================================== + + +/* +================== +Host_PreSpawn_f +================== +*/ +void Host_PreSpawn_f (void) +{ + if (cmd_source == src_command) + { + Con_Printf ("prespawn is not valid from the console\n"); + return; + } + + if (host_client->spawned) + { + Con_Printf ("prespawn not valid -- allready spawned\n"); + return; + } + + SZ_Write (&host_client->message, sv.signon.data, sv.signon.cursize); + MSG_WriteByte (&host_client->message, svc_signonnum); + MSG_WriteByte (&host_client->message, 2); + host_client->sendsignon = true; +} + +/* +================== +Host_Spawn_f +================== +*/ +void Host_Spawn_f (void) +{ + int i; + client_t *client; + edict_t *ent; + + if (cmd_source == src_command) + { + Con_Printf ("spawn is not valid from the console\n"); + return; + } + + if (host_client->spawned) + { + Con_Printf ("Spawn not valid -- allready spawned\n"); + return; + } + +// run the entrance script + if (sv.loadgame) + { // loaded games are fully inited allready + // if this is the last client to be connected, unpause + sv.paused = false; + } + else + { + // set up the edict + ent = host_client->edict; + + memset (&ent->v, 0, progs->entityfields * 4); + ent->v.colormap = NUM_FOR_EDICT(ent); + ent->v.team = (host_client->colors & 15) + 1; + ent->v.netname = host_client->name - pr_strings; + + // copy spawn parms out of the client_t + + for (i=0 ; i< NUM_SPAWN_PARMS ; i++) + (&pr_global_struct->parm1)[i] = host_client->spawn_parms[i]; + + // call the spawn function + + pr_global_struct->time = sv.time; + pr_global_struct->self = EDICT_TO_PROG(sv_player); + PR_ExecuteProgram (pr_global_struct->ClientConnect); + + if ((Sys_FloatTime() - host_client->netconnection->connecttime) <= sv.time) + Sys_Printf ("%s entered the game\n", host_client->name); + + PR_ExecuteProgram (pr_global_struct->PutClientInServer); + } + + +// send all current names, colors, and frag counts + SZ_Clear (&host_client->message); + +// send time of update + MSG_WriteByte (&host_client->message, svc_time); + MSG_WriteFloat (&host_client->message, sv.time); + + for (i=0, client = svs.clients ; imessage, svc_updatename); + MSG_WriteByte (&host_client->message, i); + MSG_WriteString (&host_client->message, client->name); + MSG_WriteByte (&host_client->message, svc_updatefrags); + MSG_WriteByte (&host_client->message, i); + MSG_WriteShort (&host_client->message, client->old_frags); + MSG_WriteByte (&host_client->message, svc_updatecolors); + MSG_WriteByte (&host_client->message, i); + MSG_WriteByte (&host_client->message, client->colors); + } + +// send all current light styles + for (i=0 ; imessage, svc_lightstyle); + MSG_WriteByte (&host_client->message, (char)i); + MSG_WriteString (&host_client->message, sv.lightstyles[i]); + } + +// +// send some stats +// + MSG_WriteByte (&host_client->message, svc_updatestat); + MSG_WriteByte (&host_client->message, STAT_TOTALSECRETS); + MSG_WriteLong (&host_client->message, pr_global_struct->total_secrets); + + MSG_WriteByte (&host_client->message, svc_updatestat); + MSG_WriteByte (&host_client->message, STAT_TOTALMONSTERS); + MSG_WriteLong (&host_client->message, pr_global_struct->total_monsters); + + MSG_WriteByte (&host_client->message, svc_updatestat); + MSG_WriteByte (&host_client->message, STAT_SECRETS); + MSG_WriteLong (&host_client->message, pr_global_struct->found_secrets); + + MSG_WriteByte (&host_client->message, svc_updatestat); + MSG_WriteByte (&host_client->message, STAT_MONSTERS); + MSG_WriteLong (&host_client->message, pr_global_struct->killed_monsters); + + +// +// send a fixangle +// Never send a roll angle, because savegames can catch the server +// in a state where it is expecting the client to correct the angle +// and it won't happen if the game was just loaded, so you wind up +// with a permanent head tilt + ent = EDICT_NUM( 1 + (host_client - svs.clients) ); + MSG_WriteByte (&host_client->message, svc_setangle); + for (i=0 ; i < 2 ; i++) + MSG_WriteAngle (&host_client->message, ent->v.angles[i] ); + MSG_WriteAngle (&host_client->message, 0 ); + + SV_WriteClientdataToMessage (sv_player, &host_client->message); + + MSG_WriteByte (&host_client->message, svc_signonnum); + MSG_WriteByte (&host_client->message, 3); + host_client->sendsignon = true; +} + +/* +================== +Host_Begin_f +================== +*/ +void Host_Begin_f (void) +{ + if (cmd_source == src_command) + { + Con_Printf ("begin is not valid from the console\n"); + return; + } + + host_client->spawned = true; +} + +//=========================================================================== + + +/* +================== +Host_Kick_f + +Kicks a user off of the server +================== +*/ +void Host_Kick_f (void) +{ + char *who; + char *message = NULL; + client_t *save; + int i; + qboolean byNumber = false; + + if (cmd_source == src_command) + { + if (!sv.active) + { + Cmd_ForwardToServer (); + return; + } + } + else if (pr_global_struct->deathmatch && !host_client->privileged) + return; + + save = host_client; + + if (Cmd_Argc() > 2 && Q_strcmp(Cmd_Argv(1), "#") == 0) + { + i = Q_atof(Cmd_Argv(2)) - 1; + if (i < 0 || i >= svs.maxclients) + return; + if (!svs.clients[i].active) + return; + host_client = &svs.clients[i]; + byNumber = true; + } + else + { + for (i = 0, host_client = svs.clients; i < svs.maxclients; i++, host_client++) + { + if (!host_client->active) + continue; + if (Q_strcasecmp(host_client->name, Cmd_Argv(1)) == 0) + break; + } + } + + if (i < svs.maxclients) + { + if (cmd_source == src_command) + if (cls.state == ca_dedicated) + who = "Console"; + else + who = cl_name.string; + else + who = save->name; + + // can't kick yourself! + if (host_client == save) + return; + + if (Cmd_Argc() > 2) + { + message = COM_Parse(Cmd_Args()); + if (byNumber) + { + message++; // skip the # + while (*message == ' ') // skip white space + message++; + message += Q_strlen(Cmd_Argv(2)); // skip the number + } + while (*message && *message == ' ') + message++; + } + if (message) + SV_ClientPrintf ("Kicked by %s: %s\n", who, message); + else + SV_ClientPrintf ("Kicked by %s\n", who); + SV_DropClient (false); + } + + host_client = save; +} + +/* +=============================================================================== + +DEBUGGING TOOLS + +=============================================================================== +*/ + +/* +================== +Host_Give_f +================== +*/ +void Host_Give_f (void) +{ + char *t; + int v; + eval_t *val; + + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (pr_global_struct->deathmatch && !host_client->privileged) + return; + + t = Cmd_Argv(1); + v = atoi (Cmd_Argv(2)); + + switch (t[0]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + + // MED 01/04/97 added hipnotic give stuff + if (hipnotic) + { + if (t[0] == '6') + { + if (t[1] == 'a') + sv_player->v.items = (int)sv_player->v.items | HIT_PROXIMITY_GUN; + else + sv_player->v.items = (int)sv_player->v.items | IT_GRENADE_LAUNCHER; + } + else if (t[0] == '9') + sv_player->v.items = (int)sv_player->v.items | HIT_LASER_CANNON; + else if (t[0] == '0') + sv_player->v.items = (int)sv_player->v.items | HIT_MJOLNIR; + else if (t[0] >= '2') + sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2')); + } + else + { + if (t[0] >= '2') + sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2')); + } + break; + + case 's': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_shells1"); + if (val) + val->_float = v; + } + + sv_player->v.ammo_shells = v; + break; + case 'n': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_nails1"); + if (val) + { + val->_float = v; + if (sv_player->v.weapon <= IT_LIGHTNING) + sv_player->v.ammo_nails = v; + } + } + else + { + sv_player->v.ammo_nails = v; + } + break; + case 'l': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_lava_nails"); + if (val) + { + val->_float = v; + if (sv_player->v.weapon > IT_LIGHTNING) + sv_player->v.ammo_nails = v; + } + } + break; + case 'r': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_rockets1"); + if (val) + { + val->_float = v; + if (sv_player->v.weapon <= IT_LIGHTNING) + sv_player->v.ammo_rockets = v; + } + } + else + { + sv_player->v.ammo_rockets = v; + } + break; + case 'm': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_multi_rockets"); + if (val) + { + val->_float = v; + if (sv_player->v.weapon > IT_LIGHTNING) + sv_player->v.ammo_rockets = v; + } + } + break; + case 'h': + sv_player->v.health = v; + break; + case 'c': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_cells1"); + if (val) + { + val->_float = v; + if (sv_player->v.weapon <= IT_LIGHTNING) + sv_player->v.ammo_cells = v; + } + } + else + { + sv_player->v.ammo_cells = v; + } + break; + case 'p': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_plasma"); + if (val) + { + val->_float = v; + if (sv_player->v.weapon > IT_LIGHTNING) + sv_player->v.ammo_cells = v; + } + } + break; + } +} + +edict_t *FindViewthing (void) +{ + int i; + edict_t *e; + + for (i=0 ; iv.classname, "viewthing") ) + return e; + } + Con_Printf ("No viewthing on map\n"); + return NULL; +} + +/* +================== +Host_Viewmodel_f +================== +*/ +void Host_Viewmodel_f (void) +{ + edict_t *e; + model_t *m; + + e = FindViewthing (); + if (!e) + return; + + m = Mod_ForName (Cmd_Argv(1), false); + if (!m) + { + Con_Printf ("Can't load %s\n", Cmd_Argv(1)); + return; + } + + e->v.frame = 0; + cl.model_precache[(int)e->v.modelindex] = m; +} + +/* +================== +Host_Viewframe_f +================== +*/ +void Host_Viewframe_f (void) +{ + edict_t *e; + int f; + model_t *m; + + e = FindViewthing (); + if (!e) + return; + m = cl.model_precache[(int)e->v.modelindex]; + + f = atoi(Cmd_Argv(1)); + if (f >= m->numframes) + f = m->numframes-1; + + e->v.frame = f; +} + + +void PrintFrameName (model_t *m, int frame) +{ + aliashdr_t *hdr; + maliasframedesc_t *pframedesc; + + hdr = (aliashdr_t *)Mod_Extradata (m); + if (!hdr) + return; + pframedesc = &hdr->frames[frame]; + + Con_Printf ("frame %i: %s\n", frame, pframedesc->name); +} + +/* +================== +Host_Viewnext_f +================== +*/ +void Host_Viewnext_f (void) +{ + edict_t *e; + model_t *m; + + e = FindViewthing (); + if (!e) + return; + m = cl.model_precache[(int)e->v.modelindex]; + + e->v.frame = e->v.frame + 1; + if (e->v.frame >= m->numframes) + e->v.frame = m->numframes - 1; + + PrintFrameName (m, e->v.frame); +} + +/* +================== +Host_Viewprev_f +================== +*/ +void Host_Viewprev_f (void) +{ + edict_t *e; + model_t *m; + + e = FindViewthing (); + if (!e) + return; + + m = cl.model_precache[(int)e->v.modelindex]; + + e->v.frame = e->v.frame - 1; + if (e->v.frame < 0) + e->v.frame = 0; + + PrintFrameName (m, e->v.frame); +} + +/* +=============================================================================== + +DEMO LOOP CONTROL + +=============================================================================== +*/ + + +/* +================== +Host_Startdemos_f +================== +*/ +void Host_Startdemos_f (void) +{ + int i, c; + + if (cls.state == ca_dedicated) + { + if (!sv.active) + Cbuf_AddText ("map start\n"); + return; + } + + c = Cmd_Argc() - 1; + if (c > MAX_DEMOS) + { + Con_Printf ("Max %i demos in demoloop\n", MAX_DEMOS); + c = MAX_DEMOS; + } + Con_Printf ("%i demo(s) in loop\n", c); + + for (i=1 ; i 1, it is autorepeating +qboolean keydown[256]; + +void Con_OSK_f (char *input, char *output, int outlen); +void Con_SetOSKActive(qboolean active); +qboolean Con_isSetOSKActive(void); +void Con_OSK_Key (int key); + +typedef struct +{ + char *name; + int keynum; +} keyname_t; + +keyname_t keynames[] = +{ + {"TAB", K_TAB}, + {"ENTER", K_ENTER}, + {"ESCAPE", K_ESCAPE}, + {"SPACE", K_SPACE}, + {"BACKSPACE", K_BACKSPACE}, + {"UPARROW", K_UPARROW}, + {"DOWNARROW", K_DOWNARROW}, + {"LEFTARROW", K_LEFTARROW}, + {"RIGHTARROW", K_RIGHTARROW}, + + {"ALT", K_ALT}, + {"CTRL", K_CTRL}, + {"SHIFT", K_SHIFT}, + + {"F1", K_F1}, + {"F2", K_F2}, + {"F3", K_F3}, + {"F4", K_F4}, + {"F5", K_F5}, + {"F6", K_F6}, + {"F7", K_F7}, + {"F8", K_F8}, + {"F9", K_F9}, + {"F10", K_F10}, + {"F11", K_F11}, + {"F12", K_F12}, + + {"INS", K_INS}, + {"DEL", K_DEL}, + {"PGDN", K_PGDN}, + {"PGUP", K_PGUP}, + {"HOME", K_HOME}, + {"END", K_END}, + + {"MOUSE1", K_MOUSE1}, + {"MOUSE2", K_MOUSE2}, + {"MOUSE3", K_MOUSE3}, + +#ifdef PSP + {"TRIANGLE", K_JOY1}, + {"CIRCLE", K_JOY2}, + {"CROSS", K_JOY3}, + {"SQUARE", K_JOY4}, +#else + {"JOY1", K_JOY1}, + {"JOY2", K_JOY2}, + {"JOY3", K_JOY3}, + {"JOY4", K_JOY4}, +#endif + +#ifdef PSP + {"LTRIGGER", K_AUX1}, + {"RTRIGGER", K_AUX2}, +#else + {"AUX1", K_AUX1}, + {"AUX2", K_AUX2}, +#endif + {"AUX3", K_AUX3}, + {"AUX4", K_AUX4}, + {"AUX5", K_AUX5}, + {"AUX6", K_AUX6}, + {"AUX7", K_AUX7}, + {"AUX8", K_AUX8}, + {"AUX9", K_AUX9}, + {"AUX10", K_AUX10}, + {"AUX11", K_AUX11}, + {"AUX12", K_AUX12}, + {"AUX13", K_AUX13}, + {"AUX14", K_AUX14}, + {"AUX15", K_AUX15}, + {"AUX16", K_AUX16}, + {"AUX17", K_AUX17}, + {"AUX18", K_AUX18}, + {"AUX19", K_AUX19}, + {"AUX20", K_AUX20}, + {"AUX21", K_AUX21}, + {"AUX22", K_AUX22}, + {"AUX23", K_AUX23}, + {"AUX24", K_AUX24}, + {"AUX25", K_AUX25}, + {"AUX26", K_AUX26}, + {"AUX27", K_AUX27}, + {"AUX28", K_AUX28}, + {"AUX29", K_AUX29}, + {"AUX30", K_AUX30}, + {"AUX31", K_AUX31}, + {"AUX32", K_AUX32}, + + {"PAUSE", K_PAUSE}, + + {"MWHEELUP", K_MWHEELUP}, + {"MWHEELDOWN", K_MWHEELDOWN}, + + {"SEMICOLON", ';'}, // because a raw semicolon seperates commands + + {NULL,0} +}; + +char consoleInput[MAXCMDLINE]; +qboolean consoleOskDone = false; + +/* +============================================================================== + + LINE TYPING INTO THE CONSOLE + +============================================================================== +*/ + + +/* +==================== +Key_Console + +Interactive line editing and console scrollback +==================== +*/ +void Key_Console (int key) +{ + char *cmd; + +#ifdef PSP + if (Con_isSetOSKActive()) { + if (key == K_JOY1) + Con_OSK_Key (K_DEL); + else if (key == K_JOY2) + Con_OSK_Key (K_ESCAPE); + else if (key == K_JOY3) + Con_OSK_Key (K_ENTER); + else if (key == K_JOY4) + Con_OSK_Key (K_INS); + else + Con_OSK_Key (key); + return; + } + + if ( key == K_JOY4 || key == K_INS) + { + consoleOskDone = false; + Con_SetOSKActive(true); + Con_OSK_f(key_lines[edit_line]+1, consoleInput, 72); + return; + } +#endif + + if (key == K_JOY3 || key == K_ENTER) + { + Cbuf_AddText (key_lines[edit_line]+1); // skip the > + Cbuf_AddText ("\n"); + Con_Printf ("%s\n",key_lines[edit_line]); + edit_line = (edit_line + 1) & 31; + history_line = edit_line; + key_lines[edit_line][0] = ']'; + key_linepos = 1; + if (cls.state == ca_disconnected) + SCR_UpdateScreen (); // force an update, because the command + // may take some time + return; + } + + + + if (key == K_TAB || key == K_RIGHTARROW) + { // command completion + cmd = Cmd_CompleteCommand (key_lines[edit_line]+1); + if (!cmd) + cmd = Cvar_CompleteVariable (key_lines[edit_line]+1); + if (cmd) + { + Q_strcpy (key_lines[edit_line]+1, cmd); + key_linepos = Q_strlen(cmd)+1; + key_lines[edit_line][key_linepos] = ' '; + key_linepos++; + key_lines[edit_line][key_linepos] = 0; + return; + } + } + + if (key == K_BACKSPACE || key == K_LEFTARROW) + { + if (key_linepos > 1) + key_linepos--; + return; + } + + if (key == K_UPARROW) + { + do + { + history_line = (history_line - 1) & 31; + } while (history_line != edit_line + && !key_lines[history_line][1]); + if (history_line == edit_line) + history_line = (edit_line+1)&31; + Q_strcpy(key_lines[edit_line], key_lines[history_line]); + key_linepos = Q_strlen(key_lines[edit_line]); + return; + } + + if (key == K_DOWNARROW) + { + if (history_line == edit_line) return; + do + { + history_line = (history_line + 1) & 31; + } + while (history_line != edit_line + && !key_lines[history_line][1]); + if (history_line == edit_line) + { + key_lines[edit_line][0] = ']'; + key_linepos = 1; + } + else + { + Q_strcpy(key_lines[edit_line], key_lines[history_line]); + key_linepos = Q_strlen(key_lines[edit_line]); + } + return; + } + + if (key == K_PGUP || key==K_MWHEELUP) + { + con_backscroll += 2; + if (con_backscroll > con_totallines - (vid.height>>3) - 1) + con_backscroll = con_totallines - (vid.height>>3) - 1; + return; + } + + if (key == K_PGDN || key==K_MWHEELDOWN) + { + con_backscroll -= 2; + if (con_backscroll < 0) + con_backscroll = 0; + return; + } + + if (key == K_HOME) + { + con_backscroll = con_totallines - (vid.height>>3) - 1; + return; + } + + if (key == K_END) + { + con_backscroll = 0; + return; + } + + if (key < 32 || key > 127) + return; // non printable + + if (key_linepos < MAXCMDLINE-1) + { + key_lines[edit_line][key_linepos] = key; + key_linepos++; + key_lines[edit_line][key_linepos] = 0; + } + +} + +//============================================================================ + +char chat_buffer[32]; +qboolean team_message = false; + +void Key_Message (int key) +{ + static int chat_bufferlen = 0; + +/* +#ifdef PSP + if (Con_isSetOSKActive()) { + if (key == K_JOY1) + Con_OSK_Key (K_DEL); + else if (key == K_JOY2) + Con_OSK_Key (K_ESCAPE); + else if (key == K_JOY3) + Con_OSK_Key (K_ENTER); + else if (key == K_JOY4) + Con_OSK_Key (K_INS); + else + Con_OSK_Key (key); + return; + } + + if ( key == K_JOY4 || key == K_INS) + { + consoleOskDone = false; + Con_SetOSKActive(true); + Con_OSK_f(key_lines[edit_line]+1, consoleInput, 72); + return; + } +#endif +*/ + + if (key == K_ENTER) + { + if (team_message) + Cbuf_AddText ("say_team \""); + else + Cbuf_AddText ("say \""); + Cbuf_AddText(chat_buffer); + Cbuf_AddText("\"\n"); + + key_dest = key_game; + chat_bufferlen = 0; + chat_buffer[0] = 0; + return; + } + + if (key == K_ESCAPE) + { + key_dest = key_game; + chat_bufferlen = 0; + chat_buffer[0] = 0; + return; + } + + if (key < 32 || key > 127) + return; // non printable + + if (key == K_BACKSPACE) + { + if (chat_bufferlen) + { + chat_bufferlen--; + chat_buffer[chat_bufferlen] = 0; + } + return; + } + + if (chat_bufferlen == 31) + return; // all full + + chat_buffer[chat_bufferlen++] = key; + chat_buffer[chat_bufferlen] = 0; +} + +//============================================================================ + + +/* +=================== +Key_StringToKeynum + +Returns a key number to be used to index keybindings[] by looking at +the given string. Single ascii characters return themselves, while +the K_* names are matched up. +=================== +*/ +int Key_StringToKeynum (char *str) +{ + keyname_t *kn; + + if (!str || !str[0]) + return -1; + if (!str[1]) + return str[0]; + + for (kn=keynames ; kn->name ; kn++) + { + if (!Q_strcasecmp(str,kn->name)) + return kn->keynum; + } + return -1; +} + +/* +=================== +Key_KeynumToString + +Returns a string (either a single ascii char, or a K_* name) for the +given keynum. +FIXME: handle quote special (general escape sequence?) +=================== +*/ +char *Key_KeynumToString (int keynum) +{ + keyname_t *kn; + static char tinystr[2]; + + if (keynum == -1) + return ""; + if (keynum > 32 && keynum < 127) + { // printable ascii + tinystr[0] = keynum; + tinystr[1] = 0; + return tinystr; + } + + for (kn=keynames ; kn->name ; kn++) + if (keynum == kn->keynum) + return kn->name; + + return ""; +} + + +/* +=================== +Key_SetBinding +=================== +*/ +void Key_SetBinding (int keynum, char *binding) +{ + char *new; + int l; + + if (keynum == -1) + return; + +// free old bindings + if (keybindings[keynum]) + { + Z_Free (keybindings[keynum]); + keybindings[keynum] = NULL; + } + +// allocate memory for new binding + l = Q_strlen (binding); + new = Z_Malloc (l+1); + Q_strcpy (new, binding); + new[l] = 0; + keybindings[keynum] = new; +} + +/* +=================== +Key_Unbind_f +=================== +*/ +void Key_Unbind_f (void) +{ + int b; + + if (Cmd_Argc() != 2) + { + Con_Printf ("unbind : remove commands from a key\n"); + return; + } + + b = Key_StringToKeynum (Cmd_Argv(1)); + if (b==-1) + { + Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1)); + return; + } + + Key_SetBinding (b, ""); +} + +void Key_Unbindall_f (void) +{ + int i; + + for (i=0 ; i<256 ; i++) + if (keybindings[i]) + Key_SetBinding (i, ""); +} + + +/* +=================== +Key_Bind_f +=================== +*/ +void Key_Bind_f (void) +{ + int i, c, b; + char cmd[1024]; + + c = Cmd_Argc(); + + if (c != 2 && c != 3) + { + Con_Printf ("bind [command] : attach a command to a key\n"); + return; + } + b = Key_StringToKeynum (Cmd_Argv(1)); + if (b==-1) + { + Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1)); + return; + } + + if (c == 2) + { + if (keybindings[b]) + Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b] ); + else + Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) ); + return; + } + +// copy the rest of the command line + cmd[0] = 0; // start out with a null string + for (i=2 ; i< c ; i++) + { + if (i > 2) + strcat (cmd, " "); + strcat (cmd, Cmd_Argv(i)); + } + + Key_SetBinding (b, cmd); +} + +/* +============ +Key_WriteBindings + +Writes lines containing "bind key value" +============ +*/ +void Key_WriteBindings (FILE *f) +{ + int i; + + for (i=0 ; i<256 ; i++) + if (keybindings[i]) + if (*keybindings[i]) + fprintf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString(i), keybindings[i]); +} + + +/* +=================== +Key_Init +=================== +*/ +void Key_Init (void) +{ + int i; + + for (i=0 ; i<32 ; i++) + { + key_lines[i][0] = ']'; + key_lines[i][1] = 0; + } + key_linepos = 1; + +// +// init ascii characters in console mode +// + for (i=32 ; i<128 ; i++) + consolekeys[i] = true; + consolekeys[K_ENTER] = true; + consolekeys[K_TAB] = true; + consolekeys[K_LEFTARROW] = true; + consolekeys[K_RIGHTARROW] = true; + consolekeys[K_UPARROW] = true; + consolekeys[K_DOWNARROW] = true; + consolekeys[K_BACKSPACE] = true; + consolekeys[K_PGUP] = true; + consolekeys[K_PGDN] = true; + consolekeys[K_SHIFT] = true; + consolekeys[K_MWHEELUP] = true; + consolekeys[K_MWHEELDOWN] = true; + consolekeys['`'] = false; + consolekeys['~'] = false; +#ifdef PSP + consolekeys[K_INS] = true; + consolekeys[K_JOY1] = true; + consolekeys[K_JOY2] = true; + consolekeys[K_JOY3] = true; + consolekeys[K_JOY4] = true; +#endif + + for (i=0 ; i<256 ; i++) + keyshift[i] = i; + for (i='a' ; i<='z' ; i++) + keyshift[i] = i - 'a' + 'A'; + keyshift['1'] = '!'; + keyshift['2'] = '@'; + keyshift['3'] = '#'; + keyshift['4'] = '$'; + keyshift['5'] = '%'; + keyshift['6'] = '^'; + keyshift['7'] = '&'; + keyshift['8'] = '*'; + keyshift['9'] = '('; + keyshift['0'] = ')'; + keyshift['-'] = '_'; + keyshift['='] = '+'; + keyshift[','] = '<'; + keyshift['.'] = '>'; + keyshift['/'] = '?'; + keyshift[';'] = ':'; + keyshift['\''] = '"'; + keyshift['['] = '{'; + keyshift[']'] = '}'; + keyshift['`'] = '~'; + keyshift['\\'] = '|'; + + menubound[K_ESCAPE] = true; + for (i=0 ; i<12 ; i++) + menubound[K_F1+i] = true; + +// +// register our functions +// + Cmd_AddCommand ("bind",Key_Bind_f); + Cmd_AddCommand ("unbind",Key_Unbind_f); + Cmd_AddCommand ("unbindall",Key_Unbindall_f); + + +} + +/* +=================== +Key_Event + +Called by the system between frames for both key up and key down events +Should NOT be called during an interrupt! +=================== +*/ +void Key_Event (int key, qboolean down) +{ + char *kb; + char cmd[1024]; + + keydown[key] = down; + +#ifdef PSP + if (Con_isSetOSKActive() && down) { + if (key == K_JOY1) + Con_OSK_Key (K_DEL); + else if (key == K_JOY2) + Con_OSK_Key (K_ESCAPE); + else if (key == K_JOY3) + Con_OSK_Key (K_ENTER); + else if (key == K_JOY4) + Con_OSK_Key (K_INS); + else + Con_OSK_Key (key); + + if (!Con_isSetOSKActive()) { + consoleOskDone = true; + strcpy(key_lines[edit_line]+1, consoleInput); + key_linepos = Q_strlen(key_lines[edit_line]); + consoleOskDone = false; + consoleInput[0] = 0; + return; + + } + else { + return; + } + } +#endif + if (!down) + key_repeats[key] = 0; + + key_lastpress = key; + key_count++; + if (key_count <= 0) + { + return; // just catching keys for Con_NotifyBox + } + +// update auto-repeat status + if (down) + { + key_repeats[key]++; + if (key != K_PAUSE && key_repeats[key] > 1) + { + return; // ignore most autorepeats + } + + if (key >= 200 && !keybindings[key]) +#ifdef PSP + Con_Printf ("%s is unbound, hit START to set.\n", Key_KeynumToString (key) ); +#else + Con_Printf ("%s is unbound, hit F4 to set.\n", Key_KeynumToString (key) ); +#endif + } + + if (key == K_SHIFT) + shift_down = down; + +// +// handle escape specialy, so the user can never unbind it +// + if (key == K_ESCAPE) + { + if (!down) + return; + switch (key_dest) + { + case key_message: + Key_Message (key); + break; + case key_menu: + M_Keydown (key); + break; + case key_game: + case key_console: + M_ToggleMenu_f (); + break; + default: + Sys_Error ("Bad key_dest"); + } + return; + } + +// +// key up events only generate commands if the game key binding is +// a button command (leading + sign). These will occur even in console mode, +// to keep the character from continuing an action started before a console +// switch. Button commands include the kenum as a parameter, so multiple +// downs can be matched with ups +// + if (!down) + { + kb = keybindings[key]; + if (kb && kb[0] == '+') + { + sprintf (cmd, "-%s %i\n", kb+1, key); + Cbuf_AddText (cmd); + } + if (keyshift[key] != key) + { + kb = keybindings[keyshift[key]]; + if (kb && kb[0] == '+') + { + sprintf (cmd, "-%s %i\n", kb+1, key); + Cbuf_AddText (cmd); + } + } + return; + } + +// +// during demo playback, most keys bring up the main menu +// + if (cls.demoplayback && down && consolekeys[key] && key_dest == key_game) + { + M_ToggleMenu_f (); + return; + } + +// +// if not a consolekey, send to the interpreter no matter what mode is +// + if ( (key_dest == key_menu && menubound[key]) + || (key_dest == key_console && !consolekeys[key]) + || (key_dest == key_game && ( !con_forcedup || !consolekeys[key] ) ) ) + { + kb = keybindings[key]; + if (kb) + { + if (kb[0] == '+') + { // button commands add keynum as a parm + sprintf (cmd, "%s %i\n", kb, key); + Cbuf_AddText (cmd); + } + else + { + Cbuf_AddText (kb); + Cbuf_AddText ("\n"); + } + } + return; + } + + if (!down) + return; // other systems only care about key down events + + if (shift_down) + { + key = keyshift[key]; + } + + switch (key_dest) + { + case key_message: + Key_Message (key); + break; + case key_menu: + M_Keydown (key); + break; + + case key_game: + case key_console: + Key_Console (key); + break; + default: + Sys_Error ("Bad key_dest"); + } +} + + +/* +=================== +Key_ClearStates +=================== +*/ +void Key_ClearStates (void) +{ + int i; + + for (i=0 ; i<256 ; i++) + { + keydown[i] = false; + key_repeats[i] = 0; + } +} + diff --git a/r17/Revamped src/revamped_src/keys.h b/r17/Revamped src/revamped_src/keys.h new file mode 100755 index 00000000..986c9d07 --- /dev/null +++ b/r17/Revamped src/revamped_src/keys.h @@ -0,0 +1,133 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +// +// these are the key numbers that should be passed to Key_Event +// +#define K_TAB 9 +#define K_ENTER 13 +#define K_ESCAPE 27 +#define K_SPACE 32 + +// normal keys should be passed as lowercased ascii + +#define K_BACKSPACE 127 +#define K_UPARROW 128 +#define K_DOWNARROW 129 +#define K_LEFTARROW 130 +#define K_RIGHTARROW 131 + +#define K_ALT 132 +#define K_CTRL 133 +#define K_SHIFT 134 +#define K_F1 135 +#define K_F2 136 +#define K_F3 137 +#define K_F4 138 +#define K_F5 139 +#define K_F6 140 +#define K_F7 141 +#define K_F8 142 +#define K_F9 143 +#define K_F10 144 +#define K_F11 145 +#define K_F12 146 +#define K_INS 147 +#define K_DEL 148 +#define K_PGDN 149 +#define K_PGUP 150 +#define K_HOME 151 +#define K_END 152 + +#define K_PAUSE 255 + +// +// mouse buttons generate virtual keys +// +#define K_MOUSE1 200 +#define K_MOUSE2 201 +#define K_MOUSE3 202 + +// +// joystick buttons +// +#define K_JOY1 203 +#define K_JOY2 204 +#define K_JOY3 205 +#define K_JOY4 206 + +// +// aux keys are for multi-buttoned joysticks to generate so they can use +// the normal binding process +// +#define K_AUX1 207 +#define K_AUX2 208 +#define K_AUX3 209 +#define K_AUX4 210 +#define K_AUX5 211 +#define K_AUX6 212 +#define K_AUX7 213 +#define K_AUX8 214 +#define K_AUX9 215 +#define K_AUX10 216 +#define K_AUX11 217 +#define K_AUX12 218 +#define K_AUX13 219 +#define K_AUX14 220 +#define K_AUX15 221 +#define K_AUX16 222 +#define K_AUX17 223 +#define K_AUX18 224 +#define K_AUX19 225 +#define K_AUX20 226 +#define K_AUX21 227 +#define K_AUX22 228 +#define K_AUX23 229 +#define K_AUX24 230 +#define K_AUX25 231 +#define K_AUX26 232 +#define K_AUX27 233 +#define K_AUX28 234 +#define K_AUX29 235 +#define K_AUX30 236 +#define K_AUX31 237 +#define K_AUX32 238 + +// JACK: Intellimouse(c) Mouse Wheel Support + +#define K_MWHEELUP 239 +#define K_MWHEELDOWN 240 + + + +typedef enum {key_game, key_console, key_message, key_menu} keydest_t; + +extern keydest_t key_dest; +extern char *keybindings[256]; +extern int key_repeats[256]; +extern int key_count; // incremented every key event +extern int key_lastpress; + +void Key_Event (int key, qboolean down); +void Key_Init (void); +void Key_WriteBindings (FILE *f); +void Key_SetBinding (int keynum, char *binding); +void Key_ClearStates (void); + diff --git a/r17/Revamped src/revamped_src/mathlib.c b/r17/Revamped src/revamped_src/mathlib.c new file mode 100755 index 00000000..809dcfbc --- /dev/null +++ b/r17/Revamped src/revamped_src/mathlib.c @@ -0,0 +1,594 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// mathlib.c -- math primitives + +#include +#include "quakedef.h" + +void Sys_Error (char *error, ...); + +vec3_t vec3_origin = {0,0,0}; +int nanmask = 255<<23; + +/*-----------------------------------------------------------------*/ + +void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ) +{ + float d; + vec3_t n; + float inv_denom; + + inv_denom = 1.0F / DotProduct( normal, normal ); + + d = DotProduct( normal, p ) * inv_denom; + + n[0] = normal[0] * inv_denom; + n[1] = normal[1] * inv_denom; + n[2] = normal[2] * inv_denom; + + dst[0] = p[0] - d * n[0]; + dst[1] = p[1] - d * n[1]; + dst[2] = p[2] - d * n[2]; +} + +/* +** assumes "src" is normalized +*/ +void PerpendicularVector( vec3_t dst, const vec3_t src ) +{ + int pos; + int i; + float minelem = 1.0F; + vec3_t tempvec; + + /* + ** find the smallest magnitude axially aligned vector + */ + for ( pos = 0, i = 0; i < 3; i++ ) + { + if ( fabsf( src[i] ) < minelem ) + { + pos = i; + minelem = fabsf( src[i] ); + } + } + tempvec[0] = tempvec[1] = tempvec[2] = 0.0F; + tempvec[pos] = 1.0F; + + /* + ** project the point onto the plane defined by src + */ + ProjectPointOnPlane( dst, tempvec, src ); + + /* + ** normalize the result + */ + VectorNormalize( dst ); +} + +#ifdef WIN32 +#pragma optimize( "", off ) +#endif + + +void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ) +{ + float m[3][3]; + float im[3][3]; + float zrot[3][3]; + float tmpmat[3][3]; + float rot[3][3]; + int i; + vec3_t vr, vup, vf; + + vf[0] = dir[0]; + vf[1] = dir[1]; + vf[2] = dir[2]; + + PerpendicularVector( vr, dir ); + CrossProduct( vr, vf, vup ); + + m[0][0] = vr[0]; + m[1][0] = vr[1]; + m[2][0] = vr[2]; + + m[0][1] = vup[0]; + m[1][1] = vup[1]; + m[2][1] = vup[2]; + + m[0][2] = vf[0]; + m[1][2] = vf[1]; + m[2][2] = vf[2]; + + memcpy( im, m, sizeof( im ) ); + + im[0][1] = m[1][0]; + im[0][2] = m[2][0]; + im[1][0] = m[0][1]; + im[1][2] = m[2][1]; + im[2][0] = m[0][2]; + im[2][1] = m[1][2]; + + memset( zrot, 0, sizeof( zrot ) ); + zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F; + + zrot[0][0] = cosf( DEG2RAD( degrees ) ); + zrot[0][1] = sinf( DEG2RAD( degrees ) ); + zrot[1][0] = -sinf( DEG2RAD( degrees ) ); + zrot[1][1] = cosf( DEG2RAD( degrees ) ); + + R_ConcatRotations( m, zrot, tmpmat ); + R_ConcatRotations( tmpmat, im, rot ); + + for ( i = 0; i < 3; i++ ) + { + dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2]; + } +} + +#ifdef WIN32 +#pragma optimize( "", on ) +#endif + +/*-----------------------------------------------------------------*/ + + +float anglemod(float a) +{ +#if 0 + if (a >= 0) + a -= 360*(int)(a/360); + else + a += 360*( 1 + (int)(-a/360) ); +#endif + a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535); + return a; +} + +/* +================== +BOPS_Error + +Split out like this for ASM to call. +================== +*/ +void BOPS_Error (void) +{ + Sys_Error ("BoxOnPlaneSide: Bad signbits"); +} + + +#if !id386 + +/* +================== +BoxOnPlaneSide + +Returns 1, 2, or 1 + 2 +================== +*/ +int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, mplane_t *p) +{ + float dist1, dist2; + int sides; + +#if 0 // this is done by the BOX_ON_PLANE_SIDE macro before calling this + // function +// fast axial cases + if (p->type < 3) + { + if (p->dist <= emins[p->type]) + return 1; + if (p->dist >= emaxs[p->type]) + return 2; + return 3; + } +#endif + +// general case + switch (p->signbits) + { + case 0: +dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; +dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + break; + case 1: +dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; +dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + break; + case 2: +dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; +dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + break; + case 3: +dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; +dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + break; + case 4: +dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; +dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + break; + case 5: +dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; +dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + break; + case 6: +dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; +dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + break; + case 7: +dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; +dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + break; + default: + dist1 = dist2 = 0; // shut up compiler + BOPS_Error (); + break; + } + +#if 0 + int i; + vec3_t corners[2]; + + for (i=0 ; i<3 ; i++) + { + if (plane->normal[i] < 0) + { + corners[0][i] = emins[i]; + corners[1][i] = emaxs[i]; + } + else + { + corners[1][i] = emins[i]; + corners[0][i] = emaxs[i]; + } + } + dist = DotProduct (plane->normal, corners[0]) - plane->dist; + dist2 = DotProduct (plane->normal, corners[1]) - plane->dist; + sides = 0; + if (dist1 >= 0) + sides = 1; + if (dist2 < 0) + sides |= 2; + +#endif + + sides = 0; + if (dist1 >= p->dist) + sides = 1; + if (dist2 < p->dist) + sides |= 2; + +#ifdef PARANOID +if (sides == 0) + Sys_Error ("BoxOnPlaneSide: sides==0"); +#endif + + return sides; +} + +#endif + +void vectoangles (vec3_t vec, vec3_t ang) +{ + float forward, yaw, pitch; + + if (!vec[1] && !vec[0]) + { + yaw = 0; + pitch = (vec[2] > 0) ? 90 : 270; + } + else + { + yaw = atan2 (vec[1], vec[0]) * 180 / M_PI; + if (yaw < 0) + yaw += 360; + + forward = sqrt (vec[0]*vec[0] + vec[1]*vec[1]); + pitch = atan2 (vec[2], forward) * 180 / M_PI; + if (pitch < 0) + pitch += 360; + } + + ang[0] = pitch; + ang[1] = yaw; + ang[2] = 0; +} + +void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) +{ + float angle; + float sr, sp, sy, cr, cp, cy; + + angle = angles[YAW] * (M_PI*2 / 360); + sy = sinf(angle); + cy = cosf(angle); + angle = angles[PITCH] * (M_PI*2 / 360); + sp = sinf(angle); + cp = cosf(angle); + angle = angles[ROLL] * (M_PI*2 / 360); + sr = sinf(angle); + cr = cosf(angle); + + forward[0] = cp*cy; + forward[1] = cp*sy; + forward[2] = -sp; + right[0] = (-1*sr*sp*cy+-1*cr*-sy); + right[1] = (-1*sr*sp*sy+-1*cr*cy); + right[2] = -1*sr*cp; + up[0] = (cr*sp*cy+-sr*-sy); + up[1] = (cr*sp*sy+-sr*cy); + up[2] = cr*cp; +} + +int VectorCompare (vec3_t v1, vec3_t v2) +{ + int i; + + for (i=0 ; i<3 ; i++) + if (v1[i] != v2[i]) + return 0; + + return 1; +} + +void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc) +{ + vecc[0] = veca[0] + scale*vecb[0]; + vecc[1] = veca[1] + scale*vecb[1]; + vecc[2] = veca[2] + scale*vecb[2]; +} + + +vec_t _DotProduct (vec3_t v1, vec3_t v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; +} + +void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out) +{ + out[0] = veca[0]-vecb[0]; + out[1] = veca[1]-vecb[1]; + out[2] = veca[2]-vecb[2]; +} + +void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out) +{ + out[0] = veca[0]+vecb[0]; + out[1] = veca[1]+vecb[1]; + out[2] = veca[2]+vecb[2]; +} + +void _VectorCopy (vec3_t in, vec3_t out) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; +} + +void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross) +{ + cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; + cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; + cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; +} + +vec_t Length(vec3_t v) +{ + return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +} + +float VectorNormalize (vec3_t v) +{ + float length = sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + if (length) + { + const float ilength = 1.0f / length; + v[0] *= ilength; + v[1] *= ilength; + v[2] *= ilength; + } + + return length; + +} + +void VectorInverse (vec3_t v) +{ + v[0] = -v[0]; + v[1] = -v[1]; + v[2] = -v[2]; +} + +void VectorScale (vec3_t in, vec_t scale, vec3_t out) +{ + out[0] = in[0]*scale; + out[1] = in[1]*scale; + out[2] = in[2]*scale; +} + + +int Q_log2(int val) +{ + int answer=0; + while (val>>=1) + answer++; + return answer; +} + + +/* +================ +R_ConcatRotations +================ +*/ +void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]) +{ + out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + + in1[0][2] * in2[2][0]; + out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + + in1[0][2] * in2[2][1]; + out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + + in1[0][2] * in2[2][2]; + out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + + in1[1][2] * in2[2][0]; + out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + + in1[1][2] * in2[2][1]; + out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + + in1[1][2] * in2[2][2]; + out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + + in1[2][2] * in2[2][0]; + out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + + in1[2][2] * in2[2][1]; + out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + + in1[2][2] * in2[2][2]; +} + + +/* +================ +R_ConcatTransforms +================ +*/ +void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]) +{ + out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + + in1[0][2] * in2[2][0]; + out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + + in1[0][2] * in2[2][1]; + out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + + in1[0][2] * in2[2][2]; + out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + + in1[0][2] * in2[2][3] + in1[0][3]; + out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + + in1[1][2] * in2[2][0]; + out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + + in1[1][2] * in2[2][1]; + out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + + in1[1][2] * in2[2][2]; + out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + + in1[1][2] * in2[2][3] + in1[1][3]; + out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + + in1[2][2] * in2[2][0]; + out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + + in1[2][2] * in2[2][1]; + out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + + in1[2][2] * in2[2][2]; + out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + + in1[2][2] * in2[2][3] + in1[2][3]; +} + + +/* +=================== +FloorDivMod + +Returns mathematically correct (floor-based) quotient and remainder for +numer and denom, both of which should contain no fractional part. The +quotient must fit in 32 bits. +==================== +*/ + +void FloorDivMod (float numer, float denom, int *quotient, + int *rem) +{ + int q, r; + float x; + +#ifndef PARANOID + if (denom <= 0.0) + Sys_Error ("FloorDivMod: bad denominator %d\n", denom); + +// if ((floorf(numer) != numer) || (floor(denom) != denom)) +// Sys_Error ("FloorDivMod: non-integer numer or denom %f %f\n", +// numer, denom); +#endif + + if (numer >= 0.0) + { + + x = floorf(numer / denom); + q = (int)x; + r = (int)floorf(numer - (x * denom)); + } + else + { + // + // perform operations with positive values, and fix mod to make floor-based + // + x = floorf(-numer / denom); + q = -(int)x; + r = (int)floorf(-numer - (x * denom)); + if (r != 0) + { + q--; + r = (int)denom - r; + } + } + + *quotient = q; + *rem = r; +} + + +/* +=================== +GreatestCommonDivisor +==================== +*/ +int GreatestCommonDivisor (int i1, int i2) +{ + if (i1 > i2) + { + if (i2 == 0) + return (i1); + return GreatestCommonDivisor (i2, i1 % i2); + } + else + { + if (i1 == 0) + return (i2); + return GreatestCommonDivisor (i1, i2 % i1); + } +} + + +#if !id386 + +// TODO: move to nonintel.c + +/* +=================== +Invert24To16 + +Inverts an 8.24 value to a 16.16 value +==================== +*/ + +fixed16_t Invert24To16(fixed16_t val) +{ + if (val < 256) + return (0xFFFFFFFF); + + return (fixed16_t) + (((float)0x10000 * (float)0x1000000 / (float)val) + 0.5); +} + +#endif diff --git a/r17/Revamped src/revamped_src/mathlib.h b/r17/Revamped src/revamped_src/mathlib.h new file mode 100755 index 00000000..3c20bf09 --- /dev/null +++ b/r17/Revamped src/revamped_src/mathlib.h @@ -0,0 +1,129 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// mathlib.h +#include + +typedef float vec_t; +typedef vec_t vec3_t[3]; +typedef vec_t vec5_t[5]; + +typedef int fixed4_t; +typedef int fixed8_t; +typedef int fixed16_t; + +//#ifdef PSP_SOFTWARE_VIDEO +/* +#ifndef M_PI +#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h +#endif + +#define M_PI_DIV_180 (M_PI / 180.0) //johnfitz +//#define DEG2RAD( a ) ( a * M_PI ) / 180.0F +#define DEG2RAD( a ) ( (a) * M_PI_DIV_180 ) //johnfitz + +//#else +*/ +#ifndef M_PI +#define M_PI = GU_PI // matches value in gcc v2 math.h +#endif + +#define M_PI_DIV_180 (M_PI / 180.0) //johnfitz +//#define DEG2RAD( a ) ( a * M_PI ) / 180.0F +#define DEG2RAD( a ) ( (a) * M_PI_DIV_180 ) //johnfitz +//#endif + +struct mplane_s; + +extern vec3_t vec3_origin; +extern int nanmask; + +#define CLAMP(min, x, max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x)) //johnfitz + +#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) + +#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2]) +#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];} +#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];} +#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];} +#define VectorClear(a) ((a)[0] = (a)[1] = (a)[2] = 0) + +// MDave -- courtesy of johnfitz, lordhavoc +#define VectorNormalizeFast(_v)\ +{\ + float _y, _number;\ + _number = DotProduct(_v, _v);\ + if (_number != 0.0)\ + {\ + *((long *)&_y) = 0x5f3759df - ((* (long *) &_number) >> 1);\ + _y = _y * (1.5f - (_number * 0.5f * _y * _y));\ + VectorScale(_v, _y, _v);\ + }\ +} + +void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc); + +vec_t _DotProduct (vec3_t v1, vec3_t v2); +void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out); +void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out); +void _VectorCopy (vec3_t in, vec3_t out); + +int VectorCompare (vec3_t v1, vec3_t v2); +vec_t Length (vec3_t v); +void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross); +float VectorNormalize (vec3_t v); // returns vector length +void VectorInverse (vec3_t v); +void VectorScale (vec3_t in, vec_t scale, vec3_t out); +int Q_log2(int val); + +void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]); +void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]); + +void FloorDivMod (float numer, float denom, int *quotient, + int *rem); +fixed16_t Invert24To16(fixed16_t val); +int GreatestCommonDivisor (int i1, int i2); + +void vectoangles (vec3_t vec, vec3_t ang); +void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); +int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane); +float anglemod(float a); + + + +#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \ + (((p)->type < 3)? \ + ( \ + ((p)->dist <= (emins)[(p)->type])? \ + 1 \ + : \ + ( \ + ((p)->dist >= (emaxs)[(p)->type])?\ + 2 \ + : \ + 3 \ + ) \ + ) \ + : \ + BoxOnPlaneSide( (emins), (emaxs), (p))) + +// Prototypes added by PM. +void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ); +void VectorVectors (vec3_t forward, vec3_t right, vec3_t up); + diff --git a/r17/Revamped src/revamped_src/menu.c b/r17/Revamped src/revamped_src/menu.c new file mode 100755 index 00000000..cd86c687 --- /dev/null +++ b/r17/Revamped src/revamped_src/menu.c @@ -0,0 +1,5858 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +#include "quakedef.h" + +#ifdef WIN32 +#include "winquake.h" +#endif + +#ifdef PSP +#include +#include +#include "net_dgrm.h" + +extern cvar_t accesspoint; +extern cvar_t r_wateralpha; +extern cvar_t r_vsync; +extern cvar_t r_mipmaps; +extern cvar_t r_mipmaps_bias; +extern cvar_t in_freelook_analog; +extern cvar_t in_disable_analog; +extern cvar_t in_analog_strafe; +extern cvar_t lookspring; + +extern cvar_t in_x_axis_adjust; +extern cvar_t in_y_axis_adjust; +extern cvar_t r_dithering; +extern cvar_t r_i_model_animation; +extern cvar_t t_i_model_transform; +extern cvar_t show_fps; +extern cvar_t sv_aim; +extern cvar_t noexit; + +//////////////////////////////////////////////////////////////////// +// Deathmatch flags +//////////////////////////////////////////////////////////////////// + +int items_respawn = 1; +int weapons_stay; +int pistols; +int automatics; +int shotguns; +int explosives; +int snipers; +int exit_non_fatal; +int infinite_ammo; +int all_weapons; +int no_reload; +int no_armor; +int no_health; +int armor_regen; +int health_regen; +int safe_spawn; +int no_bots; + +refdef_t r_refdef; + +#endif + +extern qboolean bmg_type_changed; + +void (*vid_menudrawfn)(void); +void (*vid_menukeyfn)(int key); + +enum { + m_none, + m_main, + m_singleplayer, + m_load, + m_save, + m_multiplayer, + m_setup, + m_net, + m_options, + m_video, + m_keys, + m_help, + m_quit, + m_serialconfig, + m_modemconfig, + m_lanconfig, + m_gameoptions, + m_doptions, + m_search, + m_slist, + m_osk} +m_state; + +void M_Menu_Main_f (void); + void M_Menu_SinglePlayer_f (void); + void M_Menu_Load_f (void); + void M_Menu_Save_f (void); + void M_Menu_MultiPlayer_f (void); + void M_Menu_Setup_f (void); + void M_Menu_Net_f (void); + void M_Menu_Options_f (void); + void M_Menu_Keys_f (void); + void M_Menu_Video_f (void); + void M_Menu_Help_f (void); + void M_Menu_Quit_f (void); +void M_Menu_SerialConfig_f (void); + void M_Menu_ModemConfig_f (void); +void M_Menu_LanConfig_f (void); +void M_Menu_GameOptions_f (void); +void M_Menu_DOptions_f (void); +void M_Menu_Search_f (void); +void M_Menu_ServerList_f (void); + +void M_Main_Draw (void); + void M_SinglePlayer_Draw (void); + void M_Load_Draw (void); + void M_Save_Draw (void); + void M_MultiPlayer_Draw (void); + void M_Setup_Draw (void); + void M_Net_Draw (void); + void M_Options_Draw (void); + void M_Keys_Draw (void); + void M_Video_Draw (void); + void M_Help_Draw (void); + void M_Quit_Draw (void); +void M_SerialConfig_Draw (void); + void M_ModemConfig_Draw (void); +void M_LanConfig_Draw (void); +void M_GameOptions_Draw (void); +void M_DOptions_Draw (void); +void M_Search_Draw (void); +void M_ServerList_Draw (void); + +void M_Main_Key (int key); +void M_SinglePlayer_Key (int key); + void M_Load_Key (int key); + void M_Save_Key (int key); +void M_MultiPlayer_Key (int key); + void M_Setup_Key (int key); + void M_Net_Key (int key); +void M_Options_Key (int key); + void M_Keys_Key (int key); + void M_Video_Key (int key); +void M_Help_Key (int key); +void M_Quit_Key (int key); +void M_SerialConfig_Key (int key); +void M_ModemConfig_Key (int key); +void M_LanConfig_Key (int key); +void M_GameOptions_Key (int key); +void M_DOptions_Key (int key); +void M_Search_Key (int key); +void M_ServerList_Key (int key); + +void Con_SetOSKActive(qboolean active); +void M_Menu_OSK_f (char *input, char *output, int outlen); + + +qboolean m_entersound; // play after drawing a frame, so caching + // won't disrupt the sound +qboolean m_recursiveDraw; + +int m_return_state; + +//int track; + +qboolean m_return_onerror; +char m_return_reason [32]; + +#define StartingGame (m_multiplayer_cursor == 1) +#define JoiningGame (m_multiplayer_cursor == 0) +#define SerialConfig (m_net_cursor == 0) +#define DirectConfig (m_net_cursor == 1) +#define IPXConfig (m_net_cursor == 2) +#define TCPIPConfig (m_net_cursor == 3) + +void M_ConfigureNetSubsystem(void); + +/* +============= +Sbar_DrawAlphaPic +Alpha = 1 : full alpha which is fully solid +Alpha = 0.5 ... 50% transparency +Alpha = 0.25 ... 75% transparency +Alpha = 0 ... invisible .. not drawn essentially +This function calls Draw_AlphaPic in video_hardware_draw.cpp (PSP)/gl_draw.c (GLQuake) +instead of Draw_Pic (Draw_Pic draws fully solid images). Draw_AlphaPic offers an extra field "alpha" +which can draw fully solid or with transparency/translucency or whatever you like to call it. +============= +*/ +void Menu_DrawAlphaPic (int x, int y, qpic_t *pic, float alpha) +{ + if(kurok) + Draw_AlphaPic (x /* + ((vid.width - 320)>>1)*/, y + (vid.height-SBAR_HEIGHT), pic, alpha); + else + { + if (cl.gametype == GAME_DEATHMATCH) + Draw_AlphaPic (x /* + ((vid.width - 320)>>1)*/, y + + +(vid.height-SBAR_HEIGHT), pic, alpha); + else + Draw_AlphaPic (x + ((vid.width - 320)>>1), y + (vid.height-SBAR_HEIGHT), pic, alpha); + } +} +/* +================ +M_DrawCharacter + +Draws one solid graphics character +================ +*/ +void M_DrawCharacter (int cx, int line, int num) +{ + Draw_Character ( cx + ((vid.width - 320)>>1), line, num); +} + +void M_Print (int cx, int cy, char *str) +{ + while (*str) + { + M_DrawCharacter (cx, cy, (*str)+128); + str++; + cx += 8; + } +} + +void M_PrintWhite (int cx, int cy, char *str) +{ + while (*str) + { + M_DrawCharacter (cx, cy, *str); + str++; + cx += 8; + } +} + +void M_DrawTransPic (int x, int y, qpic_t *pic) +{ + Draw_TransPic (x + ((vid.width - 320)>>1), y, pic); +} + +void M_DrawPic (int x, int y, qpic_t *pic) +{ + Draw_Pic (x + ((vid.width - 320)>>1), y, pic); +} + +byte identityTable[256]; +byte translationTable[256]; + +void M_BuildTranslationTable(int top, int bottom) +{ + int j; + byte *dest, *source; + + for (j = 0; j < 256; j++) + identityTable[j] = j; + dest = translationTable; + source = identityTable; + memcpy (dest, source, 256); + + if (top < 128) // the artists made some backwards ranges. sigh. + memcpy (dest + TOP_RANGE, source + top, 16); + else + for (j=0 ; j<16 ; j++) + dest[TOP_RANGE+j] = source[top+15-j]; + + if (bottom < 128) + memcpy (dest + BOTTOM_RANGE, source + bottom, 16); + else + for (j=0 ; j<16 ; j++) + dest[BOTTOM_RANGE+j] = source[bottom+15-j]; +} + + +void M_DrawTransPicTranslate (int x, int y, qpic_t *pic) +{ + Draw_TransPicTranslate (x + ((vid.width - 320)>>1), y, pic, translationTable); +} + + +void M_DrawTextBox (int x, int y, int width, int lines) +{ + qpic_t *p; + int cx, cy; + int n; + + // draw left side + cx = x; + cy = y; + p = Draw_CachePic ("gfx/box_tl.lmp"); + M_DrawTransPic (cx, cy, p); + p = Draw_CachePic ("gfx/box_ml.lmp"); + for (n = 0; n < lines; n++) + { + cy += 8; + M_DrawTransPic (cx, cy, p); + } + p = Draw_CachePic ("gfx/box_bl.lmp"); + M_DrawTransPic (cx, cy+8, p); + + // draw middle + cx += 8; + while (width > 0) + { + cy = y; + p = Draw_CachePic ("gfx/box_tm.lmp"); + M_DrawTransPic (cx, cy, p); + p = Draw_CachePic ("gfx/box_mm.lmp"); + for (n = 0; n < lines; n++) + { + cy += 8; + if (n == 1) + p = Draw_CachePic ("gfx/box_mm2.lmp"); + M_DrawTransPic (cx, cy, p); + } + p = Draw_CachePic ("gfx/box_bm.lmp"); + M_DrawTransPic (cx, cy+8, p); + width -= 2; + cx += 16; + } + + // draw right side + cy = y; + p = Draw_CachePic ("gfx/box_tr.lmp"); + M_DrawTransPic (cx, cy, p); + p = Draw_CachePic ("gfx/box_mr.lmp"); + for (n = 0; n < lines; n++) + { + cy += 8; + M_DrawTransPic (cx, cy, p); + } + p = Draw_CachePic ("gfx/box_br.lmp"); + M_DrawTransPic (cx, cy+8, p); +} + +void M_DrawCheckbox (int x, int y, int on) +{ +#if 0 + if (on) + M_DrawCharacter (x, y, 131); + else + M_DrawCharacter (x, y, 129); +#endif + if (on) + M_Print (x, y, "on"); + else + M_Print (x, y, "off"); +} + +//============================================================================= + +int m_save_demonum; + +/* +================ +M_ToggleMenu_f +================ +*/ +void M_ToggleMenu_f (void) +{ + m_entersound = true; + + if (key_dest == key_menu) + { + if (m_state != m_main) + { + M_Menu_Main_f (); + return; + } + key_dest = key_game; + m_state = m_none; + return; + } + if (key_dest == key_console) + { + Con_ToggleConsole_f (); + } + else + { + M_Menu_Main_f (); + } +} + + +//============================================================================= +/* MAIN MENU */ + +int m_main_cursor; +#define MAIN_ITEMS 5 + +void M_Menu_Main_f (void) +{ + if (key_dest != key_menu) + { + m_save_demonum = cls.demonum; + cls.demonum = -1; + } + key_dest = key_menu; + m_state = m_main; + m_entersound = true; +} + + +void M_Main_Draw (void) +{ + int f; + qpic_t *p,*b, *s, *m, *o, *h, *q, *t, *bac; + + if (kurok) + { + t = Draw_CachePic ("gfx/menu/title.lmp"); + M_DrawPic ((320-t->width)/2, 16, t); + bac = Draw_CachePic ("gfx/menu/text_box.lmp"); + Menu_DrawAlphaPic (24, -90, bac, 0.5); + + + if (m_main_cursor == 0) + s = Draw_CachePic ("gfx/menu/single_1.lmp"); + else + s = Draw_CachePic ("gfx/menu/single_0.lmp"); + M_DrawPic ((0-s->width)/2, 160, s); + + if (m_main_cursor == 1) + m = Draw_CachePic ("gfx/menu/multi_1.lmp"); + else + m = Draw_CachePic ("gfx/menu/multi_0.lmp"); + M_DrawPic ((0-m->width)/2, 176, m); + + if (m_main_cursor == 2) + o = Draw_CachePic ("gfx/menu/option_1.lmp"); + else + o = Draw_CachePic ("gfx/menu/option_0.lmp"); + M_DrawPic ((0-o->width)/2, 192, o); + + if (m_main_cursor == 3) + h = Draw_CachePic ("gfx/menu/help_1.lmp"); + else + h = Draw_CachePic ("gfx/menu/help_0.lmp"); + M_DrawPic ((0-h->width)/2, 208, h); + + if (m_main_cursor == 4) + q = Draw_CachePic ("gfx/menu/quit_1.lmp"); + else + q = Draw_CachePic ("gfx/menu/quit_0.lmp"); + M_DrawPic ((0-q->width)/2, 224, q); + + } + else + { + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + + p = Draw_CachePic ("gfx/ttl_main.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawTransPic (72, 32, Draw_CachePic ("gfx/mainmenu.lmp") ); + + f = (int)(host_time * 10)%6; + M_DrawTransPic (54, 32 + m_main_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); + } + + b = Draw_CachePic ("gfx/m_bttns.lmp"); + M_DrawPic ( (320-b->width)/2, 248, b ); + + M_Print (120, 0, va("Naievil's Custom: Version %4.2f", (float) KUR_VERSION)); +} + + +void M_Main_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + key_dest = key_game; + m_state = m_none; + cls.demonum = m_save_demonum; + if (cls.demonum != -1 && !cls.demoplayback && cls.state != ca_connected) + CL_NextDemo (); + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + if (++m_main_cursor >= MAIN_ITEMS) + m_main_cursor = 0; + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + if (--m_main_cursor < 0) + m_main_cursor = MAIN_ITEMS - 1; + break; + + case K_ENTER: + m_entersound = true; + + switch (m_main_cursor) + { + case 0: + //M_Menu_SinglePlayer_f (); + break; + + case 1: + M_Menu_MultiPlayer_f (); + break; + + case 2: + M_Menu_Options_f (); + break; + + case 3: + M_Menu_Help_f (); + break; + +// if(!kurok) +// { + case 4: + M_Menu_Quit_f (); + break; +// } + } + } +} + +//============================================================================= +/* SINGLE PLAYER MENU */ + +int m_singleplayer_cursor; +#define SINGLEPLAYER_ITEMS 3 + + +void M_Menu_SinglePlayer_f (void) +{ + key_dest = key_menu; + m_state = m_singleplayer; + m_entersound = true; +} + + +void M_SinglePlayer_Draw (void) +{ + int f; + qpic_t *p,*b, *n, *l, *s, *t; + + b = Draw_CachePic ("gfx/m_bttns.lmp"); + M_DrawPic ( (320-b->width)/2, 248, b ); + + if (kurok) + { + t = Draw_CachePic ("gfx/menu/title.lmp"); + M_DrawPic ((320-t->width)/2, 16, t); + + if (m_singleplayer_cursor == 0) + n = Draw_CachePic ("gfx/menu/sp/new_1.lmp"); + else + n = Draw_CachePic ("gfx/menu/sp/new_0.lmp"); + M_DrawPic ((0-n->width)/2, 160, n); + + if (m_singleplayer_cursor == 1) + l = Draw_CachePic ("gfx/menu/sp/load_1.lmp"); + else + l = Draw_CachePic ("gfx/menu/sp/load_0.lmp"); + M_DrawPic ((0-l->width)/2, 176, l); + + if (m_singleplayer_cursor == 2) + s = Draw_CachePic ("gfx/menu/sp/save_1.lmp"); + else + s = Draw_CachePic ("gfx/menu/sp/save_0.lmp"); + M_DrawPic ((0-s->width)/2, 192, s); + } + else + { + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/ttl_sgl.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawTransPic (72, 32, Draw_CachePic ("gfx/sp_menu.lmp") ); + + f = (int)(host_time * 10)%6; + + M_DrawTransPic (54, 32 + m_singleplayer_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); + } +} + + +void M_SinglePlayer_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + M_Menu_Main_f (); + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + if (++m_singleplayer_cursor >= SINGLEPLAYER_ITEMS) + m_singleplayer_cursor = 0; + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + if (--m_singleplayer_cursor < 0) + m_singleplayer_cursor = SINGLEPLAYER_ITEMS - 1; + break; + + case K_ENTER: + m_entersound = true; + + switch (m_singleplayer_cursor) + { + case 0: + /* + if (sv.active) + if (!SCR_ModalMessage("Are you sure you want to\nstart a new game?\n")) + break; + */ + key_dest = key_game; + if (sv.active) + Cbuf_AddText ("disconnect\n"); + Cbuf_AddText ("maxplayers 1\n"); + + if(kurok) + Cbuf_AddText ("viewsize 120\n cl_gunpitch 0\n fov 90\n scr_ofsy 0\n cl_autoaim 1\n chase_active 0\n"); + + // If we were in a multiplayer game, reset all the deathmatch flags to 0; + + items_respawn = 1; + weapons_stay = + pistols = + automatics = + shotguns = + explosives = + snipers = + exit_non_fatal = + infinite_ammo = + all_weapons = + no_reload = + no_armor = + no_health = + armor_regen = + health_regen = + safe_spawn = + no_bots = 0; + + Cbuf_AddText ("map start\n"); + break; + + case 1: + M_Menu_Load_f (); + break; + + case 2: + M_Menu_Save_f (); + break; + } + } +} + +//============================================================================= +/* LOAD/SAVE MENU */ + +int load_cursor; // 0 < load_cursor < MAX_SAVEGAMES + +#define MAX_SAVEGAMES 12 +char m_filenames[MAX_SAVEGAMES][SAVEGAME_COMMENT_LENGTH+1]; +int loadable[MAX_SAVEGAMES]; + +void M_ScanSaves (void) +{ + int i, j; + char name[MAX_OSPATH]; + FILE *f; + int version; + + for (i=0 ; iwidth)/2, 248, b ); + + if (kurok) + { + p = Draw_CachePic ("gfx/menu/sp/load_0.lmp"); + // line cursor + M_DrawCharacter (8, 32 + load_cursor*8, 12+((int)(realtime*30)&1)); + } + else + { + p = Draw_CachePic ("gfx/p_load.lmp"); + // line cursor + M_DrawCharacter (8, 32 + load_cursor*8, 12+((int)(realtime*4)&1)); + } + M_DrawPic ( (320-p->width)/2, 4, p); + + for (i=0 ; i< MAX_SAVEGAMES; i++) + M_Print (16, 32 + 8*i, m_filenames[i]); + + +} + + +void M_Save_Draw (void) +{ + int i; + qpic_t *p, *b; + + b = Draw_CachePic ("gfx/m_bttns.lmp"); + M_DrawPic ( (320-b->width)/2, 248, b ); + + if (kurok) + { + p = Draw_CachePic ("gfx/menu/sp/save_0.lmp"); + // line cursor + M_DrawCharacter (8, 32 + load_cursor*8, 12+((int)(realtime*30)&1)); + } + else + { + p = Draw_CachePic ("gfx/p_save.lmp"); + // line cursor + M_DrawCharacter (8, 32 + load_cursor*8, 12+((int)(realtime*4)&1)); + } + M_DrawPic ( (320-p->width)/2, 4, p); + + for (i=0 ; i= MAX_SAVEGAMES) + load_cursor = 0; + break; + } +} + + +void M_Save_Key (int k) +{ + switch (k) + { + case K_ESCAPE: + M_Menu_SinglePlayer_f (); + break; + + case K_ENTER: + m_state = m_none; + key_dest = key_game; + Cbuf_AddText (va("save s%i\n", load_cursor)); + return; + + case K_UPARROW: + case K_LEFTARROW: + S_LocalSound ("misc/menu1.wav"); + load_cursor--; + if (load_cursor < 0) + load_cursor = MAX_SAVEGAMES-1; + break; + + case K_DOWNARROW: + case K_RIGHTARROW: + S_LocalSound ("misc/menu1.wav"); + load_cursor++; + if (load_cursor >= MAX_SAVEGAMES) + load_cursor = 0; + break; + } +} + +//============================================================================= +/* MULTIPLAYER MENU */ + +int m_multiplayer_cursor; + +#ifdef PSP +#define MULTIPLAYER_ITEMS 9 +#else +#define MULTIPLAYER_ITEMS 3 +#endif + +void M_Menu_MultiPlayer_f (void) +{ + key_dest = key_menu; + m_state = m_multiplayer; + m_entersound = true; +} + + +void M_MultiPlayer_Draw (void) +{ + int f; + + qpic_t *p,*b, *j, *c, *t, *i, *a; + + b = Draw_CachePic ("gfx/m_bttns.lmp"); + M_DrawPic ( (320-b->width)/2, 248, b ); + + if (kurok) + { +// M_DrawTransPic (72, 32, Draw_CachePic ("gfx/menu/multi_0.lmp") ); + + if (m_multiplayer_cursor == 0) + j = Draw_CachePic ("gfx/menu/mp/join_1.lmp"); + else + j = Draw_CachePic ("gfx/menu/mp/join_0.lmp"); + M_DrawPic ((0-j->width)/2, 72, j); + + if (m_multiplayer_cursor == 1) + c = Draw_CachePic ("gfx/menu/mp/create_1.lmp"); + else + c = Draw_CachePic ("gfx/menu/mp/create_0.lmp"); + M_DrawPic ((0-c->width)/2, 88, c); + + if (m_multiplayer_cursor == 2) + t = Draw_CachePic ("gfx/menu/mp/setup_1.lmp"); + else + t = Draw_CachePic ("gfx/menu/mp/setup_0.lmp"); + M_DrawPic ((0-t->width)/2, 104, t); + + if (m_multiplayer_cursor == 3) + i = Draw_CachePic ("gfx/menu/mp/inf_1.lmp"); + else + i = Draw_CachePic ("gfx/menu/mp/inf_0.lmp"); + M_DrawPic ((0-i->width)/2, 128, i); + + M_DrawCheckbox ((320/2) - ((3*8)/2), 144, tcpipAvailable && !tcpipAdhoc); + + if (m_multiplayer_cursor == 4) + a = Draw_CachePic ("gfx/menu/mp/adhoc_1.lmp"); + else + a = Draw_CachePic ("gfx/menu/mp/adhoc_0.lmp"); + M_DrawPic ((0-a->width)/2, 152, a); + + M_DrawCheckbox ((320/2) - ((3*8)/2), 168, tcpipAvailable && tcpipAdhoc); + + if (m_multiplayer_cursor == 5) + M_PrintWhite ((0/2) - ((8*8)/2), 184, "Add Bot"); + else + M_Print ((0/2) - ((8*8)/2), 184, "Add Bot"); + + if (m_multiplayer_cursor == 6) + M_PrintWhite ((0/2) - ((12*8)/2), 192, "Add Team Bot"); + else + M_Print ((0/2) - ((12*8)/2), 192, "Add Team Bot"); + + if (m_multiplayer_cursor == 7) + M_PrintWhite ((0/2) - ((10*8)/2), 200, "Remove Bot"); + else + M_Print ((0/2) - ((10*8)/2), 200, "Remove Bot"); + + if (m_multiplayer_cursor == 8) + M_PrintWhite ((46) - ((26*8)/2), 216, "Co-op Player Camera Change"); + else + M_Print ((46) - ((26*8)/2), 216, "Co-op Player Camera Change"); + + if (serialAvailable || ipxAvailable || tcpipAvailable) + return; + M_PrintWhite ((50) - ((27*8)/2), 232, "No Communications Available"); + } + else + { + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + M_DrawTransPic (72, 32, Draw_CachePic ("gfx/mp_menu.lmp") ); + + f = (int)(host_time * 10)%6; + + M_DrawTransPic (54, 32 + m_multiplayer_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); + + #ifdef PSP + M_Print (72, 97, "Infrastructure "); + M_DrawCheckbox (220, 97, tcpipAvailable && !tcpipAdhoc); + + M_Print (72, 117, "Adhoc "); + M_DrawCheckbox (220, 117, tcpipAvailable && tcpipAdhoc); + #endif + + M_Print (72, 137, "Add Bot "); + M_Print (72, 157, "Add Team Bot "); + M_Print (72, 177, "Remove Bot "); + M_Print (72, 197, "Co-op Player Camera Change"); + + if (serialAvailable || ipxAvailable || tcpipAvailable) + return; + M_PrintWhite ((320/2) - ((27*8)/2), 207, "No Communications Available"); + + } +} + + +void M_MultiPlayer_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + M_Menu_Main_f (); + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + if (++m_multiplayer_cursor >= MULTIPLAYER_ITEMS) + m_multiplayer_cursor = 0; + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + if (--m_multiplayer_cursor < 0) + m_multiplayer_cursor = MULTIPLAYER_ITEMS - 1; + break; + + case K_ENTER: + m_entersound = true; + switch (m_multiplayer_cursor) + { + case 0: + if (serialAvailable || ipxAvailable || tcpipAvailable) + M_Menu_LanConfig_f (); + break; + + case 1: + if (serialAvailable || ipxAvailable || tcpipAvailable) + M_Menu_LanConfig_f (); + else + M_Menu_GameOptions_f (); + break; + + case 2: + M_Menu_Setup_f (); + break; + +#ifdef PSP + case 3: + Datagram_Shutdown(); + + tcpipAvailable = !tcpipAvailable; + + if(tcpipAvailable) { + tcpipAdhoc = false; + net_driver_to_use = 0; + Datagram_Init(); + } + + break; + + case 4: + Datagram_Shutdown(); + + tcpipAvailable = !tcpipAvailable; + + if(tcpipAvailable) { + tcpipAdhoc = true; + net_driver_to_use = 1; + Datagram_Init(); + } + + break; + + case 5: // add bot + Cbuf_AddText ("impulse 101\n"); + break; + + case 6: // add team bot + Cbuf_AddText ("impulse 100\n"); + break; + + case 7: // remove bot + Cbuf_AddText ("impulse 102\n"); + break; + + case 8: // player camera switch + if (coop.value) + Cbuf_AddText ("impulse 103\n"); + break; + +#endif + } + } +} + +//============================================================================= +/* SETUP MENU */ + +#ifndef PSP +int setup_cursor = 4; +int setup_cursor_table[] = {40, 56, 80, 104, 140}; +#else +int setup_cursor = 5; +int setup_cursor_table[] = {40, 56, 72, 96, 120, 156}; +#endif + +char setup_hostname[16]; +char setup_myname[16]; +int setup_oldtop; +int setup_oldbottom; +int setup_top; +int setup_bottom; + +#ifndef PSP +#define NUM_SETUP_CMDS 5 +#else +// Define PSP specific variables +#define NUM_SETUP_CMDS 6 +extern int totalAccessPoints; +extern int accessPointNumber[100]; +char setup_accesspoint[64]; +#endif + +void M_Menu_Setup_f (void) +{ + key_dest = key_menu; + m_state = m_setup; + m_entersound = true; + Q_strcpy(setup_myname, cl_name.string); + Q_strcpy(setup_hostname, hostname.string); + setup_top = setup_oldtop = ((int)cl_color.value) >> 4; + setup_bottom = setup_oldbottom = ((int)cl_color.value) & 15; + +#ifdef PSP + if(totalAccessPoints) + { + sceUtilityGetNetParam(accessPointNumber[(int)accesspoint.value], 0, (netData*)setup_accesspoint); + } +#endif +} + +int M_ColorForMap (int m) +{ + return m < 128 ? m + 8 : m + 8; +} + +void M_Setup_Draw (void) +{ + qpic_t *p,*b; + int offset = 0; + int top, bottom, tc, bc; + + if (kurok) + { + if (setup_cursor == 0+offset) + M_DrawCharacter (168 + 8*strlen(setup_hostname), setup_cursor_table [setup_cursor], 10+((int)(realtime*30)&1)); + + if (setup_cursor == 1+offset) + M_DrawCharacter (168 + 8*strlen(setup_myname), setup_cursor_table [setup_cursor], 10+((int)(realtime*30)&1)); + } + else + { + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + + if (setup_cursor == 0+offset) + M_DrawCharacter (168 + 8*strlen(setup_hostname), setup_cursor_table [setup_cursor], 10+((int)(realtime*4)&1)); + + if (setup_cursor == 1+offset) + M_DrawCharacter (168 + 8*strlen(setup_myname), setup_cursor_table [setup_cursor], 10+((int)(realtime*4)&1)); + } + b = Draw_CachePic ("gfx/m_bttns.lmp"); + M_DrawPic ( (320-b->width)/2, 248, b ); + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + +#ifdef PSP + offset = 16; + + M_Print (64, 40, "Access Point"); + M_DrawTextBox (160, 32, 16, 1); + M_Print (168, 40, setup_accesspoint); +#endif + + M_Print (64, 40+offset, "Host name"); + M_DrawTextBox (160, 32+offset, 16, 1); + M_Print (168, 56, setup_hostname); + + M_Print (64, 56+offset, "Player name"); + M_DrawTextBox (160, 48+offset, 16, 1); + M_Print (168, 56+offset, setup_myname); + + if(!kurok) + { + M_Print (64, 80+offset, "Top color"); + M_Print (64, 104+offset, "Bottom color"); + } + else + { + M_Print (64, 80+offset, "Top color"); + M_Print (64, 104+offset, "Team color"); + } + + M_DrawTextBox (64, 140+offset-8, 14, 1); + M_Print (72, 140+offset, "Accept Changes"); + + p = Draw_CachePic ("gfx/bigbox.lmp"); + M_DrawTransPic (160, 64+offset, p); + + tc = (setup_top & 15)<<4; + bc = (setup_bottom & 15)<<4; + top = M_ColorForMap (tc); + bottom = M_ColorForMap (bc); + + Draw_Fill ( 248, 72+offset, 56, 28, top); + Draw_Fill ( 248, 72+28+offset, 56, 28, bottom); + + if(!kurok) + { + p = Draw_CachePic ("gfx/menuplyr.lmp"); +// M_BuildTranslationTable(setup_top*16, setup_bottom*16); +// M_DrawTransPicTranslate (172, 72+offset, p); + M_DrawTransPic (172, 72+offset, p); + } + + M_DrawCharacter (56, setup_cursor_table [setup_cursor], 12+((int)(realtime*4)&1)); + +#ifndef PSP + offset = 0; +#else + offset = 1; +#endif +} + + +void M_Setup_Key (int k) +{ + int l; + int offset = 0; + + switch (k) + { + case K_ESCAPE: + M_Menu_MultiPlayer_f (); + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + setup_cursor--; + if (setup_cursor < 0) + setup_cursor = NUM_SETUP_CMDS-1; + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + setup_cursor++; + if (setup_cursor >= NUM_SETUP_CMDS) + setup_cursor = 0; + break; + + case K_LEFTARROW: +#ifdef PSP + if (setup_cursor == 0) + { + S_LocalSound ("misc/menu3.wav"); + if(accesspoint.value > 1) + { + Cvar_SetValue("accesspoint", accesspoint.value-1); + sceUtilityGetNetParam(accessPointNumber[(int)accesspoint.value], 0, (netData*)setup_accesspoint); + } + } + offset = 1; +#endif + if (setup_cursor < 2+offset) + return; + S_LocalSound ("misc/menu3.wav"); + if (setup_cursor == 2+offset) + setup_top = setup_top - 1; + if (setup_cursor == 3+offset) + { + if(!kurok) + setup_bottom = setup_bottom - 1; + else + setup_bottom = 4; + } + + break; + case K_RIGHTARROW: +#ifdef PSP + if (setup_cursor == 0) + { + S_LocalSound ("misc/menu3.wav"); + if(accesspoint.value < totalAccessPoints) + { + Cvar_SetValue("accesspoint", accesspoint.value+1); + sceUtilityGetNetParam(accessPointNumber[(int)accesspoint.value], 0, (netData*)setup_accesspoint); + } + } + + offset = 1; +#endif + + if (setup_cursor < 2+offset) + return; +forward: + S_LocalSound ("misc/menu3.wav"); + if (setup_cursor == 2+offset) + setup_top = setup_top + 1; + if (setup_cursor == 3+offset) + { + if(!kurok) + setup_bottom = setup_bottom + 1; + else + setup_bottom = 13; + } + + break; + + case K_INS: +#ifdef PSP + offset = 1; +#endif + if (setup_cursor == 0+offset) + { + M_Menu_OSK_f(setup_hostname, setup_hostname, 16); + break; + } + + if (setup_cursor == 1+offset) + { + M_Menu_OSK_f(setup_myname, setup_myname,16); + break; + } + break; + + case K_ENTER: +#ifdef PSP + offset = 1; +#endif + if (setup_cursor == 0+offset || setup_cursor == 1+offset) + return; + + if (setup_cursor == 2+offset || setup_cursor == 3+offset) + goto forward; + + if (setup_cursor < 4+offset) + break; + + // setup_cursor == 4 (OK) + if (Q_strcmp(cl_name.string, setup_myname) != 0) + Cbuf_AddText ( va ("name \"%s\"\n", setup_myname) ); + if (Q_strcmp(hostname.string, setup_hostname) != 0) + Cvar_Set("hostname", setup_hostname); + if (setup_top != setup_oldtop || setup_bottom != setup_oldbottom) + Cbuf_AddText( va ("color %i %i\n", setup_top, setup_bottom) ); + m_entersound = true; + M_Menu_MultiPlayer_f (); + break; + + case K_BACKSPACE: +#ifdef PSP + offset = 1; +#endif + if (setup_cursor == 0+offset) + { + if (strlen(setup_hostname)) + setup_hostname[strlen(setup_hostname)-1] = 0; + } + + if (setup_cursor == 1+offset) + { + if (strlen(setup_myname)) + setup_myname[strlen(setup_myname)-1] = 0; + } + break; + + default: + if (k < 32 || k > 127) + break; + +#ifdef PSP + offset = 1; +#endif + + if (setup_cursor == 0+offset) + { + l = strlen(setup_hostname); + if (l < 15) + { + setup_hostname[l+1] = 0; + setup_hostname[l] = k; + } + } + if (setup_cursor == 1+offset) + { + l = strlen(setup_myname); + if (l < 15) + { + setup_myname[l+1] = 0; + setup_myname[l] = k; + } + } + } + + if (setup_top > 13) + setup_top = 0; + if (setup_top < 0) + setup_top = 13; + if (setup_bottom > 13) + setup_bottom = 0; + if (setup_bottom < 0) + setup_bottom = 13; +} + +//============================================================================= +/* NET MENU */ + +int m_net_cursor; +int m_net_items; +int m_net_saveHeight; + +char *net_helpMessage [] = +{ +/* .........1.........2.... */ + " ", + " Two computers connected", + " through two modems. ", + " ", + + " ", + " Two computers connected", + " by a null-modem cable. ", + " ", + + " Novell network LANs ", + " or Windows 95 DOS-box. ", + " ", + "(LAN=Local Area Network)", + + " Commonly used to play ", + " over the Internet, but ", + " also used on a Local ", + " Area Network. " +}; + +void M_Menu_Net_f (void) +{ + key_dest = key_menu; + m_state = m_net; + m_entersound = true; + m_net_items = 4; + + if (m_net_cursor >= m_net_items) + m_net_cursor = 0; + m_net_cursor--; + M_Net_Key (K_DOWNARROW); +} + + +void M_Net_Draw (void) +{ + int f; + qpic_t *p,*b; + + if (!kurok) + { + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + } + b = Draw_CachePic ("gfx/m_bttns.lmp"); + M_DrawPic ( (320-b->width)/2, 248, b ); + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + f = 32; + + if (serialAvailable) + { + p = Draw_CachePic ("gfx/netmen1.lmp"); + } + else + { +#ifdef WIN32 + p = NULL; +#else + p = Draw_CachePic ("gfx/dim_modm.lmp"); +#endif + } + + if (p) + M_DrawTransPic (72, f, p); + + f += 19; + + if (serialAvailable) + { + p = Draw_CachePic ("gfx/netmen2.lmp"); + } + else + { +#ifdef WIN32 + p = NULL; +#else + p = Draw_CachePic ("gfx/dim_drct.lmp"); +#endif + } + + if (p) + M_DrawTransPic (72, f, p); + + f += 19; + if (ipxAvailable) + p = Draw_CachePic ("gfx/netmen3.lmp"); + else + p = Draw_CachePic ("gfx/dim_ipx.lmp"); + M_DrawTransPic (72, f, p); + + f += 19; + if (tcpipAvailable) + p = Draw_CachePic ("gfx/netmen4.lmp"); + else + p = Draw_CachePic ("gfx/dim_tcp.lmp"); + M_DrawTransPic (72, f, p); + + if (m_net_items == 5) // JDC, could just be removed + { + f += 19; + p = Draw_CachePic ("gfx/netmen5.lmp"); + M_DrawTransPic (72, f, p); + } + + f = (320-26*8)/2; + M_DrawTextBox (f, 134, 24, 4); + f += 8; + M_Print (f, 142, net_helpMessage[m_net_cursor*4+0]); + M_Print (f, 150, net_helpMessage[m_net_cursor*4+1]); + M_Print (f, 158, net_helpMessage[m_net_cursor*4+2]); + M_Print (f, 166, net_helpMessage[m_net_cursor*4+3]); + + f = (int)(host_time * 10)%6; + M_DrawTransPic (54, 32 + m_net_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); +} + + +void M_Net_Key (int k) +{ +again: + switch (k) + { + case K_ESCAPE: + M_Menu_MultiPlayer_f (); + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + if (++m_net_cursor >= m_net_items) + m_net_cursor = 0; + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + if (--m_net_cursor < 0) + m_net_cursor = m_net_items - 1; + break; + + case K_ENTER: + m_entersound = true; + + switch (m_net_cursor) + { + case 0: + M_Menu_SerialConfig_f (); + break; + + case 1: + M_Menu_SerialConfig_f (); + break; + + case 2: + M_Menu_LanConfig_f (); + break; + + case 3: + M_Menu_LanConfig_f (); + break; + + case 4: +// multiprotocol + break; + } + } + + if (m_net_cursor == 0 && !serialAvailable) + goto again; + if (m_net_cursor == 1 && !serialAvailable) + goto again; + if (m_net_cursor == 2 && !ipxAvailable) + goto again; + if (m_net_cursor == 3 && !tcpipAvailable) + goto again; +} + +//============================================================================= +/* OPTIONS MENU */ +#define SLIDER_RANGE 10 +#define NUM_SUBMENU 4 +#define KNUM_SUBMENU 4 +#ifdef PSP_HARDWARE_VIDEO +enum +{ + OPT_CUSTOMIZE = 0, + OPT_CONSOLE, + OPT_GAP, + OPT_DEFAULTS1, +// OPT_DEFAULTS2, +// OPT_DEFAULTS3, + OPT_GAP1, + OPT_SUBMENU, + OPTIONS_ITEMS +}; +enum +{ + OPT_SUBMENU_0 = OPT_SUBMENU, + OPT_GAP_0, + OPT_MOUSELOOK, + OPT_MOUSESTRAFE, + OPT_AUTOCENTER, + OPT_GAP_0_1, + OPT_IN_SPEED, + OPT_IN_X_ADJUST, + OPT_IN_Y_ADJUST, + OPT_IN_TOLERANCE, + OPT_IN_ACCELERATION, + OPT_GAP_0_2, + OPT_ALWAYRUN, + OPT_INVMOUSE, + OPT_NOMOUSE, + OPTIONS_ITEMS_0 +}; +enum +{ + OPT_SUBMENU_1 = OPT_SUBMENU, + OPT_GAP_1, + OPT_GAMMA, + OPT_MAXFPS, + OPT_GAP_1_1, + OPT_DYNAMIC, + OPT_MODEL_BRIGHTNESS, + OPT_SIMPLE_PART, + OPT_MIPMAPS, + OPT_ANTIALIAS, + OPT_VSYNC, + OPT_FPS, + OPTIONS_ITEMS_1 +}; + +enum +{ + OPT_SUBMENU_2 = OPT_SUBMENU, + OPT_GAP_2, +// OPT_MUSICTRACK, + OPT_MUSICVOL, + OPT_SNDVOL, + OPT_GAP_2_1, +// OPT_MUSICTYPE, + OPTIONS_ITEMS_2 +}; + +enum +{ + OPT_SUBMENU_3 = OPT_SUBMENU, + OPT_GAP_3, + OPT_FOG_START, + OPT_FOG_END, + OPT_FOG_RED, + OPT_FOG_GREEN, + OPT_FOG_BLUE, + OPT_GAP_3_1, + OPT_SCRSIZE, + OPT_WATERTRANS, + OPT_MIPMAP_BIAS, + OPT_TEX_SCALEDOWN, + OPT_SMOOTH_ANIMS, + OPT_SMOOTH_MOVEMENT, + OPTIONS_ITEMS_3 +}; + +#else +enum +{ + OPT_CUSTOMIZE = 0, + OPT_CONSOLE, + OPT_DEFAULTS, + OPT_SUBMENU, + OPTIONS_ITEMS +}; +enum +{ + OPT_SUBMENU_0 = OPT_SUBMENU, + //OPT_GAP_0, + OPT_SCRSIZE, + OPT_GAMMA, + OPT_VSYNC, + //OPT_GAP_0_1, + OPT_MUSICTYPE, + OPT_MUSICVOL, + OPT_SNDVOL, + OPTIONS_ITEMS_0 +}; +enum +{ + OPT_SUBMENU_1 = OPT_SUBMENU, + //OPT_GAP_1, + OPT_ALWAYRUN, + OPT_IN_SPEED, + OPT_IN_TOLERANCE, + OPT_IN_ACCELERATION, + OPT_INVMOUSE, + OPT_NOMOUSE, + OPT_MOUSELOOK, + OPT_MOUSESTAFE, + OPT_IN_X_ADJUST, + OPT_IN_Y_ADJUST, + OPTIONS_ITEMS_1 +}; +#endif + +int options_cursor; +int m_submenu = 0; + +void M_Menu_Options_f (void) +{ + key_dest = key_menu; + m_state = m_options; + m_entersound = true; +} + +#ifdef PSP_HARDWARE_VIDEO +extern int changeMp3Volume; +#endif + +void M_AdjustSliders (int dir) +{ + S_LocalSound ("misc/menu3.wav"); + + switch (options_cursor) + { + case OPT_SUBMENU: + m_submenu += dir; + if (kurok) + { + if (m_submenu > KNUM_SUBMENU-1) + m_submenu = 0; + else if (m_submenu < 0) + m_submenu = KNUM_SUBMENU-1; + break; + } + else + { + if (m_submenu > NUM_SUBMENU-1) + m_submenu = 0; + else if (m_submenu < 0) + m_submenu = NUM_SUBMENU-1; + break; + } + } + + if (m_submenu == 0) + { + switch (options_cursor) + { + case OPT_IN_SPEED: // mouse speed + in_sensitivity.value += dir * 1; + if (in_sensitivity.value < 1) + in_sensitivity.value = 1; + if (in_sensitivity.value > 33) + in_sensitivity.value = 33; + Cvar_SetValue ("sensitivity", in_sensitivity.value); + break; + + case OPT_IN_TOLERANCE: // mouse tolerance + in_tolerance.value += dir * 0.01; + if (in_tolerance.value < 0) + in_tolerance.value = 0; + if (in_tolerance.value > 0.5) + in_tolerance.value = 0.5; + Cvar_SetValue ("tolerance", in_tolerance.value); + break; + + case OPT_IN_ACCELERATION: // mouse tolerance + in_acceleration.value -= dir * 0.25; + if (in_acceleration.value < 0.5) + in_acceleration.value = 0.5; + if (in_acceleration.value > 2) + in_acceleration.value = 2; + Cvar_SetValue ("acceleration", in_acceleration.value); + break; + + case OPT_IN_X_ADJUST: + in_x_axis_adjust.value += dir * 1; + if (in_x_axis_adjust.value < 1) + in_x_axis_adjust.value = 1; + if (in_x_axis_adjust.value > 11) + in_x_axis_adjust.value = 11; + Cvar_SetValue ("in_x_axis_adjust", in_x_axis_adjust.value); + break; + + case OPT_IN_Y_ADJUST: + in_y_axis_adjust.value += dir * 1; + if (in_y_axis_adjust.value < 1) + in_y_axis_adjust.value = 1; + if (in_y_axis_adjust.value > 11) + in_y_axis_adjust.value = 11; + Cvar_SetValue ("in_y_axis_adjust", in_y_axis_adjust.value); + break; + + case OPT_INVMOUSE: // invert mouse + Cvar_SetValue ("m_pitch", -m_pitch.value); + break; + + case OPT_NOMOUSE: // disable mouse + Cvar_SetValue ("in_disable_analog", !in_disable_analog.value); + break; + + case OPT_AUTOCENTER: // auto center looking for digital keys + Cvar_SetValue ("lookcenter", !lookcenter.value); + break; + + case OPT_MOUSESTRAFE: + Cvar_SetValue ("in_analog_strafe", !in_analog_strafe.value); + break; + + case OPT_MOUSELOOK: + Cvar_SetValue ("in_freelook_analog", !in_freelook_analog.value); + break; + + case OPT_ALWAYRUN: // allways run + if (kurok) + { + if (cl_forwardspeed.value > 150) + { + Cvar_SetValue ("cl_forwardspeed", 150); + Cvar_SetValue ("cl_backspeed", 150); + } + else + { + Cvar_SetValue ("cl_forwardspeed", 200); + Cvar_SetValue ("cl_backspeed", 200); + } + } + else + { + if (cl_forwardspeed.value > 200) + { + Cvar_SetValue ("cl_forwardspeed", 200); + Cvar_SetValue ("cl_backspeed", 200); + } + else + { + Cvar_SetValue ("cl_forwardspeed", 400); + Cvar_SetValue ("cl_backspeed", 400); + } + } + break; + } + } + else if (m_submenu == 1) + { + switch (options_cursor) + { + case OPT_GAMMA: // gamma + v_gamma.value -= dir * 0.05; + if (v_gamma.value < 0.5) + v_gamma.value = 0.5; + if (v_gamma.value > 1) + v_gamma.value = 1; + Cvar_SetValue ("gamma", v_gamma.value); + break; + + case OPT_MAXFPS: // frame rate controller + max_fps.value += dir * 5; + if (max_fps.value < 30) + max_fps.value = 30; + if (max_fps.value > 65) + max_fps.value = 65; + Cvar_SetValue ("max_fps", max_fps.value); + break; + + case OPT_VSYNC: + Cvar_SetValue ("r_vsync", !r_vsync.value); + break; + + case OPT_MODEL_BRIGHTNESS: + Cvar_SetValue ("r_model_brightness", !r_model_brightness.value); + break; + + case OPT_FPS: + Cvar_SetValue ("show_fps", !show_fps.value); + break; + + case OPT_DYNAMIC: + Cvar_SetValue ("r_dynamic", !r_dynamic.value); + break; +#ifdef PSP_HARDWARE_VIDEO + case OPT_SIMPLE_PART: + Cvar_SetValue ("r_particles_simple", !r_particles_simple.value); + break; + + case OPT_ANTIALIAS: + Cvar_SetValue ("r_antialias", !r_antialias.value); + break; + + case OPT_MIPMAPS: + Cvar_SetValue ("r_mipmaps", !r_mipmaps.value); + break; +#endif + } + } + else if (m_submenu == 2) + { + switch (options_cursor) + { +/* + case OPT_MUSICTRACK: + track += dir * 1; + if (track < 1) + track = 1; + if (track > 13) + track = 13; + Cvar_SetValue ("cd play", track); + break; +*/ + case OPT_MUSICVOL: // music volume +#ifdef WIN32 + bgmvolume.value += dir * 1.0; +#else + bgmvolume.value += dir * 0.1; +#endif + if (bgmvolume.value < 0) + bgmvolume.value = 0; + if (bgmvolume.value > 1) + bgmvolume.value = 1; + Cvar_SetValue ("bgmvolume", bgmvolume.value); +#ifdef PSP_MP3HARDWARE_MP3LIB + changeMp3Volume = 1; +#endif + break; + + case OPT_SNDVOL: // sfx volume + volume.value += dir * 0.1; + if (volume.value < 0) + volume.value = 0; + if (volume.value > 1) + volume.value = 1; + Cvar_SetValue ("volume", volume.value); + break; +/* + case OPT_MUSICTYPE: // bgm type + if (strcmpi(bgmtype.string,"cd") == 0) + { + Cvar_Set("bgmtype","none"); + bmg_type_changed = true; + } + else + { + Cvar_Set("bgmtype","cd"); + bmg_type_changed = true; + } + break; +*/ + } + } + else if (m_submenu == 3) + { + switch (options_cursor) + { + case OPT_FOG_START: // Fog start distance from viewpoint + r_refdef.fog_start += dir * 100; + if (r_refdef.fog_start < -5000) + r_refdef.fog_start = -5000; + if (r_refdef.fog_start > 5000) + r_refdef.fog_start = 5000; + break; + + case OPT_FOG_END: // Fog end distance from viewpoint + r_refdef.fog_end += dir * 100; + if (r_refdef.fog_end < -5000) + r_refdef.fog_end = -5000; + if (r_refdef.fog_end > 5000) + r_refdef.fog_end = 5000; + break; + + case OPT_FOG_RED: // Fog red + r_refdef.fog_red += dir * 5; + if (r_refdef.fog_red < 0) + r_refdef.fog_red = 0; + if (r_refdef.fog_red > 100) + r_refdef.fog_red = 100; + break; + + case OPT_FOG_GREEN: // Fog green + r_refdef.fog_green += dir * 5; + if (r_refdef.fog_green < 0) + r_refdef.fog_green = 0; + if (r_refdef.fog_green > 100) + r_refdef.fog_green = 100; + break; + + case OPT_FOG_BLUE: // Fog blue + r_refdef.fog_blue += dir * 5; + if (r_refdef.fog_blue < 0) + r_refdef.fog_blue = 0; + if (r_refdef.fog_blue > 100) + r_refdef.fog_blue = 100; + break; + + case OPT_SCRSIZE: // screen size + scr_viewsize.value += dir * 10; + if (scr_viewsize.value < 30) + scr_viewsize.value = 30; + if (scr_viewsize.value > 130) + scr_viewsize.value = 130; + Cvar_SetValue ("viewsize", scr_viewsize.value); + break; + + case OPT_WATERTRANS: // wateralpha + r_wateralpha.value += dir * 0.1; + if (r_wateralpha.value < 0) + r_wateralpha.value = 0; + if (r_wateralpha.value > 1) + r_wateralpha.value = 1; + + Cvar_SetValue ("r_wateralpha", r_wateralpha.value); + break; + + case OPT_MIPMAP_BIAS: // mipmapping bais + r_mipmaps_bias.value += dir * 0.5; + if (r_mipmaps_bias.value < -10) + r_mipmaps_bias.value = -10; + if (r_mipmaps_bias.value > 0) + r_mipmaps_bias.value = 0; + + Cvar_SetValue ("r_mipmaps_bias", r_mipmaps_bias.value); + break; + + case OPT_TEX_SCALEDOWN: + Cvar_SetValue ("r_tex_scale_down", !r_tex_scale_down.value); + break; + + case OPT_SMOOTH_ANIMS: + Cvar_SetValue ("r_i_model_animation", !r_i_model_animation.value); + break; + + case OPT_SMOOTH_MOVEMENT: + Cvar_SetValue ("r_i_model_transform", !r_i_model_transform.value); + break; + } + } +} + + +void M_DrawSlider (int x, int y, float range) +{ + int i; + + if (range < 0) + range = 0; + if (range > 1) + range = 1; + M_DrawCharacter (x-8, y, 128); + for (i=0 ; iwidth)/2, 36, p); + + // Cursor + M_DrawCharacter (200, offset + options_cursor*8, 12+((int)(realtime*30)&1)); + } + else + { + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/p_option.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + // Cursor + M_DrawCharacter (200, offset + options_cursor*8, 12+((int)(realtime*4)&1)); + } + + b = Draw_CachePic ("gfx/m_bttns.lmp"); + M_DrawPic ( (320-b->width)/2, 248, b ); + + M_Print (16, offset+(OPT_CUSTOMIZE*8), " Customize Buttons"); + M_Print (16, offset+(OPT_CONSOLE*8), " Go to console"); + + M_Print (16, offset+(OPT_DEFAULTS1*8), " Load defaults"); +// M_Print (16, offset+(OPT_DEFAULTS2*8), " 'Golden' defaults"); +// M_Print (16, offset+(OPT_DEFAULTS3*8), " 'Digital' defaults"); + + switch (m_submenu) + { + case 0: + + #ifdef PSP + M_Print (16, offset+(OPT_IN_SPEED*8), " Analog Speed"); + #else + M_Print (16, offset+(OPT_IN_SPEED*8), " Mouse Speed"); + #endif + r = (in_sensitivity.value - 1)/33; + M_DrawSlider (220, offset+(OPT_IN_SPEED*8), r); + + M_Print (16, offset+(OPT_IN_ACCELERATION*8), " Analog Acceleration"); + r = 1.0f -((in_acceleration.value - 0.5f)/1.5f); + M_DrawSlider (220, offset+(OPT_IN_ACCELERATION*8), r); + + M_Print (16, offset+(OPT_IN_TOLERANCE*8), " Analog Tolerance"); + r = (in_tolerance.value )/1.0f; + M_DrawSlider (220, offset+(OPT_IN_TOLERANCE*8), r); + + M_Print (16, offset+(OPT_IN_X_ADJUST*8), " Analog Speed X Axis"); + r = (in_x_axis_adjust.value - 1)/10; + M_DrawSlider (220, offset+(OPT_IN_X_ADJUST*8), r); + + M_Print (16, offset+(OPT_IN_Y_ADJUST*8), " Analog Speed Y Axis"); + r = (in_y_axis_adjust.value - 1)/10; + M_DrawSlider (220, offset+(OPT_IN_Y_ADJUST*8), r); + + #ifdef PSP + M_Print (16, offset+(OPT_INVMOUSE*8), " Invert Analog"); + #else + M_Print (16, offset+(OPT_INVMOUSE*8), " Invert Mouse"); + #endif + M_DrawCheckbox (220, offset+(OPT_INVMOUSE*8), m_pitch.value < 0); + + M_Print (16, offset+(OPT_MOUSELOOK*8), " Analog Mode"); + if (in_freelook_analog.value == 1) + M_Print (220, offset+(OPT_MOUSELOOK*8), "Look"); + else + M_Print (220, offset+(OPT_MOUSELOOK*8), "Move"); + + M_Print (16, offset+(OPT_NOMOUSE*8), " Disable Analog"); + M_DrawCheckbox (220, offset+(OPT_NOMOUSE*8), in_disable_analog.value ); + + M_Print (16, offset+(OPT_AUTOCENTER*8), "Autocenter Button Look"); + M_DrawCheckbox (220, offset+(OPT_AUTOCENTER*8), !lookcenter.value ); + + M_Print (16, offset+(OPT_MOUSESTRAFE*8), " Analog Strafing"); + M_DrawCheckbox (220, offset+(OPT_MOUSESTRAFE*8), in_analog_strafe.value ); + + M_Print (16, offset+(OPT_ALWAYRUN*8), " Always Run"); + if (kurok) + M_DrawCheckbox (220, offset+(OPT_ALWAYRUN*8), cl_forwardspeed.value > 150); + else + M_DrawCheckbox (220, offset+(OPT_ALWAYRUN*8), cl_forwardspeed.value > 200); + + break; + + case 1: + + M_Print (16, offset+(OPT_GAMMA*8), " Brightness"); + r = (1.0 - v_gamma.value) / 0.5; + M_DrawSlider (220, offset+(OPT_GAMMA*8), r); + + M_Print (16, offset+(OPT_VSYNC*8), " VSync"); + M_DrawCheckbox (220, offset+(OPT_VSYNC*8), r_vsync.value); + + M_Print (16, offset+(OPT_DYNAMIC*8), " Dynamic Lighting"); + M_DrawCheckbox (220, offset+(OPT_DYNAMIC*8), r_dynamic.value); + + M_Print (16, offset+(OPT_MODEL_BRIGHTNESS*8), " Brighter Models"); + M_DrawCheckbox (220, offset+(OPT_MODEL_BRIGHTNESS*8), r_model_brightness.value); + + M_Print (16, offset+(OPT_MAXFPS*8), " Maximum Frame Rate"); + r = (max_fps.value - 30) / (65 - 30); + M_DrawSlider (220, offset+(OPT_MAXFPS*8), r); + + M_Print (16, offset+(OPT_FPS*8), " Display Frame rate"); + M_DrawCheckbox (220, offset+(OPT_FPS*8), show_fps.value); + + #ifdef PSP_HARDWARE_VIDEO + + M_Print (16, offset+(OPT_SIMPLE_PART*8), " Simple Particles"); + M_DrawCheckbox (220, offset+(OPT_SIMPLE_PART*8), r_particles_simple.value); + + M_Print (16, offset+(OPT_ANTIALIAS*8), " Anti-Aliasing"); + M_DrawCheckbox (220, offset+(OPT_ANTIALIAS*8), r_antialias.value); + + M_Print (16, offset+(OPT_MIPMAPS*8), " MipMapping"); + M_DrawCheckbox (220, offset+(OPT_MIPMAPS*8), r_mipmaps.value); + #endif + + break; + + case 2: +/* + M_Print (16, offset+(OPT_MUSICTRACK*8), " Music Track"); + r = (track - 1)/13; + M_DrawSlider (220, offset+(OPT_MUSICTRACK*8), r); +*/ + + M_Print (16, offset+(OPT_MUSICVOL*8), " MP3 Music Volume"); + r = bgmvolume.value; + M_DrawSlider (220, offset+(OPT_MUSICVOL*8), r); + + M_Print (16, offset+(OPT_SNDVOL*8), " Sound Volume"); + r = volume.value; + M_DrawSlider (220, offset+(OPT_SNDVOL*8), r); +/* + M_Print (16, offset+(OPT_MUSICTYPE*8)," MP3 Playback"); + if (strcmpi(bgmtype.string,"cd") == 0) + M_Print (220, offset+(OPT_MUSICTYPE*8), "On"); + else + M_Print (220, offset+(OPT_MUSICTYPE*8), "Off"); +*/ + break; + + case 3: + + M_Print (16, offset+(OPT_FOG_START*8), " Fog start distance"); + r = (r_refdef.fog_start - (-5000)) / ((5000) - (-5000)); + M_DrawSlider (220, offset+(OPT_FOG_START*8), r); + + M_Print (16, offset+(OPT_FOG_END*8), " Fog end distance"); + r = (r_refdef.fog_end - (-5000)) / ((5000) - (-5000)); + M_DrawSlider (220, offset+(OPT_FOG_END*8), r); + + M_Print (16, offset+(OPT_FOG_RED*8), " Fog red amount"); + r = (r_refdef.fog_red) / 100; + M_DrawSlider (220, offset+(OPT_FOG_RED*8), r); + + M_Print (16, offset+(OPT_FOG_GREEN*8), " Fog green amount"); + r = (r_refdef.fog_green) / 100; + M_DrawSlider (220, offset+(OPT_FOG_GREEN*8), r); + + M_Print (16, offset+(OPT_FOG_BLUE*8), " Fog blue amount"); + r = (r_refdef.fog_blue) / 100; + M_DrawSlider (220, offset+(OPT_FOG_BLUE*8), r); + + M_Print (16, offset+(OPT_SCRSIZE*8), " Screen size"); + r = (scr_viewsize.value - 30) / (130 - 30); + M_DrawSlider (220, offset+(OPT_SCRSIZE*8), r); + + M_Print (16, offset+(OPT_WATERTRANS*8), " Water tranparency"); + M_DrawSlider (220, offset+(OPT_WATERTRANS*8), r_wateralpha.value); + + M_Print (16, offset+(OPT_MIPMAP_BIAS*8), " MipMap Amount"); + r = (r_mipmaps_bias.value + 10) / 10; + M_DrawSlider (220, offset+(OPT_MIPMAP_BIAS*8), r); + + M_Print (16, offset+(OPT_TEX_SCALEDOWN*8), " Texture Scale Down"); + M_DrawCheckbox (220, offset+(OPT_TEX_SCALEDOWN*8), r_tex_scale_down.value); + + M_Print (16, offset+(OPT_SMOOTH_ANIMS*8), "Smooth Model Animation"); + M_DrawCheckbox (220, offset+(OPT_SMOOTH_ANIMS*8), r_i_model_animation.value); + + M_Print (16, offset+(OPT_SMOOTH_MOVEMENT*8), " Smooth Model Movement"); + M_DrawCheckbox (220, offset+(OPT_SMOOTH_MOVEMENT*8), r_i_model_transform.value); + + break; + + } + + M_PrintWhite (16, offset+(OPT_SUBMENU*8), " Select Submenu"); + switch (m_submenu) + { + case 0: + M_PrintWhite (220, offset+(OPT_SUBMENU*8), "Control Options"); + break; + case 1: + M_PrintWhite (220, offset+(OPT_SUBMENU*8), "Video Options"); + break; + case 2: + M_PrintWhite (220, offset+(OPT_SUBMENU*8), "Audio Options"); + break; + case 3: + M_PrintWhite (220, offset+(OPT_SUBMENU*8), "Misc. Options"); + break; + default: + break; + } +} + + +void M_Options_Key (int k) +{ + switch (k) + { + case K_ESCAPE: + M_Menu_Main_f (); + break; + + case K_ENTER: + m_entersound = true; + switch (options_cursor) + { + case OPT_CUSTOMIZE: + M_Menu_Keys_f (); + break; + case OPT_CONSOLE: + m_state = m_none; + Con_ToggleConsole_f (); + break; + case OPT_DEFAULTS1: + Cbuf_AddText ("exec default.cfg\n"); +// Cbuf_AddText ("-klook\n"); + break; +/* + case OPT_DEFAULTS2: + Cbuf_AddText ("exec default2.cfg\n"); + Cbuf_AddText ("+klook\n"); + break; + case OPT_DEFAULTS3: + Cbuf_AddText ("exec default3.cfg\n"); + Cbuf_AddText ("+klook\n"); + break; +*/ + default: + M_AdjustSliders (1); + break; + } + return; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + options_cursor--; + + if (options_cursor == OPT_GAP) + options_cursor = options_cursor -1; + + if (options_cursor == OPT_GAP1) + options_cursor = options_cursor -1; + + if (m_submenu == 0) + { + if (options_cursor == OPT_GAP_0) + options_cursor = options_cursor -1; + if (options_cursor == OPT_GAP_0_1) + options_cursor = options_cursor -1; + if (options_cursor == OPT_GAP_0_2) + options_cursor = options_cursor -1; + } + + if (m_submenu == 1) + { + if (options_cursor == OPT_GAP_1) + options_cursor = options_cursor -1; + if (options_cursor == OPT_GAP_1_1) + options_cursor = options_cursor -1; + } + + if (m_submenu == 2) + { + if (options_cursor == OPT_GAP_2) + options_cursor = options_cursor -1; + if (options_cursor == OPT_GAP_2_1) + options_cursor = options_cursor -1; + } + + if (m_submenu == 3) + { + if (options_cursor == OPT_GAP_3) + options_cursor = options_cursor -1; + if (options_cursor == OPT_GAP_3_1) + options_cursor = options_cursor -1; + } + + if (options_cursor < 0) { + if (m_submenu == 0) + options_cursor = OPTIONS_ITEMS_0-1; + if (m_submenu == 1) + options_cursor = OPTIONS_ITEMS_1-1; + if (m_submenu == 2) + options_cursor = OPTIONS_ITEMS_2-1; + if (m_submenu == 3) + options_cursor = OPTIONS_ITEMS_3-1; + } + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + options_cursor++; + + if (options_cursor == OPT_GAP) + options_cursor = options_cursor +1; + + if (options_cursor == OPT_GAP1) + options_cursor = options_cursor +1; + + if (m_submenu == 0) + { + if (options_cursor >= OPTIONS_ITEMS_0) + options_cursor = 0; + if (options_cursor == OPT_GAP_0) + options_cursor = options_cursor +1; + if (options_cursor == OPT_GAP_0_1) + options_cursor = options_cursor +1; + if (options_cursor == OPT_GAP_0_2) + options_cursor = options_cursor +1; + } + if (m_submenu == 1) + { + if (options_cursor >= OPTIONS_ITEMS_1) + options_cursor = 0; + if (options_cursor == OPT_GAP_1) + options_cursor = options_cursor +1; + if (options_cursor == OPT_GAP_1_1) + options_cursor = options_cursor +1; + } + if (m_submenu == 2) + { + if (options_cursor >= OPTIONS_ITEMS_2) + options_cursor = 0; + if (options_cursor == OPT_GAP_2) + options_cursor = options_cursor +1; + if (options_cursor == OPT_GAP_2_1) + options_cursor = options_cursor +1; + } + if (m_submenu == 3) + { + if (options_cursor >= OPTIONS_ITEMS_3) + options_cursor = 0; + if (options_cursor == OPT_GAP_3) + options_cursor = options_cursor +1; + if (options_cursor == OPT_GAP_3_1) + options_cursor = options_cursor +1; + } + break; + + case K_LEFTARROW: + M_AdjustSliders (-1); + break; + + case K_RIGHTARROW: + M_AdjustSliders (1); + break; + + case K_AUX1: + m_submenu--; + options_cursor = OPT_SUBMENU; + if (m_submenu < 0) + m_submenu = 3; + break; + + case K_AUX2: + m_submenu++; + options_cursor = OPT_SUBMENU; + if (m_submenu > 3) + m_submenu = 0; + break; + } +} + +//============================================================================= +/* KEYS MENU */ + +char *bindnames[][2] = +{ +{"+attack", "Attack"}, +{"impulse 10", "Next Weapon"}, +{"impulse 12", "Previous Weapon"}, +{"+jump", "Jump / Swim Up"}, +{"+forward", "Move Forward"}, +{"+back", "Move Backwards"}, +{"+moveleft", "Move Left"}, +{"+moveright", "Move Right"}, +{"+left", "Turn Left"}, +{"+right", "Turn Right"}, +{"+lookup", "Look up"}, +{"+lookdown", "Look down"}, +{"+moveup", "Swim Up"}, +{"+movedown", "Swim Down"}, +{"+speed", "Run"}, +{"+strafe", "Sidestep"}, +{"centerview", "Center view"}, +#ifdef PSP +{"+mlook", "Analog Nub Look"}, +{"+klook", "D-Pad Look"}, +#else +{"+mlook", "Mouse Look"}, +{"+klook", "Keyboard Look"}, +#endif +{"+showscores", "Show Scores"}, +{"screenshot", "Screenshot"}, +{"toggleconsole", "Toggle Console"}, +}; + +char *kbindnames[][2] = +{ +{"+attack", "Attack"}, +{"impulse 10", "Next Weapon"}, +{"impulse 12", "Previous Weapon"}, +{"impulse 13", "Reload / Secondary"}, +{"impulse 14", "Zoom"}, +{"+jump", "Jump / Swim Up"}, +{"+forward", "Move Forward"}, +{"+back", "Move Backwards"}, +{"+moveleft", "Move Left"}, +{"+moveright", "Move Right"}, +{"+left", "Turn Left"}, +{"+right", "Turn Right"}, +{"+lookup", "Look up"}, +{"+lookdown", "Look down"}, +{"impulse 27", "Switch Grenades"}, +{"+movedown", "Swim Down"}, +{"+speed", "Run"}, +{"+strafe", "Sidestep"}, +{"centerview", "Center view"}, +#ifdef PSP +{"+mlook", "Analog Nub Look"}, +{"+klook", "D-Pad Look"}, +#else +{"+mlook", "Mouse Look"}, +{"+klook", "Keyboard Look"}, +#endif +{"+showscores", "Show Scores"}, +{"screenshot", "Screenshot"}, +{"toggleconsole", "Toggle Console"}, +}; + +#define NUMCOMMANDS (sizeof(bindnames)/sizeof(bindnames[0])) +#define KNUMCOMMANDS (sizeof(kbindnames)/sizeof(kbindnames[0])) + +int keys_cursor; +int bind_grab; + +void M_Menu_Keys_f (void) +{ + key_dest = key_menu; + m_state = m_keys; + m_entersound = true; +} + + +void M_FindKeysForCommand (char *command, int *twokeys) +{ + int count; + int j; + int l; + char *b; + + twokeys[0] = twokeys[1] = -1; + l = strlen(command); + count = 0; + + for (j=0 ; j<256 ; j++) + { + b = keybindings[j]; + if (!b) + continue; + if (!strncmp (b, command, l) ) + { + twokeys[count] = j; + count++; + if (count == 2) + break; + } + } +} + +void M_UnbindCommand (char *command) +{ + int j; + int l; + char *b; + + l = strlen(command); + + for (j=0 ; j<256 ; j++) + { + b = keybindings[j]; + if (!b) + continue; + if (!strncmp (b, command, l) ) + Key_SetBinding (j, ""); + } +} + + +void M_Keys_Draw (void) +{ + int i, l; + int keys[2]; + char *name; + int x, y; + qpic_t *p, *b; + + p = Draw_CachePic ("gfx/ttl_cstm.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + b = Draw_CachePic ("gfx/m_bttns.lmp"); + M_DrawPic ( (320-b->width)/2, 248, b ); + +#ifdef PSP + if (bind_grab) + M_Print (12, 32, "Press a button for this action"); + else + M_Print (18, 32, "Press CROSS to change, TRIANGLE to clear"); +#else + if (bind_grab) + M_Print (12, 32, "Press a key or button for this action"); + else + M_Print (18, 32, "Enter to change, backspace to clear"); +#endif + +// search for known bindings + if (kurok) + { + if (bind_grab) + M_DrawCharacter (170, 48 + keys_cursor*8, '?'); + else + M_DrawCharacter (170, 48 + keys_cursor*8, 12+((int)(realtime*30)&1)); + + for (i=0 ; i= KNUMCOMMANDS) + keys_cursor = 0; + } + else + { + if (keys_cursor >= NUMCOMMANDS) + keys_cursor = 0; + } + break; + + case K_ENTER: // go into bind mode + if (kurok) + M_FindKeysForCommand (kbindnames[keys_cursor][0], keys); + else + M_FindKeysForCommand (bindnames[keys_cursor][0], keys); + S_LocalSound ("misc/menu2.wav"); + if (keys[1] != -1) + { + if (kurok) + M_UnbindCommand (kbindnames[keys_cursor][0]); + else + M_UnbindCommand (bindnames[keys_cursor][0]); + } + bind_grab = true; + break; + + case K_BACKSPACE: // delete bindings + case K_DEL: // delete bindings + S_LocalSound ("misc/menu2.wav"); + if (kurok) + M_UnbindCommand (kbindnames[keys_cursor][0]); + else + M_UnbindCommand (bindnames[keys_cursor][0]); + break; + } +} + +//============================================================================= +/* VIDEO MENU */ + +void M_Menu_Video_f (void) +{ + key_dest = key_menu; + m_state = m_video; + m_entersound = true; +} + + +void M_Video_Draw (void) +{ + (*vid_menudrawfn) (); +} + + +void M_Video_Key (int key) +{ + (*vid_menukeyfn) (key); +} + +//============================================================================= +/* HELP MENU */ + +int help_page; +#define NUM_HELP_PAGES 6 +#define KNUM_HELP_PAGES 2 + + +void M_Menu_Help_f (void) +{ + key_dest = key_menu; + m_state = m_help; + m_entersound = true; + help_page = 0; +} + + + +void M_Help_Draw (void) +{ + if (kurok) + M_DrawPic (vid.width - 560, 0, Draw_CachePic ( va("gfx/menu/hp/help%i.lmp", help_page)) ); + else + M_DrawPic (0, 0, Draw_CachePic ( va("gfx/help%i.lmp", help_page)) ); +} + + +void M_Help_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + M_Menu_Main_f (); + break; + + case K_UPARROW: + case K_RIGHTARROW: + m_entersound = true; + if (!kurok) + { + if (++help_page >= NUM_HELP_PAGES) + help_page = 0; + } + else + { + if (++help_page >= KNUM_HELP_PAGES) + help_page = 0; + } + break; + + case K_DOWNARROW: + case K_LEFTARROW: + m_entersound = true; + if (!kurok) + { + if (--help_page < 0) + help_page = NUM_HELP_PAGES-1; + } + else + { + if (--help_page < 0) + help_page = KNUM_HELP_PAGES-1; + } + break; + } + +} + +//============================================================================= +/* QUIT MENU */ + +int msgNumber; +int m_quit_prevstate; +qboolean wasInMenus; + +#ifndef WIN32 +char *quitMessage [] = +{ +/* .........1.........2.... */ + " Are you gonna quit ", + " this game just like ", + " everything else? ", + " ", + + " Milord, methinks that ", + " thou art a lowly ", + " quitter. Is this true? ", + " ", + + " Do I need to bust your ", + " face open for trying ", + " to quit? ", + " ", + + " Man, I oughta smack you", + " for trying to quit! ", + " Press Y to get ", + " smacked out. ", + + " Press Y to quit like a ", + " big loser in life. ", + " Press N to stay proud ", + " and successful! ", + + " If you press Y to ", + " quit, I will summon ", + " Satan all over your ", + " hard drive! ", + + " Um, Asmodeus dislikes ", + " his children trying to ", + " quit. Press Y to return", + " to your Tinkertoys. ", + + " If you quit now, I'll ", + " throw a blanket-party ", + " for you next time! ", + " " +}; +#endif + +void M_Menu_Quit_f (void) +{ + if (m_state == m_quit) + return; + wasInMenus = (key_dest == key_menu); + key_dest = key_menu; + m_quit_prevstate = m_state; + m_state = m_quit; + m_entersound = true; + msgNumber = rand()&7; +} + + +void M_Quit_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + case 'n': + case 'N': + if (wasInMenus) + { + m_state = m_quit_prevstate; + m_entersound = true; + } + else + { + key_dest = key_game; + m_state = m_none; + } + break; + + case 'Y': + case 'y': +#ifdef PSP + case K_ENTER: +#endif + key_dest = key_console; + Host_Quit_f (); + break; + + default: + break; + } + +} + + +void M_Quit_Draw (void) +{ + if (wasInMenus) + { + m_state = m_quit_prevstate; + m_recursiveDraw = true; + M_Draw (); + m_state = m_quit; + } + +#ifdef WIN32 + M_DrawTextBox (0, 0, 38, 23); + M_PrintWhite (16, 12, " Quake version 1.09 by id Software\n\n"); + M_PrintWhite (16, 28, "Programming Art \n"); + M_Print (16, 36, " John Carmack Adrian Carmack\n"); + M_Print (16, 44, " Michael Abrash Kevin Cloud\n"); + M_Print (16, 52, " John Cash Paul Steed\n"); + M_Print (16, 60, " Dave 'Zoid' Kirsch\n"); + M_PrintWhite (16, 68, "Design Biz\n"); + M_Print (16, 76, " John Romero Jay Wilbur\n"); + M_Print (16, 84, " Sandy Petersen Mike Wilson\n"); + M_Print (16, 92, " American McGee Donna Jackson\n"); + M_Print (16, 100, " Tim Willits Todd Hollenshead\n"); + M_PrintWhite (16, 108, "Support Projects\n"); + M_Print (16, 116, " Barrett Alexander Shawn Green\n"); + M_PrintWhite (16, 124, "Sound Effects\n"); + M_Print (16, 132, " Trent Reznor and Nine Inch Nails\n\n"); + M_PrintWhite (16, 140, "Quake is a trademark of Id Software,\n"); + M_PrintWhite (16, 148, "inc., (c)1996 Id Software, inc. All\n"); + M_PrintWhite (16, 156, "rights reserved. NIN logo is a\n"); + M_PrintWhite (16, 164, "registered trademark licensed to\n"); + M_PrintWhite (16, 172, "Nothing Interactive, Inc. All rights\n"); + M_PrintWhite (16, 180, "reserved. Press y to exit\n"); +#elif defined PSP + M_DrawTextBox (56, 76, 24, 4); + M_Print (64, 84, " Really quit? "); + M_Print (64, 92, " "); + M_Print (64, 100, " Press CROSS to quit, "); + M_Print (64, 108, " or CIRCLE to continue. "); +#else + M_DrawTextBox (56, 76, 24, 4); + M_Print (64, 84, quitMessage[msgNumber*4+0]); + M_Print (64, 92, quitMessage[msgNumber*4+1]); + M_Print (64, 100, quitMessage[msgNumber*4+2]); + M_Print (64, 108, quitMessage[msgNumber*4+3]); +#endif +} +//============================================================================= +/* OSK IMPLEMENTATION */ +#define CHAR_SIZE 8 +#define MAX_Y 8 +#define MAX_X 12 + +#define MAX_CHAR_LINE 36 +#define MAX_CHAR 72 + +int osk_pos_x = 0; +int osk_pos_y = 0; +int max_len = 0; +int m_old_state = 0; + +char* osk_out_buff = NULL; +char osk_buffer[128]; + +char *osk_text [] = + { + " 1 2 3 4 5 6 7 8 9 0 - = ` ", + " q w e r t y u i o p [ ] ", + " a s d f g h j k l ; ' \\ ", + " z x c v b n m , . / ", + " ", + " ! @ # $ % ^ & * ( ) _ + ~ ", + " Q W E R T Y U I O P { } ", + " A S D F G H J K L : \" | ", + " Z X C V B N M < > ? " + }; + +char *osk_help [] = + { + "CONFIRM: ", + " SQUARE ", + "CANCEL: ", + " CIRCLE ", + "DELETE: ", + " TRIAGLE ", + "ADD CHAR:", + " CROSS ", + "" + }; + +void M_Menu_OSK_f (char *input, char *output, int outlen) +{ + key_dest = key_menu; + m_old_state = m_state; + m_state = m_osk; + m_entersound = false; + max_len = outlen; + strncpy(osk_buffer,input,max_len); + osk_buffer[outlen] = '\0'; + osk_out_buff = output; +} + +void Con_OSK_f (char *input, char *output, int outlen) +{ + max_len = outlen; + strncpy(osk_buffer,input,max_len); + osk_buffer[outlen] = '\0'; + osk_out_buff = output; +} + + +void M_OSK_Draw (void) +{ +#ifdef PSP + int x,y; + int i; + + char *selected_line = osk_text[osk_pos_y]; + char selected_char[2]; + + selected_char[0] = selected_line[1+(2*osk_pos_x)]; + selected_char[1] = '\0'; + if (selected_char[0] == ' ' || selected_char[0] == '\t') + selected_char[0] = 'X'; + + y = 20; + x = 16; + + M_DrawTextBox (10, 10, 26, 10); + M_DrawTextBox (10+(26*CHAR_SIZE), 10, 10, 10); + M_DrawTextBox (10, 10+(10*CHAR_SIZE),36, 3); + + for(i=0;i<=MAX_Y;i++) + { + M_PrintWhite (x, y+(CHAR_SIZE*i), osk_text[i]); + if (i % 2 == 0) + M_Print (x+(27*CHAR_SIZE), y+(CHAR_SIZE*i), osk_help[i]); + else + M_PrintWhite (x+(27*CHAR_SIZE), y+(CHAR_SIZE*i), osk_help[i]); + } + + int text_len = strlen(osk_buffer); + if (text_len > MAX_CHAR_LINE) { + + char oneline[MAX_CHAR_LINE+1]; + strncpy(oneline,osk_buffer,MAX_CHAR_LINE); + oneline[MAX_CHAR_LINE] = '\0'; + + M_Print (x+4, y+4+(CHAR_SIZE*(MAX_Y+2)), oneline ); + + strncpy(oneline,osk_buffer+MAX_CHAR_LINE, text_len - MAX_CHAR_LINE); + oneline[text_len - MAX_CHAR_LINE] = '\0'; + + M_Print (x+4, y+4+(CHAR_SIZE*(MAX_Y+3)), oneline ); + M_PrintWhite (x+4+(CHAR_SIZE*(text_len - MAX_CHAR_LINE)), y+4+(CHAR_SIZE*(MAX_Y+3)),"_"); + } + else { + M_Print (x+4, y+4+(CHAR_SIZE*(MAX_Y+2)), osk_buffer ); + M_PrintWhite (x+4+(CHAR_SIZE*(text_len)), y+4+(CHAR_SIZE*(MAX_Y+2)),"_"); + } + M_Print (x+((((osk_pos_x)*2)+1)*CHAR_SIZE), y+(osk_pos_y*CHAR_SIZE), selected_char); + +#endif +} + +void M_OSK_Key (int key) +{ +#ifdef PSP + switch (key) + { + case K_RIGHTARROW: + osk_pos_x++; + if (osk_pos_x > MAX_X) + osk_pos_x = MAX_X; + break; + case K_LEFTARROW: + osk_pos_x--; + if (osk_pos_x < 0) + osk_pos_x = 0; + break; + case K_DOWNARROW: + osk_pos_y++; + if (osk_pos_y > MAX_Y) + osk_pos_y = MAX_Y; + break; + case K_UPARROW: + osk_pos_y--; + if (osk_pos_y < 0) + osk_pos_y = 0; + break; + case K_ENTER: + if (max_len > strlen(osk_buffer)) { + char *selected_line = osk_text[osk_pos_y]; + char selected_char[2]; + + selected_char[0] = selected_line[1+(2*osk_pos_x)]; + + if (selected_char[0] == '\t') + selected_char[0] = ' '; + + selected_char[1] = '\0'; + strcat(osk_buffer,selected_char); + } + break; + case K_DEL: + if (strlen(osk_buffer) > 0) { + osk_buffer[strlen(osk_buffer)-1] = '\0'; + } + break; + case K_INS: + strncpy(osk_out_buff,osk_buffer,max_len); + + m_state = m_old_state; + break; + case K_ESCAPE: + m_state = m_old_state; + break; + default: + break; + } +#endif +} + +void Con_OSK_Key (int key) +{ +#ifdef PSP + switch (key) + { + case K_RIGHTARROW: + osk_pos_x++; + if (osk_pos_x > MAX_X) + osk_pos_x = MAX_X; + break; + case K_LEFTARROW: + osk_pos_x--; + if (osk_pos_x < 0) + osk_pos_x = 0; + break; + case K_DOWNARROW: + osk_pos_y++; + if (osk_pos_y > MAX_Y) + osk_pos_y = MAX_Y; + break; + case K_UPARROW: + osk_pos_y--; + if (osk_pos_y < 0) + osk_pos_y = 0; + break; + case K_ENTER: + if (max_len > strlen(osk_buffer)) { + char *selected_line = osk_text[osk_pos_y]; + char selected_char[2]; + + selected_char[0] = selected_line[1+(2*osk_pos_x)]; + + if (selected_char[0] == '\t') + selected_char[0] = ' '; + + selected_char[1] = '\0'; + strcat(osk_buffer,selected_char); + } + break; + case K_DEL: + if (strlen(osk_buffer) > 0) { + osk_buffer[strlen(osk_buffer)-1] = '\0'; + } + break; + case K_INS: + strncpy(osk_out_buff,osk_buffer,max_len); + Con_SetOSKActive(false); + break; + case K_ESCAPE: + Con_SetOSKActive(false); + break; + default: + break; + } +#endif +} + +//============================================================================= + +/* SERIAL CONFIG MENU */ + +int serialConfig_cursor; +int serialConfig_cursor_table[] = {48, 64, 80, 96, 112, 132}; +#define NUM_SERIALCONFIG_CMDS 6 + +static int ISA_uarts[] = {0x3f8,0x2f8,0x3e8,0x2e8}; +static int ISA_IRQs[] = {4,3,4,3}; +int serialConfig_baudrate[] = {9600,14400,19200,28800,38400,57600}; + +int serialConfig_comport; +int serialConfig_irq ; +int serialConfig_baud; +char serialConfig_phone[16]; + +void M_Menu_SerialConfig_f (void) +{ + int n; + int port; + int baudrate; + qboolean useModem; + + key_dest = key_menu; + m_state = m_serialconfig; + m_entersound = true; + if (JoiningGame && SerialConfig) + serialConfig_cursor = 4; + else + serialConfig_cursor = 5; + + (*GetComPortConfig) (0, &port, &serialConfig_irq, &baudrate, &useModem); + + // map uart's port to COMx + for (n = 0; n < 4; n++) + if (ISA_uarts[n] == port) + break; + if (n == 4) + { + n = 0; + serialConfig_irq = 4; + } + serialConfig_comport = n + 1; + + // map baudrate to index + for (n = 0; n < 6; n++) + if (serialConfig_baudrate[n] == baudrate) + break; + if (n == 6) + n = 5; + serialConfig_baud = n; + + m_return_onerror = false; + m_return_reason[0] = 0; +} + + +void M_SerialConfig_Draw (void) +{ + qpic_t *p,*b; + int basex; + char *startJoin; + char *directModem; + + if (!kurok) + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + + b = Draw_CachePic ("gfx/m_bttns.lmp"); + M_DrawPic ( (320-b->width)/2, 248, b ); + p = Draw_CachePic ("gfx/p_multi.lmp"); + basex = (320-p->width)/2; + M_DrawPic (basex, 4, p); + + if (StartingGame) + startJoin = "New Game"; + else + startJoin = "Join Game"; + if (SerialConfig) + directModem = "Modem"; + else + directModem = "Direct Connect"; + M_Print (basex, 32, va ("%s - %s", startJoin, directModem)); + basex += 8; + + M_Print (basex, serialConfig_cursor_table[0], "Port"); + M_DrawTextBox (160, 40, 4, 1); + M_Print (168, serialConfig_cursor_table[0], va("COM%u", serialConfig_comport)); + + M_Print (basex, serialConfig_cursor_table[1], "IRQ"); + M_DrawTextBox (160, serialConfig_cursor_table[1]-8, 1, 1); + M_Print (168, serialConfig_cursor_table[1], va("%u", serialConfig_irq)); + + M_Print (basex, serialConfig_cursor_table[2], "Baud"); + M_DrawTextBox (160, serialConfig_cursor_table[2]-8, 5, 1); + M_Print (168, serialConfig_cursor_table[2], va("%u", serialConfig_baudrate[serialConfig_baud])); + + if (SerialConfig) + { + M_Print (basex, serialConfig_cursor_table[3], "Modem Setup..."); + if (JoiningGame) + { + M_Print (basex, serialConfig_cursor_table[4], "Phone number"); + M_DrawTextBox (160, serialConfig_cursor_table[4]-8, 16, 1); + M_Print (168, serialConfig_cursor_table[4], serialConfig_phone); + } + } + + if (JoiningGame) + { + M_DrawTextBox (basex, serialConfig_cursor_table[5]-8, 7, 1); + M_Print (basex+8, serialConfig_cursor_table[5], "Connect"); + } + else + { + M_DrawTextBox (basex, serialConfig_cursor_table[5]-8, 2, 1); + M_Print (basex+8, serialConfig_cursor_table[5], "OK"); + } + + M_DrawCharacter (basex-8, serialConfig_cursor_table [serialConfig_cursor], 12+((int)(realtime*4)&1)); + + if (serialConfig_cursor == 4) + M_DrawCharacter (168 + 8*strlen(serialConfig_phone), serialConfig_cursor_table [serialConfig_cursor], 10+((int)(realtime*4)&1)); + + if (*m_return_reason) + M_PrintWhite (basex, 148, m_return_reason); +} + + +void M_SerialConfig_Key (int key) +{ + int l; + + switch (key) + { + case K_ESCAPE: + M_Menu_Net_f (); + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + serialConfig_cursor--; + if (serialConfig_cursor < 0) + serialConfig_cursor = NUM_SERIALCONFIG_CMDS-1; + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + serialConfig_cursor++; + if (serialConfig_cursor >= NUM_SERIALCONFIG_CMDS) + serialConfig_cursor = 0; + break; + + case K_LEFTARROW: + if (serialConfig_cursor > 2) + break; + S_LocalSound ("misc/menu3.wav"); + + if (serialConfig_cursor == 0) + { + serialConfig_comport--; + if (serialConfig_comport == 0) + serialConfig_comport = 4; + serialConfig_irq = ISA_IRQs[serialConfig_comport-1]; + } + + if (serialConfig_cursor == 1) + { + serialConfig_irq--; + if (serialConfig_irq == 6) + serialConfig_irq = 5; + if (serialConfig_irq == 1) + serialConfig_irq = 7; + } + + if (serialConfig_cursor == 2) + { + serialConfig_baud--; + if (serialConfig_baud < 0) + serialConfig_baud = 5; + } + + break; + + case K_RIGHTARROW: + if (serialConfig_cursor > 2) + break; +forward: + S_LocalSound ("misc/menu3.wav"); + + if (serialConfig_cursor == 0) + { + serialConfig_comport++; + if (serialConfig_comport > 4) + serialConfig_comport = 1; + serialConfig_irq = ISA_IRQs[serialConfig_comport-1]; + } + + if (serialConfig_cursor == 1) + { + serialConfig_irq++; + if (serialConfig_irq == 6) + serialConfig_irq = 7; + if (serialConfig_irq == 8) + serialConfig_irq = 2; + } + + if (serialConfig_cursor == 2) + { + serialConfig_baud++; + if (serialConfig_baud > 5) + serialConfig_baud = 0; + } + + break; + + case K_ENTER: + if (serialConfig_cursor < 3) + goto forward; + + m_entersound = true; + + if (serialConfig_cursor == 3) + { + (*SetComPortConfig) (0, ISA_uarts[serialConfig_comport-1], serialConfig_irq, serialConfig_baudrate[serialConfig_baud], SerialConfig); + + M_Menu_ModemConfig_f (); + break; + } + + if (serialConfig_cursor == 4) + { + serialConfig_cursor = 5; + break; + } + + // serialConfig_cursor == 5 (OK/CONNECT) + (*SetComPortConfig) (0, ISA_uarts[serialConfig_comport-1], serialConfig_irq, serialConfig_baudrate[serialConfig_baud], SerialConfig); + + M_ConfigureNetSubsystem (); + + if (StartingGame) + { + M_Menu_GameOptions_f (); + break; + } + + m_return_state = m_state; + m_return_onerror = true; + key_dest = key_game; + m_state = m_none; + + // If we were in a multiplayer game, reset all the deathmatch flags to 0; + + items_respawn = 1; + weapons_stay = + pistols = + automatics = + shotguns = + explosives = + snipers = + exit_non_fatal = + infinite_ammo = + all_weapons = + no_reload = + no_armor = + no_health = + armor_regen = + health_regen = + safe_spawn = + no_bots = 0; + + if (SerialConfig) + { + Cbuf_AddText ("viewsize 120\n cl_gunpitch 0\n fov 90\n scr_ofsy 0\n cl_autoaim 1\n chase_active 0\n"); + Cbuf_AddText (va ("connect \"%s\"\n", serialConfig_phone)); + } + else + { + Cbuf_AddText ("viewsize 120\n cl_gunpitch 0\n fov 90\n scr_ofsy 0\n cl_autoaim 1\n chase_active 0\n"); + Cbuf_AddText ("connect\n"); + } + break; + + case K_BACKSPACE: + if (serialConfig_cursor == 4) + { + if (strlen(serialConfig_phone)) + serialConfig_phone[strlen(serialConfig_phone)-1] = 0; + } + break; + + default: + if (key < 32 || key > 127) + break; + if (serialConfig_cursor == 4) + { + l = strlen(serialConfig_phone); + if (l < 15) + { + serialConfig_phone[l+1] = 0; + serialConfig_phone[l] = key; + } + } + } + + if (DirectConfig && (serialConfig_cursor == 3 || serialConfig_cursor == 4)) + { + if (key == K_UPARROW) + serialConfig_cursor = 2; + else + serialConfig_cursor = 5; + } + if (SerialConfig && StartingGame && serialConfig_cursor == 4) + { + if (key == K_UPARROW) + serialConfig_cursor = 3; + else + serialConfig_cursor = 5; + } +} + +//============================================================================= +/* MODEM CONFIG MENU */ + +int modemConfig_cursor; +int modemConfig_cursor_table [] = {40, 56, 88, 120, 156}; +#define NUM_MODEMCONFIG_CMDS 5 + +char modemConfig_dialing; +char modemConfig_clear [16]; +char modemConfig_init [32]; +char modemConfig_hangup [16]; + +void M_Menu_ModemConfig_f (void) +{ + key_dest = key_menu; + m_state = m_modemconfig; + m_entersound = true; + (*GetModemConfig) (0, &modemConfig_dialing, modemConfig_clear, modemConfig_init, modemConfig_hangup); +} + + +void M_ModemConfig_Draw (void) +{ + qpic_t *p,*b; + int basex; + + if (!kurok) + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + + b = Draw_CachePic ("gfx/m_bttns.lmp"); + M_DrawPic ( (320-b->width)/2, 248, b ); + p = Draw_CachePic ("gfx/p_multi.lmp"); + basex = (320-p->width)/2; + M_DrawPic (basex, 4, p); + basex += 8; + + if (modemConfig_dialing == 'P') + M_Print (basex, modemConfig_cursor_table[0], "Pulse Dialing"); + else + M_Print (basex, modemConfig_cursor_table[0], "Touch Tone Dialing"); + + M_Print (basex, modemConfig_cursor_table[1], "Clear"); + M_DrawTextBox (basex, modemConfig_cursor_table[1]+4, 16, 1); + M_Print (basex+8, modemConfig_cursor_table[1]+12, modemConfig_clear); + if (modemConfig_cursor == 1) + M_DrawCharacter (basex+8 + 8*strlen(modemConfig_clear), modemConfig_cursor_table[1]+12, 10+((int)(realtime*4)&1)); + + M_Print (basex, modemConfig_cursor_table[2], "Init"); + M_DrawTextBox (basex, modemConfig_cursor_table[2]+4, 30, 1); + M_Print (basex+8, modemConfig_cursor_table[2]+12, modemConfig_init); + if (modemConfig_cursor == 2) + M_DrawCharacter (basex+8 + 8*strlen(modemConfig_init), modemConfig_cursor_table[2]+12, 10+((int)(realtime*4)&1)); + + M_Print (basex, modemConfig_cursor_table[3], "Hangup"); + M_DrawTextBox (basex, modemConfig_cursor_table[3]+4, 16, 1); + M_Print (basex+8, modemConfig_cursor_table[3]+12, modemConfig_hangup); + if (modemConfig_cursor == 3) + M_DrawCharacter (basex+8 + 8*strlen(modemConfig_hangup), modemConfig_cursor_table[3]+12, 10+((int)(realtime*4)&1)); + + M_DrawTextBox (basex, modemConfig_cursor_table[4]-8, 2, 1); + M_Print (basex+8, modemConfig_cursor_table[4], "OK"); + + M_DrawCharacter (basex-8, modemConfig_cursor_table [modemConfig_cursor], 12+((int)(realtime*4)&1)); +} + + +void M_ModemConfig_Key (int key) +{ + int l; + + switch (key) + { + case K_ESCAPE: + M_Menu_SerialConfig_f (); + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + modemConfig_cursor--; + if (modemConfig_cursor < 0) + modemConfig_cursor = NUM_MODEMCONFIG_CMDS-1; + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + modemConfig_cursor++; + if (modemConfig_cursor >= NUM_MODEMCONFIG_CMDS) + modemConfig_cursor = 0; + break; + + case K_LEFTARROW: + case K_RIGHTARROW: + if (modemConfig_cursor == 0) + { + if (modemConfig_dialing == 'P') + modemConfig_dialing = 'T'; + else + modemConfig_dialing = 'P'; + S_LocalSound ("misc/menu1.wav"); + } + break; + + case K_ENTER: + if (modemConfig_cursor == 0) + { + if (modemConfig_dialing == 'P') + modemConfig_dialing = 'T'; + else + modemConfig_dialing = 'P'; + m_entersound = true; + } + + if (modemConfig_cursor == 4) + { + (*SetModemConfig) (0, va ("%c", modemConfig_dialing), modemConfig_clear, modemConfig_init, modemConfig_hangup); + m_entersound = true; + M_Menu_SerialConfig_f (); + } + break; + + case K_BACKSPACE: + if (modemConfig_cursor == 1) + { + if (strlen(modemConfig_clear)) + modemConfig_clear[strlen(modemConfig_clear)-1] = 0; + } + + if (modemConfig_cursor == 2) + { + if (strlen(modemConfig_init)) + modemConfig_init[strlen(modemConfig_init)-1] = 0; + } + + if (modemConfig_cursor == 3) + { + if (strlen(modemConfig_hangup)) + modemConfig_hangup[strlen(modemConfig_hangup)-1] = 0; + } + break; + + default: + if (key < 32 || key > 127) + break; + + if (modemConfig_cursor == 1) + { + l = strlen(modemConfig_clear); + if (l < 15) + { + modemConfig_clear[l+1] = 0; + modemConfig_clear[l] = key; + } + } + + if (modemConfig_cursor == 2) + { + l = strlen(modemConfig_init); + if (l < 29) + { + modemConfig_init[l+1] = 0; + modemConfig_init[l] = key; + } + } + + if (modemConfig_cursor == 3) + { + l = strlen(modemConfig_hangup); + if (l < 15) + { + modemConfig_hangup[l+1] = 0; + modemConfig_hangup[l] = key; + } + } + } +} + +//============================================================================= +/* LAN CONFIG MENU */ + +int lanConfig_cursor = -1; +int lanConfig_cursor_table [] = {72, 92, 124}; +#define NUM_LANCONFIG_CMDS 3 + +int lanConfig_port; +char lanConfig_portname[6]; +char lanConfig_joinname[22]; + +void M_Menu_LanConfig_f (void) +{ + key_dest = key_menu; + m_state = m_lanconfig; + m_entersound = true; + if (lanConfig_cursor == -1) + { + if (JoiningGame && TCPIPConfig) + lanConfig_cursor = 2; + else + lanConfig_cursor = 1; + } + if (StartingGame && lanConfig_cursor == 2) + lanConfig_cursor = 1; + lanConfig_port = DEFAULTnet_hostport; + sprintf(lanConfig_portname, "%u", lanConfig_port); + + m_return_onerror = false; + m_return_reason[0] = 0; +} + + +void M_LanConfig_Draw (void) +{ + qpic_t *p,*b; + int basex; + char *startJoin; + char *protocol; + + if (!kurok) + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + + b = Draw_CachePic ("gfx/m_bttns.lmp"); + M_DrawPic ( (320-b->width)/2, 248, b ); + p = Draw_CachePic ("gfx/p_multi.lmp"); + basex = (320-p->width)/2; + M_DrawPic (basex, 4, p); + + if (StartingGame) + startJoin = "New Game"; + else + startJoin = "Join Game"; + if (IPXConfig) + protocol = "IPX"; + else + protocol = "TCP/IP"; + M_PrintWhite (basex, 32, va ("%s - %s", startJoin, protocol)); + basex += 8; + + M_PrintWhite (basex, 52, "Address:"); + if (IPXConfig) + M_Print (basex+9*8, 52, my_ipx_address); + else + M_Print (basex+9*8, 52, my_tcpip_address); + + M_PrintWhite (basex, lanConfig_cursor_table[0], "Port"); + M_DrawTextBox (basex+8*8, lanConfig_cursor_table[0]-8, 6, 1); + M_PrintWhite (basex+9*8, lanConfig_cursor_table[0], lanConfig_portname); + + if (JoiningGame) + { + M_PrintWhite (basex, lanConfig_cursor_table[1], "Search for local games..."); + M_PrintWhite (basex, 108, "Join game at:"); + M_DrawTextBox (basex+8, lanConfig_cursor_table[2]-8, 22, 1); + M_PrintWhite (basex+16, lanConfig_cursor_table[2], lanConfig_joinname); + } + else + { + M_DrawTextBox (basex, lanConfig_cursor_table[1]-8, 2, 1); + M_PrintWhite (basex+8, lanConfig_cursor_table[1], "OK"); + } + + if (*m_return_reason) + M_PrintWhite (basex, 148, m_return_reason); + + if (kurok) + { + M_DrawCharacter (basex-8, lanConfig_cursor_table [lanConfig_cursor], 12+((int)(realtime*30)&1)); + + if (lanConfig_cursor == 0) + M_DrawCharacter (basex+9*8 + 8*strlen(lanConfig_portname), lanConfig_cursor_table [0], 10+((int)(realtime*30)&1)); + + if (lanConfig_cursor == 2) + M_DrawCharacter (basex+16 + 8*strlen(lanConfig_joinname), lanConfig_cursor_table [2], 10+((int)(realtime*30)&1)); + } + else + { + M_DrawCharacter (basex-8, lanConfig_cursor_table [lanConfig_cursor], 12+((int)(realtime*4)&1)); + + if (lanConfig_cursor == 0) + M_DrawCharacter (basex+9*8 + 8*strlen(lanConfig_portname), lanConfig_cursor_table [0], 10+((int)(realtime*4)&1)); + + if (lanConfig_cursor == 2) + M_DrawCharacter (basex+16 + 8*strlen(lanConfig_joinname), lanConfig_cursor_table [2], 10+((int)(realtime*4)&1)); + } + +} + + +void M_LanConfig_Key (int key) +{ + int l; + + switch (key) + { + case K_ESCAPE: +// M_Menu_Net_f (); + M_Menu_MultiPlayer_f (); + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + lanConfig_cursor--; + if (lanConfig_cursor < 0) + lanConfig_cursor = NUM_LANCONFIG_CMDS-1; + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + lanConfig_cursor++; + if (lanConfig_cursor >= NUM_LANCONFIG_CMDS) + lanConfig_cursor = 0; + break; + + case K_INS: + if (lanConfig_cursor == 0) + { + M_Menu_OSK_f(lanConfig_portname, lanConfig_portname, 6); + break; + } + + if (lanConfig_cursor == 2) + { + M_Menu_OSK_f(lanConfig_joinname, lanConfig_joinname, 22); + break; + } + break; + + case K_ENTER: + if (lanConfig_cursor == 0) + break; + + m_entersound = true; + + M_ConfigureNetSubsystem (); + + if (lanConfig_cursor == 1) + { + if (StartingGame) + { + M_Menu_GameOptions_f (); + break; + } + M_Menu_Search_f(); + break; + } + + if (lanConfig_cursor == 2) + { + m_return_state = m_state; + m_return_onerror = true; + key_dest = key_game; + m_state = m_none; + + // If we were in a multiplayer game, reset all the deathmatch flags to 0; + + items_respawn = 1; + weapons_stay = + pistols = + automatics = + shotguns = + explosives = + snipers = + exit_non_fatal = + infinite_ammo = + all_weapons = + no_reload = + no_armor = + no_health = + armor_regen = + health_regen = + safe_spawn = + no_bots = 0; + + if(kurok) + Cbuf_AddText ("viewsize 120\n cl_gunpitch 0\n fov 90\n scr_ofsy 0\n cl_autoaim 1\n chase_active 0\n"); + + Cbuf_AddText ( va ("connect \"%s\"\n", lanConfig_joinname) ); + break; + } + + break; + + case K_BACKSPACE: + if (lanConfig_cursor == 0) + { + if (strlen(lanConfig_portname)) + lanConfig_portname[strlen(lanConfig_portname)-1] = 0; + } + + if (lanConfig_cursor == 2) + { + if (strlen(lanConfig_joinname)) + lanConfig_joinname[strlen(lanConfig_joinname)-1] = 0; + } + break; + + default: + if (key < 32 || key > 127) + break; + + if (lanConfig_cursor == 2) + { + l = strlen(lanConfig_joinname); + if (l < 21) + { + lanConfig_joinname[l+1] = 0; + lanConfig_joinname[l] = key; + } + } + + if (key < '0' || key > '9') + break; + if (lanConfig_cursor == 0) + { + l = strlen(lanConfig_portname); + if (l < 5) + { + lanConfig_portname[l+1] = 0; + lanConfig_portname[l] = key; + } + } + } + + if (StartingGame && lanConfig_cursor == 2) + { + if (key == K_UPARROW) + lanConfig_cursor = 1; + else + lanConfig_cursor = 0; + } + + l = Q_atoi(lanConfig_portname); + if (l > 65535) + l = lanConfig_port; + else + lanConfig_port = l; + sprintf(lanConfig_portname, "%u", lanConfig_port); +} + +//============================================================================= +/* GAME OPTIONS MENU */ + +typedef struct +{ + char *name; + char *description; +} level_t; + +level_t levels[] = +{ + {"start", "Entrance"}, // 0 + + {"e1m1", "Slipgate Complex"}, // 1 + {"e1m2", "Castle of the Damned"}, + {"e1m3", "The Necropolis"}, + {"e1m4", "The Grisly Grotto"}, + {"e1m5", "Gloom Keep"}, + {"e1m6", "The Door To Chthon"}, + {"e1m7", "The House of Chthon"}, + {"e1m8", "Ziggurat Vertigo"}, + + {"e2m1", "The Installation"}, // 9 + {"e2m2", "Ogre Citadel"}, + {"e2m3", "Crypt of Decay"}, + {"e2m4", "The Ebon Fortress"}, + {"e2m5", "The Wizard's Manse"}, + {"e2m6", "The Dismal Oubliette"}, + {"e2m7", "Underearth"}, + + {"e3m1", "Termination Central"}, // 16 + {"e3m2", "The Vaults of Zin"}, + {"e3m3", "The Tomb of Terror"}, + {"e3m4", "Satan's Dark Delight"}, + {"e3m5", "Wind Tunnels"}, + {"e3m6", "Chambers of Torment"}, + {"e3m7", "The Haunted Halls"}, + + {"e4m1", "The Sewage System"}, // 23 + {"e4m2", "The Tower of Despair"}, + {"e4m3", "The Elder God Shrine"}, + {"e4m4", "The Palace of Hate"}, + {"e4m5", "Hell's Atrium"}, + {"e4m6", "The Pain Maze"}, + {"e4m7", "Azure Agony"}, + {"e4m8", "The Nameless City"}, + + {"end", "Shub-Niggurath's Pit"}, // 31 + + {"dm1", "Place of Two Deaths"}, // 32 + {"dm2", "Claustrophobopolis"}, + {"dm3", "The Abandoned Base"}, + {"dm4", "The Bad Place"}, + {"dm5", "The Cistern"}, + {"dm6", "The Dark Zone"} +}; + +level_t kuroklevels[] = +{ + {"start", "Entrance"}, // 0 + {"Maze", "Small Test place"}, + {"Foundation", "Halo 2's best map"}, + {"Station-118", "A small 2v2 base"}, + {"Cliff", "Flaming Ice best map"}, + {"Chill", "Jomart-2000 Halo 1 remake"}, + {"Lockout", "Not complete"}, + {"prisoner", "Jomart2000"}, + {"Rat", "Jomart2000"}, + + {"Needle", "How many points can you rake up?"}, // 9 + {"spawn", "Elite Firefight"}, + {"elite", "Elite fight"}, + {"kdm4", "GE: Complex"}, + {"kdm5", "RF: Lobby"}, + {"kdm6", "HL:Crossfire"}, + {"kdm7", "PD: Area 52"} +}; + +//MED 01/06/97 added hipnotic levels +level_t hipnoticlevels[] = +{ + {"start", "Command HQ"}, // 0 + + {"hip1m1", "The Pumping Station"}, // 1 + {"hip1m2", "Storage Facility"}, + {"hip1m3", "The Lost Mine"}, + {"hip1m4", "Research Facility"}, + {"hip1m5", "Military Complex"}, + + {"hip2m1", "Ancient Realms"}, // 6 + {"hip2m2", "The Black Cathedral"}, + {"hip2m3", "The Catacombs"}, + {"hip2m4", "The Crypt"}, + {"hip2m5", "Mortum's Keep"}, + {"hip2m6", "The Gremlin's Domain"}, + + {"hip3m1", "Tur Torment"}, // 12 + {"hip3m2", "Pandemonium"}, + {"hip3m3", "Limbo"}, + {"hip3m4", "The Gauntlet"}, + + {"hipend", "Armagon's Lair"}, // 16 + + {"hipdm1", "The Edge of Oblivion"} // 17 +}; + +//PGM 01/07/97 added rogue levels +//PGM 03/02/97 added dmatch level +level_t roguelevels[] = +{ + {"start", "Split Decision"}, + {"r1m1", "Deviant's Domain"}, + {"r1m2", "Dread Portal"}, + {"r1m3", "Judgement Call"}, + {"r1m4", "Cave of Death"}, + {"r1m5", "Towers of Wrath"}, + {"r1m6", "Temple of Pain"}, + {"r1m7", "Tomb of the Overlord"}, + {"r2m1", "Tempus Fugit"}, + {"r2m2", "Elemental Fury I"}, + {"r2m3", "Elemental Fury II"}, + {"r2m4", "Curse of Osiris"}, + {"r2m5", "Wizard's Keep"}, + {"r2m6", "Blood Sacrifice"}, + {"r2m7", "Last Bastion"}, + {"r2m8", "Source of Evil"}, + {"ctf1", "Division of Change"} +}; + +typedef struct +{ + char *description; + int firstLevel; + int levels; +} episode_t; + +episode_t episodes[] = +{ + {"Welcome to Quake", 0, 1}, + {"Doomed Dimension", 1, 8}, + {"Realm of Black Magic", 9, 7}, + {"Netherworld", 16, 7}, + {"The Elder World", 23, 8}, + {"Final Level", 31, 1}, + {"Deathmatch Arena", 32, 6} +}; + +episode_t kurokepisodes[] = +{ + {"Revamped start", 0, 1}, + {"Revamped maps", 1, 8}, + {"Mini games", 9, 7} +}; + +//MED 01/06/97 added hipnotic episodes +episode_t hipnoticepisodes[] = +{ + {"Scourge of Armagon", 0, 1}, + {"Fortress of the Dead", 1, 5}, + {"Dominion of Darkness", 6, 6}, + {"The Rift", 12, 4}, + {"Final Level", 16, 1}, + {"Deathmatch Arena", 17, 1} +}; + +//PGM 01/07/97 added rogue episodes +//PGM 03/02/97 added dmatch episode +episode_t rogueepisodes[] = +{ + {"Introduction", 0, 1}, + {"Hell's Fortress", 1, 7}, + {"Corridors of Time", 8, 8}, + {"Deathmatch Arena", 16, 1} +}; + +int startepisode; +int startlevel; +int maxplayers; +qboolean m_serverInfoMessage = false; +double m_serverInfoMessageTime; + +void M_Menu_GameOptions_f (void) +{ + key_dest = key_menu; + m_state = m_gameoptions; + m_entersound = true; + if (maxplayers == 0) + maxplayers = svs.maxclients; + if (maxplayers < 2) + maxplayers = svs.maxclientslimit; +} + +int gameoptions_cursor_table[] = {40, 56, 64, 72, 80, 88, 96, 104, 112, 144, 152}; +int gameoptions_cursor_tablek[] = {40, 56, 64, 72, 80, 88, 96, 104, 112, 128, 144, 152}; +#define NUM_GAMEOPTIONS 11 +#define NUM_KGAMEOPTIONS 12 +int gameoptions_cursor; + +void M_GameOptions_Draw (void) +{ + qpic_t *p,*b; + int x; +// int r; + + if (kurok) + // line cursor + M_DrawCharacter (144, gameoptions_cursor_tablek[gameoptions_cursor], 12+((int)(realtime*30)&1)); + else + { + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + // line cursor + M_DrawCharacter (144, gameoptions_cursor_table[gameoptions_cursor], 12+((int)(realtime*4)&1)); + } + + b = Draw_CachePic ("gfx/m_bttns.lmp"); + M_DrawPic ( (320-b->width)/2, 248, b ); + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + M_DrawTextBox (152, 32, 10, 1); + M_PrintWhite (160, 40, "begin game"); + + M_PrintWhite (0, 56, " Max players"); + M_Print (160, 56, va("%i", maxplayers) ); + + M_PrintWhite (0, 64, " Game Type"); + if (coop.value) + M_Print (160, 64, "Cooperative"); + else + M_Print (160, 64, "Deathmatch"); + + M_PrintWhite (0, 72, " Teamplay"); + if (rogue) + { + char *msg; + + switch((int)teamplay.value) + { + case 1: msg = "No Friendly Fire"; break; + case 2: msg = "Friendly Fire"; break; + case 3: msg = "Tag"; break; + case 4: msg = "Capture the Flag"; break; + case 5: msg = "One Flag CTF"; break; + case 6: msg = "Three Team CTF"; break; + default: msg = "Off"; break; + } + M_Print (160, 72, msg); + } + else + { + char *msg; + + switch((int)teamplay.value) + { + case 1: msg = "No Friendly Fire"; break; + case 2: msg = "Friendly Fire"; break; + default: msg = "Off"; break; + } + M_Print (160, 72, msg); + } + + M_PrintWhite (0, 80, " Skill"); + if (skill.value == 0) + M_Print (160, 80, "Easy difficulty"); + else if (skill.value == 1) + M_Print (160, 80, "Normal difficulty"); + else if (skill.value == 2) + M_Print (160, 80, "Hard difficulty"); + else + { + if (kurok) + M_Print (160, 80, "Insane difficulty"); + else + M_Print (160, 80, "Nightmare difficulty"); + } + + M_PrintWhite (0, 88, " Frag Limit"); + if (fraglimit.value == 0) + M_Print (160, 88, "none"); + else + M_Print (160, 88, va("%i frags", (int)fraglimit.value)); + + M_PrintWhite (0, 96, " Time Limit"); + if (timelimit.value == 0) + M_Print (160, 96, "none"); + else + M_Print (160, 96, va("%i minutes", (int)timelimit.value)); + + M_PrintWhite (0, 104, " Auto Aim"); + if (sv_aim.value == 1) + M_Print (160, 104, "Off"); + else + M_Print (160, 104, "On"); + + M_PrintWhite (0, 112, " Level Exits"); + if (noexit.value == 1) + M_Print (160, 112, "Off"); + else + M_Print (160, 112, "On"); + + if(kurok) + { + M_DrawTextBox (152, 120, 18, 1); + M_PrintWhite (160, 128, "Deathmatch Options"); + } + + M_PrintWhite (0, 144, " Episode"); + //MED 01/06/97 added hipnotic episodes + if (hipnotic) + M_Print (160, 144, hipnoticepisodes[startepisode].description); + //PGM 01/07/97 added rogue episodes + else if (rogue) + M_Print (160, 144, rogueepisodes[startepisode].description); + else if (kurok) + M_Print (160, 144, kurokepisodes[startepisode].description); + else + M_Print (160, 144, episodes[startepisode].description); + + M_PrintWhite (0, 152, " Level"); + //MED 01/06/97 added hipnotic episodes + if (hipnotic) + { + M_Print (160, 152, hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].description); + M_Print (160, 160, hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].name); + } + //PGM 01/07/97 added rogue episodes + else if (rogue) + { + M_Print (160, 152, roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].description); + M_Print (160, 160, roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].name); + } + else if (kurok) + { + M_Print (160, 152, kuroklevels[kurokepisodes[startepisode].firstLevel + startlevel].description); + M_Print (160, 160, kuroklevels[kurokepisodes[startepisode].firstLevel + startlevel].name); + } + else + { + M_Print (160, 152, levels[episodes[startepisode].firstLevel + startlevel].description); + M_Print (160, 160, levels[episodes[startepisode].firstLevel + startlevel].name); + } + + if (m_serverInfoMessage) + { + if ((realtime - m_serverInfoMessageTime) < 5.0) + { + x = (320-26*8)/2; + M_DrawTextBox (x, 138, 24, 4); + x += 8; + M_Print (x, 146, " More than 4 players "); + M_Print (x, 154, " requires using command "); + M_Print (x, 162, " line -listen. Use "); + M_Print (x, 170, " -listen 8 for example. "); + } + else + { + m_serverInfoMessage = false; + } + } +} + + +void M_NetStart_Change (int dir) +{ + int count; + + switch (gameoptions_cursor) + { + case 1: + maxplayers += dir; + if (maxplayers > svs.maxclientslimit) + { + maxplayers = svs.maxclientslimit; + m_serverInfoMessage = true; + m_serverInfoMessageTime = realtime; + } + if (maxplayers < 2) + maxplayers = 2; + break; + + case 2: + Cvar_SetValue ("coop", coop.value ? 0 : 1); + break; + + case 3: + if (rogue) + count = 6; + else + count = 2; + + Cvar_SetValue ("teamplay", teamplay.value + dir); + if (teamplay.value > count) + Cvar_SetValue ("teamplay", 0); + else if (teamplay.value < 0) + Cvar_SetValue ("teamplay", count); + break; + + case 4: + Cvar_SetValue ("skill", skill.value + dir); + if (skill.value > 3) + Cvar_SetValue ("skill", 0); + if (skill.value < 0) + Cvar_SetValue ("skill", 3); + break; + + case 5: + Cvar_SetValue ("fraglimit", fraglimit.value + dir*10); + if (fraglimit.value > 100) + Cvar_SetValue ("fraglimit", 0); + if (fraglimit.value < 0) + Cvar_SetValue ("fraglimit", 100); + break; + + case 6: + Cvar_SetValue ("timelimit", timelimit.value + dir*5); + if (timelimit.value > 60) + Cvar_SetValue ("timelimit", 0); + if (timelimit.value < 0) + Cvar_SetValue ("timelimit", 60); + break; + + case 7: + Cvar_SetValue ("sv_aim", sv_aim.value + dir * 0.01); + if (sv_aim.value > 1) + Cvar_SetValue ("sv_aim", 0.99); + if (sv_aim.value < 0.99) + Cvar_SetValue ("sv_aim", 1); + break; + + case 8: + Cvar_SetValue ("noexit", noexit.value ? 0 : 1); + break; + + case 9: + if (kurok) + break; + + startepisode += dir; + //MED 01/06/97 added hipnotic count + if (hipnotic) + count = 6; + //PGM 01/07/97 added rogue count + //PGM 03/02/97 added 1 for dmatch episode + else if (rogue) + count = 4; + else if (kurok) + count = 3; + else if (registered.value) + count = 7; + else + count = 2; + + if (startepisode < 0) + startepisode = count - 1; + + if (startepisode >= count) + startepisode = 0; + + startlevel = 0; + break; + + case 10: + if (kurok) + { + startepisode += dir; + //MED 01/06/97 added hipnotic count + if (hipnotic) + count = 6; + //PGM 01/07/97 added rogue count + //PGM 03/02/97 added 1 for dmatch episode + else if (rogue) + count = 4; + else if (kurok) + count = 3; + else if (registered.value) + count = 7; + else + count = 2; + + if (startepisode < 0) + startepisode = count - 1; + + if (startepisode >= count) + startepisode = 0; + + startlevel = 0; + break; + } + else + { + startlevel += dir; + //MED 01/06/97 added hipnotic episodes + if (hipnotic) + count = hipnoticepisodes[startepisode].levels; + //PGM 01/06/97 added hipnotic episodes + else if (rogue) + count = rogueepisodes[startepisode].levels; + else if (kurok) + count = kurokepisodes[startepisode].levels; + else + count = episodes[startepisode].levels; + + if (startlevel < 0) + startlevel = count - 1; + + if (startlevel >= count) + startlevel = 0; + break; + } + case 11: + startlevel += dir; + //MED 01/06/97 added hipnotic episodes + if (hipnotic) + count = hipnoticepisodes[startepisode].levels; + //PGM 01/06/97 added hipnotic episodes + else if (rogue) + count = rogueepisodes[startepisode].levels; + else if (kurok) + count = kurokepisodes[startepisode].levels; + else + count = episodes[startepisode].levels; + + if (startlevel < 0) + startlevel = count - 1; + + if (startlevel >= count) + startlevel = 0; + break; + } +} + +void M_GameOptions_Key (int key) +{ + switch (key) + { + case K_ESCAPE: +// M_Menu_Net_f (); + M_Menu_MultiPlayer_f (); + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + gameoptions_cursor--; + if (kurok) + { + if (gameoptions_cursor < 0) + gameoptions_cursor = NUM_KGAMEOPTIONS-1; + } + else + { + if (gameoptions_cursor < 0) + gameoptions_cursor = NUM_GAMEOPTIONS-1; + } + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + gameoptions_cursor++; + if (kurok) + { + if (gameoptions_cursor >= NUM_KGAMEOPTIONS) + gameoptions_cursor = 0; + } + else + { + if (gameoptions_cursor >= NUM_GAMEOPTIONS) + gameoptions_cursor = 0; + } + break; + + case K_LEFTARROW: + if (kurok) + { + if (gameoptions_cursor == (0 || 9)) + break; + } + else + { + if (gameoptions_cursor == 0) + break; + } + S_LocalSound ("misc/menu3.wav"); + M_NetStart_Change (-1); + break; + + case K_RIGHTARROW: + if (kurok) + { + if (gameoptions_cursor == (0 || 9)) + break; + } + else + { + if (gameoptions_cursor == 0) + break; + } + S_LocalSound ("misc/menu3.wav"); + M_NetStart_Change (1); + break; + + case K_ENTER: + S_LocalSound ("misc/menu2.wav"); + if (gameoptions_cursor == 0) + { + if (sv.active) + Cbuf_AddText ("disconnect\n"); + Cbuf_AddText ("listen 0\n"); // so host_netport will be re-examined + Cbuf_AddText ( va ("maxplayers %u\n", maxplayers) ); + SCR_BeginLoadingPlaque (); + + if(kurok) + Cbuf_AddText ("viewsize 120\n cl_gunpitch 0\n fov 90\n scr_ofsy 0\n cl_autoaim 1\n chase_active 0\n"); + + if (hipnotic) + Cbuf_AddText ( va ("map %s\n", hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].name) ); + else if (rogue) + Cbuf_AddText ( va ("map %s\n", roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].name) ); + else if (kurok) + Cbuf_AddText ( va ("map %s\n", kuroklevels[kurokepisodes[startepisode].firstLevel + startlevel].name) ); + else + Cbuf_AddText ( va ("map %s\n", levels[episodes[startepisode].firstLevel + startlevel].name) ); + + return; + } + + if (kurok) + { + if (gameoptions_cursor == 9) + { + M_Menu_DOptions_f(); + break; + } + } + + M_NetStart_Change (1); + break; + } +} + + +/* +---------------------------------------------------------------------------------------------- +DEATHMATCH OPTIONS +---------------------------------------------------------------------------------------------- +*/ + +int DM_RESPAWN = 1; +int DM_WEAPONS_STAY = 2; +int DM_PISTOLS = 4; +int DM_AUTOMATICS = 8; +int DM_SHOTGUNS = 16; +int DM_EXPLOSIVES = 32; +int DM_SNIPERS = 64; +int DM_EXIT_NON_FATAL = 128; +int DM_INFINITE_AMMO = 256; +int DM_ALL_WEAPONS = 512; +int DM_NO_RELOAD = 1024; +int DM_NO_ARMOR = 2048; +int DM_NO_HEALTH = 4096; +int DM_ARMOR_REGEN = 8192; +int DM_HEALTH_REGEN = 16384; +int DM_SAFE_SPAWN = 32768; +int DM_NO_BOTS = 65536; + +qboolean m_dOptionsInfoMessage = false; +double m_dOptionsInfoMessageTime; + +int doptions_cursor_table[] = {40, 56, 64, 72, 80, 88, 96, 104, 112, 128, 136, 144, 152, 160, 168, 176, 184, 192}; +#define NUM_DOPTIONS 18 +int doptions_cursor; + +void M_Menu_DOptions_f (void) +{ + key_dest = key_menu; + m_state = m_doptions; + m_entersound = true; +} + +void M_AdjustDSliders (int dir) +{ + S_LocalSound ("misc/menu3.wav"); + + switch (doptions_cursor) + { + + case 1: // Item Respawns + if (deathmatch.value > 1) + { + items_respawn += dir * 1; + + if (items_respawn < 0) + { + items_respawn = 0; + break; + } + if (items_respawn > 1) + { + items_respawn = 1; + break; + } + + if (items_respawn == 0) + deathmatch.value = deathmatch.value - DM_RESPAWN; + if (items_respawn == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN; + + Cvar_SetValue ("deathmatch", deathmatch.value); + } + else + { + items_respawn = 1; + deathmatch.value = 1; + Cvar_SetValue ("deathmatch", deathmatch.value); + + m_dOptionsInfoMessage = true; + m_dOptionsInfoMessageTime = realtime; + } + break; + + case 2: // Weapon stays + weapons_stay += dir * 1; + + if (weapons_stay < 0) + { + weapons_stay = 0; + break; + } + if (weapons_stay > 1) + { + weapons_stay = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_WEAPONS_STAY && weapons_stay == 0)) + { + items_respawn = 1; + + if (weapons_stay == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_WEAPONS_STAY; + if (weapons_stay == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_WEAPONS_STAY; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (weapons_stay == 0) + deathmatch.value = deathmatch.value - DM_WEAPONS_STAY; + if (weapons_stay == 1) + deathmatch.value = deathmatch.value + DM_WEAPONS_STAY; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 3: // Pistols + pistols += dir * 1; + + if (pistols < 0) + { + pistols = 0; + break; + } + if (pistols > 1) + { + pistols = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_PISTOLS && pistols == 0)) + { + items_respawn = 1; + + if (pistols == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_PISTOLS; + if (pistols == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_PISTOLS; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (pistols == 0) + deathmatch.value = deathmatch.value - DM_PISTOLS; + if (pistols == 1) + deathmatch.value = deathmatch.value + DM_PISTOLS; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 4: // Automatics + automatics += dir * 1; + + if (automatics < 0) + { + automatics = 0; + break; + } + if (automatics > 1) + { + automatics = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_AUTOMATICS && automatics == 0)) + { + items_respawn = 1; + + if (automatics == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_AUTOMATICS; + if (automatics == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_AUTOMATICS; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (automatics == 0) + deathmatch.value = deathmatch.value - DM_AUTOMATICS; + if (automatics == 1) + deathmatch.value = deathmatch.value + DM_AUTOMATICS; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 5: // Shotguns + shotguns += dir * 1; + + if (shotguns < 0) + { + shotguns = 0; + break; + } + if (shotguns > 1) + { + shotguns = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_SHOTGUNS && shotguns == 0)) + { + items_respawn = 1; + + if (shotguns == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_SHOTGUNS; + if (shotguns == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_SHOTGUNS; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (shotguns == 0) + deathmatch.value = deathmatch.value - DM_SHOTGUNS; + if (shotguns == 1) + deathmatch.value = deathmatch.value + DM_SHOTGUNS; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 6: // Explosives + explosives += dir * 1; + + if (explosives < 0) + { + explosives = 0; + break; + } + if (explosives > 1) + { + explosives = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_EXPLOSIVES && explosives == 0)) + { + items_respawn = 1; + + if (explosives == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_EXPLOSIVES; + if (explosives == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_EXPLOSIVES; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (explosives == 0) + deathmatch.value = deathmatch.value - DM_EXPLOSIVES; + if (explosives == 1) + deathmatch.value = deathmatch.value + DM_EXPLOSIVES; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 7: // Snipers + snipers += dir * 1; + + if (snipers < 0) + { + snipers = 0; + break; + } + if (snipers > 1) + { + snipers = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_SNIPERS && snipers == 0)) + { + items_respawn = 1; + + if (snipers == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_SNIPERS; + if (snipers == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_SNIPERS; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (snipers == 0) + deathmatch.value = deathmatch.value - DM_SNIPERS; + if (snipers == 1) + deathmatch.value = deathmatch.value + DM_SNIPERS; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 8: // Exit non fatal + exit_non_fatal += dir * 1; + + if (exit_non_fatal < 0) + { + exit_non_fatal = 0; + break; + } + if (exit_non_fatal > 1) + { + exit_non_fatal = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_EXIT_NON_FATAL && exit_non_fatal == 0)) + { + items_respawn = 1; + + if (exit_non_fatal == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_EXIT_NON_FATAL; + if (exit_non_fatal == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_EXIT_NON_FATAL; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (exit_non_fatal == 0) + deathmatch.value = deathmatch.value - DM_EXIT_NON_FATAL; + if (exit_non_fatal == 1) + deathmatch.value = deathmatch.value + DM_EXIT_NON_FATAL; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 9: // Infinite Ammo + infinite_ammo += dir * 1; + + if (infinite_ammo < 0) + { + infinite_ammo = 0; + break; + } + if (infinite_ammo > 1) + { + infinite_ammo = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_INFINITE_AMMO && infinite_ammo == 0)) + { + items_respawn = 1; + + if (infinite_ammo == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_INFINITE_AMMO; + if (infinite_ammo == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_INFINITE_AMMO; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (infinite_ammo == 0) + deathmatch.value = deathmatch.value - DM_INFINITE_AMMO; + if (infinite_ammo == 1) + deathmatch.value = deathmatch.value + DM_INFINITE_AMMO; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 10: // All weapons + all_weapons += dir * 1; + + if (all_weapons < 0) + { + all_weapons = 0; + break; + } + if (all_weapons > 1) + { + all_weapons = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_ALL_WEAPONS && all_weapons == 0)) + { + items_respawn = 1; + + if (all_weapons == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_ALL_WEAPONS; + if (all_weapons == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_ALL_WEAPONS; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (all_weapons == 0) + deathmatch.value = deathmatch.value - DM_ALL_WEAPONS; + if (all_weapons == 1) + deathmatch.value = deathmatch.value + DM_ALL_WEAPONS; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 11: // No reloading + no_reload += dir * 1; + + if (no_reload < 0) + { + no_reload = 0; + break; + } + if (no_reload > 1) + { + no_reload = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_NO_RELOAD && no_reload == 0)) + { + items_respawn = 1; + + if (no_reload == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_NO_RELOAD; + if (no_reload == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_NO_RELOAD; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (no_reload == 0) + deathmatch.value = deathmatch.value - DM_NO_RELOAD; + if (no_reload == 1) + deathmatch.value = deathmatch.value + DM_NO_RELOAD; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 12: // No armor + no_armor += dir * 1; + + if (no_armor < 0) + { + no_armor = 0; + break; + } + if (no_armor > 1) + { + no_armor = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_NO_ARMOR && no_armor == 0)) + { + items_respawn = 1; + + if (no_armor == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_NO_ARMOR; + if (no_armor == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_NO_ARMOR; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (no_armor == 0) + deathmatch.value = deathmatch.value - DM_NO_ARMOR; + if (no_armor == 1) + deathmatch.value = deathmatch.value + DM_NO_ARMOR; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 13: // No health + no_health += dir * 1; + + if (no_health < 0) + { + no_health = 0; + break; + } + if (no_health > 1) + { + no_health = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_NO_HEALTH && no_health == 0)) + { + items_respawn = 1; + + if (no_health == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_NO_HEALTH; + if (no_health == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_NO_HEALTH; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (no_health == 0) + deathmatch.value = deathmatch.value - DM_NO_HEALTH; + if (no_health == 1) + deathmatch.value = deathmatch.value + DM_NO_HEALTH; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 14: // Armor regen + armor_regen += dir * 1; + + if (armor_regen < 0) + { + armor_regen = 0; + break; + } + if (armor_regen > 1) + { + armor_regen = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_ARMOR_REGEN && armor_regen == 0)) + { + items_respawn = 1; + + if (armor_regen == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_ARMOR_REGEN; + if (armor_regen == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_ARMOR_REGEN; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (armor_regen == 0) + deathmatch.value = deathmatch.value - DM_ARMOR_REGEN; + if (armor_regen == 1) + deathmatch.value = deathmatch.value + DM_ARMOR_REGEN; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 15: // Health regen + health_regen += dir * 1; + + if (health_regen < 0) + { + health_regen = 0; + break; + } + if (health_regen > 1) + { + health_regen = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_HEALTH_REGEN && health_regen == 0)) + { + items_respawn = 1; + + if (health_regen == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_HEALTH_REGEN; + if (health_regen == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_HEALTH_REGEN; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (health_regen == 0) + deathmatch.value = deathmatch.value - DM_HEALTH_REGEN; + if (health_regen == 1) + deathmatch.value = deathmatch.value + DM_HEALTH_REGEN; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 16: // Safe spawn + safe_spawn += dir * 1; + + if (safe_spawn < 0) + { + safe_spawn = 0; + break; + } + if (safe_spawn > 1) + { + safe_spawn = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_SAFE_SPAWN && safe_spawn == 0)) + { + items_respawn = 1; + + if (safe_spawn == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_SAFE_SPAWN; + if (safe_spawn == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_SAFE_SPAWN; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (safe_spawn == 0) + deathmatch.value = deathmatch.value - DM_SAFE_SPAWN; + if (safe_spawn == 1) + deathmatch.value = deathmatch.value + DM_SAFE_SPAWN; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + + case 17: // No bots + no_bots += dir * 1; + + if (no_bots < 0) + { + no_bots = 0; + break; + } + if (no_bots > 1) + { + no_bots = 1; + break; + } + + if (items_respawn == 0 && (deathmatch.value <= DM_NO_BOTS && no_bots == 0)) + { + items_respawn = 1; + + if (no_bots == 0) + deathmatch.value = deathmatch.value + DM_RESPAWN - DM_NO_BOTS; + if (no_bots == 1) + deathmatch.value = deathmatch.value + DM_RESPAWN + DM_NO_BOTS; + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } + + if (no_bots == 0) + deathmatch.value = deathmatch.value - DM_NO_BOTS; + if (no_bots == 1) + deathmatch.value = deathmatch.value + DM_NO_BOTS; + + Cvar_SetValue ("deathmatch", deathmatch.value); + break; + } +} + +void M_DOptions_Draw (void) +{ + qpic_t *p; + int x; + + if(!kurok) + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + M_DrawTextBox (152, 32, 4, 1); + M_PrintWhite (160, 40, "Back"); + + M_PrintWhite (0, 56, " Item Respawn"); + M_DrawCheckbox (208, 56, items_respawn == 1); + + M_PrintWhite (0, 64, " Weapons Stay"); + M_DrawCheckbox (208, 64, weapons_stay == 1); + + M_PrintWhite (0, 72, " Pistols Only"); + M_DrawCheckbox (208, 72, pistols == 1); + + M_PrintWhite (0, 80, " Automatics Only"); + M_DrawCheckbox (208, 80, automatics == 1); + + M_PrintWhite (0, 88, " Shotguns Only"); + M_DrawCheckbox (208, 88, shotguns == 1); + + M_PrintWhite (0, 96, " Explosives Only"); + M_DrawCheckbox (208, 96, explosives == 1); + + M_PrintWhite (0, 104, " Snipers Only"); + M_DrawCheckbox (208, 104, snipers == 1); + + M_PrintWhite (0, 112, " Exits don't kill"); + M_DrawCheckbox (208, 112, exit_non_fatal == 1); + + M_PrintWhite (0, 128, " Infinite Ammo"); + M_DrawCheckbox (208, 128, infinite_ammo == 1); + + M_PrintWhite (0, 136, " All Weapons"); + M_DrawCheckbox (208, 136, all_weapons == 1); + + M_PrintWhite (0, 144, " No Reload"); + M_DrawCheckbox (208, 144, no_reload == 1); + + M_PrintWhite (0, 152, " No Armor Items"); + M_DrawCheckbox (208, 152, no_armor == 1); + + M_PrintWhite (0, 160, " No Health Items"); + M_DrawCheckbox (208, 160, no_health == 1); + + M_PrintWhite (0, 168, " Armor Regenerates"); + M_DrawCheckbox (208, 168, armor_regen == 1); + + M_PrintWhite (0, 176, " Health Regenerates"); + M_DrawCheckbox (208, 176, health_regen == 1); + + M_PrintWhite (0, 184, " Safe Spawn"); + M_DrawCheckbox (208, 184, safe_spawn == 1); + + M_PrintWhite (0, 192, " No Bots"); + M_DrawCheckbox (208, 192, no_bots == 1); + +// line cursor + if(doptions_cursor == 0) + M_DrawCharacter (152, doptions_cursor_table[doptions_cursor], 12+((int)(realtime*30)&1)); + else + M_DrawCharacter (192, doptions_cursor_table[doptions_cursor], 12+((int)(realtime*30)&1)); + + + if (m_dOptionsInfoMessage) + { + if ((realtime - m_dOptionsInfoMessageTime) < 2.0) + { + x = (320-26*8)/2; + M_DrawTextBox (x, 138, 24, 4); + x += 8; + M_Print (x, 146, " Cannot turn off "); + M_Print (x, 154, " item respawns if no "); + M_Print (x, 162, " no other deathmatch "); + M_Print (x, 170, " options are set! "); + } + else + { + m_dOptionsInfoMessage = false; + } + } +} + +void M_DOptions_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + M_Menu_GameOptions_f(); + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + doptions_cursor--; + + if (doptions_cursor < 0) + doptions_cursor = NUM_DOPTIONS-1; + + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + doptions_cursor++; + + if (doptions_cursor >= NUM_DOPTIONS) + doptions_cursor = 0; + + break; + + case K_LEFTARROW: + if (doptions_cursor == 0) + break; + M_AdjustDSliders (-1); + break; + + case K_RIGHTARROW: + if (doptions_cursor == 0) + break; + M_AdjustDSliders (1); + break; + + case K_ENTER: + S_LocalSound ("misc/menu2.wav"); + if (doptions_cursor == 0) + { + M_Menu_GameOptions_f(); + return; + } + M_AdjustDSliders (1); + break; + } +} + +//============================================================================= +/* SEARCH MENU */ + +qboolean searchComplete = false; +double searchCompleteTime; + +void M_Menu_Search_f (void) +{ + key_dest = key_menu; + m_state = m_search; + m_entersound = false; + slistSilent = true; + slistLocal = false; + searchComplete = false; + NET_Slist_f(); + +} + + +void M_Search_Draw (void) +{ + qpic_t *p; + int x; + + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + x = (320/2) - ((12*8)/2) + 4; + M_DrawTextBox (x-8, 32, 12, 1); + M_Print (x, 40, "Searching..."); + + if(slistInProgress) + { + NET_Poll(); + return; + } + + if (! searchComplete) + { + searchComplete = true; + searchCompleteTime = realtime; + } + + if (hostCacheCount) + { + M_Menu_ServerList_f (); + return; + } + + if (kurok) + { + M_PrintWhite ((320/2) - ((22*8)/2), 64, "No Kurok servers found"); + if ((realtime - searchCompleteTime) < 3.0) + return; + } + + else + { + M_PrintWhite ((320/2) - ((22*8)/2), 64, "No servers found"); + if ((realtime - searchCompleteTime) < 3.0) + return; + } + + M_Menu_LanConfig_f (); +} + + +void M_Search_Key (int key) +{ +} + +//============================================================================= +/* SLIST MENU */ + +int slist_cursor; +qboolean slist_sorted; + +void M_Menu_ServerList_f (void) +{ + key_dest = key_menu; + m_state = m_slist; + m_entersound = true; + slist_cursor = 0; + m_return_onerror = false; + m_return_reason[0] = 0; + slist_sorted = false; +} + + +void M_ServerList_Draw (void) +{ + int n; + char string [64]; + qpic_t *p; + + if (!slist_sorted) + { + if (hostCacheCount > 1) + { + int i,j; + hostcache_t temp; + for (i = 0; i < hostCacheCount; i++) + for (j = i+1; j < hostCacheCount; j++) + if (strcmp(hostcache[j].name, hostcache[i].name) < 0) + { + Q_memcpy(&temp, &hostcache[j], sizeof(hostcache_t)); + Q_memcpy(&hostcache[j], &hostcache[i], sizeof(hostcache_t)); + Q_memcpy(&hostcache[i], &temp, sizeof(hostcache_t)); + } + } + slist_sorted = true; + } + + if(kurok) + M_DrawCharacter (0, 32 + slist_cursor*8, 12+((int)(realtime*30)&1)); + else + M_DrawCharacter (0, 32 + slist_cursor*8, 12+((int)(realtime*4)&1)); + + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + for (n = 0; n < hostCacheCount; n++) + { + if (hostcache[n].maxusers) + sprintf(string, "%-15.15s %-15.15s %2u/%2u\n", hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers); + else + sprintf(string, "%-15.15s %-15.15s\n", hostcache[n].name, hostcache[n].map); + M_Print (16, 32 + 8*n, string); + } + + if (*m_return_reason) + M_PrintWhite (16, 148, m_return_reason); +} + + +void M_ServerList_Key (int k) +{ + switch (k) + { + case K_ESCAPE: + M_Menu_LanConfig_f (); + break; + + case K_SPACE: + M_Menu_Search_f (); + break; + + case K_UPARROW: + case K_LEFTARROW: + S_LocalSound ("misc/menu1.wav"); + slist_cursor--; + if (slist_cursor < 0) + slist_cursor = hostCacheCount - 1; + break; + + case K_DOWNARROW: + case K_RIGHTARROW: + S_LocalSound ("misc/menu1.wav"); + slist_cursor++; + if (slist_cursor >= hostCacheCount) + slist_cursor = 0; + break; + + case K_ENTER: + S_LocalSound ("misc/menu2.wav"); + m_return_state = m_state; + m_return_onerror = true; + slist_sorted = false; + key_dest = key_game; + m_state = m_none; + + // If we were in a multiplayer game, reset all the deathmatch flags to 0; + + items_respawn = 1; + weapons_stay = + pistols = + automatics = + shotguns = + explosives = + snipers = + exit_non_fatal = + infinite_ammo = + all_weapons = + no_reload = + no_armor = + no_health = + armor_regen = + health_regen = + safe_spawn = + no_bots = 0; + + if(kurok) + Cbuf_AddText ("viewsize 120\n cl_gunpitch 0\n fov 90\n scr_ofsy 0\n cl_autoaim 1\n chase_active 0\n"); + + Cbuf_AddText ( va ("connect \"%s\"\n", hostcache[slist_cursor].cname) ); + break; + + default: + break; + } + +} + +//============================================================================= +/* Menu Subsystem */ + + +void M_Init (void) +{ + Cmd_AddCommand ("togglemenu", M_ToggleMenu_f); + + Cmd_AddCommand ("menu_main", M_Menu_Main_f); + Cmd_AddCommand ("menu_singleplayer", M_Menu_SinglePlayer_f); + Cmd_AddCommand ("menu_load", M_Menu_Load_f); + Cmd_AddCommand ("menu_save", M_Menu_Save_f); + Cmd_AddCommand ("menu_multiplayer", M_Menu_MultiPlayer_f); + Cmd_AddCommand ("menu_setup", M_Menu_Setup_f); + Cmd_AddCommand ("menu_options", M_Menu_Options_f); + Cmd_AddCommand ("menu_keys", M_Menu_Keys_f); + Cmd_AddCommand ("menu_video", M_Menu_Video_f); + Cmd_AddCommand ("help", M_Menu_Help_f); + Cmd_AddCommand ("menu_quit", M_Menu_Quit_f); +} + + +void M_Draw (void) +{ + if (m_state == m_none || key_dest != key_menu) + return; + + if (!m_recursiveDraw) + { + scr_copyeverything = 1; + + if (scr_con_current) + { + Draw_ConsoleBackground (vid.height); + VID_UnlockBuffer (); + S_ExtraUpdate (); + VID_LockBuffer (); + } + else + { + if (kurok) + Draw_FadeScreen2 (); + else + Draw_FadeScreen (); + } + scr_fullupdate = 0; + } + else + { + m_recursiveDraw = false; + } + + switch (m_state) + { + case m_none: + break; + + case m_main: + M_Main_Draw (); + break; + + case m_singleplayer: + M_SinglePlayer_Draw (); + break; + + case m_load: + M_Load_Draw (); + break; + + case m_save: + M_Save_Draw (); + break; + + case m_multiplayer: + M_MultiPlayer_Draw (); + break; + + case m_setup: + M_Setup_Draw (); + break; + + case m_net: + M_Net_Draw (); + break; + + case m_options: + M_Options_Draw (); + break; + + case m_keys: + M_Keys_Draw (); + break; + + case m_video: + M_Video_Draw (); + break; + + case m_help: + M_Help_Draw (); + break; + + case m_quit: + M_Quit_Draw (); + break; + + case m_serialconfig: + M_SerialConfig_Draw (); + break; + + case m_modemconfig: + M_ModemConfig_Draw (); + break; + + case m_lanconfig: + M_LanConfig_Draw (); + break; + + case m_gameoptions: + M_GameOptions_Draw (); + break; + + case m_doptions: + M_DOptions_Draw (); + break; + + case m_search: + M_Search_Draw (); + break; + + case m_slist: + M_ServerList_Draw (); + break; + + case m_osk: + M_OSK_Draw(); + break; + } + + if (m_entersound) + { + S_LocalSound ("misc/menu2.wav"); + m_entersound = false; + } + + VID_UnlockBuffer (); + S_ExtraUpdate (); + VID_LockBuffer (); +} + + +void M_Keydown (int key) +{ + switch (m_state) + { + case m_none: + return; + + case m_main: + M_Main_Key (key); + return; + + case m_singleplayer: + M_SinglePlayer_Key (key); + return; + + case m_load: + M_Load_Key (key); + return; + + case m_save: + M_Save_Key (key); + return; + + case m_multiplayer: + M_MultiPlayer_Key (key); + return; + + case m_setup: + M_Setup_Key (key); + return; + + case m_net: + M_Net_Key (key); + return; + + case m_options: + M_Options_Key (key); + return; + + case m_keys: + M_Keys_Key (key); + return; + + case m_video: + M_Video_Key (key); + return; + + case m_help: + M_Help_Key (key); + return; + + case m_quit: + M_Quit_Key (key); + return; + + case m_serialconfig: + M_SerialConfig_Key (key); + return; + + case m_modemconfig: + M_ModemConfig_Key (key); + return; + + case m_lanconfig: + M_LanConfig_Key (key); + return; + + case m_gameoptions: + M_GameOptions_Key (key); + return; + + case m_doptions: + M_DOptions_Key (key); + return; + + case m_search: + M_Search_Key (key); + break; + + case m_slist: + M_ServerList_Key (key); + return; + + case m_osk: + M_OSK_Key(key); + } +} + + +void M_ConfigureNetSubsystem(void) +{ +// enable/disable net systems to match desired config + + Cbuf_AddText ("stopdemo\n"); + if (SerialConfig || DirectConfig) + { + Cbuf_AddText ("com1 enable\n"); + } + + if (IPXConfig || TCPIPConfig) + net_hostport = lanConfig_port; +} diff --git a/r17/Revamped src/revamped_src/menu.h b/r17/Revamped src/revamped_src/menu.h new file mode 100755 index 00000000..4ca2ed1f --- /dev/null +++ b/r17/Revamped src/revamped_src/menu.h @@ -0,0 +1,39 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +// +// the net drivers should just set the apropriate bits in m_activenet, +// instead of having the menu code look through their internal tables +// +#define MNET_IPX 1 +#define MNET_TCP 2 + +extern int m_activenet; + +// +// menus +// +void M_Init (void); +void M_Keydown (int key); +void M_Draw (void); +void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha); +void M_ToggleMenu_f (void); + + diff --git a/r17/Revamped src/revamped_src/model.c b/r17/Revamped src/revamped_src/model.c new file mode 100755 index 00000000..9e7005f7 --- /dev/null +++ b/r17/Revamped src/revamped_src/model.c @@ -0,0 +1,1887 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// models.c -- model loading and caching + +// models are the only shared resource between a client and server running +// on the same machine. + +#include "quakedef.h" +#include "r_local.h" + +model_t *loadmodel; +char loadname[32]; // for hunk tags + +void Mod_LoadSpriteModel (model_t *mod, void *buffer); +void Mod_LoadBrushModel (model_t *mod, void *buffer); +void Mod_LoadAliasModel (model_t *mod, void *buffer); +model_t *Mod_LoadModel (model_t *mod, qboolean crash); + +byte mod_novis[MAX_MAP_LEAFS/8]; + +#define MAX_MOD_KNOWN 256 +model_t mod_known[MAX_MOD_KNOWN]; +int mod_numknown; + +// values for model_t's needload +#define NL_PRESENT 0 +#define NL_NEEDS_LOADED 1 +#define NL_UNREFERENCED 2 + +/* +=============== +Mod_Init +=============== +*/ +void Mod_Init (void) +{ + memset (mod_novis, 0xff, sizeof(mod_novis)); +} + +/* +=============== +Mod_Extradata + +Caches the data if needed +=============== +*/ +void *Mod_Extradata (model_t *mod) +{ + void *r; + + r = Cache_Check (&mod->cache); + if (r) + return r; + + Mod_LoadModel (mod, true); + + if (!mod->cache.data) + Sys_Error ("Mod_Extradata: caching failed"); + return mod->cache.data; +} + +/* +=============== +Mod_PointInLeaf +=============== +*/ +mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) +{ + mnode_t *node; + float d; + mplane_t *plane; + + if (!model || !model->nodes) + Sys_Error ("Mod_PointInLeaf: bad model"); + + node = model->nodes; + while (1) + { + if (node->contents < 0) + return (mleaf_t *)node; + plane = node->plane; + d = DotProduct (p,plane->normal) - plane->dist; + if (d > 0) + node = node->children[0]; + else + node = node->children[1]; + } + + return NULL; // never reached +} + + +/* +=================== +Mod_DecompressVis +=================== +*/ +byte *Mod_DecompressVis (byte *in, model_t *model) +{ + static byte decompressed[MAX_MAP_LEAFS/8]; + int c; + byte *out; + int row; + + row = (model->numleafs+7)>>3; + out = decompressed; + + if (!in) + { // no vis info, so make all visible + while (row) + { + *out++ = 0xff; + row--; + } + return decompressed; + } + + do + { + if (*in) + { + *out++ = *in++; + continue; + } + + c = in[1]; + in += 2; + while (c) + { + *out++ = 0; + c--; + } + } while (out - decompressed < row); + + return decompressed; +} + +byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model) +{ + if (leaf == model->leafs) + return mod_novis; + return Mod_DecompressVis (leaf->compressed_vis, model); +} + +/* +=================== +Mod_ClearAll +=================== +*/ +void Mod_ClearAll (void) +{ + int i; + model_t *mod; + + + for (i=0 , mod=mod_known ; ineedload = NL_UNREFERENCED; +//FIX FOR CACHE_ALLOC ERRORS: + if (mod->type == mod_sprite) mod->cache.data = NULL; + } +} + +/* +================== +Mod_FindName + +================== +*/ +model_t *Mod_FindName (char *name) +{ + int i; + model_t *mod; + model_t *avail = NULL; + + if (!name[0]) + Sys_Error ("Mod_ForName: NULL name"); + +// +// search the currently loaded models +// + for (i=0 , mod=mod_known ; iname, name) ) + break; + if (mod->needload == NL_UNREFERENCED) + if (!avail || mod->type != mod_alias) + avail = mod; + } + + if (i == mod_numknown) + { + if (mod_numknown == MAX_MOD_KNOWN) + { + if (avail) + { + mod = avail; + if (mod->type == mod_alias) + if (Cache_Check (&mod->cache)) + Cache_Free (&mod->cache); + } + else + Sys_Error ("mod_numknown == MAX_MOD_KNOWN"); + } + else + mod_numknown++; + strcpy (mod->name, name); + mod->needload = NL_NEEDS_LOADED; + } + + return mod; +} + +/* +================== +Mod_TouchModel + +================== +*/ +void Mod_TouchModel (char *name) +{ + model_t *mod; + + mod = Mod_FindName (name); + + if (mod->needload == NL_PRESENT) + { + if (mod->type == mod_alias) + Cache_Check (&mod->cache); + } +} + +/* +================== +Mod_LoadModel + +Loads a model into the cache +================== +*/ +model_t *Mod_LoadModel (model_t *mod, qboolean crash) +{ + unsigned *buf; + byte stackbuf[1024]; // avoid dirtying the cache heap + + if (mod->type == mod_alias) + { + if (Cache_Check (&mod->cache)) + { + mod->needload = NL_PRESENT; + return mod; + } + } + else + { + if (mod->needload == NL_PRESENT) + return mod; + } + +// +// because the world is so huge, load it one piece at a time +// + +// +// load the file +// + buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf)); + if (!buf) + { + if (crash) + Sys_Error ("Mod_NumForName: %s not found", mod->name); + return NULL; + } + +// +// allocate a new model +// + COM_FileBase (mod->name, loadname); + + loadmodel = mod; + +// +// fill it in +// + +// call the apropriate loader + mod->needload = NL_PRESENT; + + switch (LittleLong(*(unsigned *)buf)) + { + case IDPOLYHEADER: + Mod_LoadAliasModel (mod, buf); + break; + + case IDSPRITEHEADER: + Mod_LoadSpriteModel (mod, buf); + break; + + default: + Mod_LoadBrushModel (mod, buf); + break; + } + + return mod; +} + +/* +================== +Mod_ForName + +Loads in a model for the given name +================== +*/ +model_t *Mod_ForName (char *name, qboolean crash) +{ + model_t *mod; + + mod = Mod_FindName (name); + + return Mod_LoadModel (mod, crash); +} + + +/* +=============================================================================== + + BRUSHMODEL LOADING + +=============================================================================== +*/ + +byte *mod_base; + + +/* +================= +Mod_LoadTextures +================= +*/ +void Mod_LoadTextures (lump_t *l) +{ + int i, j, pixels, num, max, altmax; + miptex_t *mt; + texture_t *tx, *tx2; + texture_t *anims[10]; + texture_t *altanims[10]; + dmiptexlump_t *m; + + if (!l->filelen) + { + loadmodel->textures = NULL; + return; + } + m = (dmiptexlump_t *)(mod_base + l->fileofs); + + m->nummiptex = LittleLong (m->nummiptex); + + loadmodel->numtextures = m->nummiptex; + loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname); + + for (i=0 ; inummiptex ; i++) + { + m->dataofs[i] = LittleLong(m->dataofs[i]); + if (m->dataofs[i] == -1) + continue; + mt = (miptex_t *)((byte *)m + m->dataofs[i]); + mt->width = LittleLong (mt->width); + mt->height = LittleLong (mt->height); + for (j=0 ; joffsets[j] = LittleLong (mt->offsets[j]); + + if ( (mt->width & 15) || (mt->height & 15) ) + Sys_Error ("Texture %s is not 16 aligned", mt->name); + pixels = mt->width*mt->height/64*85; + tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname ); + loadmodel->textures[i] = tx; + + memcpy (tx->name, mt->name, sizeof(tx->name)); + tx->width = mt->width; + tx->height = mt->height; + for (j=0 ; joffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); + // the pixels immediately follow the structures + memcpy ( tx+1, mt+1, pixels); + + if (!Q_strncmp(mt->name,"sky",3)) + R_InitSky (tx); + } + +// +// sequence the animations +// + for (i=0 ; inummiptex ; i++) + { + tx = loadmodel->textures[i]; + if (!tx || tx->name[0] != '+') + continue; + if (tx->anim_next) + continue; // allready sequenced + + // find the number of frames in the animation + memset (anims, 0, sizeof(anims)); + memset (altanims, 0, sizeof(altanims)); + + max = tx->name[1]; + altmax = 0; + if (max >= 'a' && max <= 'z') + max -= 'a' - 'A'; + if (max >= '0' && max <= '9') + { + max -= '0'; + altmax = 0; + anims[max] = tx; + max++; + } + else if (max >= 'A' && max <= 'J') + { + altmax = max - 'A'; + max = 0; + altanims[altmax] = tx; + altmax++; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + + for (j=i+1 ; jnummiptex ; j++) + { + tx2 = loadmodel->textures[j]; + if (!tx2 || tx2->name[0] != '+') + continue; + if (strcmp (tx2->name+2, tx->name+2)) + continue; + + num = tx2->name[1]; + if (num >= 'a' && num <= 'z') + num -= 'a' - 'A'; + if (num >= '0' && num <= '9') + { + num -= '0'; + anims[num] = tx2; + if (num+1 > max) + max = num + 1; + } + else if (num >= 'A' && num <= 'J') + { + num = num - 'A'; + altanims[num] = tx2; + if (num+1 > altmax) + altmax = num+1; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + } + +#define ANIM_CYCLE 2 + // link them all together + for (j=0 ; jname); + tx2->anim_total = max * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = anims[ (j+1)%max ]; + if (altmax) + tx2->alternate_anims = altanims[0]; + } + for (j=0 ; jname); + tx2->anim_total = altmax * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = altanims[ (j+1)%altmax ]; + if (max) + tx2->alternate_anims = anims[0]; + } + } +} + +/* +================= +Mod_LoadLighting +================= +*/ +void Mod_LoadLighting (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->lightdata = NULL; + return; + } + loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadVisibility +================= +*/ +void Mod_LoadVisibility (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->visdata = NULL; + return; + } + loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadEntities +================= +*/ +void Mod_LoadEntities (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->entities = NULL; + return; + } + loadmodel->entities = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadVertexes +================= +*/ +void Mod_LoadVertexes (lump_t *l) +{ + dvertex_t *in; + mvertex_t *out; + int i, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->vertexes = out; + loadmodel->numvertexes = count; + + for ( i=0 ; iposition[0] = LittleFloat (in->point[0]); + out->position[1] = LittleFloat (in->point[1]); + out->position[2] = LittleFloat (in->point[2]); + out->position[3] = LittleFloat (in->point[3]); + } +} + +/* +================= +Mod_LoadSubmodels +================= +*/ +void Mod_LoadSubmodels (lump_t *l) +{ + dmodel_t *in; + dmodel_t *out; + int i, j, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->submodels = out; + loadmodel->numsubmodels = count; + + for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; + out->maxs[j] = LittleFloat (in->maxs[j]) + 1; + out->origin[j] = LittleFloat (in->origin[j]); + } + for (j=0 ; jheadnode[j] = LittleLong (in->headnode[j]); + out->visleafs = LittleLong (in->visleafs); + out->firstface = LittleLong (in->firstface); + out->numfaces = LittleLong (in->numfaces); + } +} + +/* +================= +Mod_LoadEdges +================= +*/ +void Mod_LoadEdges (lump_t *l) +{ + dedge_t *in; + medge_t *out; + int i, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname); + + loadmodel->edges = out; + loadmodel->numedges = count; + + for ( i=0 ; iv[0] = (unsigned short)LittleShort(in->v[0]); + out->v[1] = (unsigned short)LittleShort(in->v[1]); + } +} + +/* +================= +Mod_LoadTexinfo +================= +*/ +void Mod_LoadTexinfo (lump_t *l) +{ + texinfo_t *in; + mtexinfo_t *out; + int i, j, count; + int miptex; + float len1, len2; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->texinfo = out; + loadmodel->numtexinfo = count; + + for ( i=0 ; ivecs[0][j] = LittleFloat (in->vecs[0][j]); + len1 = Length (out->vecs[0]); + len2 = Length (out->vecs[1]); + len1 = (len1 + len2)/2; + if (len1 < 0.32) + out->mipadjust = 4; + else if (len1 < 0.49) + out->mipadjust = 3; + else if (len1 < 0.99) + out->mipadjust = 2; + else + out->mipadjust = 1; +#if 0 + if (len1 + len2 < 0.001) + out->mipadjust = 1; // don't crash + else + out->mipadjust = 1 / floorf( (len1+len2)/2 + 0.1 ); +#endif + + miptex = LittleLong (in->miptex); + out->flags = LittleLong (in->flags); + + if (!loadmodel->textures) + { + out->texture = r_notexture_mip; // checkerboard texture + out->flags = 0; + } + else + { + if (miptex >= loadmodel->numtextures) + Sys_Error ("miptex >= loadmodel->numtextures"); + out->texture = loadmodel->textures[miptex]; + if (!out->texture) + { + out->texture = r_notexture_mip; // texture not found + out->flags = 0; + } + } + } +} + +/* +================ +CalcSurfaceExtents + +Fills in s->texturemins[] and s->extents[] +================ +*/ +void CalcSurfaceExtents (msurface_t *s) +{ + float mins[2], maxs[2], val; + int i,j, e; + mvertex_t *v; + mtexinfo_t *tex; + int bmins[2], bmaxs[2]; + + mins[0] = mins[1] = 999999; + maxs[0] = maxs[1] = -99999; + + tex = s->texinfo; + + for (i=0 ; inumedges ; i++) + { + e = loadmodel->surfedges[s->firstedge+i]; + if (e >= 0) + v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; + else + v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; + + for (j=0 ; j<2 ; j++) + { + val = v->position[0] * tex->vecs[j][0] + + v->position[1] * tex->vecs[j][1] + + v->position[2] * tex->vecs[j][2] + + tex->vecs[j][3]; + if (val < mins[j]) + mins[j] = val; + if (val > maxs[j]) + maxs[j] = val; + } + } + + for (i=0 ; i<2 ; i++) + { + bmins[i] = floorf(mins[i]/16); + bmaxs[i] = ceilf(maxs[i]/16); + + s->texturemins[i] = bmins[i] * 16; + s->extents[i] = (bmaxs[i] - bmins[i]) * 16; + if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 256) + Sys_Error ("Bad surface extents"); + } +} + + +/* +================= +Mod_LoadFaces +================= +*/ +void Mod_LoadFaces (lump_t *l) +{ + dface_t *in; + msurface_t *out; + int i, count, surfnum; + int planenum, side; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->surfaces = out; + loadmodel->numsurfaces = count; + + for ( surfnum=0 ; surfnumfirstedge = LittleLong(in->firstedge); + out->numedges = LittleShort(in->numedges); + out->flags = 0; + + planenum = LittleShort(in->planenum); + side = LittleShort(in->side); + if (side) + out->flags |= SURF_PLANEBACK; + + out->plane = loadmodel->planes + planenum; + + out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); + + CalcSurfaceExtents (out); + + // lighting info + + for (i=0 ; istyles[i] = in->styles[i]; + i = LittleLong(in->lightofs); + if (i == -1) + out->samples = NULL; + else + out->samples = loadmodel->lightdata + i; + + // set the drawing flags flag + + if (!Q_strncmp(out->texinfo->texture->name,"sky",3)) // sky + { + out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED); + continue; + } + + if (!Q_strncmp(out->texinfo->texture->name,"*",1)) // turbulent + { + out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED); + for (i=0 ; i<2 ; i++) + { + out->extents[i] = 16384; + out->texturemins[i] = -8192; + } + continue; + } + } +} + + +/* +================= +Mod_SetParent +================= +*/ +void Mod_SetParent (mnode_t *node, mnode_t *parent) +{ + node->parent = parent; + if (node->contents < 0) + return; + Mod_SetParent (node->children[0], node); + Mod_SetParent (node->children[1], node); +} + +/* +================= +Mod_LoadNodes +================= +*/ +void Mod_LoadNodes (lump_t *l) +{ + int i, j, count, p; + dnode_t *in; + mnode_t *out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->nodes = out; + loadmodel->numnodes = count; + + for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->planenum); + out->plane = loadmodel->planes + p; + + out->firstsurface = LittleShort (in->firstface); + out->numsurfaces = LittleShort (in->numfaces); + + for (j=0 ; j<2 ; j++) + { + p = LittleShort (in->children[j]); + if (p >= 0) + out->children[j] = loadmodel->nodes + p; + else + out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); + } + } + + Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs +} + +/* +================= +Mod_LoadLeafs +================= +*/ +void Mod_LoadLeafs (lump_t *l) +{ + dleaf_t *in; + mleaf_t *out; + int i, j, count, p; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->leafs = out; + loadmodel->numleafs = count; + + for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->contents); + out->contents = p; + + out->firstmarksurface = loadmodel->marksurfaces + + LittleShort(in->firstmarksurface); + out->nummarksurfaces = LittleShort(in->nummarksurfaces); + + p = LittleLong(in->visofs); + if (p == -1) + out->compressed_vis = NULL; + else + out->compressed_vis = loadmodel->visdata + p; + out->efrags = NULL; + + for (j=0 ; j<4 ; j++) + out->ambient_sound_level[j] = in->ambient_level[j]; + } +} + +/* +================= +Mod_LoadClipnodes +================= +*/ +void Mod_LoadClipnodes (lump_t *l) +{ + dclipnode_t *in, *out; + int i, count; + hull_t *hull; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->clipnodes = out; + loadmodel->numclipnodes = count; + + hull = &loadmodel->hulls[1]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -16; + hull->clip_mins[1] = -16; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 16; + hull->clip_maxs[1] = 16; + hull->clip_maxs[2] = 32; + + hull = &loadmodel->hulls[2]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -32; + hull->clip_mins[1] = -32; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 32; + hull->clip_maxs[1] = 32; + hull->clip_maxs[2] = 64; + + hull = &loadmodel->hulls[3]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -12; + hull->clip_mins[1] = -12; + hull->clip_mins[2] = -32; + hull->clip_maxs[0] = 12; + hull->clip_maxs[1] = 12; + hull->clip_maxs[2] = 12; + + for (i=0 ; iplanenum = LittleLong(in->planenum); + out->children[0] = LittleShort(in->children[0]); + out->children[1] = LittleShort(in->children[1]); + } +} + +/* +================= +Mod_MakeHull0 + +Deplicate the drawing hull structure as a clipping hull +================= +*/ +void Mod_MakeHull0 (void) +{ + mnode_t *in, *child; + dclipnode_t *out; + int i, j, count; + hull_t *hull; + + hull = &loadmodel->hulls[0]; + + in = loadmodel->nodes; + count = loadmodel->numnodes; + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + + for (i=0 ; iplanenum = in->plane - loadmodel->planes; + for (j=0 ; j<2 ; j++) + { + child = in->children[j]; + if (child->contents < 0) + out->children[j] = child->contents; + else + out->children[j] = child - loadmodel->nodes; + } + } +} + +/* +================= +Mod_LoadMarksurfaces +================= +*/ +void Mod_LoadMarksurfaces (lump_t *l) +{ + int i, j, count; + short *in; + msurface_t **out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->marksurfaces = out; + loadmodel->nummarksurfaces = count; + + for ( i=0 ; i= loadmodel->numsurfaces) + Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); + out[i] = loadmodel->surfaces + j; + } +} + +/* +================= +Mod_LoadSurfedges +================= +*/ +void Mod_LoadSurfedges (lump_t *l) +{ + int i, count; + int *in, *out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->surfedges = out; + loadmodel->numsurfedges = count; + + for ( i=0 ; ifileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*2*sizeof(*out), loadname); + + loadmodel->planes = out; + loadmodel->numplanes = count; + + for ( i=0 ; inormal[j] = LittleFloat (in->normal[j]); + if (out->normal[j] < 0) + bits |= 1<dist = LittleFloat (in->dist); + out->type = LittleLong (in->type); + out->signbits = bits; + } +} + +/* +================= +RadiusFromBounds +================= +*/ +float RadiusFromBounds (vec3_t mins, vec3_t maxs) +{ + int i; + vec3_t corner; + + for (i=0 ; i<3 ; i++) + { + corner[i] = fabsf(mins[i]) > fabsf(maxs[i]) ? fabsf(mins[i]) : fabsf(maxs[i]); + } + + return Length (corner); +} + +/* +================= +Mod_LoadBrushModel +================= +*/ +void Mod_LoadBrushModel (model_t *mod, void *buffer) +{ + int i, j; + dheader_t *header; + dmodel_t *bm; + + loadmodel->type = mod_brush; + + header = (dheader_t *)buffer; + + i = LittleLong (header->version); + if (i != BSPVERSION) + Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); + +// swap all the lumps + mod_base = (byte *)header; + + for (i=0 ; ilumps[LUMP_VERTEXES]); + Mod_LoadEdges (&header->lumps[LUMP_EDGES]); + Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); + Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); + Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); + Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); + Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); + Mod_LoadFaces (&header->lumps[LUMP_FACES]); + Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); + Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); + Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); + Mod_LoadNodes (&header->lumps[LUMP_NODES]); + Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); + Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); + Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); + + Mod_MakeHull0 (); + + mod->numframes = 2; // regular and alternate animation + mod->flags = 0; + +// +// set up the submodels (FIXME: this is confusing) +// + for (i=0 ; inumsubmodels ; i++) + { + bm = &mod->submodels[i]; + + mod->hulls[0].firstclipnode = bm->headnode[0]; + for (j=1 ; jhulls[j].firstclipnode = bm->headnode[j]; + mod->hulls[j].lastclipnode = mod->numclipnodes-1; + } + + mod->firstmodelsurface = bm->firstface; + mod->nummodelsurfaces = bm->numfaces; + + VectorCopy (bm->maxs, mod->maxs); + VectorCopy (bm->mins, mod->mins); + mod->radius = RadiusFromBounds (mod->mins, mod->maxs); + + mod->numleafs = bm->visleafs; + + if (i < mod->numsubmodels-1) + { // duplicate the basic information + char name[10]; + + sprintf (name, "*%i", i+1); + loadmodel = Mod_FindName (name); + *loadmodel = *mod; + strcpy (loadmodel->name, name); + mod = loadmodel; + } + } +} + +/* +============================================================================== + +ALIAS MODELS + +============================================================================== +*/ + +/* +================= +Mod_LoadAliasFrame +================= +*/ +void * Mod_LoadAliasFrame (void * pin, int *pframeindex, int numv, + trivertx_t *pbboxmin, trivertx_t *pbboxmax, aliashdr_t *pheader, char *name) +{ + trivertx_t *pframe, *pinframe; + int i, j; + daliasframe_t *pdaliasframe; + + pdaliasframe = (daliasframe_t *)pin; + + strcpy (name, pdaliasframe->name); + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about + // endianness + pbboxmin->v[i] = pdaliasframe->bboxmin.v[i]; + pbboxmax->v[i] = pdaliasframe->bboxmax.v[i]; + } + + pinframe = (trivertx_t *)(pdaliasframe + 1); + pframe = Hunk_AllocName (numv * sizeof(*pframe), loadname); + + *pframeindex = (byte *)pframe - (byte *)pheader; + + for (j=0 ; jnumframes); + + paliasgroup = Hunk_AllocName (sizeof (maliasgroup_t) + + (numframes - 1) * sizeof (paliasgroup->frames[0]), loadname); + + paliasgroup->numframes = numframes; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about endianness + pbboxmin->v[i] = pingroup->bboxmin.v[i]; + pbboxmax->v[i] = pingroup->bboxmax.v[i]; + } + + *pframeindex = (byte *)paliasgroup - (byte *)pheader; + + pin_intervals = (daliasinterval_t *)(pingroup + 1); + + poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); + + paliasgroup->intervals = (byte *)poutintervals - (byte *)pheader; + + for (i=0 ; iinterval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadAliasGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; iframes[i].frame, + numv, + &paliasgroup->frames[i].bboxmin, + &paliasgroup->frames[i].bboxmax, + pheader, name); + } + + return ptemp; +} + + +/* +================= +Mod_LoadAliasSkin +================= +*/ +void * Mod_LoadAliasSkin (void * pin, int *pskinindex, int skinsize, + aliashdr_t *pheader) +{ + int i; + byte *pskin, *pinskin; + unsigned short *pusskin; + + pskin = Hunk_AllocName (skinsize * r_pixbytes, loadname); + pinskin = (byte *)pin; + *pskinindex = (byte *)pskin - (byte *)pheader; + + if (r_pixbytes == 1) + { + Q_memcpy (pskin, pinskin, skinsize); + } + else if (r_pixbytes == 2) + { + pusskin = (unsigned short *)pskin; + + for (i=0 ; inumskins); + + paliasskingroup = Hunk_AllocName (sizeof (maliasskingroup_t) + + (numskins - 1) * sizeof (paliasskingroup->skindescs[0]), + loadname); + + paliasskingroup->numskins = numskins; + + *pskinindex = (byte *)paliasskingroup - (byte *)pheader; + + pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); + + poutskinintervals = Hunk_AllocName (numskins * sizeof (float),loadname); + + paliasskingroup->intervals = (byte *)poutskinintervals - (byte *)pheader; + + for (i=0 ; iinterval); + if (*poutskinintervals <= 0) + Sys_Error ("Mod_LoadAliasSkinGroup: interval<=0"); + + poutskinintervals++; + pinskinintervals++; + } + + ptemp = (void *)pinskinintervals; + + for (i=0 ; iskindescs[i].skin, skinsize, pheader); + } + + return ptemp; +} + + +/* +================= +Mod_LoadAliasModel +================= +*/ +void Mod_LoadAliasModel (model_t *mod, void *buffer) +{ + int i; + mdl_t *pmodel, *pinmodel; + stvert_t *pstverts, *pinstverts; + aliashdr_t *pheader; + mtriangle_t *ptri; + dtriangle_t *pintriangles; + int version, numframes, numskins; + int size; + daliasframetype_t *pframetype; + daliasskintype_t *pskintype; + maliasskindesc_t *pskindesc; + int skinsize; + int start, end, total; + + start = Hunk_LowMark (); + + pinmodel = (mdl_t *)buffer; + + version = LittleLong (pinmodel->version); + if (version != ALIAS_VERSION) + Sys_Error ("%s has wrong version number (%i should be %i)", + mod->name, version, ALIAS_VERSION); + +// +// allocate space for a working header, plus all the data except the frames, +// skin and group info +// + size = sizeof (aliashdr_t) + (LittleLong (pinmodel->numframes) - 1) * + sizeof (pheader->frames[0]) + + sizeof (mdl_t) + + LittleLong (pinmodel->numverts) * sizeof (stvert_t) + + LittleLong (pinmodel->numtris) * sizeof (mtriangle_t); + + pheader = Hunk_AllocName (size, loadname); + pmodel = (mdl_t *) ((byte *)&pheader[1] + + (LittleLong (pinmodel->numframes) - 1) * + sizeof (pheader->frames[0])); + +// mod->cache.data = pheader; + mod->flags = LittleLong (pinmodel->flags); + +// +// endian-adjust and copy the data, starting with the alias model header +// + pmodel->boundingradius = LittleFloat (pinmodel->boundingradius); + pmodel->numskins = LittleLong (pinmodel->numskins); + pmodel->skinwidth = LittleLong (pinmodel->skinwidth); + pmodel->skinheight = LittleLong (pinmodel->skinheight); + + if (pmodel->skinheight > MAX_LBM_HEIGHT) + Sys_Error ("model %s has a skin taller than %d", mod->name, + MAX_LBM_HEIGHT); + + pmodel->numverts = LittleLong (pinmodel->numverts); + + if (pmodel->numverts <= 0) + Sys_Error ("model %s has no vertices", mod->name); + + if (pmodel->numverts > MAXALIASVERTS) + Sys_Error ("model %s has too many vertices", mod->name); + + pmodel->numtris = LittleLong (pinmodel->numtris); + + if (pmodel->numtris <= 0) + Sys_Error ("model %s has no triangles", mod->name); + + pmodel->numframes = LittleLong (pinmodel->numframes); + pmodel->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; + mod->synctype = LittleLong (pinmodel->synctype); + mod->numframes = pmodel->numframes; + + for (i=0 ; i<3 ; i++) + { + pmodel->scale[i] = LittleFloat (pinmodel->scale[i]); + pmodel->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); + pmodel->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); + } + + numskins = pmodel->numskins; + numframes = pmodel->numframes; + + if (pmodel->skinwidth & 0x03) + Sys_Error ("Mod_LoadAliasModel: skinwidth not multiple of 4"); + + pheader->model = (byte *)pmodel - (byte *)pheader; + +// +// load the skins +// + skinsize = pmodel->skinheight * pmodel->skinwidth; + + if (numskins < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); + + pskintype = (daliasskintype_t *)&pinmodel[1]; + + pskindesc = Hunk_AllocName (numskins * sizeof (maliasskindesc_t), + loadname); + + pheader->skindesc = (byte *)pskindesc - (byte *)pheader; + + for (i=0 ; itype); + pskindesc[i].type = skintype; + + if (skintype == ALIAS_SKIN_SINGLE) + { + pskintype = (daliasskintype_t *) + Mod_LoadAliasSkin (pskintype + 1, + &pskindesc[i].skin, + skinsize, pheader); + } + else + { + pskintype = (daliasskintype_t *) + Mod_LoadAliasSkinGroup (pskintype + 1, + &pskindesc[i].skin, + skinsize, pheader); + } + } + +// +// set base s and t vertices +// + pstverts = (stvert_t *)&pmodel[1]; + pinstverts = (stvert_t *)pskintype; + + pheader->stverts = (byte *)pstverts - (byte *)pheader; + + for (i=0 ; inumverts ; i++) + { + pstverts[i].onseam = LittleLong (pinstverts[i].onseam); + // put s and t in 16.16 format + pstverts[i].s = LittleLong (pinstverts[i].s) << 16; + pstverts[i].t = LittleLong (pinstverts[i].t) << 16; + } + +// +// set up the triangles +// + ptri = (mtriangle_t *)&pstverts[pmodel->numverts]; + pintriangles = (dtriangle_t *)&pinstverts[pmodel->numverts]; + + pheader->triangles = (byte *)ptri - (byte *)pheader; + + for (i=0 ; inumtris ; i++) + { + int j; + + ptri[i].facesfront = LittleLong (pintriangles[i].facesfront); + + for (j=0 ; j<3 ; j++) + { + ptri[i].vertindex[j] = + LittleLong (pintriangles[i].vertindex[j]); + } + } + +// +// load the frames +// + if (numframes < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); + + pframetype = (daliasframetype_t *)&pintriangles[pmodel->numtris]; + + for (i=0 ; itype); + pheader->frames[i].type = frametype; + + if (frametype == ALIAS_SINGLE) + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasFrame (pframetype + 1, + &pheader->frames[i].frame, + pmodel->numverts, + &pheader->frames[i].bboxmin, + &pheader->frames[i].bboxmax, + pheader, pheader->frames[i].name); + } + else + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasGroup (pframetype + 1, + &pheader->frames[i].frame, + pmodel->numverts, + &pheader->frames[i].bboxmin, + &pheader->frames[i].bboxmax, + pheader, pheader->frames[i].name); + } + } + + mod->type = mod_alias; + +// FIXME: do this right + mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; + mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; + +// +// move the complete, relocatable alias model to the cache +// + end = Hunk_LowMark (); + total = end - start; + + Cache_Alloc (&mod->cache, total, loadname); + if (!mod->cache.data) + return; + memcpy (mod->cache.data, pheader, total); + + Hunk_FreeToLowMark (start); +} + +//============================================================================= + +/* +================= +Mod_LoadSpriteFrame +================= +*/ +void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe) +{ + dspriteframe_t *pinframe; + mspriteframe_t *pspriteframe; + int i, width, height, size, origin[2]; + unsigned short *ppixout; + byte *ppixin; + + pinframe = (dspriteframe_t *)pin; + + width = LittleLong (pinframe->width); + height = LittleLong (pinframe->height); + size = width * height; + + pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t) + size*r_pixbytes, + loadname); + + Q_memset (pspriteframe, 0, sizeof (mspriteframe_t) + size); + *ppframe = pspriteframe; + + pspriteframe->width = width; + pspriteframe->height = height; + origin[0] = LittleLong (pinframe->origin[0]); + origin[1] = LittleLong (pinframe->origin[1]); + + pspriteframe->up = origin[1]; + pspriteframe->down = origin[1] - height; + pspriteframe->left = origin[0]; + pspriteframe->right = width + origin[0]; + + if (r_pixbytes == 1) + { + Q_memcpy (&pspriteframe->pixels[0], (byte *)(pinframe + 1), size); + } + else if (r_pixbytes == 2) + { + ppixin = (byte *)(pinframe + 1); + ppixout = (unsigned short *)&pspriteframe->pixels[0]; + + for (i=0 ; inumframes); + + pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) + + (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); + + pspritegroup->numframes = numframes; + + *ppframe = (mspriteframe_t *)pspritegroup; + + pin_intervals = (dspriteinterval_t *)(pingroup + 1); + + poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); + + pspritegroup->intervals = poutintervals; + + for (i=0 ; iinterval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; iframes[i]); + } + + return ptemp; +} + + +/* +================= +Mod_LoadSpriteModel +================= +*/ +void Mod_LoadSpriteModel (model_t *mod, void *buffer) +{ + int i; + int version; + dsprite_t *pin; + msprite_t *psprite; + int numframes; + int size; + dspriteframetype_t *pframetype; + + pin = (dsprite_t *)buffer; + + version = LittleLong (pin->version); + if (version != SPRITE_VERSION) + Sys_Error ("%s has wrong version number " + "(%i should be %i)", mod->name, version, SPRITE_VERSION); + + numframes = LittleLong (pin->numframes); + + size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); + + psprite = Hunk_AllocName (size, loadname); + + mod->cache.data = psprite; + + psprite->type = LittleLong (pin->type); + psprite->maxwidth = LittleLong (pin->width); + psprite->maxheight = LittleLong (pin->height); + psprite->beamlength = LittleFloat (pin->beamlength); + mod->synctype = LittleLong (pin->synctype); + psprite->numframes = numframes; + + mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; + mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; + mod->mins[2] = -psprite->maxheight/2; + mod->maxs[2] = psprite->maxheight/2; + +// +// load the frames +// + if (numframes < 1) + Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); + + mod->numframes = numframes; + mod->flags = 0; + + pframetype = (dspriteframetype_t *)(pin + 1); + + for (i=0 ; itype); + psprite->frames[i].type = frametype; + + if (frametype == SPR_SINGLE) + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteFrame (pframetype + 1, + &psprite->frames[i].frameptr); + } + else + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteGroup (pframetype + 1, + &psprite->frames[i].frameptr); + } + } + + mod->type = mod_sprite; +} + +//============================================================================= + +/* +================ +Mod_Print +================ +*/ +void Mod_Print (void) +{ + int i; + model_t *mod; + + Con_Printf ("Cached models:\n"); + for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++) + { + Con_Printf ("%8p : %s",mod->cache.data, mod->name); + if (mod->needload & NL_UNREFERENCED) + Con_Printf (" (!R)"); + if (mod->needload & NL_NEEDS_LOADED) + Con_Printf (" (!P)"); + Con_Printf ("\n"); + } +} + + diff --git a/r17/Revamped src/revamped_src/model.h b/r17/Revamped src/revamped_src/model.h new file mode 100755 index 00000000..312a1f1b --- /dev/null +++ b/r17/Revamped src/revamped_src/model.h @@ -0,0 +1,382 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +#ifndef __MODEL__ +#define __MODEL__ + +#include "modelgen.h" +#include "spritegn.h" + +/* + +d*_t structures are on-disk representations +m*_t structures are in-memory + +*/ + +/* +============================================================================== + +BRUSH MODELS + +============================================================================== +*/ + + +// +// in memory representation +// +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + vec3_t position; +} mvertex_t; + +#define SIDE_FRONT 0 +#define SIDE_BACK 1 +#define SIDE_ON 2 + + +// plane_t structure +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct mplane_s +{ + vec3_t normal; + float dist; + byte type; // for texture axis selection and fast side tests + byte signbits; // signx + signy<<1 + signz<<1 + byte pad[2]; +} mplane_t; + +typedef struct texture_s +{ + char name[16]; + unsigned width, height; + int anim_total; // total tenths in sequence ( 0 = no) + int anim_min, anim_max; // time for this frame min <=time< max + struct texture_s *anim_next; // in the animation sequence + struct texture_s *alternate_anims; // bmodels in frmae 1 use these + unsigned offsets[MIPLEVELS]; // four mip maps stored +} texture_t; + + +#define SURF_PLANEBACK 2 +#define SURF_DRAWSKY 4 +#define SURF_DRAWSPRITE 8 +#define SURF_DRAWTURB 0x10 +#define SURF_DRAWTILED 0x20 +#define SURF_DRAWBACKGROUND 0x40 + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + unsigned short v[2]; + unsigned int cachededgeoffset; +} medge_t; + +typedef struct +{ + float vecs[2][4]; + float mipadjust; + texture_t *texture; + int flags; +} mtexinfo_t; + +typedef struct msurface_s +{ + int visframe; // should be drawn when node is crossed + + int dlightframe; + int dlightbits; + + mplane_t *plane; + int flags; + + int firstedge; // look up in model->surfedges[], negative numbers + int numedges; // are backwards edges + +// surface generation data + struct surfcache_s *cachespots[MIPLEVELS]; + + short texturemins[2]; + short extents[2]; + + mtexinfo_t *texinfo; + +// lighting info + byte styles[MAXLIGHTMAPS]; + byte *samples; // [numstyles*surfsize] +} msurface_t; + +typedef struct mnode_s +{ +// common with leaf + int contents; // 0, to differentiate from leafs + int visframe; // node needs to be traversed if current + + short minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// node specific + mplane_t *plane; + struct mnode_s *children[2]; + + unsigned short firstsurface; + unsigned short numsurfaces; +} mnode_t; + + + +typedef struct mleaf_s +{ +// common with node + int contents; // wil be a negative contents number + int visframe; // node needs to be traversed if current + + short minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// leaf specific + byte *compressed_vis; + efrag_t *efrags; + + msurface_t **firstmarksurface; + int nummarksurfaces; + int key; // BSP sequence number for leaf's contents + byte ambient_sound_level[NUM_AMBIENTS]; +} mleaf_t; + +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct +{ + dclipnode_t *clipnodes; + mplane_t *planes; + int firstclipnode; + int lastclipnode; + vec3_t clip_mins; + vec3_t clip_maxs; +} hull_t; + +/* +============================================================================== + +SPRITE MODELS + +============================================================================== +*/ + + +// FIXME: shorten these? +typedef struct mspriteframe_s +{ + int width; + int height; + void *pcachespot; // remove? + float up, down, left, right; + byte pixels[4]; +} mspriteframe_t; + +typedef struct +{ + int numframes; + float *intervals; + mspriteframe_t *frames[1]; +} mspritegroup_t; + +typedef struct +{ + spriteframetype_t type; + mspriteframe_t *frameptr; +} mspriteframedesc_t; + +typedef struct +{ + int type; + int maxwidth; + int maxheight; + int numframes; + float beamlength; // remove? + void *cachespot; // remove? + mspriteframedesc_t frames[1]; +} msprite_t; + + +/* +============================================================================== + +ALIAS MODELS + +Alias models are position independent, so the cache manager can move them. +============================================================================== +*/ + +typedef struct +{ + aliasframetype_t type; + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; + char name[16]; +} maliasframedesc_t; + +typedef struct +{ + aliasskintype_t type; + void *pcachespot; + int skin; +} maliasskindesc_t; + +typedef struct +{ + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; +} maliasgroupframedesc_t; + +typedef struct +{ + int numframes; + int intervals; + maliasgroupframedesc_t frames[1]; +} maliasgroup_t; + +typedef struct +{ + int numskins; + int intervals; + maliasskindesc_t skindescs[1]; +} maliasskingroup_t; + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct mtriangle_s { + int facesfront; + int vertindex[3]; +} mtriangle_t; + +typedef struct { + int model; + int stverts; + int skindesc; + int triangles; + maliasframedesc_t frames[1]; +} aliashdr_t; + +//=================================================================== + +// +// Whole model +// + +typedef enum {mod_brush, mod_sprite, mod_alias} modtype_t; + +#define EF_ROCKET 1 // leave a trail +#define EF_GRENADE 2 // leave a trail +#define EF_GIB 4 // leave a trail +#define EF_ROTATE 8 // rotate (bonus items) +#define EF_TRACER 16 // green split trail +#define EF_ZOMGIB 32 // small blood trail +#define EF_TRACER2 64 // orange split trail + rotate +#define EF_TRACER3 128 // purple trail + +typedef struct model_s +{ + char name[MAX_QPATH]; + qboolean needload; // bmodels and sprites don't cache normally + + modtype_t type; + int numframes; + synctype_t synctype; + + int flags; + +// +// volume occupied by the model +// + vec3_t mins, maxs; + float radius; + +// +// brush model +// + int firstmodelsurface, nummodelsurfaces; + + int numsubmodels; + dmodel_t *submodels; + + int numplanes; + mplane_t *planes; + + int numleafs; // number of visible leafs, not counting 0 + mleaf_t *leafs; + + int numvertexes; + mvertex_t *vertexes; + + int numedges; + medge_t *edges; + + int numnodes; + mnode_t *nodes; + + int numtexinfo; + mtexinfo_t *texinfo; + + int numsurfaces; + msurface_t *surfaces; + + int numsurfedges; + int *surfedges; + + int numclipnodes; + dclipnode_t *clipnodes; + + int nummarksurfaces; + msurface_t **marksurfaces; + + hull_t hulls[MAX_MAP_HULLS]; + + int numtextures; + texture_t **textures; + + byte *visdata; + byte *lightdata; + char *entities; + +// +// additional model data +// + cache_user_t cache; // only access through Mod_Extradata + +} model_t; + +//============================================================================ + +void Mod_Init (void); +void Mod_ClearAll (void); +model_t *Mod_ForName (char *name, qboolean crash); +void *Mod_Extradata (model_t *mod); // handles caching +void Mod_TouchModel (char *name); + +mleaf_t *Mod_PointInLeaf (float *p, model_t *model); +byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model); + +#endif // __MODEL__ diff --git a/r17/Revamped src/revamped_src/modelgen.h b/r17/Revamped src/revamped_src/modelgen.h new file mode 100755 index 00000000..76cb956f --- /dev/null +++ b/r17/Revamped src/revamped_src/modelgen.h @@ -0,0 +1,134 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// +// modelgen.h: header file for model generation program +// + +// ********************************************************* +// * This file must be identical in the modelgen directory * +// * and in the Quake directory, because it's used to * +// * pass data from one to the other via model files. * +// ********************************************************* + +#ifdef INCLUDELIBS + +#include +#include +#include +#include + +#include "cmdlib.h" +#include "scriplib.h" +#include "trilib.h" +#include "lbmlib.h" +#include "mathlib.h" + +#endif + +#define ALIAS_VERSION 6 + +#define ALIAS_ONSEAM 0x0020 + +// must match definition in spritegn.h +#ifndef SYNCTYPE_T +#define SYNCTYPE_T +typedef enum {ST_SYNC=0, ST_RAND } synctype_t; +#endif + +typedef enum { ALIAS_SINGLE=0, ALIAS_GROUP } aliasframetype_t; + +typedef enum { ALIAS_SKIN_SINGLE=0, ALIAS_SKIN_GROUP } aliasskintype_t; + +typedef struct { + int ident; + int version; + vec3_t scale; + vec3_t scale_origin; + float boundingradius; + vec3_t eyeposition; + int numskins; + int skinwidth; + int skinheight; + int numverts; + int numtris; + int numframes; + synctype_t synctype; + int flags; + float size; +} mdl_t; + +// TODO: could be shorts + +typedef struct { + int onseam; + int s; + int t; +} stvert_t; + +typedef struct dtriangle_s { + int facesfront; + int vertindex[3]; +} dtriangle_t; + +#define DT_FACES_FRONT 0x0010 + +// This mirrors trivert_t in trilib.h, is present so Quake knows how to +// load this data + +typedef struct { + byte v[3]; + byte lightnormalindex; +} trivertx_t; + +typedef struct { + trivertx_t bboxmin; // lightnormal isn't used + trivertx_t bboxmax; // lightnormal isn't used + char name[16]; // frame name from grabbing +} daliasframe_t; + +typedef struct { + int numframes; + trivertx_t bboxmin; // lightnormal isn't used + trivertx_t bboxmax; // lightnormal isn't used +} daliasgroup_t; + +typedef struct { + int numskins; +} daliasskingroup_t; + +typedef struct { + float interval; +} daliasinterval_t; + +typedef struct { + float interval; +} daliasskininterval_t; + +typedef struct { + aliasframetype_t type; +} daliasframetype_t; + +typedef struct { + aliasskintype_t type; +} daliasskintype_t; + +#define IDPOLYHEADER (('O'<<24)+('P'<<16)+('D'<<8)+'I') + // little-endian "IDPO" + diff --git a/r17/Revamped src/revamped_src/mp3.c b/r17/Revamped src/revamped_src/mp3.c new file mode 100755 index 00000000..1300c31e --- /dev/null +++ b/r17/Revamped src/revamped_src/mp3.c @@ -0,0 +1,389 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic PRX template + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1888 2006-05-01 08:47:04Z tyranid $ + * $HeadURL$ + */ +#include +#include +#include +#include +#include +#include +#include "m33libs/kubridge.h" + +int mp3_last_error = 0; + +static int initialized = 0; +static SceUID thread_job_sem = -1; +static SceUID thread_busy_sem = -1; +static int thread_exit = 0; + +int done = 0; + +int mp3_job_started = 0; + +int mp3_volume; + +int first_run = 0; + +// MPEG-1, layer 3 +static int bitrates[] = { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 }; +//static int samplerates[] = { 44100, 48000, 32000, 0 }; + +#define MIN_INFRAME_SIZE 96 +#define IN_BUFFER_SIZE (2*1024) + +static unsigned long mp3_codec_struct[65] __attribute__((aligned(64))); + +static unsigned char mp3_src_buffer[2][IN_BUFFER_SIZE] __attribute__((aligned(64))); +static short mp3_mix_buffer[2][1152*2] __attribute__((aligned(64))); +static int working_buf = 0; + +static const char *mp3_fname = NULL; +static SceUID mp3_handle = -1; +static int mp3_src_pos = 0, mp3_src_size = 0; + +static int decode_thread(SceSize args, void *argp); + + +static void psp_sem_lock(SceUID sem) +{ + int ret = sceKernelWaitSema(sem, 1, 0); + if (ret < 0) printf("sceKernelWaitSema(%08x) failed with %08x\n", sem, ret); +} + +static void psp_sem_unlock(SceUID sem) +{ + int ret = sceKernelSignalSema(sem, 1); + if (ret < 0) printf("sceKernelSignalSema(%08x) failed with %08x\n", sem, ret); +} + +// only accepts MPEG-1, layer3 +static int find_sync_word(unsigned char *data, int len) +{ + int i; + for (i = 0; i < len-1; i++) + { + if ( data[i+0] != 0xff) continue; + if ((data[i+1] & 0xfe) == 0xfa) return i; + i++; + } + return -1; +} + +static int read_next_frame(int which_buffer) +{ + int i, bytes_read, frame_offset; + int bitrate, padding, frame_size = 0; + + for (i = 0; i < 32; i++) + { + bytes_read = sceIoRead(mp3_handle, mp3_src_buffer[which_buffer], sizeof(mp3_src_buffer[which_buffer])); + mp3_src_pos += bytes_read; + if (bytes_read < MIN_INFRAME_SIZE) { + mp3_src_pos = mp3_src_size; + return 0; // EOF/IO failure + } + frame_offset = find_sync_word(mp3_src_buffer[which_buffer], bytes_read); + if (frame_offset < 0) { + printf("missing syncword, foffs=%i\n", mp3_src_pos - bytes_read); + mp3_src_pos--; + sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET); + continue; + } + if (bytes_read - frame_offset < 4) { + printf("syncword @ EOB, foffs=%i\n", mp3_src_pos - bytes_read); + mp3_src_pos--; + sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET); + continue; + } + + bitrate = mp3_src_buffer[which_buffer][frame_offset+2] >> 4; + padding = (mp3_src_buffer[which_buffer][frame_offset+2] & 2) >> 1; + + frame_size = 144000*bitrates[bitrate]/44100 + padding; + if (frame_size <= 0) { + printf("bad frame, foffs=%i\n", mp3_src_pos - bytes_read); + continue; // bad frame + } + + if (bytes_read - frame_offset < frame_size) + { + printf("unfit, foffs=%i\n", mp3_src_pos - bytes_read); + mp3_src_pos -= bytes_read - frame_offset; + if (mp3_src_size - mp3_src_pos < frame_size) { + mp3_src_pos = mp3_src_size; + return 0; // EOF + } + sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET); + continue; // didn't fit, re-read.. + } + + if (frame_offset) { + //printf("unaligned, foffs=%i, offs=%i\n", mp3_src_pos - bytes_read, frame_offset); + memmove(mp3_src_buffer[which_buffer], mp3_src_buffer[which_buffer] + frame_offset, frame_size); + } + + // align for next frame read + mp3_src_pos -= bytes_read - (frame_offset + frame_size); + sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET); + + break; + } + + return frame_size > 0 ? frame_size : -1; +} + + +static SceUID load_start_module(const char *prxname) +{ + SceUID mod, mod1; + int status, ret; + + mod = pspSdkLoadStartModule(prxname, PSP_MEMORY_PARTITION_KERNEL); + if (mod < 0) { + printf("failed to load %s (%08x), trying kuKernelLoadModule\n", prxname, mod); + mod1 = kuKernelLoadModule(prxname, 0, NULL); + if (mod1 < 0) printf("kuKernelLoadModule failed with %08x\n", mod1); + else { + ret = sceKernelStartModule(mod1, 0, NULL, &status, 0); + if (ret < 0) printf("sceKernelStartModule failed with %08x\n", ret); + else mod = mod1; + } + } + return mod; +} + + +int mp3_init(void) +{ + SceUID thid, mod; + int ret; + + /* load modules */ + /* <= 1.5 (and probably some other, not sure which) fw need this to for audiocodec to work, + * so if it fails, assume we are just on new enough firmware and continue.. */ + load_start_module("flash0:/kd/me_for_vsh.prx"); + + if (sceKernelDevkitVersion() < 0x02070010) + mod = load_start_module("flash0:/kd/audiocodec.prx"); + else mod = load_start_module("flash0:/kd/avcodec.prx"); + if (mod < 0) { + ret = mod = load_start_module("flash0:/kd/audiocodec_260.prx"); // last chance.. + if (mod < 0) goto fail; + } + + /* audiocodec init */ + memset(mp3_codec_struct, 0, sizeof(mp3_codec_struct)); + ret = sceAudiocodecCheckNeedMem(mp3_codec_struct, 0x1002); + if (ret < 0) { + printf("sceAudiocodecCheckNeedMem failed with %08x\n", ret); + goto fail; + } + + ret = sceAudiocodecGetEDRAM(mp3_codec_struct, 0x1002); + if (ret < 0) { + printf("sceAudiocodecGetEDRAM failed with %08x\n", ret); + goto fail; + } + + ret = sceAudiocodecInit(mp3_codec_struct, 0x1002); + if (ret < 0) { + printf("sceAudiocodecInit failed with %08x\n", ret); + goto fail1; + } + + /* thread and stuff */ + thread_job_sem = sceKernelCreateSema("p_mp3job_sem", 0, 0, 1, NULL); + if (thread_job_sem < 0) { + printf("sceKernelCreateSema() failed: %08x\n", thread_job_sem); + ret = thread_job_sem; + goto fail1; + } + + thread_busy_sem = sceKernelCreateSema("p_mp3busy_sem", 0, 1, 1, NULL); + if (thread_busy_sem < 0) { + printf("sceKernelCreateSema() failed: %08x\n", thread_busy_sem); + ret = thread_busy_sem; + goto fail2; + } + + thread_exit = 0; + thid = sceKernelCreateThread("mp3decode_thread", decode_thread, 30, 0x2000, 0, 0); /* use slightly higher prio then main */ + if (thid < 0) { + printf("failed to create decode thread: %08x\n", thid); + ret = thid; + goto fail3; + } + ret = sceKernelStartThread(thid, 0, 0); + if (ret < 0) { + printf("failed to start decode thread: %08x\n", ret); + goto fail3; + } + + mp3_last_error = 0; + initialized = 1; + return 0; + +fail3: + sceKernelDeleteSema(thread_busy_sem); + thread_busy_sem = -1; +fail2: + sceKernelDeleteSema(thread_job_sem); + thread_job_sem = -1; +fail1: + sceAudiocodecReleaseEDRAM(mp3_codec_struct); +fail: + mp3_last_error = ret; + initialized = 0; + return 1; +} + +void mp3_deinit(void) +{ + printf("mp3_deinit, initialized=%i\n", initialized); + + if (!initialized) return; + thread_exit = 1; + psp_sem_lock(thread_busy_sem); + psp_sem_unlock(thread_busy_sem); + + sceKernelSignalSema(thread_job_sem, 1); + sceKernelDelayThread(100*1000); + + if (mp3_handle >= 0) sceIoClose(mp3_handle); + mp3_handle = -1; + mp3_fname = NULL; + + psp_sem_lock(thread_job_sem); + psp_sem_unlock(thread_job_sem); + + sceKernelDeleteSema(thread_busy_sem); + thread_busy_sem = -1; + sceKernelDeleteSema(thread_job_sem); + thread_job_sem = -1; + sceAudiocodecReleaseEDRAM(mp3_codec_struct); + initialized = 0; + +} + + +short mp3_output_buffer[4][1152 * 2] __attribute__((aligned(64))); +int mp3_output_index = 0; + +// may overflow stack? +static int decode_thread(SceSize args, void *argp) +{ + int ret, frame_size; + + int audio_channel = sceAudioChReserve(1, 1152, PSP_AUDIO_FORMAT_STEREO); + + printf("decode_thread started with id %08x, priority %i\n", + sceKernelGetThreadId(), sceKernelGetThreadCurrentPriority()); + + while (!thread_exit) + { + psp_sem_lock(thread_job_sem); + + if (thread_exit) { + psp_sem_unlock(thread_job_sem); + break; + } + + psp_sem_lock(thread_busy_sem); + + frame_size = read_next_frame(working_buf); + + while (mp3_job_started) + { + + if (thread_exit) break; + + if(frame_size > 0) + { + mp3_codec_struct[6] = (unsigned long)mp3_src_buffer[working_buf]; + mp3_codec_struct[8] = (unsigned long)mp3_mix_buffer[working_buf]; + mp3_codec_struct[7] = mp3_codec_struct[10] = frame_size; + mp3_codec_struct[9] = 1152 * 4; + + ret = sceAudiocodecDecode(mp3_codec_struct, 0x1002); + if (ret < 0) printf("sceAudiocodecDecode failed with %08x\n", ret); + + memcpy(mp3_output_buffer[mp3_output_index], mp3_mix_buffer[working_buf], 1152*4); + sceAudioOutputBlocking(audio_channel, mp3_volume, mp3_output_buffer[mp3_output_index]); + mp3_output_index = (mp3_output_index+1)%4; + + memset(mp3_mix_buffer, 0, 1152*2*2); + + frame_size = read_next_frame(working_buf); + } + + + } + + if (!mp3_job_started) { + + if (mp3_handle >= 0) sceIoClose(mp3_handle); + mp3_handle = -1; + mp3_fname = NULL; + } + + psp_sem_unlock(thread_busy_sem); + + + } + + printf("leaving decode thread\n"); + sceKernelExitDeleteThread(0); + return 0; +} + +static int mp3_samples_ready = 0, mp3_buffer_offs = 0, mp3_play_bufsel = 0; + +int mp3_start_play(char *fname, int pos) +{ + + printf("mp3_start_play(%s) @ %i\n", fname, pos); + psp_sem_lock(thread_busy_sem); + + if (mp3_fname != fname || mp3_handle < 0) + { + if (mp3_handle >= 0) sceIoClose(mp3_handle); + mp3_handle = sceIoOpen(fname, PSP_O_RDONLY, 0777); + if (mp3_handle < 0) { + printf("sceIoOpen(%s) failed\n", fname); + psp_sem_unlock(thread_busy_sem); + sceIoClose(mp3_handle); + return 2; + } + mp3_src_size = sceIoLseek32(mp3_handle, 0, PSP_SEEK_END); + mp3_fname = fname; + } + + // seek.. + mp3_src_pos = (int) (((float)pos / 1023.0f) * (float)mp3_src_size); + sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET); + printf("seek %i: %i/%i\n", pos, mp3_src_pos, mp3_src_size); + + mp3_job_started = 1; + mp3_samples_ready = mp3_buffer_offs = mp3_play_bufsel = 0; + working_buf = 0; + + /* send a request to decode first frame */ + psp_sem_unlock(thread_busy_sem); + psp_sem_unlock(thread_job_sem); + sceKernelDelayThread(1); // reschedule + + return 0; +} + + diff --git a/r17/Revamped src/revamped_src/net.h b/r17/Revamped src/revamped_src/net.h new file mode 100755 index 00000000..df078e4e --- /dev/null +++ b/r17/Revamped src/revamped_src/net.h @@ -0,0 +1,344 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// net.h -- quake's interface to the networking layer + +struct qsockaddr +{ +#ifdef PSP + unsigned char sa_len; + unsigned char sa_family; +#else + short sa_family; +#endif + unsigned char sa_data[14]; +}; + + +#define NET_NAMELEN 64 + +#define NET_MAXMESSAGE 8192 +#define NET_HEADERSIZE (2 * sizeof(unsigned int)) +#define NET_DATAGRAMSIZE (MAX_DATAGRAM + NET_HEADERSIZE) + +// NetHeader flags +#define NETFLAG_LENGTH_MASK 0x0000ffff +#define NETFLAG_DATA 0x00010000 +#define NETFLAG_ACK 0x00020000 +#define NETFLAG_NAK 0x00040000 +#define NETFLAG_EOM 0x00080000 +#define NETFLAG_UNRELIABLE 0x00100000 +#define NETFLAG_CTL 0x80000000 + + +#define NET_PROTOCOL_VERSION 3 + +// This is the network info/connection protocol. It is used to find Quake +// servers, get info about them, and connect to them. Once connected, the +// Quake game protocol (documented elsewhere) is used. +// +// +// General notes: +// game_name is currently always "QUAKE", but is there so this same protocol +// can be used for future games as well; can you say Quake2? +// +// CCREQ_CONNECT +// string game_name "QUAKE" +// byte net_protocol_version NET_PROTOCOL_VERSION +// +// CCREQ_SERVER_INFO +// string game_name "QUAKE" +// byte net_protocol_version NET_PROTOCOL_VERSION +// +// CCREQ_PLAYER_INFO +// byte player_number +// +// CCREQ_RULE_INFO +// string rule +// +// +// +// CCREP_ACCEPT +// long port +// +// CCREP_REJECT +// string reason +// +// CCREP_SERVER_INFO +// string server_address +// string host_name +// string level_name +// byte current_players +// byte max_players +// byte protocol_version NET_PROTOCOL_VERSION +// +// CCREP_PLAYER_INFO +// byte player_number +// string name +// long colors +// long frags +// long connect_time +// string address +// +// CCREP_RULE_INFO +// string rule +// string value + +// note: +// There are two address forms used above. The short form is just a +// port number. The address that goes along with the port is defined as +// "whatever address you receive this reponse from". This lets us use +// the host OS to solve the problem of multiple host addresses (possibly +// with no routing between them); the host will use the right address +// when we reply to the inbound connection request. The long from is +// a full address and port in a string. It is used for returning the +// address of a server that is not running locally. + +#define CCREQ_CONNECT 0x01 +#define CCREQ_SERVER_INFO 0x02 +#define CCREQ_PLAYER_INFO 0x03 +#define CCREQ_RULE_INFO 0x04 + +#define CCREP_ACCEPT 0x81 +#define CCREP_REJECT 0x82 +#define CCREP_SERVER_INFO 0x83 +#define CCREP_PLAYER_INFO 0x84 +#define CCREP_RULE_INFO 0x85 + +typedef struct qsocket_s +{ + struct qsocket_s *next; + double connecttime; + double lastMessageTime; + double lastSendTime; + + qboolean disconnected; + qboolean canSend; + qboolean sendNext; + + int driver; + int landriver; + int socket; + void *driverdata; + + unsigned int ackSequence; + unsigned int sendSequence; + unsigned int unreliableSendSequence; + int sendMessageLength; + byte sendMessage [NET_MAXMESSAGE]; + + unsigned int receiveSequence; + unsigned int unreliableReceiveSequence; + int receiveMessageLength; + byte receiveMessage [NET_MAXMESSAGE]; + + struct qsockaddr addr; + char address[NET_NAMELEN]; + +} qsocket_t; + +extern qsocket_t *net_activeSockets; +extern qsocket_t *net_freeSockets; +extern int net_numsockets; + +typedef struct +{ + char *name; + qboolean initialized; + int controlSock; + int (*Init) (void); + void (*Shutdown) (void); + void (*Listen) (qboolean state); + int (*OpenSocket) (int port); + int (*CloseSocket) (int socket); + int (*Connect) (int socket, struct qsockaddr *addr); + int (*CheckNewConnections) (void); + int (*Read) (int socket, byte *buf, int len, struct qsockaddr *addr); + int (*Write) (int socket, byte *buf, int len, struct qsockaddr *addr); + int (*Broadcast) (int socket, byte *buf, int len); + char * (*AddrToString) (struct qsockaddr *addr); + int (*StringToAddr) (char *string, struct qsockaddr *addr); + int (*GetSocketAddr) (int socket, struct qsockaddr *addr); + int (*GetNameFromAddr) (struct qsockaddr *addr, char *name); + int (*GetAddrFromName) (char *name, struct qsockaddr *addr); + int (*AddrCompare) (struct qsockaddr *addr1, struct qsockaddr *addr2); + int (*GetSocketPort) (struct qsockaddr *addr); + int (*SetSocketPort) (struct qsockaddr *addr, int port); +} net_landriver_t; + +#define MAX_NET_DRIVERS 8 +extern int net_numlandrivers; +extern net_landriver_t net_landrivers[MAX_NET_DRIVERS]; + +typedef struct +{ + char *name; + qboolean initialized; + int (*Init) (void); + void (*Listen) (qboolean state); + void (*SearchForHosts) (qboolean xmit); + qsocket_t *(*Connect) (char *host); + qsocket_t *(*CheckNewConnections) (void); + int (*QGetMessage) (qsocket_t *sock); + int (*QSendMessage) (qsocket_t *sock, sizebuf_t *data); + int (*SendUnreliableMessage) (qsocket_t *sock, sizebuf_t *data); + qboolean (*CanSendMessage) (qsocket_t *sock); + qboolean (*CanSendUnreliableMessage) (qsocket_t *sock); + void (*Close) (qsocket_t *sock); + void (*Shutdown) (void); + int controlSock; +} net_driver_t; + +extern int net_numdrivers; +extern net_driver_t net_drivers[MAX_NET_DRIVERS]; + +extern int DEFAULTnet_hostport; +extern int net_hostport; + +extern int net_driverlevel; +extern cvar_t hostname; +extern char playername[]; +extern int playercolor; + +extern int messagesSent; +extern int messagesReceived; +extern int unreliableMessagesSent; +extern int unreliableMessagesReceived; + +qsocket_t *NET_NewQSocket (void); +void NET_FreeQSocket(qsocket_t *); +double SetNetTime(void); + + +#define HOSTCACHESIZE 8 + +typedef struct +{ + char name[16]; + char map[16]; + char cname[32]; + int users; + int maxusers; + int driver; + int ldriver; + struct qsockaddr addr; +} hostcache_t; + +extern int hostCacheCount; +extern hostcache_t hostcache[HOSTCACHESIZE]; + +#if !defined(WIN32 ) && !defined (__linux__) && !defined (__sun__) +#ifndef htonl +extern unsigned long htonl (unsigned long hostlong); +#endif +#ifndef htons +extern unsigned short htons (unsigned short hostshort); +#endif +#ifndef ntohl +extern unsigned long ntohl (unsigned long netlong); +#endif +#ifndef ntohs +extern unsigned short ntohs (unsigned short netshort); +#endif +#endif + +#ifdef IDGODS +qboolean IsID(struct qsockaddr *addr); +#endif + +//============================================================================ +// +// public network functions +// +//============================================================================ + +extern double net_time; +extern sizebuf_t net_message; +extern int net_activeconnections; + +void NET_Init (void); +void NET_Shutdown (void); + +struct qsocket_s *NET_CheckNewConnections (void); +// returns a new connection number if there is one pending, else -1 + +struct qsocket_s *NET_Connect (char *host); +// called by client to connect to a host. Returns -1 if not able to + +qboolean NET_CanSendMessage (qsocket_t *sock); +// Returns true or false if the given qsocket can currently accept a +// message to be transmitted. + +int NET_GetMessage (struct qsocket_s *sock); +// returns data in net_message sizebuf +// returns 0 if no data is waiting +// returns 1 if a message was received +// returns 2 if an unreliable message was received +// returns -1 if the connection died + +int NET_SendMessage (struct qsocket_s *sock, sizebuf_t *data); +int NET_SendUnreliableMessage (struct qsocket_s *sock, sizebuf_t *data); +// returns 0 if the message connot be delivered reliably, but the connection +// is still considered valid +// returns 1 if the message was sent properly +// returns -1 if the connection died + +int NET_SendToAll(sizebuf_t *data, int blocktime); +// This is a reliable *blocking* send to all attached clients. + + +void NET_Close (struct qsocket_s *sock); +// if a dead connection is returned by a get or send function, this function +// should be called when it is convenient + +// Server calls when a client is kicked off for a game related misbehavior +// like an illegal protocal conversation. Client calls when disconnecting +// from a server. +// A netcon_t number will not be reused until this function is called for it + +void NET_Poll(void); + + +typedef struct _PollProcedure +{ + struct _PollProcedure *next; + double nextTime; + void (*procedure)(); + void *arg; +} PollProcedure; + +void SchedulePollProcedure(PollProcedure *pp, double timeOffset); + +extern qboolean serialAvailable; +extern qboolean ipxAvailable; +extern qboolean tcpipAvailable; +extern qboolean tcpipAdhoc; + +extern char my_ipx_address[NET_NAMELEN]; +extern char my_tcpip_address[NET_NAMELEN]; +extern void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem); +extern void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem); +extern void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); +extern void (*SetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); + +extern qboolean slistInProgress; +extern qboolean slistSilent; +extern qboolean slistLocal; + +void NET_Slist_f (void); diff --git a/r17/Revamped src/revamped_src/net_dgrm.c b/r17/Revamped src/revamped_src/net_dgrm.c new file mode 100755 index 00000000..50842116 --- /dev/null +++ b/r17/Revamped src/revamped_src/net_dgrm.c @@ -0,0 +1,1428 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// net_dgrm.c + +// This is enables a simple IP banning mechanism +#ifndef PSP +#define BAN_TEST +#endif + +#ifdef BAN_TEST +#if defined(WIN32) +#include +#elif defined (NeXT) +#include +#include +#else +#define AF_INET 2 /* internet */ +struct in_addr +{ + union + { + struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b; + struct { unsigned short s_w1,s_w2; } S_un_w; + unsigned long S_addr; + } S_un; +}; +#define s_addr S_un.S_addr /* can be used for most tcp & ip code */ +struct sockaddr_in +{ + short sin_family; + unsigned short sin_port; + struct in_addr sin_addr; + char sin_zero[8]; +}; +char *inet_ntoa(struct in_addr in); +unsigned long inet_addr(const char *cp); +#endif +#endif // BAN_TEST + +#include "quakedef.h" +#include "net_dgrm.h" + +// these two macros are to make the code more readable +#define sfunc net_landrivers[sock->landriver] +#define dfunc net_landrivers[net_landriverlevel] + +static int net_landriverlevel; + +/* statistic counters */ +int packetsSent = 0; +int packetsReSent = 0; +int packetsReceived = 0; +int receivedDuplicateCount = 0; +int shortPacketCount = 0; +int droppedDatagrams; + +static int myDriverLevel; + +struct +{ + unsigned int length; + unsigned int sequence; + byte data[MAX_DATAGRAM]; +} packetBuffer; + +extern int m_return_state; +extern int m_state; +extern qboolean m_return_onerror; +extern char m_return_reason[32]; + + +#ifdef DEBUG +char *StrAddr (struct qsockaddr *addr) +{ + static char buf[34]; + byte *p = (byte *)addr; + int n; + + for (n = 0; n < 16; n++) + sprintf (buf + n * 2, "%02x", *p++); + return buf; +} +#endif + + +#ifdef BAN_TEST +unsigned long banAddr = 0x00000000; +unsigned long banMask = 0xffffffff; + +void NET_Ban_f (void) +{ + char addrStr [32]; + char maskStr [32]; + void (*print) (char *fmt, ...); + + if (cmd_source == src_command) + { + if (!sv.active) + { + Cmd_ForwardToServer (); + return; + } + print = Con_Printf; + } + else + { + if (pr_global_struct->deathmatch && !host_client->privileged) + return; + print = SV_ClientPrintf; + } + + switch (Cmd_Argc ()) + { + case 1: + if (((struct in_addr *)&banAddr)->s_addr) + { + Q_strcpy(addrStr, inet_ntoa(*(struct in_addr *)&banAddr)); + Q_strcpy(maskStr, inet_ntoa(*(struct in_addr *)&banMask)); + print("Banning %s [%s]\n", addrStr, maskStr); + } + else + print("Banning not active\n"); + break; + + case 2: + if (Q_strcasecmp(Cmd_Argv(1), "off") == 0) + banAddr = 0x00000000; + else + banAddr = inet_addr(Cmd_Argv(1)); + banMask = 0xffffffff; + break; + + case 3: + banAddr = inet_addr(Cmd_Argv(1)); + banMask = inet_addr(Cmd_Argv(2)); + break; + + default: + print("BAN ip_address [mask]\n"); + break; + } +} +#endif + + +int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data) +{ + unsigned int packetLen; + unsigned int dataLen; + unsigned int eom; + +#ifdef DEBUG + if (data->cursize == 0) + Sys_Error("Datagram_SendMessage: zero length message\n"); + + if (data->cursize > NET_MAXMESSAGE) + Sys_Error("Datagram_SendMessage: message too big %u\n", data->cursize); + + if (sock->canSend == false) + Sys_Error("SendMessage: called with canSend == false\n"); +#endif + + Q_memcpy(sock->sendMessage, data->data, data->cursize); + sock->sendMessageLength = data->cursize; + + if (data->cursize <= MAX_DATAGRAM) + { + dataLen = data->cursize; + eom = NETFLAG_EOM; + } + else + { + dataLen = MAX_DATAGRAM; + eom = 0; + } + packetLen = NET_HEADERSIZE + dataLen; + + packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom)); + packetBuffer.sequence = BigLong(sock->sendSequence++); + Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen); + + sock->canSend = false; + + if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1) + return -1; + + sock->lastSendTime = net_time; + packetsSent++; + return 1; +} + + +int SendMessageNext (qsocket_t *sock) +{ + unsigned int packetLen; + unsigned int dataLen; + unsigned int eom; + + if (sock->sendMessageLength <= MAX_DATAGRAM) + { + dataLen = sock->sendMessageLength; + eom = NETFLAG_EOM; + } + else + { + dataLen = MAX_DATAGRAM; + eom = 0; + } + packetLen = NET_HEADERSIZE + dataLen; + + packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom)); + packetBuffer.sequence = BigLong(sock->sendSequence++); + Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen); + + sock->sendNext = false; + + if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1) + return -1; + + sock->lastSendTime = net_time; + packetsSent++; + return 1; +} + + +int ReSendMessage (qsocket_t *sock) +{ + unsigned int packetLen; + unsigned int dataLen; + unsigned int eom; + + if (sock->sendMessageLength <= MAX_DATAGRAM) + { + dataLen = sock->sendMessageLength; + eom = NETFLAG_EOM; + } + else + { + dataLen = MAX_DATAGRAM; + eom = 0; + } + packetLen = NET_HEADERSIZE + dataLen; + + packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom)); + packetBuffer.sequence = BigLong(sock->sendSequence - 1); + Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen); + + sock->sendNext = false; + + if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1) + return -1; + + sock->lastSendTime = net_time; + packetsReSent++; + return 1; +} + + +qboolean Datagram_CanSendMessage (qsocket_t *sock) +{ + if (sock->sendNext) + SendMessageNext (sock); + + return sock->canSend; +} + + +qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock) +{ + return true; +} + + +int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) +{ + int packetLen; + +#ifdef DEBUG + if (data->cursize == 0) + Sys_Error("Datagram_SendUnreliableMessage: zero length message\n"); + + if (data->cursize > MAX_DATAGRAM) + Sys_Error("Datagram_SendUnreliableMessage: message too big %u\n", data->cursize); +#endif + + packetLen = NET_HEADERSIZE + data->cursize; + + packetBuffer.length = BigLong(packetLen | NETFLAG_UNRELIABLE); + packetBuffer.sequence = BigLong(sock->unreliableSendSequence++); + Q_memcpy (packetBuffer.data, data->data, data->cursize); + + if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1) + return -1; + + packetsSent++; + return 1; +} + + +int Datagram_GetMessage (qsocket_t *sock) +{ + unsigned int length; + unsigned int flags; + int ret = 0; + struct qsockaddr readaddr; + unsigned int sequence; + unsigned int count; + +#if 0 + if (!sock->canSend) + if ((net_time - sock->lastSendTime) > 1.0) + ReSendMessage (sock); +#endif + + while(1) + { + length = sfunc.Read (sock->socket, (byte *)&packetBuffer, NET_DATAGRAMSIZE, &readaddr); + +// if ((rand() & 255) > 220) +// continue; + + if (length == 0) + break; + + if (length == -1) + { + Con_Printf("Read error\n"); + return -1; + } + + if (sfunc.AddrCompare(&readaddr, &sock->addr) != 0) + { +#ifdef DEBUG + Con_DPrintf("Forged packet received\n"); + Con_DPrintf("Expected: %s\n", StrAddr (&sock->addr)); + Con_DPrintf("Received: %s\n", StrAddr (&readaddr)); +#endif + continue; + } + + if (length < NET_HEADERSIZE) + { + shortPacketCount++; + continue; + } + + length = BigLong(packetBuffer.length); + flags = length & (~NETFLAG_LENGTH_MASK); + length &= NETFLAG_LENGTH_MASK; + + if (flags & NETFLAG_CTL) + continue; + + sequence = BigLong(packetBuffer.sequence); + packetsReceived++; + + if (flags & NETFLAG_UNRELIABLE) + { + if (sequence < sock->unreliableReceiveSequence) + { + Con_DPrintf("Got a stale datagram\n"); + ret = 0; + break; + } + if (sequence != sock->unreliableReceiveSequence) + { + count = sequence - sock->unreliableReceiveSequence; + droppedDatagrams += count; + Con_DPrintf("Dropped %u datagram(s)\n", count); + } + sock->unreliableReceiveSequence = sequence + 1; + + length -= NET_HEADERSIZE; + + SZ_Clear (&net_message); + SZ_Write (&net_message, packetBuffer.data, length); + + ret = 2; + break; + } + + if (flags & NETFLAG_ACK) + { + if (sequence != (sock->sendSequence - 1)) + { + Con_DPrintf("Stale ACK received\n"); + continue; + } + if (sequence == sock->ackSequence) + { + sock->ackSequence++; + if (sock->ackSequence != sock->sendSequence) + Con_DPrintf("ack sequencing error\n"); + } + else + { + Con_DPrintf("Duplicate ACK received\n"); + continue; + } + sock->sendMessageLength -= MAX_DATAGRAM; + if (sock->sendMessageLength > 0) + { + Q_memcpy(sock->sendMessage, sock->sendMessage+MAX_DATAGRAM, sock->sendMessageLength); + sock->sendNext = true; + } + else + { + sock->sendMessageLength = 0; + sock->canSend = true; + } + continue; + } + + if (flags & NETFLAG_DATA) + { + packetBuffer.length = BigLong(NET_HEADERSIZE | NETFLAG_ACK); + packetBuffer.sequence = BigLong(sequence); + sfunc.Write (sock->socket, (byte *)&packetBuffer, NET_HEADERSIZE, &readaddr); + + if (sequence != sock->receiveSequence) + { + receivedDuplicateCount++; + continue; + } + sock->receiveSequence++; + + length -= NET_HEADERSIZE; + + if (flags & NETFLAG_EOM) + { + SZ_Clear(&net_message); + SZ_Write(&net_message, sock->receiveMessage, sock->receiveMessageLength); + SZ_Write(&net_message, packetBuffer.data, length); + sock->receiveMessageLength = 0; + + ret = 1; + break; + } + + Q_memcpy(sock->receiveMessage + sock->receiveMessageLength, packetBuffer.data, length); + sock->receiveMessageLength += length; + continue; + } + } + + if (sock->sendNext) + SendMessageNext (sock); + + return ret; +} + + +void PrintStats(qsocket_t *s) +{ + Con_Printf("canSend = %4u \n", s->canSend); + Con_Printf("sendSeq = %4u ", s->sendSequence); + Con_Printf("recvSeq = %4u \n", s->receiveSequence); + Con_Printf("\n"); +} + +void NET_Stats_f (void) +{ + qsocket_t *s; + + if (Cmd_Argc () == 1) + { + Con_Printf("unreliable messages sent = %i\n", unreliableMessagesSent); + Con_Printf("unreliable messages recv = %i\n", unreliableMessagesReceived); + Con_Printf("reliable messages sent = %i\n", messagesSent); + Con_Printf("reliable messages received = %i\n", messagesReceived); + Con_Printf("packetsSent = %i\n", packetsSent); + Con_Printf("packetsReSent = %i\n", packetsReSent); + Con_Printf("packetsReceived = %i\n", packetsReceived); + Con_Printf("receivedDuplicateCount = %i\n", receivedDuplicateCount); + Con_Printf("shortPacketCount = %i\n", shortPacketCount); + Con_Printf("droppedDatagrams = %i\n", droppedDatagrams); + } + else if (Q_strcmp(Cmd_Argv(1), "*") == 0) + { + for (s = net_activeSockets; s; s = s->next) + PrintStats(s); + for (s = net_freeSockets; s; s = s->next) + PrintStats(s); + } + else + { + for (s = net_activeSockets; s; s = s->next) + if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0) + break; + if (s == NULL) + for (s = net_freeSockets; s; s = s->next) + if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0) + break; + if (s == NULL) + return; + PrintStats(s); + } +} + + +static qboolean testInProgress = false; +static int testPollCount; +static int testDriver; +static int testSocket; + +static void Test_Poll(void); +PollProcedure testPollProcedure = {NULL, 0.0, Test_Poll}; + +static void Test_Poll(void) +{ + struct qsockaddr clientaddr; + int control; + int len; + char name[32]; + char address[64]; + int colors; + int frags; + int connectTime; + byte playerNumber; + + net_landriverlevel = testDriver; + + while (1) + { + len = dfunc.Read (testSocket, net_message.data, net_message.maxsize, &clientaddr); + if (len < sizeof(int)) + break; + + net_message.cursize = len; + + MSG_BeginReading (); + control = BigLong(*((int *)net_message.data)); + MSG_ReadLong(); + if (control == -1) + break; + if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + break; + if ((control & NETFLAG_LENGTH_MASK) != len) + break; + + if (MSG_ReadByte() != CCREP_PLAYER_INFO) + Sys_Error("Unexpected repsonse to Player Info request\n"); + + playerNumber = MSG_ReadByte(); + Q_strcpy(name, MSG_ReadString()); + colors = MSG_ReadLong(); + frags = MSG_ReadLong(); + connectTime = MSG_ReadLong(); + Q_strcpy(address, MSG_ReadString()); + + Con_Printf("%s\n frags:%3i colors:%u %u time:%u\n %s\n", name, frags, colors >> 4, colors & 0x0f, connectTime / 60, address); + } + + testPollCount--; + if (testPollCount) + { + SchedulePollProcedure(&testPollProcedure, 0.1); + } + else + { + dfunc.CloseSocket(testSocket); + testInProgress = false; + } +} + +static void Test_f (void) +{ + char *host; + int n; + int max = MAX_SCOREBOARD; + struct qsockaddr sendaddr; + + if (testInProgress) + return; + + host = Cmd_Argv (1); + + if (host && hostCacheCount) + { + for (n = 0; n < hostCacheCount; n++) + if (Q_strcasecmp (host, hostcache[n].name) == 0) + { + if (hostcache[n].driver != myDriverLevel) + continue; + net_landriverlevel = hostcache[n].ldriver; + max = hostcache[n].maxusers; + Q_memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr)); + break; + } + if (n < hostCacheCount) + goto JustDoIt; + } + + for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) + { + if (!net_landrivers[net_landriverlevel].initialized) + continue; + + // see if we can resolve the host name + if (dfunc.GetAddrFromName(host, &sendaddr) != -1) + break; + } + if (net_landriverlevel == net_numlandrivers) + return; + +JustDoIt: + testSocket = dfunc.OpenSocket(0); + if (testSocket == -1) + return; + + testInProgress = true; + testPollCount = 20; + testDriver = net_landriverlevel; + + for (n = 0; n < max; n++) + { + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREQ_PLAYER_INFO); + MSG_WriteByte(&net_message, n); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (testSocket, net_message.data, net_message.cursize, &sendaddr); + } + SZ_Clear(&net_message); + SchedulePollProcedure(&testPollProcedure, 0.1); +} + + +static qboolean test2InProgress = false; +static int test2Driver; +static int test2Socket; + +static void Test2_Poll(void); +PollProcedure test2PollProcedure = {NULL, 0.0, Test2_Poll}; + +static void Test2_Poll(void) +{ + struct qsockaddr clientaddr; + int control; + int len; + char name[256]; + char value[256]; + + net_landriverlevel = test2Driver; + name[0] = 0; + + len = dfunc.Read (test2Socket, net_message.data, net_message.maxsize, &clientaddr); + if (len < sizeof(int)) + goto Reschedule; + + net_message.cursize = len; + + MSG_BeginReading (); + control = BigLong(*((int *)net_message.data)); + MSG_ReadLong(); + if (control == -1) + goto Error; + if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + goto Error; + if ((control & NETFLAG_LENGTH_MASK) != len) + goto Error; + + if (MSG_ReadByte() != CCREP_RULE_INFO) + goto Error; + + Q_strcpy(name, MSG_ReadString()); + if (name[0] == 0) + goto Done; + Q_strcpy(value, MSG_ReadString()); + + Con_Printf("%-16.16s %-16.16s\n", name, value); + + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREQ_RULE_INFO); + MSG_WriteString(&net_message, name); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (test2Socket, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + +Reschedule: + SchedulePollProcedure(&test2PollProcedure, 0.05); + return; + +Error: + Con_Printf("Unexpected repsonse to Rule Info request\n"); +Done: + dfunc.CloseSocket(test2Socket); + test2InProgress = false; + return; +} + +static void Test2_f (void) +{ + char *host; + int n; + struct qsockaddr sendaddr; + + if (test2InProgress) + return; + + host = Cmd_Argv (1); + + if (host && hostCacheCount) + { + for (n = 0; n < hostCacheCount; n++) + if (Q_strcasecmp (host, hostcache[n].name) == 0) + { + if (hostcache[n].driver != myDriverLevel) + continue; + net_landriverlevel = hostcache[n].ldriver; + Q_memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr)); + break; + } + if (n < hostCacheCount) + goto JustDoIt; + } + + for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) + { + if (!net_landrivers[net_landriverlevel].initialized) + continue; + + // see if we can resolve the host name + if (dfunc.GetAddrFromName(host, &sendaddr) != -1) + break; + } + if (net_landriverlevel == net_numlandrivers) + return; + +JustDoIt: + test2Socket = dfunc.OpenSocket(0); + if (test2Socket == -1) + return; + + test2InProgress = true; + test2Driver = net_landriverlevel; + + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREQ_RULE_INFO); + MSG_WriteString(&net_message, ""); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (test2Socket, net_message.data, net_message.cursize, &sendaddr); + SZ_Clear(&net_message); + SchedulePollProcedure(&test2PollProcedure, 0.05); +} + + +int Datagram_Init () +{ + int i; + int csock; + + myDriverLevel = net_driverlevel; + if(!host_initialized) + Cmd_AddCommand ("net_stats", NET_Stats_f); + + if (COM_CheckParm("-nolan")) + return -1; + + i = net_driver_to_use;//for (i = 0; i < net_numlandrivers; i++) + { + csock = net_landrivers[i].Init (); + if (csock == -1) return 0; + //continue; + net_landrivers[i].initialized = true; + net_landrivers[i].controlSock = csock; + } + + if(!host_initialized) + { +#ifdef BAN_TEST + Cmd_AddCommand ("ban", NET_Ban_f); +#endif + Cmd_AddCommand ("test", Test_f); + Cmd_AddCommand ("test2", Test2_f); + } + + return 0; +} + + +void Datagram_Shutdown (void) +{ + int i; + +// +// shutdown the lan drivers +// + for (i = 0; i < net_numlandrivers; i++) + { + if (net_landrivers[i].initialized) + { + net_landrivers[i].Shutdown (); + net_landrivers[i].initialized = false; + } + } +} + + +void Datagram_Close (qsocket_t *sock) +{ + sfunc.CloseSocket(sock->socket); +} + + +void Datagram_Listen (qboolean state) +{ + int i; + + for (i = 0; i < net_numlandrivers; i++) + if (net_landrivers[i].initialized) + net_landrivers[i].Listen (state); +} + + +static qsocket_t *_Datagram_CheckNewConnections (void) +{ + struct qsockaddr clientaddr; + struct qsockaddr newaddr; + int newsock; + int acceptsock; + qsocket_t *sock; + qsocket_t *s; + int len; + int command; + int control; + int ret; + + acceptsock = dfunc.CheckNewConnections(); + if (acceptsock == -1) + return NULL; + + SZ_Clear(&net_message); + + len = dfunc.Read (acceptsock, net_message.data, net_message.maxsize, &clientaddr); + if (len < sizeof(int)) + return NULL; + net_message.cursize = len; + + MSG_BeginReading (); + control = BigLong(*((int *)net_message.data)); + MSG_ReadLong(); + if (control == -1) + return NULL; + if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + return NULL; + if ((control & NETFLAG_LENGTH_MASK) != len) + return NULL; + + command = MSG_ReadByte(); + if (command == CCREQ_SERVER_INFO) + { + if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0) + return NULL; + + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_SERVER_INFO); + dfunc.GetSocketAddr(acceptsock, &newaddr); + MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr)); + MSG_WriteString(&net_message, hostname.string); + MSG_WriteString(&net_message, sv.name); + MSG_WriteByte(&net_message, net_activeconnections); + MSG_WriteByte(&net_message, svs.maxclients); + MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + return NULL; + } + + if (command == CCREQ_PLAYER_INFO) + { + int playerNumber; + int activeNumber; + int clientNumber; + client_t *client; + + playerNumber = MSG_ReadByte(); + activeNumber = -1; + for (clientNumber = 0, client = svs.clients; clientNumber < svs.maxclients; clientNumber++, client++) + { + if (client->active) + { + activeNumber++; + if (activeNumber == playerNumber) + break; + } + } + if (clientNumber == svs.maxclients) + return NULL; + + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_PLAYER_INFO); + MSG_WriteByte(&net_message, playerNumber); + MSG_WriteString(&net_message, client->name); + MSG_WriteLong(&net_message, client->colors); + MSG_WriteLong(&net_message, (int)client->edict->v.frags); + MSG_WriteLong(&net_message, (int)(net_time - client->netconnection->connecttime)); + MSG_WriteString(&net_message, client->netconnection->address); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + + return NULL; + } + + if (command == CCREQ_RULE_INFO) + { + char *prevCvarName; + cvar_t *var; + + // find the search start location + prevCvarName = MSG_ReadString(); + if (*prevCvarName) + { + var = Cvar_FindVar (prevCvarName); + if (!var) + return NULL; + var = var->next; + } + else + var = cvar_vars; + + // search for the next server cvar + while (var) + { + if (var->server) + break; + var = var->next; + } + + // send the response + + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_RULE_INFO); + if (var) + { + MSG_WriteString(&net_message, var->name); + MSG_WriteString(&net_message, var->string); + } + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + + return NULL; + } + + if (command != CCREQ_CONNECT) + return NULL; + + if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0) + return NULL; + + if (MSG_ReadByte() != NET_PROTOCOL_VERSION) + { + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_REJECT); + MSG_WriteString(&net_message, "Incompatible version.\n"); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + return NULL; + } + +#ifdef BAN_TEST + // check for a ban + if (clientaddr.sa_family == AF_INET) + { + unsigned long testAddr; + testAddr = ((struct sockaddr_in *)&clientaddr)->sin_addr.s_addr; + if ((testAddr & banMask) == banAddr) + { + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_REJECT); + MSG_WriteString(&net_message, "You have been banned.\n"); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + return NULL; + } + } +#endif + + // see if this guy is already connected + for (s = net_activeSockets; s; s = s->next) + { + if (s->driver != net_driverlevel) + continue; + ret = dfunc.AddrCompare(&clientaddr, &s->addr); + if (ret >= 0) + { + // is this a duplicate connection reqeust? + if (ret == 0 && net_time - s->connecttime < 2.0) + { + // yes, so send a duplicate reply + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_ACCEPT); + dfunc.GetSocketAddr(s->socket, &newaddr); + MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr)); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + return NULL; + } + // it's somebody coming back in from a crash/disconnect + // so close the old qsocket and let their retry get them back in + NET_Close(s); + return NULL; + } + } + + // allocate a QSocket + sock = NET_NewQSocket (); + if (sock == NULL) + { + // no room; try to let him know + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_REJECT); + MSG_WriteString(&net_message, "Server is full.\n"); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + return NULL; + } + + // allocate a network socket + newsock = dfunc.OpenSocket(0); + if (newsock == -1) + { + NET_FreeQSocket(sock); + return NULL; + } + + // connect to the client + if (dfunc.Connect (newsock, &clientaddr) == -1) + { + dfunc.CloseSocket(newsock); + NET_FreeQSocket(sock); + return NULL; + } + + // everything is allocated, just fill in the details + sock->socket = newsock; + sock->landriver = net_landriverlevel; + sock->addr = clientaddr; + Q_strcpy(sock->address, dfunc.AddrToString(&clientaddr)); + + // send him back the info about the server connection he has been allocated + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_ACCEPT); + dfunc.GetSocketAddr(newsock, &newaddr); + MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr)); +// MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr)); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + + return sock; +} + +qsocket_t *Datagram_CheckNewConnections (void) +{ + qsocket_t *ret = NULL; + + for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) + if (net_landrivers[net_landriverlevel].initialized) + if ((ret = _Datagram_CheckNewConnections ()) != NULL) + break; + return ret; +} + + +static void _Datagram_SearchForHosts (qboolean xmit) +{ + int ret; + int n; + int i; + struct qsockaddr readaddr; + struct qsockaddr myaddr; + struct qsockaddr writeAddr; + FILE *netserversHandle=0; + char string[100]; + char *newline; + int control; + + dfunc.GetSocketAddr (dfunc.controlSock, &myaddr); + if (xmit) + { + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREQ_SERVER_INFO); + MSG_WriteString(&net_message, "QUAKE"); + MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Broadcast(dfunc.controlSock, net_message.data, net_message.cursize); + SZ_Clear(&net_message); + } + if(tcpipAvailable) + { + netserversHandle = fopen(va("%s/netservers.cfg",com_gamedir), "r"); + if(netserversHandle > 0) + { + while(fgets (string, 100, netserversHandle) > 0) + { + newline = strrchr(string, '\n'); + if(newline) + *newline = '\0'; + + newline = strrchr(string, '\r'); + if(newline) + *newline = '\0'; + + dfunc.GetAddrFromName(string, &writeAddr); + dfunc.Write(dfunc.controlSock, + net_message.data, + net_message.cursize, + &writeAddr); + sceDisplayWaitVblankStart(); + } + } + fclose(netserversHandle); + } + + while ((ret = dfunc.Read (dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0) + { + if (ret < sizeof(int)) + continue; + net_message.cursize = ret; + + // don't answer our own query + if (dfunc.AddrCompare(&readaddr, &myaddr) >= 0) + continue; + + // is the cache full? + if (hostCacheCount == HOSTCACHESIZE) + continue; + + MSG_BeginReading (); + control = BigLong(*((int *)net_message.data)); + MSG_ReadLong(); + if (control == -1) + continue; + if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + continue; + if ((control & NETFLAG_LENGTH_MASK) != ret) + continue; + + if (MSG_ReadByte() != CCREP_SERVER_INFO) + continue; + + dfunc.GetAddrFromName(MSG_ReadString(), &readaddr); + // search the cache for this server + for (n = 0; n < hostCacheCount; n++) + if (dfunc.AddrCompare(&readaddr, &hostcache[n].addr) == 0) + break; + + // is it already there? + if (n < hostCacheCount) + continue; + + // add it + hostCacheCount++; + Q_strcpy(hostcache[n].name, MSG_ReadString()); + Q_strcpy(hostcache[n].map, MSG_ReadString()); + hostcache[n].users = MSG_ReadByte(); + hostcache[n].maxusers = MSG_ReadByte(); + if (MSG_ReadByte() != NET_PROTOCOL_VERSION) + { + Q_strcpy(hostcache[n].cname, hostcache[n].name); + hostcache[n].cname[14] = 0; + Q_strcpy(hostcache[n].name, "*"); + Q_strcat(hostcache[n].name, hostcache[n].cname); + } + Q_memcpy(&hostcache[n].addr, &readaddr, sizeof(struct qsockaddr)); + hostcache[n].driver = net_driverlevel; + hostcache[n].ldriver = net_landriverlevel; + Q_strcpy(hostcache[n].cname, dfunc.AddrToString(&readaddr)); + + // check for a name conflict + for (i = 0; i < hostCacheCount; i++) + { + if (i == n) + continue; + if (Q_strcasecmp (hostcache[n].name, hostcache[i].name) == 0) + { + i = Q_strlen(hostcache[n].name); + if (i < 15 && hostcache[n].name[i-1] > '8') + { + hostcache[n].name[i] = '0'; + hostcache[n].name[i+1] = 0; + } + else + hostcache[n].name[i-1]++; + i = -1; + } + } + } +} + +void Datagram_SearchForHosts (qboolean xmit) +{ + for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) + { + if (hostCacheCount == HOSTCACHESIZE) + break; + if (net_landrivers[net_landriverlevel].initialized) + _Datagram_SearchForHosts (xmit); + } +} + + +static qsocket_t *_Datagram_Connect (char *host) +{ + struct qsockaddr sendaddr; + struct qsockaddr readaddr; + qsocket_t *sock; + int newsock; + int ret; + int reps; + double start_time; + int control; + char *reason; + + // see if we can resolve the host name + if (dfunc.GetAddrFromName(host, &sendaddr) == -1) + return NULL; + + newsock = dfunc.OpenSocket (0); + if (newsock == -1) + return NULL; + + sock = NET_NewQSocket (); + if (sock == NULL) + goto ErrorReturn2; + sock->socket = newsock; + sock->landriver = net_landriverlevel; + + // connect to the host + if (dfunc.Connect (newsock, &sendaddr) == -1) + goto ErrorReturn; + + // send the connection request + Con_Printf("trying...\n"); SCR_UpdateScreen (); + start_time = net_time; + + for (reps = 0; reps < 3; reps++) + { + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREQ_CONNECT); + MSG_WriteString(&net_message, "QUAKE"); + MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (newsock, net_message.data, net_message.cursize, &sendaddr); + SZ_Clear(&net_message); + do + { + ret = dfunc.Read (newsock, net_message.data, net_message.maxsize, &readaddr); + // if we got something, validate it + if (ret > 0) + { + // is it from the right place? + if (sfunc.AddrCompare(&readaddr, &sendaddr) != 0) + { +#ifdef DEBUG + Con_Printf("wrong reply address\n"); + Con_Printf("Expected: %s\n", StrAddr (&sendaddr)); + Con_Printf("Received: %s\n", StrAddr (&readaddr)); + SCR_UpdateScreen (); +#endif + ret = 0; + continue; + } + + if (ret < sizeof(int)) + { + ret = 0; + continue; + } + + net_message.cursize = ret; + MSG_BeginReading (); + + control = BigLong(*((int *)net_message.data)); + MSG_ReadLong(); + if (control == -1) + { + ret = 0; + continue; + } + if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + { + ret = 0; + continue; + } + if ((control & NETFLAG_LENGTH_MASK) != ret) + { + ret = 0; + continue; + } + } + sceKernelDelayThread(10); + } + while (ret == 0 && (SetNetTime() - start_time) < 5.5); + if (ret) + break; + Con_Printf("still trying...\n"); SCR_UpdateScreen (); + start_time = SetNetTime(); + } + + if (ret == 0) + { + reason = "No Response"; + Con_Printf("%s\n", reason); + Q_strcpy(m_return_reason, reason); + goto ErrorReturn; + } + + if (ret == -1) + { + reason = "Network Error"; + Con_Printf("%s\n", reason); + Q_strcpy(m_return_reason, reason); + goto ErrorReturn; + } + + ret = MSG_ReadByte(); + if (ret == CCREP_REJECT) + { + reason = MSG_ReadString(); + Con_Printf(reason); + Q_strncpy(m_return_reason, reason, 31); + goto ErrorReturn; + } + + if (ret == CCREP_ACCEPT) + { + Q_memcpy(&sock->addr, &sendaddr, sizeof(struct qsockaddr)); + dfunc.SetSocketPort (&sock->addr, MSG_ReadLong()); + } + else + { + reason = "Bad Response"; + Con_Printf("%s\n", reason); + Q_strcpy(m_return_reason, reason); + goto ErrorReturn; + } + + dfunc.GetNameFromAddr (&sendaddr, sock->address); + + Con_Printf ("Connection accepted\n"); + sock->lastMessageTime = SetNetTime(); + + // switch the connection to the specified address + if (dfunc.Connect (newsock, &sock->addr) == -1) + { + reason = "Connect to Game failed"; + Con_Printf("%s\n", reason); + Q_strcpy(m_return_reason, reason); + goto ErrorReturn; + } + + m_return_onerror = false; + return sock; + +ErrorReturn: + NET_FreeQSocket(sock); +ErrorReturn2: + dfunc.CloseSocket(newsock); + if (m_return_onerror) + { + key_dest = key_menu; + m_state = m_return_state; + m_return_onerror = false; + } + return NULL; +} + +qsocket_t *Datagram_Connect (char *host) +{ + qsocket_t *ret = NULL; + + for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) + if (net_landrivers[net_landriverlevel].initialized) + if ((ret = _Datagram_Connect (host)) != NULL) + break; + return ret; +} diff --git a/r17/Revamped src/revamped_src/net_dgrm.h b/r17/Revamped src/revamped_src/net_dgrm.h new file mode 100755 index 00000000..c4567a20 --- /dev/null +++ b/r17/Revamped src/revamped_src/net_dgrm.h @@ -0,0 +1,35 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// net_dgrm.h + +int net_driver_to_use; + +int Datagram_Init (void); +void Datagram_Listen (qboolean state); +void Datagram_SearchForHosts (qboolean xmit); +qsocket_t *Datagram_Connect (char *host); +qsocket_t *Datagram_CheckNewConnections (void); +int Datagram_GetMessage (qsocket_t *sock); +int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data); +int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data); +qboolean Datagram_CanSendMessage (qsocket_t *sock); +qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock); +void Datagram_Close (qsocket_t *sock); +void Datagram_Shutdown (void); diff --git a/r17/Revamped src/revamped_src/net_loop.c b/r17/Revamped src/revamped_src/net_loop.c new file mode 100755 index 00000000..4a2719ee --- /dev/null +++ b/r17/Revamped src/revamped_src/net_loop.c @@ -0,0 +1,245 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// net_loop.c + +#include "quakedef.h" +#include "net_loop.h" + +qboolean localconnectpending = false; +qsocket_t *loop_client = NULL; +qsocket_t *loop_server = NULL; + +int Loop_Init (void) +{ + if (cls.state == ca_dedicated) + return -1; + return 0; +} + + +void Loop_Shutdown (void) +{ +} + + +void Loop_Listen (qboolean state) +{ +} + + +void Loop_SearchForHosts (qboolean xmit) +{ + if (!sv.active) + return; + + hostCacheCount = 1; + if (Q_strcmp(hostname.string, "UNNAMED") == 0) + Q_strcpy(hostcache[0].name, "local"); + else + Q_strcpy(hostcache[0].name, hostname.string); + Q_strcpy(hostcache[0].map, sv.name); + hostcache[0].users = net_activeconnections; + hostcache[0].maxusers = svs.maxclients; + hostcache[0].driver = net_driverlevel; + Q_strcpy(hostcache[0].cname, "local"); +} + + +qsocket_t *Loop_Connect (char *host) +{ + if (Q_strcmp(host,"local") != 0) + return NULL; + + localconnectpending = true; + + if (!loop_client) + { + if ((loop_client = NET_NewQSocket ()) == NULL) + { + Con_Printf("Loop_Connect: no qsocket available\n"); + return NULL; + } + Q_strcpy (loop_client->address, "localhost"); + } + loop_client->receiveMessageLength = 0; + loop_client->sendMessageLength = 0; + loop_client->canSend = true; + + if (!loop_server) + { + if ((loop_server = NET_NewQSocket ()) == NULL) + { + Con_Printf("Loop_Connect: no qsocket available\n"); + return NULL; + } + Q_strcpy (loop_server->address, "LOCAL"); + } + loop_server->receiveMessageLength = 0; + loop_server->sendMessageLength = 0; + loop_server->canSend = true; + + loop_client->driverdata = (void *)loop_server; + loop_server->driverdata = (void *)loop_client; + + return loop_client; +} + + +qsocket_t *Loop_CheckNewConnections (void) +{ + if (!localconnectpending) + return NULL; + + localconnectpending = false; + loop_server->sendMessageLength = 0; + loop_server->receiveMessageLength = 0; + loop_server->canSend = true; + loop_client->sendMessageLength = 0; + loop_client->receiveMessageLength = 0; + loop_client->canSend = true; + return loop_server; +} + + +static int IntAlign(int value) +{ + return (value + (sizeof(int) - 1)) & (~(sizeof(int) - 1)); +} + + +int Loop_GetMessage (qsocket_t *sock) +{ + int ret; + int length; + + if (sock->receiveMessageLength == 0) + return 0; + + ret = sock->receiveMessage[0]; + length = sock->receiveMessage[1] + (sock->receiveMessage[2] << 8); + // alignment byte skipped here + SZ_Clear (&net_message); + SZ_Write (&net_message, &sock->receiveMessage[4], length); + + length = IntAlign(length + 4); + sock->receiveMessageLength -= length; + + if (sock->receiveMessageLength) + Q_memcpy(sock->receiveMessage, &sock->receiveMessage[length], sock->receiveMessageLength); + + if (sock->driverdata && ret == 1) + ((qsocket_t *)sock->driverdata)->canSend = true; + + return ret; +} + + +int Loop_SendMessage (qsocket_t *sock, sizebuf_t *data) +{ + byte *buffer; + int *bufferLength; + + if (!sock->driverdata) + return -1; + + bufferLength = &((qsocket_t *)sock->driverdata)->receiveMessageLength; + + if ((*bufferLength + data->cursize + 4) > NET_MAXMESSAGE) + Sys_Error("Loop_SendMessage: overflow\n"); + + buffer = ((qsocket_t *)sock->driverdata)->receiveMessage + *bufferLength; + + // message type + *buffer++ = 1; + + // length + *buffer++ = data->cursize & 0xff; + *buffer++ = data->cursize >> 8; + + // align + buffer++; + + // message + Q_memcpy(buffer, data->data, data->cursize); + *bufferLength = IntAlign(*bufferLength + data->cursize + 4); + + sock->canSend = false; + return 1; +} + + +int Loop_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) +{ + byte *buffer; + int *bufferLength; + + if (!sock->driverdata) + return -1; + + bufferLength = &((qsocket_t *)sock->driverdata)->receiveMessageLength; + + if ((*bufferLength + data->cursize + sizeof(byte) + sizeof(short)) > NET_MAXMESSAGE) + return 0; + + buffer = ((qsocket_t *)sock->driverdata)->receiveMessage + *bufferLength; + + // message type + *buffer++ = 2; + + // length + *buffer++ = data->cursize & 0xff; + *buffer++ = data->cursize >> 8; + + // align + buffer++; + + // message + Q_memcpy(buffer, data->data, data->cursize); + *bufferLength = IntAlign(*bufferLength + data->cursize + 4); + return 1; +} + + +qboolean Loop_CanSendMessage (qsocket_t *sock) +{ + if (!sock->driverdata) + return false; + return sock->canSend; +} + + +qboolean Loop_CanSendUnreliableMessage (qsocket_t *sock) +{ + return true; +} + + +void Loop_Close (qsocket_t *sock) +{ + if (sock->driverdata) + ((qsocket_t *)sock->driverdata)->driverdata = NULL; + sock->receiveMessageLength = 0; + sock->sendMessageLength = 0; + sock->canSend = true; + if (sock == loop_client) + loop_client = NULL; + else + loop_server = NULL; +} diff --git a/r17/Revamped src/revamped_src/net_loop.h b/r17/Revamped src/revamped_src/net_loop.h new file mode 100755 index 00000000..210f40da --- /dev/null +++ b/r17/Revamped src/revamped_src/net_loop.h @@ -0,0 +1,33 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// net_loop.h + +int Loop_Init (void); +void Loop_Listen (qboolean state); +void Loop_SearchForHosts (qboolean xmit); +qsocket_t *Loop_Connect (char *host); +qsocket_t *Loop_CheckNewConnections (void); +int Loop_GetMessage (qsocket_t *sock); +int Loop_SendMessage (qsocket_t *sock, sizebuf_t *data); +int Loop_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data); +qboolean Loop_CanSendMessage (qsocket_t *sock); +qboolean Loop_CanSendUnreliableMessage (qsocket_t *sock); +void Loop_Close (qsocket_t *sock); +void Loop_Shutdown (void); diff --git a/r17/Revamped src/revamped_src/net_main.c b/r17/Revamped src/revamped_src/net_main.c new file mode 100755 index 00000000..75c683cf --- /dev/null +++ b/r17/Revamped src/revamped_src/net_main.c @@ -0,0 +1,1017 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// net_main.c + +#include "quakedef.h" +#include "net_vcr.h" + +qsocket_t *net_activeSockets = NULL; +qsocket_t *net_freeSockets = NULL; +int net_numsockets = 0; + +qboolean serialAvailable = false; +qboolean ipxAvailable = false; +qboolean tcpipAvailable = false; +qboolean tcpipAdhoc = false; + +int net_hostport; +int DEFAULTnet_hostport = 26000; + +char my_ipx_address[NET_NAMELEN]; +char my_tcpip_address[NET_NAMELEN]; + +void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem); +void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem); +void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); +void (*SetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); + +static qboolean listening = false; + +qboolean slistInProgress = false; +qboolean slistSilent = false; +qboolean slistLocal = true; +static double slistStartTime; +static int slistLastShown; + +static void Slist_Send(void); +static void Slist_Poll(void); +PollProcedure slistSendProcedure = {NULL, 0.0, Slist_Send}; +PollProcedure slistPollProcedure = {NULL, 0.0, Slist_Poll}; + + +sizebuf_t net_message; +int net_activeconnections = 0; + +int messagesSent = 0; +int messagesReceived = 0; +int unreliableMessagesSent = 0; +int unreliableMessagesReceived = 0; + +cvar_t net_messagetimeout = {"net_messagetimeout","300"}; +cvar_t hostname = {"hostname", "Unnamed Server"}; + +qboolean configRestored = false; +cvar_t config_com_port = {"_config_com_port", "0x3f8", true}; +cvar_t config_com_irq = {"_config_com_irq", "4", true}; +cvar_t config_com_baud = {"_config_com_baud", "57600", true}; +cvar_t config_com_modem = {"_config_com_modem", "1", true}; +cvar_t config_modem_dialtype = {"_config_modem_dialtype", "T", true}; +cvar_t config_modem_clear = {"_config_modem_clear", "ATZ", true}; +cvar_t config_modem_init = {"_config_modem_init", "", true}; +cvar_t config_modem_hangup = {"_config_modem_hangup", "AT H", true}; + +#ifdef IDGODS +cvar_t idgods = {"idgods", "0"}; +#endif + +int vcrFile = -1; +qboolean recording = false; + +// these two macros are to make the code more readable +#define sfunc net_drivers[sock->driver] +#define dfunc net_drivers[net_driverlevel] + +int net_driverlevel; + + +double net_time; + +double SetNetTime(void) +{ + net_time = Sys_FloatTime(); + return net_time; +} + + +/* +=================== +NET_NewQSocket + +Called by drivers when a new communications endpoint is required +The sequence and buffer fields will be filled in properly +=================== +*/ +qsocket_t *NET_NewQSocket (void) +{ + qsocket_t *sock; + + if (net_freeSockets == NULL) + return NULL; + + if (net_activeconnections >= svs.maxclients) + return NULL; + + // get one from free list + sock = net_freeSockets; + net_freeSockets = sock->next; + + // add it to active list + sock->next = net_activeSockets; + net_activeSockets = sock; + + sock->disconnected = false; + sock->connecttime = net_time; + Q_strcpy (sock->address,"UNSET ADDRESS"); + sock->driver = net_driverlevel; + sock->socket = 0; + sock->driverdata = NULL; + sock->canSend = true; + sock->sendNext = false; + sock->lastMessageTime = net_time; + sock->ackSequence = 0; + sock->sendSequence = 0; + sock->unreliableSendSequence = 0; + sock->sendMessageLength = 0; + sock->receiveSequence = 0; + sock->unreliableReceiveSequence = 0; + sock->receiveMessageLength = 0; + + return sock; +} + + +void NET_FreeQSocket(qsocket_t *sock) +{ + qsocket_t *s; + + // remove it from active list + if (sock == net_activeSockets) + net_activeSockets = net_activeSockets->next; + else + { + for (s = net_activeSockets; s; s = s->next) + if (s->next == sock) + { + s->next = sock->next; + break; + } + if (!s) + Sys_Error ("NET_FreeQSocket: not active\n"); + } + + // add it to free list + sock->next = net_freeSockets; + net_freeSockets = sock; + sock->disconnected = true; +} + + +static void NET_Listen_f (void) +{ + if (Cmd_Argc () != 2) + { + Con_Printf ("\"listen\" is \"%u\"\n", listening ? 1 : 0); + return; + } + + listening = Q_atoi(Cmd_Argv(1)) ? true : false; + + for (net_driverlevel=0 ; net_driverlevel svs.maxclientslimit) + { + n = svs.maxclientslimit; + Con_Printf ("\"maxplayers\" set to \"%u\"\n", n); + } + + if ((n == 1) && listening) + Cbuf_AddText ("listen 0\n"); + + if ((n > 1) && (!listening)) + Cbuf_AddText ("listen 1\n"); + + svs.maxclients = n; + if (n == 1) + { + Cvar_Set ("deathmatch", "0"); + Cvar_Set ("coop", "0"); + } + else + { + if (coop.value) + Cvar_Set ("deathmatch", "0"); + else + { + if (deathmatch.value > 1) + Cvar_SetValue ("deathmatch", deathmatch.value); + else + Cvar_Set ("deathmatch", "1"); + } + } +} + + +static void NET_Port_f (void) +{ + int n; + + if (Cmd_Argc () != 2) + { + Con_Printf ("\"port\" is \"%u\"\n", net_hostport); + return; + } + + n = Q_atoi(Cmd_Argv(1)); + if (n < 1 || n > 65534) + { + Con_Printf ("Bad value, must be between 1 and 65534\n"); + return; + } + + DEFAULTnet_hostport = n; + net_hostport = n; + + if (listening) + { + // force a change to the new port + Cbuf_AddText ("listen 0\n"); + Cbuf_AddText ("listen 1\n"); + } +} + + +static void PrintSlistHeader(void) +{ + Con_Printf("Server Map Users\n"); + Con_Printf("--------------- --------------- -----\n"); + slistLastShown = 0; +} + + +static void PrintSlist(void) +{ + int n; + + for (n = slistLastShown; n < hostCacheCount; n++) + { + if (hostcache[n].maxusers) + Con_Printf("%-15.15s %-15.15s %2u/%2u\n", hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers); + else + Con_Printf("%-15.15s %-15.15s\n", hostcache[n].name, hostcache[n].map); + } + slistLastShown = n; +} + + +static void PrintSlistTrailer(void) +{ + if (hostCacheCount) + Con_Printf("== end list ==\n\n"); + else + Con_Printf("No Quake servers found.\n\n"); +} + + +void NET_Slist_f (void) +{ + if (slistInProgress) + return; + + if (! slistSilent) + { + if (kurok) + Con_Printf("Looking for Kurok servers...\n"); + else + Con_Printf("Looking for Quake servers...\n"); + PrintSlistHeader(); + } + + slistInProgress = true; + slistStartTime = Sys_FloatTime(); + + SchedulePollProcedure(&slistSendProcedure, 0.0); + SchedulePollProcedure(&slistPollProcedure, 0.1); + + hostCacheCount = 0; +} + + +static void Slist_Send(void) +{ + for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++) + { + if (!slistLocal && net_driverlevel == 0) + continue; + if (net_drivers[net_driverlevel].initialized == false) + continue; + dfunc.SearchForHosts (true); + } + + if ((Sys_FloatTime() - slistStartTime) < 0.5) + SchedulePollProcedure(&slistSendProcedure, 0.75); +} + + +static void Slist_Poll(void) +{ + for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++) + { + if (!slistLocal && net_driverlevel == 0) + continue; + if (net_drivers[net_driverlevel].initialized == false) + continue; + dfunc.SearchForHosts (false); + } + + if (! slistSilent) + PrintSlist(); + + if ((Sys_FloatTime() - slistStartTime) < 1.5) + { + SchedulePollProcedure(&slistPollProcedure, 0.1); + return; + } + + if (! slistSilent) + PrintSlistTrailer(); + slistInProgress = false; + slistSilent = false; + slistLocal = true; +} + + +/* +=================== +NET_Connect +=================== +*/ + +int hostCacheCount = 0; +hostcache_t hostcache[HOSTCACHESIZE]; + +qsocket_t *NET_Connect (char *host) +{ + qsocket_t *ret; + int n; + int numdrivers = net_numdrivers; + + SetNetTime(); + + if (host && *host == 0) + host = NULL; + + if (host) + { + if (Q_strcasecmp (host, "local") == 0) + { + numdrivers = 1; + goto JustDoIt; + } + + if (hostCacheCount) + { + for (n = 0; n < hostCacheCount; n++) + if (Q_strcasecmp (host, hostcache[n].name) == 0) + { + host = hostcache[n].cname; + break; + } + if (n < hostCacheCount) + goto JustDoIt; + } + } + + slistSilent = host ? true : false; + NET_Slist_f (); + + while(slistInProgress) + NET_Poll(); + + if (host == NULL) + { + if (hostCacheCount != 1) + return NULL; + host = hostcache[0].cname; + Con_Printf("Connecting to...\n%s @ %s\n\n", hostcache[0].name, host); + } + + if (hostCacheCount) + for (n = 0; n < hostCacheCount; n++) + if (Q_strcasecmp (host, hostcache[n].name) == 0) + { + host = hostcache[n].cname; + break; + } + +JustDoIt: + for (net_driverlevel=0 ; net_driverleveladdress, NET_NAMELEN); + } + return ret; + } + } + + if (recording) + { + vcrConnect.time = host_time; + vcrConnect.op = VCR_OP_CONNECT; + vcrConnect.session = 0; + Sys_FileWrite (vcrFile, &vcrConnect, sizeof(vcrConnect)); + } + + return NULL; +} + +/* +=================== +NET_Close +=================== +*/ +void NET_Close (qsocket_t *sock) +{ + if (!sock) + return; + + if (sock->disconnected) + return; + + SetNetTime(); + + // call the driver_Close function + sfunc.Close (sock); + + NET_FreeQSocket(sock); +} + + +/* +================= +NET_GetMessage + +If there is a complete message, return it in net_message + +returns 0 if no data is waiting +returns 1 if a message was received +returns -1 if connection is invalid +================= +*/ + +struct +{ + double time; + int op; + long session; + int ret; + int len; +} vcrGetMessage; + +extern void PrintStats(qsocket_t *s); + +int NET_GetMessage (qsocket_t *sock) +{ + int ret; + + if (!sock) + return -1; + + if (sock->disconnected) + { + Con_Printf("NET_GetMessage: disconnected socket\n"); + return -1; + } + + SetNetTime(); + + ret = sfunc.QGetMessage(sock); + + // see if this connection has timed out + if (ret == 0 && sock->driver) + { + if (net_time - sock->lastMessageTime > net_messagetimeout.value) + { + NET_Close(sock); + return -1; + } + } + + + if (ret > 0) + { + if (sock->driver) + { + sock->lastMessageTime = net_time; + if (ret == 1) + messagesReceived++; + else if (ret == 2) + unreliableMessagesReceived++; + } + + if (recording) + { + vcrGetMessage.time = host_time; + vcrGetMessage.op = VCR_OP_GETMESSAGE; + vcrGetMessage.session = (long)sock; + vcrGetMessage.ret = ret; + vcrGetMessage.len = net_message.cursize; + Sys_FileWrite (vcrFile, &vcrGetMessage, 24); + Sys_FileWrite (vcrFile, net_message.data, net_message.cursize); + } + } + else + { + if (recording) + { + vcrGetMessage.time = host_time; + vcrGetMessage.op = VCR_OP_GETMESSAGE; + vcrGetMessage.session = (long)sock; + vcrGetMessage.ret = ret; + Sys_FileWrite (vcrFile, &vcrGetMessage, 20); + } + } + + return ret; +} + + +/* +================== +NET_SendMessage + +Try to send a complete length+message unit over the reliable stream. +returns 0 if the message cannot be delivered reliably, but the connection + is still considered valid +returns 1 if the message was sent properly +returns -1 if the connection died +================== +*/ +struct +{ + double time; + int op; + long session; + int r; +} vcrSendMessage; + +int NET_SendMessage (qsocket_t *sock, sizebuf_t *data) +{ + int r; + + if (!sock) + return -1; + + if (sock->disconnected) + { + Con_Printf("NET_SendMessage: disconnected socket\n"); + return -1; + } + + SetNetTime(); + r = sfunc.QSendMessage(sock, data); + if (r == 1 && sock->driver) + messagesSent++; + + if (recording) + { + vcrSendMessage.time = host_time; + vcrSendMessage.op = VCR_OP_SENDMESSAGE; + vcrSendMessage.session = (long)sock; + vcrSendMessage.r = r; + Sys_FileWrite (vcrFile, &vcrSendMessage, 20); + } + + return r; +} + + +int NET_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) +{ + int r; + + if (!sock) + return -1; + + if (sock->disconnected) + { + Con_Printf("NET_SendMessage: disconnected socket\n"); + return -1; + } + + SetNetTime(); + r = sfunc.SendUnreliableMessage(sock, data); + if (r == 1 && sock->driver) + unreliableMessagesSent++; + + if (recording) + { + vcrSendMessage.time = host_time; + vcrSendMessage.op = VCR_OP_SENDMESSAGE; + vcrSendMessage.session = (long)sock; + vcrSendMessage.r = r; + Sys_FileWrite (vcrFile, &vcrSendMessage, 20); + } + + return r; +} + + +/* +================== +NET_CanSendMessage + +Returns true or false if the given qsocket can currently accept a +message to be transmitted. +================== +*/ +qboolean NET_CanSendMessage (qsocket_t *sock) +{ + int r; + + if (!sock) + return false; + + if (sock->disconnected) + return false; + + SetNetTime(); + + r = sfunc.CanSendMessage(sock); + + if (recording) + { + vcrSendMessage.time = host_time; + vcrSendMessage.op = VCR_OP_CANSENDMESSAGE; + vcrSendMessage.session = (long)sock; + vcrSendMessage.r = r; + Sys_FileWrite (vcrFile, &vcrSendMessage, 20); + } + + return r; +} + + +int NET_SendToAll(sizebuf_t *data, int blocktime) +{ + double start; + int i; + int count = 0; + qboolean state1 [MAX_SCOREBOARD]; + qboolean state2 [MAX_SCOREBOARD]; + + for (i=0, host_client = svs.clients ; inetconnection) + continue; + if (host_client->active) + { + if (host_client->netconnection->driver == 0) + { + NET_SendMessage(host_client->netconnection, data); + state1[i] = true; + state2[i] = true; + continue; + } + count++; + state1[i] = false; + state2[i] = false; + } + else + { + state1[i] = true; + state2[i] = true; + } + } + + start = Sys_FloatTime(); + while (count) + { + count = 0; + for (i=0, host_client = svs.clients ; inetconnection)) + { + state1[i] = true; + NET_SendMessage(host_client->netconnection, data); + } + else + { + NET_GetMessage (host_client->netconnection); + } + count++; + continue; + } + + if (! state2[i]) + { + if (NET_CanSendMessage (host_client->netconnection)) + { + state2[i] = true; + } + else + { + NET_GetMessage (host_client->netconnection); + } + count++; + continue; + } + } + if ((Sys_FloatTime() - start) > blocktime) + break; + } + return count; +} + + +//============================================================================= + +/* +==================== +NET_Init +==================== +*/ + +void NET_Init (void) +{ + int i; + int controlSocket; + qsocket_t *s; + + if (COM_CheckParm("-playback")) + { + net_numdrivers = 1; + net_drivers[0].Init = VCR_Init; + } + + if (COM_CheckParm("-record")) + recording = true; + + i = COM_CheckParm ("-port"); + if (!i) + i = COM_CheckParm ("-udpport"); + if (!i) + i = COM_CheckParm ("-ipxport"); + + if (i) + { + if (i < com_argc-1) + DEFAULTnet_hostport = Q_atoi (com_argv[i+1]); + else + Sys_Error ("NET_Init: you must specify a number after -port"); + } + net_hostport = DEFAULTnet_hostport; + + if (COM_CheckParm("-listen") || cls.state == ca_dedicated) + listening = true; + net_numsockets = svs.maxclientslimit; + if (cls.state != ca_dedicated) + net_numsockets++; + + SetNetTime(); + + for (i = 0; i < net_numsockets; i++) + { + s = (qsocket_t *)Hunk_AllocName(sizeof(qsocket_t), "qsocket"); + s->next = net_freeSockets; + net_freeSockets = s; + s->disconnected = true; + } + + // allocate space for network message buffer + SZ_Alloc (&net_message, NET_MAXMESSAGE); + + Cvar_RegisterVariable (&net_messagetimeout); + Cvar_RegisterVariable (&hostname); + Cvar_RegisterVariable (&config_com_port); + Cvar_RegisterVariable (&config_com_irq); + Cvar_RegisterVariable (&config_com_baud); + Cvar_RegisterVariable (&config_com_modem); + Cvar_RegisterVariable (&config_modem_dialtype); + Cvar_RegisterVariable (&config_modem_clear); + Cvar_RegisterVariable (&config_modem_init); + Cvar_RegisterVariable (&config_modem_hangup); +#ifdef IDGODS + Cvar_RegisterVariable (&idgods); +#endif + + if(!host_initialized) + { + Cmd_AddCommand ("slist", NET_Slist_f); + Cmd_AddCommand ("listen", NET_Listen_f); + Cmd_AddCommand ("maxplayers", MaxPlayers_f); + Cmd_AddCommand ("port", NET_Port_f); + } + + // initialize all the drivers + for (net_driverlevel=0 ; net_driverlevelnext) + NET_Close(sock); + +// +// shutdown the drivers +// + for (net_driverlevel = 0; net_driverlevel < net_numdrivers; net_driverlevel++) + { + if (net_drivers[net_driverlevel].initialized == true) + { + net_drivers[net_driverlevel].Shutdown (); + net_drivers[net_driverlevel].initialized = false; + } + } + + if (vcrFile != -1) + { + Con_Printf ("Closing vcrfile.\n"); + Sys_FileClose(vcrFile); + } +} + + +static PollProcedure *pollProcedureList = NULL; + +void NET_Poll(void) +{ + PollProcedure *pp; + qboolean useModem; + + if (!configRestored) + { + if (serialAvailable) + { + if (config_com_modem.value == 1.0) + useModem = true; + else + useModem = false; + SetComPortConfig (0, (int)config_com_port.value, (int)config_com_irq.value, (int)config_com_baud.value, useModem); + SetModemConfig (0, config_modem_dialtype.string, config_modem_clear.string, config_modem_init.string, config_modem_hangup.string); + } + configRestored = true; + } + + SetNetTime(); + + for (pp = pollProcedureList; pp; pp = pp->next) + { + if (pp->nextTime > net_time) + break; + pollProcedureList = pp->next; + pp->procedure(pp->arg); + } +} + + +void SchedulePollProcedure(PollProcedure *proc, double timeOffset) +{ + PollProcedure *pp, *prev; + + proc->nextTime = Sys_FloatTime() + timeOffset; + for (pp = pollProcedureList, prev = NULL; pp; pp = pp->next) + { + if (pp->nextTime >= proc->nextTime) + break; + prev = pp; + } + + if (prev == NULL) + { + proc->next = pollProcedureList; + pollProcedureList = proc; + return; + } + + proc->next = pp; + prev->next = proc; +} + + +#ifdef IDGODS +#define IDNET 0xc0f62800 + +qboolean IsID(struct qsockaddr *addr) +{ + if (idgods.value == 0.0) + return false; + + if (addr->sa_family != 2) + return false; + + if ((BigLong(*(int *)&addr->sa_data[2]) & 0xffffff00) == IDNET) + return true; + return false; +} +#endif diff --git a/r17/Revamped src/revamped_src/net_none.c b/r17/Revamped src/revamped_src/net_none.c new file mode 100755 index 00000000..b6e69689 --- /dev/null +++ b/r17/Revamped src/revamped_src/net_none.c @@ -0,0 +1,46 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +#include "quakedef.h" + +#include "net_loop.h" + +net_driver_t net_drivers[MAX_NET_DRIVERS] = +{ + { + "Loopback", + false, + Loop_Init, + Loop_Listen, + Loop_SearchForHosts, + Loop_Connect, + Loop_CheckNewConnections, + Loop_GetMessage, + Loop_SendMessage, + Loop_SendUnreliableMessage, + Loop_CanSendMessage, + Loop_CanSendUnreliableMessage, + Loop_Close, + Loop_Shutdown + } +}; +int net_numdrivers = 1; + +net_landriver_t net_landrivers[MAX_NET_DRIVERS]; +int net_numlandrivers = 0; diff --git a/r17/Revamped src/revamped_src/net_vcr.c b/r17/Revamped src/revamped_src/net_vcr.c new file mode 100755 index 00000000..e22b9dc1 --- /dev/null +++ b/r17/Revamped src/revamped_src/net_vcr.c @@ -0,0 +1,167 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// net_vcr.c + +#include "quakedef.h" +#include "net_vcr.h" + +extern int vcrFile; + +// This is the playback portion of the VCR. It reads the file produced +// by the recorder and plays it back to the host. The recording contains +// everything necessary (events, timestamps, and data) to duplicate the game +// from the viewpoint of everything above the network layer. + +static struct +{ + double time; + int op; + long session; +} next; + +int VCR_Init (void) +{ + net_drivers[0].Init = VCR_Init; + + net_drivers[0].SearchForHosts = VCR_SearchForHosts; + net_drivers[0].Connect = VCR_Connect; + net_drivers[0].CheckNewConnections = VCR_CheckNewConnections; + net_drivers[0].QGetMessage = VCR_GetMessage; + net_drivers[0].QSendMessage = VCR_SendMessage; + net_drivers[0].CanSendMessage = VCR_CanSendMessage; + net_drivers[0].Close = VCR_Close; + net_drivers[0].Shutdown = VCR_Shutdown; + + Sys_FileRead(vcrFile, &next, sizeof(next)); + return 0; +} + +void VCR_ReadNext (void) +{ + if (Sys_FileRead(vcrFile, &next, sizeof(next)) == 0) + { + next.op = 255; + Sys_Error ("=== END OF PLAYBACK===\n"); + } + if (next.op < 1 || next.op > VCR_MAX_MESSAGE) + Sys_Error ("VCR_ReadNext: bad op"); +} + + +void VCR_Listen (qboolean state) +{ +} + + +void VCR_Shutdown (void) +{ +} + + +int VCR_GetMessage (qsocket_t *sock) +{ + int ret; + + if (host_time != next.time || next.op != VCR_OP_GETMESSAGE || next.session != *(long *)(&sock->driverdata)) + Sys_Error ("VCR missmatch"); + + Sys_FileRead(vcrFile, &ret, sizeof(int)); + if (ret != 1) + { + VCR_ReadNext (); + return ret; + } + + Sys_FileRead(vcrFile, &net_message.cursize, sizeof(int)); + Sys_FileRead(vcrFile, net_message.data, net_message.cursize); + + VCR_ReadNext (); + + return 1; +} + + +int VCR_SendMessage (qsocket_t *sock, sizebuf_t *data) +{ + int ret; + + if (host_time != next.time || next.op != VCR_OP_SENDMESSAGE || next.session != *(long *)(&sock->driverdata)) + Sys_Error ("VCR missmatch"); + + Sys_FileRead(vcrFile, &ret, sizeof(int)); + + VCR_ReadNext (); + + return ret; +} + + +qboolean VCR_CanSendMessage (qsocket_t *sock) +{ + qboolean ret; + + if (host_time != next.time || next.op != VCR_OP_CANSENDMESSAGE || next.session != *(long *)(&sock->driverdata)) + Sys_Error ("VCR missmatch"); + + Sys_FileRead(vcrFile, &ret, sizeof(int)); + + VCR_ReadNext (); + + return ret; +} + + +void VCR_Close (qsocket_t *sock) +{ +} + + +void VCR_SearchForHosts (qboolean xmit) +{ +} + + +qsocket_t *VCR_Connect (char *host) +{ + return NULL; +} + + +qsocket_t *VCR_CheckNewConnections (void) +{ + qsocket_t *sock; + + if (host_time != next.time || next.op != VCR_OP_CONNECT) + Sys_Error ("VCR missmatch"); + + if (!next.session) + { + VCR_ReadNext (); + return NULL; + } + + sock = NET_NewQSocket (); + *(long *)(&sock->driverdata) = next.session; + + Sys_FileRead (vcrFile, sock->address, NET_NAMELEN); + VCR_ReadNext (); + + return sock; +} diff --git a/r17/Revamped src/revamped_src/net_vcr.h b/r17/Revamped src/revamped_src/net_vcr.h new file mode 100755 index 00000000..23746974 --- /dev/null +++ b/r17/Revamped src/revamped_src/net_vcr.h @@ -0,0 +1,37 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// net_vcr.h + +#define VCR_OP_CONNECT 1 +#define VCR_OP_GETMESSAGE 2 +#define VCR_OP_SENDMESSAGE 3 +#define VCR_OP_CANSENDMESSAGE 4 +#define VCR_MAX_MESSAGE 4 + +int VCR_Init (void); +void VCR_Listen (qboolean state); +void VCR_SearchForHosts (qboolean xmit); +qsocket_t *VCR_Connect (char *host); +qsocket_t *VCR_CheckNewConnections (void); +int VCR_GetMessage (qsocket_t *sock); +int VCR_SendMessage (qsocket_t *sock, sizebuf_t *data); +qboolean VCR_CanSendMessage (qsocket_t *sock); +void VCR_Close (qsocket_t *sock); +void VCR_Shutdown (void); diff --git a/r17/Revamped src/revamped_src/nonintel.c b/r17/Revamped src/revamped_src/nonintel.c new file mode 100755 index 00000000..66a9d105 --- /dev/null +++ b/r17/Revamped src/revamped_src/nonintel.c @@ -0,0 +1,64 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// +// nonintel.c: code for non-Intel processors only +// + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" + +#if !id386 + +/* +================ +R_Surf8Patch +================ +*/ +void R_Surf8Patch () +{ + // we only patch code on Intel +} + + +/* +================ +R_Surf16Patch +================ +*/ +void R_Surf16Patch () +{ + // we only patch code on Intel +} + + +/* +================ +R_SurfacePatch +================ +*/ +void R_SurfacePatch (void) +{ + // we only patch code on Intel +} + + +#endif // !id386 + diff --git a/r17/Revamped src/revamped_src/pr_cmds.c b/r17/Revamped src/revamped_src/pr_cmds.c new file mode 100755 index 00000000..58c6f811 --- /dev/null +++ b/r17/Revamped src/revamped_src/pr_cmds.c @@ -0,0 +1,1940 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +#include "quakedef.h" + +#define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e)) + +/* +=============================================================================== + + BUILT-IN FUNCTIONS + +=============================================================================== +*/ + +char *PF_VarString (int first) +{ + int i; + static char out[256]; + + out[0] = 0; + for (i=first ; is_name,s); + ed = PROG_TO_EDICT(pr_global_struct->self); + ED_Print (ed); + + Host_Error ("Program error"); +} + +/* +================= +PF_objerror + +Dumps out self, then an error message. The program is aborted and self is +removed, but the level can continue. + +objerror(value) +================= +*/ +void PF_objerror (void) +{ + char *s; + edict_t *ed; + + s = PF_VarString(0); + Con_Printf ("======OBJECT ERROR in %s:\n%s\n" + ,pr_strings + pr_xfunction->s_name,s); + ed = PROG_TO_EDICT(pr_global_struct->self); + ED_Print (ed); + ED_Free (ed); + + Host_Error ("Program error"); +} + + + +/* +============== +PF_makevectors + +Writes new values for v_forward, v_up, and v_right based on angles +makevectors(vector) +============== +*/ +void PF_makevectors (void) +{ + AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up); +} + +/* +================= +PF_setorigin + +This is the only valid way to move an object without using the physics of the world (setting velocity and waiting). Directly changing origin will not set internal links correctly, so clipping would be messed up. This should be called when an object is spawned, and then only if it is teleported. + +setorigin (entity, origin) +================= +*/ +void PF_setorigin (void) +{ + edict_t *e; + float *org; + + e = G_EDICT(OFS_PARM0); + org = G_VECTOR(OFS_PARM1); + VectorCopy (org, e->v.origin); + SV_LinkEdict (e, false); +} + + +void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) +{ + float *angles; + vec3_t rmin, rmax; + float bounds[2][3]; + float xvector[2], yvector[2]; + float a; + vec3_t base, transformed; + int i, j, k, l; + + for (i=0 ; i<3 ; i++) + if (min[i] > max[i]) + PR_RunError ("backwards mins/maxs"); + + rotate = false; // FIXME: implement rotation properly again + + if (!rotate) + { + VectorCopy (min, rmin); + VectorCopy (max, rmax); + } + else + { + // find min / max for rotations + angles = e->v.angles; + + a = angles[1]/180 * M_PI; + + xvector[0] = cosf(a); + xvector[1] = sinf(a); + yvector[0] = -sinf(a); + yvector[1] = cosf(a); + + VectorCopy (min, bounds[0]); + VectorCopy (max, bounds[1]); + + rmin[0] = rmin[1] = rmin[2] = 9999; + rmax[0] = rmax[1] = rmax[2] = -9999; + + for (i=0 ; i<= 1 ; i++) + { + base[0] = bounds[i][0]; + for (j=0 ; j<= 1 ; j++) + { + base[1] = bounds[j][1]; + for (k=0 ; k<= 1 ; k++) + { + base[2] = bounds[k][2]; + + // transform the point + transformed[0] = xvector[0]*base[0] + yvector[0]*base[1]; + transformed[1] = xvector[1]*base[0] + yvector[1]*base[1]; + transformed[2] = base[2]; + + for (l=0 ; l<3 ; l++) + { + if (transformed[l] < rmin[l]) + rmin[l] = transformed[l]; + if (transformed[l] > rmax[l]) + rmax[l] = transformed[l]; + } + } + } + } + } + +// set derived values + VectorCopy (rmin, e->v.mins); + VectorCopy (rmax, e->v.maxs); + VectorSubtract (max, min, e->v.size); + + SV_LinkEdict (e, false); +} + +/* +================= +PF_setsize + +the size box is rotated by the current angle + +setsize (entity, minvector, maxvector) +================= +*/ +void PF_setsize (void) +{ + edict_t *e; + float *min, *max; + + e = G_EDICT(OFS_PARM0); + min = G_VECTOR(OFS_PARM1); + max = G_VECTOR(OFS_PARM2); + SetMinMaxSize (e, min, max, false); +} + + +/* +================= +PF_setmodel + +setmodel(entity, model) +================= +*/ +void PF_setmodel (void) +{ + edict_t *e; + char *m, **check; + model_t *mod; + int i; + + e = G_EDICT(OFS_PARM0); + m = G_STRING(OFS_PARM1); + +// check to see if model was properly precached + for (i=0, check = sv.model_precache ; *check ; i++, check++) + if (!strcmp(*check, m)) + break; + + if (!*check) + PR_RunError ("no precache: %s\n", m); + + + e->v.model = m - pr_strings; + e->v.modelindex = i; //SV_ModelIndex (m); + + mod = sv.models[ (int)e->v.modelindex]; // Mod_ForName (m, true); + + if (mod) + SetMinMaxSize (e, mod->mins, mod->maxs, true); + else + SetMinMaxSize (e, vec3_origin, vec3_origin, true); +} + +/* +================= +PF_bprint + +broadcast print to everyone on server + +bprint(value) +================= +*/ +void PF_bprint (void) +{ + char *s; + + s = PF_VarString(0); + SV_BroadcastPrintf ("%s", s); +} + +/* +================= +PF_sprint + +single print to a specific client + +sprint(clientent, value) +================= +*/ +void PF_sprint (void) +{ + char *s; + client_t *client; + int entnum; + + entnum = G_EDICTNUM(OFS_PARM0); + s = PF_VarString(1); + + if (entnum < 1 || entnum > svs.maxclients) + { + Con_Printf ("tried to sprint to a non-client\n"); + return; + } + + client = &svs.clients[entnum-1]; + + MSG_WriteChar (&client->message,svc_print); + MSG_WriteString (&client->message, s ); +} + + +/* +================= +PF_centerprint + +single print to a specific client + +centerprint(clientent, value) +================= +*/ +void PF_centerprint (void) +{ + char *s; + client_t *client; + int entnum; + + entnum = G_EDICTNUM(OFS_PARM0); + s = PF_VarString(1); + + if (entnum < 1 || entnum > svs.maxclients) + { + Con_Printf ("tried to sprint to a non-client\n"); + return; + } + + client = &svs.clients[entnum-1]; + + MSG_WriteChar (&client->message,svc_centerprint); + MSG_WriteString (&client->message, s ); +} + + +/* +================= +PF_normalize + +vector normalize(vector) +================= +*/ +void PF_normalize (void) +{ + float *value1; + vec3_t newvalue; + float new; + + value1 = G_VECTOR(OFS_PARM0); + + new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2]; + new = sqrtf(new); + + if (new == 0) + newvalue[0] = newvalue[1] = newvalue[2] = 0; + else + { + new = 1/new; + newvalue[0] = value1[0] * new; + newvalue[1] = value1[1] * new; + newvalue[2] = value1[2] * new; + } + + VectorCopy (newvalue, G_VECTOR(OFS_RETURN)); +} + +/* +================= +PF_vlen + +scalar vlen(vector) +================= +*/ +void PF_vlen (void) +{ + float *value1; + float new; + + value1 = G_VECTOR(OFS_PARM0); + + new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2]; + new = sqrtf(new); + + G_FLOAT(OFS_RETURN) = new; +} + +/* +================= +PF_vectoyaw + +float vectoyaw(vector) +================= +*/ +void PF_vectoyaw (void) +{ + float *value1; + float yaw; + + value1 = G_VECTOR(OFS_PARM0); + + if (value1[1] == 0 && value1[0] == 0) + yaw = 0; + else + { + yaw = (int) (atan2f(value1[1], value1[0]) * 180 / M_PI); + if (yaw < 0) + yaw += 360; + } + + G_FLOAT(OFS_RETURN) = yaw; +} + + +/* +================= +PF_vectoangles + +vector vectoangles(vector) +================= +*/ +void PF_vectoangles (void) +{ + float *value1; + float forward; + float yaw, pitch; + + value1 = G_VECTOR(OFS_PARM0); + + if (value1[1] == 0 && value1[0] == 0) + { + yaw = 0; + if (value1[2] > 0) + pitch = 90; + else + pitch = 270; + } + else + { + yaw = (int) (atan2f(value1[1], value1[0]) * 180 / M_PI); + if (yaw < 0) + yaw += 360; + + forward = sqrtf (value1[0]*value1[0] + value1[1]*value1[1]); + pitch = (int) (atan2f(value1[2], forward) * 180 / M_PI); + if (pitch < 0) + pitch += 360; + } + + G_FLOAT(OFS_RETURN+0) = pitch; + G_FLOAT(OFS_RETURN+1) = yaw; + G_FLOAT(OFS_RETURN+2) = 0; +} + +/* +================= +PF_Random + +Returns a number from 0<= num < 1 + +random() +================= +*/ +void PF_random (void) +{ + float num; + + num = (rand ()&0x7fff) / ((float)0x7fff); + + G_FLOAT(OFS_RETURN) = num; +} + +/* +================= +PF_particle + +particle(origin, color, count) +================= +*/ +void PF_particle (void) +{ + float *org, *dir; + float color; + float count; + + org = G_VECTOR(OFS_PARM0); + dir = G_VECTOR(OFS_PARM1); + color = G_FLOAT(OFS_PARM2); + count = G_FLOAT(OFS_PARM3); + SV_StartParticle (org, dir, color, count); +} + + +/* +================= +PF_ambientsound + +================= +*/ +void PF_ambientsound (void) +{ + char **check; + char *samp; + float *pos; + float vol, attenuation; + int i, soundnum; + + pos = G_VECTOR (OFS_PARM0); + samp = G_STRING(OFS_PARM1); + vol = G_FLOAT(OFS_PARM2); + attenuation = G_FLOAT(OFS_PARM3); + +// check to see if samp was properly precached + for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++) + if (!strcmp(*check,samp)) + break; + + if (!*check) + { + Con_Printf ("no precache: %s\n", samp); + return; + } + +// add an svc_spawnambient command to the level signon packet + + MSG_WriteByte (&sv.signon,svc_spawnstaticsound); + for (i=0 ; i<3 ; i++) + MSG_WriteCoord(&sv.signon, pos[i]); + + MSG_WriteByte (&sv.signon, soundnum); + + MSG_WriteByte (&sv.signon, vol*255); + MSG_WriteByte (&sv.signon, attenuation*64); + +} + +/* +================= +PF_sound + +Each entity can have eight independant sound sources, like voice, +weapon, feet, etc. + +Channel 0 is an auto-allocate channel, the others override anything +allready running on that entity/channel pair. + +An attenuation of 0 will play full volume everywhere in the level. +Larger attenuations will drop off. + +================= +*/ +void PF_sound (void) +{ + char *sample; + int channel; + edict_t *entity; + int volume; + float attenuation; + + entity = G_EDICT(OFS_PARM0); + channel = G_FLOAT(OFS_PARM1); + sample = G_STRING(OFS_PARM2); + volume = G_FLOAT(OFS_PARM3) * 255; + attenuation = G_FLOAT(OFS_PARM4); + + if (volume < 0 || volume > 255) + Sys_Error ("SV_StartSound: volume = %i", volume); + + if (attenuation < 0 || attenuation > 4) + Sys_Error ("SV_StartSound: attenuation = %f", attenuation); + + if (channel < 0 || channel > 7) + Sys_Error ("SV_StartSound: channel = %i", channel); + + SV_StartSound (entity, channel, sample, volume, attenuation); +} + +/* +================= +PF_break + +break() +================= +*/ +void PF_break (void) +{ +Con_Printf ("break statement\n"); +*(int *)-4 = 0; // dump to debugger +// PR_RunError ("break statement"); +} + +/* +================= +PF_traceline + +Used for use tracing and shot targeting +Traces are blocked by bbox and exact bsp entityes, and also slide box entities +if the tryents flag is set. + +traceline (vector1, vector2, tryents) +================= +*/ +void PF_traceline (void) +{ + float *v1, *v2; + trace_t trace; + int nomonsters; + edict_t *ent; + + v1 = G_VECTOR(OFS_PARM0); + v2 = G_VECTOR(OFS_PARM1); + nomonsters = G_FLOAT(OFS_PARM2); + ent = G_EDICT(OFS_PARM3); + + trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent); + + pr_global_struct->trace_allsolid = trace.allsolid; + pr_global_struct->trace_startsolid = trace.startsolid; + pr_global_struct->trace_fraction = trace.fraction; + pr_global_struct->trace_inwater = trace.inwater; + pr_global_struct->trace_inopen = trace.inopen; + VectorCopy (trace.endpos, pr_global_struct->trace_endpos); + VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal); + pr_global_struct->trace_plane_dist = trace.plane.dist; + if (trace.ent) + pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent); + else + pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts); +} + + +#ifdef QUAKE2 +extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore); + +void PF_TraceToss (void) +{ + trace_t trace; + edict_t *ent; + edict_t *ignore; + + ent = G_EDICT(OFS_PARM0); + ignore = G_EDICT(OFS_PARM1); + + trace = SV_Trace_Toss (ent, ignore); + + pr_global_struct->trace_allsolid = trace.allsolid; + pr_global_struct->trace_startsolid = trace.startsolid; + pr_global_struct->trace_fraction = trace.fraction; + pr_global_struct->trace_inwater = trace.inwater; + pr_global_struct->trace_inopen = trace.inopen; + VectorCopy (trace.endpos, pr_global_struct->trace_endpos); + VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal); + pr_global_struct->trace_plane_dist = trace.plane.dist; + if (trace.ent) + pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent); + else + pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts); +} +#endif + + +/* +================= +PF_checkpos + +Returns true if the given entity can move to the given position from it's +current position by walking or rolling. +FIXME: make work... +scalar checkpos (entity, vector) +================= +*/ +void PF_checkpos (void) +{ +} + +//============================================================================ + +byte checkpvs[MAX_MAP_LEAFS/8]; + +int PF_newcheckclient (int check) +{ + int i; + byte *pvs; + edict_t *ent; + mleaf_t *leaf; + vec3_t org; + +// cycle to the next one + + if (check < 1) + check = 1; + if (check > svs.maxclients) + check = svs.maxclients; + + if (check == svs.maxclients) + i = 1; + else + i = check + 1; + + for ( ; ; i++) + { + if (i == svs.maxclients+1) + i = 1; + + ent = EDICT_NUM(i); + + if (i == check) + break; // didn't find anything else + + if (ent->free) + continue; + if (ent->v.health <= 0) + continue; + if ((int)ent->v.flags & FL_NOTARGET) + continue; + + // anything that is a client, or has a client as an enemy + break; + } + +// get the PVS for the entity + VectorAdd (ent->v.origin, ent->v.view_ofs, org); + leaf = Mod_PointInLeaf (org, sv.worldmodel); + pvs = Mod_LeafPVS (leaf, sv.worldmodel); + memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 ); + + return i; +} + +/* +================= +PF_checkclient + +Returns a client (or object that has a client enemy) that would be a +valid target. + +If there are more than one valid options, they are cycled each frame + +If (self.origin + self.viewofs) is not in the PVS of the current target, +it is not returned at all. + +name checkclient () +================= +*/ +#define MAX_CHECK 16 +int c_invis, c_notvis; +void PF_checkclient (void) +{ + edict_t *ent, *self; + mleaf_t *leaf; + int l; + vec3_t view; + +// find a new check if on a new frame + if (sv.time - sv.lastchecktime >= 0.1) + { + sv.lastcheck = PF_newcheckclient (sv.lastcheck); + sv.lastchecktime = sv.time; + } + +// return check if it might be visible + ent = EDICT_NUM(sv.lastcheck); + if (ent->free || ent->v.health <= 0) + { + RETURN_EDICT(sv.edicts); + return; + } + +// if current entity can't possibly see the check entity, return 0 + self = PROG_TO_EDICT(pr_global_struct->self); + VectorAdd (self->v.origin, self->v.view_ofs, view); + leaf = Mod_PointInLeaf (view, sv.worldmodel); + l = (leaf - sv.worldmodel->leafs) - 1; + if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) ) + { +c_notvis++; + RETURN_EDICT(sv.edicts); + return; + } + +// might be able to see it +c_invis++; + RETURN_EDICT(ent); +} + +//============================================================================ + + +/* +================= +PF_stuffcmd + +Sends text over to the client's execution buffer + +stuffcmd (clientent, value) +================= +*/ +void PF_stuffcmd (void) +{ + int entnum; + char *str; + client_t *old; + + entnum = G_EDICTNUM(OFS_PARM0); + if (entnum < 1 || entnum > svs.maxclients) + PR_RunError ("Parm 0 not a client"); + str = G_STRING(OFS_PARM1); + + old = host_client; + host_client = &svs.clients[entnum-1]; + Host_ClientCommands ("%s", str); + host_client = old; +} + +/* +================= +PF_localcmd + +Sends text over to the client's execution buffer + +localcmd (string) +================= +*/ +void PF_localcmd (void) +{ + char *str; + + str = G_STRING(OFS_PARM0); + Cbuf_AddText (str); +} + +/* +================= +PF_cvar + +float cvar (string) +================= +*/ +void PF_cvar (void) +{ + char *str; + + str = G_STRING(OFS_PARM0); + + G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str); +} + +/* +================= +PF_cvar_set + +float cvar (string) +================= +*/ +void PF_cvar_set (void) +{ + char *var, *val; + + var = G_STRING(OFS_PARM0); + val = G_STRING(OFS_PARM1); + + Cvar_Set (var, val); +} + +/* +================= +PF_findradius + +Returns a chain of entities that have origins within a spherical area + +findradius (origin, radius) +================= +*/ +void PF_findradius (void) +{ + edict_t *ent, *chain; + float rad; + float *org; + vec3_t eorg; + int i, j; + + chain = (edict_t *)sv.edicts; + + org = G_VECTOR(OFS_PARM0); + rad = G_FLOAT(OFS_PARM1); + + ent = NEXT_EDICT(sv.edicts); + for (i=1 ; ifree) + continue; + if (ent->v.solid == SOLID_NOT) + continue; + for (j=0 ; j<3 ; j++) + eorg[j] = org[j] - (ent->v.origin[j] + (ent->v.mins[j] + ent->v.maxs[j])*0.5); + if (Length(eorg) > rad) + continue; + + ent->v.chain = EDICT_TO_PROG(chain); + chain = ent; + } + + RETURN_EDICT(chain); +} + + +/* +========= +PF_dprint +========= +*/ +void PF_dprint (void) +{ + Con_DPrintf ("%s",PF_VarString(0)); +} + +char pr_string_temp[128]; + +void PF_ftos (void) +{ + float v; + v = G_FLOAT(OFS_PARM0); + + if (v == (int)v) + sprintf (pr_string_temp, "%d",(int)v); + else +// sprintf (pr_string_temp, "%5.1f",v); + sprintf (pr_string_temp, "%1f",v); + G_INT(OFS_RETURN) = pr_string_temp - pr_strings; +} + +void PF_fabs (void) +{ + float v; + v = G_FLOAT(OFS_PARM0); + G_FLOAT(OFS_RETURN) = fabsf(v); +} + +void PF_vtos (void) +{ + sprintf (pr_string_temp, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]); + G_INT(OFS_RETURN) = pr_string_temp - pr_strings; +} + +#ifdef QUAKE2 +void PF_etos (void) +{ + sprintf (pr_string_temp, "entity %i", G_EDICTNUM(OFS_PARM0)); + G_INT(OFS_RETURN) = pr_string_temp - pr_strings; +} +#endif + +void PF_Spawn (void) +{ + edict_t *ed; + ed = ED_Alloc(); + RETURN_EDICT(ed); +} + +void PF_Remove (void) +{ + edict_t *ed; + + ed = G_EDICT(OFS_PARM0); + ED_Free (ed); +} + + +// entity (entity start, .string field, string match) find = #5; +void PF_Find (void) +#ifdef QUAKE2 +{ + int e; + int f; + char *s, *t; + edict_t *ed; + edict_t *first; + edict_t *second; + edict_t *last; + + first = second = last = (edict_t *)sv.edicts; + e = G_EDICTNUM(OFS_PARM0); + f = G_INT(OFS_PARM1); + s = G_STRING(OFS_PARM2); + if (!s) + PR_RunError ("PF_Find: bad search string"); + + for (e++ ; e < sv.num_edicts ; e++) + { + ed = EDICT_NUM(e); + if (ed->free) + continue; + t = E_STRING(ed,f); + if (!t) + continue; + if (!strcmp(t,s)) + { + if (first == (edict_t *)sv.edicts) + first = ed; + else if (second == (edict_t *)sv.edicts) + second = ed; + ed->v.chain = EDICT_TO_PROG(last); + last = ed; + } + } + + if (first != last) + { + if (last != second) + first->v.chain = last->v.chain; + else + first->v.chain = EDICT_TO_PROG(last); + last->v.chain = EDICT_TO_PROG((edict_t *)sv.edicts); + if (second && second != last) + second->v.chain = EDICT_TO_PROG(last); + } + RETURN_EDICT(first); +} +#else +{ + int e; + int f; + char *s, *t; + edict_t *ed; + + e = G_EDICTNUM(OFS_PARM0); + f = G_INT(OFS_PARM1); + s = G_STRING(OFS_PARM2); + if (!s) + PR_RunError ("PF_Find: bad search string"); + + for (e++ ; e < sv.num_edicts ; e++) + { + ed = EDICT_NUM(e); + if (ed->free) + continue; + t = E_STRING(ed,f); + if (!t) + continue; + if (!strcmp(t,s)) + { + RETURN_EDICT(ed); + return; + } + } + + RETURN_EDICT(sv.edicts); +} +#endif + +void PR_CheckEmptyString (char *s) +{ + if (s[0] <= ' ') + PR_RunError ("Bad string"); +} + +void PF_precache_file (void) +{ // precache_file is only used to copy files with qcc, it does nothing + G_INT(OFS_RETURN) = G_INT(OFS_PARM0); +} + +void PF_precache_sound (void) +{ + char *s; + int i; + + if (sv.state != ss_loading) + PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions"); + + s = G_STRING(OFS_PARM0); + G_INT(OFS_RETURN) = G_INT(OFS_PARM0); + PR_CheckEmptyString (s); + + for (i=0 ; iself); + yaw = G_FLOAT(OFS_PARM0); + dist = G_FLOAT(OFS_PARM1); + + if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) ) + { + G_FLOAT(OFS_RETURN) = 0; + return; + } + + yaw = yaw*M_PI*2 / 360; + + move[0] = cosf(yaw)*dist; + move[1] = sinf(yaw)*dist; + move[2] = 0; + +// save program state, because SV_movestep may call other progs + oldf = pr_xfunction; + oldself = pr_global_struct->self; + + G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true); + + +// restore program state + pr_xfunction = oldf; + pr_global_struct->self = oldself; +} + +/* +=============== +PF_droptofloor + +void() droptofloor +=============== +*/ +void PF_droptofloor (void) +{ + edict_t *ent; + vec3_t end; + trace_t trace; + + ent = PROG_TO_EDICT(pr_global_struct->self); + + VectorCopy (ent->v.origin, end); + end[2] -= 256; + + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent); + + if (trace.fraction == 1 || trace.allsolid) + G_FLOAT(OFS_RETURN) = 0; + else + { + VectorCopy (trace.endpos, ent->v.origin); + SV_LinkEdict (ent, false); + ent->v.flags = (int)ent->v.flags | FL_ONGROUND; + ent->v.groundentity = EDICT_TO_PROG(trace.ent); + G_FLOAT(OFS_RETURN) = 1; + } +} + +/* +=============== +PF_lightstyle + +void(float style, string value) lightstyle +=============== +*/ +void PF_lightstyle (void) +{ + int style; + char *val; + client_t *client; + int j; + + style = G_FLOAT(OFS_PARM0); + val = G_STRING(OFS_PARM1); + +// change the string in sv + sv.lightstyles[style] = val; + +// send message to all clients on this server + if (sv.state != ss_active) + return; + + for (j=0, client = svs.clients ; jactive || client->spawned) + { + MSG_WriteChar (&client->message, svc_lightstyle); + MSG_WriteChar (&client->message,style); + MSG_WriteString (&client->message, val); + } +} + +void PF_rint (void) +{ + float f; + f = G_FLOAT(OFS_PARM0); + if (f > 0) + G_FLOAT(OFS_RETURN) = (int)(f + 0.5); + else + G_FLOAT(OFS_RETURN) = (int)(f - 0.5); +} +void PF_floor (void) +{ + G_FLOAT(OFS_RETURN) = floorf(G_FLOAT(OFS_PARM0)); +} +void PF_ceil (void) +{ + G_FLOAT(OFS_RETURN) = ceilf(G_FLOAT(OFS_PARM0)); +} + + +/* +============= +PF_checkbottom +============= +*/ +void PF_checkbottom (void) +{ + edict_t *ent; + + ent = G_EDICT(OFS_PARM0); + + G_FLOAT(OFS_RETURN) = SV_CheckBottom (ent); +} + +/* +============= +PF_pointcontents +============= +*/ +void PF_pointcontents (void) +{ + float *v; + + v = G_VECTOR(OFS_PARM0); + + G_FLOAT(OFS_RETURN) = SV_PointContents (v); +} + +/* +============= +PF_nextent + +entity nextent(entity) +============= +*/ +void PF_nextent (void) +{ + int i; + edict_t *ent; + + i = G_EDICTNUM(OFS_PARM0); + while (1) + { + i++; + if (i == sv.num_edicts) + { + RETURN_EDICT(sv.edicts); + return; + } + ent = EDICT_NUM(i); + if (!ent->free) + { + RETURN_EDICT(ent); + return; + } + } +} + +/* +============= +PF_aim + +Pick a vector for the player to shoot along +vector aim(entity, missilespeed) +============= +*/ +cvar_t sv_aim = {"sv_aim", "0.99"}; +void PF_aim (void) +{ + edict_t *ent, *check, *bestent; + vec3_t start, dir, end, bestdir; + int i, j; + trace_t tr; + float dist, bestdist; + float speed; + + ent = G_EDICT(OFS_PARM0); + speed = G_FLOAT(OFS_PARM1); + + VectorCopy (ent->v.origin, start); + start[2] += 20; + +// try sending a trace straight + VectorCopy (pr_global_struct->v_forward, dir); + VectorMA (start, 2048, dir, end); + tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent); + if (tr.ent && tr.ent->v.takedamage == DAMAGE_AIM + && (!teamplay.value || ent->v.team <=0 || ent->v.team != tr.ent->v.team) ) + { + VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN)); + return; + } + + +// try all possible entities + VectorCopy (dir, bestdir); + if (cl_autoaim.value) + bestdist = sv_aim.value; + else + bestdist = 1; + bestent = NULL; + + check = NEXT_EDICT(sv.edicts); + for (i=1 ; iv.takedamage != DAMAGE_AIM) + continue; + if (check == ent) + continue; + if (teamplay.value && ent->v.team > 0 && ent->v.team == check->v.team) + continue; // don't aim at teammate + for (j=0 ; j<3 ; j++) + end[j] = check->v.origin[j] + + 0.5*(check->v.mins[j] + check->v.maxs[j]); + VectorSubtract (end, start, dir); + VectorNormalize (dir); + dist = DotProduct (dir, pr_global_struct->v_forward); + if (dist < bestdist) + continue; // to far to turn + tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent); + if (tr.ent == check) + { // can shoot at this one + bestdist = dist; + bestent = check; + } + } + + if (bestent) + { + VectorSubtract (bestent->v.origin, ent->v.origin, dir); +// dist = DotProduct (dir, pr_global_struct->v_forward); +// VectorScale (pr_global_struct->v_forward, dist, end); + end[0] = dir[0]; + end[1] = dir[1]; + end[2] = dir[2]; + VectorNormalize (end); + VectorCopy (end, G_VECTOR(OFS_RETURN)); + } + else + { + VectorCopy (bestdir, G_VECTOR(OFS_RETURN)); + } +} + +/* +============== +PF_changeyaw + +This was a major timewaster in progs, so it was converted to C +============== +*/ +void PF_changeyaw (void) +{ + edict_t *ent; + float ideal, current, move, speed; + + ent = PROG_TO_EDICT(pr_global_struct->self); + current = anglemod( ent->v.angles[1] ); + ideal = ent->v.ideal_yaw; + speed = ent->v.yaw_speed; + + if (current == ideal) + return; + move = ideal - current; + if (ideal > current) + { + if (move >= 180) + move = move - 360; + } + else + { + if (move <= -180) + move = move + 360; + } + if (move > 0) + { + if (move > speed) + move = speed; + } + else + { + if (move < -speed) + move = -speed; + } + + ent->v.angles[1] = anglemod (current + move); +} + +#ifdef QUAKE2 +/* +============== +PF_changepitch +============== +*/ +void PF_changepitch (void) +{ + edict_t *ent; + float ideal, current, move, speed; + + ent = G_EDICT(OFS_PARM0); + current = anglemod( ent->v.angles[0] ); + ideal = ent->v.idealpitch; + speed = ent->v.pitch_speed; + + if (current == ideal) + return; + move = ideal - current; + if (ideal > current) + { + if (move >= 180) + move = move - 360; + } + else + { + if (move <= -180) + move = move + 360; + } + if (move > 0) + { + if (move > speed) + move = speed; + } + else + { + if (move < -speed) + move = -speed; + } + + ent->v.angles[0] = anglemod (current + move); +} +#endif + +/* +=============================================================================== + +MESSAGE WRITING + +=============================================================================== +*/ + +#define MSG_BROADCAST 0 // unreliable to all +#define MSG_ONE 1 // reliable to one (msg_entity) +#define MSG_ALL 2 // reliable to all +#define MSG_INIT 3 // write to the init string + +sizebuf_t *WriteDest (void) +{ + int entnum; + int dest; + edict_t *ent; + + dest = G_FLOAT(OFS_PARM0); + switch (dest) + { + case MSG_BROADCAST: + return &sv.datagram; + + case MSG_ONE: + ent = PROG_TO_EDICT(pr_global_struct->msg_entity); + entnum = NUM_FOR_EDICT(ent); + if (entnum < 1 || entnum > svs.maxclients) + PR_RunError ("WriteDest: not a client"); + return &svs.clients[entnum-1].message; + + case MSG_ALL: + return &sv.reliable_datagram; + + case MSG_INIT: + return &sv.signon; + + default: + PR_RunError ("WriteDest: bad destination"); + break; + } + + return NULL; +} + +void PF_WriteByte (void) +{ + MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1)); +} + +void PF_WriteChar (void) +{ + MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1)); +} + +void PF_WriteShort (void) +{ + MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1)); +} + +void PF_WriteLong (void) +{ + MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1)); +} + +void PF_WriteAngle (void) +{ + MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1)); +} + +void PF_WriteCoord (void) +{ + MSG_WriteCoord (WriteDest(), G_FLOAT(OFS_PARM1)); +} + +void PF_WriteString (void) +{ + MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1)); +} + + +void PF_WriteEntity (void) +{ + MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1)); +} + +//============================================================================= + +int SV_ModelIndex (char *name); + +void PF_makestatic (void) +{ + edict_t *ent; + int i; + + ent = G_EDICT(OFS_PARM0); + + MSG_WriteByte (&sv.signon,svc_spawnstatic); + + MSG_WriteByte (&sv.signon, SV_ModelIndex(pr_strings + ent->v.model)); + + MSG_WriteByte (&sv.signon, ent->v.frame); + MSG_WriteByte (&sv.signon, ent->v.colormap); + MSG_WriteByte (&sv.signon, ent->v.skin); + for (i=0 ; i<3 ; i++) + { + MSG_WriteCoord(&sv.signon, ent->v.origin[i]); + MSG_WriteAngle(&sv.signon, ent->v.angles[i]); + } + +// throw the entity away now + ED_Free (ent); +} + +//============================================================================= + +/* +============== +PF_setspawnparms +============== +*/ +void PF_setspawnparms (void) +{ + edict_t *ent; + int i; + client_t *client; + + ent = G_EDICT(OFS_PARM0); + i = NUM_FOR_EDICT(ent); + if (i < 1 || i > svs.maxclients) + PR_RunError ("Entity is not a client"); + + // copy spawn parms out of the client_t + client = svs.clients + (i-1); + + for (i=0 ; i< NUM_SPAWN_PARMS ; i++) + (&pr_global_struct->parm1)[i] = client->spawn_parms[i]; +} + +/* +============== +PF_changelevel +============== +*/ +void PF_changelevel (void) +{ +#ifdef QUAKE2 + char *s1, *s2; + + if (svs.changelevel_issued) + return; + svs.changelevel_issued = true; + + s1 = G_STRING(OFS_PARM0); + s2 = G_STRING(OFS_PARM1); + + if ((int)pr_global_struct->serverflags & (SFL_NEW_UNIT | SFL_NEW_EPISODE)) + Cbuf_AddText (va("changelevel %s %s\n",s1, s2)); + else + Cbuf_AddText (va("changelevel2 %s %s\n",s1, s2)); +#else + char *s; + +// make sure we don't issue two changelevels + if (svs.changelevel_issued) + return; + svs.changelevel_issued = true; + + s = G_STRING(OFS_PARM0); + Cbuf_AddText (va("changelevel %s\n",s)); +#endif +} + + +#ifdef QUAKE2 + +#define CONTENT_WATER -3 +#define CONTENT_SLIME -4 +#define CONTENT_LAVA -5 + +#define FL_IMMUNE_WATER 131072 +#define FL_IMMUNE_SLIME 262144 +#define FL_IMMUNE_LAVA 524288 + +#define CHAN_VOICE 2 +#define CHAN_BODY 4 + +#define ATTN_NORM 1 + +void PF_WaterMove (void) +{ + edict_t *self; + int flags; + int waterlevel; + int watertype; + float drownlevel; + float damage = 0.0; + + self = PROG_TO_EDICT(pr_global_struct->self); + + if (self->v.movetype == MOVETYPE_NOCLIP) + { + self->v.air_finished = sv.time + 12; + G_FLOAT(OFS_RETURN) = damage; + return; + } + + if (self->v.health < 0) + { + G_FLOAT(OFS_RETURN) = damage; + return; + } + + if (self->v.deadflag == DEAD_NO) + drownlevel = 3; + else + drownlevel = 1; + + flags = (int)self->v.flags; + waterlevel = (int)self->v.waterlevel; + watertype = (int)self->v.watertype; + + if (!(flags & (FL_IMMUNE_WATER + FL_GODMODE))) + if (((flags & FL_SWIM) && (waterlevel < drownlevel)) || (waterlevel >= drownlevel)) + { + if (self->v.air_finished < sv.time) + if (self->v.pain_finished < sv.time) + { + self->v.dmg = self->v.dmg + 2; + if (self->v.dmg > 15) + self->v.dmg = 10; +// T_Damage (self, world, world, self.dmg, 0, FALSE); + damage = self->v.dmg; + self->v.pain_finished = sv.time + 1.0; + } + } + else + { + if (self->v.air_finished < sv.time) +// sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM); + SV_StartSound (self, CHAN_VOICE, "player/gasp2.wav", 255, ATTN_NORM); + else if (self->v.air_finished < sv.time + 9) +// sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM); + SV_StartSound (self, CHAN_VOICE, "player/gasp1.wav", 255, ATTN_NORM); + self->v.air_finished = sv.time + 12.0; + self->v.dmg = 2; + } + + if (!waterlevel) + { + if (flags & FL_INWATER) + { + // play leave water sound +// sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM); + SV_StartSound (self, CHAN_BODY, "misc/outwater.wav", 255, ATTN_NORM); + self->v.flags = (float)(flags &~FL_INWATER); + } + self->v.air_finished = sv.time + 12.0; + G_FLOAT(OFS_RETURN) = damage; + return; + } + + if (watertype == CONTENT_LAVA) + { // do damage + if (!(flags & (FL_IMMUNE_LAVA + FL_GODMODE))) + if (self->v.dmgtime < sv.time) + { + if (self->v.radsuit_finished < sv.time) + self->v.dmgtime = sv.time + 0.2; + else + self->v.dmgtime = sv.time + 1.0; +// T_Damage (self, world, world, 10*self.waterlevel, 0, TRUE); + damage = (float)(10*waterlevel); + } + } + else if (watertype == CONTENT_SLIME) + { // do damage + if (!(flags & (FL_IMMUNE_SLIME + FL_GODMODE))) + if (self->v.dmgtime < sv.time && self->v.radsuit_finished < sv.time) + { + self->v.dmgtime = sv.time + 1.0; +// T_Damage (self, world, world, 4*self.waterlevel, 0, TRUE); + damage = (float)(4*waterlevel); + } + } + + if ( !(flags & FL_INWATER) ) + { + +// player enter water sound + if (watertype == CONTENT_LAVA) +// sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM); + SV_StartSound (self, CHAN_BODY, "player/inlava.wav", 255, ATTN_NORM); + if (watertype == CONTENT_WATER) +// sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM); + SV_StartSound (self, CHAN_BODY, "player/inh2o.wav", 255, ATTN_NORM); + if (watertype == CONTENT_SLIME) +// sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM); + SV_StartSound (self, CHAN_BODY, "player/slimbrn2.wav", 255, ATTN_NORM); + + self->v.flags = (float)(flags | FL_INWATER); + self->v.dmgtime = 0; + } + + if (! (flags & FL_WATERJUMP) ) + { +// self.velocity = self.velocity - 0.8*self.waterlevel*frametime*self.velocity; + VectorMA (self->v.velocity, -0.8 * self->v.waterlevel * host_frametime, self->v.velocity, self->v.velocity); + } + + G_FLOAT(OFS_RETURN) = damage; +} + + +void PF_sin (void) +{ + G_FLOAT(OFS_RETURN) = sinf(G_FLOAT(OFS_PARM0)); +} + +void PF_cos (void) +{ + G_FLOAT(OFS_RETURN) = cosf(G_FLOAT(OFS_PARM0)); +} + +void PF_sqrt (void) +{ + G_FLOAT(OFS_RETURN) = sqrtf(G_FLOAT(OFS_PARM0)); +} +#endif + +void PF_Fixme (void) +{ + PR_RunError ("unimplemented bulitin"); +} + + + +builtin_t pr_builtin[] = +{ +PF_Fixme, +PF_makevectors, // void(entity e) makevectors = #1; +PF_setorigin, // void(entity e, vector o) setorigin = #2; +PF_setmodel, // void(entity e, string m) setmodel = #3; +PF_setsize, // void(entity e, vector min, vector max) setsize = #4; +PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5; +PF_break, // void() break = #6; +PF_random, // float() random = #7; +PF_sound, // void(entity e, float chan, string samp) sound = #8; +PF_normalize, // vector(vector v) normalize = #9; +PF_error, // void(string e) error = #10; +PF_objerror, // void(string e) objerror = #11; +PF_vlen, // float(vector v) vlen = #12; +PF_vectoyaw, // float(vector v) vectoyaw = #13; +PF_Spawn, // entity() spawn = #14; +PF_Remove, // void(entity e) remove = #15; +PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16; +PF_checkclient, // entity() clientlist = #17; +PF_Find, // entity(entity start, .string fld, string match) find = #18; +PF_precache_sound, // void(string s) precache_sound = #19; +PF_precache_model, // void(string s) precache_model = #20; +PF_stuffcmd, // void(entity client, string s)stuffcmd = #21; +PF_findradius, // entity(vector org, float rad) findradius = #22; +PF_bprint, // void(string s) bprint = #23; +PF_sprint, // void(entity client, string s) sprint = #24; +PF_dprint, // void(string s) dprint = #25; +PF_ftos, // void(string s) ftos = #26; +PF_vtos, // void(string s) vtos = #27; +PF_coredump, +PF_traceon, +PF_traceoff, +PF_eprint, // void(entity e) debug print an entire entity +PF_walkmove, // float(float yaw, float dist) walkmove +PF_Fixme, // float(float yaw, float dist) walkmove +PF_droptofloor, +PF_lightstyle, +PF_rint, +PF_floor, +PF_ceil, +PF_Fixme, +PF_checkbottom, +PF_pointcontents, +PF_Fixme, +PF_fabs, +PF_aim, +PF_cvar, +PF_localcmd, +PF_nextent, +PF_particle, +PF_changeyaw, +PF_Fixme, +PF_vectoangles, + +PF_WriteByte, +PF_WriteChar, +PF_WriteShort, +PF_WriteLong, +PF_WriteCoord, +PF_WriteAngle, +PF_WriteString, +PF_WriteEntity, + +#ifdef QUAKE2 +PF_sin, +PF_cos, +PF_sqrt, +PF_changepitch, +PF_TraceToss, +PF_etos, +PF_WaterMove, +#else +PF_Fixme, +PF_Fixme, +PF_Fixme, +PF_Fixme, +PF_Fixme, +PF_Fixme, +PF_Fixme, +#endif + +SV_MoveToGoal, +PF_precache_file, +PF_makestatic, + +PF_changelevel, +PF_Fixme, + +PF_cvar_set, +PF_centerprint, + +PF_ambientsound, + +PF_precache_model, +PF_precache_sound, // precache_sound2 is different only for qcc +PF_precache_file, + +PF_setspawnparms +}; + +builtin_t *pr_builtins = pr_builtin; +int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]); + diff --git a/r17/Revamped src/revamped_src/pr_comp.h b/r17/Revamped src/revamped_src/pr_comp.h new file mode 100755 index 00000000..fb092516 --- /dev/null +++ b/r17/Revamped src/revamped_src/pr_comp.h @@ -0,0 +1,180 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +// this file is shared by quake and qcc + +typedef int func_t; +typedef int string_t; + +typedef enum {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer} etype_t; + + +#define OFS_NULL 0 +#define OFS_RETURN 1 +#define OFS_PARM0 4 // leave 3 ofs for each parm to hold vectors +#define OFS_PARM1 7 +#define OFS_PARM2 10 +#define OFS_PARM3 13 +#define OFS_PARM4 16 +#define OFS_PARM5 19 +#define OFS_PARM6 22 +#define OFS_PARM7 25 +#define RESERVED_OFS 28 + + +enum { + OP_DONE, + OP_MUL_F, + OP_MUL_V, + OP_MUL_FV, + OP_MUL_VF, + OP_DIV_F, + OP_ADD_F, + OP_ADD_V, + OP_SUB_F, + OP_SUB_V, + + OP_EQ_F, + OP_EQ_V, + OP_EQ_S, + OP_EQ_E, + OP_EQ_FNC, + + OP_NE_F, + OP_NE_V, + OP_NE_S, + OP_NE_E, + OP_NE_FNC, + + OP_LE, + OP_GE, + OP_LT, + OP_GT, + + OP_LOAD_F, + OP_LOAD_V, + OP_LOAD_S, + OP_LOAD_ENT, + OP_LOAD_FLD, + OP_LOAD_FNC, + + OP_ADDRESS, + + OP_STORE_F, + OP_STORE_V, + OP_STORE_S, + OP_STORE_ENT, + OP_STORE_FLD, + OP_STORE_FNC, + + OP_STOREP_F, + OP_STOREP_V, + OP_STOREP_S, + OP_STOREP_ENT, + OP_STOREP_FLD, + OP_STOREP_FNC, + + OP_RETURN, + OP_NOT_F, + OP_NOT_V, + OP_NOT_S, + OP_NOT_ENT, + OP_NOT_FNC, + OP_IF, + OP_IFNOT, + OP_CALL0, + OP_CALL1, + OP_CALL2, + OP_CALL3, + OP_CALL4, + OP_CALL5, + OP_CALL6, + OP_CALL7, + OP_CALL8, + OP_STATE, + OP_GOTO, + OP_AND, + OP_OR, + + OP_BITAND, + OP_BITOR +}; + + +typedef struct statement_s +{ + unsigned short op; + short a,b,c; +} dstatement_t; + +typedef struct +{ + unsigned short type; // if DEF_SAVEGLOBGAL bit is set + // the variable needs to be saved in savegames + unsigned short ofs; + int s_name; +} ddef_t; +#define DEF_SAVEGLOBAL (1<<15) + +#define MAX_PARMS 8 + +typedef struct +{ + int first_statement; // negative numbers are builtins + int parm_start; + int locals; // total ints of parms + locals + + int profile; // runtime + + int s_name; + int s_file; // source file defined in + + int numparms; + byte parm_size[MAX_PARMS]; +} dfunction_t; + + +#define PROG_VERSION 6 +typedef struct +{ + int version; + int crc; // check of header file + + int ofs_statements; + int numstatements; // statement 0 is an error + + int ofs_globaldefs; + int numglobaldefs; + + int ofs_fielddefs; + int numfielddefs; + + int ofs_functions; + int numfunctions; // function 0 is an empty + + int ofs_strings; + int numstrings; // first string is a null string + + int ofs_globals; + int numglobals; + + int entityfields; +} dprograms_t; + diff --git a/r17/Revamped src/revamped_src/pr_edict.c b/r17/Revamped src/revamped_src/pr_edict.c new file mode 100755 index 00000000..5035a3ff --- /dev/null +++ b/r17/Revamped src/revamped_src/pr_edict.c @@ -0,0 +1,1111 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// sv_edict.c -- entity dictionary + +#include "quakedef.h" + +dprograms_t *progs; +dfunction_t *pr_functions; +char *pr_strings; +ddef_t *pr_fielddefs; +ddef_t *pr_globaldefs; +dstatement_t *pr_statements; +globalvars_t *pr_global_struct; +float *pr_globals; // same as pr_global_struct +int pr_edict_size; // in bytes + +unsigned short pr_crc; + +int type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4}; + +ddef_t *ED_FieldAtOfs (int ofs); +qboolean ED_ParseEpair (void *base, ddef_t *key, char *s); + +cvar_t nomonsters = {"nomonsters", "0"}; +cvar_t gamecfg = {"gamecfg", "0"}; +cvar_t scratch1 = {"scratch1", "0"}; +cvar_t scratch2 = {"scratch2", "0"}; +cvar_t scratch3 = {"scratch3", "0"}; +cvar_t scratch4 = {"scratch4", "0"}; +cvar_t savedgamecfg = {"savedgamecfg", "0", true}; +cvar_t saved1 = {"saved1", "0", true}; +cvar_t saved2 = {"saved2", "0", true}; +cvar_t saved3 = {"saved3", "0", true}; +cvar_t saved4 = {"saved4", "0", true}; + +#define MAX_FIELD_LEN 64 +#define GEFV_CACHESIZE 2 + +typedef struct { + ddef_t *pcache; + char field[MAX_FIELD_LEN]; +} gefv_cache; + +static gefv_cache gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}}; + +/* +================= +ED_ClearEdict + +Sets everything to NULL +================= +*/ +void ED_ClearEdict (edict_t *e) +{ + memset (&e->v, 0, progs->entityfields * 4); + e->free = false; +} + +/* +================= +ED_Alloc + +Either finds a free edict, or allocates a new one. +Try to avoid reusing an entity that was recently freed, because it +can cause the client to think the entity morphed into something else +instead of being removed and recreated, which can cause interpolated +angles and bad trails. +================= +*/ +edict_t *ED_Alloc (void) +{ + int i; + edict_t *e; + + for ( i=svs.maxclients+1 ; ifree && ( e->freetime < 2 || sv.time - e->freetime > 0.5 ) ) + { + ED_ClearEdict (e); + return e; + } + } + + if (i == MAX_EDICTS) + Sys_Error ("ED_Alloc: no free edicts"); + + sv.num_edicts++; + e = EDICT_NUM(i); + ED_ClearEdict (e); + + return e; +} + +/* +================= +ED_Free + +Marks the edict as free +FIXME: walk all entities and NULL out references to this entity +================= +*/ +void ED_Free (edict_t *ed) +{ + SV_UnlinkEdict (ed); // unlink from world bsp + + ed->free = true; + ed->v.model = 0; + ed->v.takedamage = 0; + ed->v.modelindex = 0; + ed->v.colormap = 0; + ed->v.skin = 0; + ed->v.frame = 0; + VectorCopy (vec3_origin, ed->v.origin); + VectorCopy (vec3_origin, ed->v.angles); + ed->v.nextthink = -1; + ed->v.solid = 0; + + ed->freetime = sv.time; +} + +//=========================================================================== + +/* +============ +ED_GlobalAtOfs +============ +*/ +ddef_t *ED_GlobalAtOfs (int ofs) +{ + ddef_t *def; + int i; + + for (i=0 ; inumglobaldefs ; i++) + { + def = &pr_globaldefs[i]; + if (def->ofs == ofs) + return def; + } + return NULL; +} + +/* +============ +ED_FieldAtOfs +============ +*/ +ddef_t *ED_FieldAtOfs (int ofs) +{ + ddef_t *def; + int i; + + for (i=0 ; inumfielddefs ; i++) + { + def = &pr_fielddefs[i]; + if (def->ofs == ofs) + return def; + } + return NULL; +} + +/* +============ +ED_FindField +============ +*/ +ddef_t *ED_FindField (char *name) +{ + ddef_t *def; + int i; + + for (i=0 ; inumfielddefs ; i++) + { + def = &pr_fielddefs[i]; + if (!strcmp(pr_strings + def->s_name,name) ) + return def; + } + return NULL; +} + + +/* +============ +ED_FindGlobal +============ +*/ +ddef_t *ED_FindGlobal (char *name) +{ + ddef_t *def; + int i; + + for (i=0 ; inumglobaldefs ; i++) + { + def = &pr_globaldefs[i]; + if (!strcmp(pr_strings + def->s_name,name) ) + return def; + } + return NULL; +} + + +/* +============ +ED_FindFunction +============ +*/ +dfunction_t *ED_FindFunction (char *name) +{ + dfunction_t *func; + int i; + + for (i=0 ; inumfunctions ; i++) + { + func = &pr_functions[i]; + if (!strcmp(pr_strings + func->s_name,name) ) + return func; + } + return NULL; +} + + +eval_t *GetEdictFieldValue(edict_t *ed, char *field) +{ + ddef_t *def = NULL; + int i; + static int rep = 0; + + for (i=0 ; iv + def->ofs*4); +} + + +/* +============ +PR_ValueString + +Returns a string describing *data in a type specific manner +============= +*/ +char *PR_ValueString (etype_t type, eval_t *val) +{ + static char line[256]; + ddef_t *def; + dfunction_t *f; + + type &= ~DEF_SAVEGLOBAL; + + switch (type) + { + case ev_string: + sprintf (line, "%s", pr_strings + val->string); + break; + case ev_entity: + sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) ); + break; + case ev_function: + f = pr_functions + val->function; + sprintf (line, "%s()", pr_strings + f->s_name); + break; + case ev_field: + def = ED_FieldAtOfs ( val->_int ); + sprintf (line, ".%s", pr_strings + def->s_name); + break; + case ev_void: + sprintf (line, "void"); + break; + case ev_float: + sprintf (line, "%5.1f", val->_float); + break; + case ev_vector: + sprintf (line, "'%5.1f %5.1f %5.1f'", val->vector[0], val->vector[1], val->vector[2]); + break; + case ev_pointer: + sprintf (line, "pointer"); + break; + default: + sprintf (line, "bad type %i", type); + break; + } + + return line; +} + +/* +============ +PR_UglyValueString + +Returns a string describing *data in a type specific manner +Easier to parse than PR_ValueString +============= +*/ +char *PR_UglyValueString (etype_t type, eval_t *val) +{ + static char line[256]; + ddef_t *def; + dfunction_t *f; + + type &= ~DEF_SAVEGLOBAL; + + switch (type) + { + case ev_string: + sprintf (line, "%s", pr_strings + val->string); + break; + case ev_entity: + sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict))); + break; + case ev_function: + f = pr_functions + val->function; + sprintf (line, "%s", pr_strings + f->s_name); + break; + case ev_field: + def = ED_FieldAtOfs ( val->_int ); + sprintf (line, "%s", pr_strings + def->s_name); + break; + case ev_void: + sprintf (line, "void"); + break; + case ev_float: + sprintf (line, "%f", val->_float); + break; + case ev_vector: + sprintf (line, "%f %f %f", val->vector[0], val->vector[1], val->vector[2]); + break; + default: + sprintf (line, "bad type %i", type); + break; + } + + return line; +} + +/* +============ +PR_GlobalString + +Returns a string with a description and the contents of a global, +padded to 20 field width +============ +*/ +char *PR_GlobalString (int ofs) +{ + char *s; + int i; + ddef_t *def; + void *val; + static char line[128]; + + val = (void *)&pr_globals[ofs]; + def = ED_GlobalAtOfs(ofs); + if (!def) + sprintf (line,"%i(???)", ofs); + else + { + s = PR_ValueString (def->type, val); + sprintf (line,"%i(%s)%s", ofs, pr_strings + def->s_name, s); + } + + i = strlen(line); + for ( ; i<20 ; i++) + strcat (line," "); + strcat (line," "); + + return line; +} + +char *PR_GlobalStringNoContents (int ofs) +{ + int i; + ddef_t *def; + static char line[128]; + + def = ED_GlobalAtOfs(ofs); + if (!def) + sprintf (line,"%i(???)", ofs); + else + sprintf (line,"%i(%s)", ofs, pr_strings + def->s_name); + + i = strlen(line); + for ( ; i<20 ; i++) + strcat (line," "); + strcat (line," "); + + return line; +} + + +/* +============= +ED_Print + +For debugging +============= +*/ +void ED_Print (edict_t *ed) +{ + int l; + ddef_t *d; + int *v; + int i, j; + char *name; + int type; + + if (ed->free) + { + Con_Printf ("FREE\n"); + return; + } + + Con_Printf("\nEDICT %i:\n", NUM_FOR_EDICT(ed)); + for (i=1 ; inumfielddefs ; i++) + { + d = &pr_fielddefs[i]; + name = pr_strings + d->s_name; + if (name[strlen(name)-2] == '_') + continue; // skip _x, _y, _z vars + + v = (int *)((char *)&ed->v + d->ofs*4); + + // if the value is still all 0, skip the field + type = d->type & ~DEF_SAVEGLOBAL; + + for (j=0 ; jtype, (eval_t *)v)); + } +} + +/* +============= +ED_Write + +For savegames +============= +*/ +void ED_Write (FILE *f, edict_t *ed) +{ + ddef_t *d; + int *v; + int i, j; + char *name; + int type; + + fprintf (f, "{\n"); + + if (ed->free) + { + fprintf (f, "}\n"); + return; + } + + for (i=1 ; inumfielddefs ; i++) + { + d = &pr_fielddefs[i]; + name = pr_strings + d->s_name; + if (name[strlen(name)-2] == '_') + continue; // skip _x, _y, _z vars + + v = (int *)((char *)&ed->v + d->ofs*4); + + // if the value is still all 0, skip the field + type = d->type & ~DEF_SAVEGLOBAL; + for (j=0 ; jtype, (eval_t *)v)); + } + + fprintf (f, "}\n"); +} + +void ED_PrintNum (int ent) +{ + ED_Print (EDICT_NUM(ent)); +} + +/* +============= +ED_PrintEdicts + +For debugging, prints all the entities in the current server +============= +*/ +void ED_PrintEdicts (void) +{ + int i; + + Con_Printf ("%i entities\n", sv.num_edicts); + for (i=0 ; i= sv.num_edicts) + { + Con_Printf("Bad edict number\n"); + return; + } + ED_PrintNum (i); +} + +/* +============= +ED_Count + +For debugging +============= +*/ +void ED_Count (void) +{ + int i; + edict_t *ent; + int active, models, solid, step; + + active = models = solid = step = 0; + for (i=0 ; ifree) + continue; + active++; + if (ent->v.solid) + solid++; + if (ent->v.model) + models++; + if (ent->v.movetype == MOVETYPE_STEP) + step++; + } + + Con_Printf ("num_edicts:%3i\n", sv.num_edicts); + Con_Printf ("active :%3i\n", active); + Con_Printf ("view :%3i\n", models); + Con_Printf ("touch :%3i\n", solid); + Con_Printf ("step :%3i\n", step); + +} + +/* +============================================================================== + + ARCHIVING GLOBALS + +FIXME: need to tag constants, doesn't really work +============================================================================== +*/ + +/* +============= +ED_WriteGlobals +============= +*/ +void ED_WriteGlobals (FILE *f) +{ + ddef_t *def; + int i; + char *name; + int type; + + fprintf (f,"{\n"); + for (i=0 ; inumglobaldefs ; i++) + { + def = &pr_globaldefs[i]; + type = def->type; + if ( !(def->type & DEF_SAVEGLOBAL) ) + continue; + type &= ~DEF_SAVEGLOBAL; + + if (type != ev_string + && type != ev_float + && type != ev_entity) + continue; + + name = pr_strings + def->s_name; + fprintf (f,"\"%s\" ", name); + fprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs])); + } + fprintf (f,"}\n"); +} + +/* +============= +ED_ParseGlobals +============= +*/ +void ED_ParseGlobals (char *data) +{ + char keyname[64]; + ddef_t *key; + + while (1) + { + // parse key + data = COM_Parse (data); + if (com_token[0] == '}') + break; + if (!data) + Sys_Error ("ED_ParseEntity: EOF without closing brace"); + + strcpy (keyname, com_token); + + // parse value + data = COM_Parse (data); + if (!data) + Sys_Error ("ED_ParseEntity: EOF without closing brace"); + + if (com_token[0] == '}') + Sys_Error ("ED_ParseEntity: closing brace without data"); + + key = ED_FindGlobal (keyname); + if (!key) + { + Con_Printf ("'%s' is not a global\n", keyname); + continue; + } + + if (!ED_ParseEpair ((void *)pr_globals, key, com_token)) + Host_Error ("ED_ParseGlobals: parse error"); + } +} + +//============================================================================ + + +/* +============= +ED_NewString +============= +*/ +char *ED_NewString (char *string) +{ + char *new, *new_p; + int i,l; + + l = strlen(string) + 1; + new = Hunk_Alloc (l); + new_p = new; + + for (i=0 ; i< l ; i++) + { + if (string[i] == '\\' && i < l-1) + { + i++; + if (string[i] == 'n') + *new_p++ = '\n'; + else + *new_p++ = '\\'; + } + else + *new_p++ = string[i]; + } + + return new; +} + + +/* +============= +ED_ParseEval + +Can parse either fields or globals +returns false if error +============= +*/ +qboolean ED_ParseEpair (void *base, ddef_t *key, char *s) +{ + int i; + char string[128]; + ddef_t *def; + char *v, *w; + void *d; + dfunction_t *func; + + d = (void *)((int *)base + key->ofs); + + switch (key->type & ~DEF_SAVEGLOBAL) + { + case ev_string: + *(string_t *)d = ED_NewString (s) - pr_strings; + break; + + case ev_float: + *(float *)d = atof (s); + break; + + case ev_vector: + strcpy (string, s); + v = string; + w = string; + for (i=0 ; i<3 ; i++) + { + while (*v && *v != ' ') + v++; + *v = 0; + ((float *)d)[i] = atof (w); + w = v = v+1; + } + break; + + case ev_entity: + *(int *)d = EDICT_TO_PROG(EDICT_NUM(atoi (s))); + break; + + case ev_field: + def = ED_FindField (s); + if (!def) + { + //johnfitz -- HACK -- suppress error becuase fog/sky fields might not be mentioned in defs.qc + if (strncmp(s, "sky", 3) && strcmp(s, "fog")) + Con_Printf ("Can't find field %s\n", s); + return false; + } + *(int *)d = G_INT(def->ofs); + break; + + case ev_function: + func = ED_FindFunction (s); + if (!func) + { + Con_Printf ("Can't find function %s\n", s); + return false; + } + *(func_t *)d = func - pr_functions; + break; + + default: + break; + } + return true; +} + +/* +==================== +ED_ParseEdict + +Parses an edict out of the given string, returning the new position +ed should be a properly initialized empty edict. +Used for initial level load and for savegames. +==================== +*/ +char *ED_ParseEdict (char *data, edict_t *ent) +{ + ddef_t *key; + qboolean anglehack; + qboolean init; + char keyname[256]; + int n; + + init = false; + +// clear it + if (ent != sv.edicts) // hack + memset (&ent->v, 0, progs->entityfields * 4); + +// go through all the dictionary pairs + while (1) + { + // parse key + data = COM_Parse (data); + if (com_token[0] == '}') + break; + if (!data) + Sys_Error ("ED_ParseEntity: EOF without closing brace"); + +// anglehack is to allow QuakeEd to write single scalar angles +// and allow them to be turned into vectors. (FIXME...) +if (!strcmp(com_token, "angle")) +{ + strcpy (com_token, "angles"); + anglehack = true; +} +else + anglehack = false; + +// FIXME: change light to _light to get rid of this hack +if (!strcmp(com_token, "light")) + strcpy (com_token, "light_lev"); // hack for single light def + + strcpy (keyname, com_token); + + // another hack to fix heynames with trailing spaces + n = strlen(keyname); + while (n && keyname[n-1] == ' ') + { + keyname[n-1] = 0; + n--; + } + + // parse value + data = COM_Parse (data); + if (!data) + Sys_Error ("ED_ParseEntity: EOF without closing brace"); + + if (com_token[0] == '}') + Sys_Error ("ED_ParseEntity: closing brace without data"); + + init = true; + +// keynames with a leading underscore are used for utility comments, +// and are immediately discarded by quake + if (keyname[0] == '_') + continue; + + key = ED_FindField (keyname); + if (!key) + { + //johnfitz -- HACK -- suppress error becuase fog/sky fields might not be mentioned in defs.qc + if (strncmp(keyname, "sky", 3) && strcmp(keyname, "fog")) + Con_SafePrintf ("'%s' is not a field\n", keyname); + continue; + } + +if (anglehack) +{ +char temp[32]; +strcpy (temp, com_token); +sprintf (com_token, "0 %s 0", temp); +} + + if (!ED_ParseEpair ((void *)&ent->v, key, com_token)) + Host_Error ("ED_ParseEdict: parse error"); + } + + if (!init) + ent->free = true; + + return data; +} + + +/* +================ +ED_LoadFromFile + +The entities are directly placed in the array, rather than allocated with +ED_Alloc, because otherwise an error loading the map would have entity +number references out of order. + +Creates a server's entity / program execution context by +parsing textual entity definitions out of an ent file. + +Used for both fresh maps and savegame loads. A fresh map would also need +to call ED_CallSpawnFunctions () to let the objects initialize themselves. +================ +*/ +void ED_LoadFromFile (char *data) +{ + edict_t *ent; + int inhibit; + dfunction_t *func; + + ent = NULL; + inhibit = 0; + pr_global_struct->time = sv.time; + +// parse ents + while (1) + { +// parse the opening brace + data = COM_Parse (data); + if (!data) + break; + if (com_token[0] != '{') + Sys_Error ("ED_LoadFromFile: found %s when expecting {",com_token); + + if (!ent) + ent = EDICT_NUM(0); + else + ent = ED_Alloc (); + data = ED_ParseEdict (data, ent); + +// remove things from different skill levels or deathmatch + if (deathmatch.value) + { + if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH)) + { + ED_Free (ent); + inhibit++; + continue; + } + } + else if ((current_skill == 0 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_EASY)) + || (current_skill == 1 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_MEDIUM)) + || (current_skill >= 2 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_HARD)) ) + { + ED_Free (ent); + inhibit++; + continue; + } + +// +// immediately call spawn function +// + if (!ent->v.classname) + { + Con_Printf ("No classname for:\n"); + ED_Print (ent); + ED_Free (ent); + continue; + } + + // look for the spawn function + func = ED_FindFunction ( pr_strings + ent->v.classname ); + + if (!func) + { + Con_Printf ("No spawn function for:\n"); + ED_Print (ent); + ED_Free (ent); + continue; + } + + pr_global_struct->self = EDICT_TO_PROG(ent); + PR_ExecuteProgram (func - pr_functions); + } + + Con_DPrintf ("%i entities inhibited\n", inhibit); +} + + +/* +=============== +PR_LoadProgs +=============== +*/ +void PR_LoadProgs (void) +{ + int i; + +// flush the non-C variable lookup cache + for (i=0 ; iversion != PROG_VERSION) + Sys_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION); + if (progs->crc != PROGHEADER_CRC) + Sys_Error ("progs.dat system vars have been modified, progdefs.h is out of date"); + + pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions); + pr_strings = (char *)progs + progs->ofs_strings; + pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs); + pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs); + pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements); + + pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals); + pr_globals = (float *)pr_global_struct; + + pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t); + +// byte swap the lumps + for (i=0 ; inumstatements ; i++) + { + pr_statements[i].op = LittleShort(pr_statements[i].op); + pr_statements[i].a = LittleShort(pr_statements[i].a); + pr_statements[i].b = LittleShort(pr_statements[i].b); + pr_statements[i].c = LittleShort(pr_statements[i].c); + } + + for (i=0 ; inumfunctions; i++) + { + pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement); + pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start); + pr_functions[i].s_name = LittleLong (pr_functions[i].s_name); + pr_functions[i].s_file = LittleLong (pr_functions[i].s_file); + pr_functions[i].numparms = LittleLong (pr_functions[i].numparms); + pr_functions[i].locals = LittleLong (pr_functions[i].locals); + } + + for (i=0 ; inumglobaldefs ; i++) + { + pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type); + pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs); + pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name); + } + + for (i=0 ; inumfielddefs ; i++) + { + pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type); + if (pr_fielddefs[i].type & DEF_SAVEGLOBAL) + Sys_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL"); + pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs); + pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name); + } + + for (i=0 ; inumglobals ; i++) + ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]); + +} + + +/* +=============== +PR_Init +=============== +*/ +void PR_Init (void) +{ + Cmd_AddCommand ("edict", ED_PrintEdict_f); + Cmd_AddCommand ("edicts", ED_PrintEdicts); + Cmd_AddCommand ("edictcount", ED_Count); + Cmd_AddCommand ("profile", PR_Profile_f); + Cvar_RegisterVariable (&nomonsters); + Cvar_RegisterVariable (&gamecfg); + Cvar_RegisterVariable (&scratch1); + Cvar_RegisterVariable (&scratch2); + Cvar_RegisterVariable (&scratch3); + Cvar_RegisterVariable (&scratch4); + Cvar_RegisterVariable (&savedgamecfg); + Cvar_RegisterVariable (&saved1); + Cvar_RegisterVariable (&saved2); + Cvar_RegisterVariable (&saved3); + Cvar_RegisterVariable (&saved4); +} + + + +edict_t *EDICT_NUM(int n) +{ + if (n < 0 || n >= sv.max_edicts) + Sys_Error ("EDICT_NUM: bad number %i", n); + return (edict_t *)((byte *)sv.edicts+ (n)*pr_edict_size); +} + +int NUM_FOR_EDICT(edict_t *e) +{ + int b; + + b = (byte *)e - (byte *)sv.edicts; + b = b / pr_edict_size; + + if (b < 0 || b >= sv.num_edicts) + Sys_Error ("NUM_FOR_EDICT: bad pointer"); + return b; +} diff --git a/r17/Revamped src/revamped_src/pr_exec.c b/r17/Revamped src/revamped_src/pr_exec.c new file mode 100755 index 00000000..3fa0d299 --- /dev/null +++ b/r17/Revamped src/revamped_src/pr_exec.c @@ -0,0 +1,668 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +#include "quakedef.h" + + +/* + +*/ + +typedef struct +{ + int s; + dfunction_t *f; +} prstack_t; + +#define MAX_STACK_DEPTH 32 +prstack_t pr_stack[MAX_STACK_DEPTH]; +int pr_depth; + +#define LOCALSTACK_SIZE 2048 +int localstack[LOCALSTACK_SIZE]; +int localstack_used; + + +qboolean pr_trace; +dfunction_t *pr_xfunction; +int pr_xstatement; + + +int pr_argc; + +char *pr_opnames[] = +{ +"DONE", + +"MUL_F", +"MUL_V", +"MUL_FV", +"MUL_VF", + +"DIV", + +"ADD_F", +"ADD_V", + +"SUB_F", +"SUB_V", + +"EQ_F", +"EQ_V", +"EQ_S", +"EQ_E", +"EQ_FNC", + +"NE_F", +"NE_V", +"NE_S", +"NE_E", +"NE_FNC", + +"LE", +"GE", +"LT", +"GT", + +"INDIRECT", +"INDIRECT", +"INDIRECT", +"INDIRECT", +"INDIRECT", +"INDIRECT", + +"ADDRESS", + +"STORE_F", +"STORE_V", +"STORE_S", +"STORE_ENT", +"STORE_FLD", +"STORE_FNC", + +"STOREP_F", +"STOREP_V", +"STOREP_S", +"STOREP_ENT", +"STOREP_FLD", +"STOREP_FNC", + +"RETURN", + +"NOT_F", +"NOT_V", +"NOT_S", +"NOT_ENT", +"NOT_FNC", + +"IF", +"IFNOT", + +"CALL0", +"CALL1", +"CALL2", +"CALL3", +"CALL4", +"CALL5", +"CALL6", +"CALL7", +"CALL8", + +"STATE", + +"GOTO", + +"AND", +"OR", + +"BITAND", +"BITOR" +}; + +char *PR_GlobalString (int ofs); +char *PR_GlobalStringNoContents (int ofs); + + +//============================================================================= + +/* +================= +PR_PrintStatement +================= +*/ +void PR_PrintStatement (dstatement_t *s) +{ + int i; + + if ( (unsigned)s->op < sizeof(pr_opnames)/sizeof(pr_opnames[0])) + { + Con_Printf ("%s ", pr_opnames[s->op]); + i = strlen(pr_opnames[s->op]); + for ( ; i<10 ; i++) + Con_Printf (" "); + } + + if (s->op == OP_IF || s->op == OP_IFNOT) + Con_Printf ("%sbranch %i",PR_GlobalString(s->a),s->b); + else if (s->op == OP_GOTO) + { + Con_Printf ("branch %i",s->a); + } + else if ( (unsigned)(s->op - OP_STORE_F) < 6) + { + Con_Printf ("%s",PR_GlobalString(s->a)); + Con_Printf ("%s", PR_GlobalStringNoContents(s->b)); + } + else + { + if (s->a) + Con_Printf ("%s",PR_GlobalString(s->a)); + if (s->b) + Con_Printf ("%s",PR_GlobalString(s->b)); + if (s->c) + Con_Printf ("%s", PR_GlobalStringNoContents(s->c)); + } + Con_Printf ("\n"); +} + +/* +============ +PR_StackTrace +============ +*/ +void PR_StackTrace (void) +{ + dfunction_t *f; + int i; + + if (pr_depth == 0) + { + Con_Printf ("\n"); + return; + } + + pr_stack[pr_depth].f = pr_xfunction; + for (i=pr_depth ; i>=0 ; i--) + { + f = pr_stack[i].f; + + if (!f) + { + Con_Printf ("\n"); + } + else + Con_Printf ("%12s : %s\n", pr_strings + f->s_file, pr_strings + f->s_name); + } +} + + +/* +============ +PR_Profile_f + +============ +*/ +void PR_Profile_f (void) +{ + dfunction_t *f, *best; + int max; + int num; + int i; + + num = 0; + do + { + max = 0; + best = NULL; + for (i=0 ; inumfunctions ; i++) + { + f = &pr_functions[i]; + if (f->profile > max) + { + max = f->profile; + best = f; + } + } + if (best) + { + if (num < 10) + Con_Printf ("%7i %s\n", best->profile, pr_strings+best->s_name); + num++; + best->profile = 0; + } + } while (best); +} + + +/* +============ +PR_RunError + +Aborts the currently executing function +============ +*/ +void PR_RunError (char *error, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr,error); + vsprintf (string,error,argptr); + va_end (argptr); + + PR_PrintStatement (pr_statements + pr_xstatement); + PR_StackTrace (); + Con_Printf ("%s\n", string); + + pr_depth = 0; // dump the stack so host_error can shutdown functions + + Host_Error ("Program error"); +} + +/* +============================================================================ +PR_ExecuteProgram + +The interpretation main loop +============================================================================ +*/ + +/* +==================== +PR_EnterFunction + +Returns the new program statement counter +==================== +*/ +int PR_EnterFunction (dfunction_t *f) +{ + int i, j, c, o; + + pr_stack[pr_depth].s = pr_xstatement; + pr_stack[pr_depth].f = pr_xfunction; + pr_depth++; + if (pr_depth >= MAX_STACK_DEPTH) + PR_RunError ("stack overflow"); + +// save off any locals that the new function steps on + c = f->locals; + if (localstack_used + c > LOCALSTACK_SIZE) + PR_RunError ("PR_ExecuteProgram: locals stack overflow\n"); + + for (i=0 ; i < c ; i++) + localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i]; + localstack_used += c; + +// copy parameters + o = f->parm_start; + for (i=0 ; inumparms ; i++) + { + for (j=0 ; jparm_size[i] ; j++) + { + ((int *)pr_globals)[o] = ((int *)pr_globals)[OFS_PARM0+i*3+j]; + o++; + } + } + + pr_xfunction = f; + return f->first_statement - 1; // offset the s++ +} + +/* +==================== +PR_LeaveFunction +==================== +*/ +int PR_LeaveFunction (void) +{ + int i, c; + + if (pr_depth <= 0) + Sys_Error ("prog stack underflow"); + +// restore locals from the stack + c = pr_xfunction->locals; + localstack_used -= c; + if (localstack_used < 0) + PR_RunError ("PR_ExecuteProgram: locals stack underflow\n"); + + for (i=0 ; i < c ; i++) + ((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i]; + +// up stack + pr_depth--; + pr_xfunction = pr_stack[pr_depth].f; + return pr_stack[pr_depth].s; +} + + +/* +==================== +PR_ExecuteProgram +==================== +*/ +void PR_ExecuteProgram (func_t fnum) +{ + eval_t *a, *b, *c; + int s; + dstatement_t *st; + dfunction_t *f, *newf; + int runaway; + int i; + edict_t *ed; + int exitdepth; + eval_t *ptr; + + if (!fnum || fnum >= progs->numfunctions) + { + if (pr_global_struct->self) + ED_Print (PROG_TO_EDICT(pr_global_struct->self)); + Host_Error ("PR_ExecuteProgram: NULL function"); + } + + f = &pr_functions[fnum]; + + runaway = 100000; + pr_trace = false; + +// make a stack frame + exitdepth = pr_depth; + + s = PR_EnterFunction (f); + +while (1) +{ + s++; // next statement + + st = &pr_statements[s]; + a = (eval_t *)&pr_globals[st->a]; + b = (eval_t *)&pr_globals[st->b]; + c = (eval_t *)&pr_globals[st->c]; + + if (!--runaway) + PR_RunError ("runaway loop error"); + + pr_xfunction->profile++; + pr_xstatement = s; + + if (pr_trace) + PR_PrintStatement (st); + + switch (st->op) + { + case OP_ADD_F: + c->_float = a->_float + b->_float; + break; + case OP_ADD_V: + c->vector[0] = a->vector[0] + b->vector[0]; + c->vector[1] = a->vector[1] + b->vector[1]; + c->vector[2] = a->vector[2] + b->vector[2]; + break; + + case OP_SUB_F: + c->_float = a->_float - b->_float; + break; + case OP_SUB_V: + c->vector[0] = a->vector[0] - b->vector[0]; + c->vector[1] = a->vector[1] - b->vector[1]; + c->vector[2] = a->vector[2] - b->vector[2]; + break; + + case OP_MUL_F: + c->_float = a->_float * b->_float; + break; + case OP_MUL_V: + c->_float = a->vector[0]*b->vector[0] + + a->vector[1]*b->vector[1] + + a->vector[2]*b->vector[2]; + break; + case OP_MUL_FV: + c->vector[0] = a->_float * b->vector[0]; + c->vector[1] = a->_float * b->vector[1]; + c->vector[2] = a->_float * b->vector[2]; + break; + case OP_MUL_VF: + c->vector[0] = b->_float * a->vector[0]; + c->vector[1] = b->_float * a->vector[1]; + c->vector[2] = b->_float * a->vector[2]; + break; + + case OP_DIV_F: + c->_float = a->_float / b->_float; + break; + + case OP_BITAND: + c->_float = (int)a->_float & (int)b->_float; + break; + + case OP_BITOR: + c->_float = (int)a->_float | (int)b->_float; + break; + + + case OP_GE: + c->_float = a->_float >= b->_float; + break; + case OP_LE: + c->_float = a->_float <= b->_float; + break; + case OP_GT: + c->_float = a->_float > b->_float; + break; + case OP_LT: + c->_float = a->_float < b->_float; + break; + case OP_AND: + c->_float = a->_float && b->_float; + break; + case OP_OR: + c->_float = a->_float || b->_float; + break; + + case OP_NOT_F: + c->_float = !a->_float; + break; + case OP_NOT_V: + c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2]; + break; + case OP_NOT_S: + c->_float = !a->string || !pr_strings[a->string]; + break; + case OP_NOT_FNC: + c->_float = !a->function; + break; + case OP_NOT_ENT: + c->_float = (PROG_TO_EDICT(a->edict) == sv.edicts); + break; + + case OP_EQ_F: + c->_float = a->_float == b->_float; + break; + case OP_EQ_V: + c->_float = (a->vector[0] == b->vector[0]) && + (a->vector[1] == b->vector[1]) && + (a->vector[2] == b->vector[2]); + break; + case OP_EQ_S: + c->_float = !strcmp(pr_strings+a->string,pr_strings+b->string); + break; + case OP_EQ_E: + c->_float = a->_int == b->_int; + break; + case OP_EQ_FNC: + c->_float = a->function == b->function; + break; + + + case OP_NE_F: + c->_float = a->_float != b->_float; + break; + case OP_NE_V: + c->_float = (a->vector[0] != b->vector[0]) || + (a->vector[1] != b->vector[1]) || + (a->vector[2] != b->vector[2]); + break; + case OP_NE_S: + c->_float = strcmp(pr_strings+a->string,pr_strings+b->string); + break; + case OP_NE_E: + c->_float = a->_int != b->_int; + break; + case OP_NE_FNC: + c->_float = a->function != b->function; + break; + +//================== + case OP_STORE_F: + case OP_STORE_ENT: + case OP_STORE_FLD: // integers + case OP_STORE_S: + case OP_STORE_FNC: // pointers + b->_int = a->_int; + break; + case OP_STORE_V: + b->vector[0] = a->vector[0]; + b->vector[1] = a->vector[1]; + b->vector[2] = a->vector[2]; + break; + + case OP_STOREP_F: + case OP_STOREP_ENT: + case OP_STOREP_FLD: // integers + case OP_STOREP_S: + case OP_STOREP_FNC: // pointers + ptr = (eval_t *)((byte *)sv.edicts + b->_int); + ptr->_int = a->_int; + break; + case OP_STOREP_V: + ptr = (eval_t *)((byte *)sv.edicts + b->_int); + ptr->vector[0] = a->vector[0]; + ptr->vector[1] = a->vector[1]; + ptr->vector[2] = a->vector[2]; + break; + + case OP_ADDRESS: + ed = PROG_TO_EDICT(a->edict); +#ifdef PARANOID + NUM_FOR_EDICT(ed); // make sure it's in range +#endif + if (ed == (edict_t *)sv.edicts && sv.state == ss_active) + PR_RunError ("assignment to world entity"); + c->_int = (byte *)((int *)&ed->v + b->_int) - (byte *)sv.edicts; + break; + + case OP_LOAD_F: + case OP_LOAD_FLD: + case OP_LOAD_ENT: + case OP_LOAD_S: + case OP_LOAD_FNC: + ed = PROG_TO_EDICT(a->edict); +#ifdef PARANOID + NUM_FOR_EDICT(ed); // make sure it's in range +#endif + a = (eval_t *)((int *)&ed->v + b->_int); + c->_int = a->_int; + break; + + case OP_LOAD_V: + ed = PROG_TO_EDICT(a->edict); +#ifdef PARANOID + NUM_FOR_EDICT(ed); // make sure it's in range +#endif + a = (eval_t *)((int *)&ed->v + b->_int); + c->vector[0] = a->vector[0]; + c->vector[1] = a->vector[1]; + c->vector[2] = a->vector[2]; + break; + +//================== + + case OP_IFNOT: + if (!a->_int) + s += st->b - 1; // offset the s++ + break; + + case OP_IF: + if (a->_int) + s += st->b - 1; // offset the s++ + break; + + case OP_GOTO: + s += st->a - 1; // offset the s++ + break; + + case OP_CALL0: + case OP_CALL1: + case OP_CALL2: + case OP_CALL3: + case OP_CALL4: + case OP_CALL5: + case OP_CALL6: + case OP_CALL7: + case OP_CALL8: + pr_argc = st->op - OP_CALL0; + if (!a->function) + PR_RunError ("NULL function"); + + newf = &pr_functions[a->function]; + + if (newf->first_statement < 0) + { // negative statements are built in functions + i = -newf->first_statement; + if (i >= pr_numbuiltins) + PR_RunError ("Bad builtin call number"); + pr_builtins[i] (); + break; + } + + s = PR_EnterFunction (newf); + break; + + case OP_DONE: + case OP_RETURN: + pr_globals[OFS_RETURN] = pr_globals[st->a]; + pr_globals[OFS_RETURN+1] = pr_globals[st->a+1]; + pr_globals[OFS_RETURN+2] = pr_globals[st->a+2]; + + s = PR_LeaveFunction (); + if (pr_depth == exitdepth) + return; // all done + break; + + case OP_STATE: + ed = PROG_TO_EDICT(pr_global_struct->self); +#ifdef FPS_20 + ed->v.nextthink = pr_global_struct->time + 0.05; +#else + ed->v.nextthink = pr_global_struct->time + 0.1; +#endif + if (a->_float != ed->v.frame) + { + ed->v.frame = a->_float; + } + ed->v.think = b->function; + break; + + default: + PR_RunError ("Bad opcode %i", st->op); + } +} + +} diff --git a/r17/Revamped src/revamped_src/progdefs.h b/r17/Revamped src/revamped_src/progdefs.h new file mode 100755 index 00000000..6681b446 --- /dev/null +++ b/r17/Revamped src/revamped_src/progdefs.h @@ -0,0 +1,24 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +#ifdef QUAKE2 +#include "progdefs.q2" +#else +#include "progdefs.q1" +#endif diff --git a/r17/Revamped src/revamped_src/progdefs.q1 b/r17/Revamped src/revamped_src/progdefs.q1 new file mode 100755 index 00000000..c976cf8e --- /dev/null +++ b/r17/Revamped src/revamped_src/progdefs.q1 @@ -0,0 +1,143 @@ + +/* file generated by qcc, do not modify */ + +typedef struct +{ int pad[28]; + int self; + int other; + int world; + float time; + float frametime; + float force_retouch; + string_t mapname; + float deathmatch; + float coop; + float teamplay; + float serverflags; + float total_secrets; + float total_monsters; + float found_secrets; + float killed_monsters; + float parm1; + float parm2; + float parm3; + float parm4; + float parm5; + float parm6; + float parm7; + float parm8; + float parm9; + float parm10; + float parm11; + float parm12; + float parm13; + float parm14; + float parm15; + float parm16; + vec3_t v_forward; + vec3_t v_up; + vec3_t v_right; + float trace_allsolid; + float trace_startsolid; + float trace_fraction; + vec3_t trace_endpos; + vec3_t trace_plane_normal; + float trace_plane_dist; + int trace_ent; + float trace_inopen; + float trace_inwater; + int msg_entity; + func_t main; + func_t StartFrame; + func_t PlayerPreThink; + func_t PlayerPostThink; + func_t ClientKill; + func_t ClientConnect; + func_t PutClientInServer; + func_t ClientDisconnect; + func_t SetNewParms; + func_t SetChangeParms; +} globalvars_t; + +typedef struct +{ + float modelindex; + vec3_t absmin; + vec3_t absmax; + float ltime; + float movetype; + float solid; + vec3_t origin; + vec3_t oldorigin; + vec3_t velocity; + vec3_t angles; + vec3_t avelocity; + vec3_t punchangle; + string_t classname; + string_t model; + float frame; + float skin; + float effects; + vec3_t mins; + vec3_t maxs; + vec3_t size; + func_t touch; + func_t use; + func_t think; + func_t blocked; + float nextthink; + int groundentity; + float health; + float frags; + float weapon; + string_t weaponmodel; + float weaponframe; + float currentammo; + float ammo_shells; + float ammo_nails; + float ammo_rockets; + float ammo_cells; + float items; + float takedamage; + int chain; + float deadflag; + vec3_t view_ofs; + float button0; + float button1; + float button2; + float impulse; + float fixangle; + vec3_t v_angle; + float idealpitch; + string_t netname; + int enemy; + float flags; + float colormap; + float team; + float max_health; + float teleport_time; + float armortype; + float armorvalue; + float waterlevel; + float watertype; + float ideal_yaw; + float yaw_speed; + int aiment; + int goalentity; + float spawnflags; + string_t target; + string_t targetname; + float dmg_take; + float dmg_save; + int dmg_inflictor; + int owner; + vec3_t movedir; + string_t message; + float sounds; + string_t noise; + string_t noise1; + string_t noise2; + string_t noise3; +} entvars_t; + +#define PROGHEADER_CRC 5927 diff --git a/r17/Revamped src/revamped_src/progs.h b/r17/Revamped src/revamped_src/progs.h new file mode 100755 index 00000000..e2a05f03 --- /dev/null +++ b/r17/Revamped src/revamped_src/progs.h @@ -0,0 +1,134 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +#include "pr_comp.h" // defs shared with qcc +#include "progdefs.h" // generated by program cdefs + +typedef union eval_s +{ + string_t string; + float _float; + float vector[3]; + func_t function; + int _int; + int edict; +} eval_t; + +#define MAX_ENT_LEAFS 16 +typedef struct edict_s +{ + qboolean free; + link_t area; // linked to a division node or leaf + + int num_leafs; + short leafnums[MAX_ENT_LEAFS]; + + entity_state_t baseline; + + float freetime; // sv.time when the object was freed + entvars_t v; // C exported fields from progs +// other fields from progs come immediately after +} edict_t; +#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area) + +//============================================================================ + +extern dprograms_t *progs; +extern dfunction_t *pr_functions; +extern char *pr_strings; +extern ddef_t *pr_globaldefs; +extern ddef_t *pr_fielddefs; +extern dstatement_t *pr_statements; +extern globalvars_t *pr_global_struct; +extern float *pr_globals; // same as pr_global_struct + +extern int pr_edict_size; // in bytes + +//============================================================================ + +void PR_Init (void); + +void PR_ExecuteProgram (func_t fnum); +void PR_LoadProgs (void); + +void PR_Profile_f (void); + +edict_t *ED_Alloc (void); +void ED_Free (edict_t *ed); + +char *ED_NewString (char *string); +// returns a copy of the string allocated from the server's string heap + +void ED_Print (edict_t *ed); +void ED_Write (FILE *f, edict_t *ed); +char *ED_ParseEdict (char *data, edict_t *ent); + +void ED_WriteGlobals (FILE *f); +void ED_ParseGlobals (char *data); + +void ED_LoadFromFile (char *data); + +//define EDICT_NUM(n) ((edict_t *)(sv.edicts+ (n)*pr_edict_size)) +//define NUM_FOR_EDICT(e) (((byte *)(e) - sv.edicts)/pr_edict_size) + +edict_t *EDICT_NUM(int n); +int NUM_FOR_EDICT(edict_t *e); + +#define NEXT_EDICT(e) ((edict_t *)( (byte *)e + pr_edict_size)) + +#define EDICT_TO_PROG(e) ((byte *)e - (byte *)sv.edicts) +#define PROG_TO_EDICT(e) ((edict_t *)((byte *)sv.edicts + e)) + +//============================================================================ + +#define G_FLOAT(o) (pr_globals[o]) +#define G_INT(o) (*(int *)&pr_globals[o]) +#define G_EDICT(o) ((edict_t *)((byte *)sv.edicts+ *(int *)&pr_globals[o])) +#define G_EDICTNUM(o) NUM_FOR_EDICT(G_EDICT(o)) +#define G_VECTOR(o) (&pr_globals[o]) +#define G_STRING(o) (pr_strings + *(string_t *)&pr_globals[o]) +#define G_FUNCTION(o) (*(func_t *)&pr_globals[o]) + +#define E_FLOAT(e,o) (((float*)&e->v)[o]) +#define E_INT(e,o) (*(int *)&((float*)&e->v)[o]) +#define E_VECTOR(e,o) (&((float*)&e->v)[o]) +#define E_STRING(e,o) (pr_strings + *(string_t *)&((float*)&e->v)[o]) + +extern int type_size[8]; + +typedef void (*builtin_t) (void); +extern builtin_t *pr_builtins; +extern int pr_numbuiltins; + +extern int pr_argc; + +extern qboolean pr_trace; +extern dfunction_t *pr_xfunction; +extern int pr_xstatement; + +extern unsigned short pr_crc; + +void PR_RunError (char *error, ...); + +void ED_PrintEdicts (void); +void ED_PrintNum (int ent); + +eval_t *GetEdictFieldValue(edict_t *ed, char *field); + diff --git a/r17/Revamped src/revamped_src/protocol.h b/r17/Revamped src/revamped_src/protocol.h new file mode 100755 index 00000000..d7832538 --- /dev/null +++ b/r17/Revamped src/revamped_src/protocol.h @@ -0,0 +1,182 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// protocol.h -- communications protocols + +#define PROTOCOL_VERSION 15 + +// if the high bit of the servercmd is set, the low bits are fast update flags: +#define U_MOREBITS (1<<0) +#define U_ORIGIN1 (1<<1) +#define U_ORIGIN2 (1<<2) +#define U_ORIGIN3 (1<<3) +#define U_ANGLE2 (1<<4) +#define U_NOLERP (1<<5) // don't interpolate movement +#define U_FRAME (1<<6) +#define U_SIGNAL (1<<7) // just differentiates from other updates + +// svc_update can pass all of the fast update bits, plus more +#define U_ANGLE1 (1<<8) +#define U_ANGLE3 (1<<9) +#define U_MODEL (1<<10) +#define U_COLORMAP (1<<11) +#define U_SKIN (1<<12) +#define U_EFFECTS (1<<13) +#define U_LONGENTITY (1<<14) + +// Tomaz - QC Alpha Scale Glow Control Begin + +#define U_EXTEND1 (1<<15) +#define U_SCALE (1<<16) +#define U_ALPHA (1<<17) +#define U_GLOW_SIZE (1<<18) +#define U_GLOW_RED (1<<19) +#define U_GLOW_GREEN (1<<20) +#define U_GLOW_BLUE (1<<21) + +// Tomaz - QC Alpha Scale Glow Control End + +#define SU_VIEWHEIGHT (1<<0) +#define SU_IDEALPITCH (1<<1) +#define SU_PUNCH1 (1<<2) +#define SU_PUNCH2 (1<<3) +#define SU_PUNCH3 (1<<4) +#define SU_VELOCITY1 (1<<5) +#define SU_VELOCITY2 (1<<6) +#define SU_VELOCITY3 (1<<7) +//define SU_AIMENT (1<<8) AVAILABLE BIT +#define SU_ITEMS (1<<9) +#define SU_ONGROUND (1<<10) // no data follows, the bit is it +#define SU_INWATER (1<<11) // no data follows, the bit is it +#define SU_WEAPONFRAME (1<<12) +#define SU_ARMOR (1<<13) +#define SU_WEAPON (1<<14) + +// a sound with no channel is a local only sound +#define SND_VOLUME (1<<0) // a byte +#define SND_ATTENUATION (1<<1) // a byte +#define SND_LOOPING (1<<2) // a long + + +// defaults for clientinfo messages +#define DEFAULT_VIEWHEIGHT 22 + + +// game types sent by serverinfo +// these determine which intermission screen plays +#define GAME_COOP 0 +#define GAME_DEATHMATCH 1 + +//================== +// note that there are some defs.qc that mirror to these numbers +// also related to svc_strings[] in cl_parse +//================== + +// +// server to client +// +#define svc_bad 0 +#define svc_nop 1 +#define svc_disconnect 2 +#define svc_updatestat 3 // [byte] [long] +#define svc_version 4 // [long] server version +#define svc_setview 5 // [short] entity number +#define svc_sound 6 // +#define svc_time 7 // [float] server time +#define svc_print 8 // [string] null terminated string +#define svc_stufftext 9 // [string] stuffed into client's console buffer + // the string should be \n terminated +#define svc_setangle 10 // [angle3] set the view angle to this absolute value + +#define svc_serverinfo 11 // [long] version + // [string] signon string + // [string]..[0]model cache + // [string]...[0]sounds cache +#define svc_lightstyle 12 // [byte] [string] +#define svc_updatename 13 // [byte] [string] +#define svc_updatefrags 14 // [byte] [short] +#define svc_clientdata 15 // +#define svc_stopsound 16 // +#define svc_updatecolors 17 // [byte] [byte] +#define svc_particle 18 // [vec3] +#define svc_damage 19 + +#define svc_spawnstatic 20 +// svc_spawnbinary 21 +#define svc_spawnbaseline 22 + +#define svc_temp_entity 23 + +#define svc_setpause 24 // [byte] on / off +#define svc_signonnum 25 // [byte] used for the signon sequence + +#define svc_centerprint 26 // [string] to put in center of the screen + +#define svc_killedmonster 27 +#define svc_foundsecret 28 + +#define svc_spawnstaticsound 29 // [coord3] [byte] samp [byte] vol [byte] aten + +#define svc_intermission 30 // [string] music +#define svc_finale 31 // [string] music [string] text + +#define svc_cdtrack 32 // [byte] track [byte] looptrack +#define svc_sellscreen 33 + +#define svc_cutscene 34 + +//johnfitz -- new server messages +#define svc_skybox 37 // [string] name +#define svc_fog 41 // [byte] start [byte] end [byte] red [byte] green [byte] blue [float] time + +// +// client to server +// +#define clc_bad 0 +#define clc_nop 1 +#define clc_disconnect 2 +#define clc_move 3 // [usercmd_t] +#define clc_stringcmd 4 // [string] message + + +// +// temp entity events +// +#define TE_SPIKE 0 +#define TE_SUPERSPIKE 1 +#define TE_GUNSHOT 2 +#define TE_EXPLOSION 3 +#define TE_TAREXPLOSION 4 +#define TE_LIGHTNING1 5 +#define TE_LIGHTNING2 6 +#define TE_WIZSPIKE 7 +#define TE_KNIGHTSPIKE 8 +#define TE_LIGHTNING3 9 +#define TE_LAVASPLASH 10 +#define TE_TELEPORT 11 +#define TE_EXPLOSION2 12 + +// PGM 01/21/97 +#define TE_BEAM 13 +// PGM 01/21/97 + +#ifdef QUAKE2 +#define TE_IMPLOSION 14 +#define TE_RAILTRAIL 15 +#endif diff --git a/r17/Revamped src/revamped_src/psp/Cygwin_normal_clean.bat.txt b/r17/Revamped src/revamped_src/psp/Cygwin_normal_clean.bat.txt new file mode 100755 index 00000000..a333c273 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Cygwin_normal_clean.bat.txt @@ -0,0 +1,6 @@ +@echo off + +D: +chdir D:\cygwin\bin + +bash --login -i -c "cd \"Kurok\psp\"; make -f MakefileNormal clean" diff --git a/r17/Revamped src/revamped_src/psp/Cygwin_normal_eboot.bat b/r17/Revamped src/revamped_src/psp/Cygwin_normal_eboot.bat new file mode 100755 index 00000000..15753db7 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Cygwin_normal_eboot.bat @@ -0,0 +1,6 @@ +@echo off + +D: +chdir D:\cygwin\bin + +bash --login -i -c "cd \"Kurok\psp\"; make -f MakefileNormal eboot" diff --git a/r17/Revamped src/revamped_src/psp/Cygwin_normal_install.bat.txt b/r17/Revamped src/revamped_src/psp/Cygwin_normal_install.bat.txt new file mode 100755 index 00000000..9dec3b21 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Cygwin_normal_install.bat.txt @@ -0,0 +1,6 @@ +@echo off + +D: +chdir D:\cygwin\bin + +bash --login -i -c "cd \"Kurok\psp\"; make -f MakefileNormal install" diff --git a/r17/Revamped src/revamped_src/psp/Cygwin_normal_make.bat.txt b/r17/Revamped src/revamped_src/psp/Cygwin_normal_make.bat.txt new file mode 100755 index 00000000..f208a726 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Cygwin_normal_make.bat.txt @@ -0,0 +1,7 @@ +@echo off + +D: +chdir D:\cygwin\bin + +bash --login -i -c "cd \"Kurok\psp\"; make -f MakefileNormal" +cmd \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/Cygwin_slim_clean.bat.txt b/r17/Revamped src/revamped_src/psp/Cygwin_slim_clean.bat.txt new file mode 100755 index 00000000..4cb5890c --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Cygwin_slim_clean.bat.txt @@ -0,0 +1,6 @@ +@echo off + +D: +chdir D:\cygwin\bin + +bash --login -i -c "cd \"Kurok\psp\"; make clean" diff --git a/r17/Revamped src/revamped_src/psp/Cygwin_slim_eboot.bat.txt b/r17/Revamped src/revamped_src/psp/Cygwin_slim_eboot.bat.txt new file mode 100755 index 00000000..d94369a2 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Cygwin_slim_eboot.bat.txt @@ -0,0 +1,6 @@ +@echo off + +D: +chdir D:\cygwin\bin + +bash --login -i -c "cd \"Kurok\psp\"; make eboot" diff --git a/r17/Revamped src/revamped_src/psp/Cygwin_slim_install.bat.txt b/r17/Revamped src/revamped_src/psp/Cygwin_slim_install.bat.txt new file mode 100755 index 00000000..7f8072b0 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Cygwin_slim_install.bat.txt @@ -0,0 +1,6 @@ +@echo off + +D: +chdir D:\cygwin\bin + +bash --login -i -c "cd \"Kurok\psp\"; make install" diff --git a/r17/Revamped src/revamped_src/psp/Cygwin_slim_make.bat.txt b/r17/Revamped src/revamped_src/psp/Cygwin_slim_make.bat.txt new file mode 100755 index 00000000..a9475465 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Cygwin_slim_make.bat.txt @@ -0,0 +1,7 @@ +@echo off + +D: +chdir D:\cygwin\bin + +bash --login -i -c "cd \"Kurok\psp\"; make" +cmd \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/Makefile b/r17/Revamped src/revamped_src/psp/Makefile new file mode 100755 index 00000000..f9555d32 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Makefile @@ -0,0 +1,196 @@ +#================= +# ZQuake Makefile +#================= + +#============================================================================== +# Here are the targets: + +.PHONY: default all server gl soft null + +default: gl server soft +all: server gl soft null + +#============================================================================== +# Architecture detection +# +# MACHINE = i686-linux-gnu, etc +# ARCH = mingw32 x86-linux ppc-linux x86-darwin ppc-darwin +# OS = windows linux darwin + +MACHINE = $(shell $(CC) -dumpmachine) +ARCH = $(shell echo $(MACHINE) | sed -e 's/.*mingw32.*/mingw32/g' \ + -e 's/i.86/x86/g' -e 's/-gnu//' -e 's/powerpc/ppc/') + # -e 's/\-.*//g' - + +OS = $(shell echo $(ARCH) | sed -e 's/.*-//') +ifeq ($(OS),mingw32) +OS = windows +endif + +#============================================================================== + + +CC = gcc + + +PRODUCT_DIR=release +GL_OBJ_DIR=release/gl +SOFT_OBJ_DIR=release/soft +SERVER_OBJ_DIR=release/server +NULL_OBJ_DIR=release/null + + +#------------------------------------------------------------------------------ + +CFLAGS = -DVWEP_TEST -DHALFLIFEBSP +CFLAGS += -Wall -Wno-format-y2k + +# optimizations (should be only for release) +CFLAGS +=-ffast-math -fomit-frame-pointer -fexpensive-optimizations + +ifeq ($(ARCH),mingw32) + CFLAGS += -D_WIN32 -DMINGW32 +endif +ifeq ($(OS),linux) + CFLAGS += -DUSE_ALSA -DUSE_VMODE -DUSE_DGA +endif +ifeq ($(ARCH),ppc-linux) + CFLAGS += -DBIGENDIAN +endif +ifeq ($(OS),darwin) + CFLAGS += -DHAVE_STRLCPY -DHAVE_STRLCAT +endif +ifeq ($(ARCH),ppc-darwin) + CFLAGS += -DBIGENDIAN +endif + +SERVER_CFLAGS = -DSERVERONLY +GL_CFLAGS = -DGLQUAKE +SW_CFLAGS = +NULL_CFLAGS = + +#------------------------------------------------------------------------------ + +LDFLAGS = +GL_LDFLAGS = +SW_LDFLAGS = +ifeq ($(ARCH),mingw32) + LDFLAGS +=-lws2_32 -luser32 -lwinmm -ldxguid -lgdi32 + GL_LDFLAGS =-mwindows -lopengl32 + SW_LDFLAGS =-mwindows -lddraw +endif +ifeq ($(OS),darwin) + LDFLAGS +=-framework "CoreAudio" -framework OpenGL +endif +ifeq ($(OS),linux) + LDFLAGS +=-lm -lGL -lXxf86vm -lXxf86dga + # -L/usr/X11R6/lib -lX11 -lXext +endif + +#============================================================================== + +CLIENT_C_FILES = cl_cam cl_cmd cl_demo cl_draw cl_effects cl_ents cl_input \ + cl_main cl_nqdemo cl_parse cl_pred cl_sbar cl_screen cl_tent cl_view \ + console keys menu teamplay textencoding +GL_C_FILES = sv_save skin rc_wad rc_image rc_pixops \ + gl_draw gl_mesh gl_model gl_ngraph gl_ralias gl_refrag gl_rlight \ + gl_rmain gl_rmisc gl_rsprite gl_rsurf gl_texture gl_warp gl_sky +SW_C_FILES = sv_save skin rc_wad rc_image rc_pixops nonintel \ + d_edge d_fill d_init d_modech d_polyse d_sky d_sprite d_surf d_vars \ + d_zpoint r_aclip r_alias r_bsp r_draw r_edge r_efrag r_light r_main \ + r_misc r_model r_part r_rast r_scan r_sky r_sprite r_surf r_vars +SERVER_C_FILES = sv_bot sv_ccmds sv_ents sv_init sv_main sv_master \ + sv_move sv_nchan sv_phys sv_send sv_user sv_world \ + pr_cmds pr_edict pr_exec +COMMON_C_FILES = cmd cmodel com_msg com_mapcheck common crc cvar host mathlib mdfour \ + net_chan pmove pmovetst qlib q_shared version zone +NULL_C_FILES = sv_save rc_null vid_null snd_null cd_null in_null sys_null +ifeq ($(ARCH),mingw32) +ZQDS_PLATFORM_C_FILES = sys_win net_wins +ZQGL_PLATFORM_C_FILES = sys_win net_wins snd_dma snd_mem snd_mix snd_win cd_win in_win vid_wgl +ZQSW_PLATFORM_C_FILES = sys_win net_wins snd_dma snd_mem snd_mix snd_win cd_win in_win vid_ddraw +NULL_C_FILES += net_wins +else +ZQDS_PLATFORM_C_FILES = sv_sys_unix net_udp +ZQGL_PLATFORM_C_FILES = net_udp +ZQSW_PLATFORM_C_FILES = net_udp +NULL_C_FILES += net_udp +endif +ifeq ($(OS),darwin) +ZQGL_PLATFORM_C_FILES += snd_null cd_null +ZQSW_PLATFORM_C_FILES += snd_null cd_null +endif +ifeq ($(OS),linux) +ZQGL_PLATFORM_C_FILES += sys_linux cd_linux snd_dma snd_mem snd_mix snd_linux snd_oss snd_alsa vid_glx +ZQSW_PLATFORM_C_FILES += sys_linux cd_linux snd_dma snd_mem snd_mix snd_linux snd_oss snd_alsa vid_x +endif +ZQDS_C_FILES = $(SERVER_C_FILES) $(COMMON_C_FILES) $(ZQDS_PLATFORM_C_FILES) cl_null +ZQSW_C_FILES = $(CLIENT_C_FILES) $(ZQSW_PLATFORM_C_FILES) $(SW_C_FILES) $(SERVER_C_FILES) $(COMMON_C_FILES) +ZQGL_C_FILES = $(CLIENT_C_FILES) $(ZQGL_PLATFORM_C_FILES) $(GL_C_FILES) $(SERVER_C_FILES) $(COMMON_C_FILES) +ZQNULL_C_FILES = $(CLIENT_C_FILES) $(SERVER_C_FILES) $(COMMON_C_FILES) $(NULL_C_FILES) +ZQDS_C_OBJS = $(addprefix $(SERVER_OBJ_DIR)/, $(addsuffix .o, $(ZQDS_C_FILES))) +ZQGL_C_OBJS = $(addprefix $(GL_OBJ_DIR)/, $(addsuffix .o, $(ZQGL_C_FILES))) +ZQSW_C_OBJS = $(addprefix $(SOFT_OBJ_DIR)/, $(addsuffix .o, $(ZQSW_C_FILES))) +ZQNULL_C_OBJS = $(addprefix $(NULL_OBJ_DIR)/, $(addsuffix .o, $(ZQNULL_C_FILES))) + +#============================================================================== + +printvars: + @echo "MACHINE = $(MACHINE)" + @echo "ARCH = $(ARCH)" + @echo "OS = $(OS)" + @echo "" + @echo "PRODUCT_DIR = $(PRODUCT_DIR)" + @echo "" + @echo "CFLAGS = $(CFLAGS)" + @echo "LDFLAGS = $(LDFLAGS)" + +#.PHONY: server +#server: +# @echo [MAKE] server +# @make server_do +#server_do: $(PRODUCT_DIR)/zqds +server: $(PRODUCT_DIR)/zqds +$(PRODUCT_DIR)/zqds: $(ZQDS_C_OBJS) + @echo [LINK] $@ + @$(CC) -o $@ $(ZQDS_C_OBJS) $(LDFLAGS) +$(ZQDS_C_OBJS): $(SERVER_OBJ_DIR)/%.o: %.c + @-mkdir -p $(SERVER_OBJ_DIR) + @echo [CC] $< + @$(CC) $(CFLAGS) $(SERVER_CFLAGS) -c -o $@ $< +#------------------------------------------------------------------------------ +gl: $(PRODUCT_DIR)/zquake-gl +$(PRODUCT_DIR)/zquake-gl: $(ZQGL_C_OBJS) + @echo [LINK] $@ + @$(CC) -o $@ $(ZQGL_C_OBJS) $(LDFLAGS) $(GL_LDFLAGS) +$(ZQGL_C_OBJS): $(GL_OBJ_DIR)/%.o: %.c + @-mkdir -p $(GL_OBJ_DIR) + @echo [CC] $< + @$(CC) $(CFLAGS) $(GL_CFLAGS) -c -o $@ $< +#------------------------------------------------------------------------------ +soft: $(PRODUCT_DIR)/zquake +$(PRODUCT_DIR)/zquake: $(ZQSW_C_OBJS) + @echo [LINK] $@ + @$(CC) -o $@ $(ZQSW_C_OBJS) $(LDFLAGS) $(SW_LDFLAGS) +$(ZQSW_C_OBJS): $(SOFT_OBJ_DIR)/%.o: %.c + @-mkdir -p $(SOFT_OBJ_DIR) + @echo [CC] $< + @$(CC) $(CFLAGS) $(SW_CFLAGS) -c -o $@ $< +#------------------------------------------------------------------------------ +null: $(PRODUCT_DIR)/zquake-null +$(PRODUCT_DIR)/zquake-null: $(ZQNULL_C_OBJS) + @echo [LINK] $@ + @$(CC) -o $@ $(ZQNULL_C_OBJS) $(LDFLAGS) +$(ZQNULL_C_OBJS): $(NULL_OBJ_DIR)/%.o: %.c + @-mkdir -p $(NULL_OBJ_DIR) + @echo [CC] $< + @$(CC) $(CFLAGS) $(NULL_CFLAGS) -c -o $@ $< +#------------------------------------------------------------------------------ +clean: + @echo [CLEAN] + @-rm $(SERVER_OBJ_DIR)/*.o $(SOFT_OBJ_DIR)/*.o $(GL_OBJ_DIR)/*.o $(NULL_OBJ_DIR)/*.o 2>/dev/null + @-rmdir $(SERVER_OBJ_DIR) $(SOFT_OBJ_DIR) $(GL_OBJ_DIR) $(NULL_OBJ_DIR) 2>/dev/null + @-rm $(PRODUCT_DIR)/zqds $(PRODUCT_DIR)/zquake $(PRODUCT_DIR)/zquake-gl $(PRODUCT_DIR)/zquake-null 2>/dev/null + @-rm $(PRODUCT_DIR) 2>/dev/null + +#============================================================================== diff --git a/r17/Revamped src/revamped_src/psp/Makefile.txt b/r17/Revamped src/revamped_src/psp/Makefile.txt new file mode 100755 index 00000000..e81bd263 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Makefile.txt @@ -0,0 +1,252 @@ +# Build type. +# Must be one of the types in VALID_VIDEOS. +VALID_VIDEOS = SOFTWARE HARDWARE +VIDEO = HARDWARE + +VAILD_MP3LIBS = MP3SOFTWARE MP3HARDWARE +MP3LIB = MP3HARDWARE +#MP3LIB = MP3SOFTWARE + +#MODEL_N=-DNORMAL_MODEL +MODEL_S=-DSLIM_MODEL + +#PSP_FW_VERSION=390 + +# If GPROF is used it builds an ELF, hence the EBOOT needs to be in GAME150 +#USE_GPROF = 1 + +# Site specific variables. +INSTALL_DIR = $(PSP_MOUNT)/PSP/GAME/Kurok + +# Compiler specific variables. +PSPSDK = $(shell psp-config --pspsdk-path) +ifeq ($(PSPSDK),) +$(error PSPSDK wasn't set) +endif +PSPLIBSDIR = $(PSPSDK)/.. + +# Project specific variables. +VERSION = 0.4 64MB +SRC_DIR = .. +OBJ_DIR = slim +TARGET = $(OBJ_DIR)/Quake +PSP_LARGE_MEMORY = 1 +PSP_EBOOT_TITLE = Kurok $(VERSION) +PSP_EBOOT_ICON = pics/icon.png +PSP_EBOOT_PIC1 = pics/pic1.png +PSP_EBOOT_SFO = $(OBJ_DIR)/PARAM.SFO +PSP_EBOOT = $(OBJ_DIR)/EBOOT.PBP +DIST_DIR = dist +DIST_FILES = readme.html gpl.txt Quake/EBOOT.PBP +ZIP_FILE = Kurok_v$(VERSION).zip + +#ifeq ($(USE_GPROF),1) +#GPROF_OBJS = $(OBJ_DIR)/psp/prof.o $(OBJ_DIR)/psp/mcount.o +#GPROF_FLAGS = -pg -DPROFILE +#else +#BUILD_PRX = 1 +#endif + +BUILD_PRX = 1 + +# Object files used regardless of video back end. +COMMON_OBJS = \ + $(OBJ_DIR)/psp/battery.o \ + $(OBJ_DIR)/psp/input.o \ + $(OBJ_DIR)/psp/main.o \ + $(OBJ_DIR)/psp/math.o \ + $(OBJ_DIR)/psp/sound.o \ + $(OBJ_DIR)/psp/system.o \ + $(OBJ_DIR)/psp/module.o \ + $(OBJ_DIR)/psp/network.o \ + $(OBJ_DIR)/psp/network_psp.o \ + $(OBJ_DIR)/psp/gethost.o \ + $(OBJ_DIR)/psp/fnmatch.o \ + \ + $(OBJ_DIR)/chase.o \ + $(OBJ_DIR)/cl_demo.o \ + $(OBJ_DIR)/cl_input.o \ + $(OBJ_DIR)/cl_main.o \ + $(OBJ_DIR)/cl_parse.o \ + $(OBJ_DIR)/cl_tent.o \ + $(OBJ_DIR)/cmd.o \ + $(OBJ_DIR)/common.o \ + $(OBJ_DIR)/console.o \ + $(OBJ_DIR)/crc.o \ + $(OBJ_DIR)/cvar.o \ + $(OBJ_DIR)/host.o \ + $(OBJ_DIR)/host_cmd.o \ + $(OBJ_DIR)/keys.o \ + $(OBJ_DIR)/mathlib.o \ + $(OBJ_DIR)/menu.o \ + $(OBJ_DIR)/net_dgrm.o \ + $(OBJ_DIR)/net_loop.o \ + $(OBJ_DIR)/net_main.o \ + $(OBJ_DIR)/net_vcr.o \ + $(OBJ_DIR)/pr_cmds.o \ + $(OBJ_DIR)/pr_edict.o \ + $(OBJ_DIR)/pr_exec.o \ + $(OBJ_DIR)/r_part.o \ + $(OBJ_DIR)/snd_dma.o \ + $(OBJ_DIR)/snd_mem.o \ + $(OBJ_DIR)/snd_mix.o \ + $(OBJ_DIR)/sbar.o \ + $(OBJ_DIR)/sv_main.o \ + $(OBJ_DIR)/sv_move.o \ + $(OBJ_DIR)/sv_phys.o \ + $(OBJ_DIR)/sv_user.o \ + $(OBJ_DIR)/view.o \ + $(OBJ_DIR)/wad.o \ + $(OBJ_DIR)/world.o \ + $(OBJ_DIR)/zone.o + +# Object files used only under software video. +SOFTWARE_VIDEO_ONLY_OBJS = \ + $(OBJ_DIR)/psp/video_software.o \ + \ + $(OBJ_DIR)/d_edge.o \ + $(OBJ_DIR)/d_fill.o \ + $(OBJ_DIR)/d_init.o \ + $(OBJ_DIR)/d_modech.o \ + $(OBJ_DIR)/d_part.o \ + $(OBJ_DIR)/d_polyse.o \ + $(OBJ_DIR)/d_scan.o \ + $(OBJ_DIR)/d_sky.o \ + $(OBJ_DIR)/d_sprite.o \ + $(OBJ_DIR)/d_surf.o \ + $(OBJ_DIR)/d_vars.o \ + $(OBJ_DIR)/d_zpoint.o \ + $(OBJ_DIR)/draw.o \ + $(OBJ_DIR)/model.o \ + $(OBJ_DIR)/nonintel.o \ + $(OBJ_DIR)/r_aclip.o \ + $(OBJ_DIR)/r_alias.o \ + $(OBJ_DIR)/r_bsp.o \ + $(OBJ_DIR)/r_draw.o \ + $(OBJ_DIR)/r_edge.o \ + $(OBJ_DIR)/r_efrag.o \ + $(OBJ_DIR)/r_light.o \ + $(OBJ_DIR)/r_main.o \ + $(OBJ_DIR)/r_misc.o \ + $(OBJ_DIR)/r_sky.o \ + $(OBJ_DIR)/r_sprite.o \ + $(OBJ_DIR)/r_surf.o \ + $(OBJ_DIR)/r_vars.o \ + $(OBJ_DIR)/screen.o +SOFTWARE_VIDEO_ONLY_FLAGS = -DPSP_SOFTWARE_VIDEO + +# Object files used only under hardware video. +HARDWARE_VIDEO_ONLY_OBJS = \ + $(OBJ_DIR)/psp/clipping.o \ + $(OBJ_DIR)/psp/video_hardware.o \ + $(OBJ_DIR)/psp/video_hardware_draw.o \ + $(OBJ_DIR)/psp/video_hardware_fog.o \ + $(OBJ_DIR)/psp/video_hardware_entity_fragment.o \ + $(OBJ_DIR)/psp/video_hardware_light.o \ + $(OBJ_DIR)/psp/video_hardware_main.o \ + $(OBJ_DIR)/psp/video_hardware_mesh.o \ + $(OBJ_DIR)/psp/video_hardware_misc.o \ + $(OBJ_DIR)/psp/video_hardware_model.o \ + $(OBJ_DIR)/psp/video_hardware_screen.o \ + $(OBJ_DIR)/psp/video_hardware_surface.o \ + $(OBJ_DIR)/psp/video_hardware_warp.o \ + $(OBJ_DIR)/psp/video_vertex_lighting.o \ + $(OBJ_DIR)/psp/vram.o \ + $(OBJ_DIR)/psp/pspDveManager.o +HARDWARE_VIDEO_ONLY_FLAGS = -DPSP_HARDWARE_VIDEO + +# Object files used only under hardware mp3. +MP3HARDWARE_MP3LIB_ONLY_OBJS = \ + $(OBJ_DIR)/psp/cd.o \ + $(OBJ_DIR)/psp/mp3.o +MP3HARDWARE_MP3LIB_ONLY_FLAGS = -DPSP_MP3HARDWARE_MP3LIB + +# Object files used only under software mp3. +MP3SOFTWARE_MP3LIB_ONLY_OBJS = \ + $(OBJ_DIR)/psp/cdmad.o +MP3SOFTWARE_MP3LIB_ONLY_FLAGS = -DPSP_MP3SOFTWARE_MP3LIB + +# Set up the object files depending on the build. +ifeq ($($(VIDEO)_VIDEO_ONLY_OBJS),) +$(error Unrecognised VIDEO type '$(VIDEO)'. It must be one of $(VALID_VIDEOS)) +endif + +ifeq ($($(MP3LIB)_MP3LIB_ONLY_OBJS),) +$(error Unrecognised MP3LIB type '$(MP3LIB)'. It must be one of $(VALID_MP3LIBS)) +endif + +OBJS = $($(VIDEO)_VIDEO_ONLY_OBJS) $($(MP3LIB)_MP3LIB_ONLY_OBJS) $(COMMON_OBJS) $(GPROF_OBJS) + +# Compiler flags. +CFLAGS = -ffast-math -O3 -G0 $(GPROF_FLAGS) -Wall -Wno-trigraphs -Winline -DPSP $(MODEL_S) $($(VIDEO)_VIDEO_ONLY_FLAGS) $($(MP3LIB)_MP3LIB_ONLY_FLAGS) -g +CXXFLAGS = -fno-rtti -Wcast-qual +ASFLAGS = $(CFLAGS) -c + +# Libs. +GU_LIBS = -lpspgum_vfpu -lpspvfpu -lpspgu +AUDIO_LIBS = -lpspaudiolib -lpspaudio -lpspaudiocodec m33libs/lib/libpspkubridge.a +#madlibs/libmad.a +MISC_LIBS = -lpsprtc -lpsppower +STD_LIBS = -lstdc++ -lm -lc +LIBS = $(GU_LIBS) $(AUDIO_LIBS) $(MISC_LIBS) $(STD_LIBS) -lpspwlan -lpspnet_adhoc -lpspnet_adhocctl + +# What else to clean. +EXTRA_CLEAN = $(foreach FILE,$(ZIP_FILE) Quake/EBOOT.PBP,$(DIST_DIR)/$(FILE)) + +# All target. +all: $(PSP_EBOOT) + +# What is an install? +install: $(INSTALL_DIR)/EBOOT.PBP + +# How to install. +$(INSTALL_DIR)/EBOOT.PBP: $(PSP_EBOOT) + @echo Installing $(PSP_EBOOT) to $@... + @-mkdir -p $(dir $@) + @cp $(PSP_EBOOT) $@ + +# How to build the distribution. +distro: clean $(ZIP_FILE) + @echo Distribution prepared. + +$(DIST_DIR)/Quake/EBOOT.PBP: $(PSP_EBOOT) + @echo Copying $< to $@... + @-mkdir -p $(dir $@) + @cp $< $@ + +$(ZIP_FILE): $(foreach FILE,$(DIST_FILES),$(DIST_DIR)/$(FILE)) + @echo Creating $(DIST_DIR)/$(ZIP_FILE)... + @-rm -rf $(ZIP_FILE) + @cd $(DIST_DIR) && zip -r -q -9 -o $(ZIP_FILE) $(DIST_FILES) + +# How to compile an S file. +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.S + @echo $(notdir $<) + @mkdir -p $(dir $@) + @$(CC) $(CFLAGS) -c $< -o $@ + +# How to compile a C file. +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c + @echo $(notdir $<) + @mkdir -p $(dir $@) + @$(CC) $(CFLAGS) -c $< -o $@ + +# How to compile a C++ file. +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp + @echo $(notdir $<) + @mkdir -p $(dir $@) + @$(CXX) $(CXXFLAGS) -c $< -o $@ + +# Use the standard PSPSDK build stuff. +include $(PSPSDK)/lib/build.mak + +ifneq ($(VS_PATH),) +CC = vs-psp-gcc +CXX = vs-psp-g++ +endif + +ifeq ($(BUILD_PRX),1) +OBJ_TYPE = prx +else +OBJ_TYPE = elf +endif diff --git a/r17/Revamped src/revamped_src/psp/MakefileNormal b/r17/Revamped src/revamped_src/psp/MakefileNormal new file mode 100755 index 00000000..8df3c685 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/MakefileNormal @@ -0,0 +1,250 @@ +# Build type. +# Must be one of the types in VALID_VIDEOS. +VALID_VIDEOS = SOFTWARE HARDWARE +VIDEO = HARDWARE + +VAILD_MP3LIBS = MP3SOFTWARE MP3HARDWARE +MP3LIB = MP3HARDWARE +#MP3LIB = MP3SOFTWARE + +MODEL_N=-DNORMAL_MODEL +#MODEL_S=-DSLIM_MODEL + +#PSP_FW_VERSION=390 + +# If GPROF is used it builds an ELF, hence the EBOOT needs to be in GAME150 +#USE_GPROF = 1 + +# Site specific variables. +INSTALL_DIR = $(PSP_MOUNT)/PSP/GAME/Kurok + +# Compiler specific variables. +PSPSDK = $(shell psp-config --pspsdk-path) +ifeq ($(PSPSDK),) +$(error PSPSDK wasn't set) +endif +PSPLIBSDIR = $(PSPSDK)/.. + +# Project specific variables. +VERSION = 0.4 32MB +SRC_DIR = .. +OBJ_DIR = normal +TARGET = $(OBJ_DIR)/Quake +PSP_EBOOT_TITLE = Kurok $(VERSION) +PSP_EBOOT_ICON = pics/icon.png +PSP_EBOOT_PIC1 = pics/pic1.png +PSP_EBOOT_SFO = $(OBJ_DIR)/PARAM.SFO +PSP_EBOOT = $(OBJ_DIR)/EBOOT.PBP +DIST_DIR = dist +DIST_FILES = readme.html gpl.txt Quake/EBOOT.PBP +ZIP_FILE = Kurok_v$(VERSION).zip + +#ifeq ($(USE_GPROF),1) +#GPROF_OBJS = $(OBJ_DIR)/psp/prof.o $(OBJ_DIR)/psp/mcount.o +#GPROF_FLAGS = -pg -DPROFILE +#else +#BUILD_PRX = 1 +#endif + +BUILD_PRX = 1 + +# Object files used regardless of video back end. +COMMON_OBJS = \ + $(OBJ_DIR)/psp/battery.o \ + $(OBJ_DIR)/psp/input.o \ + $(OBJ_DIR)/psp/main.o \ + $(OBJ_DIR)/psp/math.o \ + $(OBJ_DIR)/psp/sound.o \ + $(OBJ_DIR)/psp/system.o \ + $(OBJ_DIR)/psp/module.o \ + $(OBJ_DIR)/psp/network.o \ + $(OBJ_DIR)/psp/network_psp.o \ + $(OBJ_DIR)/psp/gethost.o \ + $(OBJ_DIR)/psp/fnmatch.o \ + \ + $(OBJ_DIR)/chase.o \ + $(OBJ_DIR)/cl_demo.o \ + $(OBJ_DIR)/cl_input.o \ + $(OBJ_DIR)/cl_main.o \ + $(OBJ_DIR)/cl_parse.o \ + $(OBJ_DIR)/cl_tent.o \ + $(OBJ_DIR)/cmd.o \ + $(OBJ_DIR)/common.o \ + $(OBJ_DIR)/console.o \ + $(OBJ_DIR)/crc.o \ + $(OBJ_DIR)/cvar.o \ + $(OBJ_DIR)/host.o \ + $(OBJ_DIR)/host_cmd.o \ + $(OBJ_DIR)/keys.o \ + $(OBJ_DIR)/mathlib.o \ + $(OBJ_DIR)/menu.o \ + $(OBJ_DIR)/net_dgrm.o \ + $(OBJ_DIR)/net_loop.o \ + $(OBJ_DIR)/net_main.o \ + $(OBJ_DIR)/net_vcr.o \ + $(OBJ_DIR)/pr_cmds.o \ + $(OBJ_DIR)/pr_edict.o \ + $(OBJ_DIR)/pr_exec.o \ + $(OBJ_DIR)/r_part.o \ + $(OBJ_DIR)/snd_dma.o \ + $(OBJ_DIR)/snd_mem.o \ + $(OBJ_DIR)/snd_mix.o \ + $(OBJ_DIR)/sbar.o \ + $(OBJ_DIR)/sv_main.o \ + $(OBJ_DIR)/sv_move.o \ + $(OBJ_DIR)/sv_phys.o \ + $(OBJ_DIR)/sv_user.o \ + $(OBJ_DIR)/view.o \ + $(OBJ_DIR)/wad.o \ + $(OBJ_DIR)/world.o \ + $(OBJ_DIR)/zone.o + +# Object files used only under software video. +SOFTWARE_VIDEO_ONLY_OBJS = \ + $(OBJ_DIR)/psp/video_software.o \ + \ + $(OBJ_DIR)/d_edge.o \ + $(OBJ_DIR)/d_fill.o \ + $(OBJ_DIR)/d_init.o \ + $(OBJ_DIR)/d_modech.o \ + $(OBJ_DIR)/d_part.o \ + $(OBJ_DIR)/d_polyse.o \ + $(OBJ_DIR)/d_scan.o \ + $(OBJ_DIR)/d_sky.o \ + $(OBJ_DIR)/d_sprite.o \ + $(OBJ_DIR)/d_surf.o \ + $(OBJ_DIR)/d_vars.o \ + $(OBJ_DIR)/d_zpoint.o \ + $(OBJ_DIR)/draw.o \ + $(OBJ_DIR)/model.o \ + $(OBJ_DIR)/nonintel.o \ + $(OBJ_DIR)/r_aclip.o \ + $(OBJ_DIR)/r_alias.o \ + $(OBJ_DIR)/r_bsp.o \ + $(OBJ_DIR)/r_draw.o \ + $(OBJ_DIR)/r_edge.o \ + $(OBJ_DIR)/r_efrag.o \ + $(OBJ_DIR)/r_light.o \ + $(OBJ_DIR)/r_main.o \ + $(OBJ_DIR)/r_misc.o \ + $(OBJ_DIR)/r_sky.o \ + $(OBJ_DIR)/r_sprite.o \ + $(OBJ_DIR)/r_surf.o \ + $(OBJ_DIR)/r_vars.o \ + $(OBJ_DIR)/screen.o +SOFTWARE_VIDEO_ONLY_FLAGS = -DPSP_SOFTWARE_VIDEO + +# Object files used only under hardware video. +HARDWARE_VIDEO_ONLY_OBJS = \ + $(OBJ_DIR)/psp/clipping.o \ + $(OBJ_DIR)/psp/video_hardware.o \ + $(OBJ_DIR)/psp/video_hardware_draw.o \ + $(OBJ_DIR)/psp/video_hardware_fog.o \ + $(OBJ_DIR)/psp/video_hardware_entity_fragment.o \ + $(OBJ_DIR)/psp/video_hardware_light.o \ + $(OBJ_DIR)/psp/video_hardware_main.o \ + $(OBJ_DIR)/psp/video_hardware_mesh.o \ + $(OBJ_DIR)/psp/video_hardware_misc.o \ + $(OBJ_DIR)/psp/video_hardware_model.o \ + $(OBJ_DIR)/psp/video_hardware_screen.o \ + $(OBJ_DIR)/psp/video_hardware_surface.o \ + $(OBJ_DIR)/psp/video_hardware_warp.o \ + $(OBJ_DIR)/psp/video_vertex_lighting.o \ + $(OBJ_DIR)/psp/vram.o +HARDWARE_VIDEO_ONLY_FLAGS = -DPSP_HARDWARE_VIDEO + +# Object files used only under hardware mp3. +MP3HARDWARE_MP3LIB_ONLY_OBJS = \ + $(OBJ_DIR)/psp/cd.o \ + $(OBJ_DIR)/psp/mp3.o +MP3HARDWARE_MP3LIB_ONLY_FLAGS = -DPSP_MP3HARDWARE_MP3LIB + +# Object files used only under software mp3. +MP3SOFTWARE_MP3LIB_ONLY_OBJS = \ + $(OBJ_DIR)/psp/cdmad.o +MP3SOFTWARE_MP3LIB_ONLY_FLAGS = -DPSP_MP3SOFTWARE_MP3LIB + +# Set up the object files depending on the build. +ifeq ($($(VIDEO)_VIDEO_ONLY_OBJS),) +$(error Unrecognised VIDEO type '$(VIDEO)'. It must be one of $(VALID_VIDEOS)) +endif + +ifeq ($($(MP3LIB)_MP3LIB_ONLY_OBJS),) +$(error Unrecognised MP3LIB type '$(MP3LIB)'. It must be one of $(VALID_MP3LIBS)) +endif + +OBJS = $($(VIDEO)_VIDEO_ONLY_OBJS) $($(MP3LIB)_MP3LIB_ONLY_OBJS) $(COMMON_OBJS) $(GPROF_OBJS) + +# Compiler flags. +CFLAGS = -ffast-math -O3 -G0 $(GPROF_FLAGS) -Wall -Wno-trigraphs -Winline -DPSP $(MODEL_N) $($(VIDEO)_VIDEO_ONLY_FLAGS) $($(MP3LIB)_MP3LIB_ONLY_FLAGS) -g +CXXFLAGS = -fno-rtti -Wcast-qual +ASFLAGS = $(CFLAGS) -c + +# Libs. +GU_LIBS = -lpspgum_vfpu -lpspvfpu -lpspgu +AUDIO_LIBS = -lpspaudiolib -lpspaudio -lpspaudiocodec m33libs/lib/libpspkubridge.a +#madlibs/libmad.a +MISC_LIBS = -lpsprtc -lpsppower +STD_LIBS = -lstdc++ -lm -lc +LIBS = $(GU_LIBS) $(AUDIO_LIBS) $(MISC_LIBS) $(STD_LIBS) -lpspwlan -lpspnet_adhoc -lpspnet_adhocctl + +# What else to clean. +EXTRA_CLEAN = $(foreach FILE,$(ZIP_FILE) Quake/EBOOT.PBP,$(DIST_DIR)/$(FILE)) + +# All target. +all: $(PSP_EBOOT) + +# What is an install? +install: $(INSTALL_DIR)/EBOOT.PBP + +# How to install. +$(INSTALL_DIR)/EBOOT.PBP: $(PSP_EBOOT) + @echo Installing $(PSP_EBOOT) to $@... + @-mkdir -p $(dir $@) + @cp $(PSP_EBOOT) $@ + +# How to build the distribution. +distro: clean $(ZIP_FILE) + @echo Distribution prepared. + +$(DIST_DIR)/Quake/EBOOT.PBP: $(PSP_EBOOT) + @echo Copying $< to $@... + @-mkdir -p $(dir $@) + @cp $< $@ + +$(ZIP_FILE): $(foreach FILE,$(DIST_FILES),$(DIST_DIR)/$(FILE)) + @echo Creating $(DIST_DIR)/$(ZIP_FILE)... + @-rm -rf $(ZIP_FILE) + @cd $(DIST_DIR) && zip -r -q -9 -o $(ZIP_FILE) $(DIST_FILES) + +# How to compile an S file. +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.S + @echo $(notdir $<) + @mkdir -p $(dir $@) + @$(CC) $(CFLAGS) -c $< -o $@ + +# How to compile a C file. +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c + @echo $(notdir $<) + @mkdir -p $(dir $@) + @$(CC) $(CFLAGS) -c $< -o $@ + +# How to compile a C++ file. +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp + @echo $(notdir $<) + @mkdir -p $(dir $@) + @$(CXX) $(CXXFLAGS) -c $< -o $@ + +# Use the standard PSPSDK build stuff. +include $(PSPSDK)/lib/build.mak + +ifneq ($(VS_PATH),) +CC = vs-psp-gcc +CXX = vs-psp-g++ +endif + +ifeq ($(BUILD_PRX),1) +OBJ_TYPE = prx +else +OBJ_TYPE = elf +endif diff --git a/r17/Revamped src/revamped_src/psp/MakefileNormal.htm b/r17/Revamped src/revamped_src/psp/MakefileNormal.htm new file mode 100755 index 00000000..8df3c685 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/MakefileNormal.htm @@ -0,0 +1,250 @@ +# Build type. +# Must be one of the types in VALID_VIDEOS. +VALID_VIDEOS = SOFTWARE HARDWARE +VIDEO = HARDWARE + +VAILD_MP3LIBS = MP3SOFTWARE MP3HARDWARE +MP3LIB = MP3HARDWARE +#MP3LIB = MP3SOFTWARE + +MODEL_N=-DNORMAL_MODEL +#MODEL_S=-DSLIM_MODEL + +#PSP_FW_VERSION=390 + +# If GPROF is used it builds an ELF, hence the EBOOT needs to be in GAME150 +#USE_GPROF = 1 + +# Site specific variables. +INSTALL_DIR = $(PSP_MOUNT)/PSP/GAME/Kurok + +# Compiler specific variables. +PSPSDK = $(shell psp-config --pspsdk-path) +ifeq ($(PSPSDK),) +$(error PSPSDK wasn't set) +endif +PSPLIBSDIR = $(PSPSDK)/.. + +# Project specific variables. +VERSION = 0.4 32MB +SRC_DIR = .. +OBJ_DIR = normal +TARGET = $(OBJ_DIR)/Quake +PSP_EBOOT_TITLE = Kurok $(VERSION) +PSP_EBOOT_ICON = pics/icon.png +PSP_EBOOT_PIC1 = pics/pic1.png +PSP_EBOOT_SFO = $(OBJ_DIR)/PARAM.SFO +PSP_EBOOT = $(OBJ_DIR)/EBOOT.PBP +DIST_DIR = dist +DIST_FILES = readme.html gpl.txt Quake/EBOOT.PBP +ZIP_FILE = Kurok_v$(VERSION).zip + +#ifeq ($(USE_GPROF),1) +#GPROF_OBJS = $(OBJ_DIR)/psp/prof.o $(OBJ_DIR)/psp/mcount.o +#GPROF_FLAGS = -pg -DPROFILE +#else +#BUILD_PRX = 1 +#endif + +BUILD_PRX = 1 + +# Object files used regardless of video back end. +COMMON_OBJS = \ + $(OBJ_DIR)/psp/battery.o \ + $(OBJ_DIR)/psp/input.o \ + $(OBJ_DIR)/psp/main.o \ + $(OBJ_DIR)/psp/math.o \ + $(OBJ_DIR)/psp/sound.o \ + $(OBJ_DIR)/psp/system.o \ + $(OBJ_DIR)/psp/module.o \ + $(OBJ_DIR)/psp/network.o \ + $(OBJ_DIR)/psp/network_psp.o \ + $(OBJ_DIR)/psp/gethost.o \ + $(OBJ_DIR)/psp/fnmatch.o \ + \ + $(OBJ_DIR)/chase.o \ + $(OBJ_DIR)/cl_demo.o \ + $(OBJ_DIR)/cl_input.o \ + $(OBJ_DIR)/cl_main.o \ + $(OBJ_DIR)/cl_parse.o \ + $(OBJ_DIR)/cl_tent.o \ + $(OBJ_DIR)/cmd.o \ + $(OBJ_DIR)/common.o \ + $(OBJ_DIR)/console.o \ + $(OBJ_DIR)/crc.o \ + $(OBJ_DIR)/cvar.o \ + $(OBJ_DIR)/host.o \ + $(OBJ_DIR)/host_cmd.o \ + $(OBJ_DIR)/keys.o \ + $(OBJ_DIR)/mathlib.o \ + $(OBJ_DIR)/menu.o \ + $(OBJ_DIR)/net_dgrm.o \ + $(OBJ_DIR)/net_loop.o \ + $(OBJ_DIR)/net_main.o \ + $(OBJ_DIR)/net_vcr.o \ + $(OBJ_DIR)/pr_cmds.o \ + $(OBJ_DIR)/pr_edict.o \ + $(OBJ_DIR)/pr_exec.o \ + $(OBJ_DIR)/r_part.o \ + $(OBJ_DIR)/snd_dma.o \ + $(OBJ_DIR)/snd_mem.o \ + $(OBJ_DIR)/snd_mix.o \ + $(OBJ_DIR)/sbar.o \ + $(OBJ_DIR)/sv_main.o \ + $(OBJ_DIR)/sv_move.o \ + $(OBJ_DIR)/sv_phys.o \ + $(OBJ_DIR)/sv_user.o \ + $(OBJ_DIR)/view.o \ + $(OBJ_DIR)/wad.o \ + $(OBJ_DIR)/world.o \ + $(OBJ_DIR)/zone.o + +# Object files used only under software video. +SOFTWARE_VIDEO_ONLY_OBJS = \ + $(OBJ_DIR)/psp/video_software.o \ + \ + $(OBJ_DIR)/d_edge.o \ + $(OBJ_DIR)/d_fill.o \ + $(OBJ_DIR)/d_init.o \ + $(OBJ_DIR)/d_modech.o \ + $(OBJ_DIR)/d_part.o \ + $(OBJ_DIR)/d_polyse.o \ + $(OBJ_DIR)/d_scan.o \ + $(OBJ_DIR)/d_sky.o \ + $(OBJ_DIR)/d_sprite.o \ + $(OBJ_DIR)/d_surf.o \ + $(OBJ_DIR)/d_vars.o \ + $(OBJ_DIR)/d_zpoint.o \ + $(OBJ_DIR)/draw.o \ + $(OBJ_DIR)/model.o \ + $(OBJ_DIR)/nonintel.o \ + $(OBJ_DIR)/r_aclip.o \ + $(OBJ_DIR)/r_alias.o \ + $(OBJ_DIR)/r_bsp.o \ + $(OBJ_DIR)/r_draw.o \ + $(OBJ_DIR)/r_edge.o \ + $(OBJ_DIR)/r_efrag.o \ + $(OBJ_DIR)/r_light.o \ + $(OBJ_DIR)/r_main.o \ + $(OBJ_DIR)/r_misc.o \ + $(OBJ_DIR)/r_sky.o \ + $(OBJ_DIR)/r_sprite.o \ + $(OBJ_DIR)/r_surf.o \ + $(OBJ_DIR)/r_vars.o \ + $(OBJ_DIR)/screen.o +SOFTWARE_VIDEO_ONLY_FLAGS = -DPSP_SOFTWARE_VIDEO + +# Object files used only under hardware video. +HARDWARE_VIDEO_ONLY_OBJS = \ + $(OBJ_DIR)/psp/clipping.o \ + $(OBJ_DIR)/psp/video_hardware.o \ + $(OBJ_DIR)/psp/video_hardware_draw.o \ + $(OBJ_DIR)/psp/video_hardware_fog.o \ + $(OBJ_DIR)/psp/video_hardware_entity_fragment.o \ + $(OBJ_DIR)/psp/video_hardware_light.o \ + $(OBJ_DIR)/psp/video_hardware_main.o \ + $(OBJ_DIR)/psp/video_hardware_mesh.o \ + $(OBJ_DIR)/psp/video_hardware_misc.o \ + $(OBJ_DIR)/psp/video_hardware_model.o \ + $(OBJ_DIR)/psp/video_hardware_screen.o \ + $(OBJ_DIR)/psp/video_hardware_surface.o \ + $(OBJ_DIR)/psp/video_hardware_warp.o \ + $(OBJ_DIR)/psp/video_vertex_lighting.o \ + $(OBJ_DIR)/psp/vram.o +HARDWARE_VIDEO_ONLY_FLAGS = -DPSP_HARDWARE_VIDEO + +# Object files used only under hardware mp3. +MP3HARDWARE_MP3LIB_ONLY_OBJS = \ + $(OBJ_DIR)/psp/cd.o \ + $(OBJ_DIR)/psp/mp3.o +MP3HARDWARE_MP3LIB_ONLY_FLAGS = -DPSP_MP3HARDWARE_MP3LIB + +# Object files used only under software mp3. +MP3SOFTWARE_MP3LIB_ONLY_OBJS = \ + $(OBJ_DIR)/psp/cdmad.o +MP3SOFTWARE_MP3LIB_ONLY_FLAGS = -DPSP_MP3SOFTWARE_MP3LIB + +# Set up the object files depending on the build. +ifeq ($($(VIDEO)_VIDEO_ONLY_OBJS),) +$(error Unrecognised VIDEO type '$(VIDEO)'. It must be one of $(VALID_VIDEOS)) +endif + +ifeq ($($(MP3LIB)_MP3LIB_ONLY_OBJS),) +$(error Unrecognised MP3LIB type '$(MP3LIB)'. It must be one of $(VALID_MP3LIBS)) +endif + +OBJS = $($(VIDEO)_VIDEO_ONLY_OBJS) $($(MP3LIB)_MP3LIB_ONLY_OBJS) $(COMMON_OBJS) $(GPROF_OBJS) + +# Compiler flags. +CFLAGS = -ffast-math -O3 -G0 $(GPROF_FLAGS) -Wall -Wno-trigraphs -Winline -DPSP $(MODEL_N) $($(VIDEO)_VIDEO_ONLY_FLAGS) $($(MP3LIB)_MP3LIB_ONLY_FLAGS) -g +CXXFLAGS = -fno-rtti -Wcast-qual +ASFLAGS = $(CFLAGS) -c + +# Libs. +GU_LIBS = -lpspgum_vfpu -lpspvfpu -lpspgu +AUDIO_LIBS = -lpspaudiolib -lpspaudio -lpspaudiocodec m33libs/lib/libpspkubridge.a +#madlibs/libmad.a +MISC_LIBS = -lpsprtc -lpsppower +STD_LIBS = -lstdc++ -lm -lc +LIBS = $(GU_LIBS) $(AUDIO_LIBS) $(MISC_LIBS) $(STD_LIBS) -lpspwlan -lpspnet_adhoc -lpspnet_adhocctl + +# What else to clean. +EXTRA_CLEAN = $(foreach FILE,$(ZIP_FILE) Quake/EBOOT.PBP,$(DIST_DIR)/$(FILE)) + +# All target. +all: $(PSP_EBOOT) + +# What is an install? +install: $(INSTALL_DIR)/EBOOT.PBP + +# How to install. +$(INSTALL_DIR)/EBOOT.PBP: $(PSP_EBOOT) + @echo Installing $(PSP_EBOOT) to $@... + @-mkdir -p $(dir $@) + @cp $(PSP_EBOOT) $@ + +# How to build the distribution. +distro: clean $(ZIP_FILE) + @echo Distribution prepared. + +$(DIST_DIR)/Quake/EBOOT.PBP: $(PSP_EBOOT) + @echo Copying $< to $@... + @-mkdir -p $(dir $@) + @cp $< $@ + +$(ZIP_FILE): $(foreach FILE,$(DIST_FILES),$(DIST_DIR)/$(FILE)) + @echo Creating $(DIST_DIR)/$(ZIP_FILE)... + @-rm -rf $(ZIP_FILE) + @cd $(DIST_DIR) && zip -r -q -9 -o $(ZIP_FILE) $(DIST_FILES) + +# How to compile an S file. +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.S + @echo $(notdir $<) + @mkdir -p $(dir $@) + @$(CC) $(CFLAGS) -c $< -o $@ + +# How to compile a C file. +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c + @echo $(notdir $<) + @mkdir -p $(dir $@) + @$(CC) $(CFLAGS) -c $< -o $@ + +# How to compile a C++ file. +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp + @echo $(notdir $<) + @mkdir -p $(dir $@) + @$(CXX) $(CXXFLAGS) -c $< -o $@ + +# Use the standard PSPSDK build stuff. +include $(PSPSDK)/lib/build.mak + +ifneq ($(VS_PATH),) +CC = vs-psp-gcc +CXX = vs-psp-g++ +endif + +ifeq ($(BUILD_PRX),1) +OBJ_TYPE = prx +else +OBJ_TYPE = elf +endif diff --git a/r17/Revamped src/revamped_src/psp/Quake_PSP.vcproj b/r17/Revamped src/revamped_src/psp/Quake_PSP.vcproj new file mode 100755 index 00000000..74b46be9 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Quake_PSP.vcproj @@ -0,0 +1,621 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/r17/Revamped src/revamped_src/psp/Quake_PSP.vcxproj b/r17/Revamped src/revamped_src/psp/Quake_PSP.vcxproj new file mode 100755 index 00000000..94f976a7 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Quake_PSP.vcxproj @@ -0,0 +1,192 @@ + + + + + PSP + Win32 + + + + {38B817AB-88C4-4ADA-8750-4187AB435363} + Quake_PSP + MakeFileProj + + + + Makefile + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(Configuration)\ + $(Configuration)\ + build.bat install + build.bat clean install + build.bat clean + + PSP;PSP_HARDWARE_VIDEO;$(NMakePreprocessorDefinitions) + $(NMakeIncludeSearchPath) + $(NMakeForcedIncludes) + $(NMakeAssemblySearchPath) + $(NMakeForcedUsingAssemblies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/Quake_PSP.vcxproj.filters b/r17/Revamped src/revamped_src/psp/Quake_PSP.vcxproj.filters new file mode 100755 index 00000000..fe144180 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Quake_PSP.vcxproj.filters @@ -0,0 +1,437 @@ + + + + + {aa96f718-0fb7-47e8-8320-789df58505ad} + + + {15e36846-252c-4c61-a0f3-af8e2ac87202} + + + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + + + PSP specific source + + + + + + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/Quake_PSP.vcxproj.user b/r17/Revamped src/revamped_src/psp/Quake_PSP.vcxproj.user new file mode 100755 index 00000000..695b5c78 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/Quake_PSP.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/battery.cpp b/r17/Revamped src/revamped_src/psp/battery.cpp new file mode 100755 index 00000000..da742837 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/battery.cpp @@ -0,0 +1,102 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#include + +extern "C" +{ +#include "../quakedef.h" +} + +#include "battery.hpp" + +namespace quake +{ + namespace battery + { + // The previous battery level. + static int lastLevel = scePowerGetBatteryLifePercent(); + static bool lastCharging = scePowerGetBatteryChargingStatus(); + + void check() + { + // No battery? + if (!scePowerIsBatteryExist()) + { + // Don't report anything. + return; + } + + // Get the new battery status. + const int level = scePowerGetBatteryLifePercent(); + const bool charging = scePowerGetBatteryChargingStatus(); + + // Is the level not sensible? + if ((level < 0) || (level > 100)) + { + // Hopefully it will be sensible soon. + return; + } + + // Has the battery status changed? + if ((level != lastLevel) || (charging != lastCharging)) + { + // Charging? + if (charging) + { + // Inform the player. + Con_Printf("Battery %d%% (charging)\n", + level); + } + else + { + // How much time is left? + const int timeLeft = scePowerGetBatteryLifeTime(); + + // Is the time sensible? + if (timeLeft > 0) + { + // Convert the time to something readable. + const int hoursLeft = timeLeft / 60; + const int minutesLeft = timeLeft % 60; + + // Inform the player. + Con_Printf("Battery %d%% (%d hour%s %d minute%s)\n", + level, + hoursLeft, + (hoursLeft == 1) ? "" : "s", // Handle pluralisation of hour(s). + minutesLeft, + (minutesLeft == 1) ? "" : "s"); // Handle pluralisation of minute(s). + } + else + { + // It's a silly time, just report the battery level. + Con_Printf("Battery %d%%\n", + level); + } + } + + // Remember the status for next frame. + lastLevel = level; + lastCharging = charging; + } + } + } +} diff --git a/r17/Revamped src/revamped_src/psp/battery.hpp b/r17/Revamped src/revamped_src/psp/battery.hpp new file mode 100755 index 00000000..bf4d9306 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/battery.hpp @@ -0,0 +1,33 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#ifndef QUAKE_BATTERY_HPP +#define QUAKE_BATTERY_HPP + +namespace quake +{ + namespace battery + { + // Checks the battery level and prints it to the console if it's changed. + void check(); + } +} + +#endif diff --git a/r17/Revamped src/revamped_src/psp/build.bat b/r17/Revamped src/revamped_src/psp/build.bat new file mode 100755 index 00000000..8b033928 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/build.bat @@ -0,0 +1,4 @@ +rem set PATH=C:/cygwin/usr/local/pspdev/bin;%PATH% +set PSPSDK=C:/cygwin/usr/local/pspdev +set PSP_MOUNT=/cygdrive/p +c:\cygwin\bin\bash -c 'export VS_PATH=`pwd`; /bin/bash --login -c "cd \"$VS_PATH\"; ./sed_make.sh %1 %2 %3 %4 %5 %6"' diff --git a/r17/Revamped src/revamped_src/psp/cd.cpp b/r17/Revamped src/revamped_src/psp/cd.cpp new file mode 100755 index 00000000..68b2e3da --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/cd.cpp @@ -0,0 +1,273 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#include +#include + +#include + +//#include + +#include "mp3.h" + +extern "C" +{ +#include "../quakedef.h" +} + +extern cvar_t bgmtype; +extern cvar_t bgmvolume; + + +namespace quake +{ + namespace cd + { + struct Sample + { + short left; + short right; + }; + +// static int file = -1; + static int last_track = 1; + + static bool playing = false; + static bool paused = false; + static bool enabled = false; + static float cdvolume = 0; + } +} + +using namespace quake; +using namespace quake::cd; + +static void CD_f (void) +{ + char *command; + + if (Cmd_Argc() < 2) + { + Con_Printf("commands:"); + Con_Printf("on, off, reset, remap, \n"); + Con_Printf("play, stop, loop, pause, resume\n"); + Con_Printf("eject, close, info\n"); + return; + } + + command = Cmd_Argv (1); + + if (Q_strcasecmp(command, "on") == 0) + { + enabled = true; + return; + } + + if (Q_strcasecmp(command, "off") == 0) + { + if (playing) + CDAudio_Stop(); + enabled = false; + return; + } + + if (Q_strcasecmp(command, "reset") == 0) + { + enabled = true; + if (playing) + CDAudio_Stop(); + return; + } + + if (Q_strcasecmp(command, "remap") == 0) + { + return; + } + + if (Q_strcasecmp(command, "close") == 0) + { + return; + } + + if (Q_strcasecmp(command, "play") == 0) + { + CDAudio_Play((byte)atoi(Cmd_Argv (2)), (qboolean) false); + return; + } + + if (Q_strcasecmp(command, "loop") == 0) + { + CDAudio_Play((byte)atoi(Cmd_Argv (2)), (qboolean) true); + return; + } + + if (Q_strcasecmp(command, "stop") == 0) + { + CDAudio_Stop(); + return; + } + + if (Q_strcasecmp(command, "pause") == 0) + { + CDAudio_Pause(); + return; + } + + if (Q_strcasecmp(command, "resume") == 0) + { + CDAudio_Resume(); + return; + } + + if (Q_strcasecmp(command, "eject") == 0) + { + if (playing) + CDAudio_Stop(); + return; + } + + if (Q_strcasecmp(command, "info") == 0) + { + return; + } +} + +void CDAudio_VolumeChange(float bgmvolume) +{ + int volume = (int) (bgmvolume * (float) PSP_VOLUME_MAX); + //pspAudioSetVolume(1, volume, volume); + mp3_volume = volume; + cdvolume = bgmvolume; + + changeMp3Volume=0; + +// Con_Printf("Volume changed to : %i\n", mp3_volume); + +} + +extern "C" int sceKernelDelayThread(int delay); + +void CDAudio_Play(byte track, qboolean looping) +{ + last_track = track; + CDAudio_Stop(); + + if (track < 1) + track = 1; + + char path[256]; + sprintf(path, "%s\\MP3\\%02u.mp3", host_parms.basedir, track); + + int ret; + ret = mp3_start_play(path, 0); + + if(ret != 2) + { +// Con_Printf("Playing %s\n", path); + playing = true; + } + else + { + Con_Printf("Couldn't find %s\n", path); + playing = false; + CDAudio_VolumeChange(0); + } + + + CDAudio_VolumeChange(bgmvolume.value); +} + +void CDAudio_Stop(void) +{ + mp3_job_started = 0; + +// file = -1; + playing = false; + CDAudio_VolumeChange(0); +} + +void CDAudio_Pause(void) +{ + CDAudio_VolumeChange(0); + paused = true; +} + +void CDAudio_Resume(void) +{ + CDAudio_VolumeChange(bgmvolume.value); + paused = false; +} + +void CDAudio_Update(void) +{ + + //if (bgmvolume.value != mp3_volume) + // CDAudio_VolumeChange(bgmvolume.value); + //if(changeMp3Volume) CDAudio_VolumeChange(bgmvolume.value); + + if (strcmpi(bgmtype.string,"cd") == 0) { + if (playing == false) { + CDAudio_Play(last_track, (qboolean) false); + } + if (paused == true) { + CDAudio_Resume(); + } + + } else { + if (paused == false) { + CDAudio_Pause(); + } + if (playing == true) { + CDAudio_Stop(); + } + } +} + +int CDAudio_Init(void) +{ + if (cls.state == ca_dedicated) + return -1; + + if (COM_CheckParm("-nocdaudio")) + return -1; + + mp3_init(); + sceKernelDelayThread(5*10000); + + enabled = true; + + Cmd_AddCommand ("cd", CD_f); + + Con_Printf("CD Audio Initialized\n"); + + return 0; +} + +void CDAudio_Shutdown(void) +{ + Con_Printf("CDAudio_Shutdown\n"); + + CDAudio_Stop(); + + sceKernelDelayThread(5*10000); +// mp3_deinit(); + +} + diff --git a/r17/Revamped src/revamped_src/psp/cdmad.cpp b/r17/Revamped src/revamped_src/psp/cdmad.cpp new file mode 100755 index 00000000..ed4482b7 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/cdmad.cpp @@ -0,0 +1,410 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#include +#include + +#include + +#include + +extern "C" +{ +#include "../quakedef.h" +} + +extern cvar_t bgmtype; +extern cvar_t bgmvolume; + + +namespace quake +{ + namespace cd + { + struct Sample + { + short left; + short right; + }; + + static int file = -1; + + static int last_track = 1; + static mad_stream stream; + static mad_frame frame; + static mad_synth synth; + static unsigned char fileBuffer[8192]; + static std::size_t samplesRead; + + static bool playing = false; + static bool paused = false; + static bool enabled = false; + static float cdvolume = 0; + + + static bool fillFileBuffer() + { + // Should be playing a track but aren't? + //Con_Printf("fillFileBuffer: "); + if (file >= 0) { + + playing = true; + + // Find out how much to keep and how much to fill. + const std::size_t bytesToKeep = stream.bufend - stream.next_frame; + std::size_t bytesToFill = sizeof(fileBuffer) - bytesToKeep; + + // Want to keep any bytes? + if (bytesToKeep) + { + // Copy the tail to the head. + memmove(fileBuffer, fileBuffer + sizeof(fileBuffer) - bytesToKeep, bytesToKeep); + } + + // Read into the rest of the file buffer. + unsigned char* bufferPos = fileBuffer + bytesToKeep; + + //Con_Printf(" bytes to fill %d \n",bytesToFill); + while (bytesToFill > 0) + { + // Read some. + const std::size_t bytesRead = Sys_FileRead(file , bufferPos, bytesToFill); + + //Con_Printf(" bytes read: %d \n",bytesRead); + // EOF? + if (bytesRead == 0) + { + Sys_FileSeek(file, 0); + continue; + + } + + // Adjust where we're writing to. + bytesToFill -= bytesRead; + bufferPos += bytesRead; + } + + } else { + playing = false; + return false; + } + return true; + } + + static void decode() + { + // While we need to fill the buffer... + while ( + (mad_frame_decode(&frame, &stream) == -1) && + ((stream.error == MAD_ERROR_BUFLEN) || (stream.error == MAD_ERROR_BUFPTR)) + ) + { + // Fill up the remainder of the file buffer. + fillFileBuffer(); + + // Give new buffer to the stream. + mad_stream_buffer(&stream, fileBuffer, sizeof(fileBuffer)); + } + + // Synth the frame. + mad_synth_frame(&synth, &frame); + } + + static inline short convertSample(mad_fixed_t sample) + { + /* round */ + sample += (1L << (MAD_F_FRACBITS - 16)); + + /* clip */ + if (sample >= MAD_F_ONE) + sample = MAD_F_ONE - 1; + else if (sample < -MAD_F_ONE) + sample = -MAD_F_ONE; + + /* quantize */ + return sample >> (MAD_F_FRACBITS + 1 - 16); + } + + static void convertLeftSamples(Sample* first, Sample* last, const mad_fixed_t* src) + { + for (Sample* dst = first; dst != last; ++dst) + { + dst->left = convertSample(*src++); + } + } + + static void convertRightSamples(Sample* first, Sample* last, const mad_fixed_t* src) + { + for (Sample* dst = first; dst != last; ++dst) + { + dst->right = convertSample(*src++); + } + } + + static void fillOutputBuffer(void* buffer, unsigned int samplesToWrite, void* userData) + { + //Con_Printf("fillOutputBuffer\n"); + if (playing == false || paused == true) + return; + + // Where are we writing to? + Sample* destination = static_cast (buffer); + + // While we've got samples to write... + while (samplesToWrite > 0) + { + // Enough samples available? + const unsigned int samplesAvailable = synth.pcm.length - samplesRead; + if (samplesAvailable > samplesToWrite) + { + // Write samplesToWrite samples. + convertLeftSamples(destination, destination + samplesToWrite, &synth.pcm.samples[0][samplesRead]); + convertRightSamples(destination, destination + samplesToWrite, &synth.pcm.samples[1][samplesRead]); + + // We're still using the same PCM data. + samplesRead += samplesToWrite; + + // Done. + samplesToWrite = 0; + } + else + { + // Write samplesAvailable samples. + convertLeftSamples(destination, destination + samplesAvailable, &synth.pcm.samples[0][samplesRead]); + convertRightSamples(destination, destination + samplesAvailable, &synth.pcm.samples[1][samplesRead]); + + // We need more PCM data. + samplesRead = 0; + decode(); + + // We've still got more to write. + destination += samplesAvailable; + samplesToWrite -= samplesAvailable; + } + } + } + } +} + +using namespace quake; +using namespace quake::cd; + +static void CD_f (void) +{ + char *command; + + if (Cmd_Argc() < 2) + { + Con_Printf("commands:"); + Con_Printf("on, off, reset, remap, \n"); + Con_Printf("play, stop, loop, pause, resume\n"); + Con_Printf("eject, close, info\n"); + return; + } + + command = Cmd_Argv (1); + + if (Q_strcasecmp(command, "on") == 0) + { + enabled = true; + return; + } + + if (Q_strcasecmp(command, "off") == 0) + { + if (playing) + CDAudio_Stop(); + enabled = false; + return; + } + + if (Q_strcasecmp(command, "reset") == 0) + { + enabled = true; + if (playing) + CDAudio_Stop(); + return; + } + + if (Q_strcasecmp(command, "remap") == 0) + { + return; + } + + if (Q_strcasecmp(command, "close") == 0) + { + return; + } + + if (Q_strcasecmp(command, "play") == 0) + { + CDAudio_Play((byte)atoi(Cmd_Argv (2)), (qboolean) false); + return; + } + + if (Q_strcasecmp(command, "loop") == 0) + { + CDAudio_Play((byte)atoi(Cmd_Argv (2)), (qboolean) true); + return; + } + + if (Q_strcasecmp(command, "stop") == 0) + { + CDAudio_Stop(); + return; + } + + if (Q_strcasecmp(command, "pause") == 0) + { + CDAudio_Pause(); + return; + } + + if (Q_strcasecmp(command, "resume") == 0) + { + CDAudio_Resume(); + return; + } + + if (Q_strcasecmp(command, "eject") == 0) + { + if (playing) + CDAudio_Stop(); + return; + } + + if (Q_strcasecmp(command, "info") == 0) + { + return; + } +} + +void CDAudio_VolumeChange(float bgmvolume) +{ + int volume = (int) (bgmvolume * (float) PSP_VOLUME_MAX); + pspAudioSetVolume(1, volume, volume); + cdvolume = bgmvolume; +} + +void CDAudio_Play(byte track, qboolean looping) +{ + last_track = track; + CDAudio_Stop(); + + char path[256]; + sprintf(path, "%s\\MP3\\%02u.mp3", host_parms.basedir, track); + + Sys_FileOpenRead(path, &file); + if (file >= 0) + { + Con_Printf("Playing %s\n", path); + playing = true; + } + else + { + Con_Printf("Couldn't find %s\n", path); + playing = false; + CDAudio_VolumeChange(0); + } + + + CDAudio_VolumeChange(bgmvolume.value); +} + +void CDAudio_Stop(void) +{ + if (file >= 0) + { + Sys_FileClose(file); + file = -1; + playing = false; + CDAudio_VolumeChange(0); + } +} + +void CDAudio_Pause(void) +{ + CDAudio_VolumeChange(0); + paused = true; +} + +void CDAudio_Resume(void) +{ + CDAudio_VolumeChange(bgmvolume.value); + paused = false; +} + +void CDAudio_Update(void) +{ + if (bgmvolume.value != cdvolume) + CDAudio_VolumeChange(bgmvolume.value); + + + // Fill the input buffer. + if (strcmpi(bgmtype.string,"cd") == 0) { + if (playing == false) { + CDAudio_Play(last_track, (qboolean) false); + } + if (paused == true) { + CDAudio_Resume(); + } + + } else { + if (paused == false) { + CDAudio_Pause(); + } + if (playing == true) { + CDAudio_Stop(); + } + } +} + +int CDAudio_Init(void) +{ + // Initialise MAD. + mad_stream_init(&stream); + mad_frame_init(&frame); + mad_synth_init(&synth); + + // Set the channel callback. + // Sound effects use channel 0, CD audio uses channel 1. + pspAudioSetChannelCallback(1, fillOutputBuffer, 0); + enabled = true; + + Cmd_AddCommand ("cd", CD_f); + + Con_Printf("CD Audio Initialized\n"); + + return 0; +} + +void CDAudio_Shutdown(void) +{ + CDAudio_Stop(); + + // Clear the channel callback. + pspAudioSetChannelCallback(1, 0, 0); + + // Shut down MAD. + mad_synth_finish(&synth); + mad_frame_finish(&frame); + mad_stream_finish(&stream); +} + diff --git a/r17/Revamped src/revamped_src/psp/clipping.cpp b/r17/Revamped src/revamped_src/psp/clipping.cpp new file mode 100755 index 00000000..6cb3247b --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/clipping.cpp @@ -0,0 +1,440 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#define CLIPPING_DEBUGGING 0 +#define CLIP_LEFT 1 +#define CLIP_RIGHT 1 +#define CLIP_BOTTOM 1 +#define CLIP_TOP 1 +#define CLIP_NEAR 0 +#define CLIP_FAR 0 + +#include "clipping.hpp" + +#include +#include +#include + +#include "math.hpp" + +extern "C" +{ +#include "../quakedef.h" +} + +namespace quake +{ + namespace clipping + { + // Plane types are sorted, most likely to clip first. + enum plane_index + { +#if CLIP_BOTTOM + plane_index_bottom, +#endif +#if CLIP_LEFT + plane_index_left, +#endif +#if CLIP_RIGHT + plane_index_right, +#endif +#if CLIP_TOP + plane_index_top, +#endif +#if CLIP_NEAR + plane_index_near, +#endif +#if CLIP_FAR + plane_index_far, +#endif + plane_count + }; + + // Types. + typedef ScePspFVector4 plane_type; + typedef plane_type frustum_t[plane_count]; + + // Transformed frustum. + static ScePspFMatrix4 projection_view_matrix; + static frustum_t projection_view_frustum; + static frustum_t clipping_frustum; + + // The temporary working buffers. + static const std::size_t max_clipped_vertices = 32; + static glvert_t work_buffer[2][max_clipped_vertices]; + + static inline void calculate_frustum(const ScePspFMatrix4& clip, frustum_t* frustum) + { +#if CLIP_NEAR + /* Extract the NEAR plane */ + plane_type* const near = &(*frustum)[plane_index_near]; + near->x = clip.x.w + clip.x.z; + near->y = clip.y.w + clip.y.z; + near->z = clip.z.w + clip.z.z; + near->w = clip.w.w + clip.w.z; + + /* Normalize the result */ + math::normalise(near); +#endif + +#if CLIP_FAR + /* Extract the FAR plane */ + plane_type* const far = &(*frustum)[plane_index_far]; + far->x = clip.x.w - clip.x.z; + far->y = clip.y.w - clip.y.z; + far->z = clip.z.w - clip.z.z; + far->w = clip.w.w - clip.w.z; + + /* Normalize the result */ + math::normalise(far); +#endif + +#if CLIP_LEFT + /* Extract the numbers for the LEFT plane */ + plane_type* const left = &(*frustum)[plane_index_left]; + left->x = clip.x.w + clip.x.x; + left->y = clip.y.w + clip.y.x; + left->z = clip.z.w + clip.z.x; + left->w = clip.w.w + clip.w.x; + + /* Normalize the result */ + math::normalise(left); +#endif + +#if CLIP_RIGHT + /* Extract the numbers for the RIGHT plane */ + plane_type* const right = &(*frustum)[plane_index_right]; + right->x = clip.x.w - clip.x.x; + right->y = clip.y.w - clip.y.x; + right->z = clip.z.w - clip.z.x; + right->w = clip.w.w - clip.w.x; + + /* Normalize the result */ + math::normalise(right); +#endif + +#if CLIP_BOTTOM + /* Extract the BOTTOM plane */ + plane_type* const bottom = &(*frustum)[plane_index_bottom]; + bottom->x = clip.x.w + clip.x.y; + bottom->y = clip.y.w + clip.y.y; + bottom->z = clip.z.w + clip.z.y; + bottom->w = clip.w.w + clip.w.y; + + /* Normalize the result */ + math::normalise(bottom); +#endif + +#if CLIP_TOP + /* Extract the TOP plane */ + plane_type* const top = &(*frustum)[plane_index_top]; + top->x = clip.x.w - clip.x.y; + top->y = clip.y.w - clip.y.y; + top->z = clip.z.w - clip.z.y; + top->w = clip.w.w - clip.w.y; + + /* Normalize the result */ + math::normalise(top); +#endif + } + + void begin_frame() + { + // Get the projection matrix. + sceGumMatrixMode(GU_PROJECTION); + ScePspFMatrix4 proj; + sceGumStoreMatrix(&proj); + + // Get the view matrix. + sceGumMatrixMode(GU_VIEW); + ScePspFMatrix4 view; + sceGumStoreMatrix(&view); + + // Restore matrix mode. + sceGumMatrixMode(GU_MODEL); + + // Combine the two matrices (multiply projection by view). + math::multiply(view, proj, &projection_view_matrix); + + // Calculate and cache the clipping frustum. + calculate_frustum(projection_view_matrix, &projection_view_frustum); + memcpy(clipping_frustum, projection_view_frustum, sizeof(frustum_t)); + + __asm__ volatile ( + "ulv.q C700, %0\n" // Load plane into register + "ulv.q C710, %1\n" // Load plane into register + "ulv.q C720, %2\n" // Load plane into register + "ulv.q C730, %3\n" // Load plane into register + :: "m"(clipping_frustum[0]),"m"(clipping_frustum[1]),"m"(clipping_frustum[2]),"m"(clipping_frustum[3]) + ); + + + } + + void begin_brush_model() + { + // Get the model matrix. + ScePspFMatrix4 model_matrix; + sceGumStoreMatrix(&model_matrix); + + // Combine the matrices (multiply projection-view by model). + ScePspFMatrix4 projection_view_model_matrix; + math::multiply(model_matrix, projection_view_matrix, &projection_view_model_matrix); + + // Calculate the clipping frustum. + calculate_frustum(projection_view_model_matrix, &clipping_frustum); + + __asm__ volatile ( + "ulv.q C700, %0\n" // Load plane into register + "ulv.q C710, %1\n" // Load plane into register + "ulv.q C720, %2\n" // Load plane into register + "ulv.q C730, %3\n" // Load plane into register + :: "m"(clipping_frustum[0]), + "m"(clipping_frustum[1]), + "m"(clipping_frustum[2]), + "m"(clipping_frustum[3]) + ); + } + + void end_brush_model() + { + // Restore the clipping frustum. + memcpy(clipping_frustum, projection_view_frustum, sizeof(frustum_t)); + + __asm__ volatile ( + "ulv.q C700, %0\n" // Load plane into register + "ulv.q C710, %1\n" // Load plane into register + "ulv.q C720, %2\n" // Load plane into register + "ulv.q C730, %3\n" // Load plane into register + :: "m"(clipping_frustum[0]), + "m"(clipping_frustum[1]), + "m"(clipping_frustum[2]), + "m"(clipping_frustum[3]) + ); + } + + // Is a point on the front side of the plane? + static inline bool point_in_front_of_plane(const vec3_t point, const plane_type& plane) + { + return ((plane.x * point[0]) + (plane.y * point[1]) + (plane.z * point[2]) + plane.w) > 0.0f; + } + + // Is clipping required? + bool is_clipping_required(const struct glvert_s* vertices, std::size_t vertex_count) + { + ScePspFVector4 temp; + float out1, out2, out3, out4; + const glvert_t* const last_vertex = &vertices[vertex_count]; + + // For each vertex... + for (const glvert_t* vertex = vertices; vertex != last_vertex; ++vertex) + { + __asm__ volatile ( + "ulv.q C610, %4\n" // Load vertex into register + "vone.s S613\n" // Now set the 4th entry to be 1 as that is just random + "vdot.q S620, C700, C610\n" // s620 = vertex->xyx . frustrum[0] + "vdot.q S621, C710, C610\n" // s621 = vertex->xyx . frustrum[1] + "vdot.q S622, C720, C610\n" // s622 = vertex->xyx . frustrum[2] + "vdot.q S623, C730, C610\n" // s623 = vertex->xyx . frustrum[3] + "mfv %0, S620\n" // out1 = s620 + "mfv %1, S621\n" // out2 = s621 + "mfv %2, S622\n" // out3 = s622 + "mfv %3, S623\n" // out4 = s623 + : "=r"(out1), "=r"(out2), "=r"(out3), "=r"(out4) : "m"(*vertex->xyz) + ); + + // Should be possible to move this within the VFPU code and just check one value here + if ((out1 < 0.0f) || (out2 < 0.0f) || (out3 < 0.0f) || (out4 < 0.0f)) + { + return true; + } + } + + // This polygon is all inside the frustum. + return false; + } + + static inline glvert_t calculate_intersection(const plane_type& plane, const glvert_t& v1, const glvert_t& v2) + { + // Work out the difference between the vertices. + const glvert_t delta = + { + { + v2.st[0] - v1.st[0], + v2.st[1] - v1.st[1] + }, + { + v2.xyz[0] - v1.xyz[0], + v2.xyz[1] - v1.xyz[1], + v2.xyz[2] - v1.xyz[2] + } + }; + + // Horrible math. + const float top = (plane.x * v1.xyz[0]) + (plane.y * v1.xyz[1]) + (plane.z * v1.xyz[2]) + plane.w; + const float bottom = (plane.x * delta.xyz[0]) + (plane.y * delta.xyz[1]) + (plane.z * delta.xyz[2]); + const float time = -top / bottom; +#if CLIPPING_DEBUGGING + if (time < -0.001f || time > 1.001f) + { + Sys_Error("time out of range,\n\t%f,\n\tv1 (%f %f %f)\n\tv2 (%f %f %f)\n\tdelta (%f %f %f)", + time, + v1.xyz[0], v1.xyz[1], v1.xyz[2], + v2.xyz[0], v2.xyz[1], v2.xyz[2], + delta.xyz[0], delta.xyz[1], delta.xyz[2] + ); + } +#endif + + // Interpolate a new vertex. + const glvert_t v = + { + { + v1.st[0] + time * delta.st[0], + v1.st[1] + time * delta.st[1] + }, + { + v1.xyz[0] + time * delta.xyz[0], + v1.xyz[1] + time * delta.xyz[1], + v1.xyz[2] + time * delta.xyz[2] + }, + }; + + return v; + } + + // Clips a polygon against a plane. + // http://hpcc.engin.umich.edu/CFD/users/charlton/Thesis/html/node90.html + static void clip_to_plane( + const plane_type& plane, + const glvert_t* const unclipped_vertices, + std::size_t const unclipped_vertex_count, + glvert_t* const clipped_vertices, + std::size_t* const clipped_vertex_count) + { + // Set up. + const glvert_t* const last_unclipped_vertex = &unclipped_vertices[unclipped_vertex_count]; + + // For each polygon edge... + const glvert_t* s = unclipped_vertices; + const glvert_t* p = s + 1; + glvert_t* clipped_vertex = clipped_vertices; + do + { + // Check both nodal values, s and p. If the point values are: + const bool s_inside = point_in_front_of_plane(s->xyz, plane); + const bool p_inside = point_in_front_of_plane(p->xyz, plane); + if (s_inside) + { + if (p_inside) + { + // 1. Inside-inside, append the second node, p. + *clipped_vertex++ = *p; + } + else + { + // 2. Inside-outside, compute and append the + // intersection, i of edge sp with the clipping plane. + *clipped_vertex++ = calculate_intersection(plane, *s, *p); + } + } + else + { + if (p_inside) + { + // 4. Outside-inside, compute and append the + // intersection i of edge sp with the clipping plane, + // then append the second node p. + *clipped_vertex++ = calculate_intersection(plane, *s, *p); + *clipped_vertex++ = *p; + } + else + { + // 3. Outside-outside, no operation. + } + } + + // Next edge. + s = p++; + if (p == last_unclipped_vertex) + { + p = unclipped_vertices; + } + } + while (s != unclipped_vertices); + + // Return the data. + *clipped_vertex_count = clipped_vertex - clipped_vertices; + } + + // Clips a polygon against the frustum. + void clip( + const struct glvert_s* unclipped_vertices, + std::size_t unclipped_vertex_count, + const struct glvert_s** clipped_vertices, + std::size_t* clipped_vertex_count) + { + // No vertices to clip? + if (!unclipped_vertex_count) + { + // Error. + Sys_Error("Calling clip with zero vertices"); + } + + // Set up constants. + const plane_type* const last_plane = &clipping_frustum[plane_count]; + + // Set up the work buffer pointers. + const glvert_t* src = unclipped_vertices; + glvert_t* dst = work_buffer[0]; + std::size_t vertex_count = unclipped_vertex_count; + + // For each frustum plane... + for (const plane_type* plane = &clipping_frustum[0]; plane != last_plane; ++plane) + { + // Clip the poly against this frustum plane. + clip_to_plane(*plane, src, vertex_count, dst, &vertex_count); + + // No vertices left to clip? + if (!vertex_count) + { + // Quit early. + *clipped_vertex_count = 0; + return; + } + + // Use the next pair of buffers. + src = dst; + if (dst == work_buffer[0]) + { + dst = work_buffer[1]; + } + else + { + dst = work_buffer[0]; + } + } + + // Fill in the return data. + *clipped_vertices = src; + *clipped_vertex_count = vertex_count; + } + } +} diff --git a/r17/Revamped src/revamped_src/psp/clipping.hpp b/r17/Revamped src/revamped_src/psp/clipping.hpp new file mode 100755 index 00000000..9d028ed9 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/clipping.hpp @@ -0,0 +1,53 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#ifndef QUAKE_CLIPPING_HPP +#define QUAKE_CLIPPING_HPP + +#include + +struct glvert_s; + +namespace quake +{ + namespace clipping + { + // Calculates clipping planes from the GU view and projection matrices. + void begin_frame(); + + // Calculates clipping planes from the GU view and projection matrices. + void begin_brush_model(); + + // Resets the frustum to camera space. + void end_brush_model(); + + // Is clipping required? + bool is_clipping_required(const struct glvert_s* vertices, std::size_t vertex_count); + + // Clips a polygon. + void clip( + const struct glvert_s* unclipped_vertices, + std::size_t unclipped_vertex_count, + const struct glvert_s** clipped_vertices, + std::size_t* clipped_vertex_count); + } +} + +#endif diff --git a/r17/Revamped src/revamped_src/psp/dist/gpl.txt b/r17/Revamped src/revamped_src/psp/dist/gpl.txt new file mode 100755 index 00000000..6e812ec1 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/dist/gpl.txt @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/r17/Revamped src/revamped_src/psp/dist/old_readme.txt b/r17/Revamped src/revamped_src/psp/dist/old_readme.txt new file mode 100755 index 00000000..ce7867a5 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/dist/old_readme.txt @@ -0,0 +1,124 @@ +Quake for PSP v2.0 +================== + +Peter Mackay and Chris Swindle +31th March 2006 + + +Introduction +------------ + +This is a port of id Software's Quake to the PSP, ported from the original source code. + +We have combined the source for the original release with the network code from Multiplayer QUake and we have submitted all of the code to a SourceForge project. The project page is at https://sourceforge.net/cvs/?group_id=158726 where the full source is available. + + +Features +-------- + +The following is working fine: +- Software rendering +- Sound +- Adhoc connection for PSP - PSP games +- Infrastructure mode for connecting to servers +- Stable firmware V2+ support, including PSP-PSP & Access point network support via the latest eLoader (DHCP is recommended for v2.5+) +- On screen keyboard (not in V2+ at the moment) + +Things missing: +- OSK support in V2+, never finishes initialising in v2+, looks like it might be due to the way the exploit works +- Hardware rendering. I have little PSP GU experience, so it'll take a while to do. + +Known bugs: +- Fast key taps may go unnoticed when the frame rate is low. This is because we're not sure how to get buffered input on the PSP. + +If you've found a bug, please post about it on the release's thread at DCEmu. + + +Installation +------------ + +Installation instructions: +1. READ THE CONTROLS SECTION BELOW. +2. Firmware v1.0 users: + Copy the Quake folder from the 1.0 folder to the PSP/GAME folder on your PSP. + Firmware v1.5 users: + Copy the Quake and Quake% folders from the 1.5 folder to the PSP/GAME folder on your PSP. + Firmware v2+ users: + Copy the Quake folder from the 2.0+ folder to the PSP/GAME folder on your PSP. +3. Download the shareware version of Quake for the PC from here: + https://sourceforge.net/project/showfiles.php?group_id=158726 +4. Unzip or Unrar the shareware version you downloaded. +5. Copy the ID1 folder from the shareware version of Quake to inside your PSP/GAME/Quake folder. + + +Controls +-------- + +Regarding the buttons: + +The PSP buttons are connected to the following keys during the game and when the menu is shown. You will need to go into Quake's options and configure the keys you want to use. + +PSP | Game key | Menu key | Default game function +---------+------------+------------+---------------------- +SELECT | ~ | ~ | Toggle console +START | ESCAPE | ESCAPE | Show menu +LTRIGGER | LTRIGGER | | +RTRIGGER | RTRIGGER | | +UP | UPARROW | UPARROW | Move forward +RIGHT | RIGHTARROW | RIGHTARROW | Turn right +DOWN | DOWNARROW | DOWNARROW | Move backwards +LEFT | LEFTARROW | LEFTARROW | Turn left +TRIANGLE | TRIANGLE | | +CIRCLE | CIRCLE | ESCAPE | +CROSS | CROSS | ENTER | +SQUARE | SQUARE | OSK | + +For example, when you press CROSS, Quake gets a CROSS key press, which you will need to set to your desired action in the game options screen. + +Regarding the analog nub: + +If mouselook is turned on, then the analog nub is used to look around. You'll need to allocate other buttons for movement. If mouselook is turned off, which is the default, then the analog nub is used for movement. + + +Network +------- + +There are two forms of networking support included in the this version of Quake (compatible with all Firmware versions capable of running homebrew). + +Adhoc (PSP-PSP communication): +In order to use this mode go to the network menu and select adhoc, this will start the adhoc communication and then you can start a server or connect to another PSP using the usual method. + +Infrastructure Mode: +If you have an access point then you can use this mode to connect to servers on the internet. Before connecting using this method for the first time please go to the setup menu and ensure that the access point is correct. If it is not then you can press left and right to select the correct one. If it does not show up then you have probably deleted an access point and there is currently a bug that if one access point is deleted it will not find the correct one to connect to, you can set the accesspoint variable to the config number in order to avoid this. + +The following commands have been added to Quake for network support: + net_adhoc (initialise adhoc libraries and connect) + net_infra (connect to the default access point) + accesspoint (set the access point to the default, this will be saved on exit) + + +Support +------- + +If you would like to help out the project then you can make a donation to the following paypal accounts so that we are able to buy extra equipment to make it more compatible with different firmware versions and to test adhoc play: + +Peter Mackay - mackay.pete+paypal@gmail.com +Chris Swindle - c_swindle@hotmail.com + +If you can't get Quake running, try posting a comment on the DCEmu thread for the release and one of us should help you. Please make sure you've followed the installation instructions before posting. + + +Thanks +------ + +Big thanks go out to: +- All the great guys on the PS2Dev forum for all your hard work on the PSPSDK, and your helpful replies on the forum +- id Software, for supporting the game porting community by making their game sources GPL +- Hazel, for putting up with the complete lack of attention from Pete while he was working on this. +- Fanjita for the help with some code from the loader to help work out networking support via GTA and VSH +- McZonk for the OSK sample that he posted + +Have fun and enjoy Quake! + +End of file +----------- diff --git a/r17/Revamped src/revamped_src/psp/dist/readme.html b/r17/Revamped src/revamped_src/psp/dist/readme.html new file mode 100755 index 00000000..ab6fdacf --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/dist/readme.html @@ -0,0 +1,117 @@ + + + PSP Quake + + + +

PSP Quake

+ +

Credits

+
    +
  • Original game by id Software.
  • +
  • Ported to the PSP by Peter Mackay and Chris Swindle.
  • +
  • Ripped off and uncredited by several others! :-)
  • +
+ +

Links

+
    +
  • Our home Page at SourceForge. You can get the latest version and the source code there.
  • +
+ +
+ +

Getting the game to run

+

Everybody!

+

To run Quake on your PSP, you need the data files from either the shareware version of Quake, or the full version.

+
    +
  1. Get the data files: +
      +
    1. Buy the full version of Quake here, or on eBay; or
    2. +
    3. Download the demo version of Quake for free here.
    4. +
    +
  2. +
  3. Copy the ID1 directory from the demo to Quake/ID1.
  4. +
+ +

Firmware 3.10 OE-A2 and compatible

+
    +
  • Copy the Quake directory to /PSP/GAME/Quake on your PSP.
  • +
+ +

Other firmware version?

+
    +
  • Only custom firmwares are supported at the moment.
  • +
+ +
+ +

Troubleshooting

+ +

Known in-game error messages

+ + + + + + + + + + + +
MessageCauseFix
W_LoadWadFile: couldn't load gfx.wadYou've not put the ID directory on your memory stick.Read this file again from the top.
+ +

Q & A

+ + + + + + + + + + + + + + + + + +
QuestionAnswer
Where do you get the full version of Quake?You buy it. It's quite hard to find nowadays, but you should be able to get it on eBay without too much difficulty. I did.
Where do you get the demo version of Quake?You download it. We have made it available here.
Why don't you bundle the shareware data files with your release?Because the demo's license says not to do that. We have to distribute the complete demo, not just the data files. We did however package it up as .rar and .zip, making it a lot easier to get at the files compared to id's DOS installer.
+ +

Found a bug or want something added?

+

Don't just bitch about it on a forum - we may not read it. Please add it to our SourceForge Bug Tracker.

+

Notes:

+
    +
  • Feature Requests are not Bugs, so please add things to the right tracker.
  • +
  • Check the "Closed" bugs in the tracker before adding yours. These are the ones which will be fixed in the next version. Duplicates will be deleted and the submitters potentially ridiculed.
  • +
+ +
+ +

Want to make a Quake-derived project?

+
    +
  1. Get our source code from SourceForge.
  2. +
  3. Credit us in your readme and release announcement. It's only fair.
  4. +
  5. Release your source. You have to because Quake's license says so.
  6. +
  7. Don't bundle data files from the full version of Quake with your game.
  8. +
+ +
+ +

Greets

+
    +
  • Hazel, for putting up with me working on this instea of giving you attention - Pete.
  • +
  • All the PSPSDK, PS2DEV and #PSPDEV guys.
  • +
  • Dark-AleX.
  • +
  • All the Noobz guys.
  • +
+ +
+ +

End of file. Thanks for making it this far!

+ + + diff --git a/r17/Revamped src/revamped_src/psp/fnmatch.cpp b/r17/Revamped src/revamped_src/psp/fnmatch.cpp new file mode 100755 index 00000000..9e36a90e --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/fnmatch.cpp @@ -0,0 +1,141 @@ + +#define FNM_NOMATCH (1) /* Match failed. */ +#define FNM_NOSYS (2) /* Function not implemented. */ + +#define FNM_NOESCAPE (0x01) /* Disable backslash escaping. */ +#define FNM_PATHNAME (0x02) /* Slash must be matched by slash. */ +#define FNM_PERIOD (0x04) /* Period must be matched by period. */ +#define FNM_CASEFOLD (0x08) /* Pattern is matched case-insensitive */ +#define FNM_LEADING_DIR (0x10) /* Ignore / after Imatch. */ + +#include +#include +#include "fnmatch.h" + +#define EOS '\0' + +static const char *rangematch(const char *, int, int); + +static inline int +foldcase(int ch, int flags) +{ + + if ((flags & FNM_CASEFOLD) != 0 && isupper(ch)) + return (tolower(ch)); + return (ch); +} + +#define FOLDCASE(ch, flags) foldcase((unsigned char)(ch), (flags)) + +int fnmatch(const char *pattern, const char *string, int flags) +{ + const char *stringstart; + char c, test; + + for (stringstart = string;;) + switch (c = FOLDCASE(*pattern++, flags)) { + case EOS: + if ((flags & FNM_LEADING_DIR) && *string == '/') + return (0); + return (*string == EOS ? 0 : FNM_NOMATCH); + case '?': + if (*string == EOS) + return (FNM_NOMATCH); + if (*string == '/' && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + ++string; + break; + case '*': + c = FOLDCASE(*pattern, flags); + /* Collapse multiple stars. */ + while (c == '*') + c = FOLDCASE(*++pattern, flags); + + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + + /* Optimize for pattern with * at end or before /. */ + if (c == EOS) { + if (flags & FNM_PATHNAME) + return ((flags & FNM_LEADING_DIR) || + strchr(string, '/') == NULL ? + 0 : FNM_NOMATCH); + else + return (0); + } else if (c == '/' && flags & FNM_PATHNAME) { + if ((string = strchr(string, '/')) == NULL) + return (FNM_NOMATCH); + break; + } + + /* General case, use recursion. */ + while ((test = FOLDCASE(*string, flags)) != EOS) { + if (!fnmatch(pattern, string, + flags & ~FNM_PERIOD)) + return (0); + if (test == '/' && flags & FNM_PATHNAME) + break; + ++string; + } + return (FNM_NOMATCH); + case '[': + if (*string == EOS) + return (FNM_NOMATCH); + if (*string == '/' && flags & FNM_PATHNAME) + return (FNM_NOMATCH); + if ((pattern = + rangematch(pattern, FOLDCASE(*string, flags), + flags)) == NULL) + return (FNM_NOMATCH); + ++string; + break; + case '\\': + if (!(flags & FNM_NOESCAPE)) { + if ((c = FOLDCASE(*pattern++, flags)) == EOS) { + c = '\\'; + --pattern; + } + } + /* FALLTHROUGH */ + default: + if (c != FOLDCASE(*string++, flags)) + return (FNM_NOMATCH); + break; + } + /* NOTREACHED */ +} + +static const char * rangematch(const char *pattern, int test, int flags) +{ + int negate, ok; + char c, c2; + + if ((negate = (*pattern == '!' || *pattern == '^')) != 0) + ++pattern; + + for (ok = 0; (c = FOLDCASE(*pattern++, flags)) != ']';) { + if (c == '\\' && !(flags & FNM_NOESCAPE)) + c = FOLDCASE(*pattern++, flags); + if (c == EOS) + return (NULL); + if (*pattern == '-' + && (c2 = FOLDCASE(*(pattern+1), flags)) != EOS && + c2 != ']') { + pattern += 2; + if (c2 == '\\' && !(flags & FNM_NOESCAPE)) + c2 = FOLDCASE(*pattern++, flags); + if (c2 == EOS) + return (NULL); + if (c <= test && test <= c2) + ok = 1; + } else if (c == test) + ok = 1; + } + return (ok == negate ? NULL : pattern); +} diff --git a/r17/Revamped src/revamped_src/psp/fnmatch.h b/r17/Revamped src/revamped_src/psp/fnmatch.h new file mode 100755 index 00000000..6676f543 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/fnmatch.h @@ -0,0 +1,10 @@ +#define FNM_NOMATCH (1) /* Match failed. */ +#define FNM_NOSYS (2) /* Function not implemented. */ + +#define FNM_NOESCAPE (0x01) /* Disable backslash escaping. */ +#define FNM_PATHNAME (0x02) /* Slash must be matched by slash. */ +#define FNM_PERIOD (0x04) /* Period must be matched by period. */ +#define FNM_CASEFOLD (0x08) /* Pattern is matched case-insensitive */ +#define FNM_LEADING_DIR (0x10) /* Ignore / after Imatch. */ + +int fnmatch(const char *pattern, const char *string, int flags); diff --git a/r17/Revamped src/revamped_src/psp/gethost.cpp b/r17/Revamped src/revamped_src/psp/gethost.cpp new file mode 100755 index 00000000..75ccb695 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/gethost.cpp @@ -0,0 +1,115 @@ + +// Copied from newlib as the current newlib did not include it + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_NAME 512 + +#ifdef F_h_errno +int h_errno = NETDB_SUCCESS; +#endif + +struct hostent *gethostbyaddr(const void *addr, int len, int type) +{ + static struct hostent ent; + static char * aliases[1] = { NULL }; + char buf[1024]; + static char sname[MAX_NAME] = ""; + static struct in_addr saddr = { 0 }; + static char *addrlist[2] = { (char *) &saddr, NULL }; + int rid; + int err; + + if((len != sizeof(struct in_addr)) || (type != AF_INET) || (addr == NULL)) + { + h_errno = HOST_NOT_FOUND; + return NULL; + } + + memcpy(&saddr, addr, len); + + if(sceNetResolverCreate(&rid, buf, sizeof(buf)) < 0) + { + h_errno = NO_RECOVERY; + return NULL; + } + + err = sceNetResolverStartAtoN(rid, &saddr, sname, sizeof(sname), 2, 3); + sceNetResolverStop(rid); + sceNetResolverDelete(rid); + if(err < 0) + { + h_errno = HOST_NOT_FOUND; + return NULL; + } + + ent.h_name = sname; + ent.h_aliases = aliases; + ent.h_addrtype = AF_INET; + ent.h_length = sizeof(struct in_addr); + ent.h_addr_list = addrlist; + ent.h_addr = (char *) &saddr; + + return &ent; +} + +struct hostent *gethostbyname(const char *name) +{ + static struct hostent ent; + char buf[1024]; + static char sname[MAX_NAME] = ""; + static struct in_addr saddr = { 0 }; + static char *addrlist[2] = { (char *) &saddr, NULL }; + int rid; + + if(sceNetInetInetAton(name, &saddr) == 0) + { + int err; + + if(sceNetResolverCreate(&rid, buf, sizeof(buf)) < 0) + { + h_errno = NO_RECOVERY; + return NULL; + } + + err = sceNetResolverStartNtoA(rid, name, &saddr, 2, 3); + sceNetResolverDelete(rid); + if(err < 0) + { + h_errno = HOST_NOT_FOUND; + return NULL; + } + + } + + snprintf(sname, MAX_NAME, "%s", name); + ent.h_name = sname; + ent.h_aliases = 0; + ent.h_addrtype = AF_INET; + ent.h_length = sizeof(struct in_addr); + ent.h_addr_list = addrlist; + ent.h_addr = (char *) &saddr; + + return &ent; +} + +int gethostname(char *name, int namelen) +{ + memset(name, 0, namelen); + if(sceUtilityGetSystemParamString(PSP_SYSTEMPARAM_ID_STRING_NICKNAME, + name, namelen) == PSP_SYSTEMPARAM_RETVAL_FAIL) + { + strcpy(name, "UNNAMED"); + return -1; + } + + return 1; +} diff --git a/r17/Revamped src/revamped_src/psp/gethost.hpp b/r17/Revamped src/revamped_src/psp/gethost.hpp new file mode 100755 index 00000000..7b0d4a24 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/gethost.hpp @@ -0,0 +1,9 @@ + +#ifndef GETHOST +#define GETHOST + +struct hostent *gethostbyaddr(const void *addr, int len, int type); +struct hostent *gethostbyname(const char *name); +int gethostname(char *name, int namelen); + +#endif diff --git a/r17/Revamped src/revamped_src/psp/input.cpp b/r17/Revamped src/revamped_src/psp/input.cpp new file mode 100755 index 00000000..2b03f3b5 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/input.cpp @@ -0,0 +1,398 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#include + +extern "C" +{ +#include "../quakedef.h" +} + +namespace quake +{ + namespace input + { + // A map from button mask to Quake key. + static const unsigned int buttonCount = sizeof(unsigned int) * 8; + typedef int ButtonToKeyMap[buttonCount]; + static ButtonToKeyMap buttonToGameKeyMap; + static ButtonToKeyMap buttonToConsoleKeyMap; + static ButtonToKeyMap buttonToMessageKeyMap; + static ButtonToKeyMap buttonToMenuKeyMap; + + // The previous key state (for checking if things changed). + static SceCtrlData lastPad; + static bool readyToBindKeys = false; + + static unsigned int buttonMaskToShift(unsigned int mask) + { + // Bad mask? + if (!mask) + return 0; + + // Shift right until we hit a 1. + unsigned int shift = 0; + while ((mask & 1) == 0) + { + mask >>= 1; + ++shift; + } + return shift; + } + + static float inverseLerp(float a, float b, float v) + { + return (v - a) / (b - a); + } + + static float applyDeadZone(float axis, float deadZone) + { + if (axis > deadZone) + { + return inverseLerp(deadZone, 1.0f, axis); + } + else if (axis < -deadZone) + { + return -inverseLerp(deadZone, 1.0f, -axis); + } + else + { + return 0.0f; + } + } + } +} + +// Quake globals. +extern "C" int bind_grab; + +using namespace quake; +using namespace quake::input; + +extern cvar_t cl_yawspeed; +extern cvar_t cl_pitchspeed; + +extern cvar_t in_freelook_analog; +extern cvar_t in_analog_strafe; + +extern cvar_t in_x_axis_adjust; +extern cvar_t in_y_axis_adjust; +extern cvar_t scr_fov; + +void IN_Init (void) +{ + // Set up the controller. + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); + + // Japanese users would prefer to have X as cancel and O as OK. + unsigned int okButton = PSP_CTRL_CROSS; + unsigned int cancelButton = PSP_CTRL_CIRCLE; + + // Build the button to Quake key maps. + // Common keys: + buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_SELECT)] = '~'; + buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_START)] = K_ESCAPE; + + buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_UP)] = K_UPARROW; + buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_RIGHT)] = K_RIGHTARROW; + buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_DOWN)] = K_DOWNARROW; + buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_LEFT)] = K_LEFTARROW; + memcpy(buttonToConsoleKeyMap, buttonToGameKeyMap, sizeof(ButtonToKeyMap)); + memcpy(buttonToMessageKeyMap, buttonToGameKeyMap, sizeof(ButtonToKeyMap)); + memcpy(buttonToMenuKeyMap, buttonToGameKeyMap, sizeof(ButtonToKeyMap)); + + // Game keys: + buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_LTRIGGER)] = K_AUX1; + buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_RTRIGGER)] = K_AUX2; + buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_TRIANGLE)] = K_JOY1; + buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_CIRCLE)] = K_JOY2; + buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_CROSS)] = K_JOY3; + buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_SQUARE)] = K_JOY4; + + // Console keys: + buttonToConsoleKeyMap[buttonMaskToShift(PSP_CTRL_LTRIGGER)] = K_PGUP; + buttonToConsoleKeyMap[buttonMaskToShift(PSP_CTRL_RTRIGGER)] = K_PGDN; + buttonToConsoleKeyMap[buttonMaskToShift(okButton)] = K_ENTER; + buttonToConsoleKeyMap[buttonMaskToShift(cancelButton)] = K_ESCAPE; + buttonToConsoleKeyMap[buttonMaskToShift(PSP_CTRL_TRIANGLE)] = K_DEL; + buttonToConsoleKeyMap[buttonMaskToShift(PSP_CTRL_SQUARE)] = K_INS; + + // Message keys: + memcpy(buttonToMessageKeyMap, buttonToConsoleKeyMap, sizeof(ButtonToKeyMap)); + + // Menu keys: + buttonToMenuKeyMap[buttonMaskToShift(PSP_CTRL_SQUARE)] = K_INS; + buttonToMenuKeyMap[buttonMaskToShift(cancelButton)] = K_ESCAPE; + buttonToMenuKeyMap[buttonMaskToShift(okButton)] = K_ENTER; + buttonToMenuKeyMap[buttonMaskToShift(PSP_CTRL_TRIANGLE)] = K_DEL; + buttonToMenuKeyMap[buttonMaskToShift(PSP_CTRL_LTRIGGER)] = K_AUX1; + buttonToMenuKeyMap[buttonMaskToShift(PSP_CTRL_RTRIGGER)] = K_AUX2; +} + +void IN_Shutdown (void) +{ +} + +void IN_Commands (void) +{ + // Changed in or out of key binding mode? + if ((bind_grab != 0) != readyToBindKeys) + { + // Was in key binding mode? + if (readyToBindKeys) + { + // Just left key binding mode. + // Release all keys which are pressed. + for (unsigned int button = 0; button < buttonCount; ++button) + { + // Was the button pressed? + if (lastPad.Buttons & (1 << button)) + { + // Is the button in the map? + const int key = buttonToGameKeyMap[button]; + if (key) + { + // Send a release event. + Key_Event(key, qfalse); + } + } + } + + // We're not ready to bind keys any more. + readyToBindKeys = false; + } + else + { + // Entering key binding mode. + // Release all keys which are pressed. + for (unsigned int button = 0; button < buttonCount; ++button) + { + // Was the button pressed? + if (lastPad.Buttons & (1 << button)) + { + // Is the button in the map? + const int key = buttonToMenuKeyMap[button]; + if (key) + { + // Send a release event. + Key_Event(key, qfalse); + } + } + } + + // We're now ready to bind keys. + readyToBindKeys = true; + } + } + + // Use a different key mapping depending on where inputs are going to go. + const ButtonToKeyMap* buttonToKeyMap = 0; + switch (key_dest) + { + case key_game: + buttonToKeyMap = &buttonToGameKeyMap; + break; + + case key_console: + buttonToKeyMap = &buttonToConsoleKeyMap; + break; + + case key_message: + buttonToKeyMap = &buttonToMessageKeyMap; + break; + + case key_menu: + // Binding keys? + if (readyToBindKeys) + { + buttonToKeyMap = &buttonToGameKeyMap; + } + else + { + buttonToKeyMap = &buttonToMenuKeyMap; + } + break; + + default: + Sys_Error("Unhandled key destination %d", key_dest); + return; + } + + // Read the pad state. + SceCtrlData pad; + sceCtrlPeekBufferPositive(&pad, 1); + + // Find out which buttons have changed. + SceCtrlData deltaPad; + deltaPad.Buttons = pad.Buttons ^ lastPad.Buttons; + deltaPad.Lx = pad.Lx - lastPad.Lx; + deltaPad.Ly = pad.Ly - lastPad.Ly; + deltaPad.TimeStamp = pad.TimeStamp - lastPad.TimeStamp; + + // Handle buttons which have changed. + for (unsigned int button = 0; button < buttonCount; ++button) + { + // Has the button changed? + const unsigned int buttonMask = 1 << button; + if (deltaPad.Buttons & buttonMask) + { + // Is the button in the map? + const int key = (*buttonToKeyMap)[button]; + if (key) + { + // Send an event. + const qboolean state = (pad.Buttons & buttonMask) ? qtrue : qfalse; + Key_Event(key, state); + } + } + } + + // Remember the pad state for next time. + lastPad = pad; +} + +float IN_CalcInput(int axis, float speed, float tolerance, float acceleration) { + + float value = ((float) axis / 128.0f) - 1.0f; + + if (value == 0.0f) { + return 0.0f; + } + + float abs_value = fabs(value); + + if (abs_value < tolerance) { + return 0.0f; + } + + abs_value -= tolerance; + abs_value /= (1.0f - tolerance); + abs_value = powf(abs_value, acceleration); + abs_value *= speed; + + if (value < 0.0f) { + value = -abs_value; + } else { + value = abs_value; + } + return value; +} + +void IN_Move (usercmd_t *cmd) +{ + unsigned char analog_strafe = 0; + + int x_adjust; + int y_adjust; + float speed; + + // Don't let the pitch drift back to centre if analog nub look is on. + if (in_freelook_analog.value) + { + Cbuf_AddText("+mlook\n"); + V_StopPitchDrift(); + } + else + { + Cbuf_AddText("-mlook\n"); + if (in_analog_strafe.value || (in_strafe.state & 1)) + analog_strafe = 1; + } + + if(kurok) + { + if(scr_fov.value <= 25) + { + x_adjust = in_x_axis_adjust.value / 4; + y_adjust = in_y_axis_adjust.value / 4; + speed = in_sensitivity.value / 4; + } + else if(scr_fov.value <= 50) + { + x_adjust = in_x_axis_adjust.value / 3; + y_adjust = in_y_axis_adjust.value / 3; + speed = in_sensitivity.value / 3; + } + else if(scr_fov.value <= 75) + { + x_adjust = in_x_axis_adjust.value / 2; + y_adjust = in_y_axis_adjust.value / 2; + speed = in_sensitivity.value / 2; + } + else + { + x_adjust = in_x_axis_adjust.value; + y_adjust = in_y_axis_adjust.value; + speed = in_sensitivity.value; + } + } + else + { + x_adjust = in_x_axis_adjust.value; + y_adjust = in_y_axis_adjust.value; + speed = in_sensitivity.value; + } + + // Read the pad state. + SceCtrlData pad; + sceCtrlPeekBufferPositive(&pad, 1); + + // Convert the inputs to floats in the range [-1, 1]. + // Implement the dead zone. + float deadZone = in_tolerance.value; + float acceleration = in_acceleration.value; + + if (speed <= 0) + speed = 0; + + float x = IN_CalcInput(pad.Lx, (speed *0.1) + x_adjust, deadZone, acceleration); + float y = IN_CalcInput(pad.Ly, (speed *0.1) + y_adjust, deadZone, acceleration); + + // Set the yaw. + + // Analog nub look? + if (!analog_strafe) { + const float yawScale = 30.0f; + cl.viewangles[YAW] -= yawScale * x * host_frametime; + + if (in_freelook_analog.value) + { + // Set the pitch. + const bool invertPitch = m_pitch.value < 0; + const float pitchScale = yawScale * (invertPitch ? -1 : 1); + cl.viewangles[PITCH] += pitchScale * y * host_frametime; + + // Don't look too far up or down. + if (cl.viewangles[PITCH] > 90.0f) + cl.viewangles[PITCH] = 90.0f; + if (cl.viewangles[PITCH] < -90.0f) + cl.viewangles[PITCH] = -90.0f; + } + else + { + // Move using up and down. + cmd->forwardmove -= cl_forwardspeed.value * y; + } + } else { + cmd->sidemove += cl_sidespeed.value * x; + cmd->forwardmove -= cl_forwardspeed.value * y; + } +} diff --git a/r17/Revamped src/revamped_src/psp/lightmaps.h b/r17/Revamped src/revamped_src/psp/lightmaps.h new file mode 100755 index 00000000..30ca0ff9 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/lightmaps.h @@ -0,0 +1,3 @@ + +extern int LIGHTMAP_BYTES; +extern int MAX_LIGHTMAPS; diff --git a/r17/Revamped src/revamped_src/psp/m33libs/include/kubridge.h b/r17/Revamped src/revamped_src/psp/m33libs/include/kubridge.h new file mode 100755 index 00000000..35613a44 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/m33libs/include/kubridge.h @@ -0,0 +1,98 @@ +#ifndef __KULIBRARY__ + +#define __KULIBRARY__ + +#include +#include +#include +#include + +/** + * Functions to let user mode access certain functions only available in + * kernel mode +*/ + +/** + * Load a module using ModuleMgrForKernel. + * + * @param path - The path to the module to load. + * @param flags - Unused, always 0 . + * @param option - Pointer to a mod_param_t structure. Can be NULL. + * + * @returns The UID of the loaded module on success, otherwise one of ::PspKernelErrorCodes. + */ +SceUID kuKernelLoadModule(const char *path, int flags, SceKernelLMOption *option); + + +/** + * Load a module with a specific apitype + * + * @param aptype - The apitype + * @param path - The path to the module to load. + * @param flags - Unused, always 0 . + * @param option - Pointer to a mod_param_t structure. Can be NULL. + * + * @returns The UID of the loaded module on success, otherwise one of ::PspKernelErrorCodes. + */ +SceUID kuKernelLoadModuleWithApitype2(int apitype, const char *path, int flags, SceKernelLMOption *option); + +/** + * Gets the api type + * + * @returns the api type in which the system has booted +*/ +int kuKernelInitApitype(); + +/** + * Gets the filename of the executable to be launched after all modules of the api. + * + * @param initfilename - String where copy the initfilename + * @returns 0 on success +*/ +int kuKernelInitFileName(char *initfilename); + +/** + * + * Gets the device in which the application was launched. + * + * @returns the device code, one of PSPBootFrom values. +*/ +int kuKernelBootFrom(); + +/** + * Get the key configuration in which the system has booted. + * + * @returns the key configuration code, one of PSPKeyConfig values +*/ +int kuKernelInitKeyConfig(); + +/** + * Get the user level of the current thread + * + * @return The user level, < 0 on error + */ +int kuKernelGetUserLevel(void); + +/** + * Set the protection of a block of ddr memory + * + * @param addr - Address to set protection on + * @param size - Size of block + * @param prot - Protection bitmask + * + * @return < 0 on error + */ +int kuKernelSetDdrMemoryProtection(void *addr, int size, int prot); + +/** + * Gets the model of the PSP from user mode. + * This function is available since 3.60 M33. + * In previous version, use the kernel function sceKernelGetModel + * + * @return one of PspModel values +*/ +int kuKernelGetModel(void); + + +#endif + diff --git a/r17/Revamped src/revamped_src/psp/m33libs/kubridge.h b/r17/Revamped src/revamped_src/psp/m33libs/kubridge.h new file mode 100755 index 00000000..35613a44 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/m33libs/kubridge.h @@ -0,0 +1,98 @@ +#ifndef __KULIBRARY__ + +#define __KULIBRARY__ + +#include +#include +#include +#include + +/** + * Functions to let user mode access certain functions only available in + * kernel mode +*/ + +/** + * Load a module using ModuleMgrForKernel. + * + * @param path - The path to the module to load. + * @param flags - Unused, always 0 . + * @param option - Pointer to a mod_param_t structure. Can be NULL. + * + * @returns The UID of the loaded module on success, otherwise one of ::PspKernelErrorCodes. + */ +SceUID kuKernelLoadModule(const char *path, int flags, SceKernelLMOption *option); + + +/** + * Load a module with a specific apitype + * + * @param aptype - The apitype + * @param path - The path to the module to load. + * @param flags - Unused, always 0 . + * @param option - Pointer to a mod_param_t structure. Can be NULL. + * + * @returns The UID of the loaded module on success, otherwise one of ::PspKernelErrorCodes. + */ +SceUID kuKernelLoadModuleWithApitype2(int apitype, const char *path, int flags, SceKernelLMOption *option); + +/** + * Gets the api type + * + * @returns the api type in which the system has booted +*/ +int kuKernelInitApitype(); + +/** + * Gets the filename of the executable to be launched after all modules of the api. + * + * @param initfilename - String where copy the initfilename + * @returns 0 on success +*/ +int kuKernelInitFileName(char *initfilename); + +/** + * + * Gets the device in which the application was launched. + * + * @returns the device code, one of PSPBootFrom values. +*/ +int kuKernelBootFrom(); + +/** + * Get the key configuration in which the system has booted. + * + * @returns the key configuration code, one of PSPKeyConfig values +*/ +int kuKernelInitKeyConfig(); + +/** + * Get the user level of the current thread + * + * @return The user level, < 0 on error + */ +int kuKernelGetUserLevel(void); + +/** + * Set the protection of a block of ddr memory + * + * @param addr - Address to set protection on + * @param size - Size of block + * @param prot - Protection bitmask + * + * @return < 0 on error + */ +int kuKernelSetDdrMemoryProtection(void *addr, int size, int prot); + +/** + * Gets the model of the PSP from user mode. + * This function is available since 3.60 M33. + * In previous version, use the kernel function sceKernelGetModel + * + * @return one of PspModel values +*/ +int kuKernelGetModel(void); + + +#endif + diff --git a/r17/Revamped src/revamped_src/psp/m33libs/lib/libpspkubridge.a b/r17/Revamped src/revamped_src/psp/m33libs/lib/libpspkubridge.a new file mode 100755 index 00000000..779c54f7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/m33libs/lib/libpspkubridge.a differ diff --git a/r17/Revamped src/revamped_src/psp/m33libs/libpspaudiocodec.a b/r17/Revamped src/revamped_src/psp/m33libs/libpspaudiocodec.a new file mode 100755 index 00000000..56a287d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/m33libs/libpspaudiocodec.a differ diff --git a/r17/Revamped src/revamped_src/psp/m33libs/libpspkubridge.a b/r17/Revamped src/revamped_src/psp/m33libs/libpspkubridge.a new file mode 100755 index 00000000..779c54f7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/m33libs/libpspkubridge.a differ diff --git a/r17/Revamped src/revamped_src/psp/mad.h b/r17/Revamped src/revamped_src/psp/mad.h new file mode 100755 index 00000000..2f7cbf55 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/mad.h @@ -0,0 +1,964 @@ +/* + * libmad - MPEG audio decoder library + * Copyright (C) 2000-2004 Underbit Technologies, Inc. + * + * 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 + * + * If you would like to negotiate alternate licensing terms, you may do + * so by contacting: Underbit Technologies, Inc. + */ + +# ifdef __cplusplus +extern "C" { +# endif + +# define FPM_MIPS + + + +# define SIZEOF_INT 4 +# define SIZEOF_LONG 4 +# define SIZEOF_LONG_LONG 8 + + +/* Id: version.h,v 1.26 2004/01/23 09:41:33 rob Exp */ + +# ifndef LIBMAD_VERSION_H +# define LIBMAD_VERSION_H + +# define MAD_VERSION_MAJOR 0 +# define MAD_VERSION_MINOR 15 +# define MAD_VERSION_PATCH 1 +# define MAD_VERSION_EXTRA " (beta)" + +# define MAD_VERSION_STRINGIZE(str) #str +# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num) + +# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \ + MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \ + MAD_VERSION_STRING(MAD_VERSION_PATCH) \ + MAD_VERSION_EXTRA + +# define MAD_PUBLISHYEAR "2000-2004" +# define MAD_AUTHOR "Underbit Technologies, Inc." +# define MAD_EMAIL "info@underbit.com" + +extern char const mad_version[]; +extern char const mad_copyright[]; +extern char const mad_author[]; +extern char const mad_build[]; + +# endif + +/* Id: fixed.h,v 1.38 2004/02/17 02:02:03 rob Exp */ + +# ifndef LIBMAD_FIXED_H +# define LIBMAD_FIXED_H + +# if SIZEOF_INT >= 4 +typedef signed int mad_fixed_t; + +typedef signed int mad_fixed64hi_t; +typedef unsigned int mad_fixed64lo_t; +# else +typedef signed long mad_fixed_t; + +typedef signed long mad_fixed64hi_t; +typedef unsigned long mad_fixed64lo_t; +# endif + +# if defined(_MSC_VER) +# define mad_fixed64_t signed __int64 +# elif 1 || defined(__GNUC__) +# define mad_fixed64_t signed long long +# endif + +# if defined(FPM_FLOAT) +typedef double mad_sample_t; +# else +typedef mad_fixed_t mad_sample_t; +# endif + +/* + * Fixed-point format: 0xABBBBBBB + * A == whole part (sign + 3 bits) + * B == fractional part (28 bits) + * + * Values are signed two's complement, so the effective range is: + * 0x80000000 to 0x7fffffff + * -8.0 to +7.9999999962747097015380859375 + * + * The smallest representable value is: + * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9) + * + * 28 bits of fractional accuracy represent about + * 8.6 digits of decimal accuracy. + * + * Fixed-point numbers can be added or subtracted as normal + * integers, but multiplication requires shifting the 64-bit result + * from 56 fractional bits back to 28 (and rounding.) + * + * Changing the definition of MAD_F_FRACBITS is only partially + * supported, and must be done with care. + */ + +# define MAD_F_FRACBITS 28 + +# if MAD_F_FRACBITS == 28 +# define MAD_F(x) ((mad_fixed_t) (x##L)) +# else +# if MAD_F_FRACBITS < 28 +# warning "MAD_F_FRACBITS < 28" +# define MAD_F(x) ((mad_fixed_t) \ + (((x##L) + \ + (1L << (28 - MAD_F_FRACBITS - 1))) >> \ + (28 - MAD_F_FRACBITS))) +# elif MAD_F_FRACBITS > 28 +# error "MAD_F_FRACBITS > 28 not currently supported" +# define MAD_F(x) ((mad_fixed_t) \ + ((x##L) << (MAD_F_FRACBITS - 28))) +# endif +# endif + +# define MAD_F_MIN ((mad_fixed_t) -0x80000000L) +# define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL) + +# define MAD_F_ONE MAD_F(0x10000000) + +# define mad_f_tofixed(x) ((mad_fixed_t) \ + ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5)) +# define mad_f_todouble(x) ((double) \ + ((x) / (double) (1L << MAD_F_FRACBITS))) + +# define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS) +# define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1)) + /* (x should be positive) */ + +# define mad_f_fromint(x) ((x) << MAD_F_FRACBITS) + +# define mad_f_add(x, y) ((x) + (y)) +# define mad_f_sub(x, y) ((x) - (y)) + +# if defined(FPM_FLOAT) +# error "FPM_FLOAT not yet supported" + +# undef MAD_F +# define MAD_F(x) mad_f_todouble(x) + +# define mad_f_mul(x, y) ((x) * (y)) +# define mad_f_scale64 + +# undef ASO_ZEROCHECK + +# elif defined(FPM_64BIT) + +/* + * This version should be the most accurate if 64-bit types are supported by + * the compiler, although it may not be the most efficient. + */ +# if defined(OPT_ACCURACY) +# define mad_f_mul(x, y) \ + ((mad_fixed_t) \ + ((((mad_fixed64_t) (x) * (y)) + \ + (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS)) +# else +# define mad_f_mul(x, y) \ + ((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS)) +# endif + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- Intel --------------------------------------------------------------- */ + +# elif defined(FPM_INTEL) + +# if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4035) /* no return value */ +static __forceinline +mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) +{ + enum { + fracbits = MAD_F_FRACBITS + }; + + __asm { + mov eax, x + imul y + shrd eax, edx, fracbits + } + + /* implicit return of eax */ +} +# pragma warning(pop) + +# define mad_f_mul mad_f_mul_inline +# define mad_f_scale64 +# else +/* + * This Intel version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("imull %3" \ + : "=a" (lo), "=d" (hi) \ + : "%a" (x), "rm" (y) \ + : "cc") + +# if defined(OPT_ACCURACY) +/* + * This gives best accuracy but is not very fast. + */ +# define MAD_F_MLA(hi, lo, x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + MAD_F_MLX(__hi, __lo, (x), (y)); \ + asm ("addl %2,%0\n\t" \ + "adcl %3,%1" \ + : "=rm" (lo), "=rm" (hi) \ + : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \ + : "cc"); \ + }) +# endif /* OPT_ACCURACY */ + +# if defined(OPT_ACCURACY) +/* + * Surprisingly, this is faster than SHRD followed by ADC. + */ +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed64hi_t __hi_; \ + mad_fixed64lo_t __lo_; \ + mad_fixed_t __result; \ + asm ("addl %4,%2\n\t" \ + "adcl %5,%3" \ + : "=rm" (__lo_), "=rm" (__hi_) \ + : "0" (lo), "1" (hi), \ + "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \ + : "cc"); \ + asm ("shrdl %3,%2,%1" \ + : "=rm" (__result) \ + : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# elif defined(OPT_INTEL) +/* + * Alternate Intel scaling that may or may not perform better. + */ +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("shrl %3,%1\n\t" \ + "shll %4,%2\n\t" \ + "orl %2,%1" \ + : "=rm" (__result) \ + : "0" (lo), "r" (hi), \ + "I" (MAD_F_SCALEBITS), "I" (32 - MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# else +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("shrdl %3,%2,%1" \ + : "=rm" (__result) \ + : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# endif /* OPT_ACCURACY */ + +# define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif + +/* --- ARM ----------------------------------------------------------------- */ + +# elif defined(FPM_ARM) + +/* + * This ARM V4 version is as accurate as FPM_64BIT but much faster. The + * least significant bit is properly rounded at no CPU cycle cost! + */ +# if 1 +/* + * This is faster than the default implementation via MAD_F_MLX() and + * mad_f_scale64(). + */ +# define mad_f_mul(x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + mad_fixed_t __result; \ + asm ("smull %0, %1, %3, %4\n\t" \ + "movs %0, %0, lsr %5\n\t" \ + "adc %2, %0, %1, lsl %6" \ + : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ + : "%r" (x), "r" (y), \ + "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) +# endif + +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("smull %0, %1, %2, %3" \ + : "=&r" (lo), "=&r" (hi) \ + : "%r" (x), "r" (y)) + +# define MAD_F_MLA(hi, lo, x, y) \ + asm ("smlal %0, %1, %2, %3" \ + : "+r" (lo), "+r" (hi) \ + : "%r" (x), "r" (y)) + +# define MAD_F_MLN(hi, lo) \ + asm ("rsbs %0, %2, #0\n\t" \ + "rsc %1, %3, #0" \ + : "=r" (lo), "=r" (hi) \ + : "0" (lo), "1" (hi) \ + : "cc") + +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("movs %0, %1, lsr %3\n\t" \ + "adc %0, %0, %2, lsl %4" \ + : "=&r" (__result) \ + : "r" (lo), "r" (hi), \ + "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- MIPS ---------------------------------------------------------------- */ + +# elif defined(FPM_MIPS) + +/* + * This MIPS version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("mult %2,%3" \ + : "=l" (lo), "=h" (hi) \ + : "%r" (x), "r" (y)) + +# if defined(HAVE_MADD_ASM) +# define MAD_F_MLA(hi, lo, x, y) \ + asm ("madd %2,%3" \ + : "+l" (lo), "+h" (hi) \ + : "%r" (x), "r" (y)) +# elif defined(HAVE_MADD16_ASM) +/* + * This loses significant accuracy due to the 16-bit integer limit in the + * multiply/accumulate instruction. + */ +# define MAD_F_ML0(hi, lo, x, y) \ + asm ("mult %2,%3" \ + : "=l" (lo), "=h" (hi) \ + : "%r" ((x) >> 12), "r" ((y) >> 16)) +# define MAD_F_MLA(hi, lo, x, y) \ + asm ("madd16 %2,%3" \ + : "+l" (lo), "+h" (hi) \ + : "%r" ((x) >> 12), "r" ((y) >> 16)) +# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo)) +# endif + +# if defined(OPT_SPEED) +# define mad_f_scale64(hi, lo) \ + ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS))) +# define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif + +/* --- SPARC --------------------------------------------------------------- */ + +# elif defined(FPM_SPARC) + +/* + * This SPARC V8 version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + asm ("smul %2, %3, %0\n\t" \ + "rd %%y, %1" \ + : "=r" (lo), "=r" (hi) \ + : "%r" (x), "rI" (y)) + +/* --- PowerPC ------------------------------------------------------------- */ + +# elif defined(FPM_PPC) + +/* + * This PowerPC version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). + */ +# define MAD_F_MLX(hi, lo, x, y) \ + do { \ + asm ("mullw %0,%1,%2" \ + : "=r" (lo) \ + : "%r" (x), "r" (y)); \ + asm ("mulhw %0,%1,%2" \ + : "=r" (hi) \ + : "%r" (x), "r" (y)); \ + } \ + while (0) + +# if defined(OPT_ACCURACY) +/* + * This gives best accuracy but is not very fast. + */ +# define MAD_F_MLA(hi, lo, x, y) \ + ({ mad_fixed64hi_t __hi; \ + mad_fixed64lo_t __lo; \ + MAD_F_MLX(__hi, __lo, (x), (y)); \ + asm ("addc %0,%2,%3\n\t" \ + "adde %1,%4,%5" \ + : "=r" (lo), "=r" (hi) \ + : "%r" (lo), "r" (__lo), \ + "%r" (hi), "r" (__hi) \ + : "xer"); \ + }) +# endif + +# if defined(OPT_ACCURACY) +/* + * This is slower than the truncating version below it. + */ +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result, __round; \ + asm ("rotrwi %0,%1,%2" \ + : "=r" (__result) \ + : "r" (lo), "i" (MAD_F_SCALEBITS)); \ + asm ("extrwi %0,%1,1,0" \ + : "=r" (__round) \ + : "r" (__result)); \ + asm ("insrwi %0,%1,%2,0" \ + : "+r" (__result) \ + : "r" (hi), "i" (MAD_F_SCALEBITS)); \ + asm ("add %0,%1,%2" \ + : "=r" (__result) \ + : "%r" (__result), "r" (__round)); \ + __result; \ + }) +# else +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("rotrwi %0,%1,%2" \ + : "=r" (__result) \ + : "r" (lo), "i" (MAD_F_SCALEBITS)); \ + asm ("insrwi %0,%1,%2,0" \ + : "+r" (__result) \ + : "r" (hi), "i" (MAD_F_SCALEBITS)); \ + __result; \ + }) +# endif + +# define MAD_F_SCALEBITS MAD_F_FRACBITS + +/* --- Default ------------------------------------------------------------- */ + +# elif defined(FPM_DEFAULT) + +/* + * This version is the most portable but it loses significant accuracy. + * Furthermore, accuracy is biased against the second argument, so care + * should be taken when ordering operands. + * + * The scale factors are constant as this is not used with SSO. + * + * Pre-rounding is required to stay within the limits of compliance. + */ +# if defined(OPT_SPEED) +# define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16)) +# else +# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \ + (((y) + (1L << 15)) >> 16)) +# endif + +/* ------------------------------------------------------------------------- */ + +# else +# error "no FPM selected" +# endif + +/* default implementations */ + +# if !defined(mad_f_mul) +# define mad_f_mul(x, y) \ + ({ register mad_fixed64hi_t __hi; \ + register mad_fixed64lo_t __lo; \ + MAD_F_MLX(__hi, __lo, (x), (y)); \ + mad_f_scale64(__hi, __lo); \ + }) +# endif + +# if !defined(MAD_F_MLA) +# define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y))) +# define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y))) +# define MAD_F_MLN(hi, lo) ((lo) = -(lo)) +# define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) +# endif + +# if !defined(MAD_F_ML0) +# define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y)) +# endif + +# if !defined(MAD_F_MLN) +# define MAD_F_MLN(hi, lo) ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi)) +# endif + +# if !defined(MAD_F_MLZ) +# define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo)) +# endif + +# if !defined(mad_f_scale64) +# if defined(OPT_ACCURACY) +# define mad_f_scale64(hi, lo) \ + ((((mad_fixed_t) \ + (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \ + ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1) +# else +# define mad_f_scale64(hi, lo) \ + ((mad_fixed_t) \ + (((hi) << (32 - MAD_F_SCALEBITS)) | \ + ((lo) >> MAD_F_SCALEBITS))) +# endif +# define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif + +/* C routines */ + +mad_fixed_t mad_f_abs(mad_fixed_t); +mad_fixed_t mad_f_div(mad_fixed_t, mad_fixed_t); + +# endif + +/* Id: bit.h,v 1.12 2004/01/23 09:41:32 rob Exp */ + +# ifndef LIBMAD_BIT_H +# define LIBMAD_BIT_H + +struct mad_bitptr { + unsigned char const *byte; + unsigned short cache; + unsigned short left; +}; + +void mad_bit_init(struct mad_bitptr *, unsigned char const *); + +# define mad_bit_finish(bitptr) /* nothing */ + +unsigned int mad_bit_length(struct mad_bitptr const *, + struct mad_bitptr const *); + +# define mad_bit_bitsleft(bitptr) ((bitptr)->left) +unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *); + +void mad_bit_skip(struct mad_bitptr *, unsigned int); +unsigned long mad_bit_read(struct mad_bitptr *, unsigned int); +void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long); + +unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short); + +# endif + +/* Id: timer.h,v 1.16 2004/01/23 09:41:33 rob Exp */ + +# ifndef LIBMAD_TIMER_H +# define LIBMAD_TIMER_H + +typedef struct { + signed long seconds; /* whole seconds */ + unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ +} mad_timer_t; + +extern mad_timer_t const mad_timer_zero; + +# define MAD_TIMER_RESOLUTION 352800000UL + +enum mad_units { + MAD_UNITS_HOURS = -2, + MAD_UNITS_MINUTES = -1, + MAD_UNITS_SECONDS = 0, + + /* metric units */ + + MAD_UNITS_DECISECONDS = 10, + MAD_UNITS_CENTISECONDS = 100, + MAD_UNITS_MILLISECONDS = 1000, + + /* audio sample units */ + + MAD_UNITS_8000_HZ = 8000, + MAD_UNITS_11025_HZ = 11025, + MAD_UNITS_12000_HZ = 12000, + + MAD_UNITS_16000_HZ = 16000, + MAD_UNITS_22050_HZ = 22050, + MAD_UNITS_24000_HZ = 24000, + + MAD_UNITS_32000_HZ = 32000, + MAD_UNITS_44100_HZ = 44100, + MAD_UNITS_48000_HZ = 48000, + + /* video frame/field units */ + + MAD_UNITS_24_FPS = 24, + MAD_UNITS_25_FPS = 25, + MAD_UNITS_30_FPS = 30, + MAD_UNITS_48_FPS = 48, + MAD_UNITS_50_FPS = 50, + MAD_UNITS_60_FPS = 60, + + /* CD audio frames */ + + MAD_UNITS_75_FPS = 75, + + /* video drop-frame units */ + + MAD_UNITS_23_976_FPS = -24, + MAD_UNITS_24_975_FPS = -25, + MAD_UNITS_29_97_FPS = -30, + MAD_UNITS_47_952_FPS = -48, + MAD_UNITS_49_95_FPS = -50, + MAD_UNITS_59_94_FPS = -60 +}; + +# define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero)) + +int mad_timer_compare(mad_timer_t, mad_timer_t); + +# define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero) + +void mad_timer_negate(mad_timer_t *); +mad_timer_t mad_timer_abs(mad_timer_t); + +void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long); +void mad_timer_add(mad_timer_t *, mad_timer_t); +void mad_timer_multiply(mad_timer_t *, signed long); + +signed long mad_timer_count(mad_timer_t, enum mad_units); +unsigned long mad_timer_fraction(mad_timer_t, unsigned long); +void mad_timer_string(mad_timer_t, char *, char const *, + enum mad_units, enum mad_units, unsigned long); + +# endif + +/* Id: stream.h,v 1.20 2004/02/05 09:02:39 rob Exp */ + +# ifndef LIBMAD_STREAM_H +# define LIBMAD_STREAM_H + + +# define MAD_BUFFER_GUARD 8 +# define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD) + +enum mad_error { + MAD_ERROR_NONE = 0x0000, /* no error */ + + MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ + MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ + + MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ + + MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ + MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ + MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ + MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ + MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ + + MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ + MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ + MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ + MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */ + MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ + MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ + MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ + MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ + MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ + MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ + MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ + MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ + MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ +}; + +# define MAD_RECOVERABLE(error) ((error) & 0xff00) + +struct mad_stream { + unsigned char const *buffer; /* input bitstream buffer */ + unsigned char const *bufend; /* end of buffer */ + unsigned long skiplen; /* bytes to skip before next frame */ + + int sync; /* stream sync found */ + unsigned long freerate; /* free bitrate (fixed) */ + + unsigned char const *this_frame; /* start of current frame */ + unsigned char const *next_frame; /* start of next frame */ + struct mad_bitptr ptr; /* current processing bit pointer */ + + struct mad_bitptr anc_ptr; /* ancillary bits pointer */ + unsigned int anc_bitlen; /* number of ancillary bits */ + + unsigned char (*main_data)[MAD_BUFFER_MDLEN]; + /* Layer III main_data() */ + unsigned int md_len; /* bytes in main_data */ + + int options; /* decoding options (see below) */ + enum mad_error error; /* error code (see above) */ +}; + +enum { + MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ + MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */ +# if 0 /* not yet implemented */ + MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ + MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ + MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */ +# endif +}; + +void mad_stream_init(struct mad_stream *); +void mad_stream_finish(struct mad_stream *); + +# define mad_stream_options(stream, opts) \ + ((void) ((stream)->options = (opts))) + +void mad_stream_buffer(struct mad_stream *, + unsigned char const *, unsigned long); +void mad_stream_skip(struct mad_stream *, unsigned long); + +int mad_stream_sync(struct mad_stream *); + +char const *mad_stream_errorstr(struct mad_stream const *); + +# endif + +/* Id: frame.h,v 1.20 2004/01/23 09:41:32 rob Exp */ + +# ifndef LIBMAD_FRAME_H +# define LIBMAD_FRAME_H + + +enum mad_layer { + MAD_LAYER_I = 1, /* Layer I */ + MAD_LAYER_II = 2, /* Layer II */ + MAD_LAYER_III = 3 /* Layer III */ +}; + +enum mad_mode { + MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ + MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ + MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ + MAD_MODE_STEREO = 3 /* normal LR stereo */ +}; + +enum mad_emphasis { + MAD_EMPHASIS_NONE = 0, /* no emphasis */ + MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ + MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */ + MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */ +}; + +struct mad_header { + enum mad_layer layer; /* audio layer (1, 2, or 3) */ + enum mad_mode mode; /* channel mode (see above) */ + int mode_extension; /* additional mode info */ + enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ + + unsigned long bitrate; /* stream bitrate (bps) */ + unsigned int samplerate; /* sampling frequency (Hz) */ + + unsigned short crc_check; /* frame CRC accumulator */ + unsigned short crc_target; /* final target CRC checksum */ + + int flags; /* flags (see below) */ + int private_bits; /* private bits (see below) */ + + mad_timer_t duration; /* audio playing time of frame */ +}; + +struct mad_frame { + struct mad_header header; /* MPEG audio header */ + + int options; /* decoding options (from stream) */ + + mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */ + mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */ +}; + +# define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1) +# define MAD_NSBSAMPLES(header) \ + ((header)->layer == MAD_LAYER_I ? 12 : \ + (((header)->layer == MAD_LAYER_III && \ + ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36)) + +enum { + MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ + MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ + + MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ + MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ + MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ + MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ + + MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ + MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ + MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ + + MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ + MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ + MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ +}; + +enum { + MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ + MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ +}; + +void mad_header_init(struct mad_header *); + +# define mad_header_finish(header) /* nothing */ + +int mad_header_decode(struct mad_header *, struct mad_stream *); + +void mad_frame_init(struct mad_frame *); +void mad_frame_finish(struct mad_frame *); + +int mad_frame_decode(struct mad_frame *, struct mad_stream *); + +void mad_frame_mute(struct mad_frame *); + +# endif + +/* Id: synth.h,v 1.15 2004/01/23 09:41:33 rob Exp */ + +# ifndef LIBMAD_SYNTH_H +# define LIBMAD_SYNTH_H + + +struct mad_pcm { + unsigned int samplerate; /* sampling frequency (Hz) */ + unsigned short channels; /* number of channels */ + unsigned short length; /* number of samples per channel */ + mad_fixed_t samples[2][1152]; /* PCM output samples [ch][sample] */ +}; + +struct mad_synth { + mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ + /* [ch][eo][peo][s][v] */ + + unsigned int phase; /* current processing phase */ + + struct mad_pcm pcm; /* PCM output */ +}; + +/* single channel PCM selector */ +enum { + MAD_PCM_CHANNEL_SINGLE = 0 +}; + +/* dual channel PCM selector */ +enum { + MAD_PCM_CHANNEL_DUAL_1 = 0, + MAD_PCM_CHANNEL_DUAL_2 = 1 +}; + +/* stereo PCM selector */ +enum { + MAD_PCM_CHANNEL_STEREO_LEFT = 0, + MAD_PCM_CHANNEL_STEREO_RIGHT = 1 +}; + +void mad_synth_init(struct mad_synth *); + +# define mad_synth_finish(synth) /* nothing */ + +void mad_synth_mute(struct mad_synth *); + +void mad_synth_frame(struct mad_synth *, struct mad_frame const *); + +# endif + +/* Id: decoder.h,v 1.17 2004/01/23 09:41:32 rob Exp */ + +# ifndef LIBMAD_DECODER_H +# define LIBMAD_DECODER_H + + +enum mad_decoder_mode { + MAD_DECODER_MODE_SYNC = 0, + MAD_DECODER_MODE_ASYNC +}; + +enum mad_flow { + MAD_FLOW_CONTINUE = 0x0000, /* continue normally */ + MAD_FLOW_STOP = 0x0010, /* stop decoding normally */ + MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */ + MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */ +}; + +struct mad_decoder { + enum mad_decoder_mode mode; + + int options; + + struct { + long pid; + int in; + int out; + } async; + + struct { + struct mad_stream stream; + struct mad_frame frame; + struct mad_synth synth; + } *sync; + + void *cb_data; + + enum mad_flow (*input_func)(void *, struct mad_stream *); + enum mad_flow (*header_func)(void *, struct mad_header const *); + enum mad_flow (*filter_func)(void *, + struct mad_stream const *, struct mad_frame *); + enum mad_flow (*output_func)(void *, + struct mad_header const *, struct mad_pcm *); + enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); + enum mad_flow (*message_func)(void *, void *, unsigned int *); +}; + +void mad_decoder_init(struct mad_decoder *, void *, + enum mad_flow (*)(void *, struct mad_stream *), + enum mad_flow (*)(void *, struct mad_header const *), + enum mad_flow (*)(void *, + struct mad_stream const *, + struct mad_frame *), + enum mad_flow (*)(void *, + struct mad_header const *, + struct mad_pcm *), + enum mad_flow (*)(void *, + struct mad_stream *, + struct mad_frame *), + enum mad_flow (*)(void *, void *, unsigned int *)); +int mad_decoder_finish(struct mad_decoder *); + +# define mad_decoder_options(decoder, opts) \ + ((void) ((decoder)->options = (opts))) + +int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode); +int mad_decoder_message(struct mad_decoder *, void *, unsigned int *); + +# endif + +# ifdef __cplusplus +} +# endif diff --git a/r17/Revamped src/revamped_src/psp/madlibs/libmad.a b/r17/Revamped src/revamped_src/psp/madlibs/libmad.a new file mode 100755 index 00000000..56eddfe9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/madlibs/libmad.a differ diff --git a/r17/Revamped src/revamped_src/psp/main.cpp b/r17/Revamped src/revamped_src/psp/main.cpp new file mode 100755 index 00000000..3e4db617 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/main.cpp @@ -0,0 +1,383 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#define CONSOLE_DEBUG 0 + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +extern "C" +{ +#include "../quakedef.h" +#include "module.h" + +#ifdef SLIM_MODEL +int pspDveMgrSetVideoOut(int, int, int, int, int, int, int); +#endif +} + +#include "battery.hpp" +#include "system.hpp" + +// Running a dedicated server? +qboolean isDedicated = qfalse; + +extern int com_argc; +extern char **com_argv; + +void Sys_ReadCommandLineFile (char* netpath); + +namespace quake +{ + namespace main + { + // Clock speeds. + extern const int cpuClockSpeed = scePowerGetCpuClockFrequencyInt(); + extern const int ramClockSpeed = cpuClockSpeed; + extern const int busClockSpeed = scePowerGetBusClockFrequencyInt(); + +#ifdef PSP_SOFTWARE_VIDEO + // How big a heap to allocate. + #ifdef NORMAL_MODEL + static const size_t heapSize = 17 * 1024 * 1024; + #endif + #ifdef SLIM_MODEL + static const size_t heapSize = 16 * 1024 * 1024; + #endif +#else + // How big a heap to allocate. + #ifdef NORMAL_MODEL + static const size_t heapSize = 14 * 1024 * 1024; + #endif + #ifdef SLIM_MODEL + static const size_t heapSize = 40 * 1024 * 1024; + #endif +#endif + // Should the main loop stop running? + static volatile bool quit = false; + + // Is the PSP in suspend mode? + static volatile bool suspended = false; + + static int exitCallback(int arg1, int arg2, void* common) + { + // Signal the main thread to stop. + quit = true; + return 0; + } + + static int powerCallback(int unknown, int powerInfo, void* common) + { + if (powerInfo & PSP_POWER_CB_POWER_SWITCH || powerInfo & PSP_POWER_CB_SUSPENDING) + { + suspended = true; + } + else if (powerInfo & PSP_POWER_CB_RESUMING) + { + } + else if (powerInfo & PSP_POWER_CB_RESUME_COMPLETE) + { + suspended = false; + } + + return 0; + } + + static int callback_thread(SceSize args, void *argp) + { + // Register the exit callback. + const SceUID exitCallbackID = sceKernelCreateCallback("exitCallback", exitCallback, NULL); + sceKernelRegisterExitCallback(exitCallbackID); + + // Register the power callback. + const SceUID powerCallbackID = sceKernelCreateCallback("powerCallback", powerCallback, NULL); + scePowerRegisterCallback(0, powerCallbackID); + + // Sleep and handle callbacks. + sceKernelSleepThreadCB(); + return 0; + } + + static int setUpCallbackThread(void) + { + const int thid = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0); + if (thid >= 0) + sceKernelStartThread(thid, 0, 0); + return thid; + } + + + static void disableFloatingPointExceptions() + { +#ifndef _WIN32 + asm( + ".set push\n" + ".set noreorder\n" + "cfc1 $2, $31\n" // Get the FP Status Register. + "lui $8, 0x80\n" // (?) + "and $8, $2, $8\n" // Mask off all bits except for 23 of FCR. (? - where does the 0x80 come in?) + "ctc1 $8, $31\n" // Set the FP Status Register. + ".set pop\n" + : // No inputs. + : // No outputs. + : "$2", "$8" // Clobbered registers. + ); +#endif + } + } +} + +extern bool bmg_type_changed; + +using namespace quake; +using namespace quake::main; + +#define MAX_NUM_ARGVS 50 +#define MAX_ARG_LENGTH 64 +static char *empty_string = ""; +char *f_argv[MAX_NUM_ARGVS]; +int f_argc; + +int main(int argc, char *argv[]) +{ +/* +#ifdef SLIM_MODEL + + SceUID mod = pspSdkLoadStartModule("dvemgr.prx", PSP_MEMORY_PARTITION_KERNEL); + if (mod < 0) + Sys_Error ("Couldn't load dvemgr.prx, error %08X", mod); + +// vramExtender(); + pspDveMgrSetVideoOut(0, 0x1d2, 720, 480, 1, 15, 0); +#endif +*/ + // Set up the callback thread. + setUpCallbackThread(); + + // Disable floating point exceptions. + // If this isn't done, Quake crashes from (presumably) divide by zero + // operations. + disableFloatingPointExceptions(); + + // Allocate the heap. + std::vector heap(heapSize, 0); + + // Initialise the Common module. + + // Get the current working dir. + char currentDirectory[1024]; + char gameDirectory[1024]; + + memset(gameDirectory, 0, sizeof(gameDirectory)); + memset(currentDirectory, 0, sizeof(currentDirectory)); + getcwd(currentDirectory, sizeof(currentDirectory) - 1); + + char path_f[256]; + strcpy(path_f,currentDirectory); + strcat(path_f,"/quake.cmdline"); + Sys_ReadCommandLineFile(path_f); + + char *args[MAX_NUM_ARGVS]; + + for (int k =0; k < f_argc; k++) { + int len = strlen(f_argv[k]); + args[k] = new char[len+1]; + strcpy(args[k], f_argv[k]); + } + +#if CONSOLE_DEBUG + if (f_argc > 1) { + args[f_argc++] = "-condebug"; + COM_InitArgv(f_argc, args); + } + else { + args[0] = ""; + args[1] = "-condebug"; + COM_InitArgv(2, args); + } +#else + if (f_argc > 1) + COM_InitArgv(f_argc, args); + else { + args[0] = ""; + COM_InitArgv(0, NULL); + } +#endif + +#ifdef PSP_SOFTWARE_VIDEO + // Bump up the clock frequency. +// if (tcpipAvailable) +// scePowerSetClockFrequency(300, 300, 150); // Stop wifi problems +// else + scePowerSetClockFrequency(333, 333, 166); +#else + if (COM_CheckParm("-cpu333")) + { +// if (tcpipAvailable) +// scePowerSetClockFrequency(300, 300, 150); // Stop wifi problems +// else + scePowerSetClockFrequency(333, 333, 166); + } +#endif + + if (COM_CheckParm("-gamedir")) { + char* tempStr = com_argv[COM_CheckParm("-gamedir")+1]; + strncpy(gameDirectory, tempStr, sizeof(gameDirectory)-1); + } + else + { + strncpy(gameDirectory,currentDirectory,sizeof(gameDirectory)-1); + } + // Catch exceptions from here. + try + { + // Initialise the Host module. + quakeparms_t parms; + memset(&parms, 0, sizeof(parms)); + parms.argc = com_argc; + parms.argv = com_argv; + parms.basedir = gameDirectory; + parms.memsize = heap.size(); + parms.membase = &heap.at(0); + Host_Init(&parms); + + // Precalculate the tick rate. + const float oneOverTickRate = 1.0f / sceRtcGetTickResolution(); + + // Record the time that the main loop started. + u64 lastTicks; + sceRtcGetCurrentTick(&lastTicks); + + // Enter the main loop. + +#ifdef PSP_MP3HARDWARE_MP3LIB + extern int changeMp3Volume; + extern void CDAudio_VolumeChange(float bgmvolume); +#endif + while (!quit) + { + +#ifdef PSP_MP3HARDWARE_MP3LIB + if(changeMp3Volume) CDAudio_VolumeChange(bgmvolume.value); +#endif + + // Handle suspend & resume. + if (suspended) + { + // Suspend. + S_ClearBuffer(); + + quake::system::suspend(); + + // Wait for resume. + while (suspended && !quit) + { + sceDisplayWaitVblankStart(); + } + + // Resume. + quake::system::resume(); + + // Reset the clock. + sceRtcGetCurrentTick(&lastTicks); + } + + // What is the time now? + u64 ticks; + sceRtcGetCurrentTick(&ticks); + + // How much time has elapsed? + const unsigned int deltaTicks = ticks - lastTicks; + const float deltaSeconds = deltaTicks * oneOverTickRate; + + // Check the battery status. + battery::check(); + + // Run the frame. + Host_Frame(deltaSeconds); + + // Remember the time for next frame. + lastTicks = ticks; + } + } + catch (const std::exception& e) + { + // Report the error and quit. + Sys_Error("C++ Exception: %s", e.what()); + return 0; + } + + // Quit. + Sys_Quit(); + return 0; +} + +void Sys_ReadCommandLineFile (char* netpath) +{ + int in; + int remaining, count; + char buf[4096]; + int argc = 1; + + remaining = Sys_FileOpenRead (netpath, &in); + + if (in > 0 && remaining > 0) { + count = Sys_FileRead (in, buf, 4096); + f_argv[0] = empty_string; + + char* lpCmdLine = buf; + + while (*lpCmdLine && (argc < MAX_NUM_ARGVS)) + { + while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126))) + lpCmdLine++; + + if (*lpCmdLine) + { + f_argv[argc] = lpCmdLine; + argc++; + + while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126))) + lpCmdLine++; + + if (*lpCmdLine) + { + *lpCmdLine = 0; + lpCmdLine++; + } + } + } + f_argc = argc; + } else { + f_argc = 0; + } + + if (in > 0) + Sys_FileClose (in); +} diff --git a/r17/Revamped src/revamped_src/psp/makefile.svgalib b/r17/Revamped src/revamped_src/psp/makefile.svgalib new file mode 100755 index 00000000..562590e0 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/makefile.svgalib @@ -0,0 +1,109 @@ +OBJS= \ + cl_demo.o \ + cl_ents.o \ + cl_input.o \ + cl_main.o \ + cl_parse.o \ + cl_pred.o \ + cl_tent.o \ + cl_cam.o \ + cmd.o \ + common.o \ + console.o \ + crc.o \ + cvar.o \ + d_edge.o \ + d_fill.o \ + d_init.o \ + d_modech.o \ + d_part.o \ + d_polyse.o \ + d_scan.o \ + d_sky.o \ + d_sprite.o \ + d_surf.o \ + d_vars.o \ + d_zpoint.o \ + draw.o \ + keys.o \ + mathlib.o \ + md4.o \ + menu.o \ + model.o \ + net_chan.o \ + net_udp.o \ + nonintel.o \ + pmove.o \ + pmovetst.o \ + r_aclip.o \ + r_alias.o \ + r_bsp.o \ + r_draw.o \ + r_edge.o \ + r_efrag.o \ + r_light.o \ + r_main.o \ + r_misc.o \ + r_part.o \ + r_sky.o \ + r_sprite.o \ + r_surf.o \ + r_vars.o \ + sbar.o \ + screen.o \ + skin.o \ + snd_dma.o \ + snd_mem.o \ + snd_mix.o \ + view.o \ + wad.o \ + zone.o \ + cd_linux.o \ + sys_linux.o \ + vid_svgalib.o \ + snd_linux.o + +ASMOBJS= \ + d_copy.o \ + d_draw.o \ + d_draw16.o \ + d_parta.o \ + d_polysa.o \ + d_scana.o \ + d_spr8.o \ + d_varsa.o \ + math.o \ + r_aclipa.o \ + r_aliasa.o \ + r_drawa.o \ + r_edgea.o \ + r_varsa.o \ + snd_mixa.o \ + surf16.o \ + surf8.o \ + sys_dosa.o + +#CFLAGS=-O3 -Wall -fomit-frame-pointer -fno-strength-reduce -funroll-loops +#CFLAGS=-mpentium -O3 -Wall -fomit-frame-pointer -fno-strength-reduce +CFLAGS=-V2.7.2.1 -bi486-linux/ -O6 -Wall -fomit-frame-pointer -fno-strength-reduce +#CFLAGS=-V2.7.2.1 -bi486-linux/ -O2 -g -Wall + +LDFLAGS = + +LIBS = -lm -lvga +TARGET = qwcl + +%.o : %.s + $(CC) $(CFLAGS) -DELF -x assembler-with-cpp -c $< + +#$(TARGET) : $(OBJS) +# $(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS) + +$(TARGET) : $(ASMOBJS) $(OBJS) + $(CC) $(LDFLAGS) -o $(TARGET) $(ASMOBJS) $(OBJS) $(LIBS) + +clean: + -rm $(OBJS) + +clobber: clean + -rm $(TARGET) diff --git a/r17/Revamped src/revamped_src/psp/math.cpp b/r17/Revamped src/revamped_src/psp/math.cpp new file mode 100755 index 00000000..29146c95 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/math.cpp @@ -0,0 +1,50 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#include "math.hpp" + +namespace quake +{ + namespace math + { + void multiply(const ScePspFMatrix4& a, const ScePspFMatrix4& b, ScePspFMatrix4* out) + { + out->x.x = a.x.x * b.x.x + a.x.y * b.y.x + a.x.z * b.z.x + a.x.w * b.w.x; + out->x.y = a.x.x * b.x.y + a.x.y * b.y.y + a.x.z * b.z.y + a.x.w * b.w.y; + out->x.z = a.x.x * b.x.z + a.x.y * b.y.z + a.x.z * b.z.z + a.x.w * b.w.z; + out->x.w = a.x.x * b.x.w + a.x.y * b.y.w + a.x.z * b.z.w + a.x.w * b.w.w; + + out->y.x = a.y.x * b.x.x + a.y.y * b.y.x + a.y.z * b.z.x + a.y.w * b.w.x; + out->y.y = a.y.x * b.x.y + a.y.y * b.y.y + a.y.z * b.z.y + a.y.w * b.w.y; + out->y.z = a.y.x * b.x.z + a.y.y * b.y.z + a.y.z * b.z.z + a.y.w * b.w.z; + out->y.w = a.y.x * b.x.w + a.y.y * b.y.w + a.y.z * b.z.w + a.y.w * b.w.w; + + out->z.x = a.z.x * b.x.x + a.z.y * b.y.x + a.z.z * b.z.x + a.z.w * b.w.x; + out->z.y = a.z.x * b.x.y + a.z.y * b.y.y + a.z.z * b.z.y + a.z.w * b.w.y; + out->z.z = a.z.x * b.x.z + a.z.y * b.y.z + a.z.z * b.z.z + a.z.w * b.w.z; + out->z.w = a.z.x * b.x.w + a.z.y * b.y.w + a.z.z * b.z.w + a.z.w * b.w.w; + + out->w.x = a.w.x * b.x.x + a.w.y * b.y.x + a.w.z * b.z.x + a.w.w * b.w.x; + out->w.y = a.w.x * b.x.y + a.w.y * b.y.y + a.w.z * b.z.y + a.w.w * b.w.y; + out->w.z = a.w.x * b.x.z + a.w.y * b.y.z + a.w.z * b.z.z + a.w.w * b.w.z; + out->w.w = a.w.x * b.x.w + a.w.y * b.y.w + a.w.z * b.z.w + a.w.w * b.w.w; + } + } +} diff --git a/r17/Revamped src/revamped_src/psp/math.hpp b/r17/Revamped src/revamped_src/psp/math.hpp new file mode 100755 index 00000000..7f7bfd11 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/math.hpp @@ -0,0 +1,49 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#ifndef QUAKE_MATH_HPP +#define QUAKE_MATH_HPP + +#include +#include + +namespace quake +{ + namespace math + { + static inline float dot(const ScePspFVector4& a, const ScePspFVector4& b) + { + return (a.x * b.x) + (a.y * b.y) + (a.z * b.z); + } + + static inline void normalise(ScePspFVector4* v) + { + const float scale = 1.0f / sqrtf(dot(*v, *v)); + v->x *= scale; + v->y *= scale; + v->z *= scale; + v->w *= scale; + } + + void multiply(const ScePspFMatrix4& a, const ScePspFMatrix4& b, ScePspFMatrix4* out); + } +} + +#endif diff --git a/r17/Revamped src/revamped_src/psp/mcount.S b/r17/Revamped src/revamped_src/psp/mcount.S new file mode 100755 index 00000000..9533cc15 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/mcount.S @@ -0,0 +1,60 @@ +.globl _mcount +.ent _mcount + +_mcount: + +.set noreorder +.set noat + + # generated code already substracts 8 bytes + # we store our ra, at and a0-a3 + addu $29, $29, -40 + sd $31, 0($29) # store ra + sd $1, 8($29) # at = ra of caller + sd $4, 16($29) + sd $5, 24($29) + sd $6, 32($29) + sd $7, 40($29) + + # make sure we're not recursively called when compiling __mcount() + # with -pg + la $4, _busy + lw $5, 0($4) + bnez $5, done + nop + + # mark busy + li $5, 1 + sw $5, 0($4) + + # call internal C handler + move $4, $1 + move $5, $31 + jal __mcount + nop + + # unmark busy + la $4, _busy + li $5, 0 + sw $5, 0($4) + + done: + + # restore registers + ld $31, 0($29) + ld $1, 8($29) + ld $4, 16($29) + ld $5, 24($29) + ld $6, 32($29) + ld $7, 40($29) + addu $29, $29, 48 # generated code substracts 8 bytes + j $31 + move $31, $1 # restore caller's ra + +_busy: + .space 4 + +.set reorder +.set at + .end _mcount + diff --git a/r17/Revamped src/revamped_src/psp/module.cpp b/r17/Revamped src/revamped_src/psp/module.cpp new file mode 100755 index 00000000..eb928e15 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/module.cpp @@ -0,0 +1,28 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#include +#include +#include "module.h" + +// Set up the module info. +PSP_MODULE_INFO("Kurok", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_VFPU); +PSP_HEAP_SIZE_KB(PSP_HEAP_SIZE_MB * 1024); diff --git a/r17/Revamped src/revamped_src/psp/module.h b/r17/Revamped src/revamped_src/psp/module.h new file mode 100755 index 00000000..85bb5114 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/module.h @@ -0,0 +1,6 @@ +#ifdef NORMAL_MODEL +#define PSP_HEAP_SIZE_MB 18 +#endif +#ifdef SLIM_MODEL +#define PSP_HEAP_SIZE_MB 46 +#endif diff --git a/r17/Revamped src/revamped_src/psp/mp3.c b/r17/Revamped src/revamped_src/psp/mp3.c new file mode 100755 index 00000000..a57feeb2 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/mp3.c @@ -0,0 +1,435 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic PRX template + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: main.c 1888 2006-05-01 08:47:04Z tyranid $ + * $HeadURL$ + */ +#include +#include +#include +#include +#include +#include +#include "m33libs/include/kubridge.h" + +#include "../quakedef.h" + +int mp3_last_error = 0; + +static int initialized = 0; +static SceUID thread_job_sem = -1; +static SceUID thread_busy_sem = -1; +static int thread_exit = 0; + +int done = 0; + +int mp3_job_started = 0; + +int mp3_volume; + +static int mp3_src_pos = 0; + +int first_run = 0; + +// MPEG-1, layer 3 +static int bitrates[] = { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 }; +//static int samplerates[] = { 44100, 48000, 32000, 0 }; + +#define MIN_INFRAME_SIZE 96 +#define IN_BUFFER_SIZE (2*1024) + +static unsigned long mp3_codec_struct[65];// __attribute__((aligned(64))); + +static unsigned char mp3_src_buffer[2][IN_BUFFER_SIZE];// __attribute__((aligned(64))); +static short mp3_mix_buffer[2][1152*2];// __attribute__((aligned(64))); +static int working_buf = 0; + +static const char *mp3_fname = NULL; +static SceUID mp3_handle = -1; +static int mp3_src_size = 0; + +static int decode_thread(SceSize args, void *argp); + + +static void psp_sem_lock(SceUID sem) +{ + int ret = sceKernelWaitSema(sem, 1, 0); + if (ret < 0) printf("sceKernelWaitSema(%08x) failed with %08x\n", sem, ret); +} + +static void psp_sem_unlock(SceUID sem) +{ + int ret = sceKernelSignalSema(sem, 1); + if (ret < 0) printf("sceKernelSignalSema(%08x) failed with %08x\n", sem, ret); +} + +// only accepts MPEG-1, layer3 +static int find_sync_word(unsigned char *data, int len) +{ + int i; + for (i = 0; i < len-1; i++) + { + if ( data[i+0] != 0xff) continue; + if ((data[i+1] & 0xfe) == 0xfa) return i; + i++; + } + return -1; +} + +static int read_next_frame(int which_buffer) +{ + int i, bytes_read, frame_offset; + int bitrate, padding, frame_size = 0; + + for (i = 0; i < 32; i++) + { + bytes_read = sceIoRead(mp3_handle, mp3_src_buffer[which_buffer], sizeof(mp3_src_buffer[which_buffer])); + mp3_src_pos += bytes_read; + if (bytes_read < MIN_INFRAME_SIZE) { + mp3_src_pos = mp3_src_size; + if (developer.value) + Con_SafePrintf ("EOF hit\n"); + else + Con_SafePrintf (""); + // CDAudio_Play ((byte)cl.cdtrack, true); + if (developer.value) + Con_SafePrintf ("Repeating track ...\n"); + Cbuf_AddText(va("cd play %i\n", cl.cdtrack)); + return 0; // EOF/IO failure + } + frame_offset = find_sync_word(mp3_src_buffer[which_buffer], bytes_read); + if (frame_offset < 0) { + printf("missing syncword, foffs=%i\n", mp3_src_pos - bytes_read); + mp3_src_pos--; + sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET); + continue; + } + if (bytes_read - frame_offset < 4) { + printf("syncword @ EOB, foffs=%i\n", mp3_src_pos - bytes_read); + mp3_src_pos--; + sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET); + continue; + } + + bitrate = mp3_src_buffer[which_buffer][frame_offset+2] >> 4; + padding = (mp3_src_buffer[which_buffer][frame_offset+2] & 2) >> 1; + + frame_size = 144000*bitrates[bitrate]/44100 + padding; + if (frame_size <= 0) { + printf("bad frame, foffs=%i\n", mp3_src_pos - bytes_read); + continue; // bad frame + } + + if (bytes_read - frame_offset < frame_size) + { + printf("unfit, foffs=%i\n", mp3_src_pos - bytes_read); + mp3_src_pos -= bytes_read - frame_offset; + if (mp3_src_size - mp3_src_pos < frame_size) { + mp3_src_pos = mp3_src_size; + return 0; // EOF + } + sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET); + continue; // didn't fit, re-read.. + } + + if (frame_offset) { + //printf("unaligned, foffs=%i, offs=%i\n", mp3_src_pos - bytes_read, frame_offset); + memmove(mp3_src_buffer[which_buffer], mp3_src_buffer[which_buffer] + frame_offset, frame_size); + } + + // align for next frame read + mp3_src_pos -= bytes_read - (frame_offset + frame_size); + sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET); + + break; + } + + return frame_size > 0 ? frame_size : -1; +} + + +static SceUID load_start_module(const char *prxname) +{ + SceUID mod, mod1; + int status, ret; + + mod = pspSdkLoadStartModule(prxname, PSP_MEMORY_PARTITION_KERNEL); + if (mod < 0) { + printf("failed to load %s (%08x), trying kuKernelLoadModule\n", prxname, mod); + mod1 = kuKernelLoadModule(prxname, 0, NULL); + if (mod1 < 0) printf("kuKernelLoadModule failed with %08x\n", mod1); + else { + ret = sceKernelStartModule(mod1, 0, NULL, &status, 0); + if (ret < 0) printf("sceKernelStartModule failed with %08x\n", ret); + else mod = mod1; + } + } + return mod; +} + + +int mp3_init(void) +{ + SceUID thid, mod; + int ret; + + /* load modules */ + /* <= 1.5 (and probably some other, not sure which) fw need this to for audiocodec to work, + * so if it fails, assume we are just on new enough firmware and continue.. */ + load_start_module("flash0:/kd/me_for_vsh.prx"); + + if (sceKernelDevkitVersion() < 0x02070010) + mod = load_start_module("flash0:/kd/audiocodec.prx"); + else mod = load_start_module("flash0:/kd/avcodec.prx"); + if (mod < 0) { + ret = mod = load_start_module("flash0:/kd/audiocodec_260.prx"); // last chance.. + if (mod < 0) goto fail; + } + + /* audiocodec init */ + memset(mp3_codec_struct, 0, sizeof(mp3_codec_struct)); + ret = sceAudiocodecCheckNeedMem(mp3_codec_struct, 0x1002); + if (ret < 0) { + printf("sceAudiocodecCheckNeedMem failed with %08x\n", ret); + + goto fail; + } + + ret = sceAudiocodecGetEDRAM(mp3_codec_struct, 0x1002); + if (ret < 0) { + printf("sceAudiocodecGetEDRAM failed with %08x\n", ret); + goto fail; + } + + ret = sceAudiocodecInit(mp3_codec_struct, 0x1002); + if (ret < 0) { + printf("sceAudiocodecInit failed with %08x\n", ret); + goto fail1; + } + + /* thread and stuff */ + thread_job_sem = sceKernelCreateSema("p_mp3job_sem", 0, 0, 1, NULL); + if (thread_job_sem < 0) { + printf("sceKernelCreateSema() failed: %08x\n", thread_job_sem); + ret = thread_job_sem; + goto fail1; + } + + thread_busy_sem = sceKernelCreateSema("p_mp3busy_sem", 0, 1, 1, NULL); + if (thread_busy_sem < 0) { + printf("sceKernelCreateSema() failed: %08x\n", thread_busy_sem); + ret = thread_busy_sem; + goto fail2; + } + + thread_exit = 0; + thid = sceKernelCreateThread("mp3decode_thread", decode_thread, 30, 0x2000, 0, 0); /* use slightly higher prio then main */ + if (thid < 0) { + printf("failed to create decode thread: %08x\n", thid); + ret = thid; + goto fail3; + } + ret = sceKernelStartThread(thid, 0, 0); + if (ret < 0) { + printf("failed to start decode thread: %08x\n", ret); + goto fail3; + } + + mp3_last_error = 0; + initialized = 1; + return 0; + +fail3: + sceKernelDeleteSema(thread_busy_sem); + thread_busy_sem = -1; +fail2: + sceKernelDeleteSema(thread_job_sem); + thread_job_sem = -1; +fail1: + sceAudiocodecReleaseEDRAM(mp3_codec_struct); +fail: + mp3_last_error = ret; + initialized = 0; + return 1; +} + +void mp3_deinit(void) +{ + printf("mp3_deinit, initialized=%i\n", initialized); + + if (!initialized) return; + thread_exit = 1; + psp_sem_lock(thread_busy_sem); + psp_sem_unlock(thread_busy_sem); + + sceKernelSignalSema(thread_job_sem, 1); + sceKernelDelayThread(100*1000); + + if (mp3_handle >= 0) sceIoClose(mp3_handle); + mp3_handle = -1; + mp3_fname = NULL; + + psp_sem_lock(thread_job_sem); + psp_sem_unlock(thread_job_sem); + + sceKernelDeleteSema(thread_busy_sem); + thread_busy_sem = -1; + sceKernelDeleteSema(thread_job_sem); + thread_job_sem = -1; + sceAudiocodecReleaseEDRAM(mp3_codec_struct); + initialized = 0; + +} + + +short mp3_output_buffer[4][1152 * 2] __attribute__((aligned(64))); +int mp3_output_index = 0; + +// may overflow stack? +static int decode_thread(SceSize args, void *argp) +{ + int ret, frame_size=0; + + int audio_channel = sceAudioChReserve(1, 1152, PSP_AUDIO_FORMAT_STEREO); + + printf("decode_thread started with id %08x, priority %i\n", + sceKernelGetThreadId(), sceKernelGetThreadCurrentPriority()); + + while (!thread_exit) + { + psp_sem_lock(thread_job_sem); + + if (thread_exit) { + psp_sem_unlock(thread_job_sem); + break; + } + + psp_sem_lock(thread_busy_sem); + + frame_size = read_next_frame(working_buf); + + if (frame_size == 0) + if (developer.value) + Con_SafePrintf("after psp_sem_lock we have frame_size = 0\n"); + else + Con_SafePrintf (""); + + while (mp3_job_started) + { + + if (frame_size == 0) + if (developer.value) + Con_SafePrintf("after frame_size we entered mp3_job_started = 0\n"); + else + Con_SafePrintf (""); + + if (thread_exit) break; + + if(frame_size > 0) + { + mp3_codec_struct[6] = (unsigned long)mp3_src_buffer[working_buf]; + mp3_codec_struct[8] = (unsigned long)mp3_mix_buffer[working_buf]; + mp3_codec_struct[7] = mp3_codec_struct[10] = frame_size; + mp3_codec_struct[9] = 1152 * 4; + + ret = sceAudiocodecDecode(mp3_codec_struct, 0x1002); + if (ret < 0) printf("sceAudiocodecDecode failed with %08x\n", ret); + + memcpy(mp3_output_buffer[mp3_output_index], mp3_mix_buffer[working_buf], 1152*4); + sceAudioOutputBlocking(audio_channel, mp3_volume, mp3_output_buffer[mp3_output_index]); + mp3_output_index = (mp3_output_index+1)%4; + + memset(mp3_mix_buffer, 0, 1152*2*2); + + frame_size = read_next_frame(working_buf); + + if (frame_size == 0) + if (developer.value) + Con_SafePrintf("encountered frame_size = 0 in loop\n"); + else + Con_SafePrintf (""); + } + + + } + + if (!mp3_job_started) { + + if (frame_size == 0) + if (developer.value) + Con_SafePrintf("closing handle\n"); + else + Con_SafePrintf(""); + + if (mp3_handle >= 0) sceIoClose(mp3_handle); + mp3_handle = -1; + mp3_fname = NULL; + } + + if (frame_size == 0) + Con_SafePrintf(""); + psp_sem_unlock(thread_busy_sem); + + + } + + if (frame_size == 0) + Con_SafePrintf(""); + + printf("leaving decode thread\n"); + sceKernelExitDeleteThread(0); + + if (frame_size == 0) + Con_SafePrintf(""); + + return 0; +} + +static int mp3_samples_ready = 0, mp3_buffer_offs = 0, mp3_play_bufsel = 0; + +int mp3_start_play(char *fname, int pos) +{ + + printf("mp3_start_play(%s) @ %i\n", fname, pos); + psp_sem_lock(thread_busy_sem); + + if (mp3_fname != fname || mp3_handle < 0) + { + if (mp3_handle >= 0) sceIoClose(mp3_handle); + mp3_handle = sceIoOpen(fname, PSP_O_RDONLY, 0777); + if (mp3_handle < 0) { + printf("sceIoOpen(%s) failed\n", fname); + psp_sem_unlock(thread_busy_sem); + sceIoClose(mp3_handle); + return 2; + } + mp3_src_size = sceIoLseek32(mp3_handle, 0, PSP_SEEK_END); + mp3_fname = fname; + } + + // seek.. + mp3_src_pos = (int) (((float)pos / 1023.0f) * (float)mp3_src_size); + sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET); + printf("seek %i: %i/%i\n", pos, mp3_src_pos, mp3_src_size); + + mp3_job_started = 1; + mp3_samples_ready = mp3_buffer_offs = mp3_play_bufsel = 0; + working_buf = 0; + + /* send a request to decode first frame */ + psp_sem_unlock(thread_busy_sem); + psp_sem_unlock(thread_job_sem); + sceKernelDelayThread(1); // reschedule + + return 0; +} + + diff --git a/r17/Revamped src/revamped_src/psp/mp3.h b/r17/Revamped src/revamped_src/psp/mp3.h new file mode 100755 index 00000000..9b196db3 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/mp3.h @@ -0,0 +1,10 @@ +// additional stuff for PSP mp3 decoder implementation + +extern "C" int mp3_init(void); +extern "C" void mp3_deinit(void); +extern "C" int mp3_start_play(char *fname, int pos); + +extern "C" int mp3_job_started; + +int mp3_volume; +int changeMp3Volume; diff --git a/r17/Revamped src/revamped_src/psp/network.cpp b/r17/Revamped src/revamped_src/psp/network.cpp new file mode 100755 index 00000000..2705bceb --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/network.cpp @@ -0,0 +1,122 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#include "network_psp.hpp" + +extern "C" +{ +#include "../net_dgrm.h" +#include "../net_loop.h" +} + +net_driver_t net_drivers[MAX_NET_DRIVERS] = +{ + { + "Loopback", + qfalse, + Loop_Init, + Loop_Listen, + Loop_SearchForHosts, + Loop_Connect, + Loop_CheckNewConnections, + Loop_GetMessage, + Loop_SendMessage, + Loop_SendUnreliableMessage, + Loop_CanSendMessage, + Loop_CanSendUnreliableMessage, + Loop_Close, + Loop_Shutdown + } + , + { + "Datagram", + qfalse, + Datagram_Init, + Datagram_Listen, + Datagram_SearchForHosts, + Datagram_Connect, + Datagram_CheckNewConnections, + Datagram_GetMessage, + Datagram_SendMessage, + Datagram_SendUnreliableMessage, + Datagram_CanSendMessage, + Datagram_CanSendUnreliableMessage, + Datagram_Close, + Datagram_Shutdown + } +}; + +int net_numdrivers = 2; + +using namespace quake; +using namespace quake::network; + +net_landriver_t net_landrivers[MAX_NET_DRIVERS] = +{ + { + "Infrastructure", + qfalse, + 0, + infrastructure::init, + infrastructure::shut_down, + infrastructure::listen, + infrastructure::open_socket, + infrastructure::close_socket, + infrastructure::connect, + infrastructure::check_new_connections, + infrastructure::read, + infrastructure::write, + infrastructure::broadcast, + infrastructure::addr_to_string, + infrastructure::string_to_addr, + infrastructure::get_socket_addr, + infrastructure::get_name_from_addr, + infrastructure::get_addr_from_name, + infrastructure::addr_compare, + infrastructure::get_socket_port, + infrastructure::set_socket_port + }, + { + "Adhoc", + qfalse, + 0, + adhoc::init, + adhoc::shut_down, + adhoc::listen, + adhoc::open_socket, + adhoc::close_socket, + adhoc::connect, + adhoc::check_new_connections, + adhoc::read, + adhoc::write, + adhoc::broadcast, + adhoc::addr_to_string, + adhoc::string_to_addr, + adhoc::get_socket_addr, + adhoc::get_name_from_addr, + adhoc::get_addr_from_name, + adhoc::addr_compare, + adhoc::get_socket_port, + adhoc::set_socket_port + } +}; + +int net_numlandrivers = 2; diff --git a/r17/Revamped src/revamped_src/psp/network_psp.cpp b/r17/Revamped src/revamped_src/psp/network_psp.cpp new file mode 100755 index 00000000..3ae1e330 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/network_psp.cpp @@ -0,0 +1,932 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +//#include +#include +#include +#include +#include +#include +#include +#include + +#include "network_psp.hpp" + +#include // inet_addr +#include // sockaddr_in +#include // PSP socket API. +#include +#include +#include +#include + +#include + +#include + +#define ADHOC_NET 29 +#define ADHOC_EWOULDBLOCK 0x80410709 + +#define MAXHOSTNAMELEN 64 +#define EWOULDBLOCK 111 +#define ECONNREFUSED 11 + +int totalAccessPoints = 0; +cvar_t accesspoint = {"accesspoint", "1", qtrue}; +int accessPointNumber[100]; + + +typedef struct sockaddr_adhoc +{ + char len; + short family; + u16 port; + char mac[6]; + char zero[6]; +} sockaddr_adhoc; + +#ifdef PROFILE +#define sceUtilityLoadNetModule +#define sceUtilityUnLoadNetModule +#endif + +static pdpStatStruct gPdpStat; +pdpStatStruct *findPdpStat(int socket, pdpStatStruct *pdpStat) +{ + if(socket == pdpStat->pdpId) { + memcpy(&gPdpStat, pdpStat, sizeof(pdpStatStruct)); + return &gPdpStat; + } + if(pdpStat->next) return findPdpStat(socket, pdpStat->next); + return (pdpStatStruct *)-1; +} + + +namespace quake +{ + namespace network + { + namespace infrastructure + { + static int accept_socket = -1; // socket for fielding new connections + static int control_socket = -1; + static int broadcast_socket = 0; + static struct qsockaddr broadcast_addr; + static int my_addr = 0; + + int init (void) + { + if(totalAccessPoints == 0) + { + int iNetIndex; + memset(accessPointNumber, 0, sizeof(accessPointNumber)); + for (iNetIndex = 1; iNetIndex < 100; iNetIndex++) // skip the 0th connection + { + if (sceUtilityCheckNetParam(iNetIndex) == 0) + { + totalAccessPoints++; + accessPointNumber[totalAccessPoints] = iNetIndex; + } + } + if(accesspoint.value > totalAccessPoints) + Cvar_SetValue("accesspoint", 1); + } + + if(!host_initialized) + { + Cvar_RegisterVariable(&accesspoint); + } + + if(!tcpipAvailable) + return -1; + + char szMyIPAddr[32]; + struct qsockaddr addr; + char *colon; + + char buff[MAXHOSTNAMELEN]; + + S_ClearBuffer (); // so dma doesn't loop current sound + + // Load the network modules when they are required + sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON); + sceUtilityLoadNetModule(PSP_NET_MODULE_INET); + + // Initialise the network. + const int err = pspSdkInetInit(); + if (err) + { + Con_Printf("Couldn't initialise the network %08X\n", err); + sceUtilityUnloadNetModule(PSP_NET_MODULE_INET); + sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON); + return -1; + } + + if(!connect_to_apctl(accessPointNumber[(int)accesspoint.value])) + { + Con_Printf("Unable to connect to access point\n"); + pspSdkInetTerm(); + sceUtilityUnloadNetModule(PSP_NET_MODULE_INET); + sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON); + + return -1; + } + + // connected, get my IPADDR and run test + if (sceNetApctlGetInfo(8, (union SceNetApctlInfo*)szMyIPAddr) != 0) + + // determine my name & address + gethostname(buff, MAXHOSTNAMELEN); + + my_addr = inet_addr(szMyIPAddr); + + // if the quake hostname isn't set, set it to the machine name + if (Q_strcmp(hostname.string, "UNNAMED") == 0) + { + buff[15] = 0; + Cvar_Set ("hostname", buff); + } + + if ((control_socket = open_socket(0)) == -1) + { + pspSdkInetTerm(); + sceUtilityUnloadNetModule(PSP_NET_MODULE_INET); + sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON); + Sys_Error("init: Unable to open control socket\n"); + } + + ((struct sockaddr_in *)&broadcast_addr)->sin_family = AF_INET; + ((struct sockaddr_in *)&broadcast_addr)->sin_addr.s_addr = INADDR_BROADCAST; + ((struct sockaddr_in *)&broadcast_addr)->sin_port = htons(net_hostport); + + get_socket_addr (control_socket, &addr); + Q_strcpy(my_tcpip_address, addr_to_string(&addr)); + colon = Q_strrchr (my_tcpip_address, ':'); + if (colon) + *colon = 0; + + Con_Printf("UDP Initialized\n"); + tcpipAvailable = qtrue; + + return control_socket; + } + + //============================================================================= + + void shut_down (void) + { + listen(qfalse); + close_socket(control_socket); + + pspSdkInetTerm(); + + // Now to unload the network modules, no need to keep them loaded all the time + sceUtilityUnloadNetModule(PSP_NET_MODULE_INET); + sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON); + } + + //============================================================================= + + void listen (qboolean state) + { + // enable listening + if (state) + { + if (accept_socket != -1) + return; + if ((accept_socket = open_socket(net_hostport)) == -1) + Sys_Error ("listen: Unable to open accept socket\n"); + return; + } + + // disable listening + if (accept_socket == -1) + return; + close_socket(accept_socket); + + accept_socket = -1; + } + + //============================================================================= + + int open_socket (int port) + { + int newsocket; + struct sockaddr_in address; + + if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + return -1; + + int val = 1; + if(setsockopt(newsocket, SOL_SOCKET, SO_NONBLOCK, &val, sizeof(val)) < 0) + goto ErrorReturn; + + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(port); + if( bind (newsocket, (sockaddr *)&address, sizeof(address)) == -1) + goto ErrorReturn; + + printf("got here4\n"); + return newsocket; + + ErrorReturn: + close(newsocket); + return -1; + } + + //============================================================================= + + int close_socket (int socket) + { + if (socket == broadcast_socket) + broadcast_socket = 0; + return close(socket); + } + + int connect (int socket, struct qsockaddr *addr) + { + return 0; + } + + //============================================================================= + + int check_new_connections (void) + { + byte buf[1000]; + + if (accept_socket == -1) + return -1; + + // Peek at the message and if there is a message waiting then return the + // socket + int ret = recvfrom(accept_socket, buf, 1000, MSG_PEEK, NULL, NULL); + + if(ret > 0) + return accept_socket; + + return -1; + } + + //============================================================================= + + int read (int socket, byte *buf, int len, struct qsockaddr *addr) + { + int addrlen = sizeof (struct qsockaddr); + int ret; + + ret = recvfrom (socket, buf, len, 0, (struct sockaddr *)addr, (socklen_t*)&addrlen); + if (ret == -1) + { + int errno = sceNetInetGetErrno(); + if(errno == EWOULDBLOCK || errno == ECONNREFUSED) + { + return 0; + } + } + + return ret; + } + + //============================================================================= + + static int make_socket_broadcast_capable (int socket) + { + int i = 1; + + // make this socket broadcast capable + if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &i, sizeof(i)) < 0) + return -1; + broadcast_socket = socket; + + return 0; + } + + //============================================================================= + + int broadcast (int socket, byte *buf, int len) + { + int ret; + + if (socket != broadcast_socket) + { + if (broadcast_socket != 0) + Sys_Error("Attempted to use multiple broadcasts sockets\n"); + ret = make_socket_broadcast_capable (socket); + if (ret == -1) + { + Con_Printf("Unable to make socket broadcast capable\n"); + return ret; + } + } + + return write(socket, buf, len, &broadcast_addr); + } + + //============================================================================= + + int write (int socket, byte *buf, int len, struct qsockaddr *addr) + { + int ret; + + ret = sendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr)); + if (ret == -1) + { + int errno = sceNetInetGetErrno(); + if(errno == EWOULDBLOCK || errno == ECONNREFUSED) + { + return 0; + } + Con_Printf("Failed to send message, errno=%08X\n", errno); + } + return ret; + } + + //============================================================================= + + char* addr_to_string (struct qsockaddr *addr) + { + static char buffer[22]; + int haddr; + + haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr); + sprintf(buffer, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, ntohs(((struct sockaddr_in *)addr)->sin_port)); + return buffer; + } + + //============================================================================= + + int string_to_addr (char *string, struct qsockaddr *addr) + { + int ha1, ha2, ha3, ha4, hp; + int ipaddr; + + sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp); + ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4; + + addr->sa_family = AF_INET; + ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr); + ((struct sockaddr_in *)addr)->sin_port = htons(hp); + return 0; + } + + //============================================================================= + + int get_socket_addr (int socket, struct qsockaddr *addr) + { + socklen_t addrlen = sizeof(struct qsockaddr); + unsigned int a; + + Q_memset(addr, 0, sizeof(struct qsockaddr)); + getsockname(socket, (struct sockaddr *)addr, &addrlen); + a = ((struct sockaddr_in *)addr)->sin_addr.s_addr; + if (a == 0 || a == inet_addr("127.0.0.1")) + ((struct sockaddr_in *)addr)->sin_addr.s_addr = my_addr; + + return 0; + } + + //============================================================================= + + int get_name_from_addr (struct qsockaddr *addr, char *name) + { + struct hostent *hostentry; + + hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET); + if (hostentry) + { + Q_strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1); + return 0; + } + + Q_strcpy (name, addr_to_string (addr)); + return 0; + } + + //============================================================================= + + int get_addr_from_name(char *name, struct qsockaddr *addr) + { + struct hostent *hostentry; + + if (name[0] >= '0' && name[0] <= '9') + return PartialIPAddress (name, addr); + + hostentry = gethostbyname (name); + if (!hostentry) + return -1; + + addr->sa_family = AF_INET; + ((struct sockaddr_in *)addr)->sin_port = htons(net_hostport); + ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; + + return 0; + } + + //============================================================================= + + int addr_compare (struct qsockaddr *addr1, struct qsockaddr *addr2) + { + if (addr1->sa_family != addr2->sa_family) + return -1; + + if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr) + return -1; + + if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port) + return 1; + + return 0; + } + + //============================================================================= + + int get_socket_port (struct qsockaddr *addr) + { + return ntohs(((struct sockaddr_in *)addr)->sin_port); + } + + + int set_socket_port (struct qsockaddr *addr, int port) + { + ((struct sockaddr_in *)addr)->sin_port = htons(port); + return 0; + } + + /* + ============ + PartialIPAddress + + this lets you type only as much of the net address as required, using + the local network components to fill in the rest + ============ + */ + int PartialIPAddress (char *in, struct qsockaddr *hostaddr) + { + char buff[256]; + char *b; + int addr; + int num; + int mask; + int run; + int port; + + buff[0] = '.'; + b = buff; + strcpy(buff+1, in); + if (buff[1] == '.') + b++; + + addr = 0; + mask=-1; + while (*b == '.') + { + b++; + num = 0; + run = 0; + while (!( *b < '0' || *b > '9')) + { + num = num*10 + *b++ - '0'; + if (++run > 3) + return -1; + } + if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0) + return -1; + if (num < 0 || num > 255) + return -1; + mask<<=8; + addr = (addr<<8) + num; + } + + if (*b++ == ':') + port = Q_atoi(b); + else + port = net_hostport; + + hostaddr->sa_family = AF_INET; + ((struct sockaddr_in *)hostaddr)->sin_port = htons((short)port); + ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (my_addr & htonl(mask)) | htonl(addr); + + return 0; + } + //============================================================================= + /* Connect to an access point */ + int connect_to_apctl(int config) + { + int err; + int stateLast = -1; + int timeout = 0; + + /* Connect using the first profile */ + err = sceNetApctlConnect(config); + if (err != 0) + { + return 0; + } + + while (1) + { + int state; + err = sceNetApctlGetState(&state); + if (err != 0) + { + break; + } + if (state > stateLast) + { + stateLast = state; + timeout = 0; + } + if (state == 4) + break; // connected with static IP + + // wait a little before polling again + sceKernelDelayThread(50*1000); // 50ms + + timeout++; + if(timeout > 200) + { + Con_Printf("Timeout connecting to access point. State=%d\n", state); + return 0; + } + } + + if(err != 0) + { + return 0; + } + + return 1; + } + //============================================================================= + } + namespace adhoc + { + static int accept_socket = -1; // socket for fielding new connections + static int control_socket = -1; + static int broadcast_socket = 0; + static struct qsockaddr broadcast_addr; + static int my_addr = 0; + + int init (void) + { + if(!tcpipAvailable) return -1; + + struct qsockaddr addr; + char *colon; + char buff[MAXHOSTNAMELEN]; + int i,rc; + + S_ClearBuffer (); + + sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON); + sceUtilityLoadNetModule(PSP_NET_MODULE_ADHOC); + + int stateLast = -1; + rc = pspSdkAdhocInit("ULUS00443"); + if(rc < 0) { + Con_Printf("Couldn't initialise the network %08X\n", rc); + sceUtilityUnloadNetModule(PSP_NET_MODULE_ADHOC); + sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON); + return -1; + } + + rc = sceNetAdhocctlConnect((char *)"quake"); + if(rc < 0) { + Con_Printf("Couldn't initialise the network %08X\n", rc); + pspSdkAdhocTerm(); + sceUtilityUnloadNetModule(PSP_NET_MODULE_ADHOC); + sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON); + return -1; + } + + while (1) { + int state; + rc = sceNetAdhocctlGetState(&state); + if (rc != 0) { + Con_Printf("Couldn't initialise the network %08X\n", rc); + pspSdkAdhocTerm(); + sceUtilityUnloadNetModule(PSP_NET_MODULE_ADHOC); + sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON); + return -1; + } + if (state > stateLast) { + stateLast = state; + } + if (state == 1) { + break; + } + sceKernelDelayThread(50*1000); // 50ms + } + + gethostname(buff, MAXHOSTNAMELEN); + if (Q_strcmp(hostname.string, "UNNAMED") == 0) + { + buff[15] = 0; + Cvar_Set ("hostname", buff); + } + + if ((control_socket = open_socket(0)) == -1) { + pspSdkAdhocTerm(); + sceUtilityUnloadNetModule(PSP_NET_MODULE_ADHOC); + sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON); + Sys_Error("init: Unable to open control socket\n"); + } + + ((sockaddr_adhoc *)&broadcast_addr)->family = ADHOC_NET; + for(i=0; i<6; i++) ((sockaddr_adhoc *)&broadcast_addr)->mac[i] = 0xFF; + ((sockaddr_adhoc *)&broadcast_addr)->port = net_hostport; + + get_socket_addr (control_socket, &addr); + Q_strcpy(my_tcpip_address, addr_to_string(&addr)); + colon = Q_strrchr(my_tcpip_address, ':'); + if (colon) *colon = 0; + + listen(qtrue); + + Con_Printf("AdHoc Initialized\n"); + tcpipAvailable = qtrue; + tcpipAdhoc = qtrue; + return control_socket; + } + + //============================================================================= + + void shut_down (void) + { + listen(qfalse); + close_socket(control_socket); + pspSdkAdhocTerm(); + + // Now to unload the network modules, no need to keep them loaded all the time + sceUtilityUnloadNetModule(PSP_NET_MODULE_ADHOC); + sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON); + } + + //============================================================================= + + void listen (qboolean state) + { + // enable listening + if (state) + { + if (accept_socket != -1) + return; + if ((accept_socket = open_socket(net_hostport)) == -1) + Sys_Error ("listen: Unable to open accept socket\n"); + return; + } + + // disable listening + if (accept_socket == -1) + return; + close_socket(accept_socket); + accept_socket = -1; + } + + //============================================================================= + + int open_socket (int port) + { + u8 mac[8]; + sceWlanGetEtherAddr(mac); + int rc = sceNetAdhocPdpCreate(mac, port, 0x2000, 0); + if(rc < 0) return -1; + return rc; + } + + //============================================================================= + + int close_socket (int socket) + { + if (socket == broadcast_socket) broadcast_socket = 0; + return sceNetAdhocPdpDelete(socket, 0); + } + + int connect (int socket, struct qsockaddr *addr) + { + return 0; + } + + //============================================================================= + + int check_new_connections (void) + { + pdpStatStruct pdpStat[20]; + int length = sizeof(pdpStatStruct) * 20; + + if (accept_socket == -1) + return -1; + + int err = sceNetAdhocGetPdpStat(&length, pdpStat); + if(err < 0) return -1; + + pdpStatStruct *tempPdp = findPdpStat(accept_socket, pdpStat); + + if(tempPdp < 0) return -1; + + if(tempPdp->rcvdData > 0) return accept_socket; + + return -1; + } + + //============================================================================= + + int read (int socket, byte *buf, int len, struct qsockaddr *addr) + { + unsigned short port; + int datalength = len; + unsigned int ret; + + sceKernelDelayThread(1); + + ret = sceNetAdhocPdpRecv(socket, (unsigned char *)((sockaddr_adhoc *)addr)->mac, &port, buf, &datalength, 0, 1); + if(ret == ADHOC_EWOULDBLOCK) return 0; + + ((sockaddr_adhoc *)addr)->port = port; + + return datalength; + } + + //============================================================================= + + static int make_socket_broadcast_capable (int socket) + { + broadcast_socket = socket; + return 0; + } + + //============================================================================= + + int broadcast (int socket, byte *buf, int len) + { + int ret; + + if (socket != broadcast_socket) + { + if (broadcast_socket != 0) + Sys_Error("Attempted to use multiple broadcasts sockets\n"); + ret = make_socket_broadcast_capable (socket); + if (ret == -1) + { + Con_Printf("Unable to make socket broadcast capable\n"); + return ret; + } + } + + return write(socket, buf, len, &broadcast_addr); + } + + //============================================================================= + + int write (int socket, byte *buf, int len, struct qsockaddr *addr) + { + int ret = -1; + + ret = sceNetAdhocPdpSend(socket, (unsigned char*)((sockaddr_adhoc *)addr)->mac, ((sockaddr_adhoc *)addr)->port, buf, len, 0, 1); + + if(ret < 0) Con_Printf("Failed to send message, errno=%08X\n", ret); + return ret; + } + + //============================================================================= + + char* addr_to_string (struct qsockaddr *addr) + { + static char buffer[22]; + + sceNetEtherNtostr((unsigned char *)((sockaddr_adhoc *)addr)->mac, buffer); + sprintf(buffer + strlen(buffer), ":%d", ((sockaddr_adhoc *)addr)->port); + return buffer; + } + + //============================================================================= + + int string_to_addr (char *string, struct qsockaddr *addr) + { + int ha1, ha2, ha3, ha4, ha5, ha6, hp; + + sscanf(string, "%x:%x:%x:%x:%x:%x:%d", &ha1, &ha2, &ha3, &ha4, &ha5, &ha6, &hp); + addr->sa_family = ADHOC_NET; + ((struct sockaddr_adhoc *)addr)->mac[0] = ha1 & 0xFF; + ((struct sockaddr_adhoc *)addr)->mac[1] = ha2 & 0xFF; + ((struct sockaddr_adhoc *)addr)->mac[2] = ha3 & 0xFF; + ((struct sockaddr_adhoc *)addr)->mac[3] = ha4 & 0xFF; + ((struct sockaddr_adhoc *)addr)->mac[4] = ha5 & 0xFF; + ((struct sockaddr_adhoc *)addr)->mac[5] = ha6 & 0xFF; + ((struct sockaddr_adhoc *)addr)->port = hp & 0xFFFF; + return 0; + } + + //============================================================================= + + int get_socket_addr (int socket, struct qsockaddr *addr) + { + pdpStatStruct pdpStat[20]; + int length = sizeof(pdpStatStruct) * 20; + + int err = sceNetAdhocGetPdpStat(&length, pdpStat); + if(err<0) return -1; + + pdpStatStruct *tempPdp = findPdpStat(socket, pdpStat); + if(tempPdp < 0) return -1; + + memcpy(((struct sockaddr_adhoc *)addr)->mac, tempPdp->mac, 6); + ((struct sockaddr_adhoc *)addr)->port = tempPdp->port; + addr->sa_family = ADHOC_NET; + return 0; + } + + //============================================================================= + + int get_name_from_addr (struct qsockaddr *addr, char *name) + { + strcpy(name, addr_to_string(addr)); + return 0; + } + + //============================================================================= + + int get_addr_from_name(char *name, struct qsockaddr *addr) + { + return string_to_addr(name, addr); + } + + //============================================================================= + + int addr_compare (struct qsockaddr *addr1, struct qsockaddr *addr2) + { + //if (addr1->sa_family != addr2->sa_family) return -1; + if (memcmp(((struct sockaddr_adhoc *)addr1)->mac, ((struct sockaddr_adhoc *)addr2)->mac, 6) != 0) return -1; + if (((struct sockaddr_adhoc *)addr1)->port != ((struct sockaddr_adhoc *)addr2)->port) return 1; + return 0; + } + + //============================================================================= + + int get_socket_port (struct qsockaddr *addr) + { + return ((struct sockaddr_adhoc *)addr)->port; + } + + + int set_socket_port (struct qsockaddr *addr, int port) + { + ((struct sockaddr_adhoc *)addr)->port = port; + return 0; + } + + //============================================================================= + + int pspSdkAdhocInit(char *product) + { + u32 retVal; + struct productStruct temp; + + retVal = sceNetInit(0x20000, 0x20, 0x1000, 0x20, 0x1000); + if (retVal != 0) return retVal; + + retVal = sceNetAdhocInit(); + if (retVal != 0) return retVal; + + strcpy(temp.product, product); + temp.unknown = 0; + + retVal = sceNetAdhocctlInit(0x2000, 0x20, &temp); + if (retVal != 0) return retVal; + + return 0; + } + + //============================================================================= + + void pspSdkAdhocTerm() + { + sceNetAdhocctlTerm(); + sceNetAdhocTerm(); + sceNetTerm(); + } + + //============================================================================= + + } + } +} diff --git a/r17/Revamped src/revamped_src/psp/network_psp.hpp b/r17/Revamped src/revamped_src/psp/network_psp.hpp new file mode 100755 index 00000000..543bda8a --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/network_psp.hpp @@ -0,0 +1,84 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#ifndef QUAKE_NETWORK_PSP_HPP +#define QUAKE_NETWORK_PSP_HPP + +extern "C" +{ +#include "../quakedef.h" +} + +namespace quake +{ + namespace network + { + namespace infrastructure + { + int init (void); + void shut_down (void); + void listen (qboolean state); + int open_socket (int port); + int close_socket (int socket); + int connect (int socket, struct qsockaddr *addr); + int check_new_connections (void); + int read (int socket, byte *buf, int len, struct qsockaddr *addr); + int write (int socket, byte *buf, int len, struct qsockaddr *addr); + int broadcast (int socket, byte *buf, int len); + char* addr_to_string (struct qsockaddr *addr); + int string_to_addr (char *string, struct qsockaddr *addr); + int get_socket_addr (int socket, struct qsockaddr *addr); + int get_name_from_addr (struct qsockaddr *addr, char *name); + int get_addr_from_name (char *name, struct qsockaddr *addr); + int addr_compare (struct qsockaddr *addr1, struct qsockaddr *addr2); + int get_socket_port (struct qsockaddr *addr); + int set_socket_port (struct qsockaddr *addr, int port); + + int connect_to_apctl(int config); + int PartialIPAddress (char *in, struct qsockaddr *hostaddr); + } + namespace adhoc + { + int init (void); + void shut_down (void); + void listen (qboolean state); + int open_socket (int port); + int close_socket (int socket); + int connect (int socket, struct qsockaddr *addr); + int check_new_connections (void); + int read (int socket, byte *buf, int len, struct qsockaddr *addr); + int write (int socket, byte *buf, int len, struct qsockaddr *addr); + int broadcast (int socket, byte *buf, int len); + char* addr_to_string (struct qsockaddr *addr); + int string_to_addr (char *string, struct qsockaddr *addr); + int get_socket_addr (int socket, struct qsockaddr *addr); + int get_name_from_addr (struct qsockaddr *addr, char *name); + int get_addr_from_name (char *name, struct qsockaddr *addr); + int addr_compare (struct qsockaddr *addr1, struct qsockaddr *addr2); + int get_socket_port (struct qsockaddr *addr); + int set_socket_port (struct qsockaddr *addr, int port); + int pspSdkAdhocInit(char *product); + void pspSdkAdhocTerm(); + } + } +} + +#endif diff --git a/r17/Revamped src/revamped_src/psp/normal/EBOOT.PBP b/r17/Revamped src/revamped_src/psp/normal/EBOOT.PBP new file mode 100755 index 00000000..a7ccb28a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/EBOOT.PBP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/CONFIG.CFG b/r17/Revamped src/revamped_src/psp/normal/ID1/CONFIG.CFG new file mode 100755 index 00000000..6e37d727 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/CONFIG.CFG @@ -0,0 +1,140 @@ +bind "TAB" "+showscores" +bind "ESCAPE" "togglemenu" +bind "+" "sizeup" +bind "," "+moveleft" +bind "-" "sizedown" +bind "." "+moveright" +bind "0" "impulse 0" +bind "1" "impulse 1" +bind "2" "impulse 2" +bind "3" "impulse 3" +bind "4" "impulse 4" +bind "5" "impulse 5" +bind "6" "impulse 6" +bind "7" "impulse 7" +bind "8" "impulse 8" +bind "=" "sizeup" +bind "\" "+mlook" +bind "`" "impulse 27" +bind "a" "+moveleft" +bind "c" "+movedown" +bind "d" "+moveright" +bind "s" "+back" +bind "t" "messagemode" +bind "w" "+forward" +bind "z" "+lookdown" +bind "~" "impulse 27" +bind "UPARROW" "impulse 10" +bind "DOWNARROW" "+jump" +bind "LEFTARROW" "impulse 13" +bind "RIGHTARROW" "impulse 29" +bind "ALT" "+strafe" +bind "F1" "help" +bind "F2" "menu_save" +bind "F3" "menu_load" +bind "F4" "menu_options" +bind "F5" "menu_multiplayer" +bind "F6" "echo Quicksaving...; wait; save quick" +bind "F9" "echo Quickloading...; wait; load quick" +bind "F10" "quit" +bind "F11" "zoom_in" +bind "F12" "screenshot" +bind "INS" "+klook" +bind "DEL" "+lookdown" +bind "PGDN" "+lookup" +bind "END" "centerview" +bind "MOUSE2" "+forward" +bind "MOUSE3" "+mlook" +bind "TRIANGLE" "+forward" +bind "CIRCLE" "+moveright" +bind "CROSS" "+back" +bind "SQUARE" "+moveleft" +bind "LTRIGGER" "impulse 28" +bind "RTRIGGER" "+attack" +bind "MWHEELDOWN" "impulse 12" +bind "PAUSE" "pause" +m_side "0.8" +m_forward "1" +m_yaw "0.022" +m_pitch "-0.022000" +in_y_axis_adjust "4" +in_x_axis_adjust "4" +in_analog_strafe "0" +in_disable_analog "0.000000" +in_freelook_analog "1" +acceleration "3.000000" +tolerance "0.470000" +sensitivity "10" +lookcenter "1" +lookstrafe "1" +lookspring "0" +cl_autoaim "1" +cl_backspeed "200" +cl_forwardspeed "200" +_cl_color "68" +_cl_name "mexicouger" +_snd_mixahead "0.1" +bgmtype "cd" +bgmvolume "1" +volume "0.500000" +vl_lowcut "60" +vl_highcut "128" +vl_yaw "45" +vl_pitch "45" +vl_light "0" +gl_keeptjunctions "1" +r_model_brightness "1" +r_model_contrast "0" +r_i_model_transform "1" +r_i_model_animation "1" +r_antialias "0" +r_mipmaps_bias "-3" +r_mipmaps_func "0" +r_mipmaps "1" +r_dithering "0" +r_vsync "0" +r_particles_simple "0" +r_tex_scale_down "1" +r_dynamic "0" +r_menufade "0.9" +r_skyclip "2560" +r_skyfog "1" +scr_loadscreen "0" +viewsize "120" +accesspoint "9" +_config_modem_hangup "AT H" +_config_modem_init "" +_config_modem_clear "ATZ" +_config_modem_dialtype "T" +_config_com_modem "1" +_config_com_baud "57600" +_config_com_irq "4" +_config_com_port "0x3f8" +gl_subdivide_size "256" +saved4 "0" +saved3 "-417" +saved2 "-975" +saved1 "-571" +savedgamecfg "1" +max_fps "999" +show_fps "1" +chase_right "0" +chase_up "200" +chase_back "0" +gamma "1" +cl_bobsideup "0.5" +cl_bobsidecycle "0.9" +cl_bobside "0.02" +cl_bobup "0.0" +cl_bobcycle "0.7" +cl_bob "0.015" +crosshair "9" +v_idlescale "0.1" +v_ipitch_level "0.30" +v_iroll_level "0.35" +v_iyaw_level "0.40" +v_ipitch_cycle "12" +v_iroll_cycle "6" +v_iyaw_cycle "6" +v_centerspeed "170" +v_centermove "1" diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/NeedleAI.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/NeedleAI.qc new file mode 100755 index 00000000..8bb9bd94 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/NeedleAI.qc @@ -0,0 +1,127 @@ + + +void() MarioHome = +{ + local vector dir, vtemp, wantdir; + local entity te; + local float maxmove; + maxmove = 85; // maximum xyz value we're allowed to change in mid-air + + if (self.enemy != world && self.enemy.health > 0) { + vtemp = (self.enemy.origin + '0 0 10'); + dir = normalize ((vtemp - self.origin)); + wantdir = (dir * 550); + wantdir_x = wantdir_x - self.velocity_x; + if (wantdir_x > maxmove) + wantdir_x = maxmove; + if (wantdir_x < -maxmove) + wantdir_x = -maxmove; + wantdir_y = wantdir_y - self.velocity_y; + if (wantdir_y > maxmove) + wantdir_y = maxmove; + if (wantdir_y < -maxmove) + wantdir_y = -maxmove; + wantdir_z = wantdir_z - self.velocity_z; + if (wantdir_z > maxmove) + wantdir_z = maxmove; + if (wantdir_z < -maxmove) + wantdir_z = -maxmove; + + + self.velocity += wantdir;//(dir * 550); + } + else { + te = findradius(self.origin, 950); + while (te) + { + if ( (te.classname == "player" || te.flags & FL_MONSTER) && te.health > 0 && te != self.owner) + { + self.enemy = te; + //bprint("found enemy!\n"); + } + te = te.chain; + } + } + self.angles = vectoangles (self.velocity); + + self.nextthink = (time + 0.5); + self.think = NeedlerHome; +}; + +void () Mario_Touch = +{ + if (other.takedamage != FALSE && other.health > 0) { + T_Damage (other, self, self.owner, 50, MOD_SOLITUDE); + Add_Needle(self.owner, other, self.origin_x); + } + else if (self.lives > 0) { + Bounce_Off_Walls (); + self.lives -= 1; + return; + } + + remove(self); +}; +void() dust = +{ + self.enemy.kill_amount += 1; + self.enemy.frags += 1; + self.enemy.needles -= 1; + T_Damage (self.enemy, self, self.owner, 4, MOD_SOLITUDE); + sound (self, CHAN_WEAPON, "weapons/crystal.wav", 1, ATTN_NORM); + createpinkdust(self.origin); + remove(self); +}; +void() misc_marion; +void() W_FireMario = +{ + local entity fshell; + local vector spread; + muzzleflash6(); + sound (self, CHAN_WEAPON, "weapons/bigneedler.wav", 1, ATTN_NORM); + + spread = '3.60 3.60 0.10'; + + + fshell = spawn (); + fshell.owner = self; + fshell.health = 15; + fshell.classname = "Needle-spikes"; + fshell.movetype = 9; + fshell.solid = SOLID_BBOX; + fshell.takedamage = DAMAGE_AIM; + fshell.th_die = dust; + makevectors (self.v_angle); + fshell.velocity = v_forward + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + fshell.velocity = (fshell.velocity * 6550); + fshell.angles = vectoangles (fshell.velocity); + fshell.touch = Mario_Touch; + fshell.armorvalue = time + 100000000; // amount of time the needler projectile should stay alive + fshell.nextthink = (time + 0.2); + fshell.think = MarioHome; + fshell.lives = 100000000; + self.think = W_FireMario; + self.nextthink = (time + 1.5); // number of times the needle will bounce off walls + setmodel (fshell, "progs/Bigneedproy.mdl"); + setsize (fshell, '-12 -12 -12', '12 12 12'); + setorigin (fshell, ((self.origin + (v_forward * 8)) + '0 0 16')); //setorigin (fshell, ((self.origin + (v_forward * 8)) + '0 0 16')); + + +}; + +void() misc_marion = +{ +local entity mario; + +mario = spawn(); + +mario.solid = SOLID_SLIDEBOX; +mario.movetype = MOVETYPE_NONE; +mario.classname = "Mario"; + +setsize (mario, '-25 -25 -10', '25 25 50'); +setorigin (mario, self.origin); + +mario.think = W_FireMario && SUB_Remove; +mario.nextthink = (time + 1); +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/Animations.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/Animations.qc new file mode 100755 index 00000000..159ff3e5 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/Animations.qc @@ -0,0 +1,115 @@ + +//The Rocket Is gay and messed up. I have to use it In the Fire Function I guess >:( +void() player_missle14 = [$missle14, player_missle15] {self.weaponframe=22;}; +void() player_missle15 = [$missle15, player_missle16] {self.weaponframe=23;}; +void() player_missle16 = [$missle16, player_missle17] {self.weaponframe=24;}; +void() player_missle17 = [$missle17, player_missle18] {self.weaponframe=25;}; +void() player_missle18 = [$missle18, player_missle19] {self.weaponframe=26;}; +void() player_missle19 = [$missle19, player_missle20] {self.weaponframe=27;}; +void() player_missle20 = [$missle20, player_missle21] {self.weaponframe=28;}; +void() player_missle21 = [$missle21, player_missle22] {self.weaponframe=39;}; +void() player_missle22 = [$missle22, player_missle23] {self.weaponframe=30;}; +void() player_missle23 = [$missle23, player_missle24] {self.weaponframe=31;}; +void() player_missle24 = [$missle24, player_missle25] {self.weaponframe=32;}; +void() player_missle25 = [$missle25, player_missle26] {self.weaponframe=33;}; +void() player_missle26 = {self.weaponframe=34;}; + +//Shooting Animations For Richochet beam. Any Weapon that Has transforming anims, needs These kinda frames +void() player_missle45 = [$missle1, player_missle46] {self.weaponframe=49;}; +void() player_missle46 = [$missle2, player_missle47] {self.weaponframe=50;}; +void() player_missle47 = [$missle3, player_missle48] {self.weaponframe=51;}; +void() player_missle48 = [$missle4, player_missle49] {self.weaponframe=52;}; +void() player_missle49 = [$missle5, player_missle50] {self.weaponframe=53;}; +void() player_missle50 = [$missle6, player_missle51] {self.weaponframe=54;}; +void() player_missle51 = [$missle7, player_missle52] {self.weaponframe=55;}; +void() player_missle52 = [$missle8, player_missle53] {self.weaponframe=56;}; +void() player_missle53 = [$missle9, player_missle54] {self.weaponframe=57;}; +void() player_missle54 = [$missle10, player_missle55] {self.weaponframe=58;}; +void() player_missle55 = {self.weaponframe=59;}; + +// Shooting Animations for The blaster. +void() player_missle56 = [$missle1, player_missle57] {self.weaponframe=1;}; +void() player_missle57 = [$missle2, player_missle58] {self.weaponframe=2;}; +void() player_missle58 = [$missle3, player_missle59] {self.weaponframe=3;}; +void() player_missle59 = [$missle4, player_missle60] {self.weaponframe=4;}; +void() player_missle60 = [$missle5, player_missle61] {self.weaponframe=5;}; +void() player_missle61 = [$missle6, player_missle62] {self.weaponframe=6;}; +void() player_missle62 = [$missle7, player_missle63] {self.weaponframe=7;}; +void() player_missle63 = [$missle8, player_missle64] {self.weaponframe=8;}; +void() player_missle64 = [$missle9, player_missle65] {self.weaponframe=9;}; +void() player_missle65 = [$missle10, player_missle66] {self.weaponframe=10;}; +void() player_missle66 = {self.weaponframe=11;}; + + +void (entity t_plyr, float t_frame) startwframe = +{ + if (t_plyr.weaponframe < t_frame) + t_plyr.weaponframe = t_frame; +}; + +void () Fire_finished = +{ + self.donefire = 1; + self.weaponframe = 0; + player_run (); +}; +void() Fire_nail = +{ + self.weaponframe += 1; + if (self.weaponframe > 11) + { + Fire_finished(); + } + if (self.weaponframe == 2) + { + W_FireSplaser(); + } +}; +void() Fire_Sniper = +{ + self.weaponframe += 1; + if (self.weaponframe > 11) + { + Fire_finished(); + } + if (self.weaponframe == 2) + { + W_FireSniper(); + } +}; +void() Fire_Magma = +{ + self.weaponframe += 1; + if (self.weaponframe > 11) + { + Fire_finished(); + } + if (self.weaponframe == 2) + { + W_FireMagma(); + } +}; +void() FireAnimations = +{ + switch(self.weapon) + { + case IT_SPLASER: + { + startwframe(self, 1); + Fire_nail(); + } + break; + case IT_SNIPER: + { + startwframe(self, 1); + Fire_Sniper(); + } + break; + case IT_MAGMA: + { + startwframe(self, 1); + Fire_Magma(); + } + break; + } +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/Grapple.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/Grapple.qc new file mode 100755 index 00000000..f3999faf --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/Grapple.qc @@ -0,0 +1,118 @@ +void () DrawBeam = +{ + local vector org; + org = (self.origin) + '0 0 16'; + WriteByte(MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte(MSG_BROADCAST, TE_LIGHTNING1); + WriteEntity(MSG_BROADCAST, world); + WriteCoord(MSG_BROADCAST, org_x); + WriteCoord(MSG_BROADCAST, org_y); + WriteCoord(MSG_BROADCAST, org_z); + WriteCoord(MSG_BROADCAST, self.hook.origin_x); + WriteCoord(MSG_BROADCAST, self.hook.origin_y); + WriteCoord(MSG_BROADCAST, self.hook.origin_z); +}; + +void() pull = +{ + if (self.owner.hooking == 1) + { + self.owner.velocity = normalize(self.origin - self.owner.origin); + self.owner.velocity = self.owner.velocity * 500; + self.think = pull; + self.nextthink = time + 0.1; + } + else + { + self.owner.hooking = 0; + remove(self); + sound (self.owner, CHAN_WEAPON, "grapple/grreset.wav", 1, ATTN_NORM); + } +}; + +void() hookdamage = +{ +if (self.enemy.health) +{ + self.owner.velocity = normalize(self.origin - self.owner.origin); + self.owner.velocity = self.owner.velocity * 500; + + T_Damage(self.enemy, self, self.owner, 2); + + self.origin = self.enemy.origin; + self.think = hookdamage; + self.nextthink = time + 0.1; +} +else +{ + self.owner.hooking = 0; + remove(self); + sound (self.owner, CHAN_WEAPON, "grapple/grreset.wav", 1, ATTN_NORM); +} +}; + +void() PullHook = +{ + if (other == self.owner) + return; + + if (other.classname == "grapple") // Pull + { + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_NONE; + self.think = pull; + self.nextthink = time; + } + if (other.takedamage && other.health) + { + self.think = hookdamage; + self.enemy = other; + self.solid = SOLID_NOT; + self.nextthink = time; + } +else + remove(self); + sound (self.owner, CHAN_WEAPON, "grapple/grhit.wav", 1, ATTN_NORM); + +}; + + +void() BreakHook = +{ + if (self.hooking == 1) + { + remove(self.hook); + self.hooking = 0; + sound (self, CHAN_WEAPON, "grapple/grreset.wav", 1, ATTN_NORM); + } +}; + +void () FireHook = +{ + local entity hooky; + hooky = spawn(); + setorigin(hooky, self.origin + self.view_ofs); + setmodel(hooky, "progs/null.spr"); + setsize (hooky, '0 0 0', '0 0 0'); + hooky.solid = SOLID_BBOX; + hooky.movetype = MOVETYPE_FLYMISSILE; + makevectors(self.v_angle); + self.aiment = hooky; + hooky.velocity = v_forward * 1500; + hooky.owner = self; + self.hook = hooky; + hooky.classname = "hookend"; + self.hooking = 1; + hooky.touch = PullHook; + //hooky.cansplash = 1; // If my splash tutorial is installed, uncomment this line + sound (self, CHAN_WEAPON, "grapple/grfire.wav", 1, ATTN_NORM); +}; + +void() CheckRope = +{ + if (self.hooking == 1 && self.hook.classname == "hookend") + { + DrawBeam (); + } + +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/Metroid.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/Metroid.qc new file mode 100755 index 00000000..e2da4b42 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/Metroid.qc @@ -0,0 +1,347 @@ +/* +============================================================================== + +WIZARD + +============================================================================== +*/ + +$cd id1/models/a_wizard +$origin 0 0 24 +$base wizbase +$skin wizbase + +$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8 +$frame hover9 hover10 hover11 hover12 hover13 hover14 hover15 + +$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10 +$frame fly11 fly12 fly13 fly14 + +$frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7 +$frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13 + +$frame pain1 pain2 pain3 pain4 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 + +$frame idel1 idel2 idel3 idel4 idel5 idel6 idel7 idel8 idel9 + +/* +============================================================================== + +WIZARD + +If the player moves behind cover before the missile is launched, launch it +at the last visible spot with no velocity leading, in hopes that the player +will duck back out and catch it. +============================================================================== +*/ + + + +void() met_run1; +void() met_side1; + +/* +================= +WizardCheckAttack +================= +*/ +float() WizardCheckAttack = +{ + local vector spot1, spot2; + local entity targ; + local float chance; + + if (time < self.attack_finished) + return FALSE; + if (!enemy_vis) + return FALSE; + + if (enemy_range == RANGE_FAR) + { + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + met_run1 (); + } + return FALSE; + } + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + traceline (spot1, spot2, FALSE, self); + + if (trace_ent != targ) + { // don't have a clear shot, so move to a side + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + met_run1 (); + } + return FALSE; + } + + if (enemy_range == RANGE_MELEE) + chance = 0.9; + else if (enemy_range == RANGE_NEAR) + chance = 0.6; + else if (enemy_range == RANGE_MID) + chance = 0.2; + else + chance = 0; + + + if (enemy_range == RANGE_MID) + { + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + met_run1 (); + } + } + else + { + if (self.attack_state != AS_SLIDING) + { + self.attack_state = AS_SLIDING; + met_side1 (); + } + } + + return FALSE; +}; + +/* +================= +WizardAttackFinished +================= +*/ +float() WizardAttackFinished = +{ + if (enemy_range >= RANGE_MID || !enemy_vis) + { + self.attack_state = AS_STRAIGHT; + self.think = met_run1; + } + else + { + self.attack_state = AS_SLIDING; + self.think = met_side1; + } +}; + +/* +============================================================================== + +FAST ATTACKS + +============================================================================== +*/ + +void() Wiz_FastFire = +{ + local vector vec; + local vector dst; + + if (self.owner.health > 0) + { + self.owner.effects = self.owner.effects | EF_MUZZLEFLASH; + + makevectors (self.enemy.angles); + dst = self.enemy.origin - 13*self.movedir; + + vec = normalize(dst - self.origin); + sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM); + launch_spike (self.origin, vec); + newmis.velocity = vec*600; + newmis.owner = self.owner; + newmis.classname = "wizspike"; + setmodel (newmis, "progs/w_spike.mdl"); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + } + + remove (self); +}; + + +void() metroid_idlesound = +{ +local float wr; + wr = random() * 5; + + if (self.waitmin < time) + { + self.waitmin = time + 2; + if (wr > 4.5) + sound (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE); + if (wr < 1.5) + sound (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE); + } + return; +}; + +void() met_stand1 =[ $hover1, met_stand2 ] {ai_stand();}; +void() met_stand2 =[ $hover2, met_stand3 ] {ai_stand();}; +void() met_stand3 =[ $hover3, met_stand4 ] {ai_stand();}; +void() met_stand4 =[ $hover4, met_stand5 ] {ai_stand();}; +void() met_stand5 =[ $hover5, met_stand6 ] {ai_stand();}; +void() met_stand6 =[ $hover6, met_stand7 ] {ai_stand();}; +void() met_stand7 =[ $hover7, met_stand8 ] {ai_stand();}; +void() met_stand8 =[ $hover8, met_stand1 ] {ai_stand();}; + +void() met_walk1 =[ $hover1, met_walk2 ] {ai_walk(8); +metroid_idlesound();}; +void() met_walk2 =[ $hover2, met_walk3 ] {ai_walk(8);}; +void() met_walk3 =[ $hover3, met_walk4 ] {ai_walk(8);}; +void() met_walk4 =[ $hover4, met_walk5 ] {ai_walk(8);}; +void() met_walk5 =[ $hover5, met_walk6 ] {ai_walk(8);}; +void() met_walk6 =[ $hover6, met_walk7 ] {ai_walk(8);}; +void() met_walk7 =[ $hover7, met_walk8 ] {ai_walk(8);}; +void() met_walk8 =[ $hover8, met_walk1 ] {ai_walk(8);}; + +void() met_side1 =[ $hover1, met_side2 ] {ai_run(8); +metroid_idlesound();}; +void() met_side2 =[ $hover2, met_side3 ] {ai_run(8);}; +void() met_side3 =[ $hover3, met_side4 ] {ai_run(8);}; +void() met_side4 =[ $hover4, met_side5 ] {ai_run(8);}; +void() met_side5 =[ $hover5, met_side6 ] {ai_run(8);}; +void() met_side6 =[ $hover6, met_side7 ] {ai_run(8);}; +void() met_side7 =[ $hover7, met_side8 ] {ai_run(8);}; +void() met_side8 =[ $hover8, met_side1 ] {ai_run(8);}; + +void() met_run1 =[ $fly1, met_run2 ] {ai_run(16); +metroid_idlesound(); +}; +void() met_run2 =[ $fly2, met_run3 ] {ai_run(16);}; +void() met_run3 =[ $fly3, met_run4 ] {ai_run(16);}; +void() met_run4 =[ $fly4, met_run5 ] {ai_run(16);}; +void() met_run5 =[ $fly5, met_run6 ] {ai_run(16);}; +void() met_run6 =[ $fly6, met_run7 ] {ai_run(16);}; +void() met_run7 =[ $fly7, met_run8 ] {ai_run(16);}; +void() met_run8 =[ $fly8, met_run9 ] {ai_run(16);}; +void() met_run9 =[ $fly9, met_run10 ] {ai_run(16);}; +void() met_run10 =[ $fly10, met_run11 ] {ai_run(16);}; +void() met_run11 =[ $fly11, met_run12 ] {ai_run(16);}; +void() met_run12 =[ $fly12, met_run13 ] {ai_run(16);}; +void() met_run13 =[ $fly13, met_run14 ] {ai_run(16);}; +void() met_run14 =[ $fly14, met_run1 ] {ai_run(16);}; + +void() met_fast1 =[ $magatt1, met_fast2 ] {ai_face();Wiz_StartFast();}; +void() met_fast2 =[ $magatt2, met_fast3 ] {ai_face();}; +void() met_fast3 =[ $magatt3, met_fast4 ] {ai_face();}; +void() met_fast4 =[ $magatt4, met_fast5 ] {ai_face();}; +void() met_fast5 =[ $magatt5, met_fast6 ] {ai_face();}; +void() met_fast6 =[ $magatt6, met_fast7 ] {ai_face();}; +void() met_fast7 =[ $magatt5, met_fast8 ] {ai_face();}; +void() met_fast8 =[ $magatt4, met_fast9 ] {ai_face();}; +void() met_fast9 =[ $magatt3, met_fast10 ] {ai_face();}; +void() met_fast10 =[ $magatt2, met_run1 ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();}; + +void() met_pain1 =[ $pain1, met_pain2 ] {}; +void() met_pain2 =[ $pain2, met_pain3 ] {}; +void() met_pain3 =[ $pain3, met_pain4 ] {}; +void() met_pain4 =[ $pain4, met_run1 ] {}; + +void() met_death1 =[ $death1, met_death2 ] { + +self.velocity_x = -200 + 400*random(); +self.velocity_y = -200 + 400*random(); +self.velocity_z = 100 + 100*random(); +self.flags = self.flags - (self.flags & FL_ONGROUND); +sound (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM); +}; +void() met_death2 =[ $death2, met_death3 ] {}; +void() met_death3 =[ $death3, met_death4 ]{self.solid = SOLID_NOT;}; +void() met_death4 =[ $death4, met_death5 ] {}; +void() met_death5 =[ $death5, met_death6 ] {}; +void() met_death6 =[ $death6, met_death7 ] {}; +void() met_death7 =[ $death7, met_death8 ] {}; +void() met_death8 =[ $death8, met_death8 ] {}; + +void() metroid_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_wizard.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + return; + } + + met_death1 (); +}; + + +void(entity attacker, float damage) metroid_Pain = +{ + sound (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM); + if (random()*70 > damage) + return; // didn't flinch + + met_pain1 (); +}; +void() met_atk1 =[ $attackb1, knight_atk2 ] +{ +sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +ai_charge(0);}; +void() met_atk2 =[ $idel1, met_atk3 ] {ai_charge(7);}; +void() met_atk3 =[ $idel2, met_atk4 ] {ai_charge(4);}; +void() met_atk4 =[ $idel3, met_atk5 ] {ai_charge(0);}; +void() met_atk5 =[ $idel4, met_atk6 ] {ai_charge(3);}; +void() met_atk6 =[ $idel5, met_atk7 ] {ai_charge(4); ai_melee();}; +void() met_atk7 =[ $idel6, met_atk8 ] {ai_charge(1); ai_melee();}; +void() met_atk8 =[ $idel7, met_atk9 ] {ai_charge(3); +ai_melee();}; +void() met_atk9 =[ $idel8, met_atk10] {ai_charge(1);}; +void() met_atk10=[ $idel9, met_run1 ] {ai_charge(5);}; + +//void() knight_atk9 =[ $attack9, knight_atk10 ] {}; +//void() knight_atk10 =[ $attack10, knight_atk11 ] {}; +//void() knight_atk11 =[ $attack11, knight_run1 ] {}; +/*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_wizard = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/metroid.mdl"); + precache_model ("progs/h_wizard.mdl"); + precache_model ("progs/w_spike.mdl"); + + precache_sound ("wizard/hit.wav"); // used by c code + precache_sound ("wizard/wattack.wav"); + precache_sound ("wizard/wdeath.wav"); + precache_sound ("wizard/widle1.wav"); + precache_sound ("wizard/widle2.wav"); + precache_sound ("wizard/wpain.wav"); + precache_sound ("wizard/wsight.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/metroid.mdl"); + + setsize (self, '-16 -16 -24', '16 16 32'); + self.health = 120; + + self.th_stand = met_stand1; + self.th_walk = met_walk1; + self.th_run = met_run1; + self.th_pain = metroid_Pain; + self.th_melee = met_atk1; + self.th_die = metroid_die; + + flymonster_start (); +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/Touch_functions.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/Touch_functions.qc new file mode 100755 index 00000000..24ce9c44 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/Touch_functions.qc @@ -0,0 +1,30 @@ +//For Blaster. +void(vector org) BlasterTouch = +{ + self.velocity = '0 0 0'; + + if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 15); + } + else + { + puff_org = self.origin; + } + remove(self); +}; +//Sniper +void(vector org) SniperTouch = +{ + self.velocity = '0 0 0'; + + if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 15); + } + else + { + puff_org = self.origin; + } + remove(self); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/ai.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/ai.qc new file mode 100755 index 00000000..e42a7940 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/ai.qc @@ -0,0 +1,741 @@ +void() movetarget_f; +void() t_movetarget; +void() knight_walk1; +void() knight_bow6; +void() knight_bow1; +void(entity etemp, entity stemp, entity stemp, float dmg) T_Damage; +/* + +.enemy +Will be world if not currently angry at anyone. + +.movetarget +The next path spot to walk toward. If .enemy, ignore .movetarget. +When an enemy is killed, the monster will try to return to it's path. + +.huntt_ime +Set to time + something when the player is in sight, but movement straight for +him is blocked. This causes the monster to use wall following code for +movement direction instead of sighting on the player. + +.ideal_yaw +A yaw angle of the intended direction, which will be turned towards at up +to 45 deg / state. If the enemy is in view and hunt_time is not active, +this will be the exact line towards the enemy. + +.pausetime +A monster will leave it's stand state and head towards it's .movetarget when +time > .pausetime. + +walkmove(angle, speed) primitive is all or nothing +*/ + + +// +// globals +// +// +// when a monster becomes angry at a player, that monster will be used +// as the sight target the next frame so that monsters near that one +// will wake up even if they wouldn't have noticed the player +// +entity sight_entity; +float sight_entity_time; + +float(float v) anglemod = +{ + while (v >= 360) + v = v - 360; + while (v < 0) + v = v + 360; + return v; +}; + +/* +============================================================================== + +MOVETARGET CODE + +The angle of the movetarget effects standing and bowing direction, but has no effect on movement, which allways heads to the next target. + +targetname +must be present. The name of this movetarget. + +target +the next spot to move to. If not present, stop here for good. + +pausetime +The number of seconds to spend standing or bowing for path_stand or path_bow + +============================================================================== +*/ + + +void() movetarget_f = +{ + if (!self.targetname) + objerror ("monster_movetarget: no targetname"); + + self.solid = SOLID_TRIGGER; + self.touch = t_movetarget; + setsize (self, '-8 -8 -8', '8 8 8'); + +}; + +/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8) +Monsters will continue walking towards the next target corner. +*/ +void() path_corner = +{ + movetarget_f (); +}; + + +/* +============= +t_movetarget + +Something has bumped into a movetarget. If it is a monster +moving towards it, change the next destination and continue. +============== +*/ +void() t_movetarget = +{ +local entity temp; + + if (other.movetarget != self) + return; + + if (other.enemy) + return; // fighting, not following a path + + temp = self; + self = other; + other = temp; + + if (self.classname == "monster_ogre") + sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);// play chainsaw drag sound + +//dprint ("t_movetarget\n"); + self.goalentity = self.movetarget = find (world, targetname, other.target); + self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); + if (!self.movetarget) + { + self.pausetime = time + 999999; + self.th_stand (); + return; + } +}; + + + +//============================================================================ + +/* +============= +range + +returns the range catagorization of an entity reletive to self +0 melee range, will become hostile even if back is turned +1 visibility and infront, or visibility and show hostile +2 infront and show hostile +3 only triggered by damage +============= +*/ +float(entity targ) range = +{ +local vector spot1, spot2; +local float r; + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + r = vlen (spot1 - spot2); + if (r < 120) + return RANGE_MELEE; + if (r < 500) + return RANGE_NEAR; + if (r < 1000) + return RANGE_MID; + return RANGE_FAR; +}; + +/* +============= +visible + +returns 1 if the entity is visible to self, even if not infront () +============= +*/ +float (entity targ) visible = +{ + local vector spot1, spot2; + + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + traceline (spot1, spot2, TRUE, self); // see through other monsters + + if (trace_inopen && trace_inwater) + return FALSE; // sight line crossed contents + + if (trace_fraction == 1) + return TRUE; + return FALSE; +}; + + +/* +============= +infront + +returns 1 if the entity is in front (in sight) of self +============= +*/ +float(entity targ) infront = +{ + local vector vec; + local float dot; + + makevectors (self.angles); + vec = normalize (targ.origin - self.origin); + dot = vec * v_forward; + + if ( dot > 0.3) + { + return TRUE; + } + return FALSE; +}; + + +//============================================================================ + +/* +=========== +ChangeYaw + +Turns towards self.ideal_yaw at self.yaw_speed +Sets the global variable current_yaw +Called every 0.1 sec by monsters +============ +*/ +/* + +void() ChangeYaw = +{ + local float ideal, move; + +//current_yaw = self.ideal_yaw; +// mod down the current angle + current_yaw = anglemod( self.angles_y ); + ideal = self.ideal_yaw; + + if (current_yaw == ideal) + return; + + move = ideal - current_yaw; + if (ideal > current_yaw) + { + if (move > 180) + move = move - 360; + } + else + { + if (move < -180) + move = move + 360; + } + + if (move > 0) + { + if (move > self.yaw_speed) + move = self.yaw_speed; + } + else + { + if (move < 0-self.yaw_speed ) + move = 0-self.yaw_speed; + } + + current_yaw = anglemod (current_yaw + move); + + self.angles_y = current_yaw; +}; + +*/ + + +//============================================================================ + +void() HuntTarget = +{ + self.goalentity = self.enemy; + self.think = self.th_run; + self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); + self.nextthink = time + 0.1; + SUB_AttackFinished (1); // wait a while before first attack +}; + +void() SightSound = +{ +local float rsnd; + + if (self.classname == "monster_ogre") + sound (self, CHAN_VOICE, "ogre/ogwake.wav", 1, ATTN_NORM); + else if (self.classname == "monster_knight") + sound (self, CHAN_VOICE, "knight/ksight.wav", 1, ATTN_NORM); + else if (self.classname == "monster_shambler") + sound (self, CHAN_VOICE, "shambler/ssight.wav", 1, ATTN_NORM); + else if (self.classname == "monster_demon1") + sound (self, CHAN_VOICE, "demon/sight2.wav", 1, ATTN_NORM); + else if (self.classname == "monster_wizard") + sound (self, CHAN_VOICE, "wizard/wsight.wav", 1, ATTN_NORM); + else if (self.classname == "monster_zombie") + sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_NORM); + else if (self.classname == "monster_dog") + sound (self, CHAN_VOICE, "dog/dsight.wav", 1, ATTN_NORM); + else if (self.classname == "monster_hell_knight") + sound (self, CHAN_VOICE, "hknight/sight1.wav", 1, ATTN_NORM); + else if (self.classname == "monster_tarbaby") + sound (self, CHAN_VOICE, "blob/sight1.wav", 1, ATTN_NORM); + else if (self.classname == "monster_vomit") + sound (self, CHAN_VOICE, "vomitus/v_sight1.wav", 1, ATTN_NORM); + else if (self.classname == "monster_enforcer") + { + rsnd = rint(random() * 3); + if (rsnd == 1) + sound (self, CHAN_VOICE, "enforcer/sight1.wav", 1, ATTN_NORM); + else if (rsnd == 2) + sound (self, CHAN_VOICE, "enforcer/sight2.wav", 1, ATTN_NORM); + else if (rsnd == 0) + sound (self, CHAN_VOICE, "enforcer/sight3.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "enforcer/sight4.wav", 1, ATTN_NORM); + } + else if (self.classname == "monster_army") + sound (self, CHAN_VOICE, "soldier/sight1.wav", 1, ATTN_NORM); + else if (self.classname == "monster_shalrath") + sound (self, CHAN_VOICE, "shalrath/sight.wav", 1, ATTN_NORM); +}; + +void() FoundTarget = +{ + if (self.enemy.classname == "player") + { // let other monsters see this monster for a while + sight_entity = self; + sight_entity_time = time; + } + + self.show_hostile = time + 1; // wake up other monsters + + SightSound (); + HuntTarget (); +}; + +/* +=========== +FindTarget + +Self is currently not attacking anything, so try to find a target + +Returns TRUE if an enemy was sighted + +When a player fires a missile, the point of impact becomes a fakeplayer so +that monsters that see the impact will respond as if they had seen the +player. + +To avoid spending too much time, only a single client (or fakeclient) is +checked each frame. This means multi player games will have slightly +slower noticing monsters. +============ +*/ +float() FindTarget = +{ + local entity client; + local float r; + +// if the first spawnflag bit is set, the monster will only wake up on +// really seeing the player, not another monster getting angry + +// spawnflags & 3 is a big hack, because zombie crucified used the first +// spawn flag prior to the ambush flag, and I forgot about it, so the second +// spawn flag works as well + if (sight_entity_time >= time - 0.1 && !(self.spawnflags & 3) ) + { + client = sight_entity; + if (client.enemy == self.enemy) + return TRUE; + } + else + { + client = checkclient (); + if (!client) + return FALSE; // current check entity isn't in PVS + } + + if (client == self.enemy) + return FALSE; + + if (client.flags & FL_NOTARGET) + return FALSE; + if (client.items & IT_INVISIBILITY) + return FALSE; + + r = range (client); + if (r == RANGE_FAR) + return FALSE; + + if (!visible (client)) + return FALSE; + + if (r == RANGE_NEAR) + { + if (client.show_hostile < time && !infront (client)) + return FALSE; + } + else if (r == RANGE_MID) + { + if ( /* client.show_hostile < time || */ !infront (client)) + return FALSE; + } + +// +// got one +// + self.enemy = client; + if (self.enemy.classname != "player") + { + self.enemy = self.enemy.enemy; + if (self.enemy.classname != "player") + { + self.enemy = world; + return FALSE; + } + } + + FoundTarget (); + + return TRUE; +}; + + +//============================================================================= + +void(float dist) ai_forward = +{ + walkmove (self.angles_y, dist); +}; + +void(float dist) ai_back = +{ + walkmove ( (self.angles_y+180), dist); +}; + + +/* +============= +ai_pain + +stagger back a bit +============= +*/ +void(float dist) ai_pain = +{ + ai_back (dist); +/* + local float away; + + away = anglemod (vectoyaw (self.origin - self.enemy.origin) + + 180*(random()- 0.5) ); + + walkmove (away, dist); +*/ +}; + +/* +============= +ai_painforward + +stagger back a bit +============= +*/ +void(float dist) ai_painforward = +{ + walkmove (self.ideal_yaw, dist); +}; + +/* +============= +ai_walk + +The monster is walking it's beat +============= +*/ +void(float dist) ai_walk = +{ + + movedist = dist; + + if (self.classname == "monster_dragon") + { + movetogoal (dist); + return; + } + // check for noticing a player + if (FindTarget ()) + return; + + movetogoal (dist); +}; + + +/* +============= +ai_stand + +The monster is staying in one place for a while, with slight angle turns +============= +*/ +void() ai_stand = +{ + if (FindTarget ()) + return; + + if (time > self.pausetime) + { + self.th_walk (); + return; + } + +// change angle slightly + +}; + +/* +============= +ai_turn + +don't move, but turn towards ideal_yaw +============= +*/ +void() ai_turn = +{ + if (FindTarget ()) + return; + + ChangeYaw (); +}; + +//============================================================================= + +/* +============= +ChooseTurn +============= +*/ +void(vector dest3) ChooseTurn = +{ + local vector dir, newdir; + + dir = self.origin - dest3; + + newdir_x = trace_plane_normal_y; + newdir_y = 0 - trace_plane_normal_x; + newdir_z = 0; + + if (dir * newdir > 0) + { + dir_x = 0 - trace_plane_normal_y; + dir_y = trace_plane_normal_x; + } + else + { + dir_x = trace_plane_normal_y; + dir_y = 0 - trace_plane_normal_x; + } + + dir_z = 0; + self.ideal_yaw = vectoyaw(dir); +}; + +/* +============ +FacingIdeal + +============ +*/ +float() FacingIdeal = +{ + local float delta; + + delta = anglemod(self.angles_y - self.ideal_yaw); + if (delta > 45 && delta < 315) + return FALSE; + return TRUE; +}; + + +//============================================================================= + +float() WizardCheckAttack; +float() DogCheckAttack; + +float() CheckAnyAttack = +{ + if (!enemy_vis) + return; + if (self.classname == "monster_army") + return SoldierCheckAttack (); + if (self.classname == "monster_ogre") + return OgreCheckAttack (); + if (self.classname == "monster_shambler") + return ShamCheckAttack (); + if (self.classname == "monster_demon1") + return DemonCheckAttack (); + if (self.classname == "monster_dog") + return DogCheckAttack (); + if (self.classname == "monster_wizard") + return WizardCheckAttack (); + return CheckAttack (); +}; + + +/* +============= +ai_run_melee + +Turn and close until within an angle to launch a melee attack +============= +*/ +void() ai_run_melee = +{ + self.ideal_yaw = enemy_yaw; + ChangeYaw (); + + if (FacingIdeal()) + { + self.th_melee (); + self.attack_state = AS_STRAIGHT; + } +}; + + +/* +============= +ai_run_missile + +Turn in place until within an angle to launch a missile attack +============= +*/ +void() ai_run_missile = +{ + self.ideal_yaw = enemy_yaw; + ChangeYaw (); + if (FacingIdeal()) + { + self.th_missile (); + self.attack_state = AS_STRAIGHT; + } +}; + + +/* +============= +ai_run_slide + +Strafe sideways, but stay at aproximately the same range +============= +*/ +void() ai_run_slide = +{ + local float ofs; + + self.ideal_yaw = enemy_yaw; + ChangeYaw (); + if (self.lefty) + ofs = 90; + else + ofs = -90; + + if (walkmove (self.ideal_yaw + ofs, movedist)) + return; + + self.lefty = 1 - self.lefty; + + walkmove (self.ideal_yaw - ofs, movedist); +}; + + +/* +============= +ai_run + +The monster has an enemy it is trying to kill +============= +*/ +void(float dist) ai_run = +{ + + movedist = dist; +// see if the enemy is dead + if (self.enemy.health <= 0) + { + self.enemy = world; + // FIXME: look all around for other targets + if (self.oldenemy.health > 0) + { + self.enemy = self.oldenemy; + HuntTarget (); + } + else + { + if (self.movetarget) + self.th_walk (); + else + self.th_stand (); + return; + } + } + + self.show_hostile = time + 1; // wake up other monsters + +// check knowledge of enemy + enemy_vis = visible(self.enemy); + if (enemy_vis) + self.search_time = time + 5; + +// look for other coop players + if (coop && self.search_time < time) + { + if (FindTarget ()) + return; + } + + enemy_infront = infront(self.enemy); + enemy_range = range(self.enemy); + enemy_yaw = vectoyaw(self.enemy.origin - self.origin); + + if (self.attack_state == AS_MISSILE) + { +//dprint ("ai_run_missile\n"); + ai_run_missile (); + return; + } + if (self.attack_state == AS_MELEE) + { +//dprint ("ai_run_melee\n"); + ai_run_melee (); + return; + } + + if (CheckAnyAttack ()) + return; // beginning an attack + + if (self.attack_state == AS_SLIDING) + { + ai_run_slide (); + return; + } + +// head straight in + movetogoal (dist); // done in C code... +}; + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/amtest.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/amtest.qc new file mode 100755 index 00000000..97f95928 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/amtest.qc @@ -0,0 +1,85 @@ +/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~> +~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/ + +void() test_teleport_touch; +void() tele_done; + +/*QUAKED test_teleport (0 .5 .8) ? +Teleporter testing +*/ +void() test_teleport = +{ + precache_model ("sprites/s_aball.spr"); + setsize (self, self.mins, self.maxs); + self.touch = test_teleport_touch; + self.solid = 1; + + if (!self.target) + objerror ("no target\n"); +}; + +void() test_teleport_touch = +{ +local entity oldself; + other.movetype = MOVETYPE_TOSS; +// other.solid = SOLID_NOT; + other.dest = '256 -128 -128'; + oldself = self; + self = other; +// SUB_CalcMove (self.dest, 200, tele_done); + self.velocity = '1000 0 0 '; + self = oldself; +}; + +void() tele_done = +{ + self.movetype = MOVETYPE_WALK; + self.solid = SOLID_SLIDEBOX; +}; + +/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~> +~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/ + +void() test_goaway; +void() test_spawn; + +/*QUAKED test_fodder (0 .5 .8) ? +beating guy +*/ +void() test_fodder = +{ + self.nextthink = time + 3; + self.think = test_spawn; +}; + +void() test_spawn = +{ +local entity body; + makevectors (self.angles); + + body = spawn(); + setmodel (body, "progs/soldier.mdl"); + setorigin (body, self.origin); + body.classname = "player"; + body.health = 1000; + body.frags = 0; + body.takedamage = DAMAGE_AIM; + body.solid = SOLID_SLIDEBOX; + body.movetype = MOVETYPE_WALK; + body.show_hostile = 0; + body.weapon = 1; + body.velocity = v_forward * 200; + + body.nextthink = time + 5; + body.think = test_goaway; + +self.nextthink = time + 3; +self.think = test_spawn; + +}; + +void() test_goaway = +{ + remove (self); +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/boss.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/boss.qc new file mode 100755 index 00000000..949de52d --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/boss.qc @@ -0,0 +1,385 @@ +/* +============================================================================== + +BOSS-ONE + +============================================================================== +*/ +$cd id1/models/boss1 +$origin 0 0 -15 +$base base +$skin skin +$scale 5 + +$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9 rise10 +$frame rise11 rise12 rise13 rise14 rise15 rise16 rise17 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 +$frame walk9 walk10 walk11 walk12 walk13 walk14 walk15 +$frame walk16 walk17 walk18 walk19 walk20 walk21 walk22 +$frame walk23 walk24 walk25 walk26 walk27 walk28 walk29 walk30 walk31 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 + +$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 +$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15 +$frame attack16 attack17 attack18 attack19 attack20 attack21 attack22 +$frame attack23 + +$frame shocka1 shocka2 shocka3 shocka4 shocka5 shocka6 shocka7 shocka8 +$frame shocka9 shocka10 + +$frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6 + +$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8 +$frame shockc9 shockc10 + + +void(vector p) boss_missile; + +void() boss_face = +{ + +// go for another player if multi player + if (self.enemy.health <= 0 || random() < 0.02) + { + self.enemy = find(self.enemy, classname, "player"); + if (!self.enemy) + self.enemy = find(self.enemy, classname, "player"); + } + ai_face(); +}; + +void() boss_rise1 =[ $rise1, boss_rise2 ] { +sound (self, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM); +}; +void() boss_rise2 =[ $rise2, boss_rise3 ] { +sound (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM); +}; +void() boss_rise3 =[ $rise3, boss_rise4 ] {}; +void() boss_rise4 =[ $rise4, boss_rise5 ] {}; +void() boss_rise5 =[ $rise5, boss_rise6 ] {}; +void() boss_rise6 =[ $rise6, boss_rise7 ] {}; +void() boss_rise7 =[ $rise7, boss_rise8 ] {}; +void() boss_rise8 =[ $rise8, boss_rise9 ] {}; +void() boss_rise9 =[ $rise9, boss_rise10 ] {}; +void() boss_rise10 =[ $rise10, boss_rise11 ] {}; +void() boss_rise11 =[ $rise11, boss_rise12 ] {}; +void() boss_rise12 =[ $rise12, boss_rise13 ] {}; +void() boss_rise13 =[ $rise13, boss_rise14 ] {}; +void() boss_rise14 =[ $rise14, boss_rise15 ] {}; +void() boss_rise15 =[ $rise15, boss_rise16 ] {}; +void() boss_rise16 =[ $rise16, boss_rise17 ] {}; +void() boss_rise17 =[ $rise17, boss_missile1 ] {}; + +void() boss_idle1 =[ $walk1, boss_idle2 ] +{ +// look for other players +}; +void() boss_idle2 =[ $walk2, boss_idle3 ] {boss_face();}; +void() boss_idle3 =[ $walk3, boss_idle4 ] {boss_face();}; +void() boss_idle4 =[ $walk4, boss_idle5 ] {boss_face();}; +void() boss_idle5 =[ $walk5, boss_idle6 ] {boss_face();}; +void() boss_idle6 =[ $walk6, boss_idle7 ] {boss_face();}; +void() boss_idle7 =[ $walk7, boss_idle8 ] {boss_face();}; +void() boss_idle8 =[ $walk8, boss_idle9 ] {boss_face();}; +void() boss_idle9 =[ $walk9, boss_idle10 ] {boss_face();}; +void() boss_idle10 =[ $walk10, boss_idle11 ] {boss_face();}; +void() boss_idle11 =[ $walk11, boss_idle12 ] {boss_face();}; +void() boss_idle12 =[ $walk12, boss_idle13 ] {boss_face();}; +void() boss_idle13 =[ $walk13, boss_idle14 ] {boss_face();}; +void() boss_idle14 =[ $walk14, boss_idle15 ] {boss_face();}; +void() boss_idle15 =[ $walk15, boss_idle16 ] {boss_face();}; +void() boss_idle16 =[ $walk16, boss_idle17 ] {boss_face();}; +void() boss_idle17 =[ $walk17, boss_idle18 ] {boss_face();}; +void() boss_idle18 =[ $walk18, boss_idle19 ] {boss_face();}; +void() boss_idle19 =[ $walk19, boss_idle20 ] {boss_face();}; +void() boss_idle20 =[ $walk20, boss_idle21 ] {boss_face();}; +void() boss_idle21 =[ $walk21, boss_idle22 ] {boss_face();}; +void() boss_idle22 =[ $walk22, boss_idle23 ] {boss_face();}; +void() boss_idle23 =[ $walk23, boss_idle24 ] {boss_face();}; +void() boss_idle24 =[ $walk24, boss_idle25 ] {boss_face();}; +void() boss_idle25 =[ $walk25, boss_idle26 ] {boss_face();}; +void() boss_idle26 =[ $walk26, boss_idle27 ] {boss_face();}; +void() boss_idle27 =[ $walk27, boss_idle28 ] {boss_face();}; +void() boss_idle28 =[ $walk28, boss_idle29 ] {boss_face();}; +void() boss_idle29 =[ $walk29, boss_idle30 ] {boss_face();}; +void() boss_idle30 =[ $walk30, boss_idle31 ] {boss_face();}; +void() boss_idle31 =[ $walk31, boss_idle1 ] {boss_face();}; + +void() boss_missile1 =[ $attack1, boss_missile2 ] {boss_face();}; +void() boss_missile2 =[ $attack2, boss_missile3 ] {boss_face();}; +void() boss_missile3 =[ $attack3, boss_missile4 ] {boss_face();}; +void() boss_missile4 =[ $attack4, boss_missile5 ] {boss_face();}; +void() boss_missile5 =[ $attack5, boss_missile6 ] {boss_face();}; +void() boss_missile6 =[ $attack6, boss_missile7 ] {boss_face();}; +void() boss_missile7 =[ $attack7, boss_missile8 ] {boss_face();}; +void() boss_missile8 =[ $attack8, boss_missile9 ] {boss_face();}; +void() boss_missile9 =[ $attack9, boss_missile10 ] {boss_missile('100 100 200');}; +void() boss_missile10 =[ $attack10, boss_missile11 ] {boss_face();}; +void() boss_missile11 =[ $attack11, boss_missile12 ] {boss_face();}; +void() boss_missile12 =[ $attack12, boss_missile13 ] {boss_face();}; +void() boss_missile13 =[ $attack13, boss_missile14 ] {boss_face();}; +void() boss_missile14 =[ $attack14, boss_missile15 ] {boss_face();}; +void() boss_missile15 =[ $attack15, boss_missile16 ] {boss_face();}; +void() boss_missile16 =[ $attack16, boss_missile17 ] {boss_face();}; +void() boss_missile17 =[ $attack17, boss_missile18 ] {boss_face();}; +void() boss_missile18 =[ $attack18, boss_missile19 ] {boss_face();}; +void() boss_missile19 =[ $attack19, boss_missile20 ] {boss_face();}; +void() boss_missile20 =[ $attack20, boss_missile21 ] {boss_missile('100 -100 200');}; +void() boss_missile21 =[ $attack21, boss_missile22 ] {boss_face();}; +void() boss_missile22 =[ $attack22, boss_missile23 ] {boss_face();}; +void() boss_missile23 =[ $attack23, boss_missile1 ] {boss_face();}; + +void() boss_shocka1 =[ $shocka1, boss_shocka2 ] {}; +void() boss_shocka2 =[ $shocka2, boss_shocka3 ] {}; +void() boss_shocka3 =[ $shocka3, boss_shocka4 ] {}; +void() boss_shocka4 =[ $shocka4, boss_shocka5 ] {}; +void() boss_shocka5 =[ $shocka5, boss_shocka6 ] {}; +void() boss_shocka6 =[ $shocka6, boss_shocka7 ] {}; +void() boss_shocka7 =[ $shocka7, boss_shocka8 ] {}; +void() boss_shocka8 =[ $shocka8, boss_shocka9 ] {}; +void() boss_shocka9 =[ $shocka9, boss_shocka10 ] {}; +void() boss_shocka10 =[ $shocka10, boss_missile1 ] {}; + +void() boss_shockb1 =[ $shockb1, boss_shockb2 ] {}; +void() boss_shockb2 =[ $shockb2, boss_shockb3 ] {}; +void() boss_shockb3 =[ $shockb3, boss_shockb4 ] {}; +void() boss_shockb4 =[ $shockb4, boss_shockb5 ] {}; +void() boss_shockb5 =[ $shockb5, boss_shockb6 ] {}; +void() boss_shockb6 =[ $shockb6, boss_shockb7 ] {}; +void() boss_shockb7 =[ $shockb1, boss_shockb8 ] {}; +void() boss_shockb8 =[ $shockb2, boss_shockb9 ] {}; +void() boss_shockb9 =[ $shockb3, boss_shockb10 ] {}; +void() boss_shockb10 =[ $shockb4, boss_missile1 ] {}; + +void() boss_shockc1 =[ $shockc1, boss_shockc2 ] {}; +void() boss_shockc2 =[ $shockc2, boss_shockc3 ] {}; +void() boss_shockc3 =[ $shockc3, boss_shockc4 ] {}; +void() boss_shockc4 =[ $shockc4, boss_shockc5 ] {}; +void() boss_shockc5 =[ $shockc5, boss_shockc6 ] {}; +void() boss_shockc6 =[ $shockc6, boss_shockc7 ] {}; +void() boss_shockc7 =[ $shockc7, boss_shockc8 ] {}; +void() boss_shockc8 =[ $shockc8, boss_shockc9 ] {}; +void() boss_shockc9 =[ $shockc9, boss_shockc10 ] {}; +void() boss_shockc10 =[ $shockc10, boss_death1 ] {}; + +void() boss_death1 = [$death1, boss_death2] { +sound (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM); +}; +void() boss_death2 = [$death2, boss_death3] {}; +void() boss_death3 = [$death3, boss_death4] {}; +void() boss_death4 = [$death4, boss_death5] {}; +void() boss_death5 = [$death5, boss_death6] {}; +void() boss_death6 = [$death6, boss_death7] {}; +void() boss_death7 = [$death7, boss_death8] {}; +void() boss_death8 = [$death8, boss_death9] {}; +void() boss_death9 = [$death9, boss_death10] +{ + sound (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM); + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_LAVASPLASH); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); +}; + +void() boss_death10 = [$death9, boss_death10] +{ + killed_monsters = killed_monsters + 1; + WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast + SUB_UseTargets (); + remove (self); +}; + +void(vector p) boss_missile = +{ + local vector offang; + local vector org, vec, d; + local float t; + + offang = vectoangles (self.enemy.origin - self.origin); + makevectors (offang); + + org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1'; + +// lead the player on hard mode + if (skill > 1) + { + t = vlen(self.enemy.origin - org) / 300; + vec = self.enemy.velocity; + vec_z = 0; + d = self.enemy.origin + t * vec; + } + else + { + d = self.enemy.origin; + } + + vec = normalize (d - org); + + launch_spike (org, vec); + setmodel (newmis, "progs/lavaball.mdl"); + newmis.avelocity = '200 100 300'; + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + newmis.velocity = vec*300; + newmis.touch = T_MissileTouch; // rocket explosion + sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM); + +// check for dead enemy + if (self.enemy.health <= 0) + boss_idle1 (); +}; + + +void() boss_awake = +{ + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + self.takedamage = DAMAGE_NO; + + setmodel (self, "progs/boss.mdl"); + setsize (self, '-128 -128 -24', '128 128 256'); + + if (skill == 0) + self.health = 1; + else + self.health = 3; + + self.enemy = activator; + + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_LAVASPLASH); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); + + self.yaw_speed = 20; + boss_rise1 (); +}; + + +/*QUAKED monster_boss (1 0 0) (-128 -128 -24) (128 128 256) +*/ +void() monster_boss = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/boss.mdl"); + precache_model ("progs/lavaball.mdl"); + + precache_sound ("weapons/rocket1i.wav"); + precache_sound ("boss1/out1.wav"); + precache_sound ("boss1/sight1.wav"); + precache_sound ("misc/power.wav"); + precache_sound ("boss1/throw.wav"); + precache_sound ("boss1/pain.wav"); + precache_sound ("boss1/death.wav"); + + total_monsters = total_monsters + 1; + + self.use = boss_awake; +}; + +//=========================================================================== + +entity le1, le2; +float lightning_end; + +void() lightning_fire = +{ + local vector p1, p2; + + if (time >= lightning_end) + { // done here, put the terminals back up + self = le1; + door_go_down (); + self = le2; + door_go_down (); + return; + } + + p1 = (le1.mins + le1.maxs) * 0.5; + p1_z = le1.absmin_z - 16; + + p2 = (le2.mins + le2.maxs) * 0.5; + p2_z = le2.absmin_z - 16; + + // compensate for length of bolt + p2 = p2 - normalize(p2-p1)*100; + + self.nextthink = time + 0.1; + self.think = lightning_fire; + + WriteByte (MSG_ALL, SVC_TEMPENTITY); + WriteByte (MSG_ALL, TE_LIGHTNING3); + WriteEntity (MSG_ALL, world); + WriteCoord (MSG_ALL, p1_x); + WriteCoord (MSG_ALL, p1_y); + WriteCoord (MSG_ALL, p1_z); + WriteCoord (MSG_ALL, p2_x); + WriteCoord (MSG_ALL, p2_y); + WriteCoord (MSG_ALL, p2_z); +}; + +void() lightning_use = +{ + if (lightning_end >= time + 1) + return; + + le1 = find( world, target, "lightning"); + le2 = find( le1, target, "lightning"); + if (!le1 || !le2) + { + dprint ("missing lightning targets\n"); + return; + } + + if ( + (le1.state != STATE_TOP && le1.state != STATE_BOTTOM) + || (le2.state != STATE_TOP && le2.state != STATE_BOTTOM) + || (le1.state != le2.state) ) + { +// dprint ("not aligned\n"); + return; + } + +// don't let the electrodes go back up until the bolt is done + le1.nextthink = -1; + le2.nextthink = -1; + lightning_end = time + 1; + + sound (self, CHAN_VOICE, "misc/power.wav", 1, ATTN_NORM); + lightning_fire (); + +// advance the boss pain if down + self = find (world, classname, "monster_boss"); + if (!self) + return; + self.enemy = activator; + if (le1.state == STATE_TOP && self.health > 0) + { + sound (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM); + self.health = self.health - 1; + if (self.health >= 2) + boss_shocka1(); + else if (self.health == 1) + boss_shockb1(); + else if (self.health == 0) + boss_shockc1(); + } +}; + + +/*QUAKED event_lightning (0 1 1) (-16 -16 -16) (16 16 16) +Just for boss level. +*/ +void() event_lightning = +{ + self.use = lightning_use; +}; + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/buttons.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/buttons.qc new file mode 100755 index 00000000..695115b0 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/buttons.qc @@ -0,0 +1,139 @@ +// button and multiple button + +void() button_wait; +void() button_return; + +void() button_wait = +{ + self.state = STATE_TOP; + self.nextthink = self.ltime + self.wait; + self.think = button_return; + activator = self.enemy; + SUB_UseTargets(); + self.frame = 1; // use alternate textures +}; + +void() button_done = +{ + self.state = STATE_BOTTOM; +}; + +void() button_return = +{ + self.state = STATE_DOWN; + SUB_CalcMove (self.pos1, self.speed, button_done); + self.frame = 0; // use normal textures + if (self.health) + self.takedamage = DAMAGE_YES; // can be shot again +}; + + +void() button_blocked = +{ // do nothing, just don't ome all the way back out +}; + + +void() button_fire = +{ + if (self.state == STATE_UP || self.state == STATE_TOP) + return; + + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + + self.state = STATE_UP; + SUB_CalcMove (self.pos2, self.speed, button_wait); +}; + + +void() button_use = +{ + self.enemy = activator; + button_fire (); +}; + +void() button_touch = +{ + if (other.classname != "player") + return; + self.enemy = other; + button_fire (); +}; + +void() button_killed = +{ + self.enemy = damage_attacker; + self.health = self.max_health; + self.takedamage = DAMAGE_NO; // wil be reset upon return + button_fire (); +}; + + +/*QUAKED func_button (0 .5 .8) ? +When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again. + +"angle" determines the opening direction +"target" all entities with a matching targetname will be used +"speed" override the default 40 speed +"wait" override the default 1 second wait (-1 = never return) +"lip" override the default 4 pixel lip remaining at end of move +"health" if set, the button must be killed instead of touched +"sounds" +0) steam metal +1) wooden clunk +2) metallic click +3) in-out +*/ +void() func_button = +{ + if (self.sounds == 0) + { + precache_sound ("buttons/airbut1.wav"); + self.noise = "buttons/airbut1.wav"; + } + if (self.sounds == 1) + { + precache_sound ("buttons/switch21.wav"); + self.noise = "buttons/switch21.wav"; + } + if (self.sounds == 2) + { + precache_sound ("buttons/switch02.wav"); + self.noise = "buttons/switch02.wav"; + } + if (self.sounds == 3) + { + precache_sound ("buttons/switch04.wav"); + self.noise = "buttons/switch04.wav"; + } + + SetMovedir (); + + self.movetype = MOVETYPE_PUSH; + self.solid = SOLID_BSP; + setmodel (self, self.model); + + self.blocked = button_blocked; + self.use = button_use; + + if (self.health) + { + self.max_health = self.health; + self.th_die = button_killed; + self.takedamage = DAMAGE_YES; + } + else + self.touch = button_touch; + + if (!self.speed) + self.speed = 40; + if (!self.wait) + self.wait = 1; + if (!self.lip) + self.lip = 4; + + self.state = STATE_BOTTOM; + + self.pos1 = self.origin; + self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip); +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/ccam.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/ccam.qc new file mode 100755 index 00000000..b85cfde0 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/ccam.qc @@ -0,0 +1,83 @@ +void () CCam; + + void () CCamChasePlayer = + { + makevectors (self.v_angle); + traceline ((self.origin + self.view_ofs),((((self.origin + self.view_ofs) + + (v_forward * self.camview_z)) + (v_up * self.camview_x)) + (v_right * self.camview_y)),FALSE,self); + setorigin (self.trigger_field,trace_endpos); + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE,self.trigger_field); + self.weaponmodel = ""; + }; + + void () CCam = + { + local entity camera; + local entity spot; + + if (self.health <= BROKENITEMS) + return; + if (self.aflag == FALSE) + { + self.cam = 1; + self.aflag = TRUE; + camera = spawn (); + spot = spawn (); + self.trigger_field = camera; + camera.classname = "camera"; + camera.movetype = MOVETYPE_FLY; + camera.solid = SOLID_NOT; + setmodel (camera,"progs/eyes.mdl"); + setsize (camera,'0 0 0','0 0 0'); + makevectors (self.v_angle); + traceline ((self.origin + self.view_ofs),(((self.origin + self.view_ofs) + + (v_forward * -64.000))),FALSE,self); + self.camview = '0 0 -64'; // added + setorigin (camera,trace_endpos); + camera.angles = self.angles; + self.weaponmodel = ""; + msg_entity = self; + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE,camera); + WriteByte (MSG_ONE,10.000); + WriteAngle (MSG_ONE,camera.angles_x); + WriteAngle (MSG_ONE,camera.angles_y); + WriteAngle (MSG_ONE,camera.angles_z); + self.avelocity = '300 300 300'; + self.currentammo = self.mbombs; + self.boostlives = 1; + self.mbombs = 3; + self.mball = 1; + self.view_ofs = '0 0 8'; + setsize (self, '-12 -12 -40', '12 12 7'); + } + else + { + //if (self.laid == LAYED) + //return; + self.cam = 0; + self.aflag = FALSE; + msg_entity = self; + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE,self); + WriteByte (MSG_ONE,10); + WriteAngle (MSG_ONE,self.angles_x); + WriteAngle (MSG_ONE,self.angles_y); + WriteAngle (MSG_ONE,self.angles_z); + remove (self.trigger_field); + if (self.health <= BROKENITEMS) //For the Suit charging.(25 health) + {} + else + { + //self.weapon = IT_BLASTER; + W_SetCurrentAmmo (); + self.origin = self.origin + v_up * 30; //Solves the Spawning in the Ground Problem + } + self.mball = 0; + self.view_ofs = '0 0 22'; + setsize (self, '-16 -16 -24', '16 16 32'); + self.weapon = IT_BLASTER; + W_SetCurrentAmmo (); + } + } \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/client.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/client.qc new file mode 100755 index 00000000..7cb4a637 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/client.qc @@ -0,0 +1,1510 @@ + +// prototypes +void () W_WeaponFrame; +void() W_SetCurrentAmmo; +void() player_pain; +void() player_stand1; +void (vector org) spawn_tfog; +void (vector org, entity death_owner) spawn_tdeath; + +float modelindex_eyes, modelindex_mball, modelindex_player; + +/* +============================================================================= + + LEVEL CHANGING / INTERMISSION + +============================================================================= +*/ + +float intermission_running; +float intermission_exittime; + +/*QUAKED info_intermission (1 0.5 0.5) (-16 -16 -16) (16 16 16) +This is the camera point for the intermission. +Use mangle instead of angle, so you can set pitch or roll as well as yaw. 'pitch roll yaw' +*/ +void() info_intermission = +{ +}; + + + +void() SetChangeParms = +{ + if (self.health <= 0) + { + SetNewParms (); + return; + } + +// remove items + self.items = self.items - (self.items & + (IT_KEY1 | IT_KEY2 | IT_INVISIBILITY | IT_INVULNERABILITY | IT_SUIT | IT_QUAD) ); + +// cap super health + if (self.health > 100) + self.health = 100; + if (self.health < 50) + self.health = 50; + parm1 = self.items; + parm2 = self.health; + parm3 = self.armorvalue; + if (self.ammo_shells < 25) + parm4 = 25; + else + parm4 = self.ammo_blaster; + parm5 = self.ammo_sniper; + parm6 = self.ammo_rockets; + parm7 = self.ammo_nails; + parm8 = self.weapon; + parm9 = self.armortype * 100; + parm10 = self.energy; +}; + +void() SetNewParms = +{ + parm1 = IT_BLASTER | IT_MORPHBALL; + parm2 = 99; + parm3 = 0; + parm4 = 100; + parm5 = 1; + parm6 = 0; + parm7 = 0; + parm8 = 1; + parm9 = 0; + if (deathmatch) + parm10 = 1; + else + parm10 = 0; +}; + +void() DecodeLevelParms = +{ + if (serverflags) + { + if (world.model == "maps/start.bsp") + SetNewParms (); // take away all stuff on starting new episode + } + + self.items = parm1; + self.health = parm2; + self.armorvalue = parm3; + self.ammo_blaster = parm4; + self.ammo_sniper = parm5; + self.ammo_rockets = parm6; + self.ammo_nails = parm7; + self.weapon = parm8; + self.armortype = parm9 * 0.01; + self.energy = parm10; +}; + +/* +============ +FindIntermission + +Returns the entity to view from +============ +*/ +entity() FindIntermission = +{ + local entity spot; + local float cyc; + +// look for info_intermission first + spot = find (world, classname, "info_intermission"); + if (spot) + { // pick a random one + cyc = random() * 4; + while (cyc > 1) + { + spot = find (spot, classname, "info_intermission"); + if (!spot) + spot = find (spot, classname, "info_intermission"); + cyc = cyc - 1; + } + return spot; + } + +// then look for the start position + spot = find (world, classname, "info_player_start"); + if (spot) + return spot; + +// testinfo_player_start is only found in regioned levels + spot = find (world, classname, "testplayerstart"); + if (spot) + return spot; + + objerror ("FindIntermission: no spot"); +}; + + +string nextmap; +void() GotoNextMap = +{ + if (cvar("samelevel")) // if samelevel is set, stay on same level + changelevel (mapname); + else + changelevel (nextmap); +}; + + +void() ExitIntermission = +{ +// skip any text in deathmatch + if (deathmatch) + { + GotoNextMap (); + return; + } + + intermission_exittime = time + 1; + intermission_running = intermission_running + 1; + +// +// run some text if at the end of an episode +// + if (intermission_running == 2) + { + if (world.model == "maps/e1m7.bsp") + { + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 2); + WriteByte (MSG_ALL, 3); + if (!cvar("registered")) + { + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task in the other three\nhaunted lands of Quake. Or are you? If\nyou don't register Quake, you'll never\nknow what awaits you in the Realm of\nBlack Magic, the Netherworld, and the\nElder World!"); + } + else + { + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task. A Rune of magic\npower lies at the end of each haunted\nland of Quake. Go forth, seek the\ntotality of the four Runes!"); + } + return; + } + else if (world.model == "maps/e2m6.bsp") + { + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 2); + WriteByte (MSG_ALL, 3); + + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "The Rune of Black Magic throbs evilly in\nyour hand and whispers dark thoughts\ninto your brain. You learn the inmost\nlore of the Hell-Mother; Shub-Niggurath!\nYou now know that she is behind all the\nterrible plotting which has led to so\nmuch death and horror. But she is not\ninviolate! Armed with this Rune, you\nrealize that once all four Runes are\ncombined, the gate to Shub-Niggurath's\nPit will open, and you can face the\nWitch-Goddess herself in her frightful\notherworld cathedral."); + return; + } + else if (world.model == "maps/e3m6.bsp") + { + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 2); + WriteByte (MSG_ALL, 3); + + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "The charred viscera of diabolic horrors\nbubble viscously as you seize the Rune\nof Hell Magic. Its heat scorches your\nhand, and its terrible secrets blight\nyour mind. Gathering the shreds of your\ncourage, you shake the devil's shackles\nfrom your soul, and become ever more\nhard and determined to destroy the\nhideous creatures whose mere existence\nthreatens the souls and psyches of all\nthe population of Earth."); + return; + } + else if (world.model == "maps/e4m7.bsp") + { + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 2); + WriteByte (MSG_ALL, 3); + + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "Despite the awful might of the Elder\nWorld, you have achieved the Rune of\nElder Magic, capstone of all types of\narcane wisdom. Beyond good and evil,\nbeyond life and death, the Rune\npulsates, heavy with import. Patient and\npotent, the Elder Being Shub-Niggurath\nweaves her dire plans to clear off all\nlife from the Earth, and bring her own\nfoul offspring to our world! For all the\ndwellers in these nightmare dimensions\nare her descendants! Once all Runes of\nmagic power are united, the energy\nbehind them will blast open the Gateway\nto Shub-Niggurath, and you can travel\nthere to foil the Hell-Mother's plots\nin person."); + return; + } + + GotoNextMap(); + } + + if (intermission_running == 3) + { + if (!cvar("registered")) + { // shareware episode has been completed, go to sell screen + WriteByte (MSG_ALL, SVC_SELLSCREEN); + return; + } + + if ( (serverflags&15) == 15) + { + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "Now, you have all four Runes. You sense\ntremendous invisible forces moving to\nunseal ancient barriers. Shub-Niggurath\nhad hoped to use the Runes Herself to\nclear off the Earth, but now instead,\nyou will use them to enter her home and\nconfront her as an avatar of avenging\nEarth-life. If you defeat her, you will\nbe remembered forever as the savior of\nthe planet. If she conquers, it will be\nas if you had never been born."); + return; + } + + } + + GotoNextMap(); +}; + +/* +============ +IntermissionThink + +When the player presses attack or jump, change to the next level +============ +*/ +void() IntermissionThink = +{ + if (time < intermission_exittime) + return; + + if (!self.button0 && !self.button1 && !self.button2) + return; + + ExitIntermission (); +}; + +void() execute_changelevel = +{ + local entity pos; + + intermission_running = 1; + +// enforce a wait time before allowing changelevel + if (deathmatch) + intermission_exittime = time + 5; + else + intermission_exittime = time + 2; + + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 3); + WriteByte (MSG_ALL, 3); + + pos = FindIntermission (); + + other = find (world, classname, "player"); + while (other != world) + { + other.view_ofs = '0 0 0'; + other.angles = other.v_angle = pos.mangle; + other.fixangle = TRUE; // turn this way immediately + other.nextthink = time + 0.5; + other.takedamage = DAMAGE_NO; + other.solid = SOLID_NOT; + other.movetype = MOVETYPE_NONE; + other.modelindex = 0; + setorigin (other, pos.origin); + other = find (other, classname, "player"); + } + + WriteByte (MSG_ALL, SVC_INTERMISSION); +}; + + +void() changelevel_touch = +{ + + if (other.classname != "player") + return; + + if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start"))) + { + T_Damage (other, self, self, 50000); + return; + } + + if (coop || deathmatch) + { + bprint (other.netname); + bprint (" exited the level\n"); + } + + nextmap = self.map; + + SUB_UseTargets (); + + if ( (self.spawnflags & 1) && (deathmatch == 0) ) + { // NO_INTERMISSION + GotoNextMap(); + return; + } + + self.touch = SUB_Null; + +// we can't move people right now, because touch functions are called +// in the middle of C movement code, so set a think time to do it + self.think = execute_changelevel; + self.nextthink = time + 0.1; +}; + +/*QUAKED trigger_changelevel (0.5 0.5 0.5) ? NO_INTERMISSION +When the player touches this, he gets sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats. +*/ +void() trigger_changelevel = +{ + if (!self.map) + objerror ("chagnelevel trigger doesn't have map"); + + InitTrigger (); + self.touch = changelevel_touch; +}; + + +/* +============================================================================= + + PLAYER GAME EDGE FUNCTIONS + +============================================================================= +*/ + +void() set_suicide_frame; + +// called by ClientKill and DeadThink +void() respawn = +{ + if (coop) + { + // get the spawn parms as they were at level start + setspawnparms (self); + // respawn + PutClientInServer (); + } + else if (deathmatch) + { + // set default spawn parms + SetNewParms (); + // respawn + PutClientInServer (); + } + else + { // restart the entire server + localcmd ("restart\n"); + } +}; + + +/* +============ +ClientKill + +Player entered the suicide command +============ +*/ +void() ClientKill = +{ + bprint (self.netname); + bprint (" suicides\n"); + set_suicide_frame (); + self.modelindex = modelindex_player; + self.frags = self.frags - 2; // extra penalty + respawn (); +}; + +float(vector v) CheckSpawnPoint = +{ + return FALSE; +}; + +/* +============ +SelectSpawnPoint + +Returns the entity to spawn at +============ +*/ +entity() SelectSpawnPoint = +{ + local entity spot; + local entity thing; + local float pcount; + +// testinfo_player_start is only found in regioned levels + spot = find (world, classname, "testplayerstart"); + if (spot) + return spot; + +// choose a info_player_deathmatch point + if (coop) + { + lastspawn = find(lastspawn, classname, "info_player_coop"); + if (lastspawn == world) + lastspawn = find (lastspawn, classname, "info_player_start"); + if (lastspawn != world) + return lastspawn; + } + else if (deathmatch) + { + spot = lastspawn; + while (1) + { + spot = find(spot, classname, "info_player_deathmatch"); + if (spot != world) + { + if (spot == lastspawn) + return lastspawn; + pcount = 0; + thing = findradius(spot.origin, 32); + while(thing) + { + if (thing.classname == "player") + pcount = pcount + 1; + thing = thing.chain; + } + if (pcount == 0) + { + lastspawn = spot; + return spot; + } + } + } + } + + if (serverflags) + { // return with a rune to start + spot = find (world, classname, "info_player_start2"); + if (spot) + return spot; + } + + spot = find (world, classname, "info_player_start"); + if (!spot) + error ("PutClientInServer: no info_player_start on level"); + + return spot; +}; + +/* +=========== +PutClientInServer + +called each time a player is spawned +============ +*/ +void() DecodeLevelParms; +void() PlayerDie; + + +void() PutClientInServer = +{ + + local entity spot; + + spot = SelectSpawnPoint (); + self.currentammo = self.ammo_rockets = 10; + self.classname = "player"; + self.health = self.max_health; + self.takedamage = DAMAGE_AIM; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_WALK; + self.show_hostile = 0; + if (!deathmatch) + { + if (self.energy == 0) + self.max_health = 99; + if (self.energy == 1) + self.max_health = 199; + if (self.energy == 2) + self.max_health = 299; + if (self.energy == 3) + self.max_health = 399; + if (self.energy == 4) + self.max_health = 499; + if (self.energy == 5) + self.max_health = 599; + if (self.energy == 6) + self.max_health = 699; + if (self.energy == 7) + self.max_health = 799; + if (self.energy == 8) + self.max_health = 899; + if (self.energy == 9) + self.max_health = 999; + } + else + self.max_health = 199; + self.flags = FL_CLIENT; + self.air_finished = time + 12; + self.dmg = 2; // initial water damage + self.super_damage_finished = 0; + self.radsuit_finished = 0; + self.invisible_finished = 0; + self.invincible_finished = 0; + self.effects = 0; + self.invincible_time = 0; + self.doublejump_time = 0; + self.doublejump_lives = 0; + self.mballset = 0; + if (self.weapon == IT_MORPHBALL) + self.weapon = IT_BLASTER; + + DecodeLevelParms (); + + W_SetCurrentAmmo (); + + Set_FOV (FOV_DEFAULT); + self.pfov = FOV_DEFAULT; + + self.attack_finished = time; + self.th_pain = player_pain; + self.th_die = PlayerDie; + + self.deadflag = DEAD_NO; +// paustime is set by teleporters to keep the player from moving a while + self.pausetime = 0; + +// spot = SelectSpawnPoint (); + + self.origin = spot.origin + '0 0 1'; + self.angles = spot.angles; + self.fixangle = TRUE; // turn this way immediately + + stuffcmd (self, "chase_active 0"); + stuffcmd (self, "cl_mball 0"); +// oh, this is a hack! + setmodel (self, "progs/eyes.mdl"); + modelindex_eyes = self.modelindex; + + setmodel (self, "progs/player.mdl"); + modelindex_player = self.modelindex; + + setmodel (self,"progs/mball.mdl"); + modelindex_mball = self.modelindex; + + setsize (self, VEC_HULL_MIN, VEC_HULL_MAX); + + self.view_ofs = '0 0 22'; + + player_stand1 (); + + + if (deathmatch || coop) + { + makevectors(self.angles); + spawn_tfog (self.origin + v_forward*20); + } + //self.doublejump_time = 0; + //self.doublejump_lives = 0; + spawn_tdeath (self.origin, self); +}; + + +/* +============================================================================= + + QUAKED FUNCTIONS + +============================================================================= +*/ + + +/*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 24) +The normal starting point for a level. +*/ +void() info_player_start = +{ +}; + + +/*QUAKED info_player_start2 (1 0 0) (-16 -16 -24) (16 16 24) +Only used on start map for the return point from an episode. +*/ +void() info_player_start2 = +{ +}; + + +/* +saved out by quaked in region mode +*/ +void() testplayerstart = +{ +}; + +/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 24) +potential spawning position for deathmatch games +*/ +void() info_player_deathmatch = +{ +}; + +/*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24) +potential spawning position for coop games +*/ +void() info_player_coop = +{ +}; + +/* +=============================================================================== + +RULES + +=============================================================================== +*/ + +/* +go to the next level for deathmatch +only called if a time or frag limit has expired +*/ +void() NextLevel = +{ + local entity o; + + if (mapname == "start") + { + if (!cvar("registered")) + { + mapname = "e1m1"; + } + else if (!(serverflags & 1)) + { + mapname = "e1m1"; + serverflags = serverflags | 1; + } + else if (!(serverflags & 2)) + { + mapname = "e2m1"; + serverflags = serverflags | 2; + } + else if (!(serverflags & 4)) + { + mapname = "e3m1"; + serverflags = serverflags | 4; + } + else if (!(serverflags & 8)) + { + mapname = "e4m1"; + serverflags = serverflags - 7; + } + + o = spawn(); + o.map = mapname; + } + else + { + // find a trigger changelevel + o = find(world, classname, "trigger_changelevel"); + + // go back to start if no trigger_changelevel + if (!o) + { + mapname = "start"; + o = spawn(); + o.map = mapname; + } + } + + nextmap = o.map; + gameover = TRUE; + + if (o.nextthink < time) + { + o.think = execute_changelevel; + o.nextthink = time + 0.1; + } +}; + +/* +============ +CheckRules + +Exit deathmatch games upon conditions +============ +*/ +void() CheckRules = +{ + local float timelimit; + local float fraglimit; + + if (gameover) // someone else quit the game already + return; + + timelimit = cvar("timelimit") * 60; + fraglimit = cvar("fraglimit"); + + if (timelimit && time >= timelimit) + { + NextLevel (); + return; + } + + if (fraglimit && self.frags >= fraglimit) + { + NextLevel (); + return; + } +}; + +//============================================================================ + +void() PlayerDeathThink = +{ + local float forward; + + if ((self.flags & FL_ONGROUND)) + { + forward = vlen (self.velocity); + forward = forward - 20; + if (forward <= 0) + self.velocity = '0 0 0'; + else + self.velocity = forward * normalize(self.velocity); + } + +// wait for all buttons released + if (self.deadflag == DEAD_DEAD) + { + if (self.button2 || self.button1 || self.button0) + return; + self.deadflag = DEAD_RESPAWNABLE; + return; + } + +// wait for any button down + if (!self.button2 && !self.button1 && !self.button0) + return; + + self.button0 = 0; + self.button1 = 0; + self.button2 = 0; + respawn(); +}; + +// modified PlayerJump: +//Thanks alot for the Double Jump code Sajt! -Mexicouger +void() PlayerJump = +{ + + if (self.flags & FL_WATERJUMP) + return; + + if (self.waterlevel >= 2) + { + if (self.watertype == CONTENT_WATER) + self.velocity_z = 100; + else if (self.watertype == CONTENT_SLIME) + self.velocity_z = 80; + else + self.velocity_z = 50; + +// play swiming sound + if (self.swim_flag < time) + { + self.swim_flag = time + 1; + if (random() < 0.5) + sound (self, CHAN_BODY, "misc/water1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_BODY, "misc/water2.wav", 1, ATTN_NORM); + } + + return; + } + + if ( !(self.flags & FL_JUMPRELEASED) ) + return; // don't pogo stick + + if (self.flags & FL_ONGROUND) + { + if (self.health <= 20) //Your suit is malfunctioned, has to recharge + self.doublejump_lives = 0; + else + self.doublejump_lives = DOUBLEJUMP_EXTRAJUMPS; + self.flags = self.flags - FL_ONGROUND; // don't stairwalk + } + else if (self.doublejump_lives > 0 && time >= self.doublejump_time && self.velocity_z > -100) + { + self.doublejump_lives = self.doublejump_lives - 1; + } + else + { + // can't jump + return; + } + + self.doublejump_time = time + DOUBLEJUMP_TIMER; + + self.flags = self.flags - (self.flags & FL_JUMPRELEASED); + + self.button2 = 0; +// player jumping sound + if (self.weapon == IT_MORPHBALL) + return; + sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM); + self.velocity_z = 350; +}; + +// no changes to PlayerPreThink + + +/* +=========== +WaterMove + +============ +*/ +.float dmgtime; + +void() WaterMove = +{ +//dprint (ftos(self.waterlevel)); + if (self.movetype == MOVETYPE_NOCLIP) + return; + if (self.health < 0) + return; + + if (!self.waterlevel) + { + if (self.flags & FL_INWATER) + { + // play leave water sound + sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM); + self.flags = self.flags - FL_INWATER; + } + return; + } + + if (self.watertype == CONTENT_LAVA) + { // do damage + if (self.dmgtime < time && self.radsuit_finished < time) + { + self.dmgtime = time + 0.25; + T_Damage (self, world, world, 1+self.waterlevel); + } + } + else if (self.watertype == CONTENT_SLIME) + { // do damage + if (self.dmgtime < time && self.radsuit_finished < time) + { + self.dmgtime = time + 1; + T_Damage (self, world, world, 4*self.waterlevel); + } + } + + if ( !(self.flags & FL_INWATER) ) + { + +// player enter water sound + + if (self.watertype == CONTENT_LAVA) + sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM); + if (self.watertype == CONTENT_WATER) + sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM); + if (self.watertype == CONTENT_SLIME) + sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM); + + self.flags = self.flags + FL_INWATER; + self.dmgtime = 0; + } + + if (! (self.flags & FL_WATERJUMP) ) + self.velocity = self.velocity - 0.8*self.waterlevel*frametime*self.velocity; +}; + +void() CheckWaterJump = +{ + local vector start, end; + +// check for a jump-out-of-water + makevectors (self.angles); + start = self.origin; + start_z = start_z + 8; + v_forward_z = 0; + normalize(v_forward); + end = start + v_forward*24; + traceline (start, end, TRUE, self); + if (trace_fraction < 1) + { // solid at waist + start_z = start_z + self.maxs_z - 8; + end = start + v_forward*24; + self.movedir = trace_plane_normal * -50; + traceline (start, end, TRUE, self); + if (trace_fraction == 1) + { // open at eye level + self.flags = self.flags | FL_WATERJUMP; + self.velocity_z = 225; + self.flags = self.flags - (self.flags & FL_JUMPRELEASED); + self.teleport_time = time + 2; // safety net + return; + } + } +}; + +/* +================ +PlayerPreThink + +Called every frame before physics are run +================ +*/ +void() PlayerPreThink = +{ + +if (BotPreFrame()) // FrikBot + return; + + if (intermission_running) + { + IntermissionThink (); // otherwise a button could be missed between + return; // the think tics + } + + if (self.view_ofs == '0 0 0') + return; // intermission or finale + + + makevectors (self.v_angle); // is this still used + + CheckRules (); + WaterMove (); + if (self.boostlives != 1) + { + if (self.boostlives >= 1) + return; + self.boostlives += 0.01; + } + + if (self.waterlevel == 2) + CheckWaterJump (); + + if (self.health < BROKENITEMS) + { + if (self.weapon == IT_MORPHBALL) + { + if (self.button0 == TRUE) + self.button0 = FALSE; + self.mballset = 0; + setorigin (self, self.origin + v_up * 20); + setsize (self, '-16 -16 -24', '16 16 32'); + stuffcmd (self, "chase_active 0"); + self.weapon = IT_BLASTER; + } + } + + + if (self.health < BROKENITEMS) + { + if (self.health > CHARGEHEALTH) //Just in case... + return; + self.health += 0.01; + } + if (self.deadflag >= DEAD_DEAD) + { + PlayerDeathThink (); + return; + } + + if (self.deadflag == DEAD_DYING) + return; // dying, so do nothing + + if (self.button2) + { + PlayerJump (); + } + else + self.flags = self.flags | FL_JUMPRELEASED; + +// teleporters can force a non-moving pause time + if (time < self.pausetime) + self.velocity = '0 0 0'; + + if(time > self.attack_finished && self.currentammo == 0 && self.weapon != IT_MORPHBALL) + { + //self.weapon = W_BestWeapon (); + W_SetCurrentAmmo (); + } +}; + + +/* +================ +CheckPowerups + +Check for turning off powerups +================ +*/ +void() CheckPowerups = +{ + if (self.health <= 0) + return; + +// invisibility + if (self.invisible_finished) + { +// sound and screen flash when items starts to run out + if (self.invisible_sound < time) + { + sound (self, CHAN_AUTO, "items/inv3.wav", 0.5, ATTN_IDLE); + self.invisible_sound = time + ((random() * 3) + 1); + } + + + if (self.invisible_finished < time + 3) + { + if (self.invisible_time == 1) + { + sprint (self, "Ring of Shadows magic is fading\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/inv2.wav", 1, ATTN_NORM); + self.invisible_time = time + 1; + } + + if (self.invisible_time < time) + { + self.invisible_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.invisible_finished < time) + { // just stopped + self.items = self.items - IT_INVISIBILITY; + self.invisible_finished = 0; + self.invisible_time = 0; + } + + // use the eyes + self.frame = 0; + self.modelindex = modelindex_eyes; + } + else + self.modelindex = modelindex_player; // don't use eyes + +// invincibility + if (self.invincible_finished) + { +// sound and screen flash when items starts to run out + if (self.invincible_finished < time + 3) + { + if (self.invincible_time == 1) + { + sprint (self, "Protection is almost burned out\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/protect2.wav", 1, ATTN_NORM); + self.invincible_time = time + 1; + } + + if (self.invincible_time < time) + { + self.invincible_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.invincible_finished < time) + { // just stopped + self.items = self.items - IT_INVULNERABILITY; + self.invincible_time = 0; + self.invincible_finished = 0; + } + if (self.invincible_finished > time) + self.effects = self.effects | EF_DIMLIGHT; + else + self.effects = self.effects - (self.effects & EF_DIMLIGHT); + } + +// super damage + if (self.super_damage_finished) + { + +// sound and screen flash when items starts to run out + + if (self.super_damage_finished < time + 3) + { + if (self.super_time == 1) + { + sprint (self, "Quad Damage is wearing off\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/damage2.wav", 1, ATTN_NORM); + self.super_time = time + 1; + } + + if (self.super_time < time) + { + self.super_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.super_damage_finished < time) + { // just stopped + self.items = self.items - IT_QUAD; + self.super_damage_finished = 0; + self.super_time = 0; + } + if (self.super_damage_finished > time) + self.effects = self.effects | EF_DIMLIGHT; + else + self.effects = self.effects - (self.effects & EF_DIMLIGHT); + } + +// suit + if (self.radsuit_finished) + { + self.air_finished = time + 12; // don't drown + +// sound and screen flash when items starts to run out + if (self.radsuit_finished < time + 3) + { + if (self.rad_time == 1) + { + sprint (self, "Air supply in Biosuit expiring\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/suit2.wav", 1, ATTN_NORM); + self.rad_time = time + 1; + } + + if (self.rad_time < time) + { + self.rad_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.radsuit_finished < time) + { // just stopped + self.items = self.items - IT_SUIT; + self.rad_time = 0; + self.radsuit_finished = 0; + } + } +//Morphball --Ghost +if (self.weapon == IT_MORPHBALL) + { + self.modelindex = modelindex_mball; + } +}; + +/* +================ +PlayerPostThink + +Called every frame after physics are run +================ +*/ +void() PlayerPostThink = +{ +if (BotPostFrame()) // FrikBot + return; + + if (self.view_ofs == '0 0 0') + return; // intermission or finale + if (self.deadflag) + return; + +// do weapon stuff + + W_WeaponFrame (); + +// check to see if player landed and play landing sound + if ((self.jump_flag < -300) && (self.flags & FL_ONGROUND) && (self.health > 0)) + { + if (self.watertype == CONTENT_WATER) + sound (self, CHAN_BODY, "player/h2ojump.wav", 1, ATTN_NORM); + else if (self.jump_flag < -650) + { + T_Damage (self, world, world, 5); + sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM); + self.deathtype = "falling"; + } + else + sound (self, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM); + + self.jump_flag = 0; + } + + if (!(self.flags & FL_ONGROUND)) + self.jump_flag = self.velocity_z; + + CheckPowerups (); +}; + + +/* +=========== +ClientConnect + +called when a player connects to a server +============ +*/ +void() ClientConnect = +{ +ClientInRankings(); // FrikBot + + bprint (self.netname); + bprint (" entered the game\n"); + +// a client connecting during an intermission can cause problems + if (intermission_running) + ExitIntermission (); +}; + + +/* +=========== +ClientDisconnect + +called when a player disconnects from a server +============ +*/ +void() ClientDisconnect = +{ +ClientDisconnected(); // FrikBot + + if (gameover) + return; + // if the level end trigger has been activated, just return + // since they aren't *really* leaving + + // let everyone else know + bprint (self.netname); + bprint (" left the game with "); + bprint (ftos(self.frags)); + bprint (" frags\n"); + sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE); + set_suicide_frame (); +}; + +/* +=========== +ClientObituary + +called when a player dies +============ +*/ +void(entity targ, entity attacker) ClientObituary = +{ + local float rnum; + local string deathstring, deathstring2; + rnum = random(); + + if (targ.classname == "player") + { + if (attacker.classname == "teledeath") + { + bprint (targ.netname); + bprint (" was telefragged by "); + bprint (attacker.owner.netname); + bprint ("\n"); + + attacker.owner.frags = attacker.owner.frags + 1; + return; + } + + if (attacker.classname == "teledeath2") + { + bprint ("Satan's power deflects "); + bprint (targ.netname); + bprint ("'s telefrag\n"); + + targ.frags = targ.frags - 1; + return; + } + + if (attacker.classname == "player") + { + if (targ == attacker) + { + // killed self + attacker.frags = attacker.frags - 1; + bprint (targ.netname); + + if (targ.weapon == 64 && targ.waterlevel > 1) + { + bprint (" discharges into the water.\n"); + return; + } + if (targ.weapon == IT_GRENADE_LAUNCHER) + bprint (" tries to put the pin back in\n"); + else + bprint (" becomes bored with life\n"); + return; + } + else if ( (teamplay == 2) && (targ.team > 0)&&(targ.team == attacker.team) ) + { + if (rnum < 0.25) + deathstring = " mows down a teammate\n"; + else if (rnum < 0.50) + deathstring = " checks his glasses\n"; + else if (rnum < 0.75) + deathstring = " gets a frag for the other team\n"; + else + deathstring = " loses another friend\n"; + bprint (attacker.netname); + bprint (deathstring); + attacker.frags = attacker.frags - 1; + return; + } + else + { + attacker.frags = attacker.frags + 1; + + rnum = attacker.weapon; + if (rnum == IT_MORPHBALL) + { + deathstring = " was ax-murdered by "; + deathstring2 = "\n"; + } + if (rnum == IT_BLASTER) + { + deathstring = " chewed on "; + deathstring2 = "'s boomstick\n"; + } + if (rnum == IT_ROCKET) + { + deathstring = " ate 2 loads of "; + deathstring2 = "'s buckshot\n"; + } + if (rnum == IT_SPLASER) + { + deathstring = " was nailed by "; + deathstring2 = "\n"; + } + if (rnum == IT_SNIPER) + { + deathstring = " was punctured by "; + deathstring2 = "\n"; + } + if (rnum == IT_GRENADE_LAUNCHER) + { + deathstring = " eats "; + deathstring2 = "'s pineapple\n"; + if (targ.health < -40) + { + deathstring = " was gibbed by "; + deathstring2 = "'s grenade\n"; + } + } + if (rnum == IT_MAGMA) + { + deathstring = " rides "; + deathstring2 = "'s rocket\n"; + if (targ.health < -40) + { + deathstring = " was gibbed by "; + deathstring2 = "'s rocket\n" ; + } + } + if (rnum == IT_LIGHTNING) + { + deathstring = " accepts "; + if (attacker.waterlevel > 1) + deathstring2 = "'s discharge\n"; + else + deathstring2 = "'s shaft\n"; + } + bprint (targ.netname); + bprint (deathstring); + bprint (attacker.netname); + bprint (deathstring2); + } + return; + } + else + { + targ.frags = targ.frags - 1; + bprint (targ.netname); + + // killed by a montser? + if (attacker.flags & FL_MONSTER) + { + if (attacker.classname == "monster_army") + bprint (" was shot by a Grunt\n"); + if (attacker.classname == "monster_demon1") + bprint (" was eviscerated by a Fiend\n"); + if (attacker.classname == "monster_dog") + bprint (" was mauled by a Rottweiler\n"); + if (attacker.classname == "monster_dragon") + bprint (" was fried by a Dragon\n"); + if (attacker.classname == "monster_enforcer") + bprint (" was blasted by an Enforcer\n"); + if (attacker.classname == "monster_fish") + bprint (" was fed to the Rotfish\n"); + if (attacker.classname == "monster_hell_knight") + bprint (" was slain by a Death Knight\n"); + if (attacker.classname == "monster_knight") + bprint (" was slashed by a Knight\n"); + if (attacker.classname == "monster_ogre") + bprint (" was destroyed by an Ogre\n"); + if (attacker.classname == "monster_oldone") + bprint (" became one with Shub-Niggurath\n"); + if (attacker.classname == "monster_shalrath") + bprint (" was exploded by a Vore\n"); + if (attacker.classname == "monster_shambler") + bprint (" was smashed by a Shambler\n"); + if (attacker.classname == "monster_tarbaby") + bprint (" was slimed by a Spawn\n"); + if (attacker.classname == "monster_vomit") + bprint (" was vomited on by a Vomitus\n"); + if (attacker.classname == "monster_wizard") + bprint (" was scragged by a Scrag\n"); + if (attacker.classname == "monster_zombie") + bprint (" joins the Zombies\n"); + + return; + } + + // tricks and traps + if (attacker.classname == "explo_box") + { + bprint (" blew up\n"); + return; + } + if (attacker.solid == SOLID_BSP && attacker != world) + { + bprint (" was squished\n"); + return; + } + if (attacker.classname == "trap_shooter" || attacker.classname == "trap_spikeshooter") + { + bprint (" was spiked\n"); + return; + } + if (attacker.classname == "fireball") + { + bprint (" ate a lavaball\n"); + return; + } + if (attacker.classname == "trigger_changelevel") + { + bprint (" tried to leave\n"); + return; + } + + // in-water deaths + rnum = targ.watertype; + if (rnum == -3) + { + if (random() < 0.5) + bprint (" sleeps with the fishes\n"); + else + bprint (" sucks it down\n"); + return; + } + else if (rnum == -4) + { + if (random() < 0.5) + bprint (" gulped a load of slime\n"); + else + bprint (" can't exist on slime alone\n"); + return; + } + else if (rnum == -5) + { + if (targ.health < -15) + { + bprint (" burst into flames\n"); + return; + } + if (random() < 0.5) + bprint (" turned into hot slag\n"); + else + bprint (" visits the Volcano God\n"); + return; + } + + // fell to their death? + if (targ.deathtype == "falling") + { + targ.deathtype = ""; + bprint (" fell to his death\n"); + return; + } + + // hell if I know; he's just dead!!! + bprint (" died\n"); + } + } +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/combat.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/combat.qc new file mode 100755 index 00000000..24f6e7cb --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/combat.qc @@ -0,0 +1,285 @@ + +void() T_MissileTouch; +void() info_player_start; +void(entity targ, entity attacker) ClientObituary; + +void() monster_death_use; + +//============================================================================ + +/* +============ +CanDamage + +Returns true if the inflictor can directly damage the target. Used for +explosions and melee attacks. +============ +*/ +float(entity targ, entity inflictor) CanDamage = +{ +// bmodels need special checking because their origin is 0,0,0 + if (targ.movetype == MOVETYPE_PUSH) + { + traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self); + if (trace_fraction == 1) + return TRUE; + if (trace_ent == targ) + return TRUE; + return FALSE; + } + + traceline(inflictor.origin, targ.origin, TRUE, self); + if (trace_fraction == 1) + return TRUE; + traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self); + if (trace_fraction == 1) + return TRUE; + traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self); + if (trace_fraction == 1) + return TRUE; + traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self); + if (trace_fraction == 1) + return TRUE; + traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self); + if (trace_fraction == 1) + return TRUE; + + return FALSE; +}; + + +/* +============ +Killed +============ +*/ +void(entity targ, entity attacker) Killed = +{ + local entity oself; + + oself = self; + self = targ; + + if (self.health < -99) + self.health = -99; // don't let sbar look bad if a player + + if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE) + { // doors, triggers, etc + self.th_die (); + self = oself; + return; + } + + self.enemy = attacker; + +// bump the monster counter + if (self.flags & FL_MONSTER) + { + killed_monsters = killed_monsters + 1; + WriteByte (MSG_ALL, SVC_KILLEDMONSTER); + } + + ClientObituary(self, attacker); + + self.takedamage = DAMAGE_NO; + self.touch = SUB_Null; + + monster_death_use(); + self.th_die (); + + self = oself; +}; + + +/* +============ +T_Damage + +The damage is coming from inflictor, but get mad at attacker +This should be the only function that ever reduces health. +============ +*/ +void(entity targ, entity inflictor, entity attacker, float damage) T_Damage= +{ + local vector dir; + local entity oldself; + local float save; + local float take; + + if (!targ.takedamage) + return; + +// used by buttons and triggers to set activator for target firing + damage_attacker = attacker; + +// check for quad damage powerup on the attacker + if (attacker.super_damage_finished > time) + damage = damage * 4; + +// save damage based on the target's armor level + + save = ceil(targ.armortype*damage); + if (save >= targ.armorvalue) + { + save = targ.armorvalue; + targ.armortype = 0; // lost all armor + targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)); + } + + targ.armorvalue = targ.armorvalue - save; + take = ceil(damage-save); + +// add to the damage total for clients, which will be sent as a single +// message at the end of the frame +// FIXME: remove after combining shotgun blasts? + if (targ.flags & FL_CLIENT) + { + targ.dmg_take = targ.dmg_take + take; + targ.dmg_save = targ.dmg_save + save; + targ.dmg_inflictor = inflictor; + } + +// figure momentum add + if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) ) + { + dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5; + dir = normalize(dir); + targ.velocity = targ.velocity + dir*damage*8; + } + +// check for godmode or invincibility + if (targ.flags & FL_GODMODE) + return; + if (targ.invincible_finished >= time) + { + if (self.invincible_sound < time) + { + sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM); + self.invincible_sound = time + 2; + } + return; + } + +// team play damage avoidance + if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) ) + return; + +// do the damage + targ.health = targ.health - take; + + if (targ.health <= 0) + { + Killed (targ, attacker); + return; + } + +// react to the damage + oldself = self; + self = targ; + + if ( (self.flags & FL_MONSTER) && attacker != world) + { + // get mad unless of the same class (except for soldiers) + if (self != attacker && attacker != self.enemy) + { + if ( (self.classname != attacker.classname) + || (self.classname == "monster_army" ) ) + { + if (self.enemy.classname == "player") + self.oldenemy = self.enemy; + self.enemy = attacker; + FoundTarget (); + } + } + } + + if (self.th_pain) + { + self.th_pain (attacker, take); + // nightmare mode monsters don't go into pain frames often + if (skill == 3) + self.pain_finished = time + 5; + } + + self = oldself; +}; + +/* +============ +T_RadiusDamage +============ +*/ +void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage = +{ + local float points; + local entity head; + local vector org; + + head = findradius(inflictor.origin, damage+40); + + while (head) + { + if (head != ignore) + { + if (head.takedamage) + { + org = head.origin + (head.mins + head.maxs)*0.5; + points = 0.5*vlen (inflictor.origin - org); + if (points < 0) + points = 0; + points = damage - points; + if (head == attacker) + points = points * 0.5; + if (points > 0) + { + if (CanDamage (head, inflictor)) + { // shambler takes half damage from all explosions + if (head.classname == "monster_shambler") + T_Damage (head, inflictor, attacker, points*0.5); + else + T_Damage (head, inflictor, attacker, points); + } + } + } + } + head = head.chain; + } +}; + +/* +============ +T_BeamDamage +============ +*/ +void(entity attacker, float damage) T_BeamDamage = +{ + local float points; + local entity head; + + head = findradius(attacker.origin, damage+40); + + while (head) + { + if (head.takedamage) + { + points = 0.5*vlen (attacker.origin - head.origin); + if (points < 0) + points = 0; + points = damage - points; + if (head == attacker) + points = points * 0.5; + if (points > 0) + { + if (CanDamage (head, attacker)) + { + if (head.classname == "monster_shambler") + T_Damage (head, attacker, attacker, points*0.5); + else + T_Damage (head, attacker, attacker, points); + } + } + } + head = head.chain; + } +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/debris.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/debris.qc new file mode 100755 index 00000000..60c3f4c8 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/debris.qc @@ -0,0 +1,96 @@ + + +/* +================ +Debris By Mexicouger (Bounce code from Needler. Not that advanced yet) +================= +*/ +vector(entity proj) Debrisbounce = // returns the velocity for bouncing off walls +{ + local vector vec; + local float backoff, change; + +// get the trace_plane_normal of the surface we hit + makevectors (proj.angles); + v_forward_z = v_forward_z * -1; + traceline (proj.origin, proj.origin + v_forward*64, FALSE, proj); + + if (trace_fraction == 1) + return proj.velocity; + +// the entity's velocity is not what we want, so set default + proj.velocity = v_forward * 50;//proj.old_velocity; + +// calculate dot product + backoff = (proj.velocity * trace_plane_normal); + backoff = backoff * 1.5; + +// finish + change = trace_plane_normal_x * backoff; + vec_x = proj.velocity_x - change; + + if (vec_x > -0.1 && vec_x < 0.1) + vec_x = 0; + + change = trace_plane_normal_y * backoff; + vec_y = proj.velocity_y - change; + + if (vec_y > -0.1 && vec_y < 0.1) + vec_y = 0; + + change = trace_plane_normal_z * backoff; + vec_z = proj.velocity_z - change; + + if (vec_z > -0.1 && vec_z < 0.1) + vec_z = 0; + + if (other.classname == "gun_shells") + sound (other, CHAN_AUTO, "weapons/shell.wav", 1, ATTN_NORM); +// set correct angles of our new velocity + proj.angles = vectoangles (vec); + + // this is required to make downward slopes not stop the projectile + proj.flags = proj.flags - ( proj.flags & FL_ONGROUND ); + + return vec; + +}; + +#define drandom() (2*(random()-0.5)) + + + +void(vector org) debris = +{ +local entity rock; +local float rand; +rand = random(); +rock = spawn (); +rock.classname = "rock"; +rock.movetype = MOVETYPE_BOUNCE; +rock.owner = self; + + +// This is all about how fast the debris goes. (My biggest problem) +makevectors (self.angles); +rock.velocity = v_forward * v_up * v_right * random(); + + +rock.velocity_z = rock.velocity_z + 5 + 20*random(); +rock.velocity_x = rock.velocity_x + 3 + 20*drandom(); +rock.velocity_y = rock.velocity_y + 3 + 20*drandom(); +rock.velocity = (rock.velocity * 12); +rock.avelocity = '300 300 300' * drandom(); +rock.angles = vectoangles (rock.velocity); +rock.solid = SOLID_NOT; +rock.touch = Debrisbounce; + +// Rock duration (How long the rocks are alive until they disapear/Explode +rock.nextthink = time + 2 * rand*4; +rock.think = SUB_Remove; +// The whole setting up the model thing. Sets up the sprite and location. +rock.origin = self.origin + v_forward*8*random() + '0 0 16'; +setorigin (rock, org); +setsize (rock, '0 0 0', '3 3 3'); +setmodel (rock, "maps/B_f1.bsp"); +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/defs.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/defs.qc new file mode 100755 index 00000000..2b044a8f --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/defs.qc @@ -0,0 +1,692 @@ + +/* +============================================================================== + + SOURCE FOR GLOBALVARS_T C STRUCTURE + +============================================================================== +*/ + +// +// system globals +// +entity self; +entity other; +entity world; +float time; +float frametime; + +float force_retouch; // force all entities to touch triggers + // next frame. this is needed because + // non-moving things don't normally scan + // for triggers, and when a trigger is + // created (like a teleport trigger), it + // needs to catch everything. + // decremented each frame, so set to 2 + // to guarantee everything is touched +string mapname; + +float deathmatch; +float coop; +float teamplay; + +float serverflags; // propagated from level to level, used to + // keep track of completed episodes + +float total_secrets; +float total_monsters; + +float found_secrets; // number of secrets found +float killed_monsters; // number of monsters killed + + +// spawnparms are used to encode information about clients across server +// level changes +float parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16; + +// +// global variables set by built in functions +// +vector v_forward, v_up, v_right; // set by makevectors() + +// set by traceline / tracebox +float trace_allsolid; +float trace_startsolid; +float trace_fraction; +vector trace_endpos; +vector trace_plane_normal; +float trace_plane_dist; +entity trace_ent; +float trace_inopen; +float trace_inwater; + +entity msg_entity; // destination of single entity writes + +// +// required prog functions +// +void() main; // only for testing + +void() StartFrame; + +void() PlayerPreThink; +void() PlayerPostThink; + +void() ClientKill; +void() ClientConnect; +void() PutClientInServer; // call after setting the parm1... parms +void() ClientDisconnect; + +void() SetNewParms; // called when a client first connects to + // a server. sets parms so they can be + // saved off for restarts + +void() SetChangeParms; // call to set parms for self so they can + // be saved for a level transition + + +//================================================ +void end_sys_globals; // flag for structure dumping +//================================================ + +/* +============================================================================== + + SOURCE FOR ENTVARS_T C STRUCTURE + +============================================================================== +*/ + +// +// system fields (*** = do not set in prog code, maintained by C code) +// +.float modelindex; // *** model index in the precached list +.vector absmin, absmax; // *** origin + mins / maxs + +.float ltime; // local time for entity +.float movetype; +.float solid; + +.vector origin; // *** +.vector oldorigin; // *** +.vector velocity; +.vector angles; +.vector avelocity; + +.vector punchangle; // temp angle adjust from damage or recoil + +.string classname; // spawn function +.string model; +.float frame; +.float skin; +.float effects; + +.vector mins, maxs; // bounding box extents reletive to origin +.vector size; // maxs - mins + +.void() touch; +.void() use; +.void() think; +.void() blocked; // for doors or plats, called when can't push other + +.float nextthink; +.entity groundentity; + +// stats +.float health; +.float frags; +.float weapon; // one of the IT_BLASTER, etc flags +.string weaponmodel; +.float weaponframe; +.float currentammo; +.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells; + +.float items; // bit flags + +.float takedamage; +.entity chain; +.float deadflag; + +.vector view_ofs; // add to origin to get eye point + + +.float button0; // fire +.float button1; // use +.float button2; // jump + +.float impulse; // weapon changes + +.float fixangle; +.vector v_angle; // view / targeting angle for players +.float idealpitch; // calculated pitch angle for lookup up slopes + + +.string netname; + +.entity enemy; + +.float flags; + +.float colormap; +.float team; + +.float max_health; // players maximum health is stored here + +.float teleport_time; // don't back up + +.float armortype; // save this fraction of incoming damage +.float armorvalue; + +.float waterlevel; // 0 = not in, 1 = feet, 2 = wast, 3 = eyes +.float watertype; // a contents value + +.float ideal_yaw; +.float yaw_speed; + +.entity aiment; + +.entity goalentity; // a movetarget or an enemy + +.float spawnflags; + +.string target; +.string targetname; + +// damage is accumulated through a frame. and sent as one single +// message, so the super shotgun doesn't generate huge messages +.float dmg_take; +.float dmg_save; +.entity dmg_inflictor; + +.entity owner; // who launched a missile +.vector movedir; // mostly for doors, but also used for waterjump + +.string message; // trigger messages + +.float sounds; // either a cd track number or sound number + +.string noise, noise1, noise2, noise3; // contains names of wavs to play + +//================================================ +void end_sys_fields; // flag for structure dumping +//================================================ + +/* +============================================================================== + + VARS NOT REFERENCED BY C CODE + +============================================================================== +*/ + + +// +// constants +// + +float FALSE = 0; +float TRUE = 1; + +// edict.flags +float FL_FLY = 1; +float FL_SWIM = 2; +float FL_CLIENT = 8; // set for all client edicts +float FL_INWATER = 16; // for enter / leave water splash +float FL_MONSTER = 32; +float FL_GODMODE = 64; // player cheat +float FL_NOTARGET = 128; // player cheat +float FL_ITEM = 256; // extra wide size for bonus items +float FL_ONGROUND = 512; // standing on something +float FL_PARTIALGROUND = 1024; // not all corners are valid +float FL_WATERJUMP = 2048; // player jumping out of water +float FL_JUMPRELEASED = 4096; // for jump debouncing + +// edict.movetype values +float MOVETYPE_NONE = 0; // never moves +//float MOVETYPE_ANGLENOCLIP = 1; +//float MOVETYPE_ANGLECLIP = 2; +float MOVETYPE_WALK = 3; // players only +float MOVETYPE_STEP = 4; // discrete, not real time unless fall +float MOVETYPE_FLY = 5; +float MOVETYPE_TOSS = 6; // gravity +float MOVETYPE_PUSH = 7; // no clip to world, push and crush +float MOVETYPE_NOCLIP = 8; +float MOVETYPE_FLYMISSILE = 9; // fly with extra size against monsters +float MOVETYPE_BOUNCE = 10; +float MOVETYPE_BOUNCEMISSILE = 11; // bounce with extra size + +// edict.solid values +float SOLID_NOT = 0; // no interaction with other objects +float SOLID_TRIGGER = 1; // touch on edge, but not blocking +float SOLID_BBOX = 2; // touch on edge, block +float SOLID_SLIDEBOX = 3; // touch on edge, but not an onground +float SOLID_BSP = 4; // bsp clip, touch on edge, block + +// range values +float RANGE_MELEE = 0; +float RANGE_NEAR = 1; +float RANGE_MID = 2; +float RANGE_FAR = 3; + +// deadflag values + +float DEAD_NO = 0; +float DEAD_DYING = 1; +float DEAD_DEAD = 2; +float DEAD_RESPAWNABLE = 3; + +// takedamage values + +float DAMAGE_NO = 0; +float DAMAGE_YES = 1; +float DAMAGE_AIM = 2; + +// items +float IT_MORPHBALL = 4096; +float IT_BLASTER = 1; //Blaster +float IT_ROCKET = 2; //Rocket Launcher +float IT_SPLASER = 4; //Splaser +float IT_SNIPER = 8; //Sniper +float IT_GRENADE_LAUNCHER = 16; +float IT_MAGMA = 32; //Magma beam +float IT_LIGHTNING = 64; +float IT_RIC = 128; //Richochet beam + +float IT_SHELLS = 256; +float IT_NAILS = 512; +float IT_ROCKETS = 1024; +float IT_CELLS = 2048; + +float IT_ARMOR1 = 8192; +float IT_ARMOR2 = 16384; +float IT_ARMOR3 = 32768; +float IT_SUPERHEALTH = 65536; + +float IT_KEY1 = 131072; +float IT_KEY2 = 262144; + +float IT_INVISIBILITY = 524288; +float IT_INVULNERABILITY = 1048576; +float IT_SUIT = 2097152; +float IT_QUAD = 4194304; + +// point content values + +float CONTENT_EMPTY = -1; +float CONTENT_SOLID = -2; +float CONTENT_WATER = -3; +float CONTENT_SLIME = -4; +float CONTENT_LAVA = -5; +float CONTENT_SKY = -6; + +float STATE_TOP = 0; +float STATE_BOTTOM = 1; +float STATE_UP = 2; +float STATE_DOWN = 3; + +vector VEC_ORIGIN = '0 0 0'; +vector VEC_HULL_MIN = '-16 -16 -24'; +vector VEC_HULL_MAX = '16 16 32'; + +vector VEC_HULL2_MIN = '-32 -32 -24'; +vector VEC_HULL2_MAX = '32 32 64'; + +// protocol bytes +float SVC_TEMPENTITY = 23; +float SVC_KILLEDMONSTER = 27; +float SVC_FOUNDSECRET = 28; +float SVC_INTERMISSION = 30; +float SVC_FINALE = 31; +float SVC_CDTRACK = 32; +float SVC_SELLSCREEN = 33; + + +float TE_SPIKE = 0; +float TE_SUPERSPIKE = 1; +float TE_GUNSHOT = 2; +float TE_EXPLOSION = 3; +float TE_TAREXPLOSION = 4; +float TE_LIGHTNING1 = 5; +float TE_LIGHTNING2 = 6; +float TE_WIZSPIKE = 7; +float TE_KNIGHTSPIKE = 8; +float TE_LIGHTNING3 = 9; +float TE_LAVASPLASH = 10; +float TE_TELEPORT = 11; + +// sound channels +// channel 0 never willingly overrides +// other channels (1-7) allways override a playing sound on that channel +float CHAN_AUTO = 0; +float CHAN_WEAPON = 1; +float CHAN_VOICE = 2; +float CHAN_ITEM = 3; +float CHAN_BODY = 4; + +float ATTN_NONE = 0; +float ATTN_NORM = 1; +float ATTN_IDLE = 2; +float ATTN_STATIC = 3; + +// update types + +float UPDATE_GENERAL = 0; +float UPDATE_STATIC = 1; +float UPDATE_BINARY = 2; +float UPDATE_TEMP = 3; + +// entity effects + +float EF_BRIGHTFIELD = 1; +float EF_MUZZLEFLASH = 2; +float EF_BRIGHTLIGHT = 4; +float EF_DIMLIGHT = 8; + + +// messages +float MSG_BROADCAST = 0; // unreliable to all +float MSG_ONE = 1; // reliable to one (msg_entity) +float MSG_ALL = 2; // reliable to all +float MSG_INIT = 3; // write to the init string + +//================================================ + +// +// globals +// +float movedist; +float gameover; // set when a rule exits + +string string_null; // null string, nothing should be held here + +entity newmis; // launch_spike sets this after spawning it + +entity activator; // the entity that activated a trigger or brush + +entity damage_attacker; // set by T_Damage +float framecount; + +float skill; + +//================================================ + +// +// world fields (FIXME: make globals) +// +.string map; +.float worldtype; // 0=medieval 1=metal 2=base + +//================================================ + +.string killtarget; + +// +// quakeed fields +// +.float style; + + +// +// monster ai +// +.void() th_stand; +.void() th_walk; +.void() th_run; +.void() th_missile; +.void() th_melee; +.void(entity attacker, float damage) th_pain; +.void() th_die; + +.entity oldenemy; // mad at this player before taking damage + +.float speed; + +.float lefty; + +.float search_time; +.float attack_state; + +float AS_STRAIGHT = 1; +float AS_SLIDING = 2; +float AS_MELEE = 3; +float AS_MISSILE = 4; + +// +// player only fields +// +.float walkframe; + +.float attack_finished; +.float pain_finished; + +.float invincible_finished; +.float invisible_finished; +.float super_damage_finished; +.float radsuit_finished; + +.float invincible_time, invincible_sound; +.float invisible_time, invisible_sound; +.float super_time, super_sound; +.float rad_time; +.float fly_sound; + +.float axhitme; + +.float show_hostile; // set to time+0.2 whenever a client fires a + // weapon or takes damage. Used to alert + // monsters that otherwise would let the player go +.float jump_flag; // player jump flag +.float swim_flag; // player swimming sound flag +.float air_finished; // when time > air_finished, start drowning +.float bubble_count; // keeps track of the number of bubbles +.string deathtype; // keeps track of how the player died + +// +// object stuff +// +.string mdl; +.vector mangle; // angle at start + +.vector oldorigin; // only used by secret door + +.float t_length, t_width; + + +// +// doors, etc +// +.vector dest1, dest2; +.float wait; // time from firing to restarting +.float delay; // time from activation to firing +.entity trigger_field; // door's trigger entity +.string noise4; + +// +// monsters +// +.float pausetime; +.entity movetarget; + + +// +// doors +// +.float aflag; +.float dmg; // damage done by door when hit + +// +// misc +// +.float cnt; // misc flag + +// +// subs +// +.void() think1; +.vector finaldest, finalangle; + +// +// triggers +// +.float count; // for counting triggers + + +// +// plats / doors / buttons +// +.float lip; +.float state; +.vector pos1, pos2; // top and bottom positions +.float height; + +// +// sounds +// +.float waitmin; +//.float volume; I can't find a use for this one yet. + + + + +//=========================================================================== + + +// +// builtin functions +// + +void(vector ang) makevectors = #1; // sets v_forward, etc globals +void(entity e, vector o) setorigin = #2; +void(entity e, string m) setmodel = #3; // set movetype and solid first +void(entity e, vector min, vector max) setsize = #4; +// #5 was removed +void() break = #6; +float() random = #7; // returns 0 - 1 +//void(entity e, float chan, string samp, float vol, float atten) sound = #8; +vector(vector v) normalize = #9; +void(string e) error = #10; +void(string e) objerror = #11; +float(vector v) vlen = #12; +float(vector v) vectoyaw = #13; +entity() spawn = #14; +void(entity e) remove = #15; + +// sets trace_* globals +// nomonsters can be: +// An entity will also be ignored for testing if forent == test, +// forent->owner == test, or test->owner == forent +// a forent of world is ignored +void(vector v1, vector v2, float nomonsters, entity forent) traceline = #16; + +entity() checkclient = #17; // returns a client to look for +entity(entity start, .string fld, string match) find = #18; +string(string s) precache_sound = #19; +string(string s) precache_model = #20; +//void(entity client, string s)stuffcmd = #21; +entity(vector org, float rad) findradius = #22; +void(string s) bprint = #23; +//void(entity client, string s) sprint = #24; +void(string s) dprint = #25; +string(float f) ftos = #26; +string(vector v) vtos = #27; +void() coredump = #28; // prints all edicts +void() traceon = #29; // turns statment trace on +void() traceoff = #30; +void(entity e) eprint = #31; // prints an entire edict +float(float yaw, float dist) walkmove = #32; // returns TRUE or FALSE +// #33 was removed +float(float yaw, float dist) droptofloor= #34; // TRUE if landed on floor +void(float style, string value) lightstyle = #35; +float(float v) rint = #36; // round to nearest int +float(float v) floor = #37; // largest integer <= v +float(float v) ceil = #38; // smallest integer >= v +// #39 was removed +float(entity e) checkbottom = #40; // true if self is on ground +float(vector v) pointcontents = #41; // returns a CONTENT_* +// #42 was removed +float(float f) fabs = #43; +//vector(entity e, float speed) aim = #44; // returns the shooting vector +float(string s) cvar = #45; // return cvar.value +void(string s) localcmd = #46; // put string into local que +entity(entity e) nextent = #47; // for looping through all ents +void(vector o, vector d, float color, float count) particle = #48;// start a particle effect +void() ChangeYaw = #49; // turn towards self.ideal_yaw + // at self.yaw_speed +// #50 was removed +vector(vector v) vectoangles = #51; + +// +// direct client message generation +// +//void(float to, float f) WriteByte = #52; +//void(float to, float f) WriteChar = #53; +//void(float to, float f) WriteShort = #54; +//void(float to, float f) WriteLong = #55; +//void(float to, float f) WriteCoord = #56; +//void(float to, float f) WriteAngle = #57; +//void(float to, string s) WriteString = #58; +//void(float to, entity s) WriteEntity = #59; + +// +// broadcast client message generation +// + +// void(float f) bWriteByte = #59; +// void(float f) bWriteChar = #60; +// void(float f) bWriteShort = #61; +// void(float f) bWriteLong = #62; +// void(float f) bWriteCoord = #63; +// void(float f) bWriteAngle = #64; +// void(string s) bWriteString = #65; +// void(entity e) bWriteEntity = #66; + +void(float step) movetogoal = #67; + +string(string s) precache_file = #68; // no effect except for -copy +void(entity e) makestatic = #69; +void(string s) changelevel = #70; + +//#71 was removed + +void(string var, string val) cvar_set = #72; // sets cvar.value + +//void(entity client, string s) centerprint = #73; // sprint, but in middle + +void(vector pos, string samp, float vol, float atten) ambientsound = #74; + +string(string s) precache_model2 = #75; // registered version only +string(string s) precache_sound2 = #76; // registered version only +string(string s) precache_file2 = #77; // registered version only + +//void(entity e) setspawnparms = #78; // set parm1... to the + // values at level start + // for coop respawn + +//============================================================================ + +// +// subs.qc +// +void(vector tdest, float tspeed, void() func) SUB_CalcMove; +void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt; +void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove; +void() SUB_CalcMoveDone; +void() SUB_CalcAngleMoveDone; +void() SUB_Null; +void() SUB_UseTargets; +void() SUB_Remove; + +// +// combat.qc +// +void(entity targ, entity inflictor, entity attacker, float damage) T_Damage; + + +float (entity e, float healamount, float ignore) T_Heal; // health function + +float(entity targ, entity inflictor) CanDamage; + + +.float semi; // Semiauto + + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/demon.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/demon.qc new file mode 100755 index 00000000..2c96af3b --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/demon.qc @@ -0,0 +1,359 @@ +/* +============================================================================== + +DEMON + +============================================================================== +*/ + +$cd id1/models/demon3 +$scale 0.8 +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 +$frame stand10 stand11 stand12 stand13 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 + +$frame run1 run2 run3 run4 run5 run6 + +$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 leap10 +$frame leap11 leap12 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 + +$frame attacka1 attacka2 attacka3 attacka4 attacka5 attacka6 attacka7 attacka8 +$frame attacka9 attacka10 attacka11 attacka12 attacka13 attacka14 attacka15 + +//============================================================================ + +void() Demon_JumpTouch; + +void() demon1_stand1 =[ $stand1, demon1_stand2 ] {ai_stand();}; +void() demon1_stand2 =[ $stand2, demon1_stand3 ] {ai_stand();}; +void() demon1_stand3 =[ $stand3, demon1_stand4 ] {ai_stand();}; +void() demon1_stand4 =[ $stand4, demon1_stand5 ] {ai_stand();}; +void() demon1_stand5 =[ $stand5, demon1_stand6 ] {ai_stand();}; +void() demon1_stand6 =[ $stand6, demon1_stand7 ] {ai_stand();}; +void() demon1_stand7 =[ $stand7, demon1_stand8 ] {ai_stand();}; +void() demon1_stand8 =[ $stand8, demon1_stand9 ] {ai_stand();}; +void() demon1_stand9 =[ $stand9, demon1_stand10 ] {ai_stand();}; +void() demon1_stand10 =[ $stand10, demon1_stand11 ] {ai_stand();}; +void() demon1_stand11 =[ $stand11, demon1_stand12 ] {ai_stand();}; +void() demon1_stand12 =[ $stand12, demon1_stand13 ] {ai_stand();}; +void() demon1_stand13 =[ $stand13, demon1_stand1 ] {ai_stand();}; + +void() demon1_walk1 =[ $walk1, demon1_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE); +ai_walk(8); +}; +void() demon1_walk2 =[ $walk2, demon1_walk3 ] {ai_walk(6);}; +void() demon1_walk3 =[ $walk3, demon1_walk4 ] {ai_walk(6);}; +void() demon1_walk4 =[ $walk4, demon1_walk5 ] {ai_walk(7);}; +void() demon1_walk5 =[ $walk5, demon1_walk6 ] {ai_walk(4);}; +void() demon1_walk6 =[ $walk6, demon1_walk7 ] {ai_walk(6);}; +void() demon1_walk7 =[ $walk7, demon1_walk8 ] {ai_walk(10);}; +void() demon1_walk8 =[ $walk8, demon1_walk1 ] {ai_walk(10);}; + +void() demon1_run1 =[ $run1, demon1_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE); +ai_run(20);}; +void() demon1_run2 =[ $run2, demon1_run3 ] {ai_run(15);}; +void() demon1_run3 =[ $run3, demon1_run4 ] {ai_run(36);}; +void() demon1_run4 =[ $run4, demon1_run5 ] {ai_run(20);}; +void() demon1_run5 =[ $run5, demon1_run6 ] {ai_run(15);}; +void() demon1_run6 =[ $run6, demon1_run1 ] {ai_run(36);}; + +void() demon1_jump1 =[ $leap1, demon1_jump2 ] {ai_face();}; +void() demon1_jump2 =[ $leap2, demon1_jump3 ] {ai_face();}; +void() demon1_jump3 =[ $leap3, demon1_jump4 ] {ai_face();}; +void() demon1_jump4 =[ $leap4, demon1_jump5 ] +{ + ai_face(); + + self.touch = Demon_JumpTouch; + makevectors (self.angles); + self.origin_z = self.origin_z + 1; + self.velocity = v_forward * 600 + '0 0 250'; + if (self.flags & FL_ONGROUND) + self.flags = self.flags - FL_ONGROUND; +}; +void() demon1_jump5 =[ $leap5, demon1_jump6 ] {}; +void() demon1_jump6 =[ $leap6, demon1_jump7 ] {}; +void() demon1_jump7 =[ $leap7, demon1_jump8 ] {}; +void() demon1_jump8 =[ $leap8, demon1_jump9 ] {}; +void() demon1_jump9 =[ $leap9, demon1_jump10 ] {}; +void() demon1_jump10 =[ $leap10, demon1_jump1 ] { +self.nextthink = time + 3; +// if three seconds pass, assume demon is stuck and jump again +}; + +void() demon1_jump11 =[ $leap11, demon1_jump12 ] {}; +void() demon1_jump12 =[ $leap12, demon1_run1 ] {}; + + +void() demon1_atta1 =[ $attacka1, demon1_atta2 ] {ai_charge(4);}; +void() demon1_atta2 =[ $attacka2, demon1_atta3 ] {ai_charge(0);}; +void() demon1_atta3 =[ $attacka3, demon1_atta4 ] {ai_charge(0);}; +void() demon1_atta4 =[ $attacka4, demon1_atta5 ] {ai_charge(1);}; +void() demon1_atta5 =[ $attacka5, demon1_atta6 ] {ai_charge(2); Demon_Melee(200);}; +void() demon1_atta6 =[ $attacka6, demon1_atta7 ] {ai_charge(1);}; +void() demon1_atta7 =[ $attacka7, demon1_atta8 ] {ai_charge(6);}; +void() demon1_atta8 =[ $attacka8, demon1_atta9 ] {ai_charge(8);}; +void() demon1_atta9 =[ $attacka9, demon1_atta10] {ai_charge(4);}; +void() demon1_atta10 =[ $attacka10, demon1_atta11] {ai_charge(2);}; +void() demon1_atta11 =[ $attacka11, demon1_atta12] {Demon_Melee(-200);}; +void() demon1_atta12 =[ $attacka12, demon1_atta13] {ai_charge(5);}; +void() demon1_atta13 =[ $attacka13, demon1_atta14] {ai_charge(8);}; +void() demon1_atta14 =[ $attacka14, demon1_atta15] {ai_charge(4);}; +void() demon1_atta15 =[ $attacka15, demon1_run1] {ai_charge(4);}; + +void() demon1_pain1 =[ $pain1, demon1_pain2 ] {}; +void() demon1_pain2 =[ $pain2, demon1_pain3 ] {}; +void() demon1_pain3 =[ $pain3, demon1_pain4 ] {}; +void() demon1_pain4 =[ $pain4, demon1_pain5 ] {}; +void() demon1_pain5 =[ $pain5, demon1_pain6 ] {}; +void() demon1_pain6 =[ $pain6, demon1_run1 ] {}; + +void(entity attacker, float damage) demon1_pain = +{ + if (self.touch == Demon_JumpTouch) + return; + + if (self.pain_finished > time) + return; + + self.pain_finished = time + 1; + sound (self, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM); + + if (random()*200 > damage) + return; // didn't flinch + + demon1_pain1 (); +}; + +void() demon1_die1 =[ $death1, demon1_die2 ] { +sound (self, CHAN_VOICE, "demon/ddeath.wav", 1, ATTN_NORM);}; +void() demon1_die2 =[ $death2, demon1_die3 ] {}; +void() demon1_die3 =[ $death3, demon1_die4 ] {}; +void() demon1_die4 =[ $death4, demon1_die5 ] {}; +void() demon1_die5 =[ $death5, demon1_die6 ] {}; +void() demon1_die6 =[ $death6, demon1_die7 ] +{self.solid = SOLID_NOT;}; +void() demon1_die7 =[ $death7, demon1_die8 ] {}; +void() demon1_die8 =[ $death8, demon1_die9 ] {}; +void() demon1_die9 =[ $death9, demon1_die9 ] {}; + +void() demon_die = +{ +// check for gib + if (self.health < -80) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_demon.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + return; + } + +// regular death + demon1_die1 (); +}; + + +void() Demon_MeleeAttack = +{ + demon1_atta1 (); +}; + + +/*QUAKED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) Ambush + +*/ +void() monster_demon1 = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/demon.mdl"); + precache_model ("progs/h_demon.mdl"); + + precache_sound ("demon/ddeath.wav"); + precache_sound ("demon/dhit2.wav"); + precache_sound ("demon/djump.wav"); + precache_sound ("demon/dpain1.wav"); + precache_sound ("demon/idle1.wav"); + precache_sound ("demon/sight2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/demon.mdl"); + + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 300; + + self.th_stand = demon1_stand1; + self.th_walk = demon1_walk1; + self.th_run = demon1_run1; + self.th_die = demon_die; + self.th_melee = Demon_MeleeAttack; // one of two attacks + self.th_missile = demon1_jump1; // jump attack + self.th_pain = demon1_pain; + + walkmonster_start(); +}; + + +/* +============================================================================== + +DEMON + +============================================================================== +*/ + +/* +============== +CheckDemonMelee + +Returns TRUE if a melee attack would hit right now +============== +*/ +float() CheckDemonMelee = +{ + if (enemy_range == RANGE_MELEE) + { // FIXME: check canreach + self.attack_state = AS_MELEE; + return TRUE; + } + return FALSE; +}; + +/* +============== +CheckDemonJump + +============== +*/ +float() CheckDemonJump = +{ + local vector dist; + local float d; + + if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z + + 0.75 * self.enemy.size_z) + return FALSE; + + if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z + + 0.25 * self.enemy.size_z) + return FALSE; + + dist = self.enemy.origin - self.origin; + dist_z = 0; + + d = vlen(dist); + + if (d < 100) + return FALSE; + + if (d > 200) + { + if (random() < 0.9) + return FALSE; + } + + return TRUE; +}; + +float() DemonCheckAttack = +{ +// if close enough for slashing, go for it + if (CheckDemonMelee ()) + { + self.attack_state = AS_MELEE; + return TRUE; + } + + if (CheckDemonJump ()) + { + self.attack_state = AS_MISSILE; + sound (self, CHAN_VOICE, "demon/djump.wav", 1, ATTN_NORM); + return TRUE; + } + + return FALSE; +}; + + +//=========================================================================== + +void(float side) Demon_Melee = +{ + local float ldmg; + local vector delta; + + ai_face (); + walkmove (self.ideal_yaw, 12); // allow a little closing + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + if (!CanDamage (self.enemy, self)) + return; + + sound (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM); + ldmg = 10 + 5*random(); + T_Damage (self.enemy, self, self, ldmg); + +}; + + +void() Demon_JumpTouch = +{ + local float ldmg; + + if (self.health <= 0) + return; + + if (other.takedamage) + { + if ( vlen(self.velocity) > 400 ) + { + ldmg = 40 + 10*random(); + T_Damage (other, self, self, ldmg); + } + } + + if (!checkbottom(self)) + { + if (self.flags & FL_ONGROUND) + { // jump randomly to not get hung up +//dprint ("popjump\n"); + self.touch = SUB_Null; + self.think = demon1_jump1; + self.nextthink = time + 0.1; + +// self.velocity_x = (random() - 0.5) * 600; +// self.velocity_y = (random() - 0.5) * 600; +// self.velocity_z = 200; +// self.flags = self.flags - FL_ONGROUND; + } + return; // not on ground yet + } + + self.touch = SUB_Null; + self.think = demon1_jump11; + self.nextthink = time + 0.1; +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/dog.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/dog.qc new file mode 100755 index 00000000..a9e18565 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/dog.qc @@ -0,0 +1,362 @@ +/* +============================================================================== + +DOG + +============================================================================== +*/ +$cd id1/models/dog +$origin 0 0 24 +$base base +$skin skin + +$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10 +$frame painb11 painb12 painb13 painb14 painb15 painb16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 + +$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 + + +void() dog_leap1; +void() dog_run1; + +/* +================ +dog_bite + +================ +*/ +void() dog_bite = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + + ai_charge(10); + + if (!CanDamage (self.enemy, self)) + return; + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + ldmg = (random() + random() + random()) * 8; + T_Damage (self.enemy, self, self, ldmg); +}; + +void() Dog_JumpTouch = +{ + local float ldmg; + + if (self.health <= 0) + return; + + if (other.takedamage) + { + if ( vlen(self.velocity) > 300 ) + { + ldmg = 10 + 10*random(); + T_Damage (other, self, self, ldmg); + } + } + + if (!checkbottom(self)) + { + if (self.flags & FL_ONGROUND) + { // jump randomly to not get hung up +//dprint ("popjump\n"); + self.touch = SUB_Null; + self.think = dog_leap1; + self.nextthink = time + 0.1; + +// self.velocity_x = (random() - 0.5) * 600; +// self.velocity_y = (random() - 0.5) * 600; +// self.velocity_z = 200; +// self.flags = self.flags - FL_ONGROUND; + } + return; // not on ground yet + } + + self.touch = SUB_Null; + self.think = dog_run1; + self.nextthink = time + 0.1; +}; + + +void() dog_stand1 =[ $stand1, dog_stand2 ] {ai_stand();}; +void() dog_stand2 =[ $stand2, dog_stand3 ] {ai_stand();}; +void() dog_stand3 =[ $stand3, dog_stand4 ] {ai_stand();}; +void() dog_stand4 =[ $stand4, dog_stand5 ] {ai_stand();}; +void() dog_stand5 =[ $stand5, dog_stand6 ] {ai_stand();}; +void() dog_stand6 =[ $stand6, dog_stand7 ] {ai_stand();}; +void() dog_stand7 =[ $stand7, dog_stand8 ] {ai_stand();}; +void() dog_stand8 =[ $stand8, dog_stand9 ] {ai_stand();}; +void() dog_stand9 =[ $stand9, dog_stand1 ] {ai_stand();}; + +void() dog_walk1 =[ $walk1 , dog_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE); +ai_walk(8);}; +void() dog_walk2 =[ $walk2 , dog_walk3 ] {ai_walk(8);}; +void() dog_walk3 =[ $walk3 , dog_walk4 ] {ai_walk(8);}; +void() dog_walk4 =[ $walk4 , dog_walk5 ] {ai_walk(8);}; +void() dog_walk5 =[ $walk5 , dog_walk6 ] {ai_walk(8);}; +void() dog_walk6 =[ $walk6 , dog_walk7 ] {ai_walk(8);}; +void() dog_walk7 =[ $walk7 , dog_walk8 ] {ai_walk(8);}; +void() dog_walk8 =[ $walk8 , dog_walk1 ] {ai_walk(8);}; + +void() dog_run1 =[ $run1 , dog_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE); +ai_run(16);}; +void() dog_run2 =[ $run2 , dog_run3 ] {ai_run(32);}; +void() dog_run3 =[ $run3 , dog_run4 ] {ai_run(32);}; +void() dog_run4 =[ $run4 , dog_run5 ] {ai_run(20);}; +void() dog_run5 =[ $run5 , dog_run6 ] {ai_run(64);}; +void() dog_run6 =[ $run6 , dog_run7 ] {ai_run(32);}; +void() dog_run7 =[ $run7 , dog_run8 ] {ai_run(16);}; +void() dog_run8 =[ $run8 , dog_run9 ] {ai_run(32);}; +void() dog_run9 =[ $run9 , dog_run10 ] {ai_run(32);}; +void() dog_run10 =[ $run10 , dog_run11 ] {ai_run(20);}; +void() dog_run11 =[ $run11 , dog_run12 ] {ai_run(64);}; +void() dog_run12 =[ $run12 , dog_run1 ] {ai_run(32);}; + +void() dog_atta1 =[ $attack1, dog_atta2 ] {ai_charge(10);}; +void() dog_atta2 =[ $attack2, dog_atta3 ] {ai_charge(10);}; +void() dog_atta3 =[ $attack3, dog_atta4 ] {ai_charge(10);}; +void() dog_atta4 =[ $attack4, dog_atta5 ] { +sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM); +dog_bite();}; +void() dog_atta5 =[ $attack5, dog_atta6 ] {ai_charge(10);}; +void() dog_atta6 =[ $attack6, dog_atta7 ] {ai_charge(10);}; +void() dog_atta7 =[ $attack7, dog_atta8 ] {ai_charge(10);}; +void() dog_atta8 =[ $attack8, dog_run1 ] {ai_charge(10);}; + +void() dog_leap1 =[ $leap1, dog_leap2 ] {ai_face();}; +void() dog_leap2 =[ $leap2, dog_leap3 ] +{ + ai_face(); + + self.touch = Dog_JumpTouch; + makevectors (self.angles); + self.origin_z = self.origin_z + 1; + self.velocity = v_forward * 300 + '0 0 200'; + if (self.flags & FL_ONGROUND) + self.flags = self.flags - FL_ONGROUND; +}; + +void() dog_leap3 =[ $leap3, dog_leap4 ] {}; +void() dog_leap4 =[ $leap4, dog_leap5 ] {}; +void() dog_leap5 =[ $leap5, dog_leap6 ] {}; +void() dog_leap6 =[ $leap6, dog_leap7 ] {}; +void() dog_leap7 =[ $leap7, dog_leap8 ] {}; +void() dog_leap8 =[ $leap8, dog_leap9 ] {}; +void() dog_leap9 =[ $leap9, dog_leap9 ] {}; + +void() dog_pain1 =[ $pain1 , dog_pain2 ] {}; +void() dog_pain2 =[ $pain2 , dog_pain3 ] {}; +void() dog_pain3 =[ $pain3 , dog_pain4 ] {}; +void() dog_pain4 =[ $pain4 , dog_pain5 ] {}; +void() dog_pain5 =[ $pain5 , dog_pain6 ] {}; +void() dog_pain6 =[ $pain6 , dog_run1 ] {}; + +void() dog_painb1 =[ $painb1 , dog_painb2 ] {}; +void() dog_painb2 =[ $painb2 , dog_painb3 ] {}; +void() dog_painb3 =[ $painb3 , dog_painb4 ] {ai_pain(4);}; +void() dog_painb4 =[ $painb4 , dog_painb5 ] {ai_pain(12);}; +void() dog_painb5 =[ $painb5 , dog_painb6 ] {ai_pain(12);}; +void() dog_painb6 =[ $painb6 , dog_painb7 ] {ai_pain(2);}; +void() dog_painb7 =[ $painb7 , dog_painb8 ] {}; +void() dog_painb8 =[ $painb8 , dog_painb9 ] {ai_pain(4);}; +void() dog_painb9 =[ $painb9 , dog_painb10 ] {}; +void() dog_painb10 =[ $painb10 , dog_painb11 ] {ai_pain(10);}; +void() dog_painb11 =[ $painb11 , dog_painb12 ] {}; +void() dog_painb12 =[ $painb12 , dog_painb13 ] {}; +void() dog_painb13 =[ $painb13 , dog_painb14 ] {}; +void() dog_painb14 =[ $painb14 , dog_painb15 ] {}; +void() dog_painb15 =[ $painb15 , dog_painb16 ] {}; +void() dog_painb16 =[ $painb16 , dog_run1 ] {}; + +void() dog_pain = +{ + sound (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM); + + if (random() > 0.5) + dog_pain1 (); + else + dog_painb1 (); +}; + +void() dog_die1 =[ $death1, dog_die2 ] {}; +void() dog_die2 =[ $death2, dog_die3 ] {}; +void() dog_die3 =[ $death3, dog_die4 ] {}; +void() dog_die4 =[ $death4, dog_die5 ] {}; +void() dog_die5 =[ $death5, dog_die6 ] {}; +void() dog_die6 =[ $death6, dog_die7 ] {}; +void() dog_die7 =[ $death7, dog_die8 ] {}; +void() dog_die8 =[ $death8, dog_die9 ] {}; +void() dog_die9 =[ $death9, dog_die9 ] {}; + +void() dog_dieb1 =[ $deathb1, dog_dieb2 ] {}; +void() dog_dieb2 =[ $deathb2, dog_dieb3 ] {}; +void() dog_dieb3 =[ $deathb3, dog_dieb4 ] {}; +void() dog_dieb4 =[ $deathb4, dog_dieb5 ] {}; +void() dog_dieb5 =[ $deathb5, dog_dieb6 ] {}; +void() dog_dieb6 =[ $deathb6, dog_dieb7 ] {}; +void() dog_dieb7 =[ $deathb7, dog_dieb8 ] {}; +void() dog_dieb8 =[ $deathb8, dog_dieb9 ] {}; +void() dog_dieb9 =[ $deathb9, dog_dieb9 ] {}; + + +void() dog_die = +{ +// check for gib + if (self.health < -35) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowHead ("progs/h_dog.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM); + self.solid = SOLID_NOT; + + if (random() > 0.5) + dog_die1 (); + else + dog_dieb1 (); +}; + +//============================================================================ + +/* +============== +CheckDogMelee + +Returns TRUE if a melee attack would hit right now +============== +*/ +float() CheckDogMelee = +{ + if (enemy_range == RANGE_MELEE) + { // FIXME: check canreach + self.attack_state = AS_MELEE; + return TRUE; + } + return FALSE; +}; + +/* +============== +CheckDogJump + +============== +*/ +float() CheckDogJump = +{ + local vector dist; + local float d; + + if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z + + 0.75 * self.enemy.size_z) + return FALSE; + + if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z + + 0.25 * self.enemy.size_z) + return FALSE; + + dist = self.enemy.origin - self.origin; + dist_z = 0; + + d = vlen(dist); + + if (d < 80) + return FALSE; + + if (d > 150) + return FALSE; + + return TRUE; +}; + +float() DogCheckAttack = +{ +// if close enough for slashing, go for it + if (CheckDogMelee ()) + { + self.attack_state = AS_MELEE; + return TRUE; + } + + if (CheckDogJump ()) + { + self.attack_state = AS_MISSILE; + return TRUE; + } + + return FALSE; +}; + + + +//=========================================================================== + +/*QUAKED monster_dog (1 0 0) (-32 -32 -24) (32 32 40) Ambush + +*/ +void(vector org) monster_dog = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/metroid.mdl"); + + precache_sound ("dog/dattack1.wav"); + precache_sound ("dog/ddeath.wav"); + precache_sound ("dog/dpain1.wav"); + precache_sound ("dog/dsight.wav"); + precache_sound ("dog/idle.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/metroid.mdl"); + + setsize (self, '-16 -16 -32', '16 16 20'); + self.health = 400; + + self.th_stand = dog_stand1; + self.th_walk = dog_walk1; + self.th_run = dog_run1; + self.th_pain = dog_pain; + self.th_die = dog_die; + self.th_melee = dog_atta1; + self.th_missile = dog_leap1; + + walkmonster_start(); +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/doors.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/doors.qc new file mode 100755 index 00000000..5a85ca86 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/doors.qc @@ -0,0 +1,778 @@ + +float DOOR_START_OPEN = 1; +float DOOR_DONT_LINK = 4; +float DOOR_GOLD_KEY = 8; +float DOOR_SILVER_KEY = 16; +float DOOR_TOGGLE = 32; + +/* + +Doors are similar to buttons, but can spawn a fat trigger field around them +to open without a touch, and they link together to form simultanious +double/quad doors. + +Door.owner is the master door. If there is only one door, it points to itself. +If multiple doors, all will point to a single one. + +Door.enemy chains from the master door through all doors linked in the chain. + +*/ + +/* +============================================================================= + +THINK FUNCTIONS + +============================================================================= +*/ + +void() door_go_down; +void() door_go_up; + +void() door_blocked = +{ + T_Damage (other, self, self, self.dmg); + +// if a door has a negative wait, it would never come back if blocked, +// so let it just squash the object to death real fast + if (self.wait >= 0) + { + if (self.state == STATE_DOWN) + door_go_up (); + else + door_go_down (); + } +}; + + +void() door_hit_top = +{ + sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_TOP; + if (self.spawnflags & DOOR_TOGGLE) + return; // don't come down automatically + self.think = door_go_down; + self.nextthink = self.ltime + self.wait; +}; + +void() door_hit_bottom = +{ + sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_BOTTOM; +}; + +void() door_go_down = +{ + sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + if (self.max_health) + { + self.takedamage = DAMAGE_YES; + self.health = self.max_health; + } + + self.state = STATE_DOWN; + SUB_CalcMove (self.pos1, self.speed, door_hit_bottom); +}; + +void() door_go_up = +{ + if (self.state == STATE_UP) + return; // allready going up + + if (self.state == STATE_TOP) + { // reset top wait time + self.nextthink = self.ltime + self.wait; + return; + } + + sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + self.state = STATE_UP; + SUB_CalcMove (self.pos2, self.speed, door_hit_top); + + SUB_UseTargets(); +}; + + +/* +============================================================================= + +ACTIVATION FUNCTIONS + +============================================================================= +*/ + +void() door_fire = +{ + local entity oself; + local entity starte; + + if (self.owner != self) + objerror ("door_fire: self.owner != self"); + +// play use key sound + + if (self.items) + sound (self, CHAN_VOICE, self.noise4, 1, ATTN_NORM); + + self.message = string_null; // no more message + oself = self; + + if (self.spawnflags & DOOR_TOGGLE) + { + if (self.state == STATE_UP || self.state == STATE_TOP) + { + starte = self; + do + { + door_go_down (); + self = self.enemy; + } while ( (self != starte) && (self != world) ); + self = oself; + return; + } + } + +// trigger all paired doors + starte = self; + do + { + door_go_up (); + self = self.enemy; + } while ( (self != starte) && (self != world) ); + self = oself; +}; + + +void() door_use = +{ + local entity oself; + + self.message = ""; // door message are for touch only + self.owner.message = ""; + self.enemy.message = ""; + oself = self; + self = self.owner; + door_fire (); + self = oself; +}; + + +void() door_trigger_touch = +{ + if (other.health <= 0) + return; + + if (time < self.attack_finished) + return; + self.attack_finished = time + 1; + + activator = other; + + self = self.owner; + door_use (); +}; + + +void() door_killed = +{ + local entity oself; + + oself = self; + self = self.owner; + self.health = self.max_health; + self.takedamage = DAMAGE_NO; // wil be reset upon return + door_use (); + self = oself; +}; + + +/* +================ +door_touch + +Prints messages and opens key doors +================ +*/ +void() door_touch = +{ + if (other.classname != "player") + return; + if (self.owner.attack_finished > time) + return; + + self.owner.attack_finished = time + 2; + + if (self.owner.message != "") + { + centerprint (other, self.owner.message); + sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM); + } + +// key door stuff + if (!self.items) + return; + +// FIXME: blink key on player's status bar + if ( (self.items & other.items) != self.items ) + { + if (self.owner.items == IT_KEY1) + { + if (world.worldtype == 2) + { + centerprint (other, "You need the silver keycard"); + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + } + else if (world.worldtype == 1) + { + centerprint (other, "You need the silver runekey"); + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + } + else if (world.worldtype == 0) + { + centerprint (other, "You need the silver key"); + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + } + } + else + { + if (world.worldtype == 2) + { + centerprint (other, "You need the gold keycard"); + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + } + else if (world.worldtype == 1) + { + centerprint (other, "You need the gold runekey"); + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + } + else if (world.worldtype == 0) + { + centerprint (other, "You need the gold key"); + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + } + } + return; + } + + other.items = other.items - self.items; + self.touch = SUB_Null; + if (self.enemy) + self.enemy.touch = SUB_Null; // get paired door + door_use (); +}; + +/* +============================================================================= + +SPAWNING FUNCTIONS + +============================================================================= +*/ + + +entity(vector fmins, vector fmaxs) spawn_field = +{ + local entity trigger; + local vector t1, t2; + + trigger = spawn(); + trigger.movetype = MOVETYPE_NONE; + trigger.solid = SOLID_TRIGGER; + trigger.owner = self; + trigger.touch = door_trigger_touch; + + t1 = fmins; + t2 = fmaxs; + setsize (trigger, t1 - '60 60 8', t2 + '60 60 8'); + return (trigger); +}; + + +float (entity e1, entity e2) EntitiesTouching = +{ + if (e1.mins_x > e2.maxs_x) + return FALSE; + if (e1.mins_y > e2.maxs_y) + return FALSE; + if (e1.mins_z > e2.maxs_z) + return FALSE; + if (e1.maxs_x < e2.mins_x) + return FALSE; + if (e1.maxs_y < e2.mins_y) + return FALSE; + if (e1.maxs_z < e2.mins_z) + return FALSE; + return TRUE; +}; + + +/* +============= +LinkDoors + + +============= +*/ +void() LinkDoors = +{ + local entity t, starte; + local vector cmins, cmaxs; + + if (self.enemy) + return; // already linked by another door + if (self.spawnflags & 4) + { + self.owner = self.enemy = self; + return; // don't want to link this door + } + + cmins = self.mins; + cmaxs = self.maxs; + + starte = self; + t = self; + + do + { + self.owner = starte; // master door + + if (self.health) + starte.health = self.health; + if (self.targetname) + starte.targetname = self.targetname; + if (self.message != "") + starte.message = self.message; + + t = find (t, classname, self.classname); + if (!t) + { + self.enemy = starte; // make the chain a loop + + // shootable, fired, or key doors just needed the owner/enemy links, + // they don't spawn a field + + self = self.owner; + + if (self.health) + return; + if (self.targetname) + return; + if (self.items) + return; + + self.owner.trigger_field = spawn_field(cmins, cmaxs); + + return; + } + + if (EntitiesTouching(self,t)) + { + if (t.enemy) + objerror ("cross connected doors"); + + self.enemy = t; + self = t; + + if (t.mins_x < cmins_x) + cmins_x = t.mins_x; + if (t.mins_y < cmins_y) + cmins_y = t.mins_y; + if (t.mins_z < cmins_z) + cmins_z = t.mins_z; + if (t.maxs_x > cmaxs_x) + cmaxs_x = t.maxs_x; + if (t.maxs_y > cmaxs_y) + cmaxs_y = t.maxs_y; + if (t.maxs_z > cmaxs_z) + cmaxs_z = t.maxs_z; + } + } while (1 ); + +}; + + +/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE +if two doors touch, they are assumed to be connected and operate as a unit. + +TOGGLE causes the door to wait in both the start and end states for a trigger event. + +START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not usefull for touch or takedamage doors). + +Key doors are allways wait -1. + +"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet +"angle" determines the opening direction +"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door. +"health" if set, door must be shot open +"speed" movement speed (100 default) +"wait" wait before returning (3 default, -1 = never return) +"lip" lip remaining at end of move (8 default) +"dmg" damage to inflict when blocked (2 default) +"sounds" +0) no sound +1) stone +2) base +3) stone chain +4) screechy metal +*/ + +void() func_door = + +{ + + if (world.worldtype == 0) + { + precache_sound ("doors/medtry.wav"); + precache_sound ("doors/meduse.wav"); + self.noise3 = "doors/medtry.wav"; + self.noise4 = "doors/meduse.wav"; + } + else if (world.worldtype == 1) + { + precache_sound ("doors/runetry.wav"); + precache_sound ("doors/runeuse.wav"); + self.noise3 = "doors/runetry.wav"; + self.noise4 = "doors/runeuse.wav"; + } + else if (world.worldtype == 2) + { + precache_sound ("doors/basetry.wav"); + precache_sound ("doors/baseuse.wav"); + self.noise3 = "doors/basetry.wav"; + self.noise4 = "doors/baseuse.wav"; + } + else + { + dprint ("no worldtype set!\n"); + } + if (self.sounds == 0) + { + precache_sound ("misc/null.wav"); + precache_sound ("misc/null.wav"); + self.noise1 = "misc/null.wav"; + self.noise2 = "misc/null.wav"; + } + if (self.sounds == 1) + { + precache_sound ("doors/drclos4.wav"); + precache_sound ("doors/doormv1.wav"); + self.noise1 = "doors/drclos4.wav"; + self.noise2 = "doors/doormv1.wav"; + } + if (self.sounds == 2) + { + precache_sound ("doors/hydro1.wav"); + precache_sound ("doors/hydro2.wav"); + self.noise2 = "doors/hydro1.wav"; + self.noise1 = "doors/hydro2.wav"; + } + if (self.sounds == 3) + { + precache_sound ("doors/stndr1.wav"); + precache_sound ("doors/stndr2.wav"); + self.noise2 = "doors/stndr1.wav"; + self.noise1 = "doors/stndr2.wav"; + } + if (self.sounds == 4) + { + precache_sound ("doors/ddoor1.wav"); + precache_sound ("doors/ddoor2.wav"); + self.noise1 = "doors/ddoor2.wav"; + self.noise2 = "doors/ddoor1.wav"; + } + + + SetMovedir (); + + self.max_health = self.health; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + setorigin (self, self.origin); + setmodel (self, self.model); + self.classname = "door"; + + self.blocked = door_blocked; + self.use = door_use; + + if (self.spawnflags & DOOR_SILVER_KEY) + self.items = IT_KEY1; + if (self.spawnflags & DOOR_GOLD_KEY) + self.items = IT_KEY2; + + if (!self.speed) + self.speed = 100; + if (!self.wait) + self.wait = 3; + if (!self.lip) + self.lip = 8; + if (!self.dmg) + self.dmg = 2; + + self.pos1 = self.origin; + self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip); + +// DOOR_START_OPEN is to allow an entity to be lighted in the closed position +// but spawn in the open position + if (self.spawnflags & DOOR_START_OPEN) + { + setorigin (self, self.pos2); + self.pos2 = self.pos1; + self.pos1 = self.origin; + } + + self.state = STATE_BOTTOM; + + if (self.health) + { + self.takedamage = DAMAGE_YES; + self.th_die = door_killed; + } + + if (self.items) + self.wait = -1; + + self.touch = door_touch; + +// LinkDoors can't be done until all of the doors have been spawned, so +// the sizes can be detected properly. + self.think = LinkDoors; + self.nextthink = self.ltime + 0.1; +}; + +/* +============================================================================= + +SECRET DOORS + +============================================================================= +*/ + +void() fd_secret_move1; +void() fd_secret_move2; +void() fd_secret_move3; +void() fd_secret_move4; +void() fd_secret_move5; +void() fd_secret_move6; +void() fd_secret_done; + +float SECRET_OPEN_ONCE = 1; // stays open +float SECRET_1ST_LEFT = 2; // 1st move is left of arrow +float SECRET_1ST_DOWN = 4; // 1st move is down from arrow +float SECRET_NO_SHOOT = 8; // only opened by trigger +float SECRET_YES_SHOOT = 16; // shootable even if targeted + + +void () fd_secret_use = +{ + local float temp; + + self.health = 10000; + + // exit if still moving around... + if (self.origin != self.oldorigin) + return; + + self.message = string_null; // no more message + + SUB_UseTargets(); // fire all targets / killtargets + + if (!(self.spawnflags & SECRET_NO_SHOOT)) + { + self.th_pain = SUB_Null; + self.takedamage = DAMAGE_NO; + } + self.velocity = '0 0 0'; + + // Make a sound, wait a little... + + sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.nextthink = self.ltime + 0.1; + + temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1 + makevectors(self.mangle); + + if (!self.t_width) + { + if (self.spawnflags & SECRET_1ST_DOWN) + self. t_width = fabs(v_up * self.size); + else + self. t_width = fabs(v_right * self.size); + } + + if (!self.t_length) + self. t_length = fabs(v_forward * self.size); + + if (self.spawnflags & SECRET_1ST_DOWN) + self.dest1 = self.origin - v_up * self.t_width; + else + self.dest1 = self.origin + v_right * (self.t_width * temp); + + self.dest2 = self.dest1 + v_forward * self.t_length; + SUB_CalcMove(self.dest1, self.speed, fd_secret_move1); + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); +}; + +// Wait after first movement... +void () fd_secret_move1 = +{ + self.nextthink = self.ltime + 1.0; + self.think = fd_secret_move2; + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); +}; + +// Start moving sideways w/sound... +void () fd_secret_move2 = +{ + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + SUB_CalcMove(self.dest2, self.speed, fd_secret_move3); +}; + +// Wait here until time to go back... +void () fd_secret_move3 = +{ + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + if (!(self.spawnflags & SECRET_OPEN_ONCE)) + { + self.nextthink = self.ltime + self.wait; + self.think = fd_secret_move4; + } +}; + +// Move backward... +void () fd_secret_move4 = +{ + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + SUB_CalcMove(self.dest1, self.speed, fd_secret_move5); +}; + +// Wait 1 second... +void () fd_secret_move5 = +{ + self.nextthink = self.ltime + 1.0; + self.think = fd_secret_move6; + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); +}; + +void () fd_secret_move6 = +{ + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done); +}; + +void () fd_secret_done = +{ + if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT) + { + self.health = 10000; + self.takedamage = DAMAGE_YES; + self.th_pain = fd_secret_use; + } + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); +}; + +void () secret_blocked = +{ + if (time < self.attack_finished) + return; + self.attack_finished = time + 0.5; + T_Damage (other, self, self, self.dmg); +}; + +/* +================ +secret_touch + +Prints messages +================ +*/ +void() secret_touch = +{ + if (other.classname != "player") + return; + if (self.attack_finished > time) + return; + + self.attack_finished = time + 2; + + if (self.message) + { + centerprint (other, self.message); + sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM); + } +}; + + +/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot +Basic secret door. Slides back, then to the side. Angle determines direction. +wait = # of seconds before coming back +1st_left = 1st move is left of arrow +1st_down = 1st move is down from arrow +always_shoot = even if targeted, keep shootable +t_width = override WIDTH to move back (or height if going down) +t_length = override LENGTH to move sideways +"dmg" damage to inflict when blocked (2 default) + +If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage. +"sounds" +1) medieval +2) metal +3) base +*/ + +void () func_door_secret = +{ + if (self.sounds == 0) + self.sounds = 3; + if (self.sounds == 1) + { + precache_sound ("doors/latch2.wav"); + precache_sound ("doors/winch2.wav"); + precache_sound ("doors/drclos4.wav"); + self.noise1 = "doors/latch2.wav"; + self.noise2 = "doors/winch2.wav"; + self.noise3 = "doors/drclos4.wav"; + } + if (self.sounds == 2) + { + precache_sound ("doors/airdoor1.wav"); + precache_sound ("doors/airdoor2.wav"); + self.noise2 = "doors/airdoor1.wav"; + self.noise1 = "doors/airdoor2.wav"; + self.noise3 = "doors/airdoor2.wav"; + } + if (self.sounds == 3) + { + precache_sound ("doors/basesec1.wav"); + precache_sound ("doors/basesec2.wav"); + self.noise2 = "doors/basesec1.wav"; + self.noise1 = "doors/basesec2.wav"; + self.noise3 = "doors/basesec2.wav"; + } + + if (!self.dmg) + self.dmg = 2; + + // Magic formula... + self.mangle = self.angles; + self.angles = '0 0 0'; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + self.classname = "door"; + setmodel (self, self.model); + setorigin (self, self.origin); + + self.touch = secret_touch; + self.blocked = secret_blocked; + self.speed = 50; + self.use = fd_secret_use; + if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT) + { + self.health = 10000; + self.takedamage = DAMAGE_YES; + self.th_pain = fd_secret_use; + self.th_die = fd_secret_use; + } + self.oldorigin = self.origin; + if (!self.wait) + self.wait = 5; // 5 seconds before closing +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/effects.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/effects.qc new file mode 100755 index 00000000..293a8f23 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/effects.qc differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/enforcer.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/enforcer.qc new file mode 100755 index 00000000..2e520190 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/enforcer.qc @@ -0,0 +1,349 @@ +/* +============================================================================== + +SOLDIER / PLAYER + +============================================================================== +*/ + +$cd id1/models/enforcer +$origin 0 -6 24 +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 +$frame walk11 walk12 walk13 walk14 walk15 walk16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame attack1 attack2 attack3 attack4 attack5 attack6 +$frame attack7 attack8 attack9 attack10 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 death11 death12 death13 death14 + +$frame fdeath1 fdeath2 fdeath3 fdeath4 fdeath5 fdeath6 fdeath7 fdeath8 +$frame fdeath9 fdeath10 fdeath11 + +$frame paina1 paina2 paina3 paina4 + +$frame painb1 painb2 painb3 painb4 painb5 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 +$frame paind9 paind10 paind11 paind12 paind13 paind14 paind15 paind16 +$frame paind17 paind18 paind19 + + +void() Laser_Touch = +{ + local vector org; + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + + sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); + org = self.origin - 8*normalize(self.velocity); + + if (other.health) + { + SpawnBlood (org, self.velocity*0.2, 15); + T_Damage (other, self, self.owner, 15); + } + else + { + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_GUNSHOT); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); + } + + remove(self); +}; + +void(vector org, vector vec) LaunchLaser = +{ + if (self.classname == "monster_enforcer") + sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM); + + vec = normalize(vec); + + newmis = spawn(); + newmis.owner = self; + newmis.movetype = MOVETYPE_FLY; + newmis.solid = SOLID_BBOX; + newmis.effects = EF_DIMLIGHT; + + setmodel (newmis, "progs/laser.mdl"); + setsize (newmis, '0 0 0', '0 0 0'); + + setorigin (newmis, org); + + newmis.velocity = vec * 600; + newmis.angles = vectoangles(newmis.velocity); + + newmis.nextthink = time + 5; + newmis.think = SUB_Remove; + newmis.touch = Laser_Touch; +}; + + + +void() enforcer_fire = +{ + local vector org; + + self.effects = self.effects | EF_MUZZLEFLASH; + makevectors (self.angles); + + org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16'; + + LaunchLaser(org, self.enemy.origin - self.origin); +}; + +//============================================================================ + +void() enf_stand1 =[ $stand1, enf_stand2 ] {ai_stand();}; +void() enf_stand2 =[ $stand2, enf_stand3 ] {ai_stand();}; +void() enf_stand3 =[ $stand3, enf_stand4 ] {ai_stand();}; +void() enf_stand4 =[ $stand4, enf_stand5 ] {ai_stand();}; +void() enf_stand5 =[ $stand5, enf_stand6 ] {ai_stand();}; +void() enf_stand6 =[ $stand6, enf_stand7 ] {ai_stand();}; +void() enf_stand7 =[ $stand7, enf_stand1 ] {ai_stand();}; + +void() enf_walk1 =[ $walk1 , enf_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); +ai_walk(2);}; +void() enf_walk2 =[ $walk2 , enf_walk3 ] {ai_walk(4);}; +void() enf_walk3 =[ $walk3 , enf_walk4 ] {ai_walk(4);}; +void() enf_walk4 =[ $walk4 , enf_walk5 ] {ai_walk(3);}; +void() enf_walk5 =[ $walk5 , enf_walk6 ] {ai_walk(1);}; +void() enf_walk6 =[ $walk6 , enf_walk7 ] {ai_walk(2);}; +void() enf_walk7 =[ $walk7 , enf_walk8 ] {ai_walk(2);}; +void() enf_walk8 =[ $walk8 , enf_walk9 ] {ai_walk(1);}; +void() enf_walk9 =[ $walk9 , enf_walk10 ] {ai_walk(2);}; +void() enf_walk10 =[ $walk10, enf_walk11 ] {ai_walk(4);}; +void() enf_walk11 =[ $walk11, enf_walk12 ] {ai_walk(4);}; +void() enf_walk12 =[ $walk12, enf_walk13 ] {ai_walk(1);}; +void() enf_walk13 =[ $walk13, enf_walk14 ] {ai_walk(2);}; +void() enf_walk14 =[ $walk14, enf_walk15 ] {ai_walk(3);}; +void() enf_walk15 =[ $walk15, enf_walk16 ] {ai_walk(4);}; +void() enf_walk16 =[ $walk16, enf_walk1 ] {ai_walk(2);}; + +void() enf_run1 =[ $run1 , enf_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); +ai_run(18);}; +void() enf_run2 =[ $run2 , enf_run3 ] {ai_run(14);}; +void() enf_run3 =[ $run3 , enf_run4 ] {ai_run(7);}; +void() enf_run4 =[ $run4 , enf_run5 ] {ai_run(12);}; +void() enf_run5 =[ $run5 , enf_run6 ] {ai_run(14);}; +void() enf_run6 =[ $run6 , enf_run7 ] {ai_run(14);}; +void() enf_run7 =[ $run7 , enf_run8 ] {ai_run(7);}; +void() enf_run8 =[ $run8 , enf_run1 ] {ai_run(11);}; + +void() enf_atk1 =[ $attack1, enf_atk2 ] {ai_face();}; +void() enf_atk2 =[ $attack2, enf_atk3 ] {ai_face();}; +void() enf_atk3 =[ $attack3, enf_atk4 ] {ai_face();}; +void() enf_atk4 =[ $attack4, enf_atk5 ] {ai_face();}; +void() enf_atk5 =[ $attack5, enf_atk6 ] {ai_face();}; +void() enf_atk6 =[ $attack6, enf_atk7 ] {enforcer_fire();}; +void() enf_atk7 =[ $attack7, enf_atk8 ] {ai_face();}; +void() enf_atk8 =[ $attack8, enf_atk9 ] {ai_face();}; +void() enf_atk9 =[ $attack5, enf_atk10 ] {ai_face();}; +void() enf_atk10 =[ $attack6, enf_atk11 ] {enforcer_fire();}; +void() enf_atk11 =[ $attack7, enf_atk12 ] {ai_face();}; +void() enf_atk12 =[ $attack8, enf_atk13 ] {ai_face();}; +void() enf_atk13 =[ $attack9, enf_atk14 ] {ai_face();}; +void() enf_atk14 =[ $attack10, enf_run1 ] {ai_face(); +SUB_CheckRefire (enf_atk1); +}; + +void() enf_paina1 =[ $paina1, enf_paina2 ] {}; +void() enf_paina2 =[ $paina2, enf_paina3 ] {}; +void() enf_paina3 =[ $paina3, enf_paina4 ] {}; +void() enf_paina4 =[ $paina4, enf_run1 ] {}; + +void() enf_painb1 =[ $painb1, enf_painb2 ] {}; +void() enf_painb2 =[ $painb2, enf_painb3 ] {}; +void() enf_painb3 =[ $painb3, enf_painb4 ] {}; +void() enf_painb4 =[ $painb4, enf_painb5 ] {}; +void() enf_painb5 =[ $painb5, enf_run1 ] {}; + +void() enf_painc1 =[ $painc1, enf_painc2 ] {}; +void() enf_painc2 =[ $painc2, enf_painc3 ] {}; +void() enf_painc3 =[ $painc3, enf_painc4 ] {}; +void() enf_painc4 =[ $painc4, enf_painc5 ] {}; +void() enf_painc5 =[ $painc5, enf_painc6 ] {}; +void() enf_painc6 =[ $painc6, enf_painc7 ] {}; +void() enf_painc7 =[ $painc7, enf_painc8 ] {}; +void() enf_painc8 =[ $painc8, enf_run1 ] {}; + +void() enf_paind1 =[ $paind1, enf_paind2 ] {}; +void() enf_paind2 =[ $paind2, enf_paind3 ] {}; +void() enf_paind3 =[ $paind3, enf_paind4 ] {}; +void() enf_paind4 =[ $paind4, enf_paind5 ] {ai_painforward(2);}; +void() enf_paind5 =[ $paind5, enf_paind6 ] {ai_painforward(1);}; +void() enf_paind6 =[ $paind6, enf_paind7 ] {}; +void() enf_paind7 =[ $paind7, enf_paind8 ] {}; +void() enf_paind8 =[ $paind8, enf_paind9 ] {}; +void() enf_paind9 =[ $paind9, enf_paind10 ] {}; +void() enf_paind10 =[ $paind10, enf_paind11 ] {}; +void() enf_paind11 =[ $paind11, enf_paind12 ] {ai_painforward(1);}; +void() enf_paind12 =[ $paind12, enf_paind13 ] {ai_painforward(1);}; +void() enf_paind13 =[ $paind13, enf_paind14 ] {ai_painforward(1);}; +void() enf_paind14 =[ $paind14, enf_paind15 ] {}; +void() enf_paind15 =[ $paind15, enf_paind16 ] {}; +void() enf_paind16 =[ $paind16, enf_paind17 ] {ai_pain(1);}; +void() enf_paind17 =[ $paind17, enf_paind18 ] {ai_pain(1);}; +void() enf_paind18 =[ $paind18, enf_paind19 ] {}; +void() enf_paind19 =[ $paind19, enf_run1 ] {}; + +void(entity attacker, float damage) enf_pain = +{ + local float r; + + r = random (); + if (self.pain_finished > time) + return; + + + if (r < 0.5) + sound (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM); + + if (r < 0.2) + { + self.pain_finished = time + 1; + enf_paina1 (); + } + else if (r < 0.4) + { + self.pain_finished = time + 1; + enf_painb1 (); + } + else if (r < 0.7) + { + self.pain_finished = time + 1; + enf_painc1 (); + } + else + { + self.pain_finished = time + 2; + enf_paind1 (); + } +}; + +//============================================================================ + + + + +void() enf_die1 =[ $death1, enf_die2 ] {}; +void() enf_die2 =[ $death2, enf_die3 ] {}; +void() enf_die3 =[ $death3, enf_die4 ] +{self.solid = SOLID_NOT;self.ammo_cells = 5;DropBackpack();}; +void() enf_die4 =[ $death4, enf_die5 ] {ai_forward(14);}; +void() enf_die5 =[ $death5, enf_die6 ] {ai_forward(2);}; +void() enf_die6 =[ $death6, enf_die7 ] {}; +void() enf_die7 =[ $death7, enf_die8 ] {}; +void() enf_die8 =[ $death8, enf_die9 ] {}; +void() enf_die9 =[ $death9, enf_die10 ] {ai_forward(3);}; +void() enf_die10 =[ $death10, enf_die11 ] {ai_forward(5);}; +void() enf_die11 =[ $death11, enf_die12 ] {ai_forward(5);}; +void() enf_die12 =[ $death12, enf_die13 ] {ai_forward(5);}; +void() enf_die13 =[ $death13, enf_die14 ] {}; +void() enf_die14 =[ $death14, enf_die14 ] {}; + +void() enf_fdie1 =[ $fdeath1, enf_fdie2 ] { + +}; +void() enf_fdie2 =[ $fdeath2, enf_fdie3 ] {}; +void() enf_fdie3 =[ $fdeath3, enf_fdie4 ] +{self.solid = SOLID_NOT;self.ammo_cells = 5;DropBackpack();}; +void() enf_fdie4 =[ $fdeath4, enf_fdie5 ] {}; +void() enf_fdie5 =[ $fdeath5, enf_fdie6 ] {}; +void() enf_fdie6 =[ $fdeath6, enf_fdie7 ] {}; +void() enf_fdie7 =[ $fdeath7, enf_fdie8 ] {}; +void() enf_fdie8 =[ $fdeath8, enf_fdie9 ] {}; +void() enf_fdie9 =[ $fdeath9, enf_fdie10 ] {}; +void() enf_fdie10 =[ $fdeath10, enf_fdie11 ] {}; +void() enf_fdie11 =[ $fdeath11, enf_fdie11 ] {}; + + +void() enf_die = +{ +// check for gib + if (self.health < -35) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_mega.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM); + if (random() > 0.5) + enf_die1 (); + else + enf_fdie1 (); +}; + + +/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) Ambush + +*/ +void() monster_enforcer = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/enforcer.mdl"); + precache_model2 ("progs/h_mega.mdl"); + precache_model2 ("progs/laser.mdl"); + + precache_sound2 ("enforcer/death1.wav"); + precache_sound2 ("enforcer/enfire.wav"); + precache_sound2 ("enforcer/enfstop.wav"); + precache_sound2 ("enforcer/idle1.wav"); + precache_sound2 ("enforcer/pain1.wav"); + precache_sound2 ("enforcer/pain2.wav"); + precache_sound2 ("enforcer/sight1.wav"); + precache_sound2 ("enforcer/sight2.wav"); + precache_sound2 ("enforcer/sight3.wav"); + precache_sound2 ("enforcer/sight4.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/enforcer.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 80; + + self.th_stand = enf_stand1; + self.th_walk = enf_walk1; + self.th_run = enf_run1; + self.th_pain = enf_pain; + self.th_die = enf_die; + self.th_missile = enf_atk1; + + walkmonster_start(); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/fight.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/fight.qc new file mode 100755 index 00000000..4a3a4c26 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/fight.qc @@ -0,0 +1,407 @@ + +/* + +A monster is in fight mode if it thinks it can effectively attack its +enemy. + +When it decides it can't attack, it goes into hunt mode. + +*/ + +float(float v) anglemod; + +void() knight_atk1; +void() knight_runatk1; +void() ogre_smash1; +void() ogre_swing1; + +void() sham_smash1; +void() sham_swingr1; +void() sham_swingl1; + +float() DemonCheckAttack; +void(float side) Demon_Melee; + +void(vector dest) ChooseTurn; + +void() ai_face; + + +float enemy_vis, enemy_infront, enemy_range; +float enemy_yaw; + + +void() knight_attack = +{ + local float len; + +// decide if now is a good swing time + len = vlen(self.enemy.origin+self.enemy.view_ofs - (self.origin+self.view_ofs)); + + if (len<80) + knight_atk1 (); + else + knight_runatk1 (); +}; + +//============================================================================= + +/* +=========== +CheckAttack + +The player is in view, so decide to move or launch an attack +Returns FALSE if movement should continue +============ +*/ +float() CheckAttack = +{ + local vector spot1, spot2; + local entity targ; + local float chance; + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + traceline (spot1, spot2, FALSE, self); + + if (trace_ent != targ) + return FALSE; // don't have a clear shot + + if (trace_inopen && trace_inwater) + return FALSE; // sight line crossed contents + + if (enemy_range == RANGE_MELEE) + { // melee attack + if (self.th_melee) + { + if (self.classname == "monster_knight") + knight_attack (); + else + self.th_melee (); + return TRUE; + } + } + +// missile attack + if (!self.th_missile) + return FALSE; + + if (time < self.attack_finished) + return FALSE; + + if (enemy_range == RANGE_FAR) + return FALSE; + + if (enemy_range == RANGE_MELEE) + { + chance = 0.9; + self.attack_finished = 0; + } + else if (enemy_range == RANGE_NEAR) + { + if (self.th_melee) + chance = 0.2; + else + chance = 0.4; + } + else if (enemy_range == RANGE_MID) + { + if (self.th_melee) + chance = 0.05; + else + chance = 0.1; + } + else + chance = 0; + + if (random () < chance) + { + self.th_missile (); + SUB_AttackFinished (2*random()); + return TRUE; + } + + return FALSE; +}; + + +/* +============= +ai_face + +Stay facing the enemy +============= +*/ +void() ai_face = +{ + self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); + ChangeYaw (); +}; + +/* +============= +ai_charge + +The monster is in a melee attack, so get as close as possible to .enemy +============= +*/ +float (entity targ) visible; +float(entity targ) infront; +float(entity targ) range; + +void(float d) ai_charge = +{ + ai_face (); + movetogoal (d); // done in C code... +}; + +void() ai_charge_side = +{ + local vector dtemp; + local float heading; + +// aim to the left of the enemy for a flyby + + self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); + ChangeYaw (); + + makevectors (self.angles); + dtemp = self.enemy.origin - 30*v_right; + heading = vectoyaw(dtemp - self.origin); + + walkmove(heading, 20); +}; + + +/* +============= +ai_melee + +============= +*/ +void() ai_melee = +{ + local vector delta; + local float ldmg; + + if (!self.enemy) + return; // removed before stroke + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 60) + return; + + ldmg = (random() + random() + random()) * 3; + T_Damage (self.enemy, self, self, ldmg); +}; + + +void() ai_melee_side = +{ + local vector delta; + local float ldmg; + + if (!self.enemy) + return; // removed before stroke + + ai_charge_side(); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 60) + return; + if (!CanDamage (self.enemy, self)) + return; + ldmg = (random() + random() + random()) * 3; + T_Damage (self.enemy, self, self, ldmg); +}; + + +//============================================================================= + +/* +=========== +SoldierCheckAttack + +The player is in view, so decide to move or launch an attack +Returns FALSE if movement should continue +============ +*/ +float() SoldierCheckAttack = +{ + local vector spot1, spot2; + local entity targ; + local float chance; + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + traceline (spot1, spot2, FALSE, self); + + if (trace_inopen && trace_inwater) + return FALSE; // sight line crossed contents + + if (trace_ent != targ) + return FALSE; // don't have a clear shot + + +// missile attack + if (time < self.attack_finished) + return FALSE; + + if (enemy_range == RANGE_FAR) + return FALSE; + + if (enemy_range == RANGE_MELEE) + chance = 0.9; + else if (enemy_range == RANGE_NEAR) + chance = 0.4; + else if (enemy_range == RANGE_MID) + chance = 0.05; + else + chance = 0; + + if (random () < chance) + { + self.th_missile (); + SUB_AttackFinished (1 + random()); + if (random() < 0.3) + self.lefty = !self.lefty; + + return TRUE; + } + + return FALSE; +}; +//============================================================================= + +/* +=========== +ShamCheckAttack + +The player is in view, so decide to move or launch an attack +Returns FALSE if movement should continue +============ +*/ +float() ShamCheckAttack = +{ + local vector spot1, spot2; + local entity targ; + + if (enemy_range == RANGE_MELEE) + { + if (CanDamage (self.enemy, self)) + { + self.attack_state = AS_MELEE; + return TRUE; + } + } + + if (time < self.attack_finished) + return FALSE; + + if (!enemy_vis) + return FALSE; + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + if (vlen(spot1 - spot2) > 600) + return FALSE; + + traceline (spot1, spot2, FALSE, self); + + if (trace_inopen && trace_inwater) + return FALSE; // sight line crossed contents + + if (trace_ent != targ) + { + return FALSE; // don't have a clear shot + } + +// missile attack + if (enemy_range == RANGE_FAR) + return FALSE; + + self.attack_state = AS_MISSILE; + SUB_AttackFinished (2 + 2*random()); + return TRUE; +}; + +//============================================================================ + +/* +=========== +OgreCheckAttack + +The player is in view, so decide to move or launch an attack +Returns FALSE if movement should continue +============ +*/ +float() OgreCheckAttack = +{ + local vector spot1, spot2; + local entity targ; + local float chance; + + if (enemy_range == RANGE_MELEE) + { + if (CanDamage (self.enemy, self)) + { + self.attack_state = AS_MELEE; + return TRUE; + } + } + + if (time < self.attack_finished) + return FALSE; + + if (!enemy_vis) + return FALSE; + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + traceline (spot1, spot2, FALSE, self); + + if (trace_inopen && trace_inwater) + return FALSE; // sight line crossed contents + + if (trace_ent != targ) + { + return FALSE; // don't have a clear shot + } + +// missile attack + if (time < self.attack_finished) + return FALSE; + + if (enemy_range == RANGE_FAR) + return FALSE; + + else if (enemy_range == RANGE_NEAR) + chance = 0.10; + else if (enemy_range == RANGE_MID) + chance = 0.05; + else + chance = 0; + + self.attack_state = AS_MISSILE; + SUB_AttackFinished (1 + 2*random()); + return TRUE; +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/fish.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/fish.qc new file mode 100755 index 00000000..ce6e26ee --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/fish.qc @@ -0,0 +1,186 @@ +$cd id1/models/fish +$origin 0 0 24 +$base base +$skin skin + +$frame attack1 attack2 attack3 attack4 attack5 attack6 +$frame attack7 attack8 attack9 attack10 attack11 attack12 attack13 +$frame attack14 attack15 attack16 attack17 attack18 + +$frame death1 death2 death3 death4 death5 death6 death7 +$frame death8 death9 death10 death11 death12 death13 death14 death15 +$frame death16 death17 death18 death19 death20 death21 + +$frame swim1 swim2 swim3 swim4 swim5 swim6 swim7 swim8 +$frame swim9 swim10 swim11 swim12 swim13 swim14 swim15 swim16 swim17 +$frame swim18 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8 +$frame pain9 + +void() swimmonster_start; + +void() f_stand1 =[ $swim1, f_stand2 ] {ai_stand();}; +void() f_stand2 =[ $swim2, f_stand3 ] {ai_stand();}; +void() f_stand3 =[ $swim3, f_stand4 ] {ai_stand();}; +void() f_stand4 =[ $swim4, f_stand5 ] {ai_stand();}; +void() f_stand5 =[ $swim5, f_stand6 ] {ai_stand();}; +void() f_stand6 =[ $swim6, f_stand7 ] {ai_stand();}; +void() f_stand7 =[ $swim7, f_stand8 ] {ai_stand();}; +void() f_stand8 =[ $swim8, f_stand9 ] {ai_stand();}; +void() f_stand9 =[ $swim9, f_stand10 ] {ai_stand();}; +void() f_stand10 =[ $swim10, f_stand11 ] {ai_stand();}; +void() f_stand11 =[ $swim11, f_stand12 ] {ai_stand();}; +void() f_stand12 =[ $swim12, f_stand13 ] {ai_stand();}; +void() f_stand13 =[ $swim13, f_stand14 ] {ai_stand();}; +void() f_stand14 =[ $swim14, f_stand15 ] {ai_stand();}; +void() f_stand15 =[ $swim15, f_stand16 ] {ai_stand();}; +void() f_stand16 =[ $swim16, f_stand17 ] {ai_stand();}; +void() f_stand17 =[ $swim17, f_stand18 ] {ai_stand();}; +void() f_stand18 =[ $swim18, f_stand1 ] {ai_stand();}; + +void() f_walk1 =[ $swim1, f_walk2 ] {ai_walk(8);}; +void() f_walk2 =[ $swim2, f_walk3 ] {ai_walk(8);}; +void() f_walk3 =[ $swim3, f_walk4 ] {ai_walk(8);}; +void() f_walk4 =[ $swim4, f_walk5 ] {ai_walk(8);}; +void() f_walk5 =[ $swim5, f_walk6 ] {ai_walk(8);}; +void() f_walk6 =[ $swim6, f_walk7 ] {ai_walk(8);}; +void() f_walk7 =[ $swim7, f_walk8 ] {ai_walk(8);}; +void() f_walk8 =[ $swim8, f_walk9 ] {ai_walk(8);}; +void() f_walk9 =[ $swim9, f_walk10 ] {ai_walk(8);}; +void() f_walk10 =[ $swim10, f_walk11 ] {ai_walk(8);}; +void() f_walk11 =[ $swim11, f_walk12 ] {ai_walk(8);}; +void() f_walk12 =[ $swim12, f_walk13 ] {ai_walk(8);}; +void() f_walk13 =[ $swim13, f_walk14 ] {ai_walk(8);}; +void() f_walk14 =[ $swim14, f_walk15 ] {ai_walk(8);}; +void() f_walk15 =[ $swim15, f_walk16 ] {ai_walk(8);}; +void() f_walk16 =[ $swim16, f_walk17 ] {ai_walk(8);}; +void() f_walk17 =[ $swim17, f_walk18 ] {ai_walk(8);}; +void() f_walk18 =[ $swim18, f_walk1 ] {ai_walk(8);}; + +void() f_run1 =[ $swim1, f_run2 ] {ai_run(12); + if (random() < 0.5) + sound (self, CHAN_VOICE, "fish/idle.wav", 1, ATTN_NORM); +}; +void() f_run2 =[ $swim3, f_run3 ] {ai_run(12);}; +void() f_run3 =[ $swim5, f_run4 ] {ai_run(12);}; +void() f_run4 =[ $swim7, f_run5 ] {ai_run(12);}; +void() f_run5 =[ $swim9, f_run6 ] {ai_run(12);}; +void() f_run6 =[ $swim11, f_run7 ] {ai_run(12);}; +void() f_run7 =[ $swim13, f_run8 ] {ai_run(12);}; +void() f_run8 =[ $swim15, f_run9 ] {ai_run(12);}; +void() f_run9 =[ $swim17, f_run1 ] {ai_run(12);}; + +void() fish_melee = +{ + local vector delta; + local float ldmg; + + if (!self.enemy) + return; // removed before stroke + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 60) + return; + + sound (self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM); + ldmg = (random() + random()) * 3; + T_Damage (self.enemy, self, self, ldmg); +}; + +void() f_attack1 =[ $attack1, f_attack2 ] {ai_charge(10);}; +void() f_attack2 =[ $attack2, f_attack3 ] {ai_charge(10);}; +void() f_attack3 =[ $attack3, f_attack4 ] {fish_melee();}; +void() f_attack4 =[ $attack4, f_attack5 ] {ai_charge(10);}; +void() f_attack5 =[ $attack5, f_attack6 ] {ai_charge(10);}; +void() f_attack6 =[ $attack6, f_attack7 ] {ai_charge(10);}; +void() f_attack7 =[ $attack7, f_attack8 ] {ai_charge(10);}; +void() f_attack8 =[ $attack8, f_attack9 ] {ai_charge(10);}; +void() f_attack9 =[ $attack9, f_attack10] {fish_melee();}; +void() f_attack10 =[ $attack10, f_attack11] {ai_charge(10);}; +void() f_attack11 =[ $attack11, f_attack12] {ai_charge(10);}; +void() f_attack12 =[ $attack12, f_attack13] {ai_charge(10);}; +void() f_attack13 =[ $attack13, f_attack14] {ai_charge(10);}; +void() f_attack14 =[ $attack14, f_attack15] {ai_charge(10);}; +void() f_attack15 =[ $attack15, f_attack16] {fish_melee();}; +void() f_attack16 =[ $attack16, f_attack17] {ai_charge(10);}; +void() f_attack17 =[ $attack17, f_attack18] {ai_charge(10);}; +void() f_attack18 =[ $attack18, f_run1 ] {ai_charge(10);}; + +void() f_death1 =[ $death1, f_death2 ] { +sound (self, CHAN_VOICE, "fish/death.wav", 1, ATTN_NORM); +}; +void() f_death2 =[ $death2, f_death3 ] {}; +void() f_death3 =[ $death3, f_death4 ] {}; +void() f_death4 =[ $death4, f_death5 ] {}; +void() f_death5 =[ $death5, f_death6 ] {}; +void() f_death6 =[ $death6, f_death7 ] {}; +void() f_death7 =[ $death7, f_death8 ] {}; +void() f_death8 =[ $death8, f_death9 ] {}; +void() f_death9 =[ $death9, f_death10 ] {}; +void() f_death10 =[ $death10, f_death11 ] {}; +void() f_death11 =[ $death11, f_death12 ] {}; +void() f_death12 =[ $death12, f_death13 ] {}; +void() f_death13 =[ $death13, f_death14 ] {}; +void() f_death14 =[ $death14, f_death15 ] {}; +void() f_death15 =[ $death15, f_death16 ] {}; +void() f_death16 =[ $death16, f_death17 ] {}; +void() f_death17 =[ $death17, f_death18 ] {}; +void() f_death18 =[ $death18, f_death19 ] {}; +void() f_death19 =[ $death19, f_death20 ] {}; +void() f_death20 =[ $death20, f_death21 ] {}; +void() f_death21 =[ $death21, f_death21 ] {self.solid = SOLID_NOT;}; + +void() f_pain1 =[ $pain1, f_pain2 ] {}; +void() f_pain2 =[ $pain2, f_pain3 ] {ai_pain(6);}; +void() f_pain3 =[ $pain3, f_pain4 ] {ai_pain(6);}; +void() f_pain4 =[ $pain4, f_pain5 ] {ai_pain(6);}; +void() f_pain5 =[ $pain5, f_pain6 ] {ai_pain(6);}; +void() f_pain6 =[ $pain6, f_pain7 ] {ai_pain(6);}; +void() f_pain7 =[ $pain7, f_pain8 ] {ai_pain(6);}; +void() f_pain8 =[ $pain8, f_pain9 ] {ai_pain(6);}; +void() f_pain9 =[ $pain9, f_run1 ] {ai_pain(6);}; + +void(entity attacker, float damage) fish_pain = +{ + +// fish allways do pain frames + f_pain1 (); +}; + + + +/*QUAKED monster_fish (1 0 0) (-16 -16 -24) (16 16 24) Ambush +*/ +void() monster_fish = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/fish.mdl"); + + precache_sound2 ("fish/death.wav"); + precache_sound2 ("fish/bite.wav"); + precache_sound2 ("fish/idle.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/fish.mdl"); + + setsize (self, '-16 -16 -24', '16 16 24'); + self.health = 25; + + self.th_stand = f_stand1; + self.th_walk = f_walk1; + self.th_run = f_run1; + self.th_die = f_death1; + self.th_pain = fish_pain; + self.th_melee = f_attack1; + + swimmonster_start (); +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/flag.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/flag.qc new file mode 100755 index 00000000..44daa003 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/flag.qc @@ -0,0 +1,8 @@ +/*QUAKED item_deathball (.3 .3 1) (0 0 0) (32 32 32) +*/ +void() deathball_touch; + +void() item_deathball = +{ + self.touch = deathball_touch; +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot.qc new file mode 100755 index 00000000..a14716e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot.qc @@ -0,0 +1,1219 @@ + +/* +====================================== +FrikBot X (Version 0.10.0) +====================================== + +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. + + +====================================== +These installation instructions only apply to Normal Quake (as does this +entire file). For QuakeWorld, please refer to bot_qw.qc + +-------------------------------------- +To install on a new mod, do all this: +-------------------------------------- +Place all included bot*.qc files in the subdirectory "frikbot" +in your source folder, then... + +* Add the following lines to progs.src right after the defs.qc line +frikbot/bot.qc +frikbot/bot_way.qc +frikbot/bot_fight.qc +frikbot/bot_ai.qc +frikbot/bot_misc.qc +frikbot/bot_phys.qc +frikbot/bot_move.qc +frikbot/bot_ed.qc + +-------------------------------------- +* Comment out the following functions in defs.qc +sound, stuffcmd, sprint, aim, centerprint, setspawnparms +WriteByte, WriteChar, WriteShort, WriteLong, WriteCoord +WriteAngle, WriteString, WriteEntity +-------------------------------------- +* Add this to worldspawn() in world.qc, right at the very top, before InitBodyQue(); +BotInit(); // FrikBot +-------------------------------------- +* add this line to StartFrame() in world.qc, at the very top +BotFrame(); // FrikBot +-------------------------------------- +* Add these two lines to PlayerPreThink in client.qc at the very top +if (BotPreFrame()) // FrikBot + return; +-------------------------------------- +* Add this line to PlayerPostThink in client.qc at the very top +if (BotPostFrame()) // FrikBot + return; +-------------------------------------- +* Add the following line to the very top of Client Connect in client.qc +ClientInRankings(); // FrikBot +-------------------------------------- +* Add these lines to the very top of ClientDisconnect in client.qc +ClientDisconnected(); // FrikBot +-------------------------------------- +*/ + +void() bot_map_load = +{ + // place your qc loaded waypoints here +/* + if (mapname == "dm1") + map_dm1(); + else if (mapname == "dm2") + map_dm2(); + else if (mapname == "dm3") + map_dm3(); + else if (mapname == "dm4") + map_dm4(); + else if (mapname == "dm5") + map_dm5(); + else if (mapname == "dm6") + map_dm6(); +*/ + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Variables and shtuff + +bot.qc has become pretty much a header file +for all variable in the bot... + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +// ----- entity fields --- +.float wallhug, keys, oldkeys, ishuman; +.float b_frags, b_clientno, b_shirt, b_pants; +.float ai_time, b_sound, missile_speed; +.float portal_time, b_skill, switch_wallhug; +.float b_aiflags, b_num, b_chattime; +.float b_menu, b_menu_time, b_menu_value; +.float route_failed, dyn_flags, dyn_time; +.float dyn_plat; +.entity temp_way, last_way, phys_obj; +.entity target1, target2, target3, target4; +.entity _next, _last; +.entity current_way; +.vector b_angle, mouse_emu, obs_dir; +.vector movevect, b_dir; +.vector dyn_dest; + +// --------defines----- +float SVC_UPDATENAME = 13; +float SVC_UPDATEFRAGS = 14; +float SVC_UPDATECOLORS = 17; + +// used for the physics & movement AI +float KEY_MOVEUP = 1; +float KEY_MOVEDOWN = 2; +float KEY_MOVELEFT = 4; +float KEY_MOVERIGHT = 8; +float KEY_MOVEFORWARD = 16; +float KEY_MOVEBACK = 32; +float KEY_LOOKUP = 64; +float KEY_LOOKDOWN = 128; +float KEY_LOOKLEFT = 256; +float KEY_LOOKRIGHT = 512; + +// these are aiflags for waypoints +// some overlap to the bot +float AI_TELELINK_1 = 1; // link type +float AI_TELELINK_2 = 2; // link type +float AI_TELELINK_3 = 4; // link type +float AI_TELELINK_4 = 8; // link type +float AI_DOORFLAG = 16; // read ahead +float AI_PRECISION = 32; // read ahead + point +float AI_SURFACE = 64; // point +float AI_BLIND = 128; // read ahead + point +float AI_JUMP = 256; // point + ignore +float AI_DIRECTIONAL = 512; // read ahead + ignore +float AI_PLAT_BOTTOM = 1024; // read ahead +float AI_RIDE_TRAIN = 2048; // read ahead +float AI_SUPER_JUMP = 4096; // point + ignore + route test +float AI_SNIPER = 8192; // point type +float AI_AMBUSH = 16384; // point type +float AI_DOOR_NO_OPEN = 32768; // read ahead +float AI_DIFFICULT = 65536; // route test +float AI_TRACE_TEST = 131072; // route test + +// these are flags for bots/players (dynamic/editor flags) +float AI_OBSTRUCTED = 1; +float AI_HOLD_SELECT = 2; +float AI_ROUTE_FAILED = 2; +float AI_WAIT = 4; +float AI_DANGER = 8; + + +// addition masks +float AI_POINT_TYPES = 29152; +float AI_READAHEAD_TYPES = 36528; +float AI_IGNORE_TYPES = 4864; + +float WM_UNINIT = 0; +float WM_DYNAMIC = 1; +float WM_LOADING = 2; +float WM_LOADED = 3; +float WM_EDITOR = 4; +float WM_EDITOR_DYNAMIC = 5; +float WM_EDITOR_DYNLINK = 6; + + +float OPT_SAVEBOTS = 1; +float OPT_NOCHAT = 2; + +// -------globals----- +float active_clients; +float max_clients, real_frametime; +float bot_count, b_options; +float waypoint_mode, dump_mode; +float waypoints, direct_route; +float sv_friction, sv_gravity; +float sv_accelerate, sv_maxspeed, sv_stopspeed; +entity fixer; +entity route_table; +entity b_temp1, b_temp2, b_temp3; +entity player_head, phys_head, way_head; +float busy_waypoints; +float saved_bots, saved_skills1, saved_skills2, current_bots; + +// -------ProtoTypes------ +// external +void() ClientConnect; +void() ClientDisconnect; +void() SetNewParms; + +// rankings +float(float clientno) ClientBitFlag; +float() ClientNextAvailable; +void(float whichteam, float whatbot, float whatskill) BotConnect; +void(entity bot) BotDisconnect; +void(float clientno) BotInvalidClientNo; +void(entity who) UpdateClient; + +// waypointing +void() DynamicWaypoint; +entity(vector org) make_waypoint; +void() ClearAllWays; +void() FixWaypoints; +float() begin_route; +void(entity this, float direct) bot_get_path; +void() WaypointThink; +entity(entity start) FindWayPoint; + +// physics & movement +float(entity e) bot_can_rj; +void() bot_jump; +void() frik_bot_roam; +float(vector weird) frik_walkmove; +void() frik_movetogoal; +void() frik_obstacles; +float(float flag) frik_recognize_plat; +float(vector sdir) frik_KeysForDir; +void(vector whichway, float danger) frik_obstructed; +void() SV_Physics_Client; +void() SV_ClientThink; +void() CL_KeyMove; + +// ai & misc +string() PickARandomName; +float(entity targ) fov; +float(float y1, float y2) angcomp; +float(entity targ1, entity targ2) wisible; +float(entity targ) sisible; +float(entity targ) fisible; +vector(entity ent) realorigin; +void(entity ent) target_drop; +void(entity ent) target_add; +void() KickABot; +void() BotImpulses; +void(entity targ, float success) bot_lost; +string(float r) BotName; +float(float v) frik_anglemod; +void() bot_chat; +void(float tpic) bot_start_topic; + + +// editor stuffs + +void() bot_way_edit; +void() bot_menu_display; + + +// ----------Commands--------- +void(entity e, float chan, string samp, float vol, float atten) frik_sound = #8; +void(entity client, string s) frik_stuffcmd = #21; +void(entity client, string s) frik_sprint = #24; +vector(entity e, float sped) frik_aim = #44; +void(entity client, string s) frik_centerprint = #73; +void(entity e) frik_setspawnparms = #78; +void(float to, float f) frik_WriteByte = #52; +void(float to, float f) frik_WriteChar = #53; +void(float to, float f) frik_WriteShort = #54; +void(float to, float f) frik_WriteLong = #55; +void(float to, float f) frik_WriteCoord = #56; +void(float to, float f) frik_WriteAngle = #57; +void(float to, string s) frik_WriteString = #58; +void(float to, entity s) frik_WriteEntity = #59; + +void(entity client, string s1, string s2, string s3, string s4, string s5, string s6, string s7) +frik_big_centerprint = #73; + +//---------------------------------------------------------------------------- + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Function redclarations. These allow function +designed to work for clients (sprint, so forth) +to mainly not complain when working with a bot + +Although these shouldn't be needed anymore, +as the bots truly are clients now, if you don't +stop the SZ_ buffer from filling up by disabling +direct messages to the bots, it crashes quake :-( + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(entity client, string s) stuffcmd = +{ + if (client.ishuman == 1) + frik_stuffcmd(client, s); + b_temp1 = player_head; + + while(b_temp1) + { + if (b_temp1.classname == "botcam") + { + if ((b_temp1.enemy == client) && b_temp1.ishuman) + frik_stuffcmd(b_temp1, s); + } + b_temp1 = b_temp1._next; + } +}; + +void(entity e) setspawnparms = +{ + if (e.ishuman == 1) + frik_setspawnparms(e); + else + { + b_temp1 = player_head; + while(b_temp1) + { + if (b_temp1.ishuman) + { + frik_setspawnparms(b_temp1); + return; + } + b_temp1 = b_temp1._next; + } + SetNewParms(); + } +}; +void(entity client, string s) sprint = +{ + if (client.ishuman == 1) + frik_sprint(client, s); + b_temp1 = player_head; + + while(b_temp1) + { + if (b_temp1.classname == "botcam") + { + if ((b_temp1.enemy == client) && b_temp1.ishuman) + frik_sprint(b_temp1, s); + } + b_temp1 = b_temp1._next; + } + +}; +void(entity client, string s) centerprint = +{ + if (client.ishuman == 1) + frik_centerprint(client, s); + b_temp1 = player_head; + + while(b_temp1) + { + if (b_temp1.classname == "botcam") + { + if ((b_temp1.enemy == client) && b_temp1.ishuman) + frik_centerprint(b_temp1, s); + } + b_temp1 = b_temp1._next; + } +}; + +vector(entity e, float sped) aim = +{ + e.missile_speed = sped; + return frik_aim(e, sped); +}; + +void(entity e, float chan, string samp, float vol, float atten) sound = +{ + + frik_sound(e, chan, samp, vol, atten); + if (samp == "items/inv3.wav") + return; + else if (e.classname == "player") + e.b_sound = time + 1; + else if (other.classname == "player") + other.b_sound = time + 1; + +}; +void(float to, float f) WriteByte = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteByte(to, f); +}; +void(float to, float f) WriteChar = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteChar(to, f); +}; +void(float to, float f) WriteShort = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteShort(to, f); +}; +void(float to, float f) WriteLong = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteLong(to, f); +}; +void(float to, float f) WriteCoord = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteCoord(to, f); +}; +void(float to, float f) WriteAngle = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteAngle(to, f); +}; +void(float to, string s) WriteString = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteString(to, s); +}; +void(float to, entity s) WriteEntity = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteEntity(to, s); +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Cam, see what the bot sees (or any other player) + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float() botcam = +{ + if (self.classname != "botcam") + return FALSE; + setorigin(self, self.enemy.origin); + self.items = self.enemy.items; + self.weapon = self.enemy.weapon; + self.weaponmodel = self.enemy.weaponmodel; + self.currentammo = self.enemy.currentammo; + self.weaponframe = self.enemy.weaponframe; + self.ammo_shells = self.enemy.ammo_shells; + self.ammo_nails = self.enemy.ammo_nails; + self.ammo_rockets= self.enemy.ammo_rockets; + self.ammo_cells = self.enemy.ammo_cells; + self.view_ofs = self.enemy.view_ofs; + self.health = self.enemy.health; + self.armorvalue = self.enemy.armorvalue; + self.dmg_take = self.enemy.dmg_take; + self.dmg_save = self.enemy.dmg_save; + self.dmg_inflictor = self.enemy.dmg_inflictor; + self.punchangle = self.enemy.punchangle; + self.deadflag = self.enemy.deadflag; + msg_entity = self; + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE, self.enemy); + WriteByte (MSG_ONE, 10); + WriteAngle (MSG_ONE,self.enemy.v_angle_x); + WriteAngle (MSG_ONE,self.enemy.v_angle_y); + WriteAngle (MSG_ONE,self.enemy.v_angle_z); + self.modelindex = 0; + + self.impulse = 0; + return TRUE; + +}; + +void() botcam_u = +{ + + // sloppy cycling code + if (self.classname != "botcam") + { + self.enemy = player_head; + } + else + { + do + self.enemy = self.enemy._next; + while (self.enemy.classname == "botcam"); + } + if (self.enemy == self) + { + do + self.enemy = self.enemy._next; + while (self.enemy.classname == "botcam"); + } + + self.classname = "botcam"; + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_NONE; + self.takedamage = DAMAGE_NO; + + + if (!self.enemy) + { + sprint(self, "No one left to track!\n"); + msg_entity = self; + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE, self); + PutClientInServer(); + return; + } + if (!self.enemy.ishuman) + { + self.enemy.dmg_take = 0; + self.enemy.dmg_save = 0; + } + sprint(self, "Now tracking "); + sprint(self, self.enemy.netname); + sprint(self, "\n"); +}; + + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Stuff mentioned up top +it just links the bot into the mod + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClientFixRankings = +{ + local float cno; + if (self.switch_wallhug > time) + return; + self.switch_wallhug = 0; + + b_temp2 = nextent(world); + cno = 0; + + while (cno < max_clients) + { + if ((!b_temp2.ishuman) && (active_clients & ClientBitFlag(cno))) + UpdateClient(b_temp2); + cno = cno + 1; + b_temp2 = nextent(b_temp2); + } +}; + +void() ClientInRankings = +{ + local float cno; + if (player_head) + player_head._last = self; + self._next = player_head; + player_head = self; + + if (!self.phys_obj) + { + b_temp2 = phys_head; + while (b_temp2 != world && b_temp2.owner != self) + b_temp2 = b_temp2._next; + self.phys_obj = b_temp2; + } + + if (self.ishuman == 2) + { + self.ishuman = FALSE; + return; + } + cno = self.colormap - 1; + BotInvalidClientNo (cno); + active_clients = active_clients | ClientBitFlag(cno); + + self.b_clientno = cno; + self.ishuman = TRUE; + self.switch_wallhug = time + 1; +}; + + +void() ClientDisconnected = +{ + if (player_head == self) + player_head = self._next; + if (self._next) + self._next._last = self._last; + if (self._last) + self._last._next = self._next; + active_clients = active_clients - active_clients & ClientBitFlag(self.b_clientno); +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotPreFrame & BotPostFrame, used to make the +bot easier to install + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float () BotPreFrame = +{ + if (self.b_clientno == -1) + return TRUE; + if (self.ishuman) + { + if (self.switch_wallhug) + ClientFixRankings(); + if (self.classname == "botcam") + return TRUE; + } + if (self.b_frags != self.frags) + { + + if (self.b_frags > self.frags) + { + if (pointcontents(self.origin) == CONTENT_LAVA) + bot_start_topic(10); + else + bot_start_topic(9); + } + else + bot_start_topic(2); + self.b_frags = self.frags; + } + DynamicWaypoint(); + return FALSE; +}; +float () BotPostFrame = +{ + if (self.b_clientno == -1) + return TRUE; + if (self.ishuman) + { + + if (waypoint_mode > WM_LOADED) + bot_menu_display(); + + BotImpulses(); + + if (botcam()) + return TRUE; + } + return FALSE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Chat code + +The rest of this code is in bot_misc.qc + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(string h) BotSay = // simulate talking by composing a 'chat' message +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, self.netname); + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 2); + WriteString(MSG_ALL, h); +}; +void() BotSayInit = +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, self.netname); +}; +void(string h) BotSay2 = +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 2); + WriteString(MSG_ALL, h); +}; +void(string h) BotSayTeam = +{ + local entity t; + if (!teamplay) + return; + t = player_head; + while(t) + { + if (t.team == self.team) + { + msg_entity = t; + WriteByte(MSG_ONE, 8); + WriteByte(MSG_ONE, 1); + WriteByte(MSG_ONE, 40); + WriteString(MSG_ONE, self.netname); + WriteByte(MSG_ONE, 8); + WriteByte(MSG_ONE, 2); + WriteByte(MSG_ONE, 41); + WriteString(MSG_ONE, h); + } + t = t._next; + } +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotInit + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void() BotInit = +{ + local entity ent, fisent; + local float numents; + + // spawn entities for the physics + ent = nextent(world); + max_clients = 0; + + while(ent != world) + { + max_clients = max_clients + 1; + ent = nextent(ent); + } + + ent = nextent(world); + fisent = world; + while (numents < max_clients) + { + + phys_head = spawn(); + if (fisent) + fisent._next = phys_head; + phys_head._last = fisent; + fisent = phys_head; + ent.phys_obj = phys_head; + phys_head.classname = "phys_obj"; + phys_head.owner = ent; + numents = numents + 1; + ent = nextent(ent); + } + precache_model("progs/s_light.spr"); + precache_model("progs/s_bubble.spr"); + // the bots return! + b_options = cvar("saved1"); + if (coop || (b_options & OPT_SAVEBOTS)) + { + saved_bots = cvar("scratch1"); + saved_skills1 = cvar("scratch2"); + saved_skills2 = cvar("scratch3"); + } + cvar_set ("saved4", "0"); + localcmd("exec maps/"); + localcmd(mapname); + localcmd(".way\n"); + waypoint_mode = WM_DYNAMIC; + bot_map_load(); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Rankings 'utilities'. Written by Alan Kivlin, +this code just fools clients by sending precisely +the same network messages as when a real player +signs on to the server. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void(entity who) UpdateClient = +{ + WriteByte (MSG_ALL, SVC_UPDATENAME); + WriteByte (MSG_ALL, who.b_clientno); + WriteString (MSG_ALL, who.netname); + WriteByte (MSG_ALL, SVC_UPDATECOLORS); + WriteByte (MSG_ALL, who.b_clientno); + WriteByte (MSG_ALL, who.b_shirt * 16 + who.b_pants); + WriteByte (MSG_ALL, SVC_UPDATEFRAGS); + WriteByte (MSG_ALL, who.b_clientno); + WriteShort (MSG_ALL, who.frags); +}; + +float(float clientno) ClientBitFlag = +{ + // bigger, but faster + if (clientno == 0) + return 1; + else if (clientno == 1) + return 2; + else if (clientno == 2) + return 4; + else if (clientno == 3) + return 8; + else if (clientno == 4) + return 16; + else if (clientno == 5) + return 32; + else if (clientno == 6) + return 64; + else if (clientno == 7) + return 128; + else if (clientno == 8) + return 256; + else if (clientno == 9) + return 512; + else if (clientno == 10) + return 1024; + else if (clientno == 11) + return 2048; + else if (clientno == 12) + return 4096; + else if (clientno == 13) + return 8192; + else if (clientno == 14) + return 16384; + else if (clientno == 15) + return 32768; + return 0; +}; + +float() ClientNextAvailable = +{ + local float clientno; + + clientno = max_clients; + while(clientno > 0) + { + clientno = clientno - 1; + + if(!(active_clients & ClientBitFlag(clientno))) + return clientno; + } + + return -1; +}; + + +void(entity e1, entity e2, float flag) DeveloperLightning = +{ + // used to show waypoint links for debugging + WriteByte (MSG_BROADCAST, 23); + if (flag) + WriteByte (MSG_BROADCAST, 6); + else + WriteByte (MSG_BROADCAST, 13); + WriteEntity (MSG_BROADCAST, e2); + WriteCoord (MSG_BROADCAST, e1.origin_x); + WriteCoord (MSG_BROADCAST, e1.origin_y); + WriteCoord (MSG_BROADCAST, e1.origin_z); + WriteCoord (MSG_BROADCAST, e2.origin_x); + WriteCoord (MSG_BROADCAST, e2.origin_y); + WriteCoord (MSG_BROADCAST, e2.origin_z); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Find Another Color + +Team finding code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float(float tcolor) FindAnotherColor = +{ + local float bestbet, scolor, pcount, bestp; + bestbet = -1; + bestp = 16; + while(scolor < 14) + { + if (scolor != tcolor) + { + b_temp2 = player_head; + pcount = 0; + while(b_temp2 != world) + { + if (b_temp2.team == scolor + 1) + pcount = pcount + 1; + b_temp2 = b_temp2._next; + } + if ((pcount < bestp) && pcount) + { + bestbet = scolor; + bestp = pcount; + } + } + scolor = scolor + 1; + } + if (bestbet < 0) + { + bestbet = tcolor; + while (bestbet == tcolor) + { + bestbet = floor(random() * 13); + } + } + return bestbet; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotConnect and related functions. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +entity(float num) GetClientEntity = +{ + local entity upsy; + upsy = world; + num = num + 1; + while (num > 0) + { + num = num - 1; + upsy = nextent(upsy); + } + return upsy; +}; + +void(float whichteam, float whatbot, float whatskill) BotConnect = +{ + local float f; + local string h; + local entity uself; + + f = ClientNextAvailable(); + uself = self; + if(f == -1) + { + bprint("Unable to connect a bot, server is full.\n"); + return; + } + + // chat thing + + active_clients = active_clients | ClientBitFlag(f); + bot_count = bot_count + 1; + self = GetClientEntity(f); + if (!saved_bots) + bot_start_topic(1); + self.b_clientno = f; + self.colormap = f + 1; + if (whatbot) + self.netname = BotName(whatbot); + else + self.netname = PickARandomName(); + + + // players can set skill all weird, so leave these checks in + whatskill = rint(whatskill); + if (whatskill > 3) + whatskill = 3; + else if (whatskill < 0) + whatskill = 0; + self.b_skill = whatskill; + + if (teamplay && !coop) + { + if (whichteam) + self.b_pants = FindAnotherColor(uself.team - 1); + else + self.b_pants = uself.team - 1; + self.b_shirt = self.b_pants; + } + + self.team = self.b_pants + 1; + UpdateClient(self); + SetNewParms(); + self.ishuman = 2; + ClientConnect(); + PutClientInServer(); + + // this is risky... could corrupt .way files if done wrong + // If you're not the gambling type, comment this out + + f = ClientBitFlag(self.b_num - 1); + current_bots = current_bots | f; + + if (self.b_num <= 8) + saved_skills1 = (saved_skills1 & (65536 - (3 * f)) | (self.b_skill * f)); + else + { + f = ClientBitFlag(self.b_num - 9); + saved_skills2 = (saved_skills2 & (65536 - (3 * f)) | (self.b_skill * f)); + } + + h = ftos(current_bots); + cvar_set("scratch1", h); + h = ftos(saved_skills1); + cvar_set("scratch2", h); + h = ftos(saved_skills2); + cvar_set("scratch3", h); + self = uself; + +}; + +void(entity bot) BotDisconnect = +{ + local string h; + local entity uself; + uself = self; + self = bot; + + bot_count = bot_count - 1; + current_bots = current_bots - (current_bots & ClientBitFlag(self.b_num)); + h = ftos(current_bots); + cvar_set("scratch1", h); + + + ClientDisconnect(); + + if (self.b_clientno != -1) + { + // the bot's client number is not in use by a real player so we + // must remove it's entry in the rankings + // Quake engine sets all fields to 0, can only do the most important here + self.b_frags = self.frags = 0; + self.netname = ""; + self.classname = ""; + self.health = 0; + self.items = 0; + self.armorvalue = 0; + self.weaponmodel = ""; + self.b_pants = 0; + self.b_shirt = 0; + self.ammo_shells = self.ammo_nails = self.ammo_rockets = self.ammo_cells = 0; + UpdateClient(self); + active_clients = active_clients - (active_clients & ClientBitFlag(self.b_clientno)); + self.b_clientno = -1; + } + self = uself; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotInvalidClientNo +kicks a bot if a player connects and takes the bot's space + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(float clientno) BotInvalidClientNo = +{ + local entity bot; + + bot = GetClientEntity(clientno); + if(bot.b_clientno > 0) + { + if (!bot.ishuman) + { + bot.b_clientno = -1; + BotDisconnect(bot); + active_clients = active_clients | ClientBitFlag(self.b_clientno); + BotConnect(0, bot.b_num, bot.b_skill); + return; + } + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Loading from file + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void() LoadWaypoint = +{ + local vector org; + local entity tep; + local float r; + org_x = cvar("saved1"); + org_y = cvar("saved2"); + org_z = cvar("saved3"); + + tep = make_waypoint(org); + + r = cvar("saved4"); + + tep.b_aiflags = floor(r / 4); + tep.b_pants = cvar("scratch1"); + tep.b_skill = cvar("scratch2"); + tep.b_shirt = cvar("scratch3"); + tep.b_frags = cvar("scratch4"); +}; + +void() bot_return = +{ + if (time > 2) + { + if ((waypoint_mode == WM_DYNAMIC) || (waypoint_mode == WM_LOADED)) + { + // minor precaution + + if (saved_bots & 1) BotConnect(0, 1, saved_skills1 & 3); + if (saved_bots & 2) BotConnect(0, 2, (saved_skills1 & 12) / 4); + if (saved_bots & 4) BotConnect(0, 3, (saved_skills1 & 48) / 16); + if (saved_bots & 8) BotConnect(0, 4, (saved_skills1 & 192) / 64); + if (saved_bots & 16) BotConnect(0, 5, (saved_skills1 & 768) / 256); + if (saved_bots & 32) BotConnect(0, 6, (saved_skills1 & 3072) / 1024); + if (saved_bots & 64) BotConnect(0, 7, (saved_skills1 & 12288) / 4096); + if (saved_bots & 128) BotConnect(0, 8, (saved_skills1 & 49152) / 16384); + if (saved_bots & 256) BotConnect(0, 9, saved_skills2 & 3); + if (saved_bots & 512) BotConnect(0, 10, (saved_skills2 & 12) / 4); + if (saved_bots & 1024) BotConnect(0, 11, (saved_skills2& 48) / 16); + if (saved_bots & 2048) BotConnect(0, 12, (saved_skills2 & 192) / 64); + if (saved_bots & 4096) BotConnect(0, 13, (saved_skills2 & 768) / 256); + if (saved_bots & 8192) BotConnect(0, 14, (saved_skills2 & 3072) / 1024); + if (saved_bots & 16384) BotConnect(0, 15, (saved_skills2 & 12288) / 4096); + if (saved_bots & 32768) BotConnect(0, 16, (saved_skills2 & 49152) / 16384); + saved_bots = 0; + } + } +}; + + +void() WaypointWatch = +{ + // Waypoint Baywatch + local float bigboobs; + local string h; + + if (max_clients < 2) + return; + if (waypoint_mode != WM_UNINIT) + { + bigboobs = cvar("saved4"); + if (bigboobs != 0) + { + if ((bigboobs & 3) == 1) + ClearAllWays(); + else if ((bigboobs & 3) == 3) + { + FixWaypoints(); + h = ftos(b_options); + cvar_set("saved1", h); + cvar_set("saved4", "0"); + cvar_set("scratch1", "0"); + waypoint_mode = WM_LOADED; + return; + } + LoadWaypoint(); + waypoint_mode = WM_LOADING; + cvar_set("saved4", "0"); + } + } +}; +void() BotFrame = +{ + local float num; + + // for the sake of speed + sv_maxspeed = cvar("sv_maxspeed"); + sv_gravity = cvar("sv_gravity"); + sv_friction = cvar("sv_friction"); + sv_accelerate = cvar("sv_accelerate"); + sv_stopspeed = cvar("sv_stopspeed"); + real_frametime = frametime; // in NQ this is alright + + self = nextent(world); + num = 0; + while (num < max_clients) + { + if (self.ishuman == FALSE) + { + if (active_clients & ClientBitFlag(num)) + { + frik_obstacles(); + CL_KeyMove(); + SV_ClientThink(); + SV_Physics_Client(); + } + } + self = nextent(self); + num = num + 1; + } + WaypointWatch(); + + if (saved_bots) + bot_return(); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Impulses. Allows the player to perform bot +related functions. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() BotImpulses = +{ + local float f; + + if (self.impulse == 100) + { + f = cvar("skill"); + BotConnect(0, 0, f); + } + else if (self.impulse == 101) + { + f = cvar("skill"); + BotConnect(1, 0, f); + } + else if (self.impulse == 102) + KickABot(); + else if (self.impulse == 103) + botcam_u(); + else if (self.impulse == 104) + bot_way_edit(); + else + return; + + self.impulse = 0; +}; + + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_ai.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_ai.qc new file mode 100755 index 00000000..17f7dfc1 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_ai.qc @@ -0,0 +1,974 @@ +/*********************************************** +* * +* FrikBot General AI * +* "The I'd rather be playing Quake AI" * +* * +***********************************************/ + +/* +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. +*/ + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +target_onstack + +checks to see if an entity is on the bot's stack + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float(entity scot) target_onstack = +{ + if (scot == world) + return FALSE; + else if (self.target1 == scot) + return 1; + else if (self.target2 == scot) + return 2; + else if (self.target3 == scot) + return 3; + else if (self.target4 == scot) + return 4; + else + return FALSE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +target_add + +adds a new entity to the stack, since it's a +LIFO stack, this will be the bot's new target1 + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity ent) target_add = +{ + if (ent == world) + return; + if (target_onstack(ent)) + return; + self.target4 = self.target3; + self.target3 = self.target2; + self.target2 = self.target1; + self.target1 = ent; + self.search_time = time + 5; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +target_drop + +Removes an entity from the bot's target stack. +The stack will empty everything up to the object +So if you have target2 item_health, target1 +waypoint, and you drop the health, the waypoint +is gone too. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity ent) target_drop = +{ + local float tg; + + tg = target_onstack(ent); + if (tg == 1) + { + self.target1 = self.target2; + self.target2 = self.target3; + self.target3 = self.target4; + self.target4 = world; + } + else if (tg == 2) + { + self.target1 = self.target3; + self.target2 = self.target4; + self.target3 = self.target4 = world; + } + else if (tg == 3) + { + self.target1 = self.target4; + self.target2 = self.target3 = self.target4 = world; + } + else if (tg == 4) + self.target1 = self.target2 = self.target3 = self.target4 = world; + self.search_time = time + 5; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_lost + +Bot has lost its target. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity targ, float success) bot_lost = +{ + if (!targ) + return; + + target_drop(targ); + if (targ.classname == "waypoint") + targ.b_sound = targ.b_sound - (targ.b_sound & ClientBitFlag(self.b_clientno)); + + // find a new route + if (!success) + { + self.target1 = self.target2 = self.target3 = self.target4 = world; + self.last_way = FindWayPoint(self.current_way); + ClearMyRoute(); + self.b_aiflags = 0; + } + else + { + if (targ.classname == "item_artifact_invisibility") + if (self.items & 524288) + bot_start_topic(3); + + if (targ.flags & FL_ITEM) + { + if (targ.model == string_null) + targ._last = world; + else + targ._last = self; + } + } + + + if (targ.classname != "player") + targ.search_time = time + 5; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_check_lost + +decide if my most immediate target should be +removed. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(entity targ) bot_check_lost = +{ + local vector dist; + dist = realorigin(targ) - self.origin; + dist_z = 0; + if (targ == world) + return; + + // waypoints and items are lost if you get close enough to them + + else if (targ.flags & FL_ITEM) + { + if (vlen(targ.origin - self.origin) < 32) + bot_lost(targ, TRUE); + else if (targ.model == string_null) + bot_lost(targ, TRUE); + } + else if (targ.classname == "waypoint") + { + if (!(self.b_aiflags & (AI_SNIPER | AI_AMBUSH))) + { + if (self.b_aiflags & AI_RIDE_TRAIN) + { + if (vlen(targ.origin - self.origin) < 48) + bot_lost(targ, TRUE); + } + else if (self.b_aiflags & AI_PRECISION) + { + if (vlen(targ.origin - self.origin) < 24) + bot_lost(targ, TRUE); + } + else if (vlen(targ.origin - self.origin) < 32) + bot_lost(targ, TRUE); + } + } + else if (targ.classname == "temp_waypoint") + { + if (vlen(targ.origin - self.origin) < 32) + bot_lost(targ, TRUE); + } + else if (targ.classname == "player") + { + if (targ.health <= 0) + bot_lost(targ, TRUE); + else if ((coop) || (teamplay && targ.team == self.team)) + { + if (targ.target1.classname == "player") + { + if (!targ.target1.ishuman) + bot_lost(targ, TRUE); + } + else if (targ.teleport_time > time) + { + // try not to telefrag teammates + self.keys = self.keys & 960; + } + else if (vlen(targ.origin - self.origin) < 128) + { + if (vlen(targ.origin - self.origin) < 48) + frik_walkmove(self.origin - targ.origin); + else + { + self.keys = self.keys & 960; + bot_start_topic(4); + } + self.search_time = time + 5; // never time out + } + else if (!fisible(targ)) + bot_lost(targ, FALSE); + } + else if (waypoint_mode > WM_LOADED) + { + if (vlen(targ.origin - self.origin) < 128) + { + bot_lost(targ, TRUE); + } + } + } + + // buttons are lost of their frame changes + else if (targ.classname == "func_button") + { + if (targ.frame) + { + bot_lost(targ, TRUE); + if (self.enemy == targ) + self.enemy = world; + //if (self.target1) + // bot_get_path(self.target1, TRUE); + + } + } + // trigger_multiple style triggers are lost if their thinktime changes + else if ((targ.movetype == MOVETYPE_NONE) && (targ.solid == SOLID_TRIGGER)) + { + if (targ.nextthink >= time) + { + bot_lost(targ, TRUE); + //if (self.target1) + // bot_get_path(self.target1, TRUE); + } + } + // lose any target way above the bot's head + // FIXME: if the bot can fly in your mod.. + if ((targ.origin_z - self.origin_z) > 64) + { + dist = targ.origin - self.origin; + dist_z = 0; + if (vlen(dist) < 32) + if (self.flags & FL_ONGROUND) + if(!frik_recognize_plat(FALSE)) + bot_lost(targ, FALSE); + } + else if (targ.classname == "train") + { + if (frik_recognize_plat(FALSE)) + bot_lost(targ, TRUE); + } + // targets are lost if the bot's search time has expired + if (time > self.search_time) + bot_lost(targ, FALSE); +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_handle_ai + +This is a 0.10 addition. Handles any action +based b_aiflags. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_handle_ai = +{ + local entity newt; + local vector v; + + // handle ai flags -- note, not all aiflags are handled + // here, just those that perform some sort of action + + // wait is used by the ai to stop the bot until his search time expires / or route changes + + if (self.b_aiflags & AI_WAIT) + self.keys = self.keys & 960; + + if (self.b_aiflags & AI_DOORFLAG) // was on a door when spawned + { + b_temp3 = self; + self = self.last_way; + if (!frik_recognize_plat(FALSE)) // if there is nothing there now + { + newt = FindThing("door"); // this is likely the door responsible (crossfingers) + self = b_temp3; + + if (self.b_aiflags & AI_DOOR_NO_OPEN) + { + if (newt.nextthink) + self.keys = self.keys & 960; // wait until it closes + else + { + bot_lost(self.last_way, FALSE); + self.b_aiflags = self.b_aiflags - AI_DOORFLAG; + } + } + else + { + if (newt.targetname) + { + newt = find(world, target, newt.targetname); + if (newt.health > 0) + { + self.enemy = newt; + bot_weapon_switch(1); + } + else + { + // target_drop(self.last_way); + target_add(newt); + // bot_get_path(newt, TRUE); + } + } + self.b_aiflags = self.b_aiflags - AI_DOORFLAG; + } + } + else + self = b_temp3; + } + + if (self.b_aiflags & AI_JUMP) + { + if (self.flags & FL_ONGROUND) + { + bot_jump(); + self.b_aiflags = self.b_aiflags - AI_JUMP; + } + } + else if (self.b_aiflags & AI_SUPER_JUMP) + { + if (self.weapon != 32) + self.impulse = 7; + else if (self.flags & FL_ONGROUND) + { + if (bot_can_rj(self)) + { + bot_jump(); + self.v_angle_x = self.b_angle_x = 80; + self.button0 = TRUE; + } + else + bot_lost(self.target1, FALSE); + self.b_aiflags = self.b_aiflags - AI_SUPER_JUMP; + } + } + if (self.b_aiflags & AI_SURFACE) + { + if (self.waterlevel > 2) + { + self.keys = KEY_MOVEUP; + self.button2 = TRUE; // swim! + } + else + self.b_aiflags = self.b_aiflags - AI_SURFACE; + } + if (self.b_aiflags & AI_RIDE_TRAIN) + { + // simple, but effective + // this can probably be used for a lot of different + // things, not just trains (door elevators come to mind) + b_temp3 = self; + self = self.last_way; + + if (!frik_recognize_plat(FALSE)) // if there is nothing there now + { + self = b_temp3; + self.keys = self.keys & 960; + } + else + { + self = b_temp3; + if (frik_recognize_plat(FALSE)) + { + v = realorigin(trace_ent) + trace_ent.origin - self.origin; + v_z = 0; + if (vlen(v) < 24) + self.keys = self.keys & 960; + else + { + self.b_aiflags = self.b_aiflags | AI_PRECISION; + self.keys = frik_KeysForDir(v); + } + } + } + } + if (self.b_aiflags & AI_PLAT_BOTTOM) + { + newt = FindThing("plat"); + if (newt.state != 1) + { + v = self.origin - realorigin(newt); + v_z = 0; + if (vlen(v) > 96) + self.keys = self.keys & 960; + else + frik_walkmove(v); + } + else + self.b_aiflags = self.b_aiflags - AI_PLAT_BOTTOM; + } + if (self.b_aiflags & AI_DIRECTIONAL) + { + if ((normalize(self.last_way.origin - self.origin) * self.b_dir) > 0.4) + { + self.b_aiflags = self.b_aiflags - AI_DIRECTIONAL; + bot_lost(self.target1, TRUE); + } + } + if (self.b_aiflags & AI_SNIPER) + { + self.b_aiflags = (self.b_aiflags | AI_WAIT | AI_PRECISION) - AI_SNIPER; + // FIXME: Add a switch to wep command + // FIXME: increase delay? + } + if (self.b_aiflags & AI_AMBUSH) + { + self.b_aiflags = (self.b_aiflags | AI_WAIT) - AI_AMBUSH; + // FIXME: Add a switch to wep command + // FIXME: increase delay? + } + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_path + +Bot will follow a route generated by the +begin_route set of functions in bot_way.qc. +This code, while it works pretty well, can get +confused + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_path = +{ + + local entity jj, tele; + + bot_check_lost(self.target1); + if (!self.target1) + { + self.keys=0; + return; + } + if (target_onstack(self.last_way)) + return; // old waypoint still being hunted + + jj = FindRoute(self.last_way); + if (!jj) + { + // this is an ugly hack + if (self.target1.current_way != self.last_way) + { + if (self.target1.classname != "temp_waypoint") + if (self.target1.classname != "player") + bot_lost(self.target1, FALSE); + } + + return; + } + + // update the bot's special ai features + + // Readahed types are AI conditions to perform while heading to a waypoint + // point types are AI flags that should be executed once reaching a waypoint + + self.b_aiflags = (jj.b_aiflags & AI_READAHEAD_TYPES) | (self.last_way.b_aiflags & AI_POINT_TYPES); + target_add(jj); + if (self.last_way) + { + if (CheckLinked(self.last_way, jj) == 2) // waypoints are telelinked + { + tele = FindThing("trigger_teleport"); // this is probbly the teleport responsible + target_add(tele); + } + traceline(self.last_way.origin, jj.origin, FALSE, self); // check for blockage + if (trace_fraction != 1) + { + if (trace_ent.classname == "door" && !(self.b_aiflags & AI_DOOR_NO_OPEN)) // a door blocks the way + { + // linked doors fix + if (trace_ent.owner) + trace_ent = trace_ent.owner; + if ((trace_ent.health > 0) && (self.enemy == world)) + { + self.enemy = trace_ent; + bot_weapon_switch(1); + self.b_aiflags = self.b_aiflags | AI_BLIND; // nick knack paddy hack + } + else if (trace_ent.targetname) + { + tele = find(world, target, trace_ent.targetname); + if (tele.health > 0) + { + self.enemy = tele; + bot_weapon_switch(1); + } + else + { + // target_drop(jj); + target_add(tele); + // bot_get_path(tele, TRUE); + self.b_aiflags = self.b_aiflags | AI_BLIND; // give a bot a bone + return; + } + } + } + else if (trace_ent.classname == "func_wall") + { + // give up + bot_lost(self.target1, FALSE); + return; + } + } + } + // this is used for AI_DRIECTIONAL + self.b_dir = normalize(jj.origin - self.last_way.origin); + + self.last_way = jj; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Priority Look. What a stupid name. This is where +the bot finds things it wants to kill/grab. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +// priority scale +// 0 - 10 virtually ignore +// 10 - 30 normal item range +// 30 - 50 bot will consider this a target worth changing course for +// 50 - 90 bot will hunt these as vital items + +// *!* Make sure you add code to bot_check_lost to remove the target *!* + +float(entity thing) priority_for_thing = +{ + local float thisp; + thisp = 0; + // This is the most executed function in the bot. Careful what you do here. + + if ((thing.flags & FL_ITEM) && thing.model != string_null && thing.search_time < time) + { + // ugly hack + if (thing._last != self) + thisp = 20; + if (thing.classname == "item_artifact_super_damage") + thisp = 65; + else if (thing.classname == "item_artifact_invulnerability") + thisp = 65; + else if (thing.classname == "item_health") + { + if (thing.spawnflags & 2) + thisp = 55; + if (self.health < 40) + thisp = thisp + 50; + } + else if (thing.model == "progs/armor.mdl") + { + if (self.armorvalue < 200) + { + if (thing.skin == 2) + thisp = 60; + else if (self.armorvalue < 100) + thisp = thisp + 25; + } + } + else if (thing.classname == "weapon_supershotgun") + { + if (!(self.items & 2)) // IT_SUPER_SHOTGUN + thisp = 25; + } + else if (thing.classname == "weapon_nailgun") + { + if (!(self.items & 4)) // IT_NAILGUN + thisp = 30; + } + else if (thing.classname == "weapon_supernailgun") + { + if (!(self.items & 8)) // IT_SUPER_NAILGUN + thisp = 35; + } + else if (thing.classname == "weapon_grenadelauncher") + { + if (!(self.items & 16)) // IT_GRENADE_LAUNCHER + thisp = 45; + } + else if (thing.classname == "weapon_rocketlauncher") + { + if (!(self.items & 32)) // IT_ROCKET_LAUNCHER + thisp = 60; + } + else if (thing.classname == "weapon_lightning") + { + if (!(self.items & 64)) // IT_LIGHTNING + thisp = 50; + } + } + else if ((thing.flags & FL_MONSTER) && thing.health > 0) + thisp = 45; + else if (thing.classname == "player") + { + if (thing.health > 0) + { + if (thing == self) + return 0; + else + { + if (thing.items & IT_INVISIBILITY) //FIXME + thisp = 2; + else if (coop) + { + thisp = 100; + if (thing.target1.classname == "player") + if (!thing.target1.ishuman) + return 0; + } + else if (teamplay && thing.team == self.team) + { + thisp = 100; + if (thing.target1.classname == "player") + return 0; + } + else thisp = 30; + } + } + } + else if (thing.classname == "waypoint") + { + if (thing.b_aiflags & AI_SNIPER) + thisp = 30; + else if (thing.b_aiflags & AI_AMBUSH) + thisp = 30; + } + if (pointcontents(thing.origin) < -3) + return 0; + if (thisp) + { + if (thing.current_way) + { + // check to see if it's unreachable + if (thing.current_way.items == -1) + return 0; + else + thisp = thisp + (13000 - thing.current_way.items) * 0.05; + + } + } + return thisp; +}; + +void(float scope) bot_look_for_crap = +{ + local entity foe, best; + local float thatp, bestp, dist; + + if (scope == 1) + foe = findradius(self.origin, 13000); + else + foe = findradius(self.origin, 500); + + bestp = 1; + while(foe) + { + thatp = priority_for_thing(foe); + if (thatp) + if (!scope) + if (!sisible(foe)) + thatp = 0; + if (thatp > bestp) + { + bestp = thatp; + best = foe; + dist = vlen(self.origin - foe.origin); + } + foe = foe.chain; + } + if (best == world) + return; + if (!target_onstack(best)) + { + target_add(best); + if (scope) + { + bot_get_path(best, FALSE); + self.b_aiflags = self.b_aiflags | AI_WAIT; + } + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_angle_set + +Sets the bots look keys & b_angle to point at +the target - used for fighting and just +generally making the bot look good. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_angle_set = +{ + local float h; + local vector view; + + if (self.enemy) + { + if (self.enemy.items & 524288) + if (random() > 0.2) + return; + if (self.missile_speed == 0) + self.missile_speed = 10000; + if (self.enemy.solid == SOLID_BSP) + { + view = (((self.enemy.absmin + self.enemy.absmax) * 0.5) - self.origin); + } + else + { + h = vlen(self.enemy.origin - self.origin) / self.missile_speed; + if (self.enemy.flags & FL_ONGROUND) + view = self.enemy.velocity * h; + else + view = (self.enemy.velocity - (sv_gravity * '0 0 1') * h) * h; + view = self.enemy.origin + view; + // FIXME: ? + traceline(self.enemy.origin, view, FALSE, self); + view = trace_endpos; + + if (self.weapon == 32) + view = view - '0 0 22'; + + view = normalize(view - self.origin); + } + view = vectoangles(view); + view_x = view_x * -1; + self.b_angle = view; + } + else if (self.target1) + { + view = realorigin(self.target1); + if (self.target1.flags & FL_ITEM) + view = view + '0 0 48'; + view = view - (self.origin + self.view_ofs); + view = vectoangles(view); + view_x = view_x * -1; + self.b_angle = view; + } + else + self.b_angle_x = 0; + // HACK HACK HACK HACK + // The bot falls off ledges a lot because of "turning around" + // so let the bot use instant turn around when not hunting a player + if (self.b_skill == 3) + { + self.keys = self.keys & 63; + self.v_angle = self.b_angle; + while (self.v_angle_x < -180) + self.v_angle_x = self.v_angle_x + 360; + while (self.v_angle_x > 180) + self.v_angle_x = self.v_angle_x - 360; + + } + else if ((self.enemy == world || self.enemy.movetype == MOVETYPE_PUSH) && self.target1.classname != "player") + { + self.keys = self.keys & 63; + self.v_angle = self.b_angle; + while (self.v_angle_x < -180) + self.v_angle_x = self.v_angle_x + 360; + while (self.v_angle_x > 180) + self.v_angle_x = self.v_angle_x - 360; + } + else if (self.b_skill < 2) // skill 2 handled in bot_phys + { + if (self.b_angle_x > 180) + self.b_angle_x = self.b_angle_x - 360; + self.keys = self.keys & 63; + + if (angcomp(self.b_angle_y, self.v_angle_y) > 10) + self.keys = self.keys | KEY_LOOKLEFT; + else if (angcomp(self.b_angle_y, self.v_angle_y) < -10) + self.keys = self.keys | KEY_LOOKRIGHT; + if (angcomp(self.b_angle_x, self.v_angle_x) < -10) + self.keys = self.keys | KEY_LOOKUP; + else if (angcomp(self.b_angle_x, self.v_angle_x) > 10) + self.keys = self.keys | KEY_LOOKDOWN; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotAI + +This is the main ai loop. Though called every +frame, the ai_time limits it's actual updating + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float stagger_think; + +void() BotAI = +{ + // am I dead? Fire randomly until I respawn + // health < 1 is used because fractional healths show up as 0 on normal player + // status bars, and the mod probably already compensated for that + + if (self.health < 1) + { + self.button0 = floor(random() * 2); + self.button2 = 0; + self.keys = 0; + self.b_aiflags = 0; + ClearMyRoute(); + self.target1 = self.target2 = self.target3 = self.target4 = self.enemy = world; + self.last_way = world; + return; + } + + // stagger the bot's AI out so they all don't think at the same time, causing game + // 'spikes' + if (self.b_skill < 2) + { + if (self.ai_time > time) + return; + + self.ai_time = time + 0.05; + if (bot_count > 0) + { + if ((time - stagger_think) < (0.1 / bot_count)) + self.ai_time = self.ai_time + 0.1 / (2 * bot_count); + } + else + return; + } + if (self.view_ofs == '0 0 0') + bot_start_topic(7); + stagger_think = time; + + // shut the bot's buttons off, various functions will turn them on by AI end + + self.button2 = 0; + self.button0 = 0; + + + // target1 is like goalentity in normal Quake monster AI. + // it's the bot's most immediate target + if (route_table == self) + { + if (busy_waypoints <= 0) + { + if (waypoint_mode < WM_EDITOR) + bot_look_for_crap(TRUE); + } + self.b_aiflags = 0; + self.keys = 0; + } + else if (self.target1) + { + frik_movetogoal(); + bot_path(); + } + else + { + if (waypoint_mode < WM_EDITOR) + { + if(self.route_failed) + { + frik_bot_roam(); + self.route_failed = 0; + } + else if(!begin_route()) + { + bot_look_for_crap(FALSE); + } + self.keys = 0; + } + else + { + self.b_aiflags = AI_WAIT; + self.keys = 0; + } + } + + // bot_angle_set points the bot at it's goal (self.enemy or target1) + + bot_angle_set(); + + // fight my enemy. Enemy is probably a field QC coders will most likely use a lot + // for their own needs, since it's unused on a normal player + // FIXME + if (self.enemy) + bot_fight_style(); + else if (random() < 0.2) + if (random() < 0.2) + bot_weapon_switch(-1); + bot_dodge_stuff(); + + // checks to see if bot needs to start going up for air + if (self.waterlevel > 2) + { + if (time > (self.air_finished - 2)) + { + traceline (self.origin, self.origin + '0 0 6800', TRUE, self); + if (trace_inopen) + { + self.keys = KEY_MOVEUP; + self.button2 = TRUE; // swim! + return; // skip ai flags for now - this is life or death + } + } + } + + // b_aiflags handling + + + if (self.b_aiflags) + bot_handle_ai(); + else + bot_chat(); // don't want chat to screw him up if he's rjing or something +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_ed.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_ed.qc new file mode 100755 index 00000000..44352c27 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_ed.qc @@ -0,0 +1,1334 @@ +/*********************************************** +* * +* FrikBot Waypoint Editor * +* "The 'wtf is this doing in my mod' code" * +* * +***********************************************/ + +/* +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. +*/ + +float saved1, saved2, saved3, scratch1, scratch2, scratch3, scratch4; +float bytecounter, filecount; + +float MENU_MAIN = 1; +float MENU_WAYPOINTS = 2; +float MENU_LINKS = 3; +float MENU_FLAGS = 4; +float MENU_FLAGS2 = 5; +float MENU_BOTS = 6; +float MENU_WAYLIST = 7; +// 8 = link way +// 9 = telelink way +// 10 = delete link +// 11 = create link X2 +// 12 = delete link x2 +// 13 = confirmation of delete all +// 14 = Teleport to way +// 15 = confirmation of delete point + +void() BSPDumpWaypoints; +void() QCDumpWaypoints; +void() DumpWaypoints; +/* +// source for the menu strings... + +-- Main Menu --\n +[1] >>Waypoint Management\n +[2] >>Link Management \n +[3] >>AI Flag Management \n +[4] >>Bot Management \n +[5] >>Waylist Management \n +[6] [#] Noclip \n +[7] [#] Godmode \n +[8] [#] Hold Select \n +[9] Teleport to Way # \n +[0] Close Menu \n + +// missing from main is show way info +// iffy on the teleport to way thing being on main...seems like either a bot or way list thing + +-- Waypoint Management --\n +[1] Move Waypoint \n +[2] Delete Waypoint \n +[3] Make Waypoint \n +[4] Make Way + Link \n +[5] Make Way + Link X2 \n +[6] Make Way + Telelink \n +[7] Show waypoint info \n +[8] >>Link Management \n +[9] >>AI Flag Management \n +[0] >>Main Menu \n + +-- Link Management --\n +[1] Unlink Waypoint \n +[2] Create Link \n +[3] Create Telelink \n +[4] Delete Link \n +[5] Create Link X2 \n +[6] Delete Link X2 \n +[7] >Make Waypoint \n +[8] >>Waypoint Management\n +[9] >>AI Flag Management \n +[0] >>Main Menu \n + +// Ai flags...ugh + +-- AI Flag Management --\n +[1] [#] Door Flag \n +[2] [#] Precision \n +[3] [#] Surface for air \n +[4] [#] Blind mode \n +[5] [#] Jump \n +[6] [#] Dark \n +[7] [#] Super Jump \n +\n +[9] >>AI Flags page 2 \n +[0] >>Main Menu \n + +-- AI Flags pg. 2--\n +[1] [#] Difficult \n +[2] [#] Wait for plat \n +[3] [#] Ride train \n +[4] [#] Door flag no open\n +[5] [#] Ambush \n +[6] [#] Snipe \n +[7] [#] Trace Test \n +\n +[9] >>AI Flag Management \n +[0] >>Main Menu \n + +-- Bot Management --\n +[1] Add a Test Bot \n +[2] Order Test Bot here \n +[3] Remove Test Bot \n +[4] Stop Test Bot \n +[5] Teleport Bot here \n +[6] Teleport to Way # \n +\n +\n +\n +[0] >>Main Menu \n + +-- Waylist Management --\n +[1] Delete ALL Waypoints \n +[2] Dump Waypoints \n +[3] Check For Errors \n +[4] Save Waypoints \n +[5] [#] Dynamic Mode \n +[6] [#] Dynamic Link \n +[7] [#] WAY output \n +[8] [#] QC output \n +[9] [#] BSP ents output \n +[0] Main Menu \n + +*/ + +void() bot_menu_display = +{ +// build options + local string s1, s2, s3, s4, s5, s6, s7, h; + local entity t; + +// check impulses + if (self.impulse > 0 && self.impulse < 11 && self.b_menu) + { + if (self.b_menu == MENU_MAIN) + { + if (self.impulse == 1) + { + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + else if (self.impulse == 3) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 4) + { + self.b_menu = MENU_BOTS; + self.b_menu_time = time; + } + else if (self.impulse == 5) + { + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + else if (self.impulse == 6) + { + if (self.movetype == MOVETYPE_NOCLIP) + self.movetype = MOVETYPE_WALK; + else + self.movetype = MOVETYPE_NOCLIP; + self.b_menu_time = time; + + } + else if (self.impulse == 7) + { + if (self.flags & FL_GODMODE) + self.flags = self.flags - FL_GODMODE; + else + self.flags = self.flags | FL_GODMODE; + self.b_menu_time = time; + + } + else if (self.impulse == 8) + { + if (self.b_aiflags & AI_HOLD_SELECT) + self.b_aiflags = self.b_aiflags - AI_HOLD_SELECT; + else + self.b_aiflags = self.b_aiflags | AI_HOLD_SELECT; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + self.b_menu = 14; + self.b_menu_time = time; + } + else if (self.impulse == 10) + bot_way_edit(); + } + else if (self.b_menu == MENU_WAYPOINTS) + { + if (self.impulse == 1) + { + if (self.current_way) + setorigin(self.current_way, self.origin + self.view_ofs); + } + else if (self.impulse == 2) + { + if (self.current_way) + { + self.b_menu = 15; + self.b_menu_time = time; + self.last_way = self.current_way; + } + } + else if (self.impulse == 3) + { + make_waypoint(self.origin + self.view_ofs); + } + else if (self.impulse == 4) + { + t = make_waypoint(self.origin + self.view_ofs); + if (!LinkWays(self.current_way, t)) + sprint(self, "Unable to link them\n"); + } + else if (self.impulse == 5) + { + t = make_waypoint(self.origin + self.view_ofs); + if (!LinkWays(self.current_way, t)) + sprint(self, "Unable to link old to new\n"); + LinkWays(t, self.current_way); + } + else if (self.impulse == 6) + { + t = make_waypoint(self.origin + self.view_ofs); + if (!TeleLinkWays(self.current_way, t)) + sprint(self, "Unable to link them\n"); + } + else if (self.impulse == 7) + { + if (self.current_way) + { + sprint(self, "\nwaypoint info for waypoint #"); + h = ftos(self.current_way.count); + sprint(self, h); + sprint(self, "\nAI Flag value: "); + h = ftos(self.current_way.b_aiflags); + sprint(self, h); + + if (self.current_way.target1) + { + h = ftos(self.current_way.target1.count); + if (self.current_way.b_aiflags & AI_TELELINK_1) + sprint(self, "\nTelelink1 to:"); + else + sprint(self, "\nLink1 to:"); + sprint(self, h); + } + if (self.current_way.target2) + { + h = ftos(self.current_way.target2.count); + if (self.current_way.b_aiflags & AI_TELELINK_2) + sprint(self, "\nTelelink2 to:"); + else + sprint(self, "\nLink2 to:"); + sprint(self, h); + } + if (self.current_way.target3) + { + h = ftos(self.current_way.target3.count); + if (self.current_way.b_aiflags & AI_TELELINK_3) + sprint(self, "\nTelelink3 to:"); + else + sprint(self, "\nLink3 to:"); + sprint(self, h); + } + if (self.current_way.target4) + { + h = ftos(self.current_way.target4.count); + if (self.current_way.b_aiflags & AI_TELELINK_4) + sprint(self, "\nTelelink4 to:"); + else + sprint(self, "\nLink4 to:"); + sprint(self, h); + } + sprint(self, "\n\n"); + } + + } + if (self.impulse == 8) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_LINKS) + { + if (self.impulse == 1) + { + if (self.current_way) + self.current_way.target1 = self.current_way.target2 = self.current_way.target3 = self.current_way.target4 = world; + } + else if (self.impulse == 2) + { + self.b_menu = 8; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 3) + { + self.b_menu = 9; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 4) + { + self.b_menu = 10; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 5) + { + self.b_menu = 11; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 6) + { + self.b_menu = 12; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 7) + make_waypoint(self.origin + self.view_ofs); + else if (self.impulse == 8) + { + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_FLAGS) + { + + if (self.current_way) + { + if (self.impulse == 1) + { + if (self.current_way.b_aiflags & AI_DOORFLAG) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DOORFLAG); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DOORFLAG; + + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + if (self.current_way.b_aiflags & AI_PRECISION) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_PRECISION); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_PRECISION; + self.b_menu_time = time; + } + else if (self.impulse == 3) + { + if (self.current_way.b_aiflags & AI_SURFACE) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_SURFACE); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_SURFACE; + self.b_menu_time = time; + } + else if (self.impulse == 4) + { + if (self.current_way.b_aiflags & AI_BLIND) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_BLIND); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_BLIND; + self.b_menu_time = time; + } + else if (self.impulse == 5) + { + if (self.current_way.b_aiflags & AI_JUMP) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_JUMP); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_JUMP; + self.b_menu_time = time; + } + else if (self.impulse == 6) + { + if (self.current_way.b_aiflags & AI_DIRECTIONAL) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DIRECTIONAL); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DIRECTIONAL; + self.b_menu_time = time; + } + else if (self.impulse == 7) + { + if (self.current_way.b_aiflags & AI_SUPER_JUMP) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_SUPER_JUMP); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_SUPER_JUMP; + self.b_menu_time = time; + } + } + if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS2; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_FLAGS2) + { + + if (self.current_way) + { + if (self.impulse == 1) + { + if (self.current_way.b_aiflags & AI_DIFFICULT) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DIFFICULT); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DIFFICULT; self.b_menu_time = time; + } + else if (self.impulse == 2) + { + if (self.current_way.b_aiflags & AI_PLAT_BOTTOM) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_PLAT_BOTTOM); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_PLAT_BOTTOM; + self.b_menu_time = time; + } + else if (self.impulse == 3) + { + if (self.current_way.b_aiflags & AI_RIDE_TRAIN) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_RIDE_TRAIN); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_RIDE_TRAIN; + self.b_menu_time = time; + } + else if (self.impulse == 4) + { + if (self.current_way.b_aiflags & AI_DOOR_NO_OPEN) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DOOR_NO_OPEN); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DOOR_NO_OPEN; + self.b_menu_time = time; + } + else if (self.impulse == 5) + { + if (self.current_way.b_aiflags & AI_AMBUSH) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_AMBUSH); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_AMBUSH; + self.b_menu_time = time; + } + else if (self.impulse == 6) + { + if (self.current_way.b_aiflags & AI_SNIPER) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_SNIPER); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_SNIPER; + self.b_menu_time = time; + } + else if (self.impulse == 7) + { + if (self.current_way.b_aiflags & AI_TRACE_TEST) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_TRACE_TEST); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_TRACE_TEST; + self.b_menu_time = time; + } + + } + if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + + else if (self.b_menu == MENU_BOTS) + { + if (self.impulse == 1) + { + self.impulse = 100; + return; + } + else if (self.impulse == 2) + { + b_temp3 = self; + self = player_head; + while(self) + { + if (!self.ishuman) + { + target_add(b_temp3); + bot_get_path(b_temp3, TRUE); + self = world; + } + else + self = self._next; + } + self = b_temp3; + } + else if (self.impulse == 3) + { + self.impulse = 102; + return; + } + else if (self.impulse == 4) + { + b_temp1 = self; + self = player_head; + while(self) + { + if (!self.ishuman) + { + self.target1 = self.target2 = self.target3 = self.target4 = world; + route_table = world; + } + self = self._next; + } + self = b_temp1; + } + else if (self.impulse == 5) + { + if (self.current_way) + { + b_temp1 = self; + self = player_head; + while(self) + { + if (!self.ishuman) + { + setorigin(self, b_temp1.current_way.origin); + } + self = self._next; + } + self = b_temp1; + } + else + sprint(self, "select a waypoint first\n"); + } + else if (self.impulse == 6) + { + self.b_menu = 14; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_WAYLIST) + { + if (self.impulse == 1) + { + self.b_menu = 13; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + if (dump_mode == 0) + DumpWaypoints(); + else if (dump_mode == 1) + QCDumpWaypoints(); + else if (dump_mode == 2) + BSPDumpWaypoints(); + } + else if (self.impulse == 3) + { + t = way_head; + while(t) + { + if ((t.target1 == world) && (t.target2 == world) && (t.target3 == world) && (t.target4 == world)) + { + sprint(self, "Waypoint #"); + h = ftos(t.count); + sprint(self, h); + sprint(self, " has no outbound links\n"); + } + if ((t.target1 == t) || (t.target2 == t) || (t.target3 == t) || (t.target4 == t)) + { + sprint(self, "Waypoint #"); + h = ftos(t.count); + sprint(self, h); + sprint(self, " links to itself (??)\n"); + } + t = t._next; + } + sprint(self, "Error check complete\n"); + } + else if (self.impulse == 4) + { + sprint(self, "not in this version (FBX 0.10.0)\n"); + } + else if (self.impulse == 5) + { + if (waypoint_mode == WM_EDITOR_DYNAMIC) + waypoint_mode = WM_EDITOR; + else + waypoint_mode = WM_EDITOR_DYNAMIC; + self.b_menu_time = time; + + } + else if (self.impulse == 6) + { + if (waypoint_mode == WM_EDITOR_DYNLINK) + waypoint_mode = WM_EDITOR; + else + waypoint_mode = WM_EDITOR_DYNLINK; + self.b_menu_time = time; + } + else if (self.impulse == 7) + { + dump_mode = 0; + self.b_menu_time = time; + } + else if (self.impulse == 8) + { + dump_mode = 1; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + dump_mode = 2; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == 8) + { + if (self.impulse == 1) + { + if (self.current_way) + { + if (!LinkWays(self.last_way, self.current_way)) + sprint(self, "Unable to link them\n"); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 9) + { + if (self.impulse == 1) + { + if (self.current_way) + { + if (!TeleLinkWays(self.last_way, self.current_way)) + sprint(self, "Unable to link them\n"); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 10) + { + if (self.impulse == 1) + { + if (self.current_way) + { + UnlinkWays(self.last_way, self.current_way); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 11) + { + if (self.impulse == 1) + { + if (self.current_way) + { + if (!LinkWays(self.last_way, self.current_way)) + sprint(self, "Unable to link 1 to 2\n"); + if (!LinkWays(self.current_way, self.last_way)) + sprint(self, "Unable to link 2 to 1\n"); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 12) + { + if (self.impulse == 1) + { + if (self.current_way) + { + UnlinkWays(self.last_way, self.current_way); + UnlinkWays(self.current_way, self.last_way); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 13) + { + if (self.impulse == 1) + { + ClearAllWays(); + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + } + else if (self.b_menu == 14) + { + if (self.impulse == 10) + self.impulse = 0; + self.b_menu_value = self.b_menu_value * 10 + self.impulse; + self.b_menu_time = 0; + } + else if (self.b_menu == 15) + { + if (self.impulse == 1) + { + delete_waypoint(self.last_way); + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + } + self.impulse = 0; + + } + if (self.b_menu_time < time) + { + if (self.b_menu == MENU_MAIN) + { + s1 = "-- Main Menu --\n[1] >>Waypoint Management\n[2] >>Link Management \n[3] >>AI Flag Management \n[4] >>Bot Management \n[5] >>Waylist Management \n"; + if (self.movetype == MOVETYPE_NOCLIP) + s2 = "[6] [#] Noclip \n"; + else + s2 = "[6] [ ] Noclip \n"; + + if (self.flags & FL_GODMODE) + s3 = "[7] [#] Godmode \n"; + else + s3 = "[7] [ ] Godmode \n"; + if (self.b_aiflags & AI_HOLD_SELECT) + s4 = "[8] [#] Hold Select \n"; + else + s4 = "[8] [ ] Hold Select \n"; + s5 = "[9] Teleport to Way # \n[0] Close Menu \n"; + } + else if (self.b_menu == MENU_WAYPOINTS) + { + s1 = "-- Waypoint Management --\n[1] Move Waypoint \n[2] Delete Waypoint \n[3] Make Waypoint \n[4] Make Way + Link \n[5] Make Way + Link X2 \n[6] Make Way + Telelink \n[7] Show waypoint info \n[8] >>Link Management \n[9] >>AI Flag Management \n[0] >>Main Menu \n"; + } + else if (self.b_menu == MENU_LINKS) + { + s1 = "-- Link Management --\n[1] Unlink Waypoint \n[2] Create Link \n[3] Create Telelink \n[4] Delete Link \n[5] Create Link X2 \n[6] Delete Link X2 \n[7] >Make Waypoint \n[8] >>Waypoint Management\n[9] >>AI Flag Management \n[0] >>Main Menu \n"; + } + else if (self.b_menu == MENU_FLAGS) + { + if (self.current_way.b_aiflags & AI_DOORFLAG) + s1 = "-- AI Flag Management --\n[1] [#] Door Flag \n"; + else + s1 = "-- AI Flag Management --\n[1] [ ] Door Flag \n"; + + if (self.current_way.b_aiflags & AI_PRECISION) + s2 = "[2] [#] Precision \n"; + else + s2 = "[2] [ ] Precision \n"; + + if (self.current_way.b_aiflags & AI_SURFACE) + s3 = "[3] [#] Surface for air \n"; + else + s3 = "[3] [ ] Surface for air \n"; + + if (self.current_way.b_aiflags & AI_BLIND) + s4 = "[4] [#] Blind mode \n"; + else + s4 = "[4] [ ] Blind mode \n"; + + if (self.current_way.b_aiflags & AI_JUMP) + s5 = "[5] [#] Jump \n"; + else + s5 = "[5] [ ] Jump \n"; + + if (self.current_way.b_aiflags & AI_DIRECTIONAL) + s6 = "[6] [#] Directional \n"; + else + s6 = "[6] [ ] Directional \n"; + + if (self.current_way.b_aiflags & AI_SUPER_JUMP) + s7 = "[7] [#] Super Jump \n\n[9] >>AI Flags page 2 \n[0] >>Main Menu \n"; + else + s7 = "[7] [ ] Super Jump \n\n[9] >>AI Flags page 2 \n[0] >>Main Menu \n"; + } + else if (self.b_menu == MENU_FLAGS2) + { + if (self.current_way.b_aiflags & AI_DIFFICULT) + s1 = "-- AI Flags pg. 2--\n[1] [#] Difficult \n"; + else + s1 = "-- AI Flags pg. 2--\n[1] [ ] Difficult \n"; + + if (self.current_way.b_aiflags & AI_PLAT_BOTTOM) + s2 = "[2] [#] Wait for plat \n"; + else + s2 = "[2] [ ] Wait for plat \n"; + + if (self.current_way.b_aiflags & AI_RIDE_TRAIN) + s3 = "[3] [#] Ride train \n"; + else + s3 = "[3] [ ] Ride train \n"; + + if (self.current_way.b_aiflags & AI_DOOR_NO_OPEN) + s4 = "[4] [#] Door flag no open\n"; + else + s4 = "[4] [ ] Door flag no open\n"; + + if (self.current_way.b_aiflags & AI_AMBUSH) + s5 = "[5] [#] Ambush \n"; + else + s5 = "[5] [ ] Ambush \n"; + + if (self.current_way.b_aiflags & AI_SNIPER) + s6 = "[6] [#] Snipe \n"; + else + s6 = "[6] [ ] Snipe \n"; + + if (self.current_way.b_aiflags & AI_TRACE_TEST) + s7 = "[7] [#] Trace Test \n\n[9] >>AI Flag Management \n[0] >>Main Menu \n"; + else + s7 = "[7] [ ] Trace Test \n\n[9] >>AI Flag Management \n[0] >>Main Menu \n"; + + } + else if (self.b_menu == MENU_BOTS) + { + s1 = "-- Bot Management --\n[1] Add a Test Bot \n[2] Order Test Bot here \n[3] Remove Test Bot \n[4] Stop Test Bot \n[5] Teleport Bot here \n[6] Teleport to Way # \n\n\n\n[0] >>Main Menu \n"; + } + else if (self.b_menu == MENU_WAYLIST) + { + s1 = "-- Waylist Management --\n[1] Delete ALL Waypoints \n[2] Dump Waypoints \n[3] Check For Errors \n[4] Save Waypoints \n"; + + if (waypoint_mode == WM_EDITOR_DYNAMIC) + s2 = "[5] [#] Dynamic Mode \n[6] [#] Dynamic Link \n"; + else if (waypoint_mode == WM_EDITOR_DYNLINK) + s2 = "[5] [ ] Dynamic Mode \n[6] [#] Dynamic Link \n"; + else + s2 = "[5] [ ] Dynamic Mode \n[6] [ ] Dynamic Link \n"; + if (dump_mode == 0) + s3 = "[7] [#] WAY output \n[8] [ ] QC output \n[9] [ ] BSP ents output \n[0] Main Menu \n"; + else if (dump_mode == 1) + s3 = "[7] [ ] WAY output \n[8] [#] QC output \n[9] [ ] BSP ents output \n[0] Main Menu \n"; + else if (dump_mode == 2) + s3 = "[7] [ ] WAY output \n[8] [ ] QC output \n[9] [#] BSP ents output \n[0] Main Menu \n"; + + } + else if (self.b_menu == 8) + s1 = "-- Link Ways --\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 9) + s1 = "-- Telelink Ways --\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 10) + s1 = "-- Delete Link --\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 11) + s1 = "-- Create Link X2 --\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 12) + s1 = "-- Delete Link X2 --\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 13) + s1 = "-- Delete ALL Ways --\n\nAre you sure? Push 1 to go\nthrough with it, 2 to cancel"; + else if (self.b_menu == 14) + { + s1 = "-- Teleport to Way # --\n\nEnter way number and press\nimpulse 104 to warp\n\nWaypoint #"; + s2 = ftos(self.b_menu_value); + + } + else if (self.b_menu == 15) + s1 = "-- Delete Waypoint --\n\nAre you sure? Push 1 to go\nthrough with it, 2 to cancel"; + frik_big_centerprint(self, s1, s2, s3, s4, s5, s6, s7); + self.b_menu_time = time + 1.25; + } +}; + + +// engage menu +void() bot_way_edit = +{ + local entity t; + local float f; + if (self.b_menu_value) + { + if (self.b_menu == 14) + { + t = WaypointForNum(self.b_menu_value); + if (t) + setorigin(self, t.origin - self.view_ofs); + else + sprint(self, "No waypoint with that number\n"); + + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + self.b_menu_value = 0; + return; + } + if (waypoint_mode < WM_EDITOR) + { + self.b_menu = MENU_MAIN; + waypoint_mode = WM_EDITOR; + self.b_menu_time = 0; + cvar_set("saved2", "0"); + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, "MAKE SURE THE FOLLOWING LINE CONTAINS -CONDEBUG BEFORE PROCEEDING\n"); + localcmd("cmdline\n"); + t = way_head; + while (t) + { + setmodel(t, "progs/s_bubble.spr"); // show the waypoints + t = t._next; + } + if (self.current_way) + setmodel(self.current_way, "progs/s_light.spr"); + } + else + { + saved2 = cvar("saved2"); + if (saved2 != 0) + { + f = self.b_menu; + self.b_menu = floor(saved2/16); + self.impulse = saved2 & 15; + bot_menu_display(); + self.b_menu = f; + cvar_set("saved2", "0"); + return; + } + self.b_menu = 0; + waypoint_mode = WM_LOADED; + t = way_head; + while (t) + { + setmodel(t, string_null); // hide the waypoints + t = t._next; + } + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Saving to file. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +// bytecount is really iffy +// since there is no true way to determine the length of an ftos +// it uses an approximate of 5 +// various other things are guesses, but I don't cut it at the absolute +// max so it should be okay + +void() PrintWaypoint = +{ + local entity t; + local float needcolon; + local string h; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + if (bytecounter >= 8000) + { + bprint("exec maps/"); + bprint(mapname); + bprint(".wa"); + h = ftos(filecount); + bprint(h); + filecount = filecount + 1; + bprint("\n// **** break here **** \n"); + bytecounter = 26; + } + if (t == world) + { + remove(self); + fixer = world; + bprint("saved4 3\n// end waypoint dump\n"); + bytecounter = bytecounter + 27; + return; + } + if ((t.origin_x != saved1) || (t.count == 1)) + { + bprint("saved1 "); + h = ftos(t.origin_x); + bprint(h); + saved1 = t.origin_x; + bytecounter = bytecounter + 12; + needcolon = TRUE; + } + if ((t.origin_y != saved2) || (t.count == 1)) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("saved2 "); + h = ftos(t.origin_y); + bprint(h); + bytecounter = bytecounter + 12; + saved2 = t.origin_y; + } + if ((t.origin_z != saved3) || (t.count == 1)) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("saved3 "); + h = ftos(t.origin_z); + bprint(h); + bytecounter = bytecounter + 12; + saved3 = t.origin_z; + } + bytecounter = bytecounter + 1; + bprint("\n"); + needcolon = FALSE; + if ((scratch1 != t.target1.count) || t.count == 1) + { + needcolon = TRUE; + bprint("scratch1 "); + bytecounter = bytecounter + 14; + h = ftos(t.target1.count); + bprint(h); + scratch1 = t.target1.count; + } + if ((scratch2 != t.target2.count) || t.count == 1) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("scratch2 "); + bytecounter = bytecounter + 14; + h = ftos(t.target2.count); + bprint(h); + scratch2 = t.target2.count; + } + if ((scratch3 != t.target3.count) || t.count == 1) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("scratch3 "); + bytecounter = bytecounter + 14; + h = ftos(t.target3.count); + bprint(h); + scratch3 = t.target3.count; + } + if ((scratch4 != t.target4.count) || t.count == 1) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("scratch4 "); + bytecounter = bytecounter + 14; + h = ftos(t.target4.count); + bprint(h); + scratch4 = t.target4.count; + } + bprint("\nsaved4 "); + bytecounter = bytecounter + 19; + if (t.count != 1) + h = ftos(t.b_aiflags * 4 + 2); + else + h = ftos(t.b_aiflags * 4 + 1); + bprint(h); + bprint ("; wait\n"); + self.nextthink = time + 0.01; + self.enemy = t; +}; + +// to allow for 100+ waypoints, we need to trick the runaway loop counter +void() DumpWaypoints = +{ + bytecounter = 50; + filecount = 1; + + bprint("// "); + bprint(world.message); + bprint("- maps/"); + bprint(mapname); + bprint(".way\n"); + bprint("// Ways by "); + bprint(self.netname); + bprint("\n"); + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = PrintWaypoint; + fixer.enemy = world; + } +}; + +void() PrintQCWaypoint = +{ + local entity t; + local string h; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + + if (t == world) + { + remove(self); + fixer = world; + bprint("};\n\n// End dump\n"); + return; + } + bprint(" make_way("); + h = vtos(t.origin); + bprint(h); + bprint(", '"); + h = ftos(t.target1.count); + bprint(h); + bprint(" "); + h = ftos(t.target2.count); + bprint(h); + bprint(" "); + h = ftos(t.target3.count); + bprint(h); + bprint("', "); + h = ftos(t.target4.count); + bprint(h); + bprint(", "); + h = ftos(t.b_aiflags); + bprint(h); + bprint(");\n"); + self.nextthink = time + 0.01; + self.enemy = t; + +}; +void() QCDumpWaypoints = +{ + bprint("/* QC Waypoint Dump - src/frikbot/map_"); + + bprint(mapname); + bprint(".qc\nFor instructions please read the\nreadme.html that comes with FrikBot */\n\nvoid(vector org, vector bit1, float bit4, float flargs) make_way;\n"); + bprint("// Ways by "); + bprint(self.netname); + bprint("\n\n"); + + bprint("void() map_"); + bprint(mapname); + bprint(" =\n{\n"); + + + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = PrintQCWaypoint; + fixer.enemy = world; + } +}; + +void() PrintBSPWaypoint = +{ + local entity t; + local string h; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + + if (t == world) + { + bprint("\n\n// End dump\n"); + remove(self); + fixer = world; + return; + } + bprint("{\n\"classname\" \"waypoint\"\n\"origin\" \""); + h = ftos(t.origin_x); + bprint(h); + bprint(" "); + h = ftos(t.origin_y); + bprint(h); + bprint(" "); + h = ftos(t.origin_z); + bprint(h); + if (t.target1.count) + { + bprint("\"\n\"b_pants\" \""); + h = ftos(t.target1.count); + bprint(h); + } + if (t.target2.count) + { + bprint("\"\n\"b_skill\" \""); + h = ftos(t.target2.count); + bprint(h); + } + if (t.target3.count) + { + bprint("\"\n\"b_shirt\" \""); + h = ftos(t.target3.count); + bprint(h); + } + if (t.target4.count) + { + bprint("\"\n\"b_frags\" \""); + h = ftos(t.target4.count); + bprint(h); + } + if (t.b_aiflags) + { + bprint("\"\n\"b_aiflags\" \""); + h = ftos(t.b_aiflags); + bprint(h); + } + bprint("\"\n}\n"); + self.nextthink = time + 0.01; + self.enemy = t; + +}; +void() BSPDumpWaypoints = +{ + bprint("/* BSP entities Dump - maps/"); + + bprint(mapname); + bprint(".ent\nFor instructions please read the\nreadme.html that comes with FrikBot */\n\n\n"); + + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = PrintBSPWaypoint; + fixer.enemy = world; + } +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_fight.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_fight.qc new file mode 100755 index 00000000..bb8d9987 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_fight.qc @@ -0,0 +1,438 @@ +/*********************************************** +* * +* FrikBot Fight Code * +* "Because I ain't no Ghandi code" * +* * +***********************************************/ + +/* +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. +*/ + +.entity avoid; + +float(entity e) bot_size_player = +{ + local float sz; + + sz = e.health + e.armorvalue * e.armortype; + if (e.weapon == 32) + sz = sz + 60; + else if (e.weapon == 64) + sz = sz + 60; + else if (e.weapon == 16) + sz = sz + 50; + else if (e.weapon == 8) + sz = sz + 50; + else if (e.weapon == 4) + sz = sz + 40; + else if (e.weapon == 2) + sz = sz + 40; + else if (e.weapon == 1) + sz = sz + 10; + else if (e.weapon == 4096) + sz = sz - 50; + if (e.items & 4194304) // Quad + sz = sz + 200; + if (e.items & 1048576) // Invul + sz = sz + 300; + if (e.items & 524288) // Invis + sz = sz + 250; + return sz; +}; + +void() bot_dodge_stuff = +{ + local entity foe; + local float foedist, avdist, foesz, flen, tsz; + local vector v; + + if (waypoint_mode > WM_LOADED) + return; + + self.avoid = world; + + + if (self.enemy) + { + v = self.origin - realorigin(self.enemy); + foedist = vlen(v); + foesz = bot_size_player(self.enemy); + } + else + { + foedist = 3000; + foesz = 9999999; + } + avdist = 256; + + foe = find(world, classname, "grenade"); + while(foe) + { + flen = vlen(foe.origin - self.origin); + if (flen < avdist) + { + avdist = flen; + self.avoid = foe; + } + foe = find(foe, classname, "grenade"); + } + if (!self.avoid) + { + foe = find(world, classname, "missile"); + while(foe) + { + if (foe.owner != self) + { + flen = vlen(foe.origin - self.origin); + if (flen < avdist) + { + avdist = flen; + self.avoid = foe; + } + } + foe = find(foe, classname, "missile"); + } + if (!self.avoid) + { + foe = find(world, classname, "spike"); + while(foe) + { + if (foe.owner != self) + { + flen = vlen(foe.origin - self.origin); + if (flen < avdist) + { + avdist = flen; + self.avoid = foe; + } + } + foe = find(foe, classname, "spike"); + } + } + } + if (coop) + { + if (!self.enemy) + { + foe = findradius(self.origin, foedist); + while(foe) + { + if(foe.flags & FL_MONSTER) + { + if(foe.health > 0) + { + flen = vlen(foe.origin - self.origin); + if (flen < foedist) + { + tsz = bot_size_player(foe); + if (tsz < foesz) + { + if (fisible(foe)) + { + self.enemy = foe; + foedist = flen; + foesz = tsz; + } + } + } + } + } + foe = foe.chain; + } + } + } + else + { + foe = player_head; + while(foe) + { + if(foe != self) + { + if (foe.modelindex != 0) + { + if (foe.health > 0) + { + if (!(teamplay && self.team == foe.team)) + { + flen = vlen(foe.origin - self.origin); + if (flen < foedist) + { + tsz = bot_size_player(foe); + if (tsz < foesz) + { + if (fov(foe) || foe.b_sound > time || self.b_skill == 3) + { + if (fisible(foe)) + { + self.enemy = foe; + foedist = vlen(foe.origin - self.origin); + } + } + } + } + } + } + } + } + foe = foe._next; + } + } +}; + + + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +weapon_range + +_x "sweet spot range" - try to maintain this range if possible +_y minimum range bot can be to be effective (rl/gl) (move away) +_z maximum range bot can be to be effective (lg/axe) (move in) +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +vector(float wep) weapon_range = +{ + if (wep == 4096) // IT_AXE + return '48 0 64'; + else if (wep == 1) // IT_SHOTGUN + return '128 0 99999'; + else if (wep == 2) // IT_SUPER_SHOTGUN + return '128 0 99999'; + else if (wep == 4) // IT_NAILGUN + return '180 0 3000'; + else if (wep == 8) // IT_SUPER_NAILGUN + return '180 0 3000'; + else if (wep == 16) // IT_GRENADE_LAUNCHER + return '180 48 3000'; + else if (wep == 32) // IT_ROCKET_LAUNCHER + return '180 48 3000'; + else if (wep == 64) // IT_LIGHTNING + return '350 0 512'; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_weapon_switch + +Pick a weapon based on range / ammo + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(float brange) bot_weapon_switch = +{ + local float it, flag, pulse; + local vector v; + + it = self.items & 127; + + while(it) + { + if ((self.ammo_rockets >= 1) && (it & 32)) + { + flag = 32; + pulse = 7; + } + else if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & 64)) + { + flag = 64; + pulse = 8; + } + else if(self.ammo_nails >= 2 && (it & 8)) + { + flag = 8; + pulse = 5; + } + else if ((self.ammo_rockets >= 1) && (it & 16)) + { + flag = 16; + pulse = 6; + } + else if(self.ammo_shells >= 2 && (it & 2)) + { + flag = 2; + pulse = 3; + } + else if(self.ammo_nails >= 1 && (it & 4)) + { + flag = 4; + pulse = 4; + } + else if(self.ammo_shells >= 1 && (it & 1)) + { + flag = 1; + pulse = 2; + } + else + { + if (pulse) + self.impulse = pulse; + return; + } + + if (brange == -1) + { + if (pulse) + self.impulse = pulse; + return; + } + + v = weapon_range(flag); + if (brange < v_y || brange > v_z) + it = it - flag; + else + { + if (pulse) + self.impulse = pulse; + return; + } + } +}; + +void() bot_shoot = +{ + // quick little function to stop making him shoot the wrong way ! Argh + local float g; + g = angcomp(self.v_angle_x, self.b_angle_x); + if (fabs(g) > 30) + return; // argh, too far away + g = angcomp(self.v_angle_y, self.b_angle_y); + if (fabs(g) > 30) + return; // not again! + self.button0 = TRUE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot_fight_style + +This is the core of the bot's thinking when +attacking an enemy. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_fight_style = +{ + local vector v, v1, v2, org; + local float foedist, mysz, foesz; + + + if (self.enemy.health <= 0) + { + self.enemy = world; + return; + } + else if (!self.enemy.takedamage) + { + self.enemy = world; + return; + } + else if (!fisible(self.enemy)) + { + self.enemy = world; + return; + } + + org = realorigin(self.enemy); + makevectors(self.v_angle); + + // decide if I should shoot + + foedist = vlen(org - self.origin); + v = weapon_range(self.weapon); + if (foedist > v_y && foedist < v_z) + { + traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * v_z, FALSE, self); + if (vlen(trace_endpos - (self.origin + self.view_ofs)) >= v_y) + { + // try to avoid shooting teammates + if (trace_ent.classname == "player") + if ((trace_ent.team == self.team && teamplay) || (coop)) + return; + bot_shoot(); + } + } + else + bot_weapon_switch(foedist); + + if (!(self.b_aiflags & (AI_PRECISION | AI_BLIND | AI_OBSTRUCTED))) + { + foesz = bot_size_player(self.enemy); + mysz = bot_size_player(self) + 5; + + if (foesz > mysz) + { + if (teamplay) + { + if (random() < 0.02) + { + bot_start_topic(5); + self.b_chattime = 1; + } + } + + return; + } + else if (mysz < 140) + return; + else if (self.avoid) + { + if (self.avoid.velocity) + v = self.avoid.velocity; + else + v = normalize(self.avoid.origin - self.origin); + v1_x = v_y; + v1_y = v_y * -1; + v2_x = v_y; + v2_y = v_y * -1; + foedist = vlen(self.avoid.origin - (self.origin + v1)); + if (foedist < vlen(self.avoid.origin - (self.origin + v2))) + frik_walkmove(v2); + else + frik_walkmove(v1); + } + else if (!self.enemy.flags & FL_MONSTER) + { + if (foedist + 32 < v_x) + frik_walkmove(self.origin - org); + else if (foedist - 32 > v_x) + frik_walkmove(org - self.origin); + else if (self.wallhug) + frik_walkmove(v_right); + else + frik_walkmove(v_right * -1); + } + } + else + { + foesz = bot_size_player(self.enemy); + mysz = bot_size_player(self) + 5; + + if (foesz > mysz) + return; + else if (mysz < 140) + return; + self.keys = self.keys & 960; + } +}; + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_misc.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_misc.qc new file mode 100755 index 00000000..e177343f --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_misc.qc @@ -0,0 +1,758 @@ +/*********************************************** +* * +* FrikBot Misc Code * +* "Because you can't name it anything else" * +* * +***********************************************/ + +/* +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. +*/ + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotName + +Sets bot's name and colors + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +string(float r) BotName = +{ + self.b_num = r; + if (r == 1) + { + self.b_pants = 11; + self.b_shirt = 0; + return "Mexicouger"; + } + else if (r == 2) + { + self.b_pants = 1; + self.b_shirt = 3; + return "Nate"; + } + else if (r == 3) + { + self.b_pants = 13; + self.b_shirt = 2; + return "DTMidian"; + } + else if (r == 4) + { + self.b_pants = 7; + self.b_shirt = 6; + return "Ducksrule"; + } + else if (r == 5) + { + self.b_pants = 12; + self.b_shirt = 6; + return "Ghostfang"; + } + else if (r == 6) + { + self.b_pants = 4; + self.b_shirt = 4; + return "Shallows"; + } + else if (r == 7) + { + self.b_pants = 2; + self.b_shirt = 5; + return "Hypermetal"; + } + else if (r == 8) + { + self.b_pants = 10; + self.b_shirt = 3; + return "Kryten"; + } + else if (r == 9) + { + self.b_pants = 9; + self.b_shirt = 4; + return "Pimp Bot"; + } + else if (r == 10) + { + self.b_pants = 4; + self.b_shirt = 7; + return "Max"; + } + else if (r == 11) + { + self.b_pants = 3; + self.b_shirt = 11; + return "Marvin"; + } + else if (r == 12) + { + self.b_pants = 13; + self.b_shirt = 12; + return "Erwin"; + } + else if (r == 13) + { + self.b_pants = 11; + self.b_shirt = 2; + return "FrikBot"; + } + else if (r == 14) + { + self.b_pants = 0; + self.b_shirt = 2; + return "Krosis"; + } + else if (r == 15) + { + self.b_pants = 8; + self.b_shirt = 9; + return "Gypsy"; + } + else if (r == 16) + { + self.b_pants = 5; + self.b_shirt = 10; + return "Hal"; + } +}; +string () PickARandomName = +{ + if (bot_count > 16) + return "player"; + + local float y, test; + local string h; + local entity t; + y = TRUE; + while(y) + { + test = ceil(random() * 16); + h = BotName(test); + t = find(world, netname, h); + if (t == world) + y = FALSE; + } + return h; +}; + + + +// I didn't like the old code so this is very stripped down + +entity b_originator; +float b_topic; +/* FBX Topics + +b_originator == self + 1 - sign on + 2 - killed targ + 3 - team message "friendly eyes" + 4 - team message "on your back" + 5 - team message "need back up" + 6 - excuses + ---- + 7 - gameover + ---- + 8 - welcoming someone onto server + 9 - ridicule lost frag (killed self?) + 10 - ridicule lost frag (lava) + 11 - lag +b_originator == targ + + +*/ +void(float tpic) bot_start_topic = +{ + if (random() < 0.2) + { + b_topic = tpic; + b_originator = self; + } + else + b_topic = 0; +}; + +void() bot_chat = +{ + local float r; + if (b_options & OPT_NOCHAT) + return; + r = ceil (random() * 6); + + if (self.b_chattime > time) + { + if (self.b_skill < 2) + self.keys = self.button0 = self.button2 = 0; + return; + } + else if (self.b_chattime) + { + if (b_topic == 1) + { + if (b_originator == self) + { + if (r == 1) + { + BotSay(": lo all\n"); + bot_start_topic(8); + } + else if (r == 2) + { + BotSay(": hey everyone\n"); + bot_start_topic(8); + } + else if (r == 3) + { + BotSay(": prepare to be fragged!\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSay(": boy this is laggy\n"); + bot_start_topic(11); + } + else if (r == 5) + { + BotSay(": #mm getting some lag here\n"); + bot_start_topic(11); + } + else + { + BotSay(": hi everyone\n"); + bot_start_topic(8); + } + } + } + else if (b_topic == 2) + { + if (b_originator == self) + { + if (r == 1) + BotSay(": take that\n"); + else if (r == 2) + BotSay(": yehaww!\n"); + else if (r == 3) + BotSay(": wh00p\n"); + else if (r == 4) + BotSay(": j00_sawk();\n"); + else if (r == 5) + BotSay(": i rule\n"); + else + BotSay(": eat that\n"); + bot_start_topic(0); + } + } + else if (b_topic == 3) + { + if (b_originator == self) + { + if (r < 3) + BotSayTeam(": friendly eyes\n"); + else + BotSayTeam(": team eyes\n"); + bot_start_topic(0); + } + } + else if (b_topic == 4) + { + if (b_originator == self) + { + if (r < 3) + BotSayTeam(": on your back\n"); + else + BotSayTeam(": I'm with you\n"); + bot_start_topic(0); + } + } + else if (b_topic == 5) + { + if (b_originator == self) + { + if (r < 3) + BotSayTeam(": I need help\n"); + else + BotSayTeam(": need backup\n"); + bot_start_topic(0); + } + } + else if (b_topic == 6) + { + if (b_originator == self) + { + if (r == 1) + { + BotSay(": sun got in my eyes\n"); + bot_start_topic(0); + } + else if (r == 2) + { + BotSay(": mouse needs cleaning\n"); + bot_start_topic(0); + } + else if (r == 3) + { + BotSay(": i meant to do that\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSay(": lag\n"); + bot_start_topic(11); + } + else if (r == 5) + { + BotSay(": killer lag\n"); + bot_start_topic(11); + } + else + { + BotSay(": 100% lag\n"); + bot_start_topic(11); + } + } + } + else if (b_topic == 7) + { + if (r == 1) + BotSay(": gg\n"); + else if (r == 2) + BotSay(": gg all\n"); + else if (r == 3) + BotSay(": that was fun\n"); + else if (r == 4) + BotSay(": good game\n"); + else if (r == 5) + BotSay(": pah\n"); + else + BotSay(": hrm\n"); + bot_start_topic(0); + } + else if (b_topic == 8) + { + if (b_originator != self) + { + if (r == 1) + { + BotSay(": heya\n"); + bot_start_topic(0); + } + else if (r == 2) + { + BotSay(": welcome\n"); + bot_start_topic(0); + } + else if (r == 3) + { + BotSayInit(); + BotSay2(": hi "); + BotSay2(b_originator.netname); + BotSay2("\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSayInit(); + BotSay2(": hey "); + BotSay2(b_originator.netname); + BotSay2("\n"); + bot_start_topic(0); + } + else if (r == 5) + { + BotSay(": howdy\n"); + bot_start_topic(0); + } + else + { + BotSay(": lo\n"); + bot_start_topic(0); + } + } + } + + else if (b_topic == 9) + { + if (b_originator != self) + { + if (r == 1) + BotSay(": hah\n"); + else if (r == 2) + BotSay(": heheh\n"); + else if (r == 3) + { + BotSayInit(); + BotSay2(": good work "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 4) + { + BotSayInit(); + BotSay2(": nice1 "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 5) + BotSay(": lol\n"); + else + BotSay(": :)\n"); + b_topic = 6; + } + } + else if (b_topic == 10) + { + if (b_originator != self) + { + if (r == 1) + BotSay(": have a nice dip?\n"); + else if (r == 2) + BotSay(": bah I hate levels with lava\n"); + else if (r == 3) + { + BotSayInit(); + BotSay2(": good job "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 4) + { + BotSayInit(); + BotSay2(": nice backflip "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 5) + BotSay(": watch your step\n"); + else + BotSay(": hehe\n"); + b_topic = 6; + } + } + + else if (b_topic == 11) + { + if (b_originator != self) + { + if (r == 1) + { + BotSayInit(); + BotSay2(": yeah right "); + BotSay2(b_originator.netname); + BotSay2("\n"); + bot_start_topic(0); + } + else if (r == 2) + { + BotSay(": ping\n"); + bot_start_topic(0); + } + else if (r == 3) + { + BotSay(": shuddup, you're an lpb\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSay(": lag my eye\n"); + bot_start_topic(0); + } + else if (r == 5) + { + BotSay(": yeah\n"); + bot_start_topic(11); + } + else + { + BotSay(": totally\n"); + bot_start_topic(11); + } + } + } + self.b_chattime = 0; + } + else if (b_topic) + { + if (random() < 0.5) + { + if (self == b_originator) + { + if (b_topic <= 7) + self.b_chattime = time + 2; + } + else + { + if (b_topic >= 7) + self.b_chattime = time + 2; + } + } + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Kick A Bot. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() KickABot = +{ + local entity ty; + ty = find(world, classname, "player"); + while (ty != world) + { + if (!(ty.ishuman)) + { + + BotDisconnect(ty); + ty.ishuman = TRUE; + ty = world; + } + else + ty = find(ty, classname, "player"); + } + +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Simplified origin checking. + +God, I wish I had inline + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +vector(entity ent) realorigin = +{ +// even more simplified... + return (ent.absmin + ent.absmax) * 0.5; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +fisible + +a version of visible that checks for corners +of the bounding boxes + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float (entity targ) fisible = +{ + local vector spot1, org; + local float thruwater, pc1, pc2; + + org = realorigin(targ); + spot1 = self.origin + self.view_ofs; + + if (targ.solid == SOLID_BSP) + { + traceline (spot1, org, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; + } + else + { + pc1 = pointcontents(org); + pc2 = pointcontents(spot1); + if (targ.classname == "player") + thruwater = FALSE; + else if (pc1 == CONTENT_LAVA) + return FALSE; + else + thruwater = TRUE; + } + + if (pc1 < -1) // targ's origin is in water or other liquid + { + if (pc2 != pc1) + { + // look for their head + traceline (spot1, org + targ.mins, TRUE, self); + // cross the water check + if (trace_inopen) + if (trace_inwater) + if (!thruwater) + return FALSE; + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; + } + } + else + { + if (pc2 != pc1) + { + traceline (spot1, org + targ.maxs, TRUE, self); + if (trace_inopen) + if (trace_inwater) + if (!thruwater) + return FALSE; + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; + } + } + traceline (spot1, org, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + traceline (spot1, org + targ.maxs, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + traceline (spot1, org + targ.mins, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Wisible + +goes through movable brushes/entities, used +for waypoints + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +// this is used for waypoint stuff.... +float (entity targ1, entity targ2) wisible = +{ + local vector spot1, spot2; + local entity ignore; + + spot1 = targ1.origin; + spot2 = realorigin(targ2); + + ignore = self; + do + { + traceline (spot1, spot2, TRUE, ignore); + spot1 = realorigin(trace_ent); + ignore = trace_ent; + } while ((trace_ent != world) && (trace_fraction != 1)); + if (trace_endpos == spot2) + return TRUE; + else + return FALSE; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +sisible + +Now this is getting ridiculous. Simple visible, +used when we need just a simple traceline nothing else + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float (entity targ) sisible = +{ + traceline (self.origin, targ.origin, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +angcomp + +subtracts one angle from another + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float (float y1, float y2) angcomp = +{ + y1 = frik_anglemod(y1); + y2 = frik_anglemod(y2); + + local float answer; + answer = y1 - y2; + if (answer > 180) + answer = (360 - answer) * -1; + else if (answer < -180) + answer = answer + 360; + return answer; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +fov + +is the entity in the bot's field of view + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float (entity targ) fov = +{ + local vector yawn; + local float g; + yawn = realorigin(targ); + yawn = (yawn + targ.view_ofs) - (self.origin + self.view_ofs); + yawn = normalize(yawn); + yawn = vectoangles(yawn); + g = angcomp(self.v_angle_x, yawn_x); + if (fabs(g) > 45) + return FALSE; + g = angcomp(self.v_angle_y, yawn_y); + if (fabs(g) > 60) + return FALSE; + + return TRUE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +frik_anglemod + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float(float v) frik_anglemod = +{ + return v - floor(v/360) * 360; +} \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_move.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_move.qc new file mode 100755 index 00000000..fd12f77c --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_move.qc @@ -0,0 +1,487 @@ +/*********************************************** +* * +* FrikBot Movement AI * +* "The slightly better movement AI" * +* * +***********************************************/ + +/* +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. +*/ + +void() bot_jump = +{ + // TODO check for precision, etc. + self.button2 = TRUE; +}; + +float(entity e) bot_can_rj = +{ + // this returns true of the bot can rocket/superjump/hook + // if your mod doesn't have an RL you can just return FALSE all the time + // if it has a hook or some other means for the bot to get to high places + // you can check here for that capability + + // am I dumb? + if (e.b_skill == 0) + return FALSE; + + // quad = bad + if (e.items & 4194304) + return FALSE; + + // do I have rockets & RL? + if (!((e.items & 32) && (e.ammo_rockets > 0))) + return FALSE; + + // do I have pent? + if (e.items & 1048576) + return TRUE; + + if (e.health > 50) + return TRUE; + else + return FALSE; +}; + +float(float flag) frik_recognize_plat = +{ + if ((self.classname != "waypoint") && !(self.flags & FL_ONGROUND)) + return FALSE; + traceline(self.origin, self.origin - '0 0 64', TRUE, self); + if (trace_ent != world) + { + if (flag) // afect bot movement too + { + if (self.keys & KEY_MOVEUP) + { + if (trace_ent.velocity_z > 0) + self.keys = self.keys & 960; // 960 is all view keys + } + else if (self.keys & KEY_MOVEDOWN) + { + if (trace_ent.velocity_z < 0) + self.keys = self.keys & 960; + } + } + return TRUE; + } + else + return FALSE; +}; + +float(vector sdir) frik_KeysForDir = +{ + + local vector keydir; + local float outkeys, tang; + outkeys = 0; + if (sdir_x || sdir_y) + { + // Everything is tested against 60 degrees, + // this allows the bot to overlap the keys + // 30 degrees on each diagonal 45 degrees + // might look more realistic + + keydir = vectoangles(sdir); + tang = angcomp(keydir_y, self.v_angle_y); + if ((tang <= 150) && (tang >= 30)) + outkeys = outkeys + KEY_MOVELEFT; + else if ((tang >= -150) && (tang <= -30)) + outkeys = outkeys + KEY_MOVERIGHT; + if (fabs(tang) <= 60) + outkeys = outkeys + KEY_MOVEFORWARD; + else if (fabs(tang) >= 120) + outkeys = outkeys + KEY_MOVEBACK; + } + if (sdir_z > 0.7) + outkeys = outkeys + KEY_MOVEUP; + else if (sdir_z < 0.7) + outkeys = outkeys + KEY_MOVEDOWN; + return outkeys; + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +frik_obstructed + +Bot has hit a ledge or wall that he should +manuever around. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(vector whichway, float danger) frik_obstructed = +{ + local float dist; + local vector disway, org; +// TODO: something + if (self.b_aiflags & AI_BLIND) + return; + org = realorigin(self.target1); + + if (danger) + { + self.b_aiflags = self.b_aiflags | AI_DANGER; + self.keys = frik_KeysForDir('0 0 0' - whichway); + } + if (self.b_aiflags & AI_PRECISION) + return; + + + if (self.target1) + { + if (self.b_aiflags & AI_OBSTRUCTED) + { + if (!(self.b_aiflags & AI_DANGER)) + { + self.b_aiflags = self.b_aiflags - AI_OBSTRUCTED; + return; + } + else if (!danger) + return; + } + self.obs_dir = whichway; + disway_x = whichway_y * -1; + disway_y = whichway_x; + dist = vlen(org - (self.origin + disway)); + disway_x = whichway_y; + disway_y = whichway_x * -1; + self.wallhug = vlen(org - (self.origin + disway)) > dist; + self.b_aiflags = self.b_aiflags | AI_OBSTRUCTED; + + } + else + { + disway_x = whichway_y * -1; + disway_y = whichway_x; + dist = vlen(disway - self.obs_dir); + disway_x = whichway_y; + disway_y = whichway_x * -1; + self.wallhug = vlen(disway - self.obs_dir) < dist; + self.obs_dir = whichway; + + self.b_aiflags = self.b_aiflags | AI_OBSTRUCTED; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +frik_obstacles + +Detects small bumps the bot needs to jump over +or ledges the bot should avoid falling in. + +Also responsible for jumping gaps. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_obstacles = +{ + local vector start, stop, ang; + local float test, conts, dist, hgt; + + if (!(self.flags & FL_ONGROUND)) + return; + if (self.b_aiflags & AI_BLIND) + return; + + ang = normalize(self.velocity); + ang_z = 0; + start = self.origin + ang * 32; // ahem + start_z = self.origin_z + self.maxs_z; + stop = start; + stop_z = self.origin_z + self.mins_z; + traceline(start, stop - '0 0 256', TRUE, self); + if (trace_allsolid || trace_startsolid) + return; + hgt = trace_endpos_z - stop_z; + + if (hgt > 18) + { + bot_jump(); + return; + } + else if (hgt <= -64) // this might be a gap + { + conts = pointcontents(trace_endpos + '0 0 4'); + start = stop - '0 0 8'; + stop = start + ang * 256; + traceline(start, stop, TRUE, self); + test = vlen(trace_endpos - start); + if (test <= 20) + return; // it's a walkable gap, do nothing + ang_x = self.velocity_y * -1; + ang_y = self.velocity_x; + ang = normalize(ang); + traceline(start - (ang * 10), start + (ang * 10), TRUE, self); + if ((trace_fraction != 1) || trace_startsolid) + return; // gap is only 20 wide, walkable + ang = self.velocity; + ang_z = 0; + dist = ((540 / sv_gravity) * vlen(ang))/* + 32*/; + if (test > dist) // I can't make it + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + else + { + if (self.target1) + { + stop = realorigin(self.target1); + if ((stop_z - self.origin_z) < -32) + return; // safe to fall + } + frik_obstructed(ang, FALSE); + return; + } + } + else + { + ang = normalize(ang); + //look for a ledge + traceline(self.origin, self.origin + (ang * (test + 20)), TRUE, self); + if (trace_fraction != 1) + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + else + { + if (self.target1) + { + stop = realorigin(self.target1); + if ((stop_z - self.origin_z) < -32) + return; // safe to fall + } + frik_obstructed(ang, FALSE); + return; + } + } + + if (self.target1) + { + // getting furter away from my target + test = vlen(self.target1.origin - (ang + self.origin)); + if (test > vlen(self.target1.origin - self.origin)) + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + else + { + frik_obstructed(ang, FALSE); + return; + } + } + } + } + // go for it + bot_jump(); + } + else if (pointcontents(trace_endpos + '0 0 4') < -3) + { + frik_obstructed(ang, TRUE); + return; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +After frik_obstructed, the bot uses the +following funtion to move "around" the obstacle + +I have no idea how well it will work + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_dodge_obstruction = +{ + local vector way, org; + local float oflags, yaw; + + if (!(self.b_aiflags & AI_OBSTRUCTED)) + return; + if ((self.b_aiflags & (AI_BLIND | AI_PRECISION)) || !(self.flags & FL_ONGROUND)) + { + self.b_aiflags = self.b_aiflags - AI_OBSTRUCTED; + return; + } + + // perform a walkmove check to see if the obs_dir is still obstructed + // walkmove is less forgiving than frik_obstacles, so I dunno + // how well this will work + + oflags = self.flags; + org = self.origin; + + yaw = vectoyaw(self.obs_dir); + if (walkmove(yaw, 32)) + self.b_aiflags = self.b_aiflags - AI_OBSTRUCTED; + else + { + if (self.b_aiflags & AI_DANGER) + { + way = '0 0 0' - self.obs_dir; + } + else if (self.wallhug) + { + way_x = self.obs_dir_y * -1; + way_y = self.obs_dir_x; + } + else + { + way_x = self.obs_dir_y; + way_y = self.obs_dir_x * -1; + } + self.keys = self.keys & 960 + frik_KeysForDir(way); + } + + // fix the bot + + self.origin = org; + self.flags = oflags; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +movetogoal and walkmove replacements + +blah + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_movetogoal = +{ + local vector way; + local float g; + + if (self.target1 == world) + { + makevectors(self.v_angle); + frik_walkmove(v_forward); + return; + } + way = realorigin(self.target1) - self.origin; + if (vlen(way) < 25) + { + self.keys = self.keys & 960; + return; + } + + way = normalize(way); + self.keys = self.keys & 960 + frik_KeysForDir(way); + + frik_dodge_obstruction(); + frik_recognize_plat(TRUE); + + if (self.b_aiflags & AI_PRECISION) + { + g = angcomp(self.v_angle_x, self.b_angle_x); + if (fabs(g) > 10) + self.keys = self.keys & 960; + g = angcomp(self.v_angle_y, self.b_angle_y); + if (fabs(g) > 10) + self.keys = self.keys & 960; + } +}; + +float(vector weird) frik_walkmove = +{ + // okay so it's not walkmove + // sue me + self.keys = self.keys & 960 + frik_KeysForDir(weird); + + frik_dodge_obstruction(); + frik_recognize_plat(TRUE); + if (self.b_aiflags & AI_OBSTRUCTED) + return FALSE; + else + return TRUE; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +The "hook" method of navigation. This nav +system is copyrighted 1999 by Ryan "Frika C" +Smith, keep that in mind when you steal it. + +I brought this back because normal roaming +won't work - the bot gets distracted by it's +own waypoints. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_bot_roam = +{ + local vector org, ang, org1; + local float loopcount, flag, dist; + + loopcount = 26; + flag = FALSE; + while((loopcount > 0) && !flag) + { + loopcount = loopcount - 1; + org = self.origin + self.view_ofs; + ang = self.angles; + ang_y = frik_anglemod(ang_y - 90 + (random() * 180)); + ang_x = 0; // avoid upward sloping + makevectors(ang); + traceline(org, org + v_forward * 2300, TRUE, self); + if (trace_fraction != 1) + { + org1 = trace_endpos; + ang = normalize(trace_plane_normal); + ang_z = 0; // avoid upward sloping + traceline(org1, org1 + (ang * 2300), TRUE, self); + if ((trace_fraction != 1) && (vlen(trace_endpos - org1) >= 64)) + { + org = trace_endpos; + traceline(org, self.origin + self.view_ofs, TRUE, self); + if (trace_fraction != 1) + { + dist = vlen(org1 - org) /2; + org = org1 + (ang * dist); + traceline(org, org - '0 0 48', TRUE, self); + if (trace_fraction != 1) + { + SpawnTempWaypoint(org); + flag = TRUE; + } + } + } + } + } + self.b_angle_y = self.v_angle_y + 10; +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_phys.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_phys.qc new file mode 100755 index 00000000..cf51766a --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_phys.qc @@ -0,0 +1,658 @@ +/*********************************************** +* * +* FrikBot Physics * +* The near-perfect emulation of * +* Client movement * +* * +* Special Thanks to: Asdf, Frog * +* Alan "Strider" Kivlin * +* * +* * +***********************************************/ + +/* +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. +*/ + +/* +========================================= + +Stuff mimicking cl_input.c code + +========================================= +*/ +float(float key) CL_KeyState = +{ + return ((self.keys & key) > 0); +}; + +void() CL_KeyMove = // CL_BaseMove + CL_AdjustAngles +{ + local float anglespeed; + local vector view; + if (self.keys != self.oldkeys) + { + self.movevect = '0 0 0'; + self.movevect_y = self.movevect_y + (350 * CL_KeyState(KEY_MOVERIGHT)); + // 350 is the default cl_sidespeed + self.movevect_y = self.movevect_y - (350 * CL_KeyState(KEY_MOVELEFT)); + // 350 is the default cl_sidespeed + self.movevect_x = self.movevect_x + (200 * CL_KeyState(KEY_MOVEFORWARD)); + // 200 is the default cl_forwardspeed + self.movevect_x = self.movevect_x - (200 * CL_KeyState(KEY_MOVEBACK)); + // 200 is the default cl_backspeed + self.movevect_z = self.movevect_z + (200 * CL_KeyState(KEY_MOVEUP)); + // 200 is the default cl_upspeed + self.movevect_z = self.movevect_z - (200 * CL_KeyState(KEY_MOVEDOWN)); + // 200 is the default cl_upspeed + if (!self.b_aiflags & AI_PRECISION) + self.movevect = self.movevect * 2; + // 2 is the default cl_movespeedkey & bot always has +speed + } + self.oldkeys = self.keys; + + if (self.b_skill != 2) // use mouse emulation + { + anglespeed = 1.5 * real_frametime; + // 1.5 is the default cl_anglespeedkey & bot always has +speed + self.v_angle_y = self.v_angle_y + anglespeed * CL_KeyState(KEY_LOOKLEFT) * 140; + // 140 is default cl_yawspeed + self.v_angle_y = self.v_angle_y - anglespeed * CL_KeyState(KEY_LOOKRIGHT) * 140; + // 140 is default cl_yawspeed + self.v_angle_x = self.v_angle_x - anglespeed * CL_KeyState(KEY_LOOKUP) * 150; + // 150 is default cl_pitchspeed + self.v_angle_x = self.v_angle_x + anglespeed * CL_KeyState(KEY_LOOKDOWN) * 150; + // 150 is default cl_pitchspeed + } + else + { + view_x = angcomp(self.b_angle_x, self.v_angle_x); + view_y = angcomp(self.b_angle_y, self.v_angle_y); + if (vlen(view) > 30) + { + self.mouse_emu = self.mouse_emu + (view * 30); + if (vlen(self.mouse_emu) > 180) + self.mouse_emu = normalize(self.mouse_emu) * 180; + } + else + self.mouse_emu = view * (1 / real_frametime); + self.v_angle = self.v_angle + self.mouse_emu * real_frametime; + + + } + if (self.v_angle_x > 80) + self.v_angle_x = 80; + else if (self.v_angle_x < -70) + self.v_angle_x = -70; + + if (self.v_angle_z > 50) + self.v_angle_z = 50; + else if (self.v_angle_z < -50) + self.v_angle_z = -50; + self.v_angle_y = frik_anglemod(self.v_angle_y); + +}; + +/* +========================================= + +Stuff mimicking sv_user.c + +========================================= +*/ +void() SV_UserFriction = +{ + local vector vel, start, stop; + local float sped, friction, newspeed; + + vel = self.velocity; + vel_z =0; + sped = vlen(vel); + vel = self.velocity; + + if (!sped) + return; + +// if the leading edge is over a dropoff, increase friction + + start_x = stop_x = self.origin_x + vel_x / (sped * 16); + start_y = stop_y = self.origin_y + vel_y / (sped * 16); + start_z = self.origin_z + self.mins_z; + stop_z = start_z - 34; + + traceline(start, stop, TRUE, self); + + if (trace_fraction == 1) + friction = sv_friction * 2; // 2 is default edgefriction, removed for QW compatability + else + friction = sv_friction; + if (sped < sv_stopspeed) + newspeed = sped - real_frametime * sv_stopspeed * friction; + else + newspeed = sped - real_frametime * sped * friction; + + if (newspeed < 0) + newspeed = 0; + newspeed = newspeed / sped; + + self.velocity_y = vel_y * newspeed; + self.velocity_x = vel_x * newspeed; +}; +void() SV_WaterJump = +{ + if (time > self.teleport_time || !self.waterlevel) + { + self.flags = self.flags - (self.flags & FL_WATERJUMP); + self.teleport_time = 0; + } + self.velocity_x = self.movedir_x; + self.velocity_y = self.movedir_y; +}; + +void() DropPunchAngle = +{ + local float len; + len = vlen(self.punchangle); + self.punchangle = normalize(self.punchangle); + len = len - 10 * real_frametime; + if (len < 0) + len = 0; + self.punchangle = self.punchangle * len; +}; + + +void(vector wishvel) SV_AirAccelerate = +{ + local float addspeed, wishspd, accelspeed, currentspeed; + + wishspd = vlen(wishvel); + wishvel = normalize(wishvel); + if (wishspd > 30) + wishspd = 30; + currentspeed = self.velocity * wishvel; + addspeed = wishspd - currentspeed; + if (addspeed <= 0) + return; + accelspeed = 10 * sv_accelerate * wishspd * real_frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + self.velocity = self.velocity + accelspeed * wishvel; +}; + +void(vector wishvel) SV_Accelerate = +{ + local float addspeed, wishspd, accelspeed, currentspeed; + + wishspd = vlen(wishvel); + wishvel = normalize(wishvel); + + currentspeed = self.velocity * wishvel; + addspeed = wishspd - currentspeed; + if (addspeed <= 0) + return; + accelspeed = sv_accelerate * wishspd * real_frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + self.velocity = self.velocity + accelspeed * wishvel; +}; +void() SV_WaterMove = +{ + local vector wishvel; + local float wishspeed, addspeed, cspeed, newspeed; + makevectors(self.v_angle); + wishvel = v_right * self.movevect_y + v_forward * self.movevect_x; + + if (self.movevect == '0 0 0') + wishvel_z = wishvel_z - 60; + else + wishvel_z = wishvel_z + self.movevect_z; + wishspeed = vlen(wishvel); + + if (wishspeed > sv_maxspeed) + { + wishvel = (sv_maxspeed / wishspeed) * wishvel; + wishspeed = sv_maxspeed; + } + wishspeed = wishspeed * 0.7; + cspeed = vlen(self.velocity); + if (cspeed) + { + newspeed = cspeed - (real_frametime * cspeed * sv_friction); + if (newspeed < 0) + newspeed = 0; + self.velocity = self.velocity * (newspeed / cspeed); + + } + else + newspeed = 0; + + if (!wishspeed) + return; + addspeed = wishspeed - newspeed; + if (addspeed <= 0) + return; + wishvel = normalize(wishvel); + cspeed = sv_accelerate * wishspeed * real_frametime; + if (cspeed > addspeed) + cspeed = addspeed; + self.velocity = self.velocity + cspeed * wishvel; +}; +void() SV_AirMove = +{ + local vector wishvel, vangle; + + vangle = self.v_angle; + vangle_x = vangle_z = 0; + makevectors(vangle); + if (time < self.teleport_time && (self.movevect_x < 0)) + self.movevect_x = 0; + wishvel = v_right * self.movevect_y + v_forward * self.movevect_x; + + + if (self.movetype != MOVETYPE_WALK) + wishvel_z = self.movevect_z; + else + wishvel_z = 0; + if (vlen(wishvel) > sv_maxspeed) + wishvel = normalize(wishvel) * sv_maxspeed; + if (self.movetype == MOVETYPE_NOCLIP) + self.velocity = wishvel; + else if (self.flags & FL_ONGROUND) + { + SV_UserFriction(); + SV_Accelerate(wishvel); + } + else + SV_AirAccelerate (wishvel); +}; + +void() SV_ClientThink = +{ + local vector vangle; + + if (self.movetype == MOVETYPE_NONE) + return; + DropPunchAngle(); + if (self.health <= 0) + return; + self.v_angle_z = 0; // V_CalcRoll removed, sucks + self.angles_z = self.v_angle_z * 4; + vangle = self.v_angle + self.punchangle; + if (!self.fixangle) + { + self.angles_x = (vangle_x / -3); + self.angles_y = vangle_y; + } else + { + self.v_angle = self.angles; + self.fixangle = 0; + } + if (self.flags & FL_WATERJUMP) + { + SV_WaterJump(); + return; + } + if ((self.waterlevel >= 2) && (self.movetype != MOVETYPE_NOCLIP)) + { + SV_WaterMove(); + return; + } + SV_AirMove(); + +}; +/* +========================================= + +Stuff mimicking sv_phys.c + +========================================= +*/ + +float() SV_RunThink = +{ + local float thinktime, bkuptime; + thinktime = self.nextthink; + bkuptime = time; + if (thinktime <= 0 || thinktime > (time + real_frametime)) + return TRUE; + if (thinktime < time) + thinktime = time; + self.nextthink = 0; + time = thinktime; + other = world; + makevectors(self.v_angle); // hack + self.think(); + time = bkuptime; + return TRUE; +}; + +void(float scale) SV_AddGravity = +{ + self.velocity_z = self.velocity_z - (scale * sv_gravity * real_frametime); +}; + +float() SV_CheckWater = +{ + local vector point; + local float cont; + + point_x = self.origin_x; + point_y = self.origin_y; + self.waterlevel = 0; + self.watertype = CONTENT_EMPTY; + point_z = self.origin_z + self.mins_z + 1; + cont = pointcontents(point); + if (cont <= CONTENT_WATER) + { + self.watertype = cont; + self.waterlevel = 1; + point_z = self.origin_z + (self.mins_z + self.maxs_z) * 0.5; + cont = pointcontents(point); + if (cont <= CONTENT_WATER) + { + self.waterlevel = 2; + point_z = self.origin_z + self.view_ofs_z; + cont = pointcontents(point); + if (cont <= CONTENT_WATER) + self.waterlevel = 3; + } + } + return (self.waterlevel > 1); + +}; +void() RemoveThud = // well sometimes +{ + local entity oself; + if (other == world) + { + if (self.flags & FL_ONGROUND) + { + self.flags = self.flags - FL_ONGROUND; + } + } + else + { + if (other.solid == SOLID_BSP && (self.flags & FL_ONGROUND)) + { + // RM: Does this break anything? + // If not, then some more thuds have been removed. + self.flags = self.flags - FL_ONGROUND; + } + if (other == self.owner) + return; + if (self.owner.solid == SOLID_NOT) + return; + oself = other; + other = self.owner; + self = oself; + if (self.solid == SOLID_BSP) + if (self.touch) + self.touch(); + } + +}; +void() SV_CheckOnGround = +{ + local vector org, v; + org = self.origin; + local float currentflags; + currentflags = self.flags; + self.flags = self.flags | FL_ONGROUND | FL_PARTIALGROUND; + walkmove(0,0); // perform C touch function + self.flags = currentflags | FL_ONGROUND; + if ((org_x != self.origin_x) || (org_y != self.origin_y)) + org = self.origin; + else + self.origin = org; + v = org; + v_z = self.maxs_z + org_z + 1; + traceline (org, v, TRUE, self); + if ((self.waterlevel == 3) && (self.movetype == MOVETYPE_WALK)) + self.flags = self.flags - FL_ONGROUND; + else if ((trace_plane_normal_z <= 0.7) && (trace_fraction != 1)) + self.flags = self.flags - FL_ONGROUND; + else if (!droptofloor(0,0)) + self.flags = self.flags - FL_ONGROUND; + else if (org_z - self.origin_z < 2) + self.flags = self.flags | FL_ONGROUND; + else + self.flags = self.flags - FL_ONGROUND; + setorigin(self, org); +}; +// Thanks to Alan Kivlin for this function +// modified heavily by me +float(vector dir) botCheckForStep = +{ + local vector currentorigin, v; + local float currentflags, yaw, stepdistance, movedistance; + currentorigin = self.origin; + currentflags = self.flags; + self.flags = FL_ONGROUND | FL_PARTIALGROUND; + dir = normalize(dir); + dir_z = 0; + yaw = vectoyaw(dir); + if(walkmove(yaw, 3)) + { + if(droptofloor(0,0)) + { + stepdistance = self.origin_z - currentorigin_z; + v = self.origin - currentorigin; + v_z = 0; + movedistance = vlen(v); + if((stepdistance > 0 && stepdistance <= 16) && movedistance != 0) + { + self.flags = currentflags | FL_PARTIALGROUND; + return 1; + } + } + } + self.flags = currentflags; + setorigin(self, currentorigin); + return 0; +}; +// this is merely here to fix a problem with e3m5 +void(vector dir) BruteForceStep = +{ + local vector currentorigin; + local float currentflags, i, len; + + currentorigin = self.origin; + currentflags = self.flags; + len = vlen(dir); + if (len > 16) + dir = normalize(dir) * 16; + + setorigin(self, currentorigin + dir); + + while(i < 18 && !walkmove(0, 0)) + { + self.origin_z = currentorigin_z + i; + i = i + 2; + } + self.flags = currentflags; + if (i >=18) + setorigin(self, currentorigin); +}; + +void() PostPhysics = +{ + local vector obstr, org; + local float back, dst,cflags; + + self = self.owner; + + self.velocity = self.velocity - self.phys_obj.dest1 + self.phys_obj.velocity; + if (self.phys_obj.dest2 == self.origin) + { + setorigin(self, self.phys_obj.origin); + // might've been moved during other person's physics + // (teleporters / plats) + + if (self.movetype == MOVETYPE_WALK) + { + + if (self.phys_obj.dest1_x || self.phys_obj.dest1_y) + { + if ((self.flags & FL_ONGROUND) || (self.waterlevel <= 2)) + { + obstr = self.phys_obj.movedir - self.origin; + obstr_z = 0; + if (vlen(obstr) > 0.1) + { + dst = vlen(obstr); + back = vectoyaw(obstr); + cflags = self.flags; + self.flags = self.flags | FL_PARTIALGROUND; + if(walkmove(back, dst)) + { + self.flags = cflags; + self.phys_obj.dest1_z = 0; + self.velocity = self.velocity + self.phys_obj.dest1 - self.phys_obj.velocity; + } + else + { + if (dst > 1) + frik_obstructed(obstr, FALSE); + + org = self.origin; + self.flags = cflags; + obstr = self.phys_obj.dest1; + obstr_x = 0; + if (!botCheckForStep(obstr)) + { + obstr = self.phys_obj.dest1; + obstr_y = 0; + if (!botCheckForStep(obstr)) + { + // if no steps were found, bot is really obstucted + BruteForceStep(self.phys_obj.dest1); + } + } + } + } + } + } + } + } + + SV_CheckOnGround(); + + PlayerPostThink(); + BotAI(); + self.dmg_take = self.dmg_save = 0; + +}; +// Avoid calling BotAI and the physics at the same time +// Can trip the runaway loop counter + +void() SV_FlyMove = +{ + // This is nothing like the Quake function. + + if (self.phys_obj == world) + { + self.phys_obj = find(world,classname,"phys_obj"); + while (self.phys_obj.owner != self) + { + self.phys_obj = find(self.phys_obj,classname,"phys_obj"); + if (self.phys_obj == world) + { + error("No physics entity spawned!\nMake sure BotInit was called\n"); + } + } + } + + setmodel (self.phys_obj, string_null); + self.phys_obj.movetype = MOVETYPE_STEP; + + self.phys_obj.solid = SOLID_TRIGGER; + self.phys_obj.touch = RemoveThud; + setsize(self.phys_obj, self.mins, self.maxs); + self.phys_obj.dest2 = self.phys_obj.origin = self.origin; + self.phys_obj.watertype = 0; + self.phys_obj.movedir = self.origin + real_frametime * self.velocity; + self.phys_obj.dest1 = self.phys_obj.velocity = self.velocity; + self.phys_obj.velocity_z = self.phys_obj.velocity_z + sv_gravity * real_frametime; + self.phys_obj.flags = 0; + self.phys_obj.think = PostPhysics; + self.phys_obj.nextthink = time; +}; + + +void() SV_Physics_Toss = +{ + if (!SV_RunThink()) + return; + if (self.flags & FL_ONGROUND) + { + self.velocity = '0 0 0'; + BotAI(); + return; + } + if (self.movetype != MOVETYPE_FLY) + SV_AddGravity(1); + self.angles = self.angles + real_frametime * self.avelocity; + SV_FlyMove(); + +}; +void() SV_Physics_Client = +{ + + PlayerPreThink(); + + if (self.movetype == MOVETYPE_NONE) + { + if (!SV_RunThink()) + return; + PlayerPostThink(); + BotAI(); + + } + else if ((self.movetype == MOVETYPE_WALK) || (self.movetype == MOVETYPE_STEP)) + { + if (!SV_RunThink()) + return; + if (!(SV_CheckWater()) && (!(self.flags & FL_WATERJUMP))) + SV_AddGravity(1); + SV_FlyMove(); + } + else if ((self.movetype == MOVETYPE_TOSS) || (self.movetype == MOVETYPE_BOUNCE)) + { + SV_Physics_Toss(); + } + else if (self.movetype == MOVETYPE_FLY) + { + if (!SV_RunThink()) + return; + SV_FlyMove(); + } + else if (self.movetype == MOVETYPE_NOCLIP) + { + if (!SV_RunThink()) + return; + self.origin = self.origin + real_frametime * self.velocity; + + PlayerPostThink(); + BotAI(); + } + else + error ("SV_Physics_Client: Bad Movetype (BOT)"); + +}; + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_way.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_way.qc new file mode 100755 index 00000000..70946e74 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikbot/bot_way.qc @@ -0,0 +1,981 @@ + /*********************************************** +* * +* FrikBot Waypoints * +* "The better than roaming AI" * +* * +***********************************************/ + +/* +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. +*/ + + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Linking code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +float (entity e1, entity e2) CheckLinked = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return FALSE; + else if (e1.target1 == e2) + { + if (e1.b_aiflags & AI_TELELINK_1) + return 2; + else return TRUE; + } + else if (e1.target2 == e2) + { + if (e1.b_aiflags & AI_TELELINK_2) + return 2; + else return TRUE; + } + else if (e1.target3 == e2) + { + if (e1.b_aiflags & AI_TELELINK_3) + return 2; + else return TRUE; + } + else if (e1.target4 == e2) + { + if (e1.b_aiflags & AI_TELELINK_4) + return 2; + else return TRUE; + } + + else return FALSE; +}; + + +float (entity e1, entity e2) LinkWays = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return FALSE; + else if (CheckLinked(e1, e2)) + return FALSE; // already linked!!! + + if (e1.target1 == world) + { + e1.target1 = e2; + return TRUE; + } + else if (e1.target2 == world) + { + e1.target2 = e2; + return TRUE; + } + else if (e1.target3 == world) + { + e1.target3 = e2; + return TRUE; + } + else if (e1.target4 == world) + { + e1.target4 = e2; + return TRUE; + } + else return FALSE; + +}; +// Link Ways part 2, used only for teleporters + +float (entity e1, entity e2) TeleLinkWays = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return FALSE; + else if (CheckLinked(e1, e2)) + return FALSE; // already linked!!! + + if (e1.target1 == world) + { + e1.target1 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_1; + return TRUE; + } + else if (e1.target2 == world) + { + e1.target2 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_2; + return TRUE; + } + else if (e1.target3 == world) + { + e1.target3 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_3; + return TRUE; + } + else if (e1.target4 == world) + { + e1.target4 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_4; + return TRUE; + } + else + return FALSE; + +}; + +void (entity e1, entity e2) UnlinkWays = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return; + else if (!CheckLinked(e1, e2)) + return; + + if (e1.target1 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_1); + e1.target1 = world; + } + if (e1.target2 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_2); + e1.target2 = world; + } + if (e1.target3 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_3); + e1.target3 = world; + } + if (e1.target4 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_4); + e1.target4 = world; + } + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +FindWaypoint + +This is used quite a bit, by many different +functions big lag causer + +Finds the closest, fisible, waypoint to e + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +entity(entity start) FindWayPoint = +{ + local entity t; + local vector org; + local float dst, tdst; + local entity best; + + org = realorigin(self); + + t = way_head; + if (start != world) + { + dst = vlen(start.origin - org); + best = start; + } + else + { + dst = 100000; + best = world; + } + while(t) + { + // real players cut through ignore types + if (dst < 20) + return best; + if (!(t.b_aiflags & AI_IGNORE_TYPES) || self.ishuman) + { + tdst = vlen(t.origin - org); + if (tdst < dst) + { + if (sisible(t)) + { + dst = tdst; + best = t; + } + } + } + t = t._next; + } + return best; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Spawning Code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +entity way_foot; // Ugh. Do I need a foot for this or not? + +entity(vector org) make_waypoint = +{ + local entity point; + point = spawn(); + point.classname = "waypoint"; + point.search_time = time; // don't double back for me; + point.solid = SOLID_TRIGGER; + point.movetype = MOVETYPE_NONE; + point.items = -1; + setorigin(point, org); + + setsize(point, VEC_HULL_MIN, VEC_HULL_MAX); + waypoints = waypoints + 1; + if (!way_head) + { + way_head = point; + way_foot = point; + } + else + { + way_foot._next = point; + point._last = way_foot; + way_foot = point; + } + + point.count = waypoints; + if (waypoint_mode > WM_LOADED) // editor modes + setmodel(point, "progs/s_bubble.spr"); + return point; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Dynamic Waypoint spawning and linking. Not +very good all things considered. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() DynamicWaypoint = +{ + local entity t; + local float dist, dynlink, dynpoint, editor; + + if (self.teleport_time > self.portal_time) + { + if (!self.flags & FL_WATERJUMP) + { + self.dyn_flags = 2; + if (!self.ishuman) + { + bot_lost(self.target1, TRUE); + self.enemy = world; + } + } + self.portal_time = self.teleport_time; + } +// stacking everything on waypoint_mode might've been good for the editor, +// but it sucks to beat hell for this code. + + +// convert waypoint_mode to something more usable.. + if (waypoint_mode > WM_LOADED) + { + if (self.ishuman) + { + if (waypoint_mode == WM_EDITOR_DYNLINK) + dynlink = 1; + else if (waypoint_mode == WM_EDITOR_DYNAMIC) + dynlink = dynpoint = 1; + editor = 1; + } + } + else if (waypoint_mode == WM_DYNAMIC) + dynlink = dynpoint = 1; + +// if there's nothing for dynamic to do.. + if (!dynpoint) + { + if (!editor) + return; + } +// for speed sake, I won't have bots dynamic waypoint in coop + if (!self.ishuman) + if (coop) + return; + +// don't waypoint in single player + if (max_clients < 2) + return; +// if you're dead + else if (self.health <= 0) + { + if (dynpoint) + { + if (self.current_way) + { + if (pointcontents(self.origin) < -4) + { + if (self.current_way.b_aiflags & AI_BLIND) + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_PRECISION; + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_BLIND; + } + } + } + self.dyn_dest = '0 0 0'; + self.current_way = world; + self.dyn_flags = 0; + return; + } + +// you shouldn't be making waypoints mid air + if (dynpoint) + { + if (!((self.flags & FL_ONGROUND) || self.waterlevel == 3)) + { + if (self.dyn_flags != 2) + { + self.dyn_flags = 1; + } + return; + } + } +// keep from doing the rest of this every frame + if (self.dyn_time > time) + return; + self.dyn_time = time + 0.2; + +// display the links for editor mode + if (editor) + { + if (self.current_way) + { + if (self.current_way.target1) + DeveloperLightning(self.current_way, self.current_way.target1, self.current_way.b_aiflags & AI_TELELINK_1); + if (self.current_way.target2) + DeveloperLightning(self.current_way, self.current_way.target2, self.current_way.b_aiflags & AI_TELELINK_2); + if (self.current_way.target3) + DeveloperLightning(self.current_way, self.current_way.target3, self.current_way.b_aiflags & AI_TELELINK_3); + if (self.current_way.target4) + DeveloperLightning(self.current_way, self.current_way.target4, self.current_way.b_aiflags & AI_TELELINK_4); + } + if (self.b_aiflags & AI_HOLD_SELECT) + return; + } + + t = FindWayPoint(self.current_way); + if (t) + { + dist = vlen(self.origin - t.origin); + if (dist < 192) + { + if (dist < 64) + { + + if (t != self.current_way) + { + if (dynlink) + { + if (!self.dyn_flags) + { + if (wisible(t, self.current_way)) + LinkWays(t, self.current_way); + } + if (self.dyn_flags == 2) + TeleLinkWays(self.current_way, t); + else if (wisible(t, self.current_way)) + LinkWays(self.current_way, t); + } + if (editor) + { + setmodel(t, "progs/s_light.spr"); + if (self.current_way) + setmodel(self.current_way, "progs/s_bubble.spr"); + } + } + self.current_way = t; + self.dyn_flags = 0; + } + self.dyn_dest = self.origin + self.view_ofs; + return; + } + } + + if (frik_recognize_plat(FALSE)) + { + if (vlen(trace_ent.velocity) > 0) + { + if (self.dyn_plat) + return; + self.dyn_plat = TRUE; + if (!self.dyn_flags) + self.dyn_flags = 1; + //bprint("on a plat!!!!!\n"); + } + else + self.dyn_plat = FALSE; + } + else + self.dyn_plat = FALSE; + + if (self.dyn_flags == 2) + self.dyn_dest = self.origin + self.view_ofs; + else if (self.dyn_dest == '0 0 0') + self.dyn_dest = self.origin + self.view_ofs; + if (!dynpoint) + return; + t = make_waypoint(self.dyn_dest); + + if (!self.dyn_flags) + { + if (wisible(t, self.current_way)) + LinkWays(t, self.current_way); + } + if (self.dyn_flags == 2) + TeleLinkWays(self.current_way, t); + else if (wisible(t, self.current_way)) + LinkWays(self.current_way, t); + + if (editor) + { + setmodel(t, "progs/s_light.spr"); + if (self.current_way) + setmodel(self.current_way, "progs/s_bubble.spr"); + } + self.current_way = t; + self.dyn_flags = 0; + + self.dyn_dest = self.origin + self.view_ofs; + + if (frik_recognize_plat(FALSE)) + { + if (trace_ent.classname == "door") + t.b_aiflags = t.b_aiflags | AI_DOORFLAG; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Loading from file + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClearAllWays = +{ + + local entity t, n; + t = way_head; + while(t) + { + n = t._next; + remove(t); + t = n; + } + way_head = world; + way_foot = world; + waypoints = 0; +}; + +entity(float num) WaypointForNum = +{ + local entity t; + if (!num) + return world; + + t = way_head; + while (t) + { + if (t.count == num) + return t; + t = t._next; + } + return world; +}; + +void() FixThisWaypoint = +{ + self.enemy.target1 = WaypointForNum(self.enemy.b_pants); + self.enemy.target2 = WaypointForNum(self.enemy.b_skill); + self.enemy.target3 = WaypointForNum(self.enemy.b_shirt); + self.enemy.target4 = WaypointForNum(self.enemy.b_frags); + self.enemy = self.enemy._next; + self.nextthink = time; + if (self.enemy == world) + { + remove(self); + fixer = world; + } +}; + +void() FixWaypoints = +{ + if (!fixer) + fixer = spawn(); + fixer.nextthink = time; + fixer.think = FixThisWaypoint; + fixer.enemy = way_head; +}; + + + +void(entity what) delete_waypoint = +{ + local entity t; + + if (way_head == what) + way_head = what._next; + if (way_foot == what) + way_foot = what._last; + if (what._last) + what._last._next = what._next; + if (what._next) + what._next._last = what._last; + waypoints = 0; + t = way_head; + while(t) + { + t.count = waypoints = waypoints + 1; + if (CheckLinked(t, what)) + UnlinkWays(t, what); + t = t._next; + } + if (self.current_way == what) + self.current_way = world; + remove(what); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +FindRoute & FindThing used by the pathing code +in bot_ai.qc + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +entity(string s) FindThing = +{ + local entity t; + local float tdst, dst; + local entity best; + dst = 100000; + best = world; + t = find (world, classname, s); + while (t != world) + { + tdst = vlen(((t.absmin + t.absmax) * 0.5) - self.origin); + if (tdst < dst) + { + dst = tdst; + best = t; + } + t = find(t, classname, s); + } + return best; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +FindRoute, this is a key function in the +pathing. The name is a bit misleading, this +code finds the closest waypoint that is part +of a route calculated by the begin_route and +end_route routines This is a definite path to +an object. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +entity(entity lastone) FindRoute = +{ + // kinda like FindWaypoint, only of this bots route though + local entity t, best; + local float dst, tdst, flag; + flag = ClientBitFlag(self.b_clientno); + t = way_head; + dst = 100000; + best = world; + while(t) + { + tdst = vlen(t.origin - self.origin); + if ((tdst < dst) && (t.b_sound & flag)) + { + if ((lastone == world) || (CheckLinked(lastone, t))) + { + dst = tdst; + best = t; + } + } + t = t._next; + } + return best; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Route & path table management + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClearRouteTable = +{ + // cleans up route table + + local entity t; + t = way_head; + while (t) + { + t. keys = FALSE; + t.enemy = world; + t.items = -1; // not in table + t = t._next; + } +}; + +void() ClearMyRoute = +{ + local float flag; + local entity t; + + flag = ClientBitFlag(self.b_clientno); + + t = way_head; + while (t) + { + t.b_sound = t.b_sound - (t.b_sound & flag); + t = t._next; + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Mark_path + +After the route has been found, mark it with +bitflags so the table can be used for a +different bot. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void(entity this) mark_path = +{ + local entity t, oself; + local float flag; + + ClearMyRoute(); + + oself = self; + self = this; + t = FindWayPoint(this.current_way); + self = oself; + // FIXME + // ugh, better way to find players please!!! + if (this.classname != "player") + this.current_way = t; + + if (t.enemy == world) + { + bot_lost(this, FALSE); + if (waypoint_mode == WM_DYNAMIC) + self.route_failed = TRUE; + return; + } + + flag = ClientBitFlag(self.b_clientno); + + while(t) + { + if (t.b_sound & flag) + return; + if (t == self.last_way) + return; + t.b_sound = t.b_sound | flag; + t = t.enemy; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +WaypointThink + +Calculates the routes. We use thinks to avoid +tripping the runaway loop counter + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity e2, float b_bit) FollowLink = +{ + local float dist; + + if (self.b_aiflags & b_bit) + dist = self.items; + else + dist = vlen(self.origin - e2.origin) + self.items; + + // check if this is an RJ link + if (e2.b_aiflags & AI_SUPER_JUMP) + { + if (!bot_can_rj(route_table)) + return; + } + if (e2.b_aiflags & AI_DIFFICULT) + dist = dist + 1000; + + dist = dist + random() * 100; // add a little chaos + + if ((dist < e2.items) || (e2.items == -1)) + { + if (!e2.keys) + busy_waypoints = busy_waypoints + 1; + e2.keys = TRUE; + e2.items = dist; + e2.think = WaypointThink; + e2.nextthink = time; + e2.enemy = self; + } +}; + +void() WaypointThink = +{ + local entity oself; + + if (self.items == -1) + return; + // can you say ugly? + if (self.b_aiflags & AI_TRACE_TEST) + { + if (self.target1) + { + traceline(self.origin, self.target1.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target1, AI_TELELINK_1); + } + if (self.target2) + { + traceline(self.origin, self.target2.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target2, AI_TELELINK_2); + } + if (self.target3) + { + traceline(self.origin, self.target3.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target3, AI_TELELINK_3); + } + if (self.target4) + { + traceline(self.origin, self.target4.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target4, AI_TELELINK_4); + } + } + else + { + if (self.target1) + FollowLink(self.target1, AI_TELELINK_1); + if (self.target2) + FollowLink(self.target2, AI_TELELINK_2); + if (self.target3) + FollowLink(self.target3, AI_TELELINK_3); + if (self.target4) + FollowLink(self.target4, AI_TELELINK_4); + } + + busy_waypoints = busy_waypoints - 1; + self.keys = FALSE; + + if (busy_waypoints <= 0) + { + if (direct_route) + { + oself = self; + self = route_table; + bot_get_path(self.target1, FALSE); + self = oself; + direct_route = FALSE; + } + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +begin_route and bot_get_path + +PLEASE NOTE: bot_get_path replaces the old +calls to begin_route. + +Routing isn't done all at once now, but in two +stages, the bot will calc a route *THEN* +choose a target, *THEN* mark a path. + +Boy it's confusing. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float() begin_route = +{ + if (busy_waypoints > 0) + return FALSE; + + if (route_table != world) + { + if (!route_table.ishuman) + { + if (route_table.b_clientno != -1) + return FALSE; + } + } + + route_table = self; + ClearRouteTable(); + self.last_way = FindWayPoint(self.current_way); + + if (self.last_way != world) + { + self.last_way.items = vlen(self.last_way.origin - self.origin); + self.last_way.nextthink = time; + self.last_way.think = WaypointThink; + self.last_way.keys = TRUE; + busy_waypoints = 1; + return TRUE; + } + else + { + route_table = world; + busy_waypoints = 0; + return FALSE; + } +}; + +void(entity this, float direct) bot_get_path = +{ + if (this == world) + return; + + if (route_table == self) + { + if (busy_waypoints <= 0) + { + route_table = world; + mark_path(this); + } + return; + } + if (direct) + { + if(begin_route()) + direct_route = TRUE; + else + bot_lost(this, FALSE); + return; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BSP/QC Waypoint loading + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() waypoint = +{ + self.search_time = time; + self.solid = SOLID_TRIGGER; + self.movetype = MOVETYPE_NONE; + setorigin(self, self.origin); + + setsize(self, VEC_HULL_MIN, VEC_HULL_MAX); + waypoints = waypoints + 1; + if (!way_head) + { + way_head = self; + way_foot = self; + } + else + { + way_foot._next = self; + self._last = way_foot; + way_foot = self; + } + + self.count = waypoints; + waypoint_mode = WM_LOADED; + if (self.count == 1) + { + self.think = FixWaypoints; // wait until all bsp loaded points are spawned + self.nextthink = time; + } +}; + +void(vector org, vector bit1, float bit4, float flargs) make_way = +{ + local entity y; + waypoint_mode = WM_LOADED; + y = make_waypoint(org); + y.b_aiflags = flargs; + y.b_pants = bit1_x; + y.b_skill = bit1_y; + y.b_shirt = bit1_z; + y.b_frags = bit4; + if (y.count == 1) + { + y.think = FixWaypoints; // wait until all qc loaded points are spawned + y.nextthink = time; + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Temporary Marker code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(vector org) SpawnTempWaypoint = +{ + local entity tep; + + if (!self.temp_way) + self.temp_way = tep = spawn(); + else + tep = self.temp_way; + + tep.classname = "temp_waypoint"; + tep.search_time = 0; + tep.solid = SOLID_TRIGGER; + tep.movetype = MOVETYPE_NOCLIP; + setorigin(tep, org); + target_add(tep); + setsize(tep, VEC_HULL_MIN, VEC_HULL_MAX); // FIXME: convert these to numerical +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikqcc.exe b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikqcc.exe new file mode 100755 index 00000000..fd9f6b95 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/frikqcc.exe differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/fteqccgui.exe b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/fteqccgui.exe new file mode 100755 index 00000000..03ae0933 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/fteqccgui.exe differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/hknight.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/hknight.qc new file mode 100755 index 00000000..0e239e08 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/hknight.qc @@ -0,0 +1,440 @@ +/* +============================================================================== + +KNIGHT + +============================================================================== +*/ + +$cd id1/models/knight2 +$origin 0 0 24 +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 +$frame walk10 walk11 walk12 walk13 walk14 walk15 walk16 walk17 +$frame walk18 walk19 walk20 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 death11 death12 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 + +$frame char_a1 char_a2 char_a3 char_a4 char_a5 char_a6 char_a7 char_a8 +$frame char_a9 char_a10 char_a11 char_a12 char_a13 char_a14 char_a15 char_a16 + +$frame magica1 magica2 magica3 magica4 magica5 magica6 magica7 magica8 +$frame magica9 magica10 magica11 magica12 magica13 magica14 + +$frame magicb1 magicb2 magicb3 magicb4 magicb5 magicb6 magicb7 magicb8 +$frame magicb9 magicb10 magicb11 magicb12 magicb13 + +$frame char_b1 char_b2 char_b3 char_b4 char_b5 char_b6 + +$frame slice1 slice2 slice3 slice4 slice5 slice6 slice7 slice8 slice9 slice10 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 smash8 smash9 smash10 +$frame smash11 + +$frame w_attack1 w_attack2 w_attack3 w_attack4 w_attack5 w_attack6 w_attack7 +$frame w_attack8 w_attack9 w_attack10 w_attack11 w_attack12 w_attack13 w_attack14 +$frame w_attack15 w_attack16 w_attack17 w_attack18 w_attack19 w_attack20 +$frame w_attack21 w_attack22 + +$frame magicc1 magicc2 magicc3 magicc4 magicc5 magicc6 magicc7 magicc8 +$frame magicc9 magicc10 magicc11 + + +void() hknight_char_a1; +void() hknight_run1; +void() hk_idle_sound; + +void(float offset) hknight_shot = +{ + local vector offang; + local vector org, vec; + + offang = vectoangles (self.enemy.origin - self.origin); + offang_y = offang_y + offset * 6; + + makevectors (offang); + + org = self.origin + self.mins + self.size*0.5 + v_forward * 20; + +// set missile speed + vec = normalize (v_forward); + vec_z = 0 - vec_z + (random() - 0.5)*0.1; + + launch_spike (org, vec); + newmis.classname = "knightspike"; + setmodel (newmis, "progs/k_spike.mdl"); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + newmis.velocity = vec*300; + sound (self, CHAN_WEAPON, "hknight/attack1.wav", 1, ATTN_NORM); +}; + +void() CheckForCharge = +{ +// check for mad charge +if (!enemy_vis) + return; +if (time < self.attack_finished) + return; +if ( fabs(self.origin_z - self.enemy.origin_z) > 20) + return; // too much height change +if ( vlen (self.origin - self.enemy.origin) < 80) + return; // use regular attack + +// charge + SUB_AttackFinished (2); + hknight_char_a1 (); + +}; + +void() CheckContinueCharge = +{ + if (time > self.attack_finished) + { + SUB_AttackFinished (3); + hknight_run1 (); + return; // done charging + } + if (random() > 0.5) + sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM); + else + sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +}; + +//=========================================================================== + +void() hknight_stand1 =[ $stand1, hknight_stand2 ] {ai_stand();}; +void() hknight_stand2 =[ $stand2, hknight_stand3 ] {ai_stand();}; +void() hknight_stand3 =[ $stand3, hknight_stand4 ] {ai_stand();}; +void() hknight_stand4 =[ $stand4, hknight_stand5 ] {ai_stand();}; +void() hknight_stand5 =[ $stand5, hknight_stand6 ] {ai_stand();}; +void() hknight_stand6 =[ $stand6, hknight_stand7 ] {ai_stand();}; +void() hknight_stand7 =[ $stand7, hknight_stand8 ] {ai_stand();}; +void() hknight_stand8 =[ $stand8, hknight_stand9 ] {ai_stand();}; +void() hknight_stand9 =[ $stand9, hknight_stand1 ] {ai_stand();}; + +//=========================================================================== + +void() hknight_walk1 =[ $walk1, hknight_walk2 ] { +hk_idle_sound(); +ai_walk(2);}; +void() hknight_walk2 =[ $walk2, hknight_walk3 ] {ai_walk(5);}; +void() hknight_walk3 =[ $walk3, hknight_walk4 ] {ai_walk(5);}; +void() hknight_walk4 =[ $walk4, hknight_walk5 ] {ai_walk(4);}; +void() hknight_walk5 =[ $walk5, hknight_walk6 ] {ai_walk(4);}; +void() hknight_walk6 =[ $walk6, hknight_walk7 ] {ai_walk(2);}; +void() hknight_walk7 =[ $walk7, hknight_walk8 ] {ai_walk(2);}; +void() hknight_walk8 =[ $walk8, hknight_walk9 ] {ai_walk(3);}; +void() hknight_walk9 =[ $walk9, hknight_walk10 ] {ai_walk(3);}; +void() hknight_walk10 =[ $walk10, hknight_walk11 ] {ai_walk(4);}; +void() hknight_walk11 =[ $walk11, hknight_walk12 ] {ai_walk(3);}; +void() hknight_walk12 =[ $walk12, hknight_walk13 ] {ai_walk(4);}; +void() hknight_walk13 =[ $walk13, hknight_walk14 ] {ai_walk(6);}; +void() hknight_walk14 =[ $walk14, hknight_walk15 ] {ai_walk(2);}; +void() hknight_walk15 =[ $walk15, hknight_walk16 ] {ai_walk(2);}; +void() hknight_walk16 =[ $walk16, hknight_walk17 ] {ai_walk(4);}; +void() hknight_walk17 =[ $walk17, hknight_walk18 ] {ai_walk(3);}; +void() hknight_walk18 =[ $walk18, hknight_walk19 ] {ai_walk(3);}; +void() hknight_walk19 =[ $walk19, hknight_walk20 ] {ai_walk(3);}; +void() hknight_walk20 =[ $walk20, hknight_walk1 ] {ai_walk(2);}; + +//=========================================================================== + +void() hknight_run1 =[ $run1, hknight_run2 ] { +hk_idle_sound(); +ai_run (20); CheckForCharge (); }; +void() hknight_run2 =[ $run2, hknight_run3 ] {ai_run(25);}; +void() hknight_run3 =[ $run3, hknight_run4 ] {ai_run(18);}; +void() hknight_run4 =[ $run4, hknight_run5 ] {ai_run(16);}; +void() hknight_run5 =[ $run5, hknight_run6 ] {ai_run(14);}; +void() hknight_run6 =[ $run6, hknight_run7 ] {ai_run(25);}; +void() hknight_run7 =[ $run7, hknight_run8 ] {ai_run(21);}; +void() hknight_run8 =[ $run8, hknight_run1 ] {ai_run(13);}; + +//============================================================================ + +void() hknight_pain1 =[ $pain1, hknight_pain2 ] {sound (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);}; +void() hknight_pain2 =[ $pain2, hknight_pain3 ] {}; +void() hknight_pain3 =[ $pain3, hknight_pain4 ] {}; +void() hknight_pain4 =[ $pain4, hknight_pain5 ] {}; +void() hknight_pain5 =[ $pain5, hknight_run1 ] {}; + +//============================================================================ + +void() hknight_die1 =[ $death1, hknight_die2 ] {ai_forward(10);}; +void() hknight_die2 =[ $death2, hknight_die3 ] {ai_forward(8);}; +void() hknight_die3 =[ $death3, hknight_die4 ] +{self.solid = SOLID_NOT; ai_forward(7);}; +void() hknight_die4 =[ $death4, hknight_die5 ] {}; +void() hknight_die5 =[ $death5, hknight_die6 ] {}; +void() hknight_die6 =[ $death6, hknight_die7 ] {}; +void() hknight_die7 =[ $death7, hknight_die8 ] {}; +void() hknight_die8 =[ $death8, hknight_die9 ] {ai_forward(10);}; +void() hknight_die9 =[ $death9, hknight_die10 ] {ai_forward(11);}; +void() hknight_die10 =[ $death10, hknight_die11 ] {}; +void() hknight_die11 =[ $death11, hknight_die12 ] {}; +void() hknight_die12 =[ $death12, hknight_die12 ] {}; + +void() hknight_dieb1 =[ $deathb1, hknight_dieb2 ] {}; +void() hknight_dieb2 =[ $deathb2, hknight_dieb3 ] {}; +void() hknight_dieb3 =[ $deathb3, hknight_dieb4 ] +{self.solid = SOLID_NOT;}; +void() hknight_dieb4 =[ $deathb4, hknight_dieb5 ] {}; +void() hknight_dieb5 =[ $deathb5, hknight_dieb6 ] {}; +void() hknight_dieb6 =[ $deathb6, hknight_dieb7 ] {}; +void() hknight_dieb7 =[ $deathb7, hknight_dieb8 ] {}; +void() hknight_dieb8 =[ $deathb8, hknight_dieb9 ] {}; +void() hknight_dieb9 =[ $deathb9, hknight_dieb9 ] {}; + +void() hknight_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_hellkn.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "hknight/death1.wav", 1, ATTN_NORM); + if (random() > 0.5) + hknight_die1 (); + else + hknight_dieb1 (); +}; + + +//============================================================================ + +void() hknight_magica1 =[ $magica1, hknight_magica2 ] {ai_face();}; +void() hknight_magica2 =[ $magica2, hknight_magica3 ] {ai_face();}; +void() hknight_magica3 =[ $magica3, hknight_magica4 ] {ai_face();}; +void() hknight_magica4 =[ $magica4, hknight_magica5 ] {ai_face();}; +void() hknight_magica5 =[ $magica5, hknight_magica6 ] {ai_face();}; +void() hknight_magica6 =[ $magica6, hknight_magica7 ] {ai_face();}; +void() hknight_magica7 =[ $magica7, hknight_magica8 ] {hknight_shot(-2);}; +void() hknight_magica8 =[ $magica8, hknight_magica9 ] {hknight_shot(-1);}; +void() hknight_magica9 =[ $magica9, hknight_magica10] {hknight_shot(0);}; +void() hknight_magica10 =[ $magica10, hknight_magica11] {hknight_shot(1);}; +void() hknight_magica11 =[ $magica11, hknight_magica12] {hknight_shot(2);}; +void() hknight_magica12 =[ $magica12, hknight_magica13] {hknight_shot(3);}; +void() hknight_magica13 =[ $magica13, hknight_magica14] {ai_face();}; +void() hknight_magica14 =[ $magica14, hknight_run1 ] {ai_face();}; + +//============================================================================ + +void() hknight_magicb1 =[ $magicb1, hknight_magicb2 ] {ai_face();}; +void() hknight_magicb2 =[ $magicb2, hknight_magicb3 ] {ai_face();}; +void() hknight_magicb3 =[ $magicb3, hknight_magicb4 ] {ai_face();}; +void() hknight_magicb4 =[ $magicb4, hknight_magicb5 ] {ai_face();}; +void() hknight_magicb5 =[ $magicb5, hknight_magicb6 ] {ai_face();}; +void() hknight_magicb6 =[ $magicb6, hknight_magicb7 ] {ai_face();}; +void() hknight_magicb7 =[ $magicb7, hknight_magicb8 ] {hknight_shot(-2);}; +void() hknight_magicb8 =[ $magicb8, hknight_magicb9 ] {hknight_shot(-1);}; +void() hknight_magicb9 =[ $magicb9, hknight_magicb10] {hknight_shot(0);}; +void() hknight_magicb10 =[ $magicb10, hknight_magicb11] {hknight_shot(1);}; +void() hknight_magicb11 =[ $magicb11, hknight_magicb12] {hknight_shot(2);}; +void() hknight_magicb12 =[ $magicb12, hknight_magicb13] {hknight_shot(3);}; +void() hknight_magicb13 =[ $magicb13, hknight_run1] {ai_face();}; + +//============================================================================ + +void() hknight_magicc1 =[ $magicc1, hknight_magicc2 ] {ai_face();}; +void() hknight_magicc2 =[ $magicc2, hknight_magicc3 ] {ai_face();}; +void() hknight_magicc3 =[ $magicc3, hknight_magicc4 ] {ai_face();}; +void() hknight_magicc4 =[ $magicc4, hknight_magicc5 ] {ai_face();}; +void() hknight_magicc5 =[ $magicc5, hknight_magicc6 ] {ai_face();}; +void() hknight_magicc6 =[ $magicc6, hknight_magicc7 ] {hknight_shot(-2);}; +void() hknight_magicc7 =[ $magicc7, hknight_magicc8 ] {hknight_shot(-1);}; +void() hknight_magicc8 =[ $magicc8, hknight_magicc9 ] {hknight_shot(0);}; +void() hknight_magicc9 =[ $magicc9, hknight_magicc10] {hknight_shot(1);}; +void() hknight_magicc10 =[ $magicc10, hknight_magicc11] {hknight_shot(2);}; +void() hknight_magicc11 =[ $magicc11, hknight_run1] {hknight_shot(3);}; + +//=========================================================================== + +void() hknight_char_a1 =[ $char_a1, hknight_char_a2 ] {ai_charge(20);}; +void() hknight_char_a2 =[ $char_a2, hknight_char_a3 ] {ai_charge(25);}; +void() hknight_char_a3 =[ $char_a3, hknight_char_a4 ] {ai_charge(18);}; +void() hknight_char_a4 =[ $char_a4, hknight_char_a5 ] {ai_charge(16);}; +void() hknight_char_a5 =[ $char_a5, hknight_char_a6 ] {ai_charge(14);}; +void() hknight_char_a6 =[ $char_a6, hknight_char_a7 ] {ai_charge(20); ai_melee();}; +void() hknight_char_a7 =[ $char_a7, hknight_char_a8 ] {ai_charge(21); ai_melee();}; +void() hknight_char_a8 =[ $char_a8, hknight_char_a9 ] {ai_charge(13); ai_melee();}; +void() hknight_char_a9 =[ $char_a9, hknight_char_a10 ] {ai_charge(20); ai_melee();}; +void() hknight_char_a10=[ $char_a10, hknight_char_a11 ] {ai_charge(20); ai_melee();}; +void() hknight_char_a11=[ $char_a11, hknight_char_a12 ] {ai_charge(18); ai_melee();}; +void() hknight_char_a12=[ $char_a12, hknight_char_a13 ] {ai_charge(16);}; +void() hknight_char_a13=[ $char_a13, hknight_char_a14 ] {ai_charge(14);}; +void() hknight_char_a14=[ $char_a14, hknight_char_a15 ] {ai_charge(25);}; +void() hknight_char_a15=[ $char_a15, hknight_char_a16 ] {ai_charge(21);}; +void() hknight_char_a16=[ $char_a16, hknight_run1 ] {ai_charge(13);}; + +//=========================================================================== + +void() hknight_char_b1 =[ $char_b1, hknight_char_b2 ] +{CheckContinueCharge (); ai_charge(23); ai_melee();}; +void() hknight_char_b2 =[ $char_b2, hknight_char_b3 ] {ai_charge(17); ai_melee();}; +void() hknight_char_b3 =[ $char_b3, hknight_char_b4 ] {ai_charge(12); ai_melee();}; +void() hknight_char_b4 =[ $char_b4, hknight_char_b5 ] {ai_charge(22); ai_melee();}; +void() hknight_char_b5 =[ $char_b5, hknight_char_b6 ] {ai_charge(18); ai_melee();}; +void() hknight_char_b6 =[ $char_b6, hknight_char_b1 ] {ai_charge(8); ai_melee();}; + +//=========================================================================== + +void() hknight_slice1 =[ $slice1, hknight_slice2 ] {ai_charge(9);}; +void() hknight_slice2 =[ $slice2, hknight_slice3 ] {ai_charge(6);}; +void() hknight_slice3 =[ $slice3, hknight_slice4 ] {ai_charge(13);}; +void() hknight_slice4 =[ $slice4, hknight_slice5 ] {ai_charge(4);}; +void() hknight_slice5 =[ $slice5, hknight_slice6 ] {ai_charge(7); ai_melee();}; +void() hknight_slice6 =[ $slice6, hknight_slice7 ] {ai_charge(15); ai_melee();}; +void() hknight_slice7 =[ $slice7, hknight_slice8 ] {ai_charge(8); ai_melee();}; +void() hknight_slice8 =[ $slice8, hknight_slice9 ] {ai_charge(2); ai_melee();}; +void() hknight_slice9 =[ $slice9, hknight_slice10 ] {ai_melee();}; +void() hknight_slice10 =[ $slice10, hknight_run1 ] {ai_charge(3);}; + +//=========================================================================== + +void() hknight_smash1 =[ $smash1, hknight_smash2 ] {ai_charge(1);}; +void() hknight_smash2 =[ $smash2, hknight_smash3 ] {ai_charge(13);}; +void() hknight_smash3 =[ $smash3, hknight_smash4 ] {ai_charge(9);}; +void() hknight_smash4 =[ $smash4, hknight_smash5 ] {ai_charge(11);}; +void() hknight_smash5 =[ $smash5, hknight_smash6 ] {ai_charge(10); ai_melee();}; +void() hknight_smash6 =[ $smash6, hknight_smash7 ] {ai_charge(7); ai_melee();}; +void() hknight_smash7 =[ $smash7, hknight_smash8 ] {ai_charge(12); ai_melee();}; +void() hknight_smash8 =[ $smash8, hknight_smash9 ] {ai_charge(2); ai_melee();}; +void() hknight_smash9 =[ $smash9, hknight_smash10 ] {ai_charge(3); ai_melee();}; +void() hknight_smash10 =[ $smash10, hknight_smash11 ] {ai_charge(0);}; +void() hknight_smash11 =[ $smash11, hknight_run1 ] {ai_charge(0);}; + +//============================================================================ + +void() hknight_watk1 =[ $w_attack1, hknight_watk2 ] {ai_charge(2);}; +void() hknight_watk2 =[ $w_attack2, hknight_watk3 ] {ai_charge(0);}; +void() hknight_watk3 =[ $w_attack3, hknight_watk4 ] {ai_charge(0);}; +void() hknight_watk4 =[ $w_attack4, hknight_watk5 ] {ai_melee();}; +void() hknight_watk5 =[ $w_attack5, hknight_watk6 ] {ai_melee();}; +void() hknight_watk6 =[ $w_attack6, hknight_watk7 ] {ai_melee();}; +void() hknight_watk7 =[ $w_attack7, hknight_watk8 ] {ai_charge(1);}; +void() hknight_watk8 =[ $w_attack8, hknight_watk9 ] {ai_charge(4);}; +void() hknight_watk9 =[ $w_attack9, hknight_watk10 ] {ai_charge(5);}; +void() hknight_watk10 =[ $w_attack10, hknight_watk11 ] {ai_charge(3); ai_melee();}; +void() hknight_watk11 =[ $w_attack11, hknight_watk12 ] {ai_charge(2); ai_melee();}; +void() hknight_watk12 =[ $w_attack12, hknight_watk13 ] {ai_charge(2); ai_melee();}; +void() hknight_watk13 =[ $w_attack13, hknight_watk14 ] {ai_charge(0);}; +void() hknight_watk14 =[ $w_attack14, hknight_watk15 ] {ai_charge(0);}; +void() hknight_watk15 =[ $w_attack15, hknight_watk16 ] {ai_charge(0);}; +void() hknight_watk16 =[ $w_attack16, hknight_watk17 ] {ai_charge(1);}; +void() hknight_watk17 =[ $w_attack17, hknight_watk18 ] {ai_charge(1); ai_melee();}; +void() hknight_watk18 =[ $w_attack18, hknight_watk19 ] {ai_charge(3); ai_melee();}; +void() hknight_watk19 =[ $w_attack19, hknight_watk20 ] {ai_charge(4); ai_melee();}; +void() hknight_watk20 =[ $w_attack20, hknight_watk21 ] {ai_charge(6);}; +void() hknight_watk21 =[ $w_attack21, hknight_watk22 ] {ai_charge(7);}; +void() hknight_watk22 =[ $w_attack22, hknight_run1 ] {ai_charge(3);}; + +//============================================================================ + +void() hk_idle_sound = +{ + if (random() < 0.2) + sound (self, CHAN_VOICE, "hknight/idle.wav", 1, ATTN_NORM); +}; + +void(entity attacker, float damage) hknight_pain = +{ + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM); + + if (time - self.pain_finished > 5) + { // allways go into pain frame if it has been a while + hknight_pain1 (); + self.pain_finished = time + 1; + return; + } + + if ((random()*30 > damage) ) + return; // didn't flinch + + self.pain_finished = time + 1; + hknight_pain1 (); +}; + +float hknight_type; + +void() hknight_melee = +{ + hknight_type = hknight_type + 1; + + sound (self, CHAN_WEAPON, "hknight/slash1.wav", 1, ATTN_NORM); + if (hknight_type == 1) + hknight_slice1 (); + else if (hknight_type == 2) + hknight_smash1 (); + else if (hknight_type == 3) + { + hknight_watk1 (); + hknight_type = 0; + } +}; + +/*QUAKED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_hell_knight = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/hknight.mdl"); + precache_model2 ("progs/k_spike.mdl"); + precache_model2 ("progs/h_hellkn.mdl"); + + + precache_sound2 ("hknight/attack1.wav"); + precache_sound2 ("hknight/death1.wav"); + precache_sound2 ("hknight/pain1.wav"); + precache_sound2 ("hknight/sight1.wav"); + precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2 + precache_sound2 ("hknight/slash1.wav"); + precache_sound2 ("hknight/idle.wav"); + precache_sound2 ("hknight/grunt.wav"); + + precache_sound ("knight/sword1.wav"); + precache_sound ("knight/sword2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/hknight.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 250; + + self.th_stand = hknight_stand1; + self.th_walk = hknight_walk1; + self.th_run = hknight_run1; + self.th_melee = hknight_melee; + self.th_missile = hknight_magicc1; + self.th_pain = hknight_pain; + self.th_die = hknight_die; + + walkmonster_start (); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/items.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/items.qc new file mode 100755 index 00000000..62ad2a40 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/items.qc @@ -0,0 +1,1726 @@ +void() W_SetCurrentAmmo; +/* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD +BE .8 .3 .4 IN COLOR */ + +void() SUB_regen = +{ + self.model = self.mdl; // restore original model + self.solid = SOLID_TRIGGER; // allow it to be touched again + sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM); // play respawn sound + setorigin (self, self.origin); +}; + + + +/*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8) +prints a warning message when spawned +*/ +void() noclass = +{ + dprint ("noclass spawned at"); + dprint (vtos(self.origin)); + dprint ("\n"); + remove (self); +}; + + + +/* +============ +PlaceItem + +plants the object on the floor +============ +*/ +void() PlaceItem = +{ + self.mdl = self.model; + self.flags = FL_ITEM; + self.solid = SOLID_TRIGGER; + self.movetype = MOVETYPE_NONE; + self.velocity = '0 0 0'; + if (self.classname == "etank") + setorigin(self, self.origin); //The metroid Float + else + setorigin(self, self.origin + '0 0 40'); +}; + +/* +============ +StartItem + +Sets the clipping size and plants the object on the floor +============ +*/ +void() StartItem = +{ + self.nextthink = time + 0.2; // items start after other solids + self.think = PlaceItem; +}; + +/* +========================================================================= + +HEALTH BOX + +========================================================================= +*/ +// +// T_Heal: add health to an entity, limiting health to max_health +// "ignore" will ignore max_health limit +// +float (entity e, float healamount, float ignore) T_Heal = +{ + if (e.health <= 0) + return 0; + if ((!ignore) && (e.health >= other.max_health)) + return 0; + healamount = ceil(healamount); + + e.health = e.health + healamount; + if ((!ignore) && (e.health >= other.max_health)) + e.health = other.max_health; + + return 1; +}; + +/*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth +Health box. Normally gives 25 points. +Rotten box heals 5-10 points, +megahealth will add 100 health, then +rot you down to your maximum health limit, +one point per second. +*/ + +float H_ROTTEN = 1; +float H_MEGA = 2; +.float healamount, healtype; +void() health_touch; +void() item_megahealth_rot; + +void() item_health = +{ + self.touch = health_touch; + + if (self.spawnflags & H_ROTTEN) + { + precache_model("maps/b_bh10.bsp"); + + precache_sound("items/r_item1.wav"); + setmodel(self, "maps/b_bh10.bsp"); + self.noise = "items/r_item1.wav"; + self.healamount = 15; + self.healtype = 0; + } + else + if (self.spawnflags & H_MEGA) + { + precache_model("maps/b_bh100.bsp"); + precache_sound("items/r_item2.wav"); + setmodel(self, "maps/b_bh100.bsp"); + self.noise = "items/r_item2.wav"; + self.healamount = 100; + self.healtype = 2; + } + else + { + precache_model("maps/b_bh25.bsp"); + precache_sound("items/health1.wav"); + setmodel(self, "maps/b_bh25.bsp"); + self.noise = "items/health1.wav"; + self.healamount = 25; + self.healtype = 1; + } + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; +//Prime Health 1 +void() item_health1 = +{ + precache_model("progs/health3.spr"); + precache_sound("items/r_item1.wav"); + setmodel(self, "progs/health3.spr"); + self.noise = "items/r_item1.wav"; + self.classname = "health1"; + self.touch = health_touch; + self.healtype = 0; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; +//Prime health2 +void() item_health2 = +{ + precache_model("progs/health.spr"); + precache_sound("items/r_item1.wav"); + setmodel(self, "progs/health.spr"); + self.noise = "items/r_item1.wav"; + self.classname = "health2"; + self.touch = health_touch; + self.healtype = 0; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; +//Prime health3 +void() item_health3 = +{ + precache_model("progs/health2.spr"); + precache_sound("items/r_item1.wav"); + setmodel(self, "progs/health2.spr"); + self.noise = "items/r_item1.wav"; + self.classname = "health3"; + self.touch = health_touch; + self.healtype = 0; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; +void() health_touch = +{ + local string s; + + if (other.classname != "player") + return; + + if (self.classname == "health1") //Oh my... So much globbered code Just for Health... +{ + if (other.energy == 0) + { + if (other.health >= 99) + return; + other.health = other.health + 20; + if (other.health >= 99) + other.health = 99; + } + if (other.energy == 1) + { + if (other.health >= 199) + return; + other.health = other.health + 20; + if (other.health >= 199) + other.health = 199; + } + if (other.energy == 2) + { + if (other.health >= 299) + return; + other.health = other.health + 20; + if (other.health >= 299) + other.health = 299; + } + if (other.energy == 3) + { + if (other.health >= 399) + return; + other.health = other.health + 20; + if (other.health >= 399) + other.health = 399; + } + if (other.energy == 4) + { + if (other.health >= 499) + return; + other.health = other.health + 20; + if (other.health >= 499) + other.health = 499; + } + if (other.energy == 5) + { + if (other.health >= 599) + return; + other.health = other.health + 20; + if (other.health >= 599) + other.health = 599; + } + if (other.energy == 6) + { + if (other.health >= 699) + return; + other.health = other.health + 20; + if (other.health >= 699) + other.health = 699; + } + if (other.energy == 7) + { + if (other.health >= 799) + return; + other.health = other.health + 20; + if (other.health >= 799) + other.health = 799; + } + if (other.energy == 8) + { + if (other.health >= 899) + return; + other.health = other.health + 20; + if (other.health >= 899) + other.health = 899; + } + if (other.energy == 9) + { + if (other.health >= 999) + return; + other.health = other.health + 20; + if (other.health >= 999) + other.health = 999; + } +} + + if (self.classname == "health2") +{ + if (other.energy == 0) + { + if (other.health >= 99) + return; + other.health = other.health + 50; + if (other.health >= 99) + other.health = 99; + } + if (other.energy == 1) + { + if (other.health >= 199) + return; + other.health = other.health + 50; + if (other.health >= 199) + other.health = 199; + } + if (other.energy == 2) + { + if (other.health >= 299) + return; + other.health = other.health + 50; + if (other.health >= 299) + other.health = 299; + } + if (other.energy == 3) + { + if (other.health >= 399) + return; + other.health = other.health + 50; + if (other.health >= 399) + other.health = 399; + } + if (other.energy == 4) + { + if (other.health >= 499) + return; + other.health = other.health + 50; + if (other.health >= 499) + other.health = 499; + } + if (other.energy == 5) + { + if (other.health >= 599) + return; + other.health = other.health + 50; + if (other.health >= 599) + other.health = 599; + } + if (other.energy == 6) + { + if (other.health >= 699) + return; + other.health = other.health + 50; + if (other.health >= 699) + other.health = 699; + } + if (other.energy == 7) + { + if (other.health >= 799) + return; + other.health = other.health + 50; + if (other.health >= 799) + other.health = 799; + } + if (other.energy == 8) + { + if (other.health >= 899) + return; + other.health = other.health + 50; + if (other.health >= 899) + other.health = 899; + } + if (other.energy == 9) + { + if (other.health >= 999) + return; + other.health = other.health + 50; + if (other.health >= 999) + other.health = 999; + } +} + + else +{ + if (other.energy == 0) + { + if (other.health >= 99) + return; + other.health = other.health + 100; + if (other.health >= 99) + other.health = 99; + } + if (other.energy == 1) + { + if (other.health >= 199) + return; + other.health = other.health + 100; + if (other.health >= 199) + other.health = 199; + } + if (other.energy == 2) + { + if (other.health >= 299) + return; + other.health = other.health + 100; + if (other.health >= 299) + other.health = 299; + } + if (other.energy == 3) + { + if (other.health >= 399) + return; + other.health = other.health + 100; + if (other.health >= 399) + other.health = 399; + } + if (other.energy == 4) + { + if (other.health >= 499) + return; + other.health = other.health + 100; + if (other.health >= 499) + other.health = 499; + } + if (other.energy == 5) + { + if (other.health >= 599) + return; + other.health = other.health + 100; + if (other.health >= 599) + other.health = 599; + } + if (other.energy == 6) + { + if (other.health >= 699) + return; + other.health = other.health + 100; + if (other.health >= 699) + other.health = 699; + } + if (other.energy == 7) + { + if (other.health >= 799) + return; + other.health = other.health + 100; + if (other.health >= 799) + other.health = 799; + } + if (other.energy == 8) + { + if (other.health >= 899) + return; + other.health = other.health + 100; + if (other.health >= 899) + other.health = 899; + } + if (other.energy == 9) + { + if (other.health >= 999) + return; + other.health = other.health + 100; + if (other.health >= 999) + other.health = 999; + } +} + + sprint(other, "You receive "); + s = ftos(other.health); + sprint(other, s); + sprint(other, " health\n"); + +// health touch sound + sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM); + + stuffcmd (other, "bf\n"); + + self.model = string_null; + self.solid = SOLID_NOT; + + if (deathmatch != 2) // deathmatch 2 is the silly old rules + { + if (deathmatch) + self.nextthink = time + 20; + self.think = SUB_regen; + } + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + +void() item_megahealth_rot = +{ + other = self.owner; + + if (other.health > other.max_health) + { + other.health = other.health - 1; + self.nextthink = time + 1; + return; + } + +// it is possible for a player to die and respawn between rots, so don't +// just blindly subtract the flag off + other.items = other.items - (other.items & IT_SUPERHEALTH); + + if (deathmatch == 1) // deathmatch 2 is silly old rules + { + self.nextthink = time + 20; + self.think = SUB_regen; + } +}; + +/* +=============================================================================== + +ARMOR + +=============================================================================== +*/ + +void() armor_touch; + +void() armor_touch = +{ + local float type, value, bit; + + if (other.health <= 0) + return; + if (other.classname != "player") + return; + + if (self.classname == "item_armor1") + { + type = 0.3; + value = 100; + bit = IT_ARMOR1; + } + if (self.classname == "item_armor2") + { + type = 0.6; + value = 150; + bit = IT_ARMOR2; + } + if (self.classname == "item_armorInv") + { + type = 0.8; + value = 200; + bit = IT_ARMOR3; + } + if (other.armortype*other.armorvalue >= type*value) + return; + + other.armortype = type; + other.armorvalue = value; + other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit; + + self.solid = SOLID_NOT; + self.model = string_null; + if (deathmatch == 1) + self.nextthink = time + 20; + self.think = SUB_regen; + + sprint(other, "You got armor\n"); +// armor touch sound + sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +/*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() item_armor1 = +{ + self.touch = armor_touch; + precache_model ("progs/armor.mdl"); + setmodel (self, "progs/armor.mdl"); + self.skin = 0; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() item_armor2 = +{ + self.touch = armor_touch; + precache_model ("progs/armor.mdl"); + setmodel (self, "progs/armor.mdl"); + self.skin = 1; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() item_armorInv = +{ + self.touch = armor_touch; + precache_model ("progs/armor.mdl"); + setmodel (self, "progs/armor.mdl"); + self.skin = 2; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/* +=============================================================================== + +WEAPONS + +=============================================================================== +*/ + +void() bound_other_ammo = +{ + if (other.ammo_shells > 100) + other.ammo_shells = 100; + if (other.ammo_nails > 200) + other.ammo_nails = 200; + if (other.ammo_rockets > 100) + other.ammo_rockets = 100; + if (other.ammo_cells > 100) + other.ammo_cells = 100; +}; + + +float(float w) RankForWeapon = +{ + if (w == IT_LIGHTNING) + return 1; + if (w == IT_MAGMA) + return 2; + if (w == IT_SNIPER) + return 3; + if (w == IT_GRENADE_LAUNCHER) + return 4; + if (w == IT_ROCKET) + return 5; + if (w == IT_SPLASER) + return 6; + return 7; +}; + +/* +============= +Deathmatch_Weapon + +Deathmatch weapon change rules for picking up a weapon + +.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells; +============= +*/ +void(float old, float new) Deathmatch_Weapon = +{ + local float or, nr; + +// change self.weapon if desired + or = RankForWeapon (self.weapon); + nr = RankForWeapon (new); + if ( nr < or ) + self.weapon = new; +}; + +/* +============= +weapon_touch +============= +*/ +//float() W_BestWeapon; + +void() weapon_touch = +{ + local float hadammo, new, old; + local entity stemp; + local float leave; + + if (!(other.flags & FL_CLIENT)) + return; + +// if the player was using his best weapon, change up to the new one if better + stemp = self; + self = other; + self = stemp; + + if (deathmatch == 2 || coop) + leave = 1; + else + leave = 0; + + if (self.classname == "weapon_nailgun") + { + if (leave && (other.items & IT_SPLASER) ) + return; + hadammo = other.ammo_nails; + new = IT_SPLASER; + if (self.ammo_nails >= 45) + return; + other.ammo_nails = other.ammo_nails + 8; + if (self.ammo_nails >= 45) + self.ammo_nails = 45; + } + else if (self.classname == "weapon_sniper") + { + if (leave && (other.items & IT_SNIPER) ) + return; + hadammo = other.ammo_rockets; + new = IT_SNIPER; + if (self.ammo_sniper >= 20) + return; + other.ammo_sniper = other.ammo_sniper + 4; + if (self.ammo_sniper >= 20) + self.ammo_sniper = 20; + } + else if (self.classname == "weapon_supershotgun") + { + if (leave && (other.items & IT_ROCKET) ) + return; + hadammo = other.ammo_rockets; + new = IT_ROCKET; + if (other.ammo_rockets >= 25) + return; + other.ammo_rockets = other.ammo_rockets + 5; + if (other.ammo_rockets >= 25) + other.ammo_rockets = 25; + } + else if (self.classname == "weapon_magma") + { + if (leave && (other.items & IT_MAGMA) ) + return; + hadammo = other.ammo_lava; + new = IT_MAGMA; + if (other.ammo_lava >= 45) + return; + other.ammo_lava = other.ammo_lava + 10; + if (other.ammo_lava >= 45) + other.ammo_rockets = 45; + } + else if (self.classname == "weapon_grenadelauncher") + { + if (leave && (other.items & IT_GRENADE_LAUNCHER) ) + return; + hadammo = other.ammo_rockets; + new = IT_GRENADE_LAUNCHER; + other.ammo_rockets = other.ammo_rockets + 5; + } + else if (self.classname == "weapon_lightning") + { + if (leave && (other.items & IT_LIGHTNING) ) + return; + hadammo = other.ammo_rockets; + new = IT_LIGHTNING; + other.ammo_cells = other.ammo_cells + 15; + } + else if (self.classname == "weapon_ric") + { + if (leave && (other.items & IT_RIC) ) + return; + hadammo = other.ammo_rockets; + new = IT_RIC; + if (other.ammo_ric >= 100) + return; + other.ammo_ric = other.ammo_ric + 25; + if (other.ammo_ric >= 80) + other.ammo_ric = 100; + } + + else + objerror ("weapon_touch: unknown classname"); + + sprint (other, "You got the "); + sprint (other, self.netname); + sprint (other, "\n"); +// weapon touch sound + sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + + bound_other_ammo (); + +// change to the weapon + old = other.items; + other.items = other.items | new; + + stemp = self; + self = other; + + if (!deathmatch) + self.weapon = new; + else + Deathmatch_Weapon (old, new); + + W_SetCurrentAmmo(); + + self = stemp; + + if (leave) + return; + +// remove it in single player, or setup for respawning in deathmatch + self.model = string_null; + self.solid = SOLID_NOT; + if (deathmatch == 1) + self.nextthink = time + 30; + self.think = SUB_regen; + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +/*Prime Weapon Rocket Launcher +*/ +void() weapon_supershotgun = +{ + precache_model ("progs/item_rocket.mdl"); + setmodel (self, "progs/item_rocket.mdl"); + self.weapon = IT_ROCKET; + self.netname = "Rocket Launcher"; + self.touch = weapon_touch; + self.effects = EF_DIMLIGHT; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; + +/*Prime Weapon Splaser +*/ + +void() weapon_nailgun = +{ + precache_model ("progs/item_splaser.spr"); + setmodel (self, "progs/item_splaser.spr"); + self.weapon = IT_SPLASER; + self.netname = "Splaser"; + self.touch = weapon_touch; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; + +/* Prime Weapon SNiper +*/ + +void() weapon_sniper = +{ + precache_model ("progs/item_sniper.spr"); + setmodel (self, "progs/item_sniper.spr"); + self.weapon = IT_SNIPER; + self.classname = "weapon_sniper"; + self.netname = "Sniper"; + self.touch = weapon_touch; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; + +/*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() weapon_grenadelauncher = +{ + precache_model ("progs/g_rock.mdl"); + setmodel (self, "progs/g_rock.mdl"); + self.weapon = 3; + self.netname = "Grenade Launcher"; + self.touch = weapon_touch; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/*Prime Weapon Magma beam +*/ + +void() weapon_magma = +{ + precache_model ("progs/item_magma.spr"); + setmodel (self, "progs/item_magma.spr"); + self.weapon = 3; + self.classname = "weapon_magma"; + self.netname = "Magma Beam"; + self.touch = weapon_touch; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + + +/*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() weapon_lightning = +{ + precache_model ("progs/g_light.mdl"); + setmodel (self, "progs/g_light.mdl"); + self.weapon = 3; + self.netname = "Thunderbolt"; + self.touch = weapon_touch; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/*Prime Weapon Richochet beam +*/ +void() weapon_ric = +{ + precache_model ("progs/item_ric.spr"); + setmodel (self, "progs/item_ric.spr"); + self.weapon = IT_RIC; + self.classname = "weapon_ric"; + self.netname = "Richochet Beam"; + self.touch = weapon_touch; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; + + + +/* +=============================================================================== + +AMMO + +=============================================================================== +*/ + +void() ammo_touch = +{ +local entity stemp; + + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + +// if the player was using his best weapon, change up to the new one if better + stemp = self; + self = other; + self = stemp; + + +// shotgun + if (self.weapon == 1) + { + if (other.ammo_shells >= 100) + return; + other.ammo_shells = other.ammo_shells + self.aflag; + } + +// rockets + if (self.weapon == 3) + { + if (other.ammo_rockets >= 100) + return; + other.ammo_rockets = other.ammo_rockets + self.aflag; + } + +// cells + if (self.weapon == 4) + { + if (other.ammo_cells >= 100) + return; + other.ammo_cells = other.ammo_cells + self.aflag; + } + + bound_other_ammo (); + + sprint (other, "You got the "); + sprint (other, self.netname); + sprint (other, "\n"); +// ammo touch sound + sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + + +// if changed current ammo, update it + stemp = self; + self = other; + W_SetCurrentAmmo(); + self = stemp; + +// remove it in single player, or setup for respawning in deathmatch + self.model = string_null; + self.solid = SOLID_NOT; + if (deathmatch == 1) + self.nextthink = time + 30; + self.think = SUB_regen; + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + + + +float WEAPON_BIG2 = 1; + +/*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big +*/ + +void() item_shells = +{ + self.touch = ammo_touch; + + if (self.spawnflags & WEAPON_BIG2) + { + precache_model ("maps/b_shell1.bsp"); + setmodel (self, "maps/b_shell1.bsp"); + self.aflag = 40; + } + else + { + precache_model ("maps/b_shell0.bsp"); + setmodel (self, "maps/b_shell0.bsp"); + self.aflag = 20; + } + self.weapon = 1; + self.netname = "shells"; + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; + +/*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big +*/ + +void() item_spikes = +{ + self.touch = ammo_touch; + + if (self.spawnflags & WEAPON_BIG2) + { + precache_model ("maps/b_nail1.bsp"); + setmodel (self, "maps/b_nail1.bsp"); + self.aflag = 50; + } + else + { + precache_model ("maps/b_nail0.bsp"); + setmodel (self, "maps/b_nail0.bsp"); + self.aflag = 25; + } + self.weapon = 2; + self.netname = "nails"; + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; + +/*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big +*/ + +void() item_rockets = +{ + self.touch = ammo_touch; + + if (self.spawnflags & WEAPON_BIG2) + { + precache_model ("maps/b_rock1.bsp"); + setmodel (self, "maps/b_rock1.bsp"); + self.aflag = 10; + } + else + { + precache_model ("maps/b_rock0.bsp"); + setmodel (self, "maps/b_rock0.bsp"); + self.aflag = 5; + } + self.weapon = 3; + self.netname = "rockets"; + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; + + +/*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big +*/ + +void() item_cells = +{ + self.touch = ammo_touch; + + if (self.spawnflags & WEAPON_BIG2) + { + precache_model ("maps/b_batt1.bsp"); + setmodel (self, "maps/b_batt1.bsp"); + self.aflag = 12; + } + else + { + precache_model ("maps/b_batt0.bsp"); + setmodel (self, "maps/b_batt0.bsp"); + self.aflag = 6; + } + self.weapon = 4; + self.netname = "cells"; + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; + + +/*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big +DO NOT USE THIS!!!! IT WILL BE REMOVED! +*/ + +float WEAPON_SHOTGUN = 1; +float WEAPON_ROCKET = 2; +float WEAPON_SPIKES = 4; +float WEAPON_BIG = 8; +void() item_weapon = +{ + self.touch = ammo_touch; + + if (self.spawnflags & WEAPON_SHOTGUN) + { + if (self.spawnflags & WEAPON_BIG) + { + precache_model ("maps/b_shell1.bsp"); + setmodel (self, "maps/b_shell1.bsp"); + self.aflag = 40; + } + else + { + precache_model ("maps/b_shell0.bsp"); + setmodel (self, "maps/b_shell0.bsp"); + self.aflag = 20; + } + self.weapon = 1; + self.netname = "shells"; + } + + if (self.spawnflags & WEAPON_SPIKES) + { + if (self.spawnflags & WEAPON_BIG) + { + precache_model ("maps/b_nail1.bsp"); + setmodel (self, "maps/b_nail1.bsp"); + self.aflag = 40; + } + else + { + precache_model ("maps/b_nail0.bsp"); + setmodel (self, "maps/b_nail0.bsp"); + self.aflag = 20; + } + self.weapon = 2; + self.netname = "spikes"; + } + + if (self.spawnflags & WEAPON_ROCKET) + { + if (self.spawnflags & WEAPON_BIG) + { + precache_model ("maps/b_rock1.bsp"); + setmodel (self, "maps/b_rock1.bsp"); + self.aflag = 10; + } + else + { + precache_model ("maps/b_rock0.bsp"); + setmodel (self, "maps/b_rock0.bsp"); + self.aflag = 5; + } + self.weapon = 3; + self.netname = "rockets"; + } + + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; + + +/* +=============================================================================== + +KEYS + +=============================================================================== +*/ + +void() key_touch = +{ + if (other.classname != "player") + return; + if (other.health <= 0) + return; + if (other.items & self.items) + return; + + sprint (other, "You got the "); + sprint (other, self.netname); + sprint (other,"\n"); + + sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + other.items = other.items | self.items; + + if (!coop) + { + self.solid = SOLID_NOT; + self.model = string_null; + } + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +void() key_setsounds = +{ + if (world.worldtype == 0) + { + precache_sound ("misc/medkey.wav"); + self.noise = "misc/medkey.wav"; + } + if (world.worldtype == 1) + { + precache_sound ("misc/runekey.wav"); + self.noise = "misc/runekey.wav"; + } + if (world.worldtype == 2) + { + precache_sound2 ("misc/basekey.wav"); + self.noise = "misc/basekey.wav"; + } +}; + +/*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) +SILVER key +In order for keys to work +you MUST set your maps +worldtype to one of the +following: +0: medieval +1: metal +2: base +*/ + +void() item_key1 = +{ + if (world.worldtype == 0) + { + precache_model ("progs/w_s_key.mdl"); + setmodel (self, "progs/w_s_key.mdl"); + self.netname = "silver key"; + } + else if (world.worldtype == 1) + { + precache_model ("progs/m_s_key.mdl"); + setmodel (self, "progs/m_s_key.mdl"); + self.netname = "silver runekey"; + } + else if (world.worldtype == 2) + { + precache_model2 ("progs/b_s_key.mdl"); + setmodel (self, "progs/b_s_key.mdl"); + self.netname = "silver keycard"; + } + key_setsounds(); + self.touch = key_touch; + self.items = IT_KEY1; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + +/*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) +GOLD key +In order for keys to work +you MUST set your maps +worldtype to one of the +following: +0: medieval +1: metal +2: base +*/ + +void() item_key2 = +{ + if (world.worldtype == 0) + { + precache_model ("progs/w_g_key.mdl"); + setmodel (self, "progs/w_g_key.mdl"); + self.netname = "gold key"; + } + if (world.worldtype == 1) + { + precache_model ("progs/m_g_key.mdl"); + setmodel (self, "progs/m_g_key.mdl"); + self.netname = "gold runekey"; + } + if (world.worldtype == 2) + { + precache_model2 ("progs/b_g_key.mdl"); + setmodel (self, "progs/b_g_key.mdl"); + self.netname = "gold keycard"; + } + key_setsounds(); + self.touch = key_touch; + self.items = IT_KEY2; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + + +/* +=============================================================================== + +END OF LEVEL RUNES + +=============================================================================== +*/ + +void() sigil_touch = +{ + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + centerprint (other, "You got the rune!"); + + sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + self.model = string_null; + serverflags = serverflags | (self.spawnflags & 15); + self.classname = ""; // so rune doors won't find it + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +/*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4 +End of level sigil, pick up to end episode and return to jrstart. +*/ + +void() item_sigil = +{ + if (!self.spawnflags) + objerror ("no spawnflags"); + + precache_sound ("misc/runekey.wav"); + self.noise = "misc/runekey.wav"; + + if (self.spawnflags & 1) + { + precache_model ("progs/end1.mdl"); + setmodel (self, "progs/end1.mdl"); + } + if (self.spawnflags & 2) + { + precache_model2 ("progs/end2.mdl"); + setmodel (self, "progs/end2.mdl"); + } + if (self.spawnflags & 4) + { + precache_model2 ("progs/end3.mdl"); + setmodel (self, "progs/end3.mdl"); + } + if (self.spawnflags & 8) + { + precache_model2 ("progs/end4.mdl"); + setmodel (self, "progs/end4.mdl"); + } + + self.touch = sigil_touch; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + +/* +=============================================================================== + +POWERUPS + +=============================================================================== +*/ + +void() powerup_touch; + + +void() powerup_touch = +{ + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + sprint (other, "You got the "); + sprint (other, self.netname); + sprint (other,"\n"); + + if (deathmatch) + { + self.mdl = self.model; + + if ((self.classname == "item_artifact_invulnerability") || + (self.classname == "item_artifact_invisibility")) + self.nextthink = time + 60*5; + else + self.nextthink = time + 60; + + self.think = SUB_regen; + } + + sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + other.items = other.items | self.items; + self.model = string_null; + +// do the apropriate action + if (self.classname == "item_artifact_envirosuit") + { + other.rad_time = 1; + other.radsuit_finished = time + 30; + } + + if (self.classname == "item_artifact_invulnerability") + { + other.invincible_time = 1; + other.invincible_finished = time + 30; + } + + if (self.classname == "item_artifact_invisibility") + { + other.invisible_time = 1; + other.invisible_finished = time + 30; + } + + if (self.classname == "item_artifact_super_damage") + { + other.super_time = 1; + other.super_damage_finished = time + 30; + } + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + + +/*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32) +Player is invulnerable for 30 seconds +*/ +void() item_artifact_invulnerability = +{ + self.touch = powerup_touch; + + precache_model ("progs/invulner.mdl"); + precache_sound ("items/protect.wav"); + precache_sound ("items/protect2.wav"); + precache_sound ("items/protect3.wav"); + self.noise = "items/protect.wav"; + setmodel (self, "progs/invulner.mdl"); + self.netname = "Pentagram of Protection"; + self.items = IT_INVULNERABILITY; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + +/*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32) +Player takes no damage from water or slime for 30 seconds +*/ +void() item_artifact_envirosuit = +{ + self.touch = powerup_touch; + + precache_model ("progs/suit.mdl"); + precache_sound ("items/suit.wav"); + precache_sound ("items/suit2.wav"); + self.noise = "items/suit.wav"; + setmodel (self, "progs/suit.mdl"); + self.netname = "Biosuit"; + self.items = IT_SUIT; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + +/*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32) +Player is invisible for 30 seconds +*/ +void() item_artifact_invisibility = +{ + self.touch = powerup_touch; + + precache_model ("progs/invisibl.mdl"); + precache_sound ("items/inv1.wav"); + precache_sound ("items/inv2.wav"); + precache_sound ("items/inv3.wav"); + self.noise = "items/inv1.wav"; + setmodel (self, "progs/invisibl.mdl"); + self.netname = "Ring of Shadows"; + self.items = IT_INVISIBILITY; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + +/*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32) +The next attack from the player will do 4x damage +*/ +void() item_artifact_super_damage = +{ + self.touch = powerup_touch; + + precache_model ("progs/quaddama.mdl"); + precache_sound ("items/damage.wav"); + precache_sound ("items/damage2.wav"); + precache_sound ("items/damage3.wav"); + self.noise = "items/damage.wav"; + setmodel (self, "progs/quaddama.mdl"); + self.netname = "Quad Damage"; + self.items = IT_QUAD; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + + +/* +=============================================================================== + +PLAYER BACKPACKS + +=============================================================================== +*/ + +void() BackpackTouch = +{ + local string s; + local float old, new; + local entity stemp; + local float acount; + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + acount = 0; + sprint (other, "You get "); + + if (self.items) + if ((other.items & self.items) == 0) + { + acount = 1; + sprint (other, "the "); + sprint (other, self.netname); + } + +// if the player was using his best weapon, change up to the new one if better + stemp = self; + self = other; + //best = W_BestWeapon(); + self = stemp; + +// change weapons + other.ammo_shells = other.ammo_shells + self.ammo_shells; + other.ammo_nails = other.ammo_nails + self.ammo_nails; + other.ammo_rockets = other.ammo_rockets + self.ammo_rockets; + other.ammo_cells = other.ammo_cells + self.ammo_cells; + + new = self.items; + if (!new) + new = other.weapon; + old = other.items; + other.items = other.items | new; + + bound_other_ammo (); + + if (self.ammo_shells) + { + if (acount) + sprint(other, ", "); + acount = 1; + s = ftos(self.ammo_shells); + sprint (other, s); + sprint (other, " shells"); + } + if (self.ammo_nails) + { + if (acount) + sprint(other, ", "); + acount = 1; + s = ftos(self.ammo_nails); + sprint (other, s); + sprint (other, " nails"); + } + if (self.ammo_rockets) + { + if (acount) + sprint(other, ", "); + acount = 1; + s = ftos(self.ammo_rockets); + sprint (other, s); + sprint (other, " rockets"); + } + if (self.ammo_cells) + { + if (acount) + sprint(other, ", "); + acount = 1; + s = ftos(self.ammo_cells); + sprint (other, s); + sprint (other, " cells"); + } + + sprint (other, "\n"); +// backpack touch sound + sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + +// remove the backpack, change self to the player + remove(self); + self = other; + +// change to the weapon + if (!deathmatch) + self.weapon = new; + else + Deathmatch_Weapon (old, new); + + W_SetCurrentAmmo (); +}; + +/* +=============== +DropBackpack +=============== +*/ +void() DropBackpack = +{ + local entity item; + + if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells)) + return; // nothing in it + + item = spawn(); + item.origin = self.origin - '0 0 24'; + + item.items = self.weapon; + if (item.items == IT_MORPHBALL) + item.netname = "Axe"; + else if (item.items == IT_BLASTER) + item.netname = "Shotgun"; + else if (item.items == IT_ROCKET) + item.netname = "Double-barrelled Shotgun"; + else if (item.items == IT_SPLASER) + item.netname = "Nailgun"; + else if (item.items == IT_SNIPER) + item.netname = "Super Nailgun"; + else if (item.items == IT_GRENADE_LAUNCHER) + item.netname = "Grenade Launcher"; + else if (item.items == IT_MAGMA) + item.netname = "Rocket Launcher"; + else if (item.items == IT_LIGHTNING) + item.netname = "Thunderbolt"; + else + item.netname = ""; + + item.ammo_shells = self.ammo_shells; + item.ammo_nails = self.ammo_nails; + item.ammo_rockets = self.ammo_rockets; + item.ammo_cells = self.ammo_cells; + + item.velocity_z = 300; + item.velocity_x = -100 + (random() * 200); + item.velocity_y = -100 + (random() * 200); + + item.flags = FL_ITEM; + item.solid = SOLID_TRIGGER; + item.movetype = MOVETYPE_TOSS; + setmodel (item, "progs/backpack.mdl"); + setsize (item, '-16 -16 0', '16 16 56'); + item.touch = BackpackTouch; + + item.nextthink = time + 120; // remove after 2 minutes + item.think = SUB_Remove; +}; +void() energy_touch = +{ +if (other.classname != "player") + return; +other.energy = other.energy + 1; +if (other.energy == 1) +{ +other.health = 199; +other.max_health = 199; +} +else if (other.energy == 2) +{ +other.health = 299; +other.max_health = 299; +} +else if (other.energy == 3) +{ +other.health = 399; +other.max_health = 399; +} +else if (other.energy == 4) +{ +other.health = 499; +other.max_health = 499; +} +else if (other.energy == 5) +{ +other.health = 599; +other.max_health = 599; +} +else if (other.energy == 6) +{ +other.health = 699; +other.max_health = 699; +} +else if (other.energy == 7) +{ +other.health = 799; +other.max_health = 799; +} +else if (other.energy == 8) +{ +other.health = 899; +other.max_health = 899; +} +else if (other.energy == 9) +{ +other.health = 999; +other.max_health = 999; +} +else +other.max_health = 99; + +self.model = string_null; +self.solid = SOLID_NOT; + +activator = other; +SUB_UseTargets(); // fire all targets / killtargets +}; +void() item_energytank = +{ + if (deathmatch) + remove(self); + precache_model("progs/etank.mdl"); + precache_sound("items/r_item1.wav"); + setmodel(self, "progs/etank.mdl"); + self.noise = "items/r_item1.wav"; + self.classname = "etank"; + self.effects = EF_DIMLIGHT; + self.healamount = other.max_health; + self.touch = energy_touch; + setsize (self, '-7 -7 0', '7 7 7'); + StartItem (); +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/jctest.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/jctest.qc new file mode 100755 index 00000000..85a7605f --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/jctest.qc @@ -0,0 +1,15 @@ + +void() jctrig = +{ +dprint ("here\n\n"); + lightstyle(0, "az"); +}; + +/*QUAKED trigger_jctest (.5 .5 .5) ? +*/ +void() trigger_jctest = +{ + setsize (self, self.mins, self.maxs); + self.solid = SOLID_EDGE; + self.touch = jctrig; +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/knight.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/knight.qc new file mode 100755 index 00000000..4969750d --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/knight.qc @@ -0,0 +1,270 @@ +/* +============================================================================== + +KNIGHT + +============================================================================== +*/ + +$cd id1/models/knight +$origin 0 0 24 +$base base +$skin badass3 + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame runb1 runb2 runb3 runb4 runb5 runb6 runb7 runb8 + +//frame runc1 runc2 runc3 runc4 runc5 runc6 + +$frame runattack1 runattack2 runattack3 runattack4 runattack5 +$frame runattack6 runattack7 runattack8 runattack9 runattack10 +$frame runattack11 + +$frame pain1 pain2 pain3 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 +$frame painb10 painb11 + +//frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 +//frame attack8 attack9 attack10 attack11 + +$frame attackb1 attackb2 attackb3 attackb4 attackb5 +$frame attackb6 attackb7 attackb8 attackb9 attackb10 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 +$frame walk10 walk11 walk12 walk13 walk14 + +$frame kneel1 kneel2 kneel3 kneel4 kneel5 + +$frame standing2 standing3 standing4 standing5 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 deathb10 deathb11 + +void() knight_stand1 =[ $stand1, knight_stand2 ] {ai_stand();}; +void() knight_stand2 =[ $stand2, knight_stand3 ] {ai_stand();}; +void() knight_stand3 =[ $stand3, knight_stand4 ] {ai_stand();}; +void() knight_stand4 =[ $stand4, knight_stand5 ] {ai_stand();}; +void() knight_stand5 =[ $stand5, knight_stand6 ] {ai_stand();}; +void() knight_stand6 =[ $stand6, knight_stand7 ] {ai_stand();}; +void() knight_stand7 =[ $stand7, knight_stand8 ] {ai_stand();}; +void() knight_stand8 =[ $stand8, knight_stand9 ] {ai_stand();}; +void() knight_stand9 =[ $stand9, knight_stand1 ] {ai_stand();}; + +void() knight_walk1 =[ $walk1, knight_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE); +ai_walk(3);}; +void() knight_walk2 =[ $walk2, knight_walk3 ] {ai_walk(2);}; +void() knight_walk3 =[ $walk3, knight_walk4 ] {ai_walk(3);}; +void() knight_walk4 =[ $walk4, knight_walk5 ] {ai_walk(4);}; +void() knight_walk5 =[ $walk5, knight_walk6 ] {ai_walk(3);}; +void() knight_walk6 =[ $walk6, knight_walk7 ] {ai_walk(3);}; +void() knight_walk7 =[ $walk7, knight_walk8 ] {ai_walk(3);}; +void() knight_walk8 =[ $walk8, knight_walk9 ] {ai_walk(4);}; +void() knight_walk9 =[ $walk9, knight_walk10 ] {ai_walk(3);}; +void() knight_walk10 =[ $walk10, knight_walk11 ] {ai_walk(3);}; +void() knight_walk11 =[ $walk11, knight_walk12 ] {ai_walk(2);}; +void() knight_walk12 =[ $walk12, knight_walk13 ] {ai_walk(3);}; +void() knight_walk13 =[ $walk13, knight_walk14 ] {ai_walk(4);}; +void() knight_walk14 =[ $walk14, knight_walk1 ] {ai_walk(3);}; + + +void() knight_run1 =[ $runb1, knight_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE); +ai_run(16);}; +void() knight_run2 =[ $runb2, knight_run3 ] {ai_run(20);}; +void() knight_run3 =[ $runb3, knight_run4 ] {ai_run(13);}; +void() knight_run4 =[ $runb4, knight_run5 ] {ai_run(7);}; +void() knight_run5 =[ $runb5, knight_run6 ] {ai_run(16);}; +void() knight_run6 =[ $runb6, knight_run7 ] {ai_run(20);}; +void() knight_run7 =[ $runb7, knight_run8 ] {ai_run(14);}; +void() knight_run8 =[ $runb8, knight_run1 ] {ai_run(6);}; + + +void() knight_runatk1 =[ $runattack1, knight_runatk2 ] +{ +if (random() > 0.5) + sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM); +else + sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +ai_charge(20); +}; +void() knight_runatk2 =[ $runattack2, knight_runatk3 ] {ai_charge_side();}; +void() knight_runatk3 =[ $runattack3, knight_runatk4 ] {ai_charge_side();}; +void() knight_runatk4 =[ $runattack4, knight_runatk5 ] {ai_charge_side();}; +void() knight_runatk5 =[ $runattack5, knight_runatk6 ] {ai_melee_side();}; +void() knight_runatk6 =[ $runattack6, knight_runatk7 ] {ai_melee_side();}; +void() knight_runatk7 =[ $runattack7, knight_runatk8 ] {ai_melee_side();}; +void() knight_runatk8 =[ $runattack8, knight_runatk9 ] {ai_melee_side();}; +void() knight_runatk9 =[ $runattack9, knight_runatk10 ] {ai_melee_side();}; +void() knight_runatk10 =[ $runattack10, knight_runatk11 ] {ai_charge_side();}; +void() knight_runatk11 =[ $runattack11, knight_run1 ] {ai_charge(10);}; + +void() knight_atk1 =[ $attackb1, knight_atk2 ] +{ +sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +ai_charge(0);}; +void() knight_atk2 =[ $attackb2, knight_atk3 ] {ai_charge(7);}; +void() knight_atk3 =[ $attackb3, knight_atk4 ] {ai_charge(4);}; +void() knight_atk4 =[ $attackb4, knight_atk5 ] {ai_charge(0);}; +void() knight_atk5 =[ $attackb5, knight_atk6 ] {ai_charge(3);}; +void() knight_atk6 =[ $attackb6, knight_atk7 ] {ai_charge(4); ai_melee();}; +void() knight_atk7 =[ $attackb7, knight_atk8 ] {ai_charge(1); ai_melee();}; +void() knight_atk8 =[ $attackb8, knight_atk9 ] {ai_charge(3); +ai_melee();}; +void() knight_atk9 =[ $attackb9, knight_atk10] {ai_charge(1);}; +void() knight_atk10=[ $attackb10, knight_run1 ] {ai_charge(5);}; + +//void() knight_atk9 =[ $attack9, knight_atk10 ] {}; +//void() knight_atk10 =[ $attack10, knight_atk11 ] {}; +//void() knight_atk11 =[ $attack11, knight_run1 ] {}; + +//=========================================================================== + +void() knight_pain1 =[ $pain1, knight_pain2 ] {}; +void() knight_pain2 =[ $pain2, knight_pain3 ] {}; +void() knight_pain3 =[ $pain3, knight_run1 ] {}; + +void() knight_painb1 =[ $painb1, knight_painb2 ] {ai_painforward(0);}; +void() knight_painb2 =[ $painb2, knight_painb3 ] {ai_painforward(3);}; +void() knight_painb3 =[ $painb3, knight_painb4 ] {}; +void() knight_painb4 =[ $painb4, knight_painb5 ] {}; +void() knight_painb5 =[ $painb5, knight_painb6 ] {ai_painforward(2);}; +void() knight_painb6 =[ $painb6, knight_painb7 ] {ai_painforward(4);}; +void() knight_painb7 =[ $painb7, knight_painb8 ] {ai_painforward(2);}; +void() knight_painb8 =[ $painb8, knight_painb9 ] {ai_painforward(5);}; +void() knight_painb9 =[ $painb9, knight_painb10 ] {ai_painforward(5);}; +void() knight_painb10 =[ $painb10, knight_painb11 ] {ai_painforward(0);}; +void() knight_painb11 =[ $painb11, knight_run1 ] {}; + +void(entity attacker, float damage) knight_pain = +{ + local float r; + + if (self.pain_finished > time) + return; + + r = random(); + + sound (self, CHAN_VOICE, "knight/khurt.wav", 1, ATTN_NORM); + if (r < 0.85) + { + knight_pain1 (); + self.pain_finished = time + 1; + } + else + { + knight_painb1 (); + self.pain_finished = time + 1; + } + +}; + +//=========================================================================== + +void() knight_bow1 =[ $kneel1, knight_bow2 ] {ai_turn();}; +void() knight_bow2 =[ $kneel2, knight_bow3 ] {ai_turn();}; +void() knight_bow3 =[ $kneel3, knight_bow4 ] {ai_turn();}; +void() knight_bow4 =[ $kneel4, knight_bow5 ] {ai_turn();}; + +void() knight_bow5 =[ $kneel5, knight_bow5 ] {ai_turn();}; + +void() knight_bow6 =[ $kneel4, knight_bow7 ] {ai_turn();}; +void() knight_bow7 =[ $kneel3, knight_bow8 ] {ai_turn();}; +void() knight_bow8 =[ $kneel2, knight_bow9 ] {ai_turn();}; +void() knight_bow9 =[ $kneel1, knight_bow10 ] {ai_turn();}; +void() knight_bow10 =[ $walk1, knight_walk1 ] {ai_turn();}; + + + +void() knight_die1 =[ $death1, knight_die2 ] {}; +void() knight_die2 =[ $death2, knight_die3 ] {}; +void() knight_die3 =[ $death3, knight_die4 ] +{self.solid = SOLID_NOT;}; +void() knight_die4 =[ $death4, knight_die5 ] {}; +void() knight_die5 =[ $death5, knight_die6 ] {}; +void() knight_die6 =[ $death6, knight_die7 ] {}; +void() knight_die7 =[ $death7, knight_die8 ] {}; +void() knight_die8 =[ $death8, knight_die9 ] {}; +void() knight_die9 =[ $death9, knight_die10] {}; +void() knight_die10=[ $death10, knight_die10] {}; + + +void() knight_dieb1 =[ $deathb1, knight_dieb2 ] {}; +void() knight_dieb2 =[ $deathb2, knight_dieb3 ] {}; +void() knight_dieb3 =[ $deathb3, knight_dieb4 ] +{self.solid = SOLID_NOT;}; +void() knight_dieb4 =[ $deathb4, knight_dieb5 ] {}; +void() knight_dieb5 =[ $deathb5, knight_dieb6 ] {}; +void() knight_dieb6 =[ $deathb6, knight_dieb7 ] {}; +void() knight_dieb7 =[ $deathb7, knight_dieb8 ] {}; +void() knight_dieb8 =[ $deathb8, knight_dieb9 ] {}; +void() knight_dieb9 =[ $deathb9, knight_dieb10] {}; +void() knight_dieb10 = [ $deathb10, knight_dieb11] {}; +void() knight_dieb11 = [ $deathb11, knight_dieb11] {}; + + +void() knight_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_knight.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "knight/kdeath.wav", 1, ATTN_NORM); + if (random() < 0.5) + knight_die1 (); + else + knight_dieb1 (); +}; + + +/*QUAKED monster_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_wizard = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/metroid.mdl"); + precache_model ("progs/h_knight.mdl"); + + precache_sound ("knight/kdeath.wav"); + precache_sound ("knight/khurt.wav"); + precache_sound ("knight/ksight.wav"); + precache_sound ("knight/sword1.wav"); + precache_sound ("knight/sword2.wav"); + precache_sound ("knight/idle.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/metroid.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 75; + + self.th_stand = knight_stand1; + self.th_walk = knight_walk1; + self.th_run = knight_run1; + self.th_melee = knight_atk1; + self.th_pain = knight_pain; + self.th_die = knight_die; + + flymonster_start (); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/misc.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/misc.qc new file mode 100755 index 00000000..30a4fc90 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/misc.qc @@ -0,0 +1,715 @@ + +/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4) +Used as a positional target for spotlights, etc. +*/ +void() info_null = +{ + remove(self); +}; + +/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4) +Used as a positional target for lightning. +*/ +void() info_notnull = +{ +}; + +//============================================================================ + +float START_OFF = 1; + +void() light_use = +{ + if (self.spawnflags & START_OFF) + { + lightstyle(self.style, "m"); + self.spawnflags = self.spawnflags - START_OFF; + } + else + { + lightstyle(self.style, "a"); + self.spawnflags = self.spawnflags + START_OFF; + } +}; + +/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF +Non-displayed light. +Default light value is 300 +Default style is 0 +If targeted, it will toggle between on or off. +*/ +void() light = +{ + if (!self.targetname) + { // inert light + remove(self); + return; + } + + if (self.style >= 32) + { + self.use = light_use; + if (self.spawnflags & START_OFF) + lightstyle(self.style, "a"); + else + lightstyle(self.style, "m"); + } +}; + +/*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF +Non-displayed light. +Default light value is 300 +Default style is 0 +If targeted, it will toggle between on or off. +Makes steady fluorescent humming sound +*/ +void() light_fluoro = +{ + if (self.style >= 32) + { + self.use = light_use; + if (self.spawnflags & START_OFF) + lightstyle(self.style, "a"); + else + lightstyle(self.style, "m"); + } + + precache_sound ("ambience/fl_hum1.wav"); + ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8) +Non-displayed light. +Default light value is 300 +Default style is 10 +Makes sparking, broken fluorescent sound +*/ +void() light_fluorospark = +{ + if (!self.style) + self.style = 10; + + precache_sound ("ambience/buzz1.wav"); + ambientsound (self.origin, "ambience/buzz1.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8) +Sphere globe light. +Default light value is 300 +Default style is 0 +*/ +void() light_globe = +{ + precache_model ("progs/s_light.spr"); + setmodel (self, "progs/s_light.spr"); + makestatic (self); +}; + +void() FireAmbient = +{ + precache_sound ("ambience/fire1.wav"); +// attenuate fast + ambientsound (self.origin, "ambience/fire1.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20) +Short wall torch +Default light value is 200 +Default style is 0 +*/ +void() light_torch_small_walltorch = +{ + precache_model ("progs/flame.mdl"); + setmodel (self, "progs/flame.mdl"); + FireAmbient (); + makestatic (self); +}; + +/*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18) +Large yellow flame ball +*/ +void() light_flame_large_yellow = +{ + precache_model ("progs/flame2.mdl"); + setmodel (self, "progs/flame2.mdl"); + self.frame = 1; + FireAmbient (); + makestatic (self); +}; + +/*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) START_OFF +Small yellow flame ball +*/ +void() light_flame_small_yellow = +{ + precache_model ("progs/flame2.mdl"); + setmodel (self, "progs/flame2.mdl"); + FireAmbient (); + makestatic (self); +}; + +/*QUAKED light_flame_small_white (0 1 0) (-10 -10 -40) (10 10 40) START_OFF +Small white flame ball +*/ +void() light_flame_small_white = +{ + precache_model ("progs/flame2.mdl"); + setmodel (self, "progs/flame2.mdl"); + FireAmbient (); + makestatic (self); +}; + +//============================================================================ + + +/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8) +Lava Balls +*/ + +void() fire_fly; +void() fire_touch; +void() misc_fireball = +{ + + self.classname = "fireball"; + self.nextthink = time + (random() * 5); + self.think = fire_fly; + //if (!self.speed) + //self.speed == 1000; +}; + +void() fire_fly = +{ +local entity fireball; + + fireball = spawn(); + fireball.solid = SOLID_TRIGGER; + fireball.movetype = MOVETYPE_TOSS; + fireball.velocity = '0 0 1000'; + fireball.velocity_x = (random() * 100) - 50; + fireball.velocity_y = (random() * 100) - 50; + fireball.velocity_z = self.speed + (random() * 200); + fireball.classname = "fireball"; + setmodel (fireball, "progs/lavaball.mdl"); + setsize (fireball, '0 0 0', '0 0 0'); + setorigin (fireball, self.origin); + fireball.nextthink = time + 5; + fireball.think = SUB_Remove; + fireball.touch = fire_touch; + + self.nextthink = time + (random() * 5) + 3; + self.think = fire_fly; +}; + + +void() fire_touch = +{ + T_Damage (other, self, self, 20); + remove(self); +}; + +//============================================================================ + + +void() barrel_explode = +{ + self.takedamage = DAMAGE_NO; + self.classname = "explo_box"; + // did say self.owner + T_RadiusDamage (self, self, 160, world); + sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM); + particle (self.origin, '0 0 0', 75, 255); + + self.origin_z = self.origin_z + 32; + CreateExplosion(self.origin); + remove(self); +}; + + + +/*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64) +TESTING THING +*/ + +void() misc_explobox = +{ + local float oldz; + + self.solid = SOLID_BBOX; + self.movetype = MOVETYPE_NONE; + precache_model ("maps/b_explob.bsp"); + setmodel (self, "maps/b_explob.bsp"); + precache_sound ("weapons/r_exp3.wav"); + self.health = 20; + self.th_die = barrel_explode; + self.takedamage = DAMAGE_AIM; + + self.origin_z = self.origin_z + 2; + oldz = self.origin_z; + droptofloor(1, 1); + if (oldz - self.origin_z > 250) + { + dprint ("item fell out of level at "); + dprint (vtos(self.origin)); + dprint ("\n"); + remove(self); + } +}; + + + + +/*QUAKED misc_explobox2 (0 .5 .8) (0 0 0) (32 32 64) +Smaller exploding box, REGISTERED ONLY +*/ + +void() misc_explobox2 = +{ + self.solid = SOLID_BBOX; + self.movetype = MOVETYPE_NONE; + precache_model2 ("maps/b_exbox2.bsp"); + setmodel (self, "maps/b_exbox2.bsp"); + precache_sound ("weapons/r_exp3.wav"); + self.health = 20; + self.th_die = barrel_explode; + self.takedamage = DAMAGE_AIM; +}; + +//============================================================================ + +float SPAWNFLAG_SUPERSPIKE = 1; +float SPAWNFLAG_LASER = 2; + +void(vector org, vector vec) LaunchLaser; + +void() spikeshooter_use = +{ + if (self.spawnflags & SPAWNFLAG_LASER) + { + sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM); + LaunchLaser (self.origin, self.movedir); + } + else + { + sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM); + launch_spike (self.origin, self.movedir); + newmis.velocity = self.movedir * 500; + if (self.spawnflags & SPAWNFLAG_SUPERSPIKE) + newmis.touch = superspike_touch; + } +}; + +void() shooter_think = +{ + spikeshooter_use (); + self.nextthink = time + self.wait; + newmis.velocity = self.movedir * 500; +}; + + +/*QUAKED trap_spikeshooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser +When triggered, fires a spike in the direction set in QuakeEd. +Laser is only for REGISTERED. +*/ + +void() trap_spikeshooter = +{ + SetMovedir (); + self.use = spikeshooter_use; + if (self.spawnflags & SPAWNFLAG_LASER) + { + precache_model2 ("progs/laser.mdl"); + + precache_sound2 ("enforcer/enfire.wav"); + precache_sound2 ("enforcer/enfstop.wav"); + } + else + precache_sound ("weapons/spike2.wav"); +}; + + +/*QUAKED trap_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser +Continuously fires spikes. +"wait" time between spike (1.0 default) +"nextthink" delay before firing first spike, so multiple shooters can be stagered. +*/ +void() trap_shooter = +{ + trap_spikeshooter (); + + if (self.wait == 0) + self.wait = 1; + self.nextthink = self.nextthink + self.wait + self.ltime; + self.think = shooter_think; +}; + + + +/* +=============================================================================== + + +=============================================================================== +*/ + + +void() make_bubbles; +void() bubble_remove; +void() bubble_bob; + +/*QUAKED air_bubbles (0 .5 .8) (-8 -8 -8) (8 8 8) + +testing air bubbles +*/ + +void() air_bubbles = + +{ + if (deathmatch) + { + remove (self); + return; + } + precache_model ("progs/s_bubble.spr"); + self.nextthink = time + 1; + self.think = make_bubbles; +}; + +void() make_bubbles = +{ +local entity bubble; + + bubble = spawn(); + setmodel (bubble, "progs/s_bubble.spr"); + setorigin (bubble, self.origin); + bubble.movetype = MOVETYPE_NOCLIP; + bubble.solid = SOLID_NOT; + bubble.velocity = '0 0 15'; + bubble.nextthink = time + 0.5; + bubble.think = bubble_bob; + bubble.touch = bubble_remove; + bubble.classname = "bubble"; + bubble.frame = 0; + bubble.cnt = 0; + setsize (bubble, '-8 -8 -8', '8 8 8'); + self.nextthink = time + random() + 0.5; + self.think = make_bubbles; +}; + +void() bubble_split = +{ +local entity bubble; + bubble = spawn(); + setmodel (bubble, "progs/s_bubble.spr"); + setorigin (bubble, self.origin); + bubble.movetype = MOVETYPE_NOCLIP; + bubble.solid = SOLID_NOT; + bubble.velocity = self.velocity; + bubble.nextthink = time + 0.5; + bubble.think = bubble_bob; + bubble.touch = bubble_remove; + bubble.classname = "bubble"; + bubble.frame = 1; + bubble.cnt = 10; + setsize (bubble, '-8 -8 -8', '8 8 8'); + self.frame = 1; + self.cnt = 10; + if (self.waterlevel != 3) + remove (self); +}; + +void() bubble_remove = +{ + if (other.classname == self.classname) + { +// dprint ("bump"); + return; + } + remove(self); +}; + +void() bubble_bob = +{ +local float rnd1, rnd2, rnd3; + + self.cnt = self.cnt + 1; + if (self.cnt == 4) + bubble_split(); + if (self.cnt == 20) + remove(self); + + rnd1 = self.velocity_x + (-10 + (random() * 20)); + rnd2 = self.velocity_y + (-10 + (random() * 20)); + rnd3 = self.velocity_z + 10 + random() * 10; + + if (rnd1 > 10) + rnd1 = 5; + if (rnd1 < -10) + rnd1 = -5; + + if (rnd2 > 10) + rnd2 = 5; + if (rnd2 < -10) + rnd2 = -5; + + if (rnd3 < 10) + rnd3 = 15; + if (rnd3 > 30) + rnd3 = 25; + + self.velocity_x = rnd1; + self.velocity_y = rnd2; + self.velocity_z = rnd3; + + self.nextthink = time + 0.5; + self.think = bubble_bob; +}; + +/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~> +~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/ + +/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8) + +Just for the debugging level. Don't use +*/ + +void() viewthing = + +{ + self.movetype = MOVETYPE_NONE; + self.solid = SOLID_NOT; + precache_model ("progs/player.mdl"); + setmodel (self, "progs/player.mdl"); +}; + + +/* +============================================================================== + +SIMPLE BMODELS + +============================================================================== +*/ + +void() func_wall_use = +{ // change to alternate textures + self.frame = 1 - self.frame; +}; + +/*QUAKED func_wall (0 .5 .8) ? +This is just a solid wall if not inhibitted +*/ +void() func_wall = +{ + self.angles = '0 0 0'; + self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything + self.solid = SOLID_BSP; + self.use = func_wall_use; + setmodel (self, self.model); +}; + + +/*QUAKED func_illusionary (0 .5 .8) ? +A simple entity that looks solid but lets you walk through it. +*/ +void() func_illusionary = + +{ + self.angles = '0 0 0'; + self.movetype = MOVETYPE_NONE; + self.solid = SOLID_NOT; + setmodel (self, self.model); + makestatic (self); +}; + +/*QUAKED func_episodegate (0 .5 .8) ? E1 E2 E3 E4 +This bmodel will appear if the episode has allready been completed, so players can't reenter it. +*/ +void() func_episodegate = + +{ + if (!(serverflags & self.spawnflags)) + return; // can still enter episode + + self.angles = '0 0 0'; + self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything + self.solid = SOLID_BSP; + self.use = func_wall_use; + setmodel (self, self.model); +}; + +/*QUAKED func_bossgate (0 .5 .8) ? +This bmodel appears unless players have all of the episode sigils. +*/ +void() func_bossgate = + +{ + if ( (serverflags & 15) == 15) + return; // all episodes completed + self.angles = '0 0 0'; + self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything + self.solid = SOLID_BSP; + self.use = func_wall_use; + setmodel (self, self.model); +}; + +//============================================================================ +/*QUAKED ambient_suck_wind (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_suck_wind = +{ + precache_sound ("ambience/suck1.wav"); + ambientsound (self.origin, "ambience/suck1.wav", 1, ATTN_STATIC); +}; + +/*QUAKED ambient_drone (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_drone = +{ + precache_sound ("ambience/drone6.wav"); + ambientsound (self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED ambient_flouro_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_flouro_buzz = +{ + precache_sound ("ambience/buzz1.wav"); + ambientsound (self.origin, "ambience/buzz1.wav", 1, ATTN_STATIC); +}; +/*QUAKED ambient_drip (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_drip = +{ + precache_sound ("ambience/drip1.wav"); + ambientsound (self.origin, "ambience/drip1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_comp_hum (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_comp_hum = +{ + precache_sound ("ambience/comp1.wav"); + ambientsound (self.origin, "ambience/comp1.wav", 1, ATTN_STATIC); +}; +/*QUAKED ambient_thunder (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_thunder = +{ + precache_sound ("ambience/thunder1.wav"); + ambientsound (self.origin, "ambience/thunder1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_light_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_light_buzz = +{ + precache_sound ("ambience/fl_hum1.wav"); + ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_swamp1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_swamp1 = +{ + precache_sound ("ambience/swamp1.wav"); + ambientsound (self.origin, "ambience/swamp1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_swamp2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_swamp2 = +{ + precache_sound ("ambience/swamp2.wav"); + ambientsound (self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC); +}; + +//============================================================================ + +void() noise_think = +{ + self.nextthink = time + 0.5; + sound (self, 1, "enforcer/enfire.wav", 1, ATTN_NORM); + sound (self, 2, "enforcer/enfstop.wav", 1, ATTN_NORM); + sound (self, 3, "enforcer/sight1.wav", 1, ATTN_NORM); + sound (self, 4, "enforcer/sight2.wav", 1, ATTN_NORM); + sound (self, 5, "enforcer/sight3.wav", 1, ATTN_NORM); + sound (self, 6, "enforcer/sight4.wav", 1, ATTN_NORM); + sound (self, 7, "enforcer/pain1.wav", 1, ATTN_NORM); +}; + +/*QUAKED misc_noisemaker (1 0.5 0) (-10 -10 -10) (10 10 10) + +For optimzation testing, starts a lot of sounds. +*/ + +void() misc_noisemaker = + +{ + precache_sound2 ("enforcer/enfire.wav"); + precache_sound2 ("enforcer/enfstop.wav"); + precache_sound2 ("enforcer/sight1.wav"); + precache_sound2 ("enforcer/sight2.wav"); + precache_sound2 ("enforcer/sight3.wav"); + precache_sound2 ("enforcer/sight4.wav"); + precache_sound2 ("enforcer/pain1.wav"); + precache_sound2 ("enforcer/pain2.wav"); + precache_sound2 ("enforcer/death1.wav"); + precache_sound2 ("enforcer/idle1.wav"); + + self.nextthink = time + 0.1 + random(); + self.think = noise_think; +}; + +void() misc_model = +{ + precache_model( self.model ); + setmodel( self, self.model ); + setorigin( self, self.origin ); + + self.movetype = MOVETYPE_NONE; + self.solid = SOLID_BBOX; + setsize(self, '-8 -8 -8', '8 8 8'); +}; + +/* +============================== + +These are The props for Mapping. They require A special Size, So they must be An actual Function. + +============================== +*/ + +void() misc_deadtree = +{ +self.solid = SOLID_BBOX; +self.movetype = MOVETYPE_NONE; +self.classname = "deadtree"; +precache_model ("progs/deadtree.mdl"); +setmodel (self, "progs/deadtree.mdl"); +setsize (self, '-18 -18 0', '18 18 100'); +}; + +void() misc_deadtree2 = +{ +self.solid = SOLID_BBOX; +self.movetype = MOVETYPE_NONE; +self.classname = "deadtree2"; +precache_model ("progs/deadtree2.mdl"); +setmodel (self, "progs/deadtree2.mdl"); +setsize (self, '-18 -18 0', '18 18 100'); +}; +void() misc_boulder = +{ +self.solid = SOLID_BBOX; +self.movetype = MOVETYPE_NONE; +self.classname = "Boulder"; +precache_model ("progs/boulder.mdl"); +setmodel (self, "progs/boulder.mdl"); +setsize (self, '-30 -30 0', '30 30 34'); +}; +void() misc_boulder2 = +{ +self.solid = SOLID_BBOX; +self.movetype = MOVETYPE_NONE; +self.classname = "Boulder"; +precache_model ("progs/boulder2.mdl"); +setmodel (self, "progs/boulder2.mdl"); +setsize (self, '-30 -30 0', '30 30 34'); +} \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/models.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/models.qc new file mode 100755 index 00000000..70e273c4 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/models.qc @@ -0,0 +1,585 @@ + +/* +=============================================================================== + +WORLD WEAPONS + +=============================================================================== +*/ + +$modelname g_shot +$cd id1/models/g_shot +$origin 0 0 -24 +$flags 8 // client side rotate +$base base +$skin skin +$frame shot1 + + +$modelname g_nail +$cd id1/models/g_nail +$flags 8 // client side rotate +$origin 0 0 -24 +$base base +$skin skin +$frame shot1 + + +$modelname g_nail2 +$cd id1/models/g_nail2 +$flags 8 // client side rotate +$origin 0 0 -24 +$base base +$skin skin +$frame shot2 + + +$modelname g_rock +$cd id1/models/g_rock +$flags 8 // client side rotate +$origin 0 0 -24 +$base base +$skin skin +$frame shot1 + + +$modelname g_rock2 +$cd id1/models/g_rock2 +$flags 8 // client side rotate +$origin 0 0 -24 +$base base +$skin skin +$frame shot1 + +$modelname g_light +$cd id1/models/g_light +$flags 8 // client side rotate +$origin 0 0 -24 +$base base +$skin skin +$frame shot1 + +/* +=============================================================================== + +VIEW WEAPONS + +=============================================================================== +*/ + +$modelname v_axe +$cd id1/models/v_axe +$origin 0 5 54 +$base base +$skin skin +$frame frame1 frame2 frame3 frame4 frame5 frame6 frame7 frame8 frame9 + + +$modelname v_shot +$cd id1/models/v_shot +$origin 0 0 54 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 + + +$modelname v_shot2 +$cd id1/models/v_shot2 +$origin 0 0 56 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 + + +$modelname v_rock2 +$cd id1/models/v_rock2 +$origin 0 0 54 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 shot6 shot6 + + +$modelname v_rock +$cd id1/models/v_rock +$origin 0 0 54 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 + + +$modelname v_nail2 +$cd id1/models/v_nail2 +$origin 0 0 54 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 shot8 shot9 + + +$modelname v_nail +$cd id1/models/v_nail +$origin 0 0 54 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 shot8 shot9 + +$modelname v_light +$cd id1/models/v_light +$origin 0 0 54 +$base base +$skin skin +$frame shot1 shot2 shot3 shot4 shot5 + + +/* +=============================================================================== + +ITEMS + +=============================================================================== +*/ + +$modelname w_g_key +$cd id1/models/w_g_key +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname w_s_key +$cd id1/models/w_s_key +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname m_g_key +$cd id1/models/m_g_key +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname m_s_key +$cd id1/models/m_s_key +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname b_g_key +$cd id1/models/b_g_key +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname b_s_key +$cd id1/models/b_s_key +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + + +$modelname quaddama +$cd id1/models/quaddama +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname invisibl +$cd id1/models/invisibl +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname invulner +$flags 8 // client side rotate +$cd id1/models/invulner +$base base +$skin skin +$frame frame1 + +//modelname jetpack +//cd id1/models/jetpack +//flags 8 // client side rotate +//base base +//skin skin +//frame frame1 + +$modelname cube +$cd id1/models/cube +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname suit +$cd id1/models/suit +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname boots +$cd id1/models/boots +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname end1 +$cd id1/models/end1 +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname end2 +$cd id1/models/end2 +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname end3 +$cd id1/models/end3 +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + +$modelname end4 +$cd id1/models/end4 +$flags 8 // client side rotate +$base base +$skin skin +$frame frame1 + + +/* +=============================================================================== + +GIBS + +=============================================================================== +*/ + +$modelname gib1 +$cd id1/models/gib1 +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + + +// torso +$modelname gib2 +$cd id1/models/gib2 +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname gib3 +$cd id1/models/gib3 +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + + +// heads + +$modelname h_player +$cd id1/models/h_player +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_dog +$cd id1/models/h_dog +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_mega +$cd id1/models/h_mega +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_guard +$cd id1/models/h_guard +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_wizard +$cd id1/models/h_wizard +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_knight +$cd id1/models/h_knight +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_hellkn +$cd id1/models/h_hellkn +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_zombie +$cd id1/models/h_zombie +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_shams +$cd id1/models/h_shams +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_shal +$cd id1/models/h_shal +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_ogre +$cd id1/models/h_ogre +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname h_demon +$cd id1/models/h_demon +$flags 4 // EF_GIB +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +/* +=============================================================================== + +MISC + +=============================================================================== +*/ + +$modelname armor +$cd id1/models/armor +$flags 8 // client side rotate +$origin 0 0 -8 +$base base +$skin skin +$skin skin2 +$skin skin3 +$frame armor + +$modelname s_light // shambler lightning ready +$cd id1/models/s_light +$origin 0 0 24 +$base base +$skin skin +$frame frame1 frame2 frame3 + +$modelname bolt3 // lightning towar bolts +$cd id1/models/bolt2 +$origin 0 0 0 +$base base +$scale 4 +$skin skin +$frame light + +$modelname bolt2 +$cd id1/models/bolt2 +$origin 0 0 0 +$base base +$skin skin +$frame light + +$modelname bolt +$cd id1/models/bolt +$origin 0 0 0 +$base light +$skin light +$frame light + +$modelname laser +$cd id1/models/laser +$base base +$skin skin +$scale 2 +$frame frame1 + +$modelname flame // with torch +$cd id1/models/flame +$origin 0 0 12 +$base base +$skin skin +$framegroupstart +$frame flame1 0.1 +$frame flame2 0.1 +$frame flame3 0.1 +$frame flame4 0.1 +$frame flame5 0.1 +$frame flame6 0.1 +$framegroupend + +$modelname flame2 // standing flame, no torch +$cd id1/models/flame2 +$origin 0 0 12 +$base base +$skin skin +$framegroupstart +$frame flame1 0.1 +$frame flame2 0.1 +$frame flame3 0.1 +$frame flame4 0.1 +$frame flame5 0.1 +$frame flame6 0.1 +$framegroupend +$framegroupstart +$frame flameb1 +$frame flameb2 +$frame flameb3 +$frame flameb4 +$frame flameb5 +$frame flameb6 +$frame flameb7 +$frame flameb8 +$frame flameb9 +$frame flameb10 +$frame flameb11 +$framegroupend + +$modelname zom_gib +$cd id1/models/zom_gib +$flags 32 // EF_ZOMGIB +$base base +$skin skin +$frame frame1 + +$modelname eyes +$cd id1/models/eyes +$origin 0 0 -24 +$base base +$skin skin +$frame frame1 + +$modelname spike +$cd id1/models/spike +$origin 0 0 0 +$base spike +$skin skin +$frame spike + +$modelname s_spike +$cd id1/models/s_spike +$origin 0 0 0 +$base spike +$skin skin +$frame spike + +$modelname v_spike +$cd id1/models/v_spike +$flags 128 // EF_TRACER3 +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname w_spike +$cd id1/models/w_spike +$flags 16 // EF_TRACER +$origin 0 0 0 +$base base +$skin skin +$framegroupstart +$frame frame1 0.1 +$frame frame2 0.1 +$frame frame3 0.1 +$frame frame4 0.1 +$framegroupend + +$modelname k_spike +$cd id1/models/k_spike +$flags 64 // EF_TRACER2 +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname backpack +$cd id1/models/backpack +$flags 8 // EF_ROTATE +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname grenade +$cd id1/models/grenade2 +$flags 2 // EF_GRENADE +$origin 0 0 0 +$base base +$skin skin +$frame grenade + +$modelname missile +$cd id1/models/missile +$flags 1 // EF_ROCKET +$origin 0 0 0 +$base base +$skin skin +$frame missile + +$modelname lavaball +$cd id1/models/lavaball +$flags 1 // EF_ROCKET +$origin 0 0 0 +$base base +$skin skin +$frame frame1 + +$modelname teleport +$cd id1/models/teleport +$origin 0 0 24 +$base base +$skin skin +$frame frame1 + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/monsters.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/monsters.qc new file mode 100755 index 00000000..0140dac1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/monsters.qc differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/ogre.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/ogre.qc new file mode 100755 index 00000000..76993c18 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/ogre.qc @@ -0,0 +1,452 @@ +/* +============================================================================== + +OGRE + +============================================================================== +*/ + +$cd id1/models/ogre_c +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 +$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7 +$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 +$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14 + +$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame painb1 painb2 painb3 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10 +$frame paind11 paind12 paind13 paind14 paind15 paind16 + +$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10 +$frame paine11 paine12 paine13 paine14 paine15 + +$frame death1 death2 death3 death4 death5 death6 +$frame death7 death8 death9 death10 death11 death12 +$frame death13 death14 + +$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6 +$frame bdeath7 bdeath8 bdeath9 bdeath10 + +$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11 + +//============================================================================= + + +void() OgreGrenadeExplode = +{ + T_RadiusDamage (self, self.owner, 40, world); + sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM); + + 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); + + self.velocity = '0 0 0'; + self.touch = SUB_Null; + setmodel (self, "progs/s_explod.spr"); + self.solid = SOLID_NOT; + s_explode1 (); +}; + +void() OgreGrenadeTouch = +{ + if (other == self.owner) + return; // don't explode on owner + if (other.takedamage == DAMAGE_AIM) + { + OgreGrenadeExplode(); + return; + } + sound (self, CHAN_VOICE, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound + if (self.velocity == '0 0 0') + self.avelocity = '0 0 0'; +}; + +/* +================ +OgreFireGrenade +================ +*/ +void() OgreFireGrenade = +{ + local entity missile; + + self.effects = self.effects | EF_MUZZLEFLASH; + + sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM); + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_BOUNCE; + missile.solid = SOLID_BBOX; + +// set missile speed + + makevectors (self.angles); + + missile.velocity = normalize(self.enemy.origin - self.origin); + missile.velocity = missile.velocity * 600; + missile.velocity_z = 200; + + missile.avelocity = '300 300 300'; + + missile.angles = vectoangles(missile.velocity); + + missile.touch = OgreGrenadeTouch; + +// set missile duration + missile.nextthink = time + 2.5; + missile.think = OgreGrenadeExplode; + + setmodel (missile, "progs/grenade.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin); +}; + + +//============================================================================= + +/* +================ +chainsaw + +FIXME +================ +*/ +void(float side) chainsaw = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + if (!CanDamage (self.enemy, self)) + return; + + ai_charge(10); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + ldmg = (random() + random() + random()) * 4; + T_Damage (self.enemy, self, self, ldmg); + +}; + + +void() ogre_stand1 =[ $stand1, ogre_stand2 ] {ai_stand();}; +void() ogre_stand2 =[ $stand2, ogre_stand3 ] {ai_stand();}; +void() ogre_stand3 =[ $stand3, ogre_stand4 ] {ai_stand();}; +void() ogre_stand4 =[ $stand4, ogre_stand5 ] {ai_stand();}; +void() ogre_stand5 =[ $stand5, ogre_stand6 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE); +ai_stand(); +}; +void() ogre_stand6 =[ $stand6, ogre_stand7 ] {ai_stand();}; +void() ogre_stand7 =[ $stand7, ogre_stand8 ] {ai_stand();}; +void() ogre_stand8 =[ $stand8, ogre_stand9 ] {ai_stand();}; +void() ogre_stand9 =[ $stand9, ogre_stand1 ] {ai_stand();}; + +void() ogre_walk1 =[ $walk1, ogre_walk2 ] {ai_walk(3);}; +void() ogre_walk2 =[ $walk2, ogre_walk3 ] {ai_walk(2);}; +void() ogre_walk3 =[ $walk3, ogre_walk4 ] { +ai_walk(2); +if (random() < 0.2) + sound (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE); +}; +void() ogre_walk4 =[ $walk4, ogre_walk5 ] {ai_walk(2);}; +void() ogre_walk5 =[ $walk5, ogre_walk6 ] {ai_walk(2);}; +void() ogre_walk6 =[ $walk6, ogre_walk7 ] { +ai_walk(5); +if (random() < 0.1) + sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE); +}; +void() ogre_walk7 =[ $walk7, ogre_walk8 ] {ai_walk(3);}; +void() ogre_walk8 =[ $walk8, ogre_walk9 ] {ai_walk(2);}; +void() ogre_walk9 =[ $walk9, ogre_walk10 ] {ai_walk(3);}; +void() ogre_walk10 =[ $walk10, ogre_walk11 ] {ai_walk(1);}; +void() ogre_walk11 =[ $walk11, ogre_walk12 ] {ai_walk(2);}; +void() ogre_walk12 =[ $walk12, ogre_walk13 ] {ai_walk(3);}; +void() ogre_walk13 =[ $walk13, ogre_walk14 ] {ai_walk(3);}; +void() ogre_walk14 =[ $walk14, ogre_walk15 ] {ai_walk(3);}; +void() ogre_walk15 =[ $walk15, ogre_walk16 ] {ai_walk(3);}; +void() ogre_walk16 =[ $walk16, ogre_walk1 ] {ai_walk(4);}; + +void() ogre_run1 =[ $run1, ogre_run2 ] {ai_run(9); +if (random() < 0.2) + sound (self, CHAN_VOICE, "ogre/ogidle2.wav", 1, ATTN_IDLE); +}; +void() ogre_run2 =[ $run2, ogre_run3 ] {ai_run(12);}; +void() ogre_run3 =[ $run3, ogre_run4 ] {ai_run(8);}; +void() ogre_run4 =[ $run4, ogre_run5 ] {ai_run(22);}; +void() ogre_run5 =[ $run5, ogre_run6 ] {ai_run(16);}; +void() ogre_run6 =[ $run6, ogre_run7 ] {ai_run(4);}; +void() ogre_run7 =[ $run7, ogre_run8 ] {ai_run(13);}; +void() ogre_run8 =[ $run8, ogre_run1 ] {ai_run(24);}; + +void() ogre_swing1 =[ $swing1, ogre_swing2 ] {ai_charge(11); +sound (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM); +}; +void() ogre_swing2 =[ $swing2, ogre_swing3 ] {ai_charge(1);}; +void() ogre_swing3 =[ $swing3, ogre_swing4 ] {ai_charge(4);}; +void() ogre_swing4 =[ $swing4, ogre_swing5 ] {ai_charge(13);}; +void() ogre_swing5 =[ $swing5, ogre_swing6 ] {ai_charge(9); chainsaw(0);self.angles_y = self.angles_y + random()*25;}; +void() ogre_swing6 =[ $swing6, ogre_swing7 ] {chainsaw(200);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing7 =[ $swing7, ogre_swing8 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing8 =[ $swing8, ogre_swing9 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing9 =[ $swing9, ogre_swing10 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing10 =[ $swing10, ogre_swing11 ] {chainsaw(-200);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing11 =[ $swing11, ogre_swing12 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing12 =[ $swing12, ogre_swing13 ] {ai_charge(3);}; +void() ogre_swing13 =[ $swing13, ogre_swing14 ] {ai_charge(8);}; +void() ogre_swing14 =[ $swing14, ogre_run1 ] {ai_charge(9);}; + +void() ogre_smash1 =[ $smash1, ogre_smash2 ] {ai_charge(6); +sound (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM); +}; +void() ogre_smash2 =[ $smash2, ogre_smash3 ] {ai_charge(0);}; +void() ogre_smash3 =[ $smash3, ogre_smash4 ] {ai_charge(0);}; +void() ogre_smash4 =[ $smash4, ogre_smash5 ] {ai_charge(1);}; +void() ogre_smash5 =[ $smash5, ogre_smash6 ] {ai_charge(4);}; +void() ogre_smash6 =[ $smash6, ogre_smash7 ] {ai_charge(4); chainsaw(0);}; +void() ogre_smash7 =[ $smash7, ogre_smash8 ] {ai_charge(4); chainsaw(0);}; +void() ogre_smash8 =[ $smash8, ogre_smash9 ] {ai_charge(10); chainsaw(0);}; +void() ogre_smash9 =[ $smash9, ogre_smash10 ] {ai_charge(13); chainsaw(0);}; +void() ogre_smash10 =[ $smash10, ogre_smash11 ] {chainsaw(1);}; +void() ogre_smash11 =[ $smash11, ogre_smash12 ] {ai_charge(2); chainsaw(0); +self.nextthink = self.nextthink + random()*0.2;}; // slight variation +void() ogre_smash12 =[ $smash12, ogre_smash13 ] {ai_charge(0);}; +void() ogre_smash13 =[ $smash13, ogre_smash14 ] {ai_charge(4);}; +void() ogre_smash14 =[ $smash14, ogre_run1 ] {ai_charge(12);}; + +void() ogre_nail1 =[ $shoot1, ogre_nail2 ] {ai_face();}; +void() ogre_nail2 =[ $shoot2, ogre_nail3 ] {ai_face();}; +void() ogre_nail3 =[ $shoot2, ogre_nail4 ] {ai_face();}; +void() ogre_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();OgreFireGrenade();}; +void() ogre_nail5 =[ $shoot4, ogre_nail6 ] {ai_face();}; +void() ogre_nail6 =[ $shoot5, ogre_nail7 ] {ai_face();}; +void() ogre_nail7 =[ $shoot6, ogre_run1 ] {ai_face();}; + +void() ogre_pain1 =[ $pain1, ogre_pain2 ] {}; +void() ogre_pain2 =[ $pain2, ogre_pain3 ] {}; +void() ogre_pain3 =[ $pain3, ogre_pain4 ] {}; +void() ogre_pain4 =[ $pain4, ogre_pain5 ] {}; +void() ogre_pain5 =[ $pain5, ogre_run1 ] {}; + + +void() ogre_painb1 =[ $painb1, ogre_painb2 ] {}; +void() ogre_painb2 =[ $painb2, ogre_painb3 ] {}; +void() ogre_painb3 =[ $painb3, ogre_run1 ] {}; + + +void() ogre_painc1 =[ $painc1, ogre_painc2 ] {}; +void() ogre_painc2 =[ $painc2, ogre_painc3 ] {}; +void() ogre_painc3 =[ $painc3, ogre_painc4 ] {}; +void() ogre_painc4 =[ $painc4, ogre_painc5 ] {}; +void() ogre_painc5 =[ $painc5, ogre_painc6 ] {}; +void() ogre_painc6 =[ $painc6, ogre_run1 ] {}; + + +void() ogre_paind1 =[ $paind1, ogre_paind2 ] {}; +void() ogre_paind2 =[ $paind2, ogre_paind3 ] {ai_pain(10);}; +void() ogre_paind3 =[ $paind3, ogre_paind4 ] {ai_pain(9);}; +void() ogre_paind4 =[ $paind4, ogre_paind5 ] {ai_pain(4);}; +void() ogre_paind5 =[ $paind5, ogre_paind6 ] {}; +void() ogre_paind6 =[ $paind6, ogre_paind7 ] {}; +void() ogre_paind7 =[ $paind7, ogre_paind8 ] {}; +void() ogre_paind8 =[ $paind8, ogre_paind9 ] {}; +void() ogre_paind9 =[ $paind9, ogre_paind10 ] {}; +void() ogre_paind10=[ $paind10, ogre_paind11 ] {}; +void() ogre_paind11=[ $paind11, ogre_paind12 ] {}; +void() ogre_paind12=[ $paind12, ogre_paind13 ] {}; +void() ogre_paind13=[ $paind13, ogre_paind14 ] {}; +void() ogre_paind14=[ $paind14, ogre_paind15 ] {}; +void() ogre_paind15=[ $paind15, ogre_paind16 ] {}; +void() ogre_paind16=[ $paind16, ogre_run1 ] {}; + +void() ogre_paine1 =[ $paine1, ogre_paine2 ] {}; +void() ogre_paine2 =[ $paine2, ogre_paine3 ] {ai_pain(10);}; +void() ogre_paine3 =[ $paine3, ogre_paine4 ] {ai_pain(9);}; +void() ogre_paine4 =[ $paine4, ogre_paine5 ] {ai_pain(4);}; +void() ogre_paine5 =[ $paine5, ogre_paine6 ] {}; +void() ogre_paine6 =[ $paine6, ogre_paine7 ] {}; +void() ogre_paine7 =[ $paine7, ogre_paine8 ] {}; +void() ogre_paine8 =[ $paine8, ogre_paine9 ] {}; +void() ogre_paine9 =[ $paine9, ogre_paine10 ] {}; +void() ogre_paine10=[ $paine10, ogre_paine11 ] {}; +void() ogre_paine11=[ $paine11, ogre_paine12 ] {}; +void() ogre_paine12=[ $paine12, ogre_paine13 ] {}; +void() ogre_paine13=[ $paine13, ogre_paine14 ] {}; +void() ogre_paine14=[ $paine14, ogre_paine15 ] {}; +void() ogre_paine15=[ $paine15, ogre_run1 ] {}; + + +void(entity attacker, float damage) ogre_pain = +{ + local float r; + +// don't make multiple pain sounds right after each other + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "ogre/ogpain1.wav", 1, ATTN_NORM); + + r = random(); + + if (r < 0.25) + { + ogre_pain1 (); + self.pain_finished = time + 1; + } + else if (r < 0.5) + { + ogre_painb1 (); + self.pain_finished = time + 1; + } + else if (r < 0.75) + { + ogre_painc1 (); + self.pain_finished = time + 1; + } + else if (r < 0.88) + { + ogre_paind1 (); + self.pain_finished = time + 2; + } + else + { + ogre_paine1 (); + self.pain_finished = time + 2; + } +}; + +void() ogre_die1 =[ $death1, ogre_die2 ] {}; +void() ogre_die2 =[ $death2, ogre_die3 ] {}; +void() ogre_die3 =[ $death3, ogre_die4 ] +{self.solid = SOLID_NOT; +self.ammo_rockets = 2;DropBackpack();}; +void() ogre_die4 =[ $death4, ogre_die5 ] {}; +void() ogre_die5 =[ $death5, ogre_die6 ] {}; +void() ogre_die6 =[ $death6, ogre_die7 ] {}; +void() ogre_die7 =[ $death7, ogre_die8 ] {}; +void() ogre_die8 =[ $death8, ogre_die9 ] {}; +void() ogre_die9 =[ $death9, ogre_die10 ] {}; +void() ogre_die10 =[ $death10, ogre_die11 ] {}; +void() ogre_die11 =[ $death11, ogre_die12 ] {}; +void() ogre_die12 =[ $death12, ogre_die13 ] {}; +void() ogre_die13 =[ $death13, ogre_die14 ] {}; +void() ogre_die14 =[ $death14, ogre_die14 ] {}; + +void() ogre_bdie1 =[ $bdeath1, ogre_bdie2 ] {}; +void() ogre_bdie2 =[ $bdeath2, ogre_bdie3 ] {ai_forward(5);}; +void() ogre_bdie3 =[ $bdeath3, ogre_bdie4 ] +{self.solid = SOLID_NOT; +self.ammo_rockets = 2;DropBackpack();}; +void() ogre_bdie4 =[ $bdeath4, ogre_bdie5 ] {ai_forward(1);}; +void() ogre_bdie5 =[ $bdeath5, ogre_bdie6 ] {ai_forward(3);}; +void() ogre_bdie6 =[ $bdeath6, ogre_bdie7 ] {ai_forward(7);}; +void() ogre_bdie7 =[ $bdeath7, ogre_bdie8 ] {ai_forward(25);}; +void() ogre_bdie8 =[ $bdeath8, ogre_bdie9 ] {}; +void() ogre_bdie9 =[ $bdeath9, ogre_bdie10 ] {}; +void() ogre_bdie10 =[ $bdeath10, ogre_bdie10 ] {}; + +void() ogre_die = +{ +// check for gib + if (self.health < -80) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_ogre.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + + sound (self, CHAN_VOICE, "ogre/ogdth.wav", 1, ATTN_NORM); + + if (random() < 0.5) + ogre_die1 (); + else + ogre_bdie1 (); +}; + +void() ogre_melee = +{ + if (random() > 0.5) + ogre_smash1 (); + else + ogre_swing1 (); +}; + + +/*QUAKED monster_ogre (1 0 0) (-32 -32 -24) (32 32 64) Ambush + +*/ +void() monster_ogre = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/ogre.mdl"); + precache_model ("progs/h_ogre.mdl"); + precache_model ("progs/grenade.mdl"); + + precache_sound ("ogre/ogdrag.wav"); + precache_sound ("ogre/ogdth.wav"); + precache_sound ("ogre/ogidle.wav"); + precache_sound ("ogre/ogidle2.wav"); + precache_sound ("ogre/ogpain1.wav"); + precache_sound ("ogre/ogsawatk.wav"); + precache_sound ("ogre/ogwake.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/ogre.mdl"); + + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 200; + + self.th_stand = ogre_stand1; + self.th_walk = ogre_walk1; + self.th_run = ogre_run1; + self.th_die = ogre_die; + self.th_melee = ogre_melee; + self.th_missile = ogre_nail1; + self.th_pain = ogre_pain; + + walkmonster_start(); +}; + +void() monster_ogre_marksman = +{ + monster_ogre (); +}; + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/oldone.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/oldone.qc new file mode 100755 index 00000000..103d6fb2 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/oldone.qc @@ -0,0 +1,283 @@ +/* +============================================================================== + +OLD ONE + +============================================================================== +*/ +$cd id1/models/old_one +$origin 0 0 24 +$base base +$skin skin +$scale 1 + +void() finale_1; +void() finale_2; +void() finale_3; +void() finale_4; + + +entity shub; + +$frame old1 old2 old3 old4 old5 old6 old7 old8 old9 +$frame old10 old11 old12 old13 old14 old15 old16 old17 old18 old19 +$frame old20 old21 old22 old23 old24 old25 old26 old27 old28 old29 +$frame old30 old31 old32 old33 old34 old35 old36 old37 old38 old39 +$frame old40 old41 old42 old43 old44 old45 old46 + +$frame shake1 shake2 shake3 shake4 shake5 shake6 shake7 shake8 +$frame shake9 shake10 shake11 shake12 shake12 shake13 shake14 +$frame shake15 shake16 shake17 shake18 shake19 shake20 + +//void() old_stand =[ $old1, old_stand ] {}; + +void() old_idle1 =[ $old1, old_idle2 ] {}; +void() old_idle2 =[ $old2, old_idle3 ] {}; +void() old_idle3 =[ $old3, old_idle4 ] {}; +void() old_idle4 =[ $old4, old_idle5 ] {}; +void() old_idle5 =[ $old5, old_idle6 ] {}; +void() old_idle6 =[ $old6, old_idle7 ] {}; +void() old_idle7 =[ $old7, old_idle8 ] {}; +void() old_idle8 =[ $old8, old_idle9 ] {}; +void() old_idle9 =[ $old9, old_idle10 ] {}; +void() old_idle10 =[ $old10, old_idle11 ] {}; +void() old_idle11 =[ $old11, old_idle12 ] {}; +void() old_idle12 =[ $old12, old_idle13 ] {}; +void() old_idle13 =[ $old13, old_idle14 ] {}; +void() old_idle14 =[ $old14, old_idle15 ] {}; +void() old_idle15 =[ $old15, old_idle16 ] {}; +void() old_idle16 =[ $old16, old_idle17 ] {}; +void() old_idle17 =[ $old17, old_idle18 ] {}; +void() old_idle18 =[ $old18, old_idle19 ] {}; +void() old_idle19 =[ $old19, old_idle20 ] {}; +void() old_idle20 =[ $old20, old_idle21 ] {}; +void() old_idle21 =[ $old21, old_idle22 ] {}; +void() old_idle22 =[ $old22, old_idle23 ] {}; +void() old_idle23 =[ $old23, old_idle24 ] {}; +void() old_idle24 =[ $old24, old_idle25 ] {}; +void() old_idle25 =[ $old25, old_idle26 ] {}; +void() old_idle26 =[ $old26, old_idle27 ] {}; +void() old_idle27 =[ $old27, old_idle28 ] {}; +void() old_idle28 =[ $old28, old_idle29 ] {}; +void() old_idle29 =[ $old29, old_idle30 ] {}; +void() old_idle30 =[ $old30, old_idle31 ] {}; +void() old_idle31 =[ $old31, old_idle32 ] {}; +void() old_idle32 =[ $old32, old_idle33 ] {}; +void() old_idle33 =[ $old33, old_idle34 ] {}; +void() old_idle34 =[ $old34, old_idle35 ] {}; +void() old_idle35 =[ $old35, old_idle36 ] {}; +void() old_idle36 =[ $old36, old_idle37 ] {}; +void() old_idle37 =[ $old37, old_idle38 ] {}; +void() old_idle38 =[ $old38, old_idle39 ] {}; +void() old_idle39 =[ $old39, old_idle40 ] {}; +void() old_idle40 =[ $old40, old_idle41 ] {}; +void() old_idle41 =[ $old41, old_idle42 ] {}; +void() old_idle42 =[ $old42, old_idle43 ] {}; +void() old_idle43 =[ $old43, old_idle44 ] {}; +void() old_idle44 =[ $old44, old_idle45 ] {}; +void() old_idle45 =[ $old45, old_idle46 ] {}; +void() old_idle46 =[ $old46, old_idle1 ] {}; + + +void() old_thrash1 =[ $shake1, old_thrash2 ] {lightstyle(0, "m");}; +void() old_thrash2 =[ $shake2, old_thrash3 ] {lightstyle(0, "k");}; +void() old_thrash3 =[ $shake3, old_thrash4 ] {lightstyle(0, "k");}; +void() old_thrash4 =[ $shake4, old_thrash5 ] {lightstyle(0, "i");}; +void() old_thrash5 =[ $shake5, old_thrash6 ] {lightstyle(0, "g");}; +void() old_thrash6 =[ $shake6, old_thrash7 ] {lightstyle(0, "e");}; +void() old_thrash7 =[ $shake7, old_thrash8 ] {lightstyle(0, "c");}; +void() old_thrash8 =[ $shake8, old_thrash9 ] {lightstyle(0, "a");}; +void() old_thrash9 =[ $shake9, old_thrash10 ] {lightstyle(0, "c");}; +void() old_thrash10 =[ $shake10, old_thrash11 ] {lightstyle(0, "e");}; +void() old_thrash11 =[ $shake11, old_thrash12 ] {lightstyle(0, "g");}; +void() old_thrash12 =[ $shake12, old_thrash13 ] {lightstyle(0, "i");}; +void() old_thrash13 =[ $shake13, old_thrash14 ] {lightstyle(0, "k");}; +void() old_thrash14 =[ $shake14, old_thrash15 ] {lightstyle(0, "m");}; +void() old_thrash15 =[ $shake15, old_thrash16 ] {lightstyle(0, "m"); +self.cnt = self.cnt + 1; +if (self.cnt != 3) + self.think = old_thrash1; +}; +void() old_thrash16 =[ $shake16, old_thrash17 ] {lightstyle(0, "g");}; +void() old_thrash17 =[ $shake17, old_thrash18 ] {lightstyle(0, "c");}; +void() old_thrash18 =[ $shake18, old_thrash19 ] {lightstyle(0, "b");}; +void() old_thrash19 =[ $shake19, old_thrash20 ] {lightstyle(0, "a");}; +void() old_thrash20 =[ $shake20, old_thrash20 ] {finale_4();}; + +//============================================================================ + +void() finale_1 = +{ + local entity pos, pl; + local entity timer; + + intermission_exittime = time + 10000000; // never allow exit + intermission_running = 1; + + // find the intermission spot + pos = find (world, classname, "info_intermission"); + if (!pos) + error ("no info_intermission"); + pl = find (world, classname, "misc_teleporttrain"); + if (!pl) + error ("no teleporttrain"); + remove (pl); + + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, ""); + + pl = find (world, classname, "player"); + while (pl != world) + { + pl.view_ofs = '0 0 0'; + pl.angles = other.v_angle = pos.mangle; + pl.fixangle = TRUE; // turn this way immediately + pl.map = self.map; + pl.nextthink = time + 0.5; + pl.takedamage = DAMAGE_NO; + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NONE; + pl.modelindex = 0; + setorigin (pl, pos.origin); + pl = find (pl, classname, "player"); + } + + // make fake versions of all players as standins, and move the real + // players to the intermission spot + + // wait for 1 second + timer = spawn(); + timer.nextthink = time + 1; + timer.think = finale_2; +}; + +void() finale_2 = +{ + local vector o; + + // start a teleport splash inside shub + + o = shub.origin - '0 100 0'; + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_TELEPORT); + WriteCoord (MSG_BROADCAST, o_x); + WriteCoord (MSG_BROADCAST, o_y); + WriteCoord (MSG_BROADCAST, o_z); + + sound (shub, CHAN_VOICE, "misc/r_tele1.wav", 1, ATTN_NORM); + + self.nextthink = time + 2; + self.think = finale_3; +}; + +void() finale_3 = +{ + // start shub thrashing wildly + shub.think = old_thrash1; + sound (shub, CHAN_VOICE, "boss2/death.wav", 1, ATTN_NORM); + lightstyle(0, "abcdefghijklmlkjihgfedcb"); +}; + +void() finale_4 = +{ + // throw tons of meat chunks + local vector oldo; + local float x, y, z; + local float r; + local entity n; + + sound (self, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NORM); + + oldo = self.origin; + + z = 16; + while (z <= 144) + { + x = -64; + while (x <= 64) + { + y = -64; + while (y <= 64) + { + self.origin_x = oldo_x + x; + self.origin_y = oldo_y + y; + self.origin_z = oldo_z + z; + + r = random(); + if (r < 0.3) + ThrowGib ("progs/gib1.mdl", -999); + else if (r < 0.6) + ThrowGib ("progs/gib2.mdl", -999); + else + ThrowGib ("progs/gib3.mdl", -999); + y = y + 32; + } + x = x + 32; + } + z = z + 96; + } + // start the end text + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "Congratulations and well done! You have\nbeaten the hideous Shub-Niggurath, and\nher hundreds of ugly changelings and\nmonsters. You have proven that your\nskill and your cunning are greater than\nall the powers of Quake. You are the\nmaster now. Id Software salutes you."); + +// put a player model down + n = spawn(); + setmodel (n, "progs/player.mdl"); + oldo = oldo - '32 264 0'; + setorigin (n, oldo); + n.angles = '0 290 0'; + n.frame = 1; + + remove (self); + +// switch cd track + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 3); + WriteByte (MSG_ALL, 3); + lightstyle(0, "m"); +}; + +//============================================================================ + +void () nopain = +{ + self.health = 40000; +}; + +//============================================================================ + + +/*QUAKED monster_oldone (1 0 0) (-16 -16 -24) (16 16 32) +*/ +void() monster_oldone = +{ + if (deathmatch) + { + remove(self); + return; + } + + precache_model2 ("progs/oldone.mdl"); + + precache_sound2 ("boss2/death.wav"); + precache_sound2 ("boss2/idle.wav"); + precache_sound2 ("boss2/sight.wav"); + precache_sound2 ("boss2/pop2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/oldone.mdl"); + setsize (self, '-160 -128 -24', '160 128 256'); + + self.health = 40000; // kill by telefrag + self.think = old_idle1; + self.nextthink = time + 0.1; + self.takedamage = DAMAGE_YES; + self.th_pain = nopain; + self.th_die = finale_1; + shub = self; + + total_monsters = total_monsters + 1; +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/plats.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/plats.qc new file mode 100755 index 00000000..ffd7ae2c --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/plats.qc @@ -0,0 +1,362 @@ + + +void() plat_center_touch; +void() plat_outside_touch; +void() plat_trigger_use; +void() plat_go_up; +void() plat_go_down; +void() plat_crush; +float PLAT_LOW_TRIGGER = 1; + +void() plat_spawn_inside_trigger = +{ + local entity trigger; + local vector tmin, tmax; + +// +// middle trigger +// + trigger = spawn(); + trigger.touch = plat_center_touch; + trigger.movetype = MOVETYPE_NONE; + trigger.solid = SOLID_TRIGGER; + trigger.enemy = self; + + tmin = self.mins + '25 25 0'; + tmax = self.maxs - '25 25 -8'; + tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8); + if (self.spawnflags & PLAT_LOW_TRIGGER) + tmax_z = tmin_z + 8; + + if (self.size_x <= 50) + { + tmin_x = (self.mins_x + self.maxs_x) / 2; + tmax_x = tmin_x + 1; + } + if (self.size_y <= 50) + { + tmin_y = (self.mins_y + self.maxs_y) / 2; + tmax_y = tmin_y + 1; + } + + setsize (trigger, tmin, tmax); +}; + +void() plat_hit_top = +{ + sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_TOP; + self.think = plat_go_down; + self.nextthink = self.ltime + 3; +}; + +void() plat_hit_bottom = +{ + sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_BOTTOM; +}; + +void() plat_go_down = +{ + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + self.state = STATE_DOWN; + SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom); +}; + +void() plat_go_up = +{ + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + self.state = STATE_UP; + SUB_CalcMove (self.pos1, self.speed, plat_hit_top); +}; + +void() plat_center_touch = +{ + if (other.classname != "player") + return; + + if (other.health <= 0) + return; + + self = self.enemy; + if (self.state == STATE_BOTTOM) + plat_go_up (); + else if (self.state == STATE_TOP) + self.nextthink = self.ltime + 1; // delay going down +}; + +void() plat_outside_touch = +{ + if (other.classname != "player") + return; + + if (other.health <= 0) + return; + +//dprint ("plat_outside_touch\n"); + self = self.enemy; + if (self.state == STATE_TOP) + plat_go_down (); +}; + +void() plat_trigger_use = +{ + if (self.think) + return; // allready activated + plat_go_down(); +}; + + +void() plat_crush = +{ +//dprint ("plat_crush\n"); + + T_Damage (other, self, self, 1); + + if (self.state == STATE_UP) + plat_go_down (); + else if (self.state == STATE_DOWN) + plat_go_up (); + else + objerror ("plat_crush: bad self.state\n"); +}; + +void() plat_use = +{ + self.use = SUB_Null; + if (self.state != STATE_UP) + objerror ("plat_use: not in up state"); + plat_go_down(); +}; + + +/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER +speed default 150 + +Plats are always drawn in the extended position, so they will light correctly. + +If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat. + +If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height. +Set "sounds" to one of the following: +1) base fast +2) chain slow +*/ + + +void() func_plat = + +{ + if (!self.t_length) + self.t_length = 80; + if (!self.t_width) + self.t_width = 10; + + if (self.sounds == 0) + self.sounds = 2; +// FIX THIS TO LOAD A GENERIC PLAT SOUND + + if (self.sounds == 1) + { + precache_sound ("plats/plat1.wav"); + precache_sound ("plats/plat2.wav"); + self.noise = "plats/plat1.wav"; + self.noise1 = "plats/plat2.wav"; + } + + if (self.sounds == 2) + { + precache_sound ("plats/medplat1.wav"); + precache_sound ("plats/medplat2.wav"); + self.noise = "plats/medplat1.wav"; + self.noise1 = "plats/medplat2.wav"; + } + + + self.mangle = self.angles; + self.angles = '0 0 0'; + + self.classname = "plat"; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + setorigin (self, self.origin); + setmodel (self, self.model); + setsize (self, self.mins , self.maxs); + + self.blocked = plat_crush; + if (!self.speed) + self.speed = 150; + +// pos1 is the top position, pos2 is the bottom + self.pos1 = self.origin; + self.pos2 = self.origin; + if (self.height) + self.pos2_z = self.origin_z - self.height; + else + self.pos2_z = self.origin_z - self.size_z + 8; + + self.use = plat_trigger_use; + + plat_spawn_inside_trigger (); // the "start moving" trigger + + if (self.targetname) + { + self.state = STATE_UP; + self.use = plat_use; + } + else + { + setorigin (self, self.pos2); + self.state = STATE_BOTTOM; + } +}; + +//============================================================================ + +void() train_next; +void() func_train_find; + +void() train_blocked = +{ + if (time < self.attack_finished) + return; + self.attack_finished = time + 0.5; + T_Damage (other, self, self, self.dmg); +}; +void() train_use = +{ + if (self.think != func_train_find) + return; // already activated + train_next(); +}; + +void() train_wait = +{ + if (self.wait) + { + self.nextthink = self.ltime + self.wait; + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + } + else + self.nextthink = self.ltime + 0.1; + + self.think = train_next; +}; + +void() train_next = +{ + local entity targ; + + targ = find (world, targetname, self.target); + self.target = targ.target; + if (!self.target) + objerror ("train_next: no next target"); + if (targ.wait) + self.wait = targ.wait; + else + self.wait = 0; + sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + SUB_CalcMove (targ.origin - self.mins, self.speed, train_wait); +}; + +void() func_train_find = + +{ + local entity targ; + + targ = find (world, targetname, self.target); + self.target = targ.target; + setorigin (self, targ.origin - self.mins); + if (!self.targetname) + { // not triggered, so start immediately + self.nextthink = self.ltime + 0.1; + self.think = train_next; + } +}; + +/*QUAKED func_train (0 .5 .8) ? +Trains are moving platforms that players can ride. +The targets origin specifies the min point of the train at each corner. +The train spawns at the first target it is pointing at. +If the train is the target of a button or trigger, it will not begin moving until activated. +speed default 100 +dmg default 2 +sounds +1) ratchet metal + +*/ +void() func_train = +{ + if (!self.speed) + self.speed = 100; + if (!self.target) + objerror ("func_train without a target"); + if (!self.dmg) + self.dmg = 2; + + if (self.sounds == 0) + { + self.noise = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + self.noise1 = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + } + + if (self.sounds == 1) + { + self.noise = ("plats/train2.wav"); + precache_sound ("plats/train2.wav"); + self.noise1 = ("plats/train1.wav"); + precache_sound ("plats/train1.wav"); + } + + self.cnt = 1; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + self.blocked = train_blocked; + self.use = train_use; + self.classname = "train"; + + setmodel (self, self.model); + setsize (self, self.mins , self.maxs); + setorigin (self, self.origin); + +// start trains on the second frame, to make sure their targets have had +// a chance to spawn + self.nextthink = self.ltime + 0.1; + self.think = func_train_find; +}; + +/*QUAKED misc_teleporttrain (0 .5 .8) (-8 -8 -8) (8 8 8) +This is used for the final bos +*/ +void() misc_teleporttrain = +{ + if (!self.speed) + self.speed = 100; + if (!self.target) + objerror ("func_train without a target"); + + self.cnt = 1; + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_PUSH; + self.blocked = train_blocked; + self.use = train_use; + self.avelocity = '100 200 300'; + + self.noise = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + self.noise1 = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + + precache_model2 ("progs/teleport.mdl"); + setmodel (self, "progs/teleport.mdl"); + setsize (self, self.mins , self.maxs); + setorigin (self, self.origin); + +// start trains on the second frame, to make sure their targets have had +// a chance to spawn + self.nextthink = self.ltime + 0.1; + self.think = func_train_find; +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/player.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/player.qc new file mode 100755 index 00000000..3cdd1b45 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/player.qc @@ -0,0 +1,618 @@ + +void() bubble_bob; + +/* +============================================================================== + +PLAYER + +============================================================================== +*/ + +$cd id1/models/player_4 +$origin 0 -6 24 +$base base +$skin skin + +// +// running +// +$frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6 + +$frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6 + +// +// standing +// +$frame stand1 stand2 stand3 stand4 stand5 + +$frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6 +$frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12 + + +// +// pain +// +$frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + + +// +// death +// + +$frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6 +$frame axdeth7 axdeth8 axdeth9 + +$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8 +$frame deatha9 deatha10 deatha11 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 + +$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8 +$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15 + +$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7 +$frame deathd8 deathd9 + +$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7 +$frame deathe8 deathe9 + +// +// attacks +// +$frame nailatt1 nailatt2 + +$frame light1 light2 + +$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6 + +$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6 + +$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6 + +$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6 + +$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6 + +$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6 + + +/* +============================================================================== +PLAYER +============================================================================== +*/ + +void() player_run; + +void() player_stand1 =[ $axstnd1, player_stand1 ] +{ + self.weaponframe=0; + if (self.velocity_x || self.velocity_y) + { + self.walkframe=0; + player_run(); + return; + } + else + { + if (self.walkframe >= 5) + self.walkframe = 0; + self.frame = $stand1 + self.walkframe; + } + self.walkframe = self.walkframe + 1; +}; + +void() player_run =[ $rockrun1, player_run ] +{ +local float r; +r = random(); +//THis is a HUGE check. I wonder if It is Memory Consuming at all. +if (checkbottom(self) == TRUE && self.flags & FL_ONGROUND && self.walkframe == 1 || self.walkframe == 4 && self.mballset == 0 && vlen(self.velocity) > 145 && !self.weapon == IT_MORPHBALL) +{ +if (r >= 0.33) + sound (self, CHAN_AUTO, "steps/foot1.wav", 0.5, ATTN_NORM); +else if (r >= 0.66) + sound (self, CHAN_AUTO, "steps/foot2.wav", 0.5, ATTN_NORM); +if (r >= 0.99) + sound (self, CHAN_AUTO, "steps/foot3.wav", 0.5, ATTN_NORM); +else + sound (self, CHAN_AUTO, "steps/foot4.wav", 0.5, ATTN_NORM); +} + + self.weaponframe=0; + if (!self.velocity_x && !self.velocity_y) + + { + self.walkframe=0; + player_stand1(); + return; + } + else + { + if (self.walkframe == 6) + self.walkframe = 0; + self.frame = self.frame + self.walkframe; + } + self.walkframe = self.walkframe + 1; +}; + + +void() player_shot1 = [$shotatt1, player_shot2 ] {self.weaponframe=1; +self.effects = self.effects | EF_MUZZLEFLASH;}; +void() player_shot2 = [$shotatt2, player_shot3 ] {self.weaponframe=2;}; +void() player_shot3 = [$shotatt3, player_shot4 ] {self.weaponframe=3;}; +void() player_shot4 = [$shotatt4, player_shot5 ] {self.weaponframe=4;}; +void() player_shot5 = [$shotatt5, player_shot6 ] {self.weaponframe=5;}; +void() player_shot6 = [$shotatt6, player_run ] {self.weaponframe=6;}; + +void() player_axe1 = [$axatt1, player_axe2 ] {self.weaponframe=1;}; +void() player_axe2 = [$axatt2, player_axe3 ] {self.weaponframe=2;}; +void() player_axe3 = [$axatt3, player_axe4 ] {self.weaponframe=3;W_FireAxe();}; +void() player_axe4 = [$axatt4, player_run ] {self.weaponframe=4;}; + +void() player_axeb1 = [$axattb1, player_axeb2 ] {self.weaponframe=5;}; +void() player_axeb2 = [$axattb2, player_axeb3 ] {self.weaponframe=6;}; +void() player_axeb3 = [$axattb3, player_axeb4 ] {self.weaponframe=7;W_FireAxe();}; +void() player_axeb4 = [$axattb4, player_run ] {self.weaponframe=8;}; + +void() player_axec1 = [$axattc1, player_axec2 ] {self.weaponframe=1;}; +void() player_axec2 = [$axattc2, player_axec3 ] {self.weaponframe=2;}; +void() player_axec3 = [$axattc3, player_axec4 ] {self.weaponframe=3;W_FireAxe();}; +void() player_axec4 = [$axattc4, player_run ] {self.weaponframe=4;}; + +void() player_axed1 = [$axattd1, player_axed2 ] {self.weaponframe=5;}; +void() player_axed2 = [$axattd2, player_axed3 ] {self.weaponframe=6;}; +void() player_axed3 = [$axattd3, player_axed4 ] {self.weaponframe=7;W_FireAxe();}; +void() player_axed4 = [$axattd4, player_run ] {self.weaponframe=8;}; + + +//============================================================================ + +void() player_nail1 =[$nailatt1, player_nail2 ] +{ + self.effects = self.effects | EF_MUZZLEFLASH; + + if (!self.button0) + {player_run ();return;} + self.weaponframe = self.weaponframe + 1; + if (self.weaponframe == 9) + self.weaponframe = 1; + SuperDamageSound(); + W_FireSpikes (4); + self.attack_finished = time + 0.2; +}; +void() player_nail2 =[$nailatt2, player_nail1 ] +{ + self.effects = self.effects | EF_MUZZLEFLASH; + + if (!self.button0) + {player_run ();return;} + self.weaponframe = self.weaponframe + 1; + if (self.weaponframe == 9) + self.weaponframe = 1; + SuperDamageSound(); + W_FireSpikes (-4); + self.attack_finished = time + 0.2; +}; + +//============================================================================ + +void() player_light1 =[$light1, player_light2 ] +{ + self.effects = self.effects | EF_MUZZLEFLASH; + + if (!self.button0) + {player_run ();return;} + self.weaponframe = self.weaponframe + 1; + if (self.weaponframe == 5) + self.weaponframe = 1; + SuperDamageSound(); + W_FireLightning(); + self.attack_finished = time + 0.2; +}; +void() player_light2 =[$light2, player_light1 ] +{ + self.effects = self.effects | EF_MUZZLEFLASH; + + if (!self.button0) + {player_run ();return;} + self.weaponframe = self.weaponframe + 1; + if (self.weaponframe == 5) + self.weaponframe = 1; + SuperDamageSound(); + W_FireLightning(); + self.attack_finished = time + 0.2; +}; + +//============================================================================ + + +void() player_rocket1 =[$rockatt1, player_rocket2 ] {self.weaponframe=1; +self.effects = self.effects | EF_MUZZLEFLASH;}; +void() player_rocket2 =[$rockatt2, player_rocket3 ] {self.weaponframe=2;}; +void() player_rocket3 =[$rockatt3, player_rocket4 ] {self.weaponframe=3;}; +void() player_rocket4 =[$rockatt4, player_rocket5 ] {self.weaponframe=4;}; +void() player_rocket5 =[$rockatt5, player_rocket6 ] {self.weaponframe=5;}; +void() player_rocket6 =[$rockatt6, player_run ] {self.weaponframe=6;}; +void(float num_bubbles) DeathBubbles; + +void() PainSound = +{ +//local float rs; + + if (self.health < 0) + return; + + if (damage_attacker.classname == "teledeath") + { + sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE); + return; + } +// slime pain sounds + if (self.watertype == CONTENT_SLIME) + { +// FIX ME put in some steam here + if (random() > 0.5) + sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM); + return; + } + /* + if (self.watertype == CONTENT_LAVA) + { + if (random() > 0.5) + sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM); + return; + } + */ + + if (self.pain_finished > time) + { + self.axhitme = 0; + return; + } + self.pain_finished = time + 0.5; + +// don't make multiple pain sounds right after each other + + + /* + rs = rint((random() * 5) + 1); + + self.noise = ""; + if (rs == 1) + self.noise = "player/pain1.wav"; + else if (rs == 2) + self.noise = "player/pain2.wav"; + else if (rs == 3) + self.noise = "player/pain3.wav"; + else if (rs == 4) + self.noise = "player/pain4.wav"; + else if (rs == 5) + self.noise = "player/pain5.wav"; + else + self.noise = "player/pain6.wav"; + + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + return; + */ +}; + +void() player_pain1 = [ $pain1, player_pain2 ] {PainSound();self.weaponframe=0;}; +void() player_pain2 = [ $pain2, player_pain3 ] {}; +void() player_pain3 = [ $pain3, player_pain4 ] {}; +void() player_pain4 = [ $pain4, player_pain5 ] {}; +void() player_pain5 = [ $pain5, player_pain6 ] {}; +void() player_pain6 = [ $pain6, player_run ] {}; + +void() player_axpain1 = [ $axpain1, player_axpain2 ] {PainSound();self.weaponframe=0;}; +void() player_axpain2 = [ $axpain2, player_axpain3 ] {}; +void() player_axpain3 = [ $axpain3, player_axpain4 ] {}; +void() player_axpain4 = [ $axpain4, player_axpain5 ] {}; +void() player_axpain5 = [ $axpain5, player_axpain6 ] {}; +void() player_axpain6 = [ $axpain6, player_run ] {}; + +void() player_pain = +{ + if (self.weaponframe) + return; + + if (self.invisible_finished > time) + return; // eyes don't have pain frames + player_pain1 (); +}; + +void() player_diea1; +void() player_dieb1; +void() player_diec1; +void() player_died1; +void() player_diee1; +void() DeathBubblesSpawn = +{ +local entity bubble; + if (self.owner.waterlevel != 3) + return; + bubble = spawn(); + setmodel (bubble, "progs/s_bubble.spr"); + setorigin (bubble, self.owner.origin + '0 0 24'); + bubble.movetype = MOVETYPE_NOCLIP; + bubble.solid = SOLID_NOT; + bubble.velocity = '0 0 15'; + bubble.nextthink = time + 0.5; + bubble.think = bubble_bob; + bubble.classname = "bubble"; + bubble.frame = 0; + bubble.cnt = 0; + setsize (bubble, '-8 -8 -8', '8 8 8'); + self.nextthink = time + 0.1; + self.think = DeathBubblesSpawn; + self.air_finished = self.air_finished + 1; + if (self.air_finished >= self.bubble_count) + remove(self); +}; + +void(float num_bubbles) DeathBubbles = +{ +local entity bubble_spawner; + + bubble_spawner = spawn(); + setorigin (bubble_spawner, self.origin); + bubble_spawner.movetype = MOVETYPE_NONE; + bubble_spawner.solid = SOLID_NOT; + bubble_spawner.nextthink = time + 0.1; + bubble_spawner.think = DeathBubblesSpawn; + bubble_spawner.air_finished = 0; + bubble_spawner.owner = self; + bubble_spawner.bubble_count = num_bubbles; + return; +}; + + +void() DeathSound = +{ +local float rs; + + // water death sounds + if (self.waterlevel == 3) + { + DeathBubbles(20); + sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE); + return; + } + + rs = rint ((random() * 4) + 1); + if (rs == 1) + self.noise = "player/death1.wav"; + if (rs == 2) + self.noise = "player/death2.wav"; + if (rs == 3) + self.noise = "player/death3.wav"; + if (rs == 4) + self.noise = "player/death4.wav"; + if (rs == 5) + self.noise = "player/death5.wav"; + + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NONE); + return; +}; + + +void() PlayerDead = +{ + self.nextthink = -1; +// allow respawn after a certain time + self.deadflag = DEAD_DEAD; +}; + +vector(float dm) VelocityForDamage = +{ + local vector v; + + v_x = 100 * crandom(); + v_y = 100 * crandom(); + v_z = 200 + 100 * random(); + + if (dm > -50) + { +// dprint ("level 1\n"); + v = v * 0.7; + } + else if (dm > -200) + { +// dprint ("level 3\n"); + v = v * 2; + } + else + v = v * 10; + + return v; +}; + +void(string gibname, float dm) ThrowGib = +{ + local entity new; + + new = spawn(); + new.origin = self.origin; + setmodel (new, gibname); + setsize (new, '0 0 0', '0 0 0'); + new.velocity = VelocityForDamage (dm); + new.movetype = MOVETYPE_BOUNCE; + new.solid = SOLID_NOT; + new.avelocity_x = random()*600; + new.avelocity_y = random()*600; + new.avelocity_z = random()*600; + new.think = SUB_Remove; + new.ltime = time; + new.nextthink = time + 10 + random()*10; + new.frame = 0; + new.flags = 0; +}; + +void(string gibname, float dm) ThrowHead = +{ + setmodel (self, gibname); + self.frame = 0; + self.nextthink = -1; + self.movetype = MOVETYPE_BOUNCE; + self.takedamage = DAMAGE_NO; + self.solid = SOLID_NOT; + self.view_ofs = '0 0 8'; + setsize (self, '-16 -16 0', '16 16 56'); + self.velocity = VelocityForDamage (dm); + self.origin_z = self.origin_z - 24; + self.flags = self.flags - (self.flags & FL_ONGROUND); + self.avelocity = crandom() * '0 600 0'; +}; + + +void() GibPlayer = +{ + ThrowHead ("progs/h_player.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + + self.deadflag = DEAD_DEAD; + + if (damage_attacker.classname == "teledeath") + { + sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE); + return; + } + + if (damage_attacker.classname == "teledeath2") + { + sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE); + return; + } + + if (random() < 0.5) + sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NONE); + else + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NONE); +}; + +void() PlayerDie = +{ + local float i; + + self.items = self.items - (self.items & IT_INVISIBILITY); + self.invisible_finished = 0; // don't die as eyes + self.invincible_finished = 0; + self.super_damage_finished = 0; + self.radsuit_finished = 0; + self.modelindex = modelindex_player; // don't use eyes + body(self.origin); + if (self.mballset == 1) + self.mballset = 0; + + self.weaponmodel=""; + self.view_ofs = '0 0 -8'; + self.deadflag = DEAD_DYING; + self.solid = SOLID_NOT; + self.flags = self.flags - (self.flags & FL_ONGROUND); + self.movetype = MOVETYPE_TOSS; + if (self.velocity_z < 10) + self.velocity_z = self.velocity_z + random()*300; + + + DeathSound(); + + self.angles_x = 0; + self.angles_z = 0; + + i = cvar("temp1"); + if (!i) + i = 1 + floor(random()*6); + + if (i == 1) + player_diea1(); + else if (i == 2) + player_dieb1(); + else if (i == 3) + player_diec1(); + else if (i == 4) + player_died1(); + else + player_diee1(); + +}; + +void() set_suicide_frame = +{ // used by klill command and diconnect command + if (self.model != "progs/player.mdl") + return; // allready gibbed + self.frame = $deatha11; + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_TOSS; + self.deadflag = DEAD_DEAD; + self.nextthink = -1; +}; + + +void() player_diea1 = [ $deatha1, player_diea2 ] {}; +void() player_diea2 = [ $deatha2, player_diea3 ] {}; +void() player_diea3 = [ $deatha3, player_diea4 ] {}; +void() player_diea4 = [ $deatha4, player_diea5 ] {}; +void() player_diea5 = [ $deatha5, player_diea6 ] {}; +void() player_diea6 = [ $deatha6, player_diea7 ] {}; +void() player_diea7 = [ $deatha7, player_diea8 ] {}; +void() player_diea8 = [ $deatha8, player_diea9 ] {}; +void() player_diea9 = [ $deatha9, player_diea10 ] {}; +void() player_diea10 = [ $deatha10, player_diea11 ] {}; +void() player_diea11 = [ $deatha11, player_diea11 ] {PlayerDead();}; + +void() player_dieb1 = [ $deathb1, player_dieb2 ] {}; +void() player_dieb2 = [ $deathb2, player_dieb3 ] {}; +void() player_dieb3 = [ $deathb3, player_dieb4 ] {}; +void() player_dieb4 = [ $deathb4, player_dieb5 ] {}; +void() player_dieb5 = [ $deathb5, player_dieb6 ] {}; +void() player_dieb6 = [ $deathb6, player_dieb7 ] {}; +void() player_dieb7 = [ $deathb7, player_dieb8 ] {}; +void() player_dieb8 = [ $deathb8, player_dieb9 ] {}; +void() player_dieb9 = [ $deathb9, player_dieb9 ] {PlayerDead();}; + +void() player_diec1 = [ $deathc1, player_diec2 ] {}; +void() player_diec2 = [ $deathc2, player_diec3 ] {}; +void() player_diec3 = [ $deathc3, player_diec4 ] {}; +void() player_diec4 = [ $deathc4, player_diec5 ] {}; +void() player_diec5 = [ $deathc5, player_diec6 ] {}; +void() player_diec6 = [ $deathc6, player_diec7 ] {}; +void() player_diec7 = [ $deathc7, player_diec8 ] {}; +void() player_diec8 = [ $deathc8, player_diec9 ] {}; +void() player_diec9 = [ $deathc9, player_diec10 ] {}; +void() player_diec10 = [ $deathc10, player_diec11 ] {}; +void() player_diec11 = [ $deathc11, player_diec12 ] {}; +void() player_diec12 = [ $deathc12, player_diec13 ] {}; +void() player_diec13 = [ $deathc13, player_diec14 ] {}; +void() player_diec14 = [ $deathc14, player_diec15 ] {}; +void() player_diec15 = [ $deathc15, player_diec15 ] {PlayerDead();}; + +void() player_died1 = [ $deathd1, player_died2 ] {}; +void() player_died2 = [ $deathd2, player_died3 ] {}; +void() player_died3 = [ $deathd3, player_died4 ] {}; +void() player_died4 = [ $deathd4, player_died5 ] {}; +void() player_died5 = [ $deathd5, player_died6 ] {}; +void() player_died6 = [ $deathd6, player_died7 ] {}; +void() player_died7 = [ $deathd7, player_died8 ] {}; +void() player_died8 = [ $deathd8, player_died9 ] {}; +void() player_died9 = [ $deathd9, player_died9 ] {PlayerDead();}; + +void() player_diee1 = [ $deathe1, player_diee2 ] {}; +void() player_diee2 = [ $deathe2, player_diee3 ] {}; +void() player_diee3 = [ $deathe3, player_diee4 ] {}; +void() player_diee4 = [ $deathe4, player_diee5 ] {}; +void() player_diee5 = [ $deathe5, player_diee6 ] {}; +void() player_diee6 = [ $deathe6, player_diee7 ] {}; +void() player_diee7 = [ $deathe7, player_diee8 ] {}; +void() player_diee8 = [ $deathe8, player_diee9 ] {}; +void() player_diee9 = [ $deathe9, player_diee9 ] {PlayerDead();}; + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/primedefs.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/primedefs.qc new file mode 100755 index 00000000..114ee3e3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/primedefs.qc differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/progdefs.h b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/progdefs.h new file mode 100755 index 00000000..c976cf8e --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/progdefs.h @@ -0,0 +1,143 @@ + +/* file generated by qcc, do not modify */ + +typedef struct +{ int pad[28]; + int self; + int other; + int world; + float time; + float frametime; + float force_retouch; + string_t mapname; + float deathmatch; + float coop; + float teamplay; + float serverflags; + float total_secrets; + float total_monsters; + float found_secrets; + float killed_monsters; + float parm1; + float parm2; + float parm3; + float parm4; + float parm5; + float parm6; + float parm7; + float parm8; + float parm9; + float parm10; + float parm11; + float parm12; + float parm13; + float parm14; + float parm15; + float parm16; + vec3_t v_forward; + vec3_t v_up; + vec3_t v_right; + float trace_allsolid; + float trace_startsolid; + float trace_fraction; + vec3_t trace_endpos; + vec3_t trace_plane_normal; + float trace_plane_dist; + int trace_ent; + float trace_inopen; + float trace_inwater; + int msg_entity; + func_t main; + func_t StartFrame; + func_t PlayerPreThink; + func_t PlayerPostThink; + func_t ClientKill; + func_t ClientConnect; + func_t PutClientInServer; + func_t ClientDisconnect; + func_t SetNewParms; + func_t SetChangeParms; +} globalvars_t; + +typedef struct +{ + float modelindex; + vec3_t absmin; + vec3_t absmax; + float ltime; + float movetype; + float solid; + vec3_t origin; + vec3_t oldorigin; + vec3_t velocity; + vec3_t angles; + vec3_t avelocity; + vec3_t punchangle; + string_t classname; + string_t model; + float frame; + float skin; + float effects; + vec3_t mins; + vec3_t maxs; + vec3_t size; + func_t touch; + func_t use; + func_t think; + func_t blocked; + float nextthink; + int groundentity; + float health; + float frags; + float weapon; + string_t weaponmodel; + float weaponframe; + float currentammo; + float ammo_shells; + float ammo_nails; + float ammo_rockets; + float ammo_cells; + float items; + float takedamage; + int chain; + float deadflag; + vec3_t view_ofs; + float button0; + float button1; + float button2; + float impulse; + float fixangle; + vec3_t v_angle; + float idealpitch; + string_t netname; + int enemy; + float flags; + float colormap; + float team; + float max_health; + float teleport_time; + float armortype; + float armorvalue; + float waterlevel; + float watertype; + float ideal_yaw; + float yaw_speed; + int aiment; + int goalentity; + float spawnflags; + string_t target; + string_t targetname; + float dmg_take; + float dmg_save; + int dmg_inflictor; + int owner; + vec3_t movedir; + string_t message; + float sounds; + string_t noise; + string_t noise1; + string_t noise2; + string_t noise3; +} entvars_t; + +#define PROGHEADER_CRC 5927 diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/progs.src b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/progs.src new file mode 100755 index 00000000..4383bd8a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/progs.src differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/shalrath.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/shalrath.qc new file mode 100755 index 00000000..adf821ab --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/shalrath.qc @@ -0,0 +1,239 @@ +/* +============================================================================== + +SHAL-RATH + +============================================================================== +*/ +$cd id1/models/shalrath +$origin 0 0 24 +$base base +$skin skin +$scale 0.7 + +$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 +$frame attack9 attack10 attack11 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame death1 death2 death3 death4 death5 death6 death7 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 +$frame walk11 walk12 + +void() shalrath_pain; +void() ShalMissile; +void() shal_stand =[ $walk1, shal_stand ] {ai_stand();}; + +void() shal_walk1 =[ $walk2, shal_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE); +ai_walk(6);}; +void() shal_walk2 =[ $walk3, shal_walk3 ] {ai_walk(4);}; +void() shal_walk3 =[ $walk4, shal_walk4 ] {ai_walk(0);}; +void() shal_walk4 =[ $walk5, shal_walk5 ] {ai_walk(0);}; +void() shal_walk5 =[ $walk6, shal_walk6 ] {ai_walk(0);}; +void() shal_walk6 =[ $walk7, shal_walk7 ] {ai_walk(0);}; +void() shal_walk7 =[ $walk8, shal_walk8 ] {ai_walk(5);}; +void() shal_walk8 =[ $walk9, shal_walk9 ] {ai_walk(6);}; +void() shal_walk9 =[ $walk10, shal_walk10 ] {ai_walk(5);}; +void() shal_walk10 =[ $walk11, shal_walk11 ] {ai_walk(0);}; +void() shal_walk11 =[ $walk12, shal_walk12 ] {ai_walk(4);}; +void() shal_walk12 =[ $walk1, shal_walk1 ] {ai_walk(5);}; + +void() shal_run1 =[ $walk2, shal_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE); +ai_run(6);}; +void() shal_run2 =[ $walk3, shal_run3 ] {ai_run(4);}; +void() shal_run3 =[ $walk4, shal_run4 ] {ai_run(0);}; +void() shal_run4 =[ $walk5, shal_run5 ] {ai_run(0);}; +void() shal_run5 =[ $walk6, shal_run6 ] {ai_run(0);}; +void() shal_run6 =[ $walk7, shal_run7 ] {ai_run(0);}; +void() shal_run7 =[ $walk8, shal_run8 ] {ai_run(5);}; +void() shal_run8 =[ $walk9, shal_run9 ] {ai_run(6);}; +void() shal_run9 =[ $walk10, shal_run10 ] {ai_run(5);}; +void() shal_run10 =[ $walk11, shal_run11 ] {ai_run(0);}; +void() shal_run11 =[ $walk12, shal_run12 ] {ai_run(4);}; +void() shal_run12 =[ $walk1, shal_run1 ] {ai_run(5);}; + +void() shal_attack1 =[ $attack1, shal_attack2 ] { +sound (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM); +ai_face(); +}; +void() shal_attack2 =[ $attack2, shal_attack3 ] {ai_face();}; +void() shal_attack3 =[ $attack3, shal_attack4 ] {ai_face();}; +void() shal_attack4 =[ $attack4, shal_attack5 ] {ai_face();}; +void() shal_attack5 =[ $attack5, shal_attack6 ] {ai_face();}; +void() shal_attack6 =[ $attack6, shal_attack7 ] {ai_face();}; +void() shal_attack7 =[ $attack7, shal_attack8 ] {ai_face();}; +void() shal_attack8 =[ $attack8, shal_attack9 ] {ai_face();}; +void() shal_attack9 =[ $attack9, shal_attack10 ] {ShalMissile();}; +void() shal_attack10 =[ $attack10, shal_attack11 ] {ai_face();}; +void() shal_attack11 =[ $attack11, shal_run1 ] {}; + +void() shal_pain1 =[ $pain1, shal_pain2 ] {}; +void() shal_pain2 =[ $pain2, shal_pain3 ] {}; +void() shal_pain3 =[ $pain3, shal_pain4 ] {}; +void() shal_pain4 =[ $pain4, shal_pain5 ] {}; +void() shal_pain5 =[ $pain5, shal_run1 ] {}; + +void() shal_death1 =[ $death1, shal_death2 ] {}; +void() shal_death2 =[ $death2, shal_death3 ] {}; +void() shal_death3 =[ $death3, shal_death4 ] {}; +void() shal_death4 =[ $death4, shal_death5 ] {}; +void() shal_death5 =[ $death5, shal_death6 ] {}; +void() shal_death6 =[ $death6, shal_death7 ] {}; +void() shal_death7 =[ $death7, shal_death7 ] {}; + + +void() shalrath_pain = +{ + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "shalrath/pain.wav", 1, ATTN_NORM); + shal_pain1(); + self.pain_finished = time + 3; +}; + +void() shalrath_die = +{ +// check for gib + if (self.health < -90) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_shal.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + + sound (self, CHAN_VOICE, "shalrath/death.wav", 1, ATTN_NORM); + shal_death1(); + self.solid = SOLID_NOT; + // insert death sounds here +}; + +/* +================ +ShalMissile +================ +*/ +void() ShalMissileTouch; +void() ShalHome; +void() ShalMissile = +{ + local entity missile; + local vector dir; + local float dist, flytime; + + dir = normalize((self.enemy.origin + '0 0 10') - self.origin); + dist = vlen (self.enemy.origin - self.origin); + flytime = dist * 0.002; + if (flytime < 0.1) + flytime = 0.1; + + self.effects = self.effects | EF_MUZZLEFLASH; + sound (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); + + missile = spawn (); + missile.owner = self; + + missile.solid = SOLID_BBOX; + missile.movetype = MOVETYPE_FLYMISSILE; + setmodel (missile, "progs/v_spike.mdl"); + + setsize (missile, '0 0 0', '0 0 0'); + + missile.origin = self.origin + '0 0 10'; + missile.velocity = dir * 400; + missile.avelocity = '300 300 300'; + missile.nextthink = flytime + time; + missile.think = ShalHome; + missile.enemy = self.enemy; + missile.touch = ShalMissileTouch; +}; + +void() ShalHome = +{ + local vector dir, vtemp; + vtemp = self.enemy.origin + '0 0 10'; + if (self.enemy.health < 1) + { + remove(self); + return; + } + dir = normalize(vtemp - self.origin); + if (skill == 3) + self.velocity = dir * 350; + else + self.velocity = dir * 250; + self.nextthink = time + 0.2; + self.think = ShalHome; +}; + +void() ShalMissileTouch = +{ + if (other == self.owner) + return; // don't explode on owner + + if (other.classname == "monster_zombie") + T_Damage (other, self, self, 110); + T_RadiusDamage (self, self.owner, 40, world); + sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); + + 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); + + self.velocity = '0 0 0'; + self.touch = SUB_Null; + setmodel (self, "progs/s_explod.spr"); + self.solid = SOLID_NOT; + s_explode1 (); +}; + +//================================================================= + +/*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) Ambush +*/ +void() monster_shalrath = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/shalrath.mdl"); + precache_model2 ("progs/h_shal.mdl"); + precache_model2 ("progs/v_spike.mdl"); + + precache_sound2 ("shalrath/attack.wav"); + precache_sound2 ("shalrath/attack2.wav"); + precache_sound2 ("shalrath/death.wav"); + precache_sound2 ("shalrath/idle.wav"); + precache_sound2 ("shalrath/pain.wav"); + precache_sound2 ("shalrath/sight.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/shalrath.mdl"); + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 400; + + self.th_stand = shal_stand; + self.th_walk = shal_walk1; + self.th_run = shal_run1; + self.th_die = shalrath_die; + self.th_pain = shalrath_pain; + self.th_missile = shal_attack1; + + self.think = walkmonster_start; + self.nextthink = time + 0.1 + random ()*0.1; + +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/shambler.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/shambler.qc new file mode 100755 index 00000000..4bd8a969 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/shambler.qc @@ -0,0 +1,360 @@ +/* +============================================================================== + +SHAMBLER + +============================================================================== +*/ + +$cd id1/models/shams +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 +$frame stand10 stand11 stand12 stand13 stand14 stand15 stand16 stand17 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 +$frame walk8 walk9 walk10 walk11 walk12 + +$frame run1 run2 run3 run4 run5 run6 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 +$frame smash8 smash9 smash10 smash11 smash12 + +$frame swingr1 swingr2 swingr3 swingr4 swingr5 +$frame swingr6 swingr7 swingr8 swingr9 + +$frame swingl1 swingl2 swingl3 swingl4 swingl5 +$frame swingl6 swingl7 swingl8 swingl9 + +$frame magic1 magic2 magic3 magic4 magic5 +$frame magic6 magic7 magic8 magic9 magic10 magic11 magic12 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame death1 death2 death3 death4 death5 death6 +$frame death7 death8 death9 death10 death11 + +void() sham_stand1 =[ $stand1, sham_stand2 ] {ai_stand();}; +void() sham_stand2 =[ $stand2, sham_stand3 ] {ai_stand();}; +void() sham_stand3 =[ $stand3, sham_stand4 ] {ai_stand();}; +void() sham_stand4 =[ $stand4, sham_stand5 ] {ai_stand();}; +void() sham_stand5 =[ $stand5, sham_stand6 ] {ai_stand();}; +void() sham_stand6 =[ $stand6, sham_stand7 ] {ai_stand();}; +void() sham_stand7 =[ $stand7, sham_stand8 ] {ai_stand();}; +void() sham_stand8 =[ $stand8, sham_stand9 ] {ai_stand();}; +void() sham_stand9 =[ $stand9, sham_stand10] {ai_stand();}; +void() sham_stand10 =[ $stand10, sham_stand11] {ai_stand();}; +void() sham_stand11 =[ $stand11, sham_stand12] {ai_stand();}; +void() sham_stand12 =[ $stand12, sham_stand13] {ai_stand();}; +void() sham_stand13 =[ $stand13, sham_stand14] {ai_stand();}; +void() sham_stand14 =[ $stand14, sham_stand15] {ai_stand();}; +void() sham_stand15 =[ $stand15, sham_stand16] {ai_stand();}; +void() sham_stand16 =[ $stand16, sham_stand17] {ai_stand();}; +void() sham_stand17 =[ $stand17, sham_stand1 ] {ai_stand();}; + +void() sham_walk1 =[ $walk1, sham_walk2 ] {ai_walk(10);}; +void() sham_walk2 =[ $walk2, sham_walk3 ] {ai_walk(9);}; +void() sham_walk3 =[ $walk3, sham_walk4 ] {ai_walk(9);}; +void() sham_walk4 =[ $walk4, sham_walk5 ] {ai_walk(5);}; +void() sham_walk5 =[ $walk5, sham_walk6 ] {ai_walk(6);}; +void() sham_walk6 =[ $walk6, sham_walk7 ] {ai_walk(12);}; +void() sham_walk7 =[ $walk7, sham_walk8 ] {ai_walk(8);}; +void() sham_walk8 =[ $walk8, sham_walk9 ] {ai_walk(3);}; +void() sham_walk9 =[ $walk9, sham_walk10] {ai_walk(13);}; +void() sham_walk10 =[ $walk10, sham_walk11] {ai_walk(9);}; +void() sham_walk11 =[ $walk11, sham_walk12] {ai_walk(7);}; +void() sham_walk12 =[ $walk12, sham_walk1 ] {ai_walk(7); +if (random() > 0.8) + sound (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);}; + +void() sham_run1 =[ $run1, sham_run2 ] {ai_run(20);}; +void() sham_run2 =[ $run2, sham_run3 ] {ai_run(24);}; +void() sham_run3 =[ $run3, sham_run4 ] {ai_run(20);}; +void() sham_run4 =[ $run4, sham_run5 ] {ai_run(20);}; +void() sham_run5 =[ $run5, sham_run6 ] {ai_run(24);}; +void() sham_run6 =[ $run6, sham_run1 ] {ai_run(20); +if (random() > 0.8) + sound (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE); +}; + +void() sham_smash1 =[ $smash1, sham_smash2 ] { +sound (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); +ai_charge(2);}; +void() sham_smash2 =[ $smash2, sham_smash3 ] {ai_charge(6);}; +void() sham_smash3 =[ $smash3, sham_smash4 ] {ai_charge(6);}; +void() sham_smash4 =[ $smash4, sham_smash5 ] {ai_charge(5);}; +void() sham_smash5 =[ $smash5, sham_smash6 ] {ai_charge(4);}; +void() sham_smash6 =[ $smash6, sham_smash7 ] {ai_charge(1);}; +void() sham_smash7 =[ $smash7, sham_smash8 ] {ai_charge(0);}; +void() sham_smash8 =[ $smash8, sham_smash9 ] {ai_charge(0);}; +void() sham_smash9 =[ $smash9, sham_smash10 ] {ai_charge(0);}; +void() sham_smash10 =[ $smash10, sham_smash11 ] { +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + ai_charge(0); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + if (!CanDamage (self.enemy, self)) + return; + + ldmg = (random() + random() + random()) * 40; + T_Damage (self.enemy, self, self, ldmg); + sound (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM); + +}; +void() sham_smash11 =[ $smash11, sham_smash12 ] {ai_charge(5);}; +void() sham_smash12 =[ $smash12, sham_run1 ] {ai_charge(4);}; + +void() sham_swingr1; + +void(float side) ShamClaw = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + ai_charge(10); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + ldmg = (random() + random() + random()) * 20; + T_Damage (self.enemy, self, self, ldmg); + sound (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM); + +}; + +void() sham_swingl1 =[ $swingl1, sham_swingl2 ] { +sound (self, CHAN_VOICE, "shambler/melee2.wav", 1, ATTN_NORM); +ai_charge(5);}; +void() sham_swingl2 =[ $swingl2, sham_swingl3 ] {ai_charge(3);}; +void() sham_swingl3 =[ $swingl3, sham_swingl4 ] {ai_charge(7);}; +void() sham_swingl4 =[ $swingl4, sham_swingl5 ] {ai_charge(3);}; +void() sham_swingl5 =[ $swingl5, sham_swingl6 ] {ai_charge(7);}; +void() sham_swingl6 =[ $swingl6, sham_swingl7 ] {ai_charge(9);}; +void() sham_swingl7 =[ $swingl7, sham_swingl8 ] {ai_charge(5); ShamClaw(250);}; +void() sham_swingl8 =[ $swingl8, sham_swingl9 ] {ai_charge(4);}; +void() sham_swingl9 =[ $swingl9, sham_run1 ] { +ai_charge(8); +if (random()<0.5) + self.think = sham_swingr1; +}; + +void() sham_swingr1 =[ $swingr1, sham_swingr2 ] { +sound (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); +ai_charge(1);}; +void() sham_swingr2 =[ $swingr2, sham_swingr3 ] {ai_charge(8);}; +void() sham_swingr3 =[ $swingr3, sham_swingr4 ] {ai_charge(14);}; +void() sham_swingr4 =[ $swingr4, sham_swingr5 ] {ai_charge(7);}; +void() sham_swingr5 =[ $swingr5, sham_swingr6 ] {ai_charge(3);}; +void() sham_swingr6 =[ $swingr6, sham_swingr7 ] {ai_charge(6);}; +void() sham_swingr7 =[ $swingr7, sham_swingr8 ] {ai_charge(6); ShamClaw(-250);}; +void() sham_swingr8 =[ $swingr8, sham_swingr9 ] {ai_charge(3);}; +void() sham_swingr9 =[ $swingr9, sham_run1 ] {ai_charge(1); +ai_charge(10); +if (random()<0.5) + self.think = sham_swingl1; +}; + +void() sham_melee = +{ + local float chance; + + chance = random(); + if (chance > 0.6 || self.health == 600) + sham_smash1 (); + else if (chance > 0.3) + sham_swingr1 (); + else + sham_swingl1 (); +}; + + +//============================================================================ + +void() CastLightning = +{ + local vector org, dir; + + self.effects = self.effects | EF_MUZZLEFLASH; + + ai_face (); + + org = self.origin + '0 0 40'; + + dir = self.enemy.origin + '0 0 16' - org; + dir = normalize (dir); + + traceline (org, self.origin + dir*600, TRUE, self); + + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_LIGHTNING1); + WriteEntity (MSG_BROADCAST, self); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); + WriteCoord (MSG_BROADCAST, trace_endpos_x); + WriteCoord (MSG_BROADCAST, trace_endpos_y); + WriteCoord (MSG_BROADCAST, trace_endpos_z); + + LightningDamage (org, trace_endpos, self, 10); +}; + +void() sham_magic1 =[ $magic1, sham_magic2 ] {ai_face(); + sound (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM); +}; +void() sham_magic2 =[ $magic2, sham_magic3 ] {ai_face();}; +void() sham_magic3 =[ $magic3, sham_magic4 ] {ai_face();self.nextthink = self.nextthink + 0.2; +local entity o; + +self.effects = self.effects | EF_MUZZLEFLASH; +ai_face(); +self.owner = spawn(); +o = self.owner; +setmodel (o, "progs/s_light.mdl"); +setorigin (o, self.origin); +o.angles = self.angles; +o.nextthink = time + 0.7; +o.think = SUB_Remove; +}; +void() sham_magic4 =[ $magic4, sham_magic5 ] +{ +self.effects = self.effects | EF_MUZZLEFLASH; +self.owner.frame = 1; +}; +void() sham_magic5 =[ $magic5, sham_magic6 ] +{ +self.effects = self.effects | EF_MUZZLEFLASH; +self.owner.frame = 2; +}; +void() sham_magic6 =[ $magic6, sham_magic9 ] +{ +remove (self.owner); +CastLightning(); +sound (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM); +}; +void() sham_magic9 =[ $magic9, sham_magic10 ] +{CastLightning();}; +void() sham_magic10 =[ $magic10, sham_magic11 ] +{CastLightning();}; +void() sham_magic11 =[ $magic11, sham_magic12 ] +{ +if (skill == 3) + CastLightning(); +}; +void() sham_magic12 =[ $magic12, sham_run1 ] {}; + + + +void() sham_pain1 =[ $pain1, sham_pain2 ] {}; +void() sham_pain2 =[ $pain2, sham_pain3 ] {}; +void() sham_pain3 =[ $pain3, sham_pain4 ] {}; +void() sham_pain4 =[ $pain4, sham_pain5 ] {}; +void() sham_pain5 =[ $pain5, sham_pain6 ] {}; +void() sham_pain6 =[ $pain6, sham_run1 ] {}; + +void(entity attacker, float damage) sham_pain = +{ + sound (self, CHAN_VOICE, "shambler/shurt2.wav", 1, ATTN_NORM); + + if (self.health <= 0) + return; // allready dying, don't go into pain frame + + if (random()*400 > damage) + return; // didn't flinch + + if (self.pain_finished > time) + return; + self.pain_finished = time + 2; + + sham_pain1 (); +}; + + +//============================================================================ + +void() sham_death1 =[ $death1, sham_death2 ] {}; +void() sham_death2 =[ $death2, sham_death3 ] {}; +void() sham_death3 =[ $death3, sham_death4 ] {self.solid = SOLID_NOT;}; +void() sham_death4 =[ $death4, sham_death5 ] {}; +void() sham_death5 =[ $death5, sham_death6 ] {}; +void() sham_death6 =[ $death6, sham_death7 ] {}; +void() sham_death7 =[ $death7, sham_death8 ] {}; +void() sham_death8 =[ $death8, sham_death9 ] {}; +void() sham_death9 =[ $death9, sham_death10 ] {}; +void() sham_death10 =[ $death10, sham_death11 ] {}; +void() sham_death11 =[ $death11, sham_death11 ] {}; + +void() sham_die = +{ +// check for gib + if (self.health < -60) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_shams.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "shambler/sdeath.wav", 1, ATTN_NORM); + sham_death1 (); +}; + +//============================================================================ + + +/*QUAKED monster_shambler (1 0 0) (-32 -32 -24) (32 32 64) Ambush +*/ +void() monster_shambler = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/shambler.mdl"); + precache_model ("progs/s_light.mdl"); + precache_model ("progs/h_shams.mdl"); + precache_model ("progs/bolt.mdl"); + + precache_sound ("shambler/sattck1.wav"); + precache_sound ("shambler/sboom.wav"); + precache_sound ("shambler/sdeath.wav"); + precache_sound ("shambler/shurt2.wav"); + precache_sound ("shambler/sidle.wav"); + precache_sound ("shambler/ssight.wav"); + precache_sound ("shambler/melee1.wav"); + precache_sound ("shambler/melee2.wav"); + precache_sound ("shambler/smack.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + setmodel (self, "progs/shambler.mdl"); + + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 600; + + self.th_stand = sham_stand1; + self.th_walk = sham_walk1; + self.th_run = sham_run1; + self.th_die = sham_die; + self.th_melee = sham_melee; + self.th_missile = sham_magic1; + self.th_pain = sham_pain; + + walkmonster_start(); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/soldier.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/soldier.qc new file mode 100755 index 00000000..f1632f54 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/soldier.qc @@ -0,0 +1,284 @@ +/* +============================================================================== + +SOLDIER / PLAYER + +============================================================================== +*/ + +$cd id1/models/soldier3 +$origin 0 -6 24 +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 + +$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8 +$frame deathc9 deathc10 deathc11 + +$frame load1 load2 load3 load4 load5 load6 load7 load8 load9 load10 load11 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10 +$frame painb11 painb12 painb13 painb14 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10 +$frame painc11 painc12 painc13 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 shoot7 shoot8 shoot9 + +$frame prowl_1 prowl_2 prowl_3 prowl_4 prowl_5 prowl_6 prowl_7 prowl_8 +$frame prowl_9 prowl_10 prowl_11 prowl_12 prowl_13 prowl_14 prowl_15 prowl_16 +$frame prowl_17 prowl_18 prowl_19 prowl_20 prowl_21 prowl_22 prowl_23 prowl_24 + +/* +============================================================================== +SOLDIER CODE +============================================================================== +*/ + +void() army_fire; + +void() army_stand1 =[ $stand1, army_stand2 ] {ai_stand();}; +void() army_stand2 =[ $stand2, army_stand3 ] {ai_stand();}; +void() army_stand3 =[ $stand3, army_stand4 ] {ai_stand();}; +void() army_stand4 =[ $stand4, army_stand5 ] {ai_stand();}; +void() army_stand5 =[ $stand5, army_stand6 ] {ai_stand();}; +void() army_stand6 =[ $stand6, army_stand7 ] {ai_stand();}; +void() army_stand7 =[ $stand7, army_stand8 ] {ai_stand();}; +void() army_stand8 =[ $stand8, army_stand1 ] {ai_stand();}; + +void() army_walk1 =[ $prowl_1, army_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE); +ai_walk(1);}; +void() army_walk2 =[ $prowl_2, army_walk3 ] {ai_walk(1);}; +void() army_walk3 =[ $prowl_3, army_walk4 ] {ai_walk(1);}; +void() army_walk4 =[ $prowl_4, army_walk5 ] {ai_walk(1);}; +void() army_walk5 =[ $prowl_5, army_walk6 ] {ai_walk(2);}; +void() army_walk6 =[ $prowl_6, army_walk7 ] {ai_walk(3);}; +void() army_walk7 =[ $prowl_7, army_walk8 ] {ai_walk(4);}; +void() army_walk8 =[ $prowl_8, army_walk9 ] {ai_walk(4);}; +void() army_walk9 =[ $prowl_9, army_walk10 ] {ai_walk(2);}; +void() army_walk10 =[ $prowl_10, army_walk11 ] {ai_walk(2);}; +void() army_walk11 =[ $prowl_11, army_walk12 ] {ai_walk(2);}; +void() army_walk12 =[ $prowl_12, army_walk13 ] {ai_walk(1);}; +void() army_walk13 =[ $prowl_13, army_walk14 ] {ai_walk(0);}; +void() army_walk14 =[ $prowl_14, army_walk15 ] {ai_walk(1);}; +void() army_walk15 =[ $prowl_15, army_walk16 ] {ai_walk(1);}; +void() army_walk16 =[ $prowl_16, army_walk17 ] {ai_walk(1);}; +void() army_walk17 =[ $prowl_17, army_walk18 ] {ai_walk(3);}; +void() army_walk18 =[ $prowl_18, army_walk19 ] {ai_walk(3);}; +void() army_walk19 =[ $prowl_19, army_walk20 ] {ai_walk(3);}; +void() army_walk20 =[ $prowl_20, army_walk21 ] {ai_walk(3);}; +void() army_walk21 =[ $prowl_21, army_walk22 ] {ai_walk(2);}; +void() army_walk22 =[ $prowl_22, army_walk23 ] {ai_walk(1);}; +void() army_walk23 =[ $prowl_23, army_walk24 ] {ai_walk(1);}; +void() army_walk24 =[ $prowl_24, army_walk1 ] {ai_walk(1);}; + +void() army_run1 =[ $run1, army_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE); +ai_run(11);}; +void() army_run2 =[ $run2, army_run3 ] {ai_run(15);}; +void() army_run3 =[ $run3, army_run4 ] {ai_run(10);}; +void() army_run4 =[ $run4, army_run5 ] {ai_run(10);}; +void() army_run5 =[ $run5, army_run6 ] {ai_run(8);}; +void() army_run6 =[ $run6, army_run7 ] {ai_run(15);}; +void() army_run7 =[ $run7, army_run8 ] {ai_run(10);}; +void() army_run8 =[ $run8, army_run1 ] {ai_run(8);}; + +void() army_atk1 =[ $shoot1, army_atk2 ] {ai_face();}; +void() army_atk2 =[ $shoot2, army_atk3 ] {ai_face();}; +void() army_atk3 =[ $shoot3, army_atk4 ] {ai_face();}; +void() army_atk4 =[ $shoot4, army_atk5 ] {ai_face();}; +void() army_atk5 =[ $shoot5, army_atk6 ] {ai_face();army_fire(); +self.effects = self.effects | EF_MUZZLEFLASH;}; +void() army_atk6 =[ $shoot6, army_atk7 ] {ai_face();}; +void() army_atk7 =[ $shoot7, army_atk8 ] {ai_face();SUB_CheckRefire (army_atk1);}; +void() army_atk8 =[ $shoot8, army_atk9 ] {ai_face();}; +void() army_atk9 =[ $shoot9, army_run1 ] {ai_face();}; + + +void() army_pain1 =[ $pain1, army_pain2 ] {}; +void() army_pain2 =[ $pain2, army_pain3 ] {}; +void() army_pain3 =[ $pain3, army_pain4 ] {}; +void() army_pain4 =[ $pain4, army_pain5 ] {}; +void() army_pain5 =[ $pain5, army_pain6 ] {}; +void() army_pain6 =[ $pain6, army_run1 ] {ai_pain(1);}; + +void() army_painb1 =[ $painb1, army_painb2 ] {}; +void() army_painb2 =[ $painb2, army_painb3 ] {ai_painforward(13);}; +void() army_painb3 =[ $painb3, army_painb4 ] {ai_painforward(9);}; +void() army_painb4 =[ $painb4, army_painb5 ] {}; +void() army_painb5 =[ $painb5, army_painb6 ] {}; +void() army_painb6 =[ $painb6, army_painb7 ] {}; +void() army_painb7 =[ $painb7, army_painb8 ] {}; +void() army_painb8 =[ $painb8, army_painb9 ] {}; +void() army_painb9 =[ $painb9, army_painb10] {}; +void() army_painb10=[ $painb10, army_painb11] {}; +void() army_painb11=[ $painb11, army_painb12] {}; +void() army_painb12=[ $painb12, army_painb13] {ai_pain(2);}; +void() army_painb13=[ $painb13, army_painb14] {}; +void() army_painb14=[ $painb14, army_run1 ] {}; + +void() army_painc1 =[ $painc1, army_painc2 ] {}; +void() army_painc2 =[ $painc2, army_painc3 ] {ai_pain(1);}; +void() army_painc3 =[ $painc3, army_painc4 ] {}; +void() army_painc4 =[ $painc4, army_painc5 ] {}; +void() army_painc5 =[ $painc5, army_painc6 ] {ai_painforward(1);}; +void() army_painc6 =[ $painc6, army_painc7 ] {ai_painforward(1);}; +void() army_painc7 =[ $painc7, army_painc8 ] {}; +void() army_painc8 =[ $painc8, army_painc9 ] {ai_pain(1);}; +void() army_painc9 =[ $painc9, army_painc10] {ai_painforward(4);}; +void() army_painc10=[ $painc10, army_painc11] {ai_painforward(3);}; +void() army_painc11=[ $painc11, army_painc12] {ai_painforward(6);}; +void() army_painc12=[ $painc12, army_painc13] {ai_painforward(8);}; +void() army_painc13=[ $painc13, army_run1] {}; + +void(entity attacker, float damage) army_pain = +{ + local float r; + + if (self.pain_finished > time) + return; + + r = random(); + + if (r < 0.2) + { + self.pain_finished = time + 0.6; + army_pain1 (); + sound (self, CHAN_VOICE, "soldier/pain1.wav", 1, ATTN_NORM); + } + else if (r < 0.6) + { + self.pain_finished = time + 1.1; + army_painb1 (); + sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM); + } + else + { + self.pain_finished = time + 1.1; + army_painc1 (); + sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM); + } +}; + + +void() army_fire = +{ + local vector dir; + local entity en; + + ai_face(); + + sound (self, CHAN_WEAPON, "soldier/sattck1.wav", 1, ATTN_NORM); + +// fire somewhat behind the player, so a dodging player is harder to hit + en = self.enemy; + + dir = en.origin - en.velocity*0.2; + dir = normalize (dir - self.origin); + + FireBullets (4, dir, '0.1 0.1 0'); +}; + + + +void() army_die1 =[ $death1, army_die2 ] {}; +void() army_die2 =[ $death2, army_die3 ] {}; +void() army_die3 =[ $death3, army_die4 ] +{self.solid = SOLID_NOT;self.ammo_shells = 5;DropBackpack();}; +void() army_die4 =[ $death4, army_die5 ] {}; +void() army_die5 =[ $death5, army_die6 ] {}; +void() army_die6 =[ $death6, army_die7 ] {}; +void() army_die7 =[ $death7, army_die8 ] {}; +void() army_die8 =[ $death8, army_die9 ] {}; +void() army_die9 =[ $death9, army_die10 ] {}; +void() army_die10 =[ $death10, army_die10 ] {}; + +void() army_cdie1 =[ $deathc1, army_cdie2 ] {}; +void() army_cdie2 =[ $deathc2, army_cdie3 ] {ai_back(5);}; +void() army_cdie3 =[ $deathc3, army_cdie4 ] +{self.solid = SOLID_NOT;self.ammo_shells = 5;DropBackpack();ai_back(4);}; +void() army_cdie4 =[ $deathc4, army_cdie5 ] {ai_back(13);}; +void() army_cdie5 =[ $deathc5, army_cdie6 ] {ai_back(3);}; +void() army_cdie6 =[ $deathc6, army_cdie7 ] {ai_back(4);}; +void() army_cdie7 =[ $deathc7, army_cdie8 ] {}; +void() army_cdie8 =[ $deathc8, army_cdie9 ] {}; +void() army_cdie9 =[ $deathc9, army_cdie10 ] {}; +void() army_cdie10 =[ $deathc10, army_cdie11 ] {}; +void() army_cdie11 =[ $deathc11, army_cdie11 ] {}; + + +void() army_die = +{ +// check for gib + if (self.health < -35) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_guard.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "soldier/death1.wav", 1, ATTN_NORM); + if (random() < 0.5) + army_die1 (); + else + army_cdie1 (); +}; + + +/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_army = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/soldier.mdl"); + precache_model ("progs/h_guard.mdl"); + precache_model ("progs/gib1.mdl"); + precache_model ("progs/gib2.mdl"); + precache_model ("progs/gib3.mdl"); + + precache_sound ("soldier/death1.wav"); + precache_sound ("soldier/idle.wav"); + precache_sound ("soldier/pain1.wav"); + precache_sound ("soldier/pain2.wav"); + precache_sound ("soldier/sattck1.wav"); + precache_sound ("soldier/sight1.wav"); + + precache_sound ("player/udeath.wav"); // gib death + + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/soldier.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 30; + + self.th_stand = army_stand1; + self.th_walk = army_walk1; + self.th_run = army_run1; + self.th_missile = army_atk1; + self.th_pain = army_pain; + self.th_die = army_die; + + walkmonster_start (); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/sprites.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/sprites.qc new file mode 100755 index 00000000..6874f595 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/sprites.qc @@ -0,0 +1,26 @@ + +// these are the only sprites still in the game... + +$spritename s_explod +$type vp_parallel +$load id1/gfx/sprites/explod03.lbm +$frame 24 24 56 56 +$frame 120 24 56 56 +$frame 216 24 56 56 +$frame 24 88 56 56 +$frame 120 88 56 56 +$frame 216 88 56 56 + + +$spritename s_bubble +$type vp_parallel +$load id1/gfx/sprites/bubble.lbm +$frame 16 16 16 16 +$frame 40 16 16 16 + + +$spritename s_light +$type vp_parallel +$load id1/gfx/sprites/light.lbm +$frame 104 32 32 32 + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/subs.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/subs.qc new file mode 100755 index 00000000..050aa88e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/subs.qc differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/tarbaby.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/tarbaby.qc new file mode 100755 index 00000000..15b2b6ec --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/tarbaby.qc @@ -0,0 +1,222 @@ +/* +============================================================================== + +BLOB + +============================================================================== +*/ + +$cd id1/models/tarbaby +$origin 0 0 24 +$base base + +$skin skin + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 +$frame walk11 walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19 +$frame walk20 walk21 walk22 walk23 walk24 walk25 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 run13 +$frame run14 run15 run16 run17 run18 run19 run20 run21 run22 run23 +$frame run24 run25 + +$frame jump1 jump2 jump3 jump4 jump5 jump6 + +$frame fly1 fly2 fly3 fly4 + +$frame exp + +void() tbaby_stand1 =[ $walk1, tbaby_stand1 ] {ai_stand();}; + +void() tbaby_hang1 =[ $walk1, tbaby_hang1 ] {ai_stand();}; + +void() tbaby_walk1 =[ $walk1, tbaby_walk2 ] {ai_turn();}; +void() tbaby_walk2 =[ $walk2, tbaby_walk3 ] {ai_turn();}; +void() tbaby_walk3 =[ $walk3, tbaby_walk4 ] {ai_turn();}; +void() tbaby_walk4 =[ $walk4, tbaby_walk5 ] {ai_turn();}; +void() tbaby_walk5 =[ $walk5, tbaby_walk6 ] {ai_turn();}; +void() tbaby_walk6 =[ $walk6, tbaby_walk7 ] {ai_turn();}; +void() tbaby_walk7 =[ $walk7, tbaby_walk8 ] {ai_turn();}; +void() tbaby_walk8 =[ $walk8, tbaby_walk9 ] {ai_turn();}; +void() tbaby_walk9 =[ $walk9, tbaby_walk10 ] {ai_turn();}; +void() tbaby_walk10 =[ $walk10, tbaby_walk11 ] {ai_turn();}; +void() tbaby_walk11 =[ $walk11, tbaby_walk12 ] {ai_walk(2);}; +void() tbaby_walk12 =[ $walk12, tbaby_walk13 ] {ai_walk(2);}; +void() tbaby_walk13 =[ $walk13, tbaby_walk14 ] {ai_walk(2);}; +void() tbaby_walk14 =[ $walk14, tbaby_walk15 ] {ai_walk(2);}; +void() tbaby_walk15 =[ $walk15, tbaby_walk16 ] {ai_walk(2);}; +void() tbaby_walk16 =[ $walk16, tbaby_walk17 ] {ai_walk(2);}; +void() tbaby_walk17 =[ $walk17, tbaby_walk18 ] {ai_walk(2);}; +void() tbaby_walk18 =[ $walk18, tbaby_walk19 ] {ai_walk(2);}; +void() tbaby_walk19 =[ $walk19, tbaby_walk20 ] {ai_walk(2);}; +void() tbaby_walk20 =[ $walk20, tbaby_walk21 ] {ai_walk(2);}; +void() tbaby_walk21 =[ $walk21, tbaby_walk22 ] {ai_walk(2);}; +void() tbaby_walk22 =[ $walk22, tbaby_walk23 ] {ai_walk(2);}; +void() tbaby_walk23 =[ $walk23, tbaby_walk24 ] {ai_walk(2);}; +void() tbaby_walk24 =[ $walk24, tbaby_walk25 ] {ai_walk(2);}; +void() tbaby_walk25 =[ $walk25, tbaby_walk1 ] {ai_walk(2);}; + +void() tbaby_run1 =[ $run1, tbaby_run2 ] {ai_face();}; +void() tbaby_run2 =[ $run2, tbaby_run3 ] {ai_face();}; +void() tbaby_run3 =[ $run3, tbaby_run4 ] {ai_face();}; +void() tbaby_run4 =[ $run4, tbaby_run5 ] {ai_face();}; +void() tbaby_run5 =[ $run5, tbaby_run6 ] {ai_face();}; +void() tbaby_run6 =[ $run6, tbaby_run7 ] {ai_face();}; +void() tbaby_run7 =[ $run7, tbaby_run8 ] {ai_face();}; +void() tbaby_run8 =[ $run8, tbaby_run9 ] {ai_face();}; +void() tbaby_run9 =[ $run9, tbaby_run10 ] {ai_face();}; +void() tbaby_run10 =[ $run10, tbaby_run11 ] {ai_face();}; +void() tbaby_run11 =[ $run11, tbaby_run12 ] {ai_run(2);}; +void() tbaby_run12 =[ $run12, tbaby_run13 ] {ai_run(2);}; +void() tbaby_run13 =[ $run13, tbaby_run14 ] {ai_run(2);}; +void() tbaby_run14 =[ $run14, tbaby_run15 ] {ai_run(2);}; +void() tbaby_run15 =[ $run15, tbaby_run16 ] {ai_run(2);}; +void() tbaby_run16 =[ $run16, tbaby_run17 ] {ai_run(2);}; +void() tbaby_run17 =[ $run17, tbaby_run18 ] {ai_run(2);}; +void() tbaby_run18 =[ $run18, tbaby_run19 ] {ai_run(2);}; +void() tbaby_run19 =[ $run19, tbaby_run20 ] {ai_run(2);}; +void() tbaby_run20 =[ $run20, tbaby_run21 ] {ai_run(2);}; +void() tbaby_run21 =[ $run21, tbaby_run22 ] {ai_run(2);}; +void() tbaby_run22 =[ $run22, tbaby_run23 ] {ai_run(2);}; +void() tbaby_run23 =[ $run23, tbaby_run24 ] {ai_run(2);}; +void() tbaby_run24 =[ $run24, tbaby_run25 ] {ai_run(2);}; +void() tbaby_run25 =[ $run25, tbaby_run1 ] {ai_run(2);}; + + +//============================================================================ + + +void() tbaby_jump1; + +void() Tar_JumpTouch = +{ + local float ldmg; + + if (other.takedamage && other.classname != self.classname) + { + if ( vlen(self.velocity) > 400 ) + { + ldmg = 10 + 10*random(); + T_Damage (other, self, self, ldmg); + sound (self, CHAN_WEAPON, "blob/hit1.wav", 1, ATTN_NORM); + } + } + else + sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM); + + + if (!checkbottom(self)) + { + if (self.flags & FL_ONGROUND) + { // jump randomly to not get hung up +//dprint ("popjump\n"); + self.touch = SUB_Null; + self.think = tbaby_run1; + self.movetype = MOVETYPE_STEP; + self.nextthink = time + 0.1; + +// self.velocity_x = (random() - 0.5) * 600; +// self.velocity_y = (random() - 0.5) * 600; +// self.velocity_z = 200; +// self.flags = self.flags - FL_ONGROUND; + } + return; // not on ground yet + } + + self.touch = SUB_Null; + self.think = tbaby_jump1; + self.nextthink = time + 0.1; +}; + +void() tbaby_jump5; + +void() tbaby_fly1 =[ $fly1, tbaby_fly2 ] {}; +void() tbaby_fly2 =[ $fly2, tbaby_fly3 ] {}; +void() tbaby_fly3 =[ $fly3, tbaby_fly4 ] {}; +void() tbaby_fly4 =[ $fly4, tbaby_fly1 ] { +self.cnt = self.cnt + 1; +if (self.cnt == 4) +{ +//dprint ("spawn hop\n"); +tbaby_jump5 (); +} +}; + +void() tbaby_jump1 =[ $jump1, tbaby_jump2 ] {ai_face();}; +void() tbaby_jump2 =[ $jump2, tbaby_jump3 ] {ai_face();}; +void() tbaby_jump3 =[ $jump3, tbaby_jump4 ] {ai_face();}; +void() tbaby_jump4 =[ $jump4, tbaby_jump5 ] {ai_face();}; +void() tbaby_jump5 =[ $jump5, tbaby_jump6 ] +{ + self.movetype = MOVETYPE_BOUNCE; + self.touch = Tar_JumpTouch; + makevectors (self.angles); + self.origin_z = self.origin_z + 1; + self.velocity = v_forward * 600 + '0 0 200'; + self.velocity_z = self.velocity_z + random()*150; + if (self.flags & FL_ONGROUND) + self.flags = self.flags - FL_ONGROUND; + self.cnt = 0; +}; +void() tbaby_jump6 =[ $jump6,tbaby_fly1 ] {}; + + + +//============================================================================= + +void() tbaby_die1 =[ $exp, tbaby_die2 ] { +self.takedamage = DAMAGE_NO; +}; +void() tbaby_die2 =[ $exp, tbaby_run1 ] +{ + T_RadiusDamage (self, self, 120, world); + + sound (self, CHAN_VOICE, "blob/death1.wav", 1, ATTN_NORM); + self.origin = self.origin - 8*normalize(self.velocity); + + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_TAREXPLOSION); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); + + CreateExplosion (self.origin); +}; + +//============================================================================= + + +/*QUAKED monster_tarbaby (1 0 0) (-16 -16 -24) (16 16 24) Ambush +*/ +void() monster_tarbaby = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/tarbaby.mdl"); + + precache_sound2 ("blob/death1.wav"); + precache_sound2 ("blob/hit1.wav"); + precache_sound2 ("blob/land1.wav"); + precache_sound2 ("blob/sight1.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/tarbaby.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 80; + + self.th_stand = tbaby_stand1; + self.th_walk = tbaby_walk1; + self.th_run = tbaby_run1; + self.th_missile = tbaby_jump1; + self.th_melee = tbaby_jump1; + self.th_die = tbaby_die1; + + walkmonster_start (); +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/triggers.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/triggers.qc new file mode 100755 index 00000000..03fe4071 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/triggers.qc @@ -0,0 +1,641 @@ + +entity s; + + +void() trigger_reactivate = +{ + self.solid = SOLID_TRIGGER; +}; + +//============================================================================= + +float SPAWNFLAG_NOMESSAGE = 1; +float SPAWNFLAG_NOTOUCH = 1; + +// the wait time has passed, so set back up for another activation +void() multi_wait = +{ + if (self.max_health) + { + self.health = self.max_health; + self.takedamage = DAMAGE_YES; + self.solid = SOLID_BBOX; + } +}; + + +// the trigger was just touched/killed/used +// self.enemy should be set to the activator so it can be held through a delay +// so wait for the delay time before firing +void() multi_trigger = +{ + if (self.nextthink > time) + { + return; // allready been triggered + } + + if (self.classname == "trigger_secret") + { + if (self.enemy.classname != "player") + return; + found_secrets = found_secrets + 1; + WriteByte (MSG_ALL, SVC_FOUNDSECRET); + } + + if (self.noise) + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + +// don't trigger again until reset + self.takedamage = DAMAGE_NO; + + activator = self.enemy; + + SUB_UseTargets(); + + if (self.wait > 0) + { + self.think = multi_wait; + self.nextthink = time + self.wait; + } + else + { // we can't just remove (self) here, because this is a touch function + // called wheil C code is looping through area links... + self.touch = SUB_Null; + self.nextthink = time + 0.1; + self.think = SUB_Remove; + } +}; + +void() multi_killed = +{ + self.enemy = damage_attacker; + multi_trigger(); +}; + +void() multi_use = +{ + self.enemy = activator; + multi_trigger(); +}; + +void() multi_touch = +{ + if (other.classname != "player") + return; + +// if the trigger has an angles field, check player's facing direction + if (self.movedir != '0 0 0') + { + makevectors (other.angles); + if (v_forward * self.movedir < 0) + return; // not facing the right way + } + + self.enemy = other; + multi_trigger (); +}; + +/*QUAKED trigger_multiple (.5 .5 .5) ? notouch +Variable sized repeatable trigger. Must be targeted at one or more entities. If "health" is set, the trigger must be killed to activate each time. +If "delay" is set, the trigger waits some time after activating before firing. +"wait" : Seconds between triggerings. (.2 default) +If notouch is set, the trigger is only fired by other entities, not by touching. +NOTOUCH has been obsoleted by trigger_relay! +sounds +1) secret +2) beep beep +3) large switch +4) +set "message" to text string +*/ +void() trigger_multiple = +{ + if (self.sounds == 1) + { + precache_sound ("misc/secret.wav"); + self.noise = "misc/secret.wav"; + } + else if (self.sounds == 2) + { + precache_sound ("misc/talk.wav"); + self.noise = "misc/talk.wav"; + } + else if (self.sounds == 3) + { + precache_sound ("misc/trigger1.wav"); + self.noise = "misc/trigger1.wav"; + } + + if (!self.wait) + self.wait = 0.2; + self.use = multi_use; + + InitTrigger (); + + if (self.health) + { + if (self.spawnflags & SPAWNFLAG_NOTOUCH) + objerror ("health and notouch don't make sense\n"); + self.max_health = self.health; + self.th_die = multi_killed; + self.takedamage = DAMAGE_YES; + self.solid = SOLID_BBOX; + setorigin (self, self.origin); // make sure it links into the world + } + else + { + if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) ) + { + self.touch = multi_touch; + } + } +}; + + +/*QUAKED trigger_once (.5 .5 .5) ? notouch +Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching +"targetname". If "health" is set, the trigger must be killed to activate. +If notouch is set, the trigger is only fired by other entities, not by touching. +if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired. +if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0. +sounds +1) secret +2) beep beep +3) large switch +4) +set "message" to text string +*/ +void() trigger_once = +{ + self.wait = -1; + trigger_multiple(); +}; + +//============================================================================= + +/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) +This fixed size trigger cannot be touched, it can only be fired by other events. It can contain killtargets, targets, delays, and messages. +*/ +void() trigger_relay = +{ + self.use = SUB_UseTargets; +}; + + +//============================================================================= + +/*QUAKED trigger_secret (.5 .5 .5) ? +secret counter trigger +sounds +1) secret +2) beep beep +3) +4) +set "message" to text string +*/ +void() trigger_secret = +{ + total_secrets = total_secrets + 1; + self.wait = -1; + if (!self.message) + self.message = "You found a secret area!"; + if (!self.sounds) + self.sounds = 1; + + if (self.sounds == 1) + { + precache_sound ("misc/secret.wav"); + self.noise = "misc/secret.wav"; + } + else if (self.sounds == 2) + { + precache_sound ("misc/talk.wav"); + self.noise = "misc/talk.wav"; + } + + trigger_multiple (); +}; + +//============================================================================= + + +void() counter_use = +{ + + self.count = self.count - 1; + if (self.count < 0) + return; + + if (self.count != 0) + { + if (activator.classname == "player" + && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0) + { + if (self.count >= 4) + centerprint (activator, "There are more to go..."); + else if (self.count == 3) + centerprint (activator, "Only 3 more to go..."); + else if (self.count == 2) + centerprint (activator, "Only 2 more to go..."); + else + centerprint (activator, "Only 1 more to go..."); + } + return; + } + + if (activator.classname == "player" + && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0) + centerprint(activator, "Sequence completed!"); + self.enemy = activator; + multi_trigger (); +}; + +/*QUAKED trigger_counter (.5 .5 .5) ? nomessage +Acts as an intermediary for an action that takes multiple inputs. + +If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished. + +After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself. +*/ +void() trigger_counter = +{ + self.wait = -1; + if (!self.count) + self.count = 2; + + self.use = counter_use; +}; + + +/* +============================================================================== + +TELEPORT TRIGGERS + +============================================================================== +*/ + +float PLAYER_ONLY = 1; +float SILENT = 2; + +void() play_teleport = +{ + local float v; + local string tmpstr; + + v = random() * 5; + if (v < 1) + tmpstr = "misc/r_tele1.wav"; + else if (v < 2) + tmpstr = "misc/r_tele2.wav"; + else if (v < 3) + tmpstr = "misc/r_tele3.wav"; + else if (v < 4) + tmpstr = "misc/r_tele4.wav"; + else + tmpstr = "misc/r_tele5.wav"; + + sound (self, CHAN_VOICE, tmpstr, 1, ATTN_NORM); + remove (self); +}; + +void(vector org) spawn_tfog = +{ + s = spawn (); + s.origin = org; + s.nextthink = time + 0.2; + s.think = play_teleport; + + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_TELEPORT); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); +}; + + +void() tdeath_touch = +{ + if (other == self.owner) + return; + +// frag anyone who teleports in on top of an invincible player + if (other.classname == "player") + { + if (other.invincible_finished > time) + self.classname = "teledeath2"; + if (self.owner.classname != "player") + { // other monsters explode themselves + T_Damage (self.owner, self, self, 50000); + return; + } + + } + + if (other.health) + { + T_Damage (other, self, self, 50000); + } +}; + + +void(vector org, entity death_owner) spawn_tdeath = +{ +local entity death; + + death = spawn(); + death.classname = "teledeath"; + death.movetype = MOVETYPE_NONE; + death.solid = SOLID_TRIGGER; + death.angles = '0 0 0'; + setsize (death, death_owner.mins - '1 1 1', death_owner.maxs + '1 1 1'); + setorigin (death, org); + death.touch = tdeath_touch; + death.nextthink = time + 0.2; + death.think = SUB_Remove; + death.owner = death_owner; + + force_retouch = 2; // make sure even still objects get hit +}; + +void() teleport_touch = +{ +local entity t; +local vector org; + + if (self.targetname) + { + if (self.nextthink < time) + { + return; // not fired yet + } + } + + if (self.spawnflags & PLAYER_ONLY) + { + if (other.classname != "player") + return; + } + +// only teleport living creatures + if (other.health <= 0 || other.solid != SOLID_SLIDEBOX) + return; + + SUB_UseTargets (); + +// put a tfog where the player was + spawn_tfog (other.origin); + + t = find (world, targetname, self.target); + if (!t) + objerror ("couldn't find target"); + +// spawn a tfog flash in front of the destination + makevectors (t.mangle); + org = t.origin + 32 * v_forward; + + spawn_tfog (org); + spawn_tdeath(t.origin, other); + +// move the player and lock him down for a little while + if (!other.health) + { + other.origin = t.origin; + other.velocity = (v_forward * other.velocity_x) + (v_forward * other.velocity_y); + return; + } + + setorigin (other, t.origin); + other.angles = t.mangle; + if (other.classname == "player") + { + other.fixangle = 1; // turn this way immediately + other.teleport_time = time + 0.7; + if (other.flags & FL_ONGROUND) + other.flags = other.flags - FL_ONGROUND; + other.velocity = v_forward * 300; + } + other.flags = other.flags - other.flags & FL_ONGROUND; +}; + +/*QUAKED info_teleport_destination (.5 .5 .5) (-8 -8 -8) (8 8 32) +This is the destination marker for a teleporter. It should have a "targetname" field with the same value as a teleporter's "target" field. +*/ +void() info_teleport_destination = +{ +// this does nothing, just serves as a target spot + self.mangle = self.angles; + self.angles = '0 0 0'; + self.model = ""; + self.origin = self.origin + '0 0 27'; + if (!self.targetname) + objerror ("no targetname"); +}; + +void() teleport_use = +{ + self.nextthink = time + 0.2; + force_retouch = 2; // make sure even still objects get hit + self.think = SUB_Null; +}; + +/*QUAKED trigger_teleport (.5 .5 .5) ? PLAYER_ONLY SILENT +Any object touching this will be transported to the corresponding info_teleport_destination entity. You must set the "target" field, and create an object with a "targetname" field that matches. + +If the trigger_teleport has a targetname, it will only teleport entities when it has been fired. +*/ +void() trigger_teleport = +{ + local vector o; + + InitTrigger (); + self.touch = teleport_touch; + // find the destination + if (!self.target) + objerror ("no target"); + self.use = teleport_use; + + if (!(self.spawnflags & SILENT)) + { + precache_sound ("ambience/hum1.wav"); + o = (self.mins + self.maxs)*0.5; + ambientsound (o, "ambience/hum1.wav",0.5 , ATTN_STATIC); + } +}; + +/* +============================================================================== + +trigger_setskill + +============================================================================== +*/ + +void() trigger_skill_touch = +{ + if (other.classname != "player") + return; + + cvar_set ("skill", self.message); +}; + +/*QUAKED trigger_setskill (.5 .5 .5) ? +sets skill level to the value of "message". +Only used on start map. +*/ +void() trigger_setskill = +{ + InitTrigger (); + self.touch = trigger_skill_touch; +}; + + +/* +============================================================================== + +ONLY REGISTERED TRIGGERS + +============================================================================== +*/ + +void() trigger_onlyregistered_touch = +{ + if (other.classname != "player") + return; + if (self.attack_finished > time) + return; + + self.attack_finished = time + 2; + if (cvar("registered")) + { + self.message = ""; + SUB_UseTargets (); + remove (self); + } + else + { + if (self.message != "") + { + centerprint (other, self.message); + sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM); + } + } +}; + +/*QUAKED trigger_onlyregistered (.5 .5 .5) ? +Only fires if playing the registered version, otherwise prints the message +*/ +void() trigger_onlyregistered = +{ + precache_sound ("misc/talk.wav"); + InitTrigger (); + self.touch = trigger_onlyregistered_touch; +}; + +//============================================================================ + +void() hurt_on = +{ + self.solid = SOLID_TRIGGER; + self.nextthink = -1; +}; + +void() hurt_touch = +{ + if (other.takedamage) + { + self.solid = SOLID_NOT; + T_Damage (other, self, self, self.dmg); + self.think = hurt_on; + self.nextthink = time + 1; + } + + return; +}; + +/*QUAKED trigger_hurt (.5 .5 .5) ? +Any object touching this will be hurt +set dmg to damage amount +defalt dmg = 5 +*/ +void() trigger_hurt = +{ + InitTrigger (); + self.touch = hurt_touch; + if (!self.dmg) + self.dmg = 5; +}; + +//============================================================================ + +float PUSH_ONCE = 1; + +void() trigger_push_touch = +{ + if (other.classname == "grenade") + other.velocity = self.speed * self.movedir * 10; + else if (other.health > 0) + { + 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); + } + } + } + if (self.spawnflags & PUSH_ONCE) + remove(self); +}; + + +/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE +Pushes the player +*/ +void() trigger_push = +{ + InitTrigger (); + precache_sound ("ambience/windfly.wav"); + self.touch = trigger_push_touch; + if (!self.speed) + self.speed = 1000; +}; + +//============================================================================ + +void() trigger_monsterjump_touch = +{ + if ( other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER ) + return; + +// set XY even if not on ground, so the jump will clear lips + other.velocity_x = self.movedir_x * self.speed; + other.velocity_y = self.movedir_y * self.speed; + + if ( !(other.flags & FL_ONGROUND) ) + return; + + other.flags = other.flags - FL_ONGROUND; + + other.velocity_z = self.height; +}; + +/*QUAKED trigger_monsterjump (.5 .5 .5) ? +Walking monsters that touch this will jump in the direction of the trigger's angle +"speed" default to 200, the speed thrown forward +"height" default to 200, the speed thrown upwards +*/ +void() trigger_monsterjump = +{ + if (!self.speed) + self.speed = 200; + if (!self.height) + self.height = 200; + if (self.angles == '0 0 0') + self.angles = '0 360 0'; + InitTrigger (); + self.touch = trigger_monsterjump_touch; +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/v_shot.mdl b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/v_shot.mdl new file mode 100755 index 00000000..02195715 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/v_shot.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/weapons.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/weapons.qc new file mode 100755 index 00000000..5217499c --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/weapons.qc @@ -0,0 +1,2478 @@ +/* +*/ + +void (entity targ, entity inflictor, entity attacker, float damage) T_Damage; +void () player_run; +void(entity inflictor, entity attacker, float radius, entity ignore) T_RadiusDamage; +void() SuperDamageSound; + +// called by worldspawn +void() W_Precache = +{ + precache_sound ("weapons/r_exp3.wav"); // new rocket explosion + precache_sound ("weapons/rocket1i.wav"); // spike gun + precache_sound ("weapons/sgun1.wav"); + precache_sound ("weapons/guncock.wav"); // player shotgun + //precache_sound ("weapons/ric1.wav"); // ricochet (used in c code) + //precache_sound ("weapons/ric2.wav"); // ricochet (used in c code) + //precache_sound ("weapons/ric3.wav"); // ricochet (used in c code) + //precache_sound ("weapons/spike2.wav"); // super spikes + precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code) + //precache_sound ("weapons/grenade.wav"); // grenade launcher + precache_sound ("weapons/bounce.wav"); // grenade bounce + precache_sound ("weapons/shotgn2.wav"); // super shotgun + precache_sound ("weapons/sniper.wav"); // sniper + precache_model ("progs/blast.spr"); //blaster bullet sprite. + precache_model ("progs/sniper.mdl"); //beam for the Sniper blaster + precache_model ("progs/ric_beam.mdl"); //Beam for The richochet blaster + precache_model ("progs/null.spr"); + precache_model ("progs/body.spr"); + + //Morphball sounds + precache_sound ("weapons/boost.wav"); + precache_sound ("weapons/mb_bomb.wav"); // Morphball lays a bomb + precache_sound ("weapons/mb_explode.wav"); + precache_sound ("weapons/morphball.wav"); + precache_sound ("weapons/mb_bomb.wav"); + + //Footsteps + precache_sound ("steps/foot1.wav"); + precache_sound ("steps/foot2.wav"); + precache_sound ("steps/foot3.wav"); + precache_sound ("steps/foot4.wav"); + + //Transform Sounds + precache_sound ("weapons/blaster_transform.wav"); + precache_sound ("weapons/rocket_transform.wav"); + + //Effects + //Muzzleflashes + precache_model ("progs/blaster_muzzle.spr"); + precache_model ("progs/ric_muzzle.spr"); + precache_model ("progs/sniper_muzzle.spr"); + precache_model ("progs/splaser_muzzle.spr"); + +}; + +float() crandom = +{ + return 2*(random() - 0.5); +}; + +/* +================ +W_FireAxe +================ +*/ +void() W_FireAxe = +{ + local vector source; + local vector org; + + makevectors (self.v_angle); + source = self.origin + '0 0 16'; + traceline (source, source + v_forward*64, FALSE, self); + if (trace_fraction == 1.0) + return; + + org = trace_endpos - v_forward*4; + + if (trace_ent.takedamage) + { + trace_ent.axhitme = 1; + SpawnBlood (org, '0 0 0', 20); + T_Damage (trace_ent, self, self, 20); + } + else + { // hit wall + sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM); + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_GUNSHOT); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); + } +}; + + +//============================================================================ + + +vector() wall_velocity = +{ + local vector vel; + + vel = normalize (self.velocity); + vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5)); + vel = vel + 2*trace_plane_normal; + vel = vel * 200; + + return vel; +}; + + +/* +============================================================================== + +MULTI-DAMAGE + +Collects multiple small damages into a single damage + +============================================================================== +*/ + +entity multi_ent; +vector puff_org; +float multi_damage; + +void() ClearMultiDamage = +{ + multi_ent = world; + multi_damage = 0; +}; + +void() ApplyMultiDamage = +{ + if (!multi_ent) + return; + T_Damage (multi_ent, self, self, multi_damage); +}; + +void(entity hit, float damage) AddMultiDamage = +{ + if (!hit) + return; + + if (hit != multi_ent) + { + ApplyMultiDamage (); + multi_damage = damage; + multi_ent = hit; + } + else + multi_damage = multi_damage + damage; +}; + +/* +>>>>>>>>>>>>>>>>>>>>>>>>> +Touch Functions and Exlosions for Damage. +-I hate how all the Bullet damage functions are strewn around everywhere. This is where you Will find the Bullet-damage +For All the weapons. And I don't wanna create a new qc because I have do define Crap, and then Go there to edit. +it is Just fine right here. +<<<<<<<<<<<<<<<<<<<<<<<<< +*/ +//For something.... Just Don't care to Go look. Find it yourself in combat.qc + +vector(entity proj) bounce_off_wall = // borrowing +{ + local vector vec; + local float backoff, change; +// get the trace_plane_normal of the surface we hit + makevectors (proj.angles); + v_forward_z = v_forward_z * -1; + traceline (proj.origin, proj.origin + v_forward*64, FALSE, proj); + + if (trace_fraction == 1) + return proj.velocity; + +// the entity's velocity is not what we want, so set default + proj.velocity = v_forward * 2000;//proj.old_velocity; + +// calculate dot product + backoff = (proj.velocity * trace_plane_normal); + backoff = backoff * 1.5; + +// finish + change = trace_plane_normal_x * backoff; + vec_x = proj.velocity_x - change; + + if (vec_x > -0.1 && vec_x < 0.1) + vec_x = 0; + + change = trace_plane_normal_y * backoff; + vec_y = proj.velocity_y - change; + + if (vec_y > -0.1 && vec_y < 0.1) + vec_y = 0; + + change = trace_plane_normal_z * backoff; + vec_z = proj.velocity_z - change; + + if (vec_z > -0.1 && vec_z < 0.1) + vec_z = 0; +// set correct angles of our new velocity + sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); + proj.angles = vectoangles (vec); + // this is required to make downward slopes not stop the projectile + proj.flags = proj.flags - ( proj.flags & FL_ONGROUND ); + return vec; +} +void () bounce_a = +{ + self.velocity = bounce_off_wall( self ); +}; + +void () Bounce_Off_Walls = +{ + self.nextthink = time; + self.think = bounce_a; + + if (self.velocity == '0 0 0') + remove (self); +}; + +/* +============================= +RIC TOUCH 0 +============================ +*/ +void () ric_touch = +{ + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 10); + } + else if (self.lives > 0) { + particle (self.origin, '0 0 0', 179, 20); + Bounce_Off_Walls (); + self.lives -= 1; + return; + } + + remove(self); +}; +/* +============================= +RIC TOUCH 1 +============================ +*/ +void () ric_touch_1 = +{ + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (20); + T_Damage (other, self, self.owner, 15); + } + else if (self.lives > 0) { + particle (self.origin, '0 0 0', 179, 20); + Bounce_Off_Walls (); + self.lives -= 1; + return; + } + + remove(self); +}; +/* +============================= +RIC TOUCH 2 +============================ +*/ +void () ric_touch_2 = +{ + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (25); + T_Damage (other, self, self.owner, 20); + } + else if (self.lives > 0) { + particle (self.origin, '0 0 0', 179, 20); + Bounce_Off_Walls (); + self.lives -= 1; + return; + } + + remove(self); +}; +/* +============================= +RIC TOUCH 3 +============================ +*/ +void () ric_touch_3 = +{ + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (25); + T_Damage (other, self, self.owner, 25); + } + else if (self.lives > 0) { + particle (self.origin, '0 0 0', 179, 20); + Bounce_Off_Walls (); + self.lives -= 1; + return; + } + + remove(self); +}; +/* +========================================== +ROCKET LAUNCHER 0 +========================================== +*/ +void() Rocket_Explode0 = +{ + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + T_RadiusDamage (self, self.owner, 120, other); + + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion (self.origin); + remove(self); +}; +/* +========================================== +ROCKET LAUNCHER 1 +========================================== +*/ +void() Rocket_Explode1 = +{ + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + T_RadiusDamage (self, self.owner, 140, other); + + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion (self.origin); + remove(self); +}; +/* +========================================== +ROCKET LAUNCHER 2 +========================================== +*/ +void() Rocket_Explode2 = +{ + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + T_RadiusDamage (self, self.owner, 160, other); + + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion (self.origin); + remove(self); +}; +/* +========================================== +ROCKET LAUNCHER 3 +========================================== +*/ +void() Rocket_Explode3 = +{ + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + T_RadiusDamage (self, self.owner, 190, other); + + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion (self.origin); + remove(self); +}; +void() T_MissileTouch = +{ + local float damg; + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + + damg = 40 + random()*10; + + if (other.health) + { + T_Damage (other, self, self.owner, damg ); + } + + // don't do radius damage to the other, because all the damage + // was done in the impact + T_RadiusDamage (self, self.owner, 120, other); + +// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion (self.origin); + remove(self); +}; + +/* +============================= +Magma explode +============================ +*/ +void() magmaexplode = +{ + T_RadiusDamage (self, self.owner, 120, other); + +// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion(self.origin); + remove(self); +}; +/* +============================= +Splaser Beam touch +============================ +*/ +void(vector org) SplaserTouch = +{ + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 9); + + + } + else + { + particle (self.origin, '0 0 0', 149, 20); + puff_org = self.origin; + remove(self); + } +}; +/* +============================= +MAGMA TOUCH +============================ +*/ +void(vector org) magma_touch = +{ + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 20); + remove(self); + } + else + { + puff_org = self.origin; + self.think = magmaexplode; + self.nextthink = time + 5; + } +}; +/* +============================= +BLASTER TOUCH 0 +============================ +*/ +void(vector org) BlasterTouch = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 7); + + + } + else + { + particle (self.origin, '0 0 0', 214, 20); + puff_org = self.origin; + } + remove(self); +}; +/* +============================= +BLASTER TOUCH 1 +============================ +*/ +void(vector org) BlasterTouch1 = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 15); + + + } + else + { + particle (self.origin, '0 0 0', 214, 20); + puff_org = self.origin; + } + remove(self); +}; +/* +============================= +BLASTER TOUCH 2 +============================ +*/ +void(vector org) BlasterTouch2 = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 36); + } + else + { + particle (self.origin, '0 0 0', 214, 20); + puff_org = self.origin; + } + remove(self); +}; +//The final Blast product for Blaster. I may fix up into 1 function, But for now, "self" is the projectile. +//And other doesn't work. Nor does other.owner + +void(vector org) BlasterTouch3 = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 30); + } + else + { + particle (self.origin, '0 0 0', 214, 20); + puff_org = self.origin; + } + remove(self); +}; + +/* +============================= +SNIPER TOUCH +============================ +*/ +void () SniperTouch = +{ + local vector p_a, p_b; + local float zdif; + + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + p_a_z = self.origin_z; + p_b_z = other.origin_z; + + zdif = vlen(p_a - p_b); + //_bprint(ftos(zdif),"\n"); + if (zdif > 20) + { + T_Damage (other, self, self.owner, 150); + spawn_touchblood (18); + } + else + { + T_Damage (other, self, self.owner, 40); + spawn_touchblood (18); + } + } + else + { + particle (self.origin, '0 0 0', 251, 40); + puff_org = self.origin; + } + remove(self); +}; +/* +============================= +Morphball Exploding +============================ +*/ +void() BombExplode = +{ + local float damg; + + damg = 16; + + if (other.health) + { + if (other.classname == "player") + damg = damg = 0; + T_Damage (other, self, self.owner, damg ); + } + + T_RadiusDamage (self, self.owner, 50, other); + self.origin = self.origin - 8*normalize(self.velocity); + CreateExplosion (self.origin); + sound (self, CHAN_WEAPON, "weapons/mb_explode.wav", 1, ATTN_NORM); + remove(self); +}; + +/* +===================== +End of Touch Functions +===================== +*/ + +/* +============================================================================== + +BULLETS + +============================================================================== +*/ + + + +/* +================ +TraceAttack +================ +*/ +void(float damage, vector dir) TraceAttack = +{ + local vector vel, org; + + vel = normalize(dir + v_up*crandom() + v_right*crandom()); + vel = vel + 2*trace_plane_normal; + vel = vel * 200; + + org = trace_endpos - dir*4; + + if (trace_ent.takedamage) + { + SpawnBlood (org, vel*0.2, damage); + AddMultiDamage (trace_ent, damage); + } + else + { + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_GUNSHOT); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); + } +}; + +/* +================ +FireBullets + +Used by shotgun, super shotgun, and enemy soldier firing +Go to the trouble of combining multiple pellets into a single damage call. +================ +*/ +void(float shotcount, vector dir, vector spread) FireBullets = +{ + local vector direction; + local vector src; + + makevectors(self.v_angle); + + src = self.origin + v_forward*10; + src_z = self.absmin_z + self.size_z * 0.7; + + ClearMultiDamage (); + while (shotcount > 0) + { + direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + + traceline (src, src + direction*2048, FALSE, self); + if (trace_fraction != 1.0) + TraceAttack (4, direction); + + shotcount = shotcount - 1; + } + ApplyMultiDamage (); +}; + + +/* +======================== +MAGMA +======================== +*/ +void() W_FireMagma = +{ + local entity sniper; + blaster_flash(); + self.currentammo = self.ammo_lava = self.ammo_lava -= 1; + sound (self, CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM); + self.punchangle_x = -3; + + sniper = spawn (); + sniper.owner = self; + sniper.movetype = MOVETYPE_BOUNCE; + sniper.solid = SOLID_BBOX; + sniper.classname = "Magma"; + +// Set The Sniper bullets speed + + makevectors (self.v_angle); + sniper.velocity = aim(self, 1000); + sniper.velocity = sniper.velocity * 1000; + sniper.angles = vectoangles(sniper.velocity); + + sniper.touch = magma_touch; + + setmodel (sniper, "progs/lavaball.mdl"); + setsize (sniper, '0 0 0', '0 0 0'); + setorigin (sniper, self.origin + v_forward*10 + '0 0 16'); +}; +/* +======================== +SPLASER +======================== +*/ +void() W_FireSplaser = +{ + local entity sniper; + blaster_flash(); + self.currentammo = self.ammo_nails = self.ammo_nails -= 1; + sound (self, CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM); + self.punchangle_x = -3; + + sniper = spawn (); + sniper.owner = self; + sniper.movetype = MOVETYPE_FLYMISSILE; + sniper.solid = SOLID_BBOX; + sniper.classname = "splaser"; + +// Set The Sniper bullets speed + + makevectors (self.v_angle); + sniper.velocity = aim(self, 1000); + sniper.velocity = sniper.velocity * 2000; //This is so It is fast Like a sniper Projectile + sniper.angles = vectoangles(sniper.velocity); + + sniper.touch = SplaserTouch; + +// set missile duration + sniper.nextthink = time + 5; + sniper.think = SUB_Remove; + sniper.frame += 1; + + setmodel (sniper, "progs/splaser_muzzle.spr"); + sniper.effects = EF_DIMLIGHT; + setsize (sniper, '0 0 0', '0 0 0'); + setorigin (sniper, self.origin + v_forward*10 + '0 0 16'); +}; +/* +======================== +SNIPER +======================== +*/ +void() W_FireSniper = +{ + local entity sniper; + blaster_flash(); + self.currentammo = self.ammo_sniper = self.ammo_sniper - 1; + sound (self, CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM); + self.punchangle_x = -3; + + sniper = spawn (); + sniper.owner = self; + sniper.movetype = MOVETYPE_FLYMISSILE; + sniper.solid = SOLID_BBOX; + sniper.classname = "Sniper"; + +// Set The Sniper bullets speed + + makevectors (self.v_angle); + sniper.velocity = aim(self, 1000); + sniper.velocity = sniper.velocity * 10000; //This is so It is fast Like a sniper Projectile + sniper.angles = vectoangles(sniper.velocity); + + sniper.touch = SniperTouch; + +// set missile duration + sniper.nextthink = time + 5; + sniper.think = SUB_Remove; + sniper.frame += 1; + + setmodel (sniper, "progs/sniper.mdl"); + sniper.effects = EF_DIMLIGHT; + setsize (sniper, '0 0 0', '0 0 0'); + setorigin (sniper, self.origin + v_forward*30 + '0 0 16'); +}; +/* +================ +BLASTER +================ +*/ +void() W_FireBlaster = +{ + + local entity plasma; + blaster_flash(); + self.currentammo = self.ammo_blaster = self.ammo_blaster - 0; + sound (self, CHAN_AUTO, "weapons/guncock.wav", 1, ATTN_NORM); + self.punchangle_x = -2; + + plasma = spawn (); + plasma.owner = self; + plasma.movetype = MOVETYPE_FLYMISSILE; + plasma.solid = SOLID_BBOX; + plasma.classname = "Plasma"; + +// Set the speed of the Plasma + + makevectors (self.v_angle); + plasma.velocity = aim(self, 1000); + if (self.charge >= 10 && self.charge <= 39) // Sets the Velocity for When charging the Blaster + plasma.velocity = plasma.velocity * 4200; + if (self.charge >= 40 && self.charge <= 69) + plasma.velocity = plasma.velocity * 3100; + if (self.charge >= 70) + plasma.velocity = plasma.velocity * 2000; + else + plasma.velocity = plasma.velocity * 4500; + + plasma.angles = vectoangles(plasma.velocity); + + if (self.charge >= 10 && self.charge <= 39) // Sets the Different Damages + plasma.touch = BlasterTouch1; + if (self.charge >= 40 && self.charge <= 69) + plasma.touch = BlasterTouch2; + if (self.charge >= 70) + plasma.touch = BlasterTouch3; + else + plasma.touch = BlasterTouch; + setmodel (plasma, "progs/blast.spr"); + if (self.charge >= 10 && self.charge <= 49) + plasma.frame = 1; + else if (self.charge >= 50) + plasma.frame = 0; + else + plasma.frame = 2; + + setsize (plasma, '0 0 0', '0 0 0'); + setorigin (plasma, self.origin + v_forward*10 + '0 0 16'); + +// set missile duration + plasma.nextthink = time + 5; + plasma.think = SUB_Remove; + self.charge = 0; +}; + +/* +================ +W_FireRic + +Has 3 Functions Because It needs 3 different origins. There are 3 slots in the Richochet beam. +================ +*/ +void() W_FireRic = +{ + + local entity plasma; + blaster_flash(); + if (self.charge >= 10 && self.charge <= 39) //Sets the amount of ammo lost when CHarging + { + if (self.ammo_ric <= 6) + self.currentammo = self.ammo_ric = self.ammo_ric - 1; + else + self.currentammo = self.ammo_ric = self.ammo_ric - 4; + } + else if (self.charge >= 40) + { + if (self.ammo_ric <= 6) + self.currentammo = self.ammo_ric = self.ammo_ric - 1; + else + self.currentammo = self.ammo_ric = self.ammo_ric - 5; + } + else + { + if (self.ammo_ric <= 6) + self.currentammo = self.ammo_ric = self.ammo_ric - 1; + else + self.currentammo = self.ammo_ric = self.ammo_ric - 3; + } + sound (self, CHAN_AUTO, "weapons/guncock.wav", 1, ATTN_NORM); + if (self.charge >= 10 && self.charge <= 39) + self.punchangle_x = -4; + else if (self.charge >= 40) + self.punchangle_x = -6; + else + self.punchangle_x = -2; + + plasma = spawn (); + plasma.owner = self; + plasma.movetype = MOVETYPE_FLYMISSILE; + plasma.solid = SOLID_BBOX; + plasma.classname = "ric"; + +// Set the speed of the Plasma + + makevectors (self.v_angle); + plasma.velocity = aim(self, 1000); + if (self.charge >= 10 && self.charge <= 39) + plasma.velocity = plasma.velocity * 2300; + else if (self.charge >= 40 && self.charge <= 69) + plasma.velocity = plasma.velocity * 2500; + else if (self.charge >= 70) + plasma.velocity = plasma.velocity * 2700; + else + plasma.velocity = plasma.velocity * 2100; + plasma.angles = vectoangles(plasma.velocity); + + if (self.charge >= 10 && self.charge <= 39) + plasma.touch = ric_touch_1; + else if (self.charge >= 40 && self.charge <= 69) + plasma.touch = ric_touch_2; + else if (self.charge >= 70) + plasma.touch = ric_touch_3; + else + plasma.touch = ric_touch; + + if (self.charge >= 40) + plasma.lives = 2 + 4 * random(); + else + plasma.lives = 2 + 2 * random(); + +// set missile duration + plasma.nextthink = time + 5; + plasma.think = SUB_Remove; + + setmodel (plasma, "progs/ric_beam.mdl"); + setsize (plasma, '0 0 0', '0 0 0'); + setorigin (plasma, self.origin + v_forward * 22 + v_right * 10.5 + '0 0 7'); +}; + +void() W_FireRic2 = +{ + + local entity plasma; + + plasma = spawn (); + plasma.owner = self; + plasma.movetype = MOVETYPE_FLYMISSILE; + plasma.solid = SOLID_BBOX; + plasma.classname = "ric"; + +// Set the speed of the Plasma + + makevectors (self.v_angle); + plasma.velocity = aim(self, 1000); + if (self.charge >= 10 && self.charge <= 39) + plasma.velocity = plasma.velocity * 2300; + else if (self.charge >= 40 && self.charge <= 69) + plasma.velocity = plasma.velocity * 2500; + else if (self.charge >= 70) + plasma.velocity = plasma.velocity * 2700; + else + plasma.velocity = plasma.velocity * 2100; + plasma.angles = vectoangles(plasma.velocity); + + if (self.charge >= 10 && self.charge <= 39) + plasma.touch = ric_touch_1; + else if (self.charge >= 40 && self.charge <= 69) + plasma.touch = ric_touch_2; + else if (self.charge >= 70) + plasma.touch = ric_touch_3; + else + plasma.touch = ric_touch; + + if (self.charge >= 40) + plasma.lives = 2 + 4 * random(); + else + plasma.lives = 2 + 2 * random(); + +// set missile duration + plasma.nextthink = time + 5; + plasma.think = SUB_Remove; + + setmodel (plasma, "progs/ric_beam.mdl"); + setsize (plasma, '0 0 0', '0 0 0'); + setorigin (plasma, self.origin + v_forward * 22 + v_right * 3.5 + '0 0 7'); +}; + +void() W_FireRic3 = +{ + + local entity plasma; + + plasma = spawn (); + plasma.owner = self; + plasma.movetype = MOVETYPE_FLYMISSILE; + plasma.solid = SOLID_BBOX; + plasma.classname = "ric"; + +// Set the speed of the Plasma + + makevectors (self.v_angle); + plasma.velocity = aim(self, 1000); + if (self.charge >= 10 && self.charge <= 39) + plasma.velocity = plasma.velocity * 2300; + else if (self.charge >= 40 && self.charge <= 69) + plasma.velocity = plasma.velocity * 2500; + else if (self.charge >= 70) + plasma.velocity = plasma.velocity * 2700; + else + plasma.velocity = plasma.velocity * 2100; + plasma.angles = vectoangles(plasma.velocity); + + if (self.charge >= 10 && self.charge <= 39) + plasma.touch = ric_touch_1; + else if (self.charge >= 40 && self.charge <= 69) + plasma.touch = ric_touch_2; + else if (self.charge >= 70) + plasma.touch = ric_touch_3; + else + plasma.touch = ric_touch; + + if (self.charge >= 40) + plasma.lives = 2 + 4 * random(); + else + plasma.lives = 2 + 2 * random(); + +// set missile duration + plasma.nextthink = time + 5; + plasma.think = SUB_Remove; + + setmodel (plasma, "progs/ric_beam.mdl"); + setsize (plasma, '0 0 0', '0 0 0'); + setorigin (plasma, self.origin + v_forward * 18 + v_right * 17.5 + '0 0 7'); +}; +/* +============================================================================== + +ROCKETS + +============================================================================== +*/ +/* +================ +W_FireRocket +================ +*/ +void() W_FireRocket = +{ + local entity missile; + if (self.charge >= 10 && self.charge < 40) + self.currentammo = self.ammo_rockets = self.ammo_rockets - 2; + else if (self.charge >= 40 && self.charge < 70) + self.currentammo = self.ammo_rockets = self.ammo_rockets - 3; + else if (self.charge >= 70) + self.currentammo = self.ammo_rockets = self.ammo_rockets - 5; + else + self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; + if (self.ammo_rockets == 0) + self.weapon = IT_BLASTER; + + sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM); + if (self.charge >= 40 && self.charge < 70) + self.punchangle_x = -4; + else if (self.charge >= 70) + self.punchangle_x = -7; + else + self.punchangle_x = -2; + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_FLYMISSILE; + missile.solid = SOLID_BBOX; + missile.classname = "missile"; + +// set missile speed + + if (self.charge >= 10 && self.charge < 40) //Dang, I messed up with making some 39 and 69 :p + { + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = missile.velocity * 1100; + missile.angles = vectoangles(missile.velocity); + } + else if (self.charge >= 40 && self.charge < 70) + { + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = missile.velocity * 1200; + missile.angles = vectoangles(missile.velocity); + } + else if (self.charge >= 70) + { + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = missile.velocity * 1500; + missile.angles = vectoangles(missile.velocity); + } + else + { + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = missile.velocity * 1000; + missile.angles = vectoangles(missile.velocity); + } + + if (self.charge >= 10 && self.charge < 40) + missile.touch = Rocket_Explode1; + else if (self.charge >= 40 && self.charge < 70) + missile.touch = Rocket_Explode2; + else if (self.charge >= 70) + missile.touch = Rocket_Explode3; + else + missile.touch = Rocket_Explode0; + +// set missile duration + missile.nextthink = time + 5; + missile.think = SUB_Remove; + + setmodel (missile, "progs/missile.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + v_forward*8 + '0 0 16'); +}; + +/* +=============================================================================== + +LIGHTNING + +=============================================================================== +*/ + +/* +================= +LightningDamage +================= +*/ +void(vector p1, vector p2, entity from, float damage) LightningDamage = +{ + local entity e1, e2; + local vector f; + + f = p2 - p1; + normalize (f); + f_x = 0 - f_y; + f_y = f_x; + f_z = 0; + f = f*16; + + e1 = e2 = world; + + traceline (p1, p2, FALSE, self); + if (trace_ent.takedamage) + { + particle (trace_endpos, '0 0 100', 225, damage*4); + T_Damage (trace_ent, from, from, damage); + if (self.classname == "player") + { + if (other.classname == "player") + trace_ent.velocity_z = trace_ent.velocity_z + 400; + } + } + e1 = trace_ent; + + traceline (p1 + f, p2 + f, FALSE, self); + if (trace_ent != e1 && trace_ent.takedamage) + { + particle (trace_endpos, '0 0 100', 225, damage*4); + T_Damage (trace_ent, from, from, damage); + } + e2 = trace_ent; + + traceline (p1 - f, p2 - f, FALSE, self); + if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage) + { + particle (trace_endpos, '0 0 100', 225, damage*4); + T_Damage (trace_ent, from, from, damage); + } +}; + + +void() W_FireLightning = +{ + local vector org; + local float cells; + + if (self.ammo_cells < 1) + { + //self.weapon = W_BestWeapon (); + W_SetCurrentAmmo (); + return; + } + +// explode if under water + if (self.waterlevel > 1) + { + cells = self.ammo_cells; + self.ammo_cells = 0; + W_SetCurrentAmmo (); + T_RadiusDamage (self, self, 35*cells, world); + return; + } + + if (self.t_width < time) + { + sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM); + self.t_width = time + 0.6; + } + self.punchangle_x = -2; + + self.currentammo = self.ammo_cells = self.ammo_cells - 1; + + org = self.origin + '0 0 16'; + + traceline (org, org + v_forward*600, TRUE, self); + + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_LIGHTNING2); + WriteEntity (MSG_BROADCAST, self); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); + WriteCoord (MSG_BROADCAST, trace_endpos_x); + WriteCoord (MSG_BROADCAST, trace_endpos_y); + WriteCoord (MSG_BROADCAST, trace_endpos_z); + + LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30); +}; + + +//============================================================================= + + +void() GrenadeExplode = +{ + T_RadiusDamage (self, self.owner, 120, world); + + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); + + CreateExplosion (self.origin); +}; + +void() GrenadeTouch = +{ + if (other == self.owner) + return; // don't explode on owner + if (other.takedamage == DAMAGE_AIM) + { + GrenadeExplode(); + return; + } + sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound + if (self.velocity == '0 0 0') + self.avelocity = '0 0 0'; +}; + +/* +================ +W_FireGrenade +================ +*/ +void() W_FireGrenade = +{ + local entity missile; + + self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; + + sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM); + + self.punchangle_x = -2; + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_BOUNCE; + missile.solid = SOLID_BBOX; + missile.classname = "grenade"; + +// set missile speed + + makevectors (self.v_angle); + + if (self.v_angle_x) + missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10; + else + { + missile.velocity = aim(self, 10000); + missile.velocity = missile.velocity * 600; + missile.velocity_z = 200; + } + + missile.avelocity = '300 300 300'; + + missile.angles = vectoangles(missile.velocity); + + missile.touch = GrenadeTouch; + +// set missile duration + missile.nextthink = time + 2.5; + missile.think = GrenadeExplode; + + setmodel (missile, "progs/grenade.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin); +}; +//For regenerating Your Bombs +void() mbomb1 = +{ +if (self.morphbombs == 3) + self.morphbombs += 1; +if (self.morphbombs == 2) + self.morphbombs += 2; +if (self.morphbombs == 1) + self.morphbombs += 3; +}; + +void() fire_morphbomb = +{ + local entity missile; + self.currentammo = self.morphbombs = self.morphbombs - 1; + sound (self, CHAN_WEAPON, "weapons/mb_bomb.wav", 1, ATTN_NORM); + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_BOUNCE; + missile.solid = SOLID_BBOX; + missile.classname = "Mbomb"; + +// set missile speed + + makevectors (self.v_angle); + + missile.avelocity = '0 0 0'; + + missile.angles = vectoangles(missile.velocity); + + +// set missile duration + missile.nextthink = time + 2.5; + missile.think = BombExplode; + + self.think = mbomb1; + self.nextthink = time + 2.5; + missile.effects = EF_DIMLIGHT; + setmodel (missile, "progs/mbomb.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + v_up * 8); +}; + + +//============================================================================= + +void() spike_touch; +void() superspike_touch; + + +/* +=============== +launch_spike + +Used for both the player and the ogre +=============== +*/ +void(vector org, vector dir) launch_spike = +{ + newmis = spawn (); + newmis.owner = self; + newmis.movetype = MOVETYPE_FLYMISSILE; + newmis.solid = SOLID_BBOX; + + newmis.angles = vectoangles(dir); + + newmis.touch = spike_touch; + newmis.classname = "spike"; + newmis.think = SUB_Remove; + newmis.nextthink = time + 6; + setmodel (newmis, "progs/spike.mdl"); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + setorigin (newmis, org); + + newmis.velocity = dir * 1000; +}; + +void() W_FireSuperSpikes = +{ + local vector dir; + + sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM); + self.attack_finished = time + 0.2; + self.currentammo = self.ammo_nails = self.ammo_nails - 2; + dir = aim (self, 1000); + launch_spike (self.origin + '0 0 16', dir); + newmis.touch = superspike_touch; + setmodel (newmis, "progs/s_spike.mdl"); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + self.punchangle_x = -2; +}; + +void(float ox) W_FireSpikes = +{ + local vector dir; + + makevectors (self.v_angle); + + if (self.ammo_nails >= 2 && self.weapon == IT_SNIPER) + { + W_FireSuperSpikes (); + return; + } + + if (self.ammo_nails < 1) + { + //self.weapon = W_BestWeapon (); + W_SetCurrentAmmo (); + return; + } + + sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM); + self.attack_finished = time + 0.2; + self.currentammo = self.ammo_nails = self.ammo_nails - 1; + dir = aim (self, 1000); + launch_spike (self.origin + '0 0 16' + v_right*ox, dir); + + self.punchangle_x = -2; +}; + + + +void() spike_touch = +{ + if (other == self.owner) + return; + + if (other.solid == SOLID_TRIGGER) + return; // trigger field, do nothing + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + +// hit something that bleeds + if (other.takedamage) + { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 18); + } + else + { + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_SUPERSPIKE); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); + } + + remove(self); + +}; + + +void() superspike_touch = +{ + if (other == self.owner) + return; + + if (other.solid == SOLID_TRIGGER) + return; // trigger field, do nothing + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + +// hit something that bleeds + if (other.takedamage) + { + spawn_touchblood (18); + T_Damage (other, self, self.owner, 18); + } + else + { + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_SUPERSPIKE); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); + } + + remove(self); + +}; + + +/* +=============================================================================== + +PLAYER WEAPON USE + +=============================================================================== +*/ + +void() W_SetCurrentAmmo = +{ + if (self.weapon == IT_MORPHBALL) + return; + +{ + player_run (); // get out of any weapon firing states + + self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) ); + + if (self.weapon == IT_BLASTER) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + if(!self.semi) + { + self.currentammo = self.ammo_blaster; + self.weaponmodel = "progs/v_shot.mdl"; + self.weaponframe = 0; + sound (self, CHAN_WEAPON, "weapons/blaster_transform.wav", 1, ATTN_NORM); + player_missle27(); + } + } + else if (self.weapon == IT_RIC) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + self.currentammo = self.ammo_ric; + self.weaponmodel = "progs/v_shot.mdl"; + player_missle37(); + self.attack_finished = time + 1.5; + } + else if (self.weapon == IT_ROCKET) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + self.currentammo = self.ammo_rockets; + self.weaponmodel = "progs/v_shot.mdl"; + sound (self, CHAN_WEAPON, "weapons/rocket_transform.wav", 1, ATTN_NORM); + player_missle1(); + self.attack_finished = time + 1.5; + } + else if (self.weapon == IT_SPLASER) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + self.currentammo = self.ammo_nails; + self.weaponmodel = "progs/v_shot.mdl"; + self.weaponframe = 0; + } + else if (self.weapon == IT_SNIPER) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + self.currentammo = self.ammo_sniper; + self.weaponmodel = "progs/v_shot.mdl"; + self.weaponframe = 0; + self.items = self.items | IT_NAILS; + } + else if (self.weapon == IT_GRENADE_LAUNCHER) + { + //self.currentammo = self.ammo_rockets; + //self.weaponmodel = "progs/v_rock.mdl"; + self.currentammo = self.morphbombs; + self.weaponframe = 0; + //self.items = self.items | IT_ROCKETS; + } + else if (self.weapon == IT_MAGMA) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + self.currentammo = self.ammo_lava; + self.weaponmodel = "progs/v_shot.mdl"; + self.weaponframe = 0; + self.items = self.items | IT_ROCKETS; + } + else if (self.weapon == IT_LIGHTNING) + { + self.currentammo = self.ammo_cells; + self.weaponmodel = "progs/v_light.mdl"; + self.weaponframe = 0; + self.items = self.items | IT_CELLS; + } + else + { + self.currentammo = 0; + self.weaponframe = 0; + } + } +}; +float() W_CheckNoAmmo = +{ + if (self.currentammo > 0) + return TRUE; + + if (self.weapon == IT_MORPHBALL) + return TRUE; + + W_SetCurrentAmmo (); + +// drop the weapon down + return FALSE; +}; + +/* +============ +W_Attack + +An attack impulse can be triggered now +============ +*/ +void() player_axe1; +void() player_axeb1; +void() player_axec1; +void() player_axed1; +void() player_shot1; +void() player_nail1; +void() player_light1; +void() player_rocket1; +void() FireAnimations; //A function that Is becoming less useable as the game goes on...Sigh +void() player_missle14; //Shooting Animations for Rocket Launcher +void() player_missle45; //Shooting Animations for Richochet beam +void() player_missle56; //Shooting Animations for Blaster +void() W_Attack = +{ + if (!W_CheckNoAmmo ()) + return; + + makevectors (self.v_angle); // calculate forward angle for velocity + self.show_hostile = time + 1; // wake monsters up + + + if (self.weapon == IT_MORPHBALL) + { + if (self.morphbombs <= 1) + return; + fire_morphbomb(); + self.attack_finished = time + 0.6; + } + else if (self.weapon == IT_BLASTER) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + else + { + if (!self.semi) + { + W_FireBlaster(); + player_missle56(); + self.semi = 1; + self.attack_finished = time + 0.12; + } + } +} + else if (self.weapon == IT_RIC) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + else + { + + if(!self.semi) + { + if (self.ammo_ric <= 6) + W_FireRic(); + else + { + W_FireRic(); + W_FireRic2(); + W_FireRic3(); + } + player_missle45(); + self.semi = 1; // Semiauto + self.attack_finished = time + 0.6; // Faster + } + } + } + + + else if (self.weapon == IT_ROCKET) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + + else + { + if(!self.semi) + { + player_missle14(); + W_FireRocket(); + self.semi = 1; + self.attack_finished = time + 0.7; + } + } + } + else if (self.weapon == IT_SPLASER) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + + else + { + if(!self.semi) + { + FireAnimations(); + self.semi = 1; + self.attack_finished = time + 0.8; + } + } + } + else if (self.weapon == IT_SNIPER) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + FireAnimations(); + self.attack_finished = time + 1; + } + else if (self.weapon == IT_GRENADE_LAUNCHER) + { + fire_morphbomb(); + self.attack_finished = time + 0.6; + } + else if (self.weapon == IT_MAGMA) + { + if (self.weapon == IT_MORPHBALL) + { + return; + } + FireAnimations(); + W_FireMagma(); + self.attack_finished = time + 0.7; + } + else if (self.weapon == IT_LIGHTNING) + { + player_light1(); + self.attack_finished = time + 0.1; + sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM); + } +}; + +/* +============ +W_ChangeWeapon + +============ +*/ +void() W_ChangeWeapon = +{ + local float it, am, fl; + + it = self.items; + am = 0; + + if (self.impulse == 1) + { + fl = IT_MORPHBALL; + } + else if (self.impulse == 2) + { + //if (self.weapon == IT_RIC | IT_ROCKET | IT_SNIPER | IT_SPLASER | IT_MAGMA); + //player_missle27(); + fl = IT_BLASTER; + if (self.ammo_shells < 1) + am = 1; + } + else if (self.impulse == 3) + { + fl = IT_ROCKET; + if (self.ammo_shells < 2) + am = 1; + } + //else if (self.impulse == 4) + //{ + //fl = IT_SPLASER; + //if (self.ammo_nails < 1) + //am = 1; + //} + else if (self.impulse == 5) + { + fl = IT_SNIPER; + if (self.ammo_sniper < 2) + am = 1; + } + //else if (self.impulse == 6) + //{ + // fl = IT_GRENADE_LAUNCHER; + // if (self.ammo_rockets < 1) + // am = 1; + //} + else if (self.impulse == 7) + { + fl = IT_MAGMA; + if (self.ammo_lava < 1) + am = 1; + } + else if (self.impulse == 8) + { + fl = IT_LIGHTNING; + if (self.ammo_cells < 1) + am = 1; + } + self.impulse = 0; + + if (!(self.items & fl)) + { // don't have the weapon or the ammo + sprint (self, "no weapon.\n"); + return; + } + + if (am) + { // don't have the ammo + sprint (self, "not enough ammo.\n"); + return; + } + +// +// set weapon, set ammo +// + self.weapon = fl; + W_SetCurrentAmmo (); + +}; + +/* +============ +CheatCommand +============ +*/ +void() CheatCommand = +{ + if (deathmatch || coop) + return; + + self.ammo_rockets = 100; + self.ammo_nails = 200; + self.ammo_shells = 100; + self.items = self.items | + IT_MORPHBALL | + IT_BLASTER | + IT_ROCKET | + IT_SPLASER | + IT_SNIPER | + IT_GRENADE_LAUNCHER | + IT_MAGMA | + IT_RIC | + IT_KEY1 | IT_KEY2; + + + self.ammo_cells = 200; + self.items = self.items | IT_LIGHTNING; + + self.weapon = IT_MAGMA; + self.impulse = 0; + W_SetCurrentAmmo (); +}; + +/* +============ +CycleWeaponCommand + +Go to the next weapon with ammo +============ +*/ +void() CycleWeaponCommand = +{ + local float it, am; + + it = self.items; + self.impulse = 0; + + while (1) + { + am = 0; + + if (self.weapon == IT_LIGHTNING) + { + player_missle27(); + self.weapon = IT_BLASTER; + if (self.ammo_blaster < 1) + am = 1; + } + else if (self.weapon == IT_BLASTER) + { + self.weapon = IT_RIC; + if (self.ammo_ric < 2) + am = 1; + } + else if (self.weapon == IT_RIC) + { + self.weapon = IT_ROCKET; + if (self.ammo_rockets < 1) + am = 1; + } + else if (self.weapon == IT_ROCKET) + { + self.weapon = IT_SPLASER; + if (self.ammo_nails < 1) + am = 1; + } + else if (self.weapon == IT_SPLASER) + { + self.weapon = IT_SNIPER; + if (self.ammo_sniper < 1) + am = 1; + } + else if (self.weapon == IT_SNIPER) + { + self.weapon = IT_MAGMA; + if (self.ammo_lava < 1) + am = 1; + } + //else if (self.weapon == IT_GRENADE_LAUNCHER) + //{ + // self.weapon = IT_MAGMA; + // if (self.ammo_lava < 1) + // am = 1; + //} + else if (self.weapon == IT_MAGMA) + { + self.weapon = IT_LIGHTNING; + if (self.ammo_cells < 1) + am = 1; + } + + if ( (it & self.weapon) && am == 0) + { + W_SetCurrentAmmo (); + return; + } + } + +}; + +/* +============ +CycleWeaponReverseCommand + +Go to the prev weapon with ammo +============ +*/ +void() CycleWeaponReverseCommand = +{ + local float it, am; + + it = self.items; + self.impulse = 0; + + while (1) + { + am = 0; + + if (self.weapon == IT_LIGHTNING) + { + self.weapon = IT_MAGMA; + if (self.ammo_lava < 1) + am = 1; + } + else if (self.weapon == IT_MAGMA) + { + self.weapon = IT_SNIPER; + if (self.ammo_sniper < 1) + am = 1; + } + //else if (self.weapon == IT_GRENADE_LAUNCHER) + //{ + // self.weapon = IT_SNIPER; + // if (self.ammo_sniper < 1) + // am = 1; + //} + else if (self.weapon == IT_SNIPER) + { + self.weapon = IT_SPLASER; + if (self.ammo_nails < 1) + am = 1; + } + else if (self.weapon == IT_SPLASER) + { + self.weapon = IT_ROCKET; + if (self.ammo_shells < 2) + am = 1; + } + + else if (self.weapon == IT_ROCKET) + { + self.weapon = IT_BLASTER; + if (self.ammo_blaster < 1) + am = 1; + } + else if (self.weapon == IT_BLASTER) + { + self.weapon = IT_MORPHBALL; + } + else if (self.weapon == IT_MORPHBALL) + { + self.weapon = IT_LIGHTNING; + if (self.ammo_cells < 1) + am = 1; + } + + if ( (it & self.weapon) && am == 0) + { + W_SetCurrentAmmo (); + return; + } + } + +}; + +/* +============ +ServerflagsCommand + +Just for development +============ +*/ +void() ServerflagsCommand = +{ + serverflags = serverflags * 2 + 1; +}; + +void() QuadCheat = +{ + if (deathmatch || coop) + return; + self.super_time = 1; + self.super_damage_finished = time + 30; + self.items = self.items | IT_QUAD; + dprint ("quad cheat\n"); +}; +void() PlayerJump; +/* +============ +ImpulseCommands + +============ +*/ +void() ImpulseCommands = +{ + if (self.impulse >= 1 && self.impulse <= 8) + W_ChangeWeapon (); + if (self.impulse == 9) + CheatCommand (); + if (self.impulse == 10) + { + CycleWeaponCommand (); + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + } + if (self.impulse == 11) + ServerflagsCommand (); + if (self.impulse == 12) + { + CycleWeaponReverseCommand (); + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + } + if (self.impulse == 15) + { + if (self.health < BROKENITEMS || self.button0 || !self.flags & FL_ONGROUND) + return; + if (self.weapon != IT_MORPHBALL) + { + self.charge = 0; + self.pfov = FOV_DEFAULT; + setsize (self, '-10 -10 -24', '10 10 10'); + self.weapon = IT_MORPHBALL; + self.morphbombs = 4; + self.mballset = 1; + self.currentammo = self.morphbombs; + self.boostlives = 1; + self.morphbombs = 4; + sound (self, CHAN_WEAPON, "weapons/morphball.wav", 1, ATTN_NORM); + stuffcmd (self, "chase_active 1"); + self.attack_finished = time + 1; + } + else if (self.weapon == IT_MORPHBALL) + { + self.charge = 0; + self.pfov = FOV_DEFAULT; + setorigin (self, self.origin + v_up * 20); + setsize (self, '-16 -16 -24', '16 16 32'); + self.mballset = 0; + self.weapon = IT_BLASTER; + stuffcmd (self, "chase_active 0"); + W_SetCurrentAmmo (); + self.attack_finished = time + 1; + } + } + if (self.impulse == 17) + { + if (self.weapon == IT_SNIPER) + { + if (self.weapon == IT_MORPHBALL) + return; + WeaponZoom(); + } + if (self.weapon == IT_MORPHBALL) + boost(); + } + if (self.impulse == 255) + QuadCheat (); + + self.impulse = 0; +}; +/* +============ +W_WeaponFrame + +Called every frame so impulse events can be handled as well as possible +============ +*/ +void() W_WeaponFrame = +{ + if (!self.button0) + self.semi = 0; + + if (time < self.attack_finished) + return; + + ImpulseCommands (); // check for attack + + //if (self.button0) // Whats funny Is That You don't even need to Press the Button! + // { + /* +=============================================== + BLASTER +================================== + */ + if (self.weapon == IT_BLASTER) + { + if (self.charge < 10) + { + self.charge = self.charge + 1; + } + + if (self.charge >= 10) + if (self.charge < 20) + { + self.charge = self.charge + 1; + } + + if (self.charge >= 20) + if (self.charge < 30) + { + self.charge = self.charge + 1; + } + if (self.charge >= 30) + if (self.charge < 40) + { + self.charge = self.charge + 1; + } + if (self.charge >= 40) + if (self.charge < 50) + { + self.charge = self.charge + 1; + } + if (self.charge >= 50) + if (self.charge < 60) + { + self.charge = self.charge + 1; + } + if (self.charge >= 60) + if (self.charge < 70) + { + self.charge = self.charge + 1; + } + if (self.charge >= 70) + { + if (self.weapon == IT_MORPHBALL) //If you turn into Morphball, Then Have no Charge + {self.charge = 0;} + else + { + self.charge = self.charge + 1; + sprint(self, "Fully charged\n"); + } + } + + if (self.charge < 10 && !self.button0) + if (self.charge >= 1 && !self.button0) // no rapid fire + { + self.charge = 0; + } + + if (!self.button0 && self.charge >= 10) // you released the button + { + if (self.weapon == IT_MORPHBALL) + return; + if (!self.semi) + { + W_FireBlaster(); + self.charge = 0; + player_missle56(); + self.semi = 0; + self.attack_finished = time + 0.12; + } + } + } +/* +=============================================== + RICHOCHET +================================== +*/ + if (self.weapon == IT_RIC) + { + if (self.charge < 10) + { + self.charge = self.charge + 1; + } + + if (self.charge >= 10) + if (self.charge < 20) + { + self.charge = self.charge + 1; + } + + if (self.charge >= 20) + if (self.charge < 30) + { + self.charge = self.charge + 1; + } + if (self.charge >= 30) + if (self.charge < 40) + { + self.charge = self.charge + 1; + } + if (self.charge >= 40) + if (self.charge < 50) + { + self.charge = self.charge + 1; + } + if (self.charge >= 50) + if (self.charge < 60) + { + self.charge = self.charge + 1; + } + if (self.charge >= 60) + if (self.charge < 70) + { + self.charge = self.charge + 1; + } + if (self.charge >= 70) + { + if (self.weapon == IT_MORPHBALL) //If you turn into Morphball, Then Have no Charge + {self.charge = 0;} + else + { + self.charge = self.charge + 1; + sprint(self, "Fully charged\n"); + } + } + + if (self.charge < 10 && !self.button0) + if (self.charge >= 1 && !self.button0) // no rapid fire + { + self.charge = 0; + } + + if (!self.button0 && self.charge >= 10) // you released the button + { + if (self.weapon == IT_MORPHBALL) + return; + if (!self.semi) + { + W_FireRic(); + self.charge = 0; + player_missle45(); + self.semi = 0; + self.attack_finished = time + 0.7; + } + } + } + +/* +=============================================== +ROCKET LAUNCHER +================================== +*/ + if (self.weapon == IT_ROCKET) + { + if (self.charge < 10) + { + self.charge = self.charge + 1; + } + + if (self.charge >= 10) + if (self.charge < 20) + { + self.charge = self.charge + 1; + } + + if (self.charge >= 20) + if (self.charge < 30) + { + self.charge = self.charge + 1; + } + if (self.charge >= 30) + if (self.charge < 40) + { + self.charge = self.charge + 1; + } + if (self.charge >= 40) + if (self.charge < 50) + { + self.charge = self.charge + 1; + } + if (self.charge >= 50) + if (self.charge < 60) + { + self.charge = self.charge + 1; + } + if (self.charge >= 60) + if (self.charge < 70) + { + self.charge = self.charge + 1; + } + if (self.charge >= 70) + { + if (self.weapon == IT_MORPHBALL) //If you turn into Morphball, Then Have no Charge + {self.charge = 0;} + else + { + self.charge = self.charge + 1; + sprint(self, "Fully charged\n"); + } + } + + if (self.charge < 10 && !self.button0) + if (self.charge >= 1 && !self.button0) // no rapid fire + { + self.charge = 0; + } + + if (!self.button0 && self.charge >= 10) // you released the button + { + if (self.weapon == IT_MORPHBALL) + return; + if (!self.semi) + { + W_FireRocket(); + self.charge = 0; + player_missle14(); + self.semi = 0; + self.attack_finished = time + 0.7; + } + } + } + + + if (self.button0) + { + SuperDamageSound (); + W_Attack (); +} +}; +/* +======== +SuperDamageSound + +Plays sound if needed +======== +*/ +void() SuperDamageSound = +{ + if (self.super_damage_finished > time) + { + if (self.super_sound < time) + { + self.super_sound = time + 1; + sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM); + } + } + return; +}; + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/wizard.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/wizard.qc new file mode 100755 index 00000000..d6a6e0ed --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/wizard.qc @@ -0,0 +1,410 @@ +/* +============================================================================== + +WIZARD + +============================================================================== +*/ + +$cd id1/models/a_wizard +$origin 0 0 24 +$base wizbase +$skin wizbase + +$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8 +$frame hover9 hover10 hover11 hover12 hover13 hover14 hover15 + +$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10 +$frame fly11 fly12 fly13 fly14 + +$frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7 +$frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13 + +$frame pain1 pain2 pain3 pain4 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 + +/* +============================================================================== + +WIZARD + +If the player moves behind cover before the missile is launched, launch it +at the last visible spot with no velocity leading, in hopes that the player +will duck back out and catch it. +============================================================================== +*/ + +/* +============= +LaunchMissile + +Sets the given entities velocity and angles so that it will hit self.enemy +if self.enemy maintains it's current velocity +0.1 is moderately accurate, 0.0 is totally accurate +============= +*/ +void(entity missile, float mspeed, float accuracy) LaunchMissile = +{ + local vector vec, move; + local float fly; + + makevectors (self.angles); + +// set missile speed + vec = self.enemy.origin + self.enemy.mins + self.enemy.size * 0.7 - missile.origin; + +// calc aproximate time for missile to reach vec + fly = vlen (vec) / mspeed; + +// get the entities xy velocity + move = self.enemy.velocity; + move_z = 0; + +// project the target forward in time + vec = vec + move * fly; + + vec = normalize(vec); + vec = vec + accuracy*v_up*(random()- 0.5) + accuracy*v_right*(random()- 0.5); + + missile.velocity = vec * mspeed; + + missile.angles = '0 0 0'; + missile.angles_y = vectoyaw(missile.velocity); + +// set missile duration + missile.nextthink = time + 5; + missile.think = SUB_Remove; +}; + + +void() wiz_run1; +void() wiz_side1; + +/* +================= +WizardCheckAttack +================= +*/ +float() WizardCheckAttack = +{ + local vector spot1, spot2; + local entity targ; + local float chance; + + if (time < self.attack_finished) + return FALSE; + if (!enemy_vis) + return FALSE; + + if (enemy_range == RANGE_FAR) + { + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + wiz_run1 (); + } + return FALSE; + } + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + traceline (spot1, spot2, FALSE, self); + + if (trace_ent != targ) + { // don't have a clear shot, so move to a side + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + wiz_run1 (); + } + return FALSE; + } + + if (enemy_range == RANGE_MELEE) + chance = 0.9; + else if (enemy_range == RANGE_NEAR) + chance = 0.6; + else if (enemy_range == RANGE_MID) + chance = 0.2; + else + chance = 0; + + if (random () < chance) + { + self.attack_state = AS_MISSILE; + return TRUE; + } + + if (enemy_range == RANGE_MID) + { + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + wiz_run1 (); + } + } + else + { + if (self.attack_state != AS_SLIDING) + { + self.attack_state = AS_SLIDING; + wiz_side1 (); + } + } + + return FALSE; +}; + +/* +================= +WizardAttackFinished +================= +*/ +float() WizardAttackFinished = +{ + if (enemy_range >= RANGE_MID || !enemy_vis) + { + self.attack_state = AS_STRAIGHT; + self.think = wiz_run1; + } + else + { + self.attack_state = AS_SLIDING; + self.think = wiz_side1; + } +}; + +/* +============================================================================== + +FAST ATTACKS + +============================================================================== +*/ + +void() Wiz_FastFire = +{ + local vector vec; + local vector dst; + + if (self.owner.health > 0) + { + self.owner.effects = self.owner.effects | EF_MUZZLEFLASH; + + makevectors (self.enemy.angles); + dst = self.enemy.origin - 13*self.movedir; + + vec = normalize(dst - self.origin); + sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM); + launch_spike (self.origin, vec); + newmis.velocity = vec*600; + newmis.owner = self.owner; + newmis.classname = "wizspike"; + setmodel (newmis, "progs/w_spike.mdl"); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + } + + remove (self); +}; + + +void() Wiz_StartFast = +{ + local entity missile; + + sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM); + self.v_angle = self.angles; + makevectors (self.angles); + + missile = spawn (); + missile.owner = self; + missile.nextthink = time + 0.6; + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right*14); + missile.enemy = self.enemy; + missile.nextthink = time + 0.8; + missile.think = Wiz_FastFire; + missile.movedir = v_right; + + missile = spawn (); + missile.owner = self; + missile.nextthink = time + 1; + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right* -14); + missile.enemy = self.enemy; + missile.nextthink = time + 0.3; + missile.think = Wiz_FastFire; + missile.movedir = VEC_ORIGIN - v_right; +}; + + + +void() Wiz_idlesound = +{ +local float wr; + wr = random() * 5; + + if (self.waitmin < time) + { + self.waitmin = time + 2; + if (wr > 4.5) + sound (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE); + if (wr < 1.5) + sound (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE); + } + return; +}; + +void() wiz_stand1 =[ $hover1, wiz_stand2 ] {ai_stand();}; +void() wiz_stand2 =[ $hover2, wiz_stand3 ] {ai_stand();}; +void() wiz_stand3 =[ $hover3, wiz_stand4 ] {ai_stand();}; +void() wiz_stand4 =[ $hover4, wiz_stand5 ] {ai_stand();}; +void() wiz_stand5 =[ $hover5, wiz_stand6 ] {ai_stand();}; +void() wiz_stand6 =[ $hover6, wiz_stand7 ] {ai_stand();}; +void() wiz_stand7 =[ $hover7, wiz_stand8 ] {ai_stand();}; +void() wiz_stand8 =[ $hover8, wiz_stand1 ] {ai_stand();}; + +void() wiz_walk1 =[ $hover1, wiz_walk2 ] {ai_walk(8); +Wiz_idlesound();}; +void() wiz_walk2 =[ $hover2, wiz_walk3 ] {ai_walk(8);}; +void() wiz_walk3 =[ $hover3, wiz_walk4 ] {ai_walk(8);}; +void() wiz_walk4 =[ $hover4, wiz_walk5 ] {ai_walk(8);}; +void() wiz_walk5 =[ $hover5, wiz_walk6 ] {ai_walk(8);}; +void() wiz_walk6 =[ $hover6, wiz_walk7 ] {ai_walk(8);}; +void() wiz_walk7 =[ $hover7, wiz_walk8 ] {ai_walk(8);}; +void() wiz_walk8 =[ $hover8, wiz_walk1 ] {ai_walk(8);}; + +void() wiz_side1 =[ $hover1, wiz_side2 ] {ai_run(8); +Wiz_idlesound();}; +void() wiz_side2 =[ $hover2, wiz_side3 ] {ai_run(8);}; +void() wiz_side3 =[ $hover3, wiz_side4 ] {ai_run(8);}; +void() wiz_side4 =[ $hover4, wiz_side5 ] {ai_run(8);}; +void() wiz_side5 =[ $hover5, wiz_side6 ] {ai_run(8);}; +void() wiz_side6 =[ $hover6, wiz_side7 ] {ai_run(8);}; +void() wiz_side7 =[ $hover7, wiz_side8 ] {ai_run(8);}; +void() wiz_side8 =[ $hover8, wiz_side1 ] {ai_run(8);}; + +void() wiz_run1 =[ $fly1, wiz_run2 ] {ai_run(16); +Wiz_idlesound(); +}; +void() wiz_run2 =[ $fly2, wiz_run3 ] {ai_run(16);}; +void() wiz_run3 =[ $fly3, wiz_run4 ] {ai_run(16);}; +void() wiz_run4 =[ $fly4, wiz_run5 ] {ai_run(16);}; +void() wiz_run5 =[ $fly5, wiz_run6 ] {ai_run(16);}; +void() wiz_run6 =[ $fly6, wiz_run7 ] {ai_run(16);}; +void() wiz_run7 =[ $fly7, wiz_run8 ] {ai_run(16);}; +void() wiz_run8 =[ $fly8, wiz_run9 ] {ai_run(16);}; +void() wiz_run9 =[ $fly9, wiz_run10 ] {ai_run(16);}; +void() wiz_run10 =[ $fly10, wiz_run11 ] {ai_run(16);}; +void() wiz_run11 =[ $fly11, wiz_run12 ] {ai_run(16);}; +void() wiz_run12 =[ $fly12, wiz_run13 ] {ai_run(16);}; +void() wiz_run13 =[ $fly13, wiz_run14 ] {ai_run(16);}; +void() wiz_run14 =[ $fly14, wiz_run1 ] {ai_run(16);}; + +void() wiz_fast1 =[ $magatt1, wiz_fast2 ] {ai_face();Wiz_StartFast();}; +void() wiz_fast2 =[ $magatt2, wiz_fast3 ] {ai_face();}; +void() wiz_fast3 =[ $magatt3, wiz_fast4 ] {ai_face();}; +void() wiz_fast4 =[ $magatt4, wiz_fast5 ] {ai_face();}; +void() wiz_fast5 =[ $magatt5, wiz_fast6 ] {ai_face();}; +void() wiz_fast6 =[ $magatt6, wiz_fast7 ] {ai_face();}; +void() wiz_fast7 =[ $magatt5, wiz_fast8 ] {ai_face();}; +void() wiz_fast8 =[ $magatt4, wiz_fast9 ] {ai_face();}; +void() wiz_fast9 =[ $magatt3, wiz_fast10 ] {ai_face();}; +void() wiz_fast10 =[ $magatt2, wiz_run1 ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();}; + +void() wiz_pain1 =[ $pain1, wiz_pain2 ] {}; +void() wiz_pain2 =[ $pain2, wiz_pain3 ] {}; +void() wiz_pain3 =[ $pain3, wiz_pain4 ] {}; +void() wiz_pain4 =[ $pain4, wiz_run1 ] {}; + +void() wiz_death1 =[ $death1, wiz_death2 ] { + +self.velocity_x = -200 + 400*random(); +self.velocity_y = -200 + 400*random(); +self.velocity_z = 100 + 100*random(); +self.flags = self.flags - (self.flags & FL_ONGROUND); +sound (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM); +}; +void() wiz_death2 =[ $death2, wiz_death3 ] {}; +void() wiz_death3 =[ $death3, wiz_death4 ]{self.solid = SOLID_NOT;}; +void() wiz_death4 =[ $death4, wiz_death5 ] {}; +void() wiz_death5 =[ $death5, wiz_death6 ] {}; +void() wiz_death6 =[ $death6, wiz_death7 ] {}; +void() wiz_death7 =[ $death7, wiz_death8 ] {}; +void() wiz_death8 =[ $death8, wiz_death8 ] {}; + +void() wiz_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_wizard.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + return; + } + + wiz_death1 (); +}; + + +void(entity attacker, float damage) Wiz_Pain = +{ + sound (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM); + if (random()*70 > damage) + return; // didn't flinch + + wiz_pain1 (); +}; + + +void() Wiz_Missile = +{ + wiz_fast1(); +}; + +/*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_knight = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/wizard.mdl"); + precache_model ("progs/h_wizard.mdl"); + precache_model ("progs/w_spike.mdl"); + + precache_sound ("wizard/hit.wav"); // used by c code + precache_sound ("wizard/wattack.wav"); + precache_sound ("wizard/wdeath.wav"); + precache_sound ("wizard/widle1.wav"); + precache_sound ("wizard/widle2.wav"); + precache_sound ("wizard/wpain.wav"); + precache_sound ("wizard/wsight.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/wizard.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 80; + + self.th_stand = wiz_stand1; + self.th_walk = wiz_walk1; + self.th_run = wiz_run1; + self.th_missile = Wiz_Missile; + self.th_pain = Wiz_Pain; + self.th_die = wiz_die; + + flymonster_start (); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/world.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/world.qc new file mode 100755 index 00000000..1fb7faa9 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/world.qc @@ -0,0 +1,396 @@ + +void() InitBodyQue; + + +void() main = +{ + dprint ("main function\n"); + +// these are just commands the the prog compiler to copy these files + + precache_file ("progs.dat"); + precache_file ("gfx.wad"); + precache_file ("quake.rc"); + precache_file ("default.cfg"); + + precache_file ("end1.bin"); + precache_file2 ("end2.bin"); + + precache_file ("demo1.dem"); + precache_file ("demo2.dem"); + precache_file ("demo3.dem"); + +// +// these are all of the lumps from the cached.ls files +// + precache_file ("gfx/palette.lmp"); + precache_file ("gfx/colormap.lmp"); + + precache_file2 ("gfx/pop.lmp"); + + precache_file ("gfx/complete.lmp"); + precache_file ("gfx/inter.lmp"); + + precache_file ("gfx/ranking.lmp"); + precache_file ("gfx/vidmodes.lmp"); + precache_file ("gfx/finale.lmp"); + precache_file ("gfx/conback.lmp"); + precache_file ("gfx/qplaque.lmp"); + + precache_file ("gfx/menudot1.lmp"); + precache_file ("gfx/menudot2.lmp"); + precache_file ("gfx/menudot3.lmp"); + precache_file ("gfx/menudot4.lmp"); + precache_file ("gfx/menudot5.lmp"); + precache_file ("gfx/menudot6.lmp"); + + precache_file ("gfx/menuplyr.lmp"); + precache_file ("gfx/bigbox.lmp"); + precache_file ("gfx/dim_modm.lmp"); + precache_file ("gfx/dim_drct.lmp"); + precache_file ("gfx/dim_ipx.lmp"); + precache_file ("gfx/dim_tcp.lmp"); + precache_file ("gfx/dim_mult.lmp"); + precache_file ("gfx/mainmenu.lmp"); + + precache_file ("gfx/box_tl.lmp"); + precache_file ("gfx/box_tm.lmp"); + precache_file ("gfx/box_tr.lmp"); + + precache_file ("gfx/box_ml.lmp"); + precache_file ("gfx/box_mm.lmp"); + precache_file ("gfx/box_mm2.lmp"); + precache_file ("gfx/box_mr.lmp"); + + precache_file ("gfx/box_bl.lmp"); + precache_file ("gfx/box_bm.lmp"); + precache_file ("gfx/box_br.lmp"); + + precache_file ("gfx/sp_menu.lmp"); + precache_file ("gfx/ttl_sgl.lmp"); + precache_file ("gfx/ttl_main.lmp"); + precache_file ("gfx/ttl_cstm.lmp"); + + precache_file ("gfx/mp_menu.lmp"); + + precache_file ("gfx/netmen1.lmp"); + precache_file ("gfx/netmen2.lmp"); + precache_file ("gfx/netmen3.lmp"); + precache_file ("gfx/netmen4.lmp"); + precache_file ("gfx/netmen5.lmp"); + + precache_file ("gfx/sell.lmp"); + + precache_file ("gfx/help0.lmp"); + precache_file ("gfx/help1.lmp"); + precache_file ("gfx/help2.lmp"); + precache_file ("gfx/help3.lmp"); + precache_file ("gfx/help4.lmp"); + precache_file ("gfx/help5.lmp"); + + precache_file ("gfx/pause.lmp"); + precache_file ("gfx/loading.lmp"); + + precache_file ("gfx/p_option.lmp"); + precache_file ("gfx/p_load.lmp"); + precache_file ("gfx/p_save.lmp"); + precache_file ("gfx/p_multi.lmp"); + +// sounds loaded by C code + precache_sound ("misc/menu1.wav"); + precache_sound ("misc/menu2.wav"); + precache_sound ("misc/menu3.wav"); + + precache_sound ("ambience/water1.wav"); + precache_sound ("ambience/wind2.wav"); + +// shareware + precache_file ("maps/start.bsp"); + + precache_file ("maps/e1m1.bsp"); + precache_file ("maps/e1m2.bsp"); + precache_file ("maps/e1m3.bsp"); + precache_file ("maps/e1m4.bsp"); + precache_file ("maps/e1m5.bsp"); + precache_file ("maps/e1m6.bsp"); + precache_file ("maps/e1m7.bsp"); + precache_file ("maps/e1m8.bsp"); + +// registered + precache_file2 ("gfx/pop.lmp"); + + precache_file2 ("maps/e2m1.bsp"); + precache_file2 ("maps/e2m2.bsp"); + precache_file2 ("maps/e2m3.bsp"); + precache_file2 ("maps/e2m4.bsp"); + precache_file2 ("maps/e2m5.bsp"); + precache_file2 ("maps/e2m6.bsp"); + precache_file2 ("maps/e2m7.bsp"); + + precache_file2 ("maps/e3m1.bsp"); + precache_file2 ("maps/e3m2.bsp"); + precache_file2 ("maps/e3m3.bsp"); + precache_file2 ("maps/e3m4.bsp"); + precache_file2 ("maps/e3m5.bsp"); + precache_file2 ("maps/e3m6.bsp"); + precache_file2 ("maps/e3m7.bsp"); + + precache_file2 ("maps/e4m1.bsp"); + precache_file2 ("maps/e4m2.bsp"); + precache_file2 ("maps/e4m3.bsp"); + precache_file2 ("maps/e4m4.bsp"); + precache_file2 ("maps/e4m5.bsp"); + precache_file2 ("maps/e4m6.bsp"); + precache_file2 ("maps/e4m7.bsp"); + precache_file2 ("maps/e4m8.bsp"); + + precache_file2 ("maps/end.bsp"); + + precache_file2 ("maps/dm1.bsp"); + precache_file2 ("maps/dm2.bsp"); + precache_file2 ("maps/dm3.bsp"); + precache_file2 ("maps/dm4.bsp"); + precache_file2 ("maps/dm5.bsp"); + precache_file2 ("maps/dm6.bsp"); +}; + + +entity lastspawn; + +//======================= +/*QUAKED worldspawn (0 0 0) ? +Only used for the world entity. +Set message to the level name. +Set sounds to the cd track to play. + +World Types: +0: medieval +1: metal +2: base +*/ +//======================= +void() worldspawn = +{ + BotInit(); // FrikBot + lastspawn = world; + InitBodyQue (); + +// custom map attributes + if (self.model == "maps/e1m8.bsp") + cvar_set ("sv_gravity", "100"); + else + cvar_set ("sv_gravity", "800"); + +// the area based ambient sounds MUST be the first precache_sounds + +// player precaches + W_Precache (); // get weapon precaches + +// sounds used from C physics code + precache_sound ("demon/dland2.wav"); // landing thud + precache_sound ("misc/h2ohit1.wav"); // landing splash + +// setup precaches allways needed + precache_sound ("items/itembk2.wav"); // item respawn sound + precache_sound ("player/plyrjmp8.wav"); // player jump + precache_sound ("player/land.wav"); // player landing + precache_sound ("player/land2.wav"); // player hurt landing + precache_sound ("player/drown1.wav"); // drowning pain + precache_sound ("player/drown2.wav"); // drowning pain + precache_sound ("player/gasp1.wav"); // gasping for air + precache_sound ("player/gasp2.wav"); // taking breath + precache_sound ("player/h2odeath.wav"); // drowning death + + precache_sound ("misc/talk.wav"); // talk + precache_sound ("player/teledth1.wav"); // telefrag + precache_sound ("misc/r_tele1.wav"); // teleport sounds + precache_sound ("misc/r_tele2.wav"); + precache_sound ("misc/r_tele3.wav"); + precache_sound ("misc/r_tele4.wav"); + precache_sound ("misc/r_tele5.wav"); + precache_sound ("weapons/lock4.wav"); // ammo pick up + precache_sound ("weapons/pkup.wav"); // weapon up + precache_sound ("items/armor1.wav"); // armor up + precache_sound ("weapons/lhit.wav"); //lightning + precache_sound ("weapons/lstart.wav"); //lightning start + precache_sound ("items/damage3.wav"); + + precache_sound ("misc/power.wav"); //lightning for boss + +// player gib sounds + precache_sound ("player/gib.wav"); // player gib sound + precache_sound ("player/udeath.wav"); // player gib sound + precache_sound ("player/tornoff2.wav"); // gib sound + +// player pain sounds + + precache_sound ("player/pain1.wav"); + precache_sound ("player/pain2.wav"); + precache_sound ("player/pain3.wav"); + precache_sound ("player/pain4.wav"); + precache_sound ("player/pain5.wav"); + precache_sound ("player/pain6.wav"); + +// player death sounds + precache_sound ("player/death1.wav"); + precache_sound ("player/death2.wav"); + precache_sound ("player/death3.wav"); + precache_sound ("player/death4.wav"); + precache_sound ("player/death5.wav"); + +// ax sounds + precache_sound ("weapons/ax1.wav"); // ax swoosh + precache_sound ("player/axhit1.wav"); // ax hit meat + precache_sound ("player/axhit2.wav"); // ax hit world + + precache_sound ("player/h2ojump.wav"); // player jumping into water + precache_sound ("player/slimbrn2.wav"); // player enter slime + precache_sound ("player/inh2o.wav"); // player enter water + precache_sound ("player/inlava.wav"); // player enter lava + precache_sound ("misc/outwater.wav"); // leaving water sound + + precache_sound ("player/lburn1.wav"); // lava burn + precache_sound ("player/lburn2.wav"); // lava burn + + precache_sound ("misc/water1.wav"); // swimming + precache_sound ("misc/water2.wav"); // swimming + + precache_model ("progs/player.mdl"); + precache_model ("progs/eyes.mdl"); + precache_model ("progs/h_player.mdl"); + precache_model ("progs/gib1.mdl"); + precache_model ("progs/gib2.mdl"); + precache_model ("progs/gib3.mdl"); + + precache_model ("progs/s_bubble.spr"); // drowning bubbles + precache_model ("progs/s_explod.spr"); // sprite explosion + + precache_model ("progs/v_axe.mdl"); + precache_model ("progs/v_shot.mdl"); + precache_model ("progs/v_nail.mdl"); + precache_model ("progs/v_rock.mdl"); + precache_model ("progs/v_shot2.mdl"); + precache_model ("progs/v_nail2.mdl"); + precache_model ("progs/v_rock2.mdl"); + + precache_model ("progs/bolt.mdl"); // for lightning gun + precache_model ("progs/bolt2.mdl"); // for lightning gun + precache_model ("progs/bolt3.mdl"); // for boss shock + precache_model ("progs/lavaball.mdl"); // for testing + + precache_model ("progs/missile.mdl"); + precache_model ("progs/grenade.mdl"); + precache_model ("progs/spike.mdl"); + precache_model ("progs/s_spike.mdl"); + precache_model ("progs/mball.mdl"); //morphball by ghost fang + precache_model ("progs/mbomb.mdl"); + + precache_model ("progs/backpack.mdl"); + + precache_model ("progs/zom_gib.mdl"); + + precache_model ("progs/v_light.mdl"); + + +// +// Setup light animation tables. 'a' is total darkness, 'z' is maxbright. +// + + // 0 normal + lightstyle(0, "m"); + + // 1 FLICKER (first variety) + lightstyle(1, "mmnmmommommnonmmonqnmmo"); + + // 2 SLOW STRONG PULSE + lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); + + // 3 CANDLE (first variety) + lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); + + // 4 FAST STROBE + lightstyle(4, "mamamamamama"); + + // 5 GENTLE PULSE 1 + lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj"); + + // 6 FLICKER (second variety) + lightstyle(6, "nmonqnmomnmomomno"); + + // 7 CANDLE (second variety) + lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm"); + + // 8 CANDLE (third variety) + lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); + + // 9 SLOW STROBE (fourth variety) + lightstyle(9, "aaaaaaaazzzzzzzz"); + + // 10 FLUORESCENT FLICKER + lightstyle(10, "mmamammmmammamamaaamammma"); + + // 11 SLOW PULSE NOT FADE TO BLACK + lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba"); + + // styles 32-62 are assigned by the light program for switchable lights + + // 63 testing + lightstyle(63, "a"); +}; + +void() StartFrame = +{ + BotFrame(); // FrikBot + teamplay = cvar("teamplay"); + skill = cvar("skill"); + framecount = framecount + 1; +}; + +/* +============================================================================== + +BODY QUE + +============================================================================== +*/ + +entity bodyque_head; + +void() bodyque = +{ // just here so spawn functions don't complain after the world + // creates bodyques +}; + +void() InitBodyQue = +{ + + bodyque_head = spawn(); + bodyque_head.classname = "bodyque"; + bodyque_head.owner = spawn(); + bodyque_head.owner.classname = "bodyque"; + bodyque_head.owner.owner = spawn(); + bodyque_head.owner.owner.classname = "bodyque"; + bodyque_head.owner.owner.owner = spawn(); + bodyque_head.owner.owner.owner.classname = "bodyque"; + bodyque_head.owner.owner.owner.owner = bodyque_head; +}; + + +// make a body que entry for the given ent so the ent can be +// respawned elsewhere +void(entity ent) CopyToBodyQue = +{ + bodyque_head.angles = ent.angles; + bodyque_head.model = ent.model; + bodyque_head.modelindex = ent.modelindex; + bodyque_head.frame = ent.frame; + bodyque_head.colormap = ent.colormap; + bodyque_head.movetype = ent.movetype; + bodyque_head.velocity = ent.velocity; + bodyque_head.flags = 0; + setorigin (bodyque_head, ent.origin); + setsize (bodyque_head, ent.mins, ent.maxs); + bodyque_head = bodyque_head.owner; +}; + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/zombie.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/zombie.qc new file mode 100755 index 00000000..b431face --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/Primeqc4/zombie.qc @@ -0,0 +1,515 @@ +/* +============================================================================== + +ZOMBIE + +============================================================================== +*/ +$cd id1/models/zombie + +$origin 0 0 24 + +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 +$frame stand9 stand10 stand11 stand12 stand13 stand14 stand15 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11 +$frame walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 +$frame run13 run14 run15 run16 run17 run18 + +$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8 atta9 atta10 atta11 +$frame atta12 atta13 + +$frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8 attb9 attb10 attb11 +$frame attb12 attb13 attb14 + +$frame attc1 attc2 attc3 attc4 attc5 attc6 attc7 attc8 attc9 attc10 attc11 +$frame attc12 + +$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10 +$frame paina11 paina12 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10 +$frame painb11 painb12 painb13 painb14 painb15 painb16 painb17 painb18 painb19 +$frame painb20 painb21 painb22 painb23 painb24 painb25 painb26 painb27 painb28 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10 +$frame painc11 painc12 painc13 painc14 painc15 painc16 painc17 painc18 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10 +$frame paind11 paind12 paind13 + +$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10 +$frame paine11 paine12 paine13 paine14 paine15 paine16 paine17 paine18 paine19 +$frame paine20 paine21 paine22 paine23 paine24 paine25 paine26 paine27 paine28 +$frame paine29 paine30 + +$frame cruc_1 cruc_2 cruc_3 cruc_4 cruc_5 cruc_6 + +float SPAWN_CRUCIFIED = 1; + +//============================================================================= + +.float inpain; + +void() zombie_stand1 =[ $stand1, zombie_stand2 ] {ai_stand();}; +void() zombie_stand2 =[ $stand2, zombie_stand3 ] {ai_stand();}; +void() zombie_stand3 =[ $stand3, zombie_stand4 ] {ai_stand();}; +void() zombie_stand4 =[ $stand4, zombie_stand5 ] {ai_stand();}; +void() zombie_stand5 =[ $stand5, zombie_stand6 ] {ai_stand();}; +void() zombie_stand6 =[ $stand6, zombie_stand7 ] {ai_stand();}; +void() zombie_stand7 =[ $stand7, zombie_stand8 ] {ai_stand();}; +void() zombie_stand8 =[ $stand8, zombie_stand9 ] {ai_stand();}; +void() zombie_stand9 =[ $stand9, zombie_stand10 ] {ai_stand();}; +void() zombie_stand10 =[ $stand10, zombie_stand11 ] {ai_stand();}; +void() zombie_stand11 =[ $stand11, zombie_stand12 ] {ai_stand();}; +void() zombie_stand12 =[ $stand12, zombie_stand13 ] {ai_stand();}; +void() zombie_stand13 =[ $stand13, zombie_stand14 ] {ai_stand();}; +void() zombie_stand14 =[ $stand14, zombie_stand15 ] {ai_stand();}; +void() zombie_stand15 =[ $stand15, zombie_stand1 ] {ai_stand();}; + +void() zombie_cruc1 = [ $cruc_1, zombie_cruc2 ] { +if (random() < 0.1) + sound (self, CHAN_VOICE, "zombie/idle_w2.wav", 1, ATTN_STATIC);}; +void() zombie_cruc2 = [ $cruc_2, zombie_cruc3 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc3 = [ $cruc_3, zombie_cruc4 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc4 = [ $cruc_4, zombie_cruc5 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc5 = [ $cruc_5, zombie_cruc6 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc6 = [ $cruc_6, zombie_cruc1 ] {self.nextthink = time + 0.1 + random()*0.1;}; + +void() zombie_walk1 =[ $walk1, zombie_walk2 ] {ai_walk(0);}; +void() zombie_walk2 =[ $walk2, zombie_walk3 ] {ai_walk(2);}; +void() zombie_walk3 =[ $walk3, zombie_walk4 ] {ai_walk(3);}; +void() zombie_walk4 =[ $walk4, zombie_walk5 ] {ai_walk(2);}; +void() zombie_walk5 =[ $walk5, zombie_walk6 ] {ai_walk(1);}; +void() zombie_walk6 =[ $walk6, zombie_walk7 ] {ai_walk(0);}; +void() zombie_walk7 =[ $walk7, zombie_walk8 ] {ai_walk(0);}; +void() zombie_walk8 =[ $walk8, zombie_walk9 ] {ai_walk(0);}; +void() zombie_walk9 =[ $walk9, zombie_walk10 ] {ai_walk(0);}; +void() zombie_walk10 =[ $walk10, zombie_walk11 ] {ai_walk(0);}; +void() zombie_walk11 =[ $walk11, zombie_walk12 ] {ai_walk(2);}; +void() zombie_walk12 =[ $walk12, zombie_walk13 ] {ai_walk(2);}; +void() zombie_walk13 =[ $walk13, zombie_walk14 ] {ai_walk(1);}; +void() zombie_walk14 =[ $walk14, zombie_walk15 ] {ai_walk(0);}; +void() zombie_walk15 =[ $walk15, zombie_walk16 ] {ai_walk(0);}; +void() zombie_walk16 =[ $walk16, zombie_walk17 ] {ai_walk(0);}; +void() zombie_walk17 =[ $walk17, zombie_walk18 ] {ai_walk(0);}; +void() zombie_walk18 =[ $walk18, zombie_walk19 ] {ai_walk(0);}; +void() zombie_walk19 =[ $walk19, zombie_walk1 ] { +ai_walk(0); +if (random() < 0.2) + sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);}; + +void() zombie_run1 =[ $run1, zombie_run2 ] {ai_run(1);self.inpain = 0;}; +void() zombie_run2 =[ $run2, zombie_run3 ] {ai_run(1);}; +void() zombie_run3 =[ $run3, zombie_run4 ] {ai_run(0);}; +void() zombie_run4 =[ $run4, zombie_run5 ] {ai_run(1);}; +void() zombie_run5 =[ $run5, zombie_run6 ] {ai_run(2);}; +void() zombie_run6 =[ $run6, zombie_run7 ] {ai_run(3);}; +void() zombie_run7 =[ $run7, zombie_run8 ] {ai_run(4);}; +void() zombie_run8 =[ $run8, zombie_run9 ] {ai_run(4);}; +void() zombie_run9 =[ $run9, zombie_run10 ] {ai_run(2);}; +void() zombie_run10 =[ $run10, zombie_run11 ] {ai_run(0);}; +void() zombie_run11 =[ $run11, zombie_run12 ] {ai_run(0);}; +void() zombie_run12 =[ $run12, zombie_run13 ] {ai_run(0);}; +void() zombie_run13 =[ $run13, zombie_run14 ] {ai_run(2);}; +void() zombie_run14 =[ $run14, zombie_run15 ] {ai_run(4);}; +void() zombie_run15 =[ $run15, zombie_run16 ] {ai_run(6);}; +void() zombie_run16 =[ $run16, zombie_run17 ] {ai_run(7);}; +void() zombie_run17 =[ $run17, zombie_run18 ] {ai_run(3);}; +void() zombie_run18 =[ $run18, zombie_run1 ] { +ai_run(8); +if (random() < 0.2) + sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE); +if (random() > 0.8) + sound (self, CHAN_VOICE, "zombie/z_idle1.wav", 1, ATTN_IDLE); +}; + +/* +============================================================================= + +ATTACKS + +============================================================================= +*/ + +void() ZombieGrenadeTouch = +{ + if (other == self.owner) + return; // don't explode on owner + if (other.takedamage) + { + T_Damage (other, self, self.owner, 10 ); + sound (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM); + remove (self); + return; + } + sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound + self.velocity = '0 0 0'; + self.avelocity = '0 0 0'; + self.touch = SUB_Remove; +}; + +/* +================ +ZombieFireGrenade +================ +*/ +void(vector st) ZombieFireGrenade = +{ + local entity missile; + local vector org; + + sound (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM); + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_BOUNCE; + missile.solid = SOLID_BBOX; + +// calc org + org = self.origin + st_x * v_forward + st_y * v_right + (st_z - 24) * v_up; + +// set missile speed + + makevectors (self.angles); + + missile.velocity = normalize(self.enemy.origin - org); + missile.velocity = missile.velocity * 600; + missile.velocity_z = 200; + + missile.avelocity = '3000 1000 2000'; + + missile.touch = ZombieGrenadeTouch; + +// set missile duration + missile.nextthink = time + 2.5; + missile.think = SUB_Remove; + + setmodel (missile, "progs/zom_gib.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, org); +}; + + +void() zombie_atta1 =[ $atta1, zombie_atta2 ] {ai_face();}; +void() zombie_atta2 =[ $atta2, zombie_atta3 ] {ai_face();}; +void() zombie_atta3 =[ $atta3, zombie_atta4 ] {ai_face();}; +void() zombie_atta4 =[ $atta4, zombie_atta5 ] {ai_face();}; +void() zombie_atta5 =[ $atta5, zombie_atta6 ] {ai_face();}; +void() zombie_atta6 =[ $atta6, zombie_atta7 ] {ai_face();}; +void() zombie_atta7 =[ $atta7, zombie_atta8 ] {ai_face();}; +void() zombie_atta8 =[ $atta8, zombie_atta9 ] {ai_face();}; +void() zombie_atta9 =[ $atta9, zombie_atta10 ] {ai_face();}; +void() zombie_atta10 =[ $atta10, zombie_atta11 ] {ai_face();}; +void() zombie_atta11 =[ $atta11, zombie_atta12 ] {ai_face();}; +void() zombie_atta12 =[ $atta12, zombie_atta13 ] {ai_face();}; +void() zombie_atta13 =[ $atta13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -22 30');}; + +void() zombie_attb1 =[ $attb1, zombie_attb2 ] {ai_face();}; +void() zombie_attb2 =[ $attb2, zombie_attb3 ] {ai_face();}; +void() zombie_attb3 =[ $attb3, zombie_attb4 ] {ai_face();}; +void() zombie_attb4 =[ $attb4, zombie_attb5 ] {ai_face();}; +void() zombie_attb5 =[ $attb5, zombie_attb6 ] {ai_face();}; +void() zombie_attb6 =[ $attb6, zombie_attb7 ] {ai_face();}; +void() zombie_attb7 =[ $attb7, zombie_attb8 ] {ai_face();}; +void() zombie_attb8 =[ $attb8, zombie_attb9 ] {ai_face();}; +void() zombie_attb9 =[ $attb9, zombie_attb10 ] {ai_face();}; +void() zombie_attb10 =[ $attb10, zombie_attb11 ] {ai_face();}; +void() zombie_attb11 =[ $attb11, zombie_attb12 ] {ai_face();}; +void() zombie_attb12 =[ $attb12, zombie_attb13 ] {ai_face();}; +void() zombie_attb13 =[ $attb13, zombie_attb14 ] {ai_face();}; +void() zombie_attb14 =[ $attb13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -24 29');}; + +void() zombie_attc1 =[ $attc1, zombie_attc2 ] {ai_face();}; +void() zombie_attc2 =[ $attc2, zombie_attc3 ] {ai_face();}; +void() zombie_attc3 =[ $attc3, zombie_attc4 ] {ai_face();}; +void() zombie_attc4 =[ $attc4, zombie_attc5 ] {ai_face();}; +void() zombie_attc5 =[ $attc5, zombie_attc6 ] {ai_face();}; +void() zombie_attc6 =[ $attc6, zombie_attc7 ] {ai_face();}; +void() zombie_attc7 =[ $attc7, zombie_attc8 ] {ai_face();}; +void() zombie_attc8 =[ $attc8, zombie_attc9 ] {ai_face();}; +void() zombie_attc9 =[ $attc9, zombie_attc10 ] {ai_face();}; +void() zombie_attc10 =[ $attc10, zombie_attc11 ] {ai_face();}; +void() zombie_attc11 =[ $attc11, zombie_attc12 ] {ai_face();}; +void() zombie_attc12 =[ $attc12, zombie_run1 ] {ai_face();ZombieFireGrenade('-12 -19 29');}; + +void() zombie_missile = +{ + local float r; + + r = random(); + + if (r < 0.3) + zombie_atta1 (); + else if (r < 0.6) + zombie_attb1 (); + else + zombie_attc1 (); +}; + + +/* +============================================================================= + +PAIN + +============================================================================= +*/ + +void() zombie_paina1 =[ $paina1, zombie_paina2 ] {sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);}; +void() zombie_paina2 =[ $paina2, zombie_paina3 ] {ai_painforward(3);}; +void() zombie_paina3 =[ $paina3, zombie_paina4 ] {ai_painforward(1);}; +void() zombie_paina4 =[ $paina4, zombie_paina5 ] {ai_pain(1);}; +void() zombie_paina5 =[ $paina5, zombie_paina6 ] {ai_pain(3);}; +void() zombie_paina6 =[ $paina6, zombie_paina7 ] {ai_pain(1);}; +void() zombie_paina7 =[ $paina7, zombie_paina8 ] {}; +void() zombie_paina8 =[ $paina8, zombie_paina9 ] {}; +void() zombie_paina9 =[ $paina9, zombie_paina10 ] {}; +void() zombie_paina10 =[ $paina10, zombie_paina11 ] {}; +void() zombie_paina11 =[ $paina11, zombie_paina12 ] {}; +void() zombie_paina12 =[ $paina12, zombie_run1 ] {}; + +void() zombie_painb1 =[ $painb1, zombie_painb2 ] {sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);}; +void() zombie_painb2 =[ $painb2, zombie_painb3 ] {ai_pain(2);}; +void() zombie_painb3 =[ $painb3, zombie_painb4 ] {ai_pain(8);}; +void() zombie_painb4 =[ $painb4, zombie_painb5 ] {ai_pain(6);}; +void() zombie_painb5 =[ $painb5, zombie_painb6 ] {ai_pain(2);}; +void() zombie_painb6 =[ $painb6, zombie_painb7 ] {}; +void() zombie_painb7 =[ $painb7, zombie_painb8 ] {}; +void() zombie_painb8 =[ $painb8, zombie_painb9 ] {}; +void() zombie_painb9 =[ $painb9, zombie_painb10 ] {sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);}; +void() zombie_painb10 =[ $painb10, zombie_painb11 ] {}; +void() zombie_painb11 =[ $painb11, zombie_painb12 ] {}; +void() zombie_painb12 =[ $painb12, zombie_painb13 ] {}; +void() zombie_painb13 =[ $painb13, zombie_painb14 ] {}; +void() zombie_painb14 =[ $painb14, zombie_painb15 ] {}; +void() zombie_painb15 =[ $painb15, zombie_painb16 ] {}; +void() zombie_painb16 =[ $painb16, zombie_painb17 ] {}; +void() zombie_painb17 =[ $painb17, zombie_painb18 ] {}; +void() zombie_painb18 =[ $painb18, zombie_painb19 ] {}; +void() zombie_painb19 =[ $painb19, zombie_painb20 ] {}; +void() zombie_painb20 =[ $painb20, zombie_painb21 ] {}; +void() zombie_painb21 =[ $painb21, zombie_painb22 ] {}; +void() zombie_painb22 =[ $painb22, zombie_painb23 ] {}; +void() zombie_painb23 =[ $painb23, zombie_painb24 ] {}; +void() zombie_painb24 =[ $painb24, zombie_painb25 ] {}; +void() zombie_painb25 =[ $painb25, zombie_painb26 ] {ai_painforward(1);}; +void() zombie_painb26 =[ $painb26, zombie_painb27 ] {}; +void() zombie_painb27 =[ $painb27, zombie_painb28 ] {}; +void() zombie_painb28 =[ $painb28, zombie_run1 ] {}; + +void() zombie_painc1 =[ $painc1, zombie_painc2 ] {sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);}; +void() zombie_painc2 =[ $painc2, zombie_painc3 ] {}; +void() zombie_painc3 =[ $painc3, zombie_painc4 ] {ai_pain(3);}; +void() zombie_painc4 =[ $painc4, zombie_painc5 ] {ai_pain(1);}; +void() zombie_painc5 =[ $painc5, zombie_painc6 ] {}; +void() zombie_painc6 =[ $painc6, zombie_painc7 ] {}; +void() zombie_painc7 =[ $painc7, zombie_painc8 ] {}; +void() zombie_painc8 =[ $painc8, zombie_painc9 ] {}; +void() zombie_painc9 =[ $painc9, zombie_painc10 ] {}; +void() zombie_painc10 =[ $painc10, zombie_painc11 ] {}; +void() zombie_painc11 =[ $painc11, zombie_painc12 ] {ai_painforward(1);}; +void() zombie_painc12 =[ $painc12, zombie_painc13 ] {ai_painforward(1);}; +void() zombie_painc13 =[ $painc13, zombie_painc14 ] {}; +void() zombie_painc14 =[ $painc14, zombie_painc15 ] {}; +void() zombie_painc15 =[ $painc15, zombie_painc16 ] {}; +void() zombie_painc16 =[ $painc16, zombie_painc17 ] {}; +void() zombie_painc17 =[ $painc17, zombie_painc18 ] {}; +void() zombie_painc18 =[ $painc18, zombie_run1 ] {}; + +void() zombie_paind1 =[ $paind1, zombie_paind2 ] {sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);}; +void() zombie_paind2 =[ $paind2, zombie_paind3 ] {}; +void() zombie_paind3 =[ $paind3, zombie_paind4 ] {}; +void() zombie_paind4 =[ $paind4, zombie_paind5 ] {}; +void() zombie_paind5 =[ $paind5, zombie_paind6 ] {}; +void() zombie_paind6 =[ $paind6, zombie_paind7 ] {}; +void() zombie_paind7 =[ $paind7, zombie_paind8 ] {}; +void() zombie_paind8 =[ $paind8, zombie_paind9 ] {}; +void() zombie_paind9 =[ $paind9, zombie_paind10 ] {ai_pain(1);}; +void() zombie_paind10 =[ $paind10, zombie_paind11 ] {}; +void() zombie_paind11 =[ $paind11, zombie_paind12 ] {}; +void() zombie_paind12 =[ $paind12, zombie_paind13 ] {}; +void() zombie_paind13 =[ $paind13, zombie_run1 ] {}; + +void() zombie_paine1 =[ $paine1, zombie_paine2 ] { +sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM); +self.health = 60; +}; +void() zombie_paine2 =[ $paine2, zombie_paine3 ] {ai_pain(8);}; +void() zombie_paine3 =[ $paine3, zombie_paine4 ] {ai_pain(5);}; +void() zombie_paine4 =[ $paine4, zombie_paine5 ] {ai_pain(3);}; +void() zombie_paine5 =[ $paine5, zombie_paine6 ] {ai_pain(1);}; +void() zombie_paine6 =[ $paine6, zombie_paine7 ] {ai_pain(2);}; +void() zombie_paine7 =[ $paine7, zombie_paine8 ] {ai_pain(1);}; +void() zombie_paine8 =[ $paine8, zombie_paine9 ] {ai_pain(1);}; +void() zombie_paine9 =[ $paine9, zombie_paine10 ] {ai_pain(2);}; +void() zombie_paine10 =[ $paine10, zombie_paine11 ] { +sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM); +self.solid = SOLID_NOT; +}; +void() zombie_paine11 =[ $paine11, zombie_paine12 ] {self.nextthink = self.nextthink + 5;self.health = 60;}; +void() zombie_paine12 =[ $paine12, zombie_paine13 ]{ +// see if ok to stand up +self.health = 60; +sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE); +self.solid = SOLID_SLIDEBOX; +if (!walkmove (0, 0)) +{ + self.think = zombie_paine11; + self.solid = SOLID_NOT; + return; +} +}; +void() zombie_paine13 =[ $paine13, zombie_paine14 ] {}; +void() zombie_paine14 =[ $paine14, zombie_paine15 ] {}; +void() zombie_paine15 =[ $paine15, zombie_paine16 ] {}; +void() zombie_paine16 =[ $paine16, zombie_paine17 ] {}; +void() zombie_paine17 =[ $paine17, zombie_paine18 ] {}; +void() zombie_paine18 =[ $paine18, zombie_paine19 ] {}; +void() zombie_paine19 =[ $paine19, zombie_paine20 ] {}; +void() zombie_paine20 =[ $paine20, zombie_paine21 ] {}; +void() zombie_paine21 =[ $paine21, zombie_paine22 ] {}; +void() zombie_paine22 =[ $paine22, zombie_paine23 ] {}; +void() zombie_paine23 =[ $paine23, zombie_paine24 ] {}; +void() zombie_paine24 =[ $paine24, zombie_paine25 ] {}; +void() zombie_paine25 =[ $paine25, zombie_paine26 ] {ai_painforward(5);}; +void() zombie_paine26 =[ $paine26, zombie_paine27 ] {ai_painforward(3);}; +void() zombie_paine27 =[ $paine27, zombie_paine28 ] {ai_painforward(1);}; +void() zombie_paine28 =[ $paine28, zombie_paine29 ] {ai_pain(1);}; +void() zombie_paine29 =[ $paine29, zombie_paine30 ] {}; +void() zombie_paine30 =[ $paine30, zombie_run1 ] {}; + +void() zombie_die = +{ + sound (self, CHAN_VOICE, "zombie/z_gib.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_zombie.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); +}; + +/* +================= +zombie_pain + +Zombies can only be killed (gibbed) by doing 60 hit points of damage +in a single frame (rockets, grenades, quad shotgun, quad nailgun). + +A hit of 25 points or more (super shotgun, quad nailgun) will allways put it +down to the ground. + +A hit of from 10 to 40 points in one frame will cause it to go down if it +has been twice in two seconds, otherwise it goes into one of the four +fast pain frames. + +A hit of less than 10 points of damage (winged by a shotgun) will be ignored. + +FIXME: don't use pain_finished because of nightmare hack +================= +*/ +void(entity attacker, float take) zombie_pain = +{ + local float r; + + self.health = 60; // allways reset health + + if (take < 9) + return; // totally ignore + + if (self.inpain == 2) + return; // down on ground, so don't reset any counters + +// go down immediately if a big enough hit + if (take >= 25) + { + self.inpain = 2; + zombie_paine1 (); + return; + } + + if (self.inpain) + { +// if hit again in next gre seconds while not in pain frames, definately drop + self.pain_finished = time + 3; + return; // currently going through an animation, don't change + } + + if (self.pain_finished > time) + { +// hit again, so drop down + self.inpain = 2; + zombie_paine1 (); + return; + } + +// gp into one of the fast pain animations + self.inpain = 1; + + r = random(); + if (r < 0.25) + zombie_paina1 (); + else if (r < 0.5) + zombie_painb1 (); + else if (r < 0.75) + zombie_painc1 (); + else + zombie_paind1 (); +}; + +//============================================================================ + +/*QUAKED monster_zombie (1 0 0) (-16 -16 -24) (16 16 32) Crucified ambush + +If crucified, stick the bounding box 12 pixels back into a wall to look right. +*/ +void() monster_zombie = +{ + if (deathmatch) + { + remove(self); + return; + } + + precache_model ("progs/zombie.mdl"); + precache_model ("progs/h_zombie.mdl"); + precache_model ("progs/zom_gib.mdl"); + + precache_sound ("zombie/z_idle.wav"); + precache_sound ("zombie/z_idle1.wav"); + precache_sound ("zombie/z_shot1.wav"); + precache_sound ("zombie/z_gib.wav"); + precache_sound ("zombie/z_pain.wav"); + precache_sound ("zombie/z_pain1.wav"); + precache_sound ("zombie/z_fall.wav"); + precache_sound ("zombie/z_miss.wav"); + precache_sound ("zombie/z_hit.wav"); + precache_sound ("zombie/idle_w2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/zombie.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 60; + + self.th_stand = zombie_stand1; + self.th_walk = zombie_walk1; + self.th_run = zombie_run1; + self.th_pain = zombie_pain; + self.th_die = zombie_die; + self.th_missile = zombie_missile; + + if (self.spawnflags & SPAWN_CRUCIFIED) + { + self.movetype = MOVETYPE_NONE; + zombie_cruc1 (); + } + else + walkmonster_start(); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/ai.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/ai.qc new file mode 100755 index 00000000..16169f77 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/ai.qc @@ -0,0 +1,751 @@ +void() t_movetarget; +/* + +.enemy +Will be world if not currently angry at anyone. + +.movetarget +The next path spot to walk toward. If .enemy, ignore .movetarget. +When an enemy is killed, the monster will try to return to it's path. + +.huntt_ime +Set to time + something when the player is in sight, but movement straight for +him is blocked. This causes the monster to use wall following code for +movement direction instead of sighting on the player. + +.ideal_yaw +A yaw angle of the intended direction, which will be turned towards at up +to 45 deg / state. If the enemy is in view and hunt_time is not active, +this will be the exact line towards the enemy. + +.pausetime +A monster will leave it's stand state and head towards it's .movetarget when +time > .pausetime. + +walkmove(angle, speed) primitive is all or nothing +*/ + +// +// when a monster becomes angry at a player, that monster will be used +// as the sight target the next frame so that monsters near that one +// will wake up even if they wouldn't have noticed the player +// +entity sight_entity; +float sight_entity_time; + +float(float v) anglemod = +{ + while (v >= 360) + v = v - 360; + while (v < 0) + v = v + 360; + return v; +}; + +/* +============================================================================== + +MOVETARGET CODE + +The angle of the movetarget effects standing and bowing direction, but has no effect on movement, which allways heads to the next target. + +targetname +must be present. The name of this movetarget. + +target +the next spot to move to. If not present, stop here for good. + +pausetime +The number of seconds to spend standing or bowing for path_stand or path_bow + +============================================================================== +*/ + + +void() movetarget_f = +{ + if (!self.targetname) + objerror ("monster_movetarget: no targetname"); + + self.solid = SOLID_TRIGGER; + self.touch = t_movetarget; + setsize (self, '-8 -8 -8', '8 8 8'); + +}; + +/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8) +Monsters will continue walking towards the next target corner. +*/ +void() path_corner = +{ + movetarget_f (); +}; + + +/* +============= +t_movetarget + +Something has bumped into a movetarget. If it is a monster +moving towards it, change the next destination and continue. +============== +*/ +void() t_movetarget = +{ +local entity temp; + + if (other.movetarget != self) + return; + + if (other.enemy) + return; // fighting, not following a path + + temp = self; + self = other; + other = temp; + + if (self.classname == "monster_ogre") + sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);// play chainsaw drag sound + +//dprint ("t_movetarget\n"); + self.goalentity = self.movetarget = find (world, targetname, other.target); + self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); + if (!self.movetarget) + { + self.pausetime = time + 999999; + self.th_stand (); + return; + } +}; + + + +//============================================================================ + +/* +============= +range + +returns the range catagorization of an entity reletive to self +0 melee range, will become hostile even if back is turned +1 visibility and infront, or visibility and show hostile +2 infront and show hostile +3 only triggered by damage +============= +*/ +float(entity targ) range = +{ + local vector spot1, spot2; + local float r; + + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + r = vlen (spot1 - spot2); + if (r < 120) + return RANGE_MELEE; + if (r < 500) + return RANGE_NEAR; + if (r < 1000) + return RANGE_MID; + return RANGE_FAR; +}; + +/* +============= +visible + +returns 1 if the entity is visible to self, even if not infront () +============= +*/ +BOOL (entity targ) visible = +{ + local vector spot1, spot2; + + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + traceline (spot1, spot2, TRUE, self); // see through other monsters + + if (trace_inopen && trace_inwater) + return FALSE; // sight line crossed contents + + if (trace_fraction == 1) + return TRUE; + return FALSE; +}; + + +/* +============= +infront + +returns 1 if the entity is in front (in sight) of self +============= +*/ +BOOL(entity targ) infront = +{ + local vector vec; + local float dot; + + makevectors (self.angles); + vec = normalize (targ.origin - self.origin); + dot = vec * v_forward; + + if ( dot > 0.3) + { + return TRUE; + } + return FALSE; +}; + + +//============================================================================ + +/* +=========== +ChangeYaw + +Turns towards self.ideal_yaw at self.yaw_speed +Sets the global variable current_yaw +Called every 0.1 sec by monsters +============ +*/ +/* +void() ChangeYaw = +{ + local float ideal, move, current_yaw; + +//current_yaw = self.ideal_yaw; +// mod down the current angle + current_yaw = anglemod( self.angles_y ); + ideal = self.ideal_yaw; + + if (current_yaw == ideal) + return; + + move = ideal - current_yaw; + if (ideal > current_yaw) + { + if (move > 180) + move = move - 360; + } + else + { + if (move < -180) + move = move + 360; + } + + if (move > 0) + { + if (move > self.yaw_speed) + move = self.yaw_speed; + } + else + { + if (move < 0-self.yaw_speed ) + move = 0-self.yaw_speed; + } + + current_yaw = anglemod (current_yaw + move); + + self.angles_y = current_yaw; +}; +*/ + + +//============================================================================ + +void() HuntTarget = +{ + self.goalentity = self.enemy; + self.think = self.th_run; + self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); + self.nextthink = time + 0.1; + SUB_AttackFinished (1); // wait a while before first attack +}; + +void() SightSound = +{ + local float rsnd; + local string s; + + switch (self.classname) + { + case "monster_ogre": + s = "ogre/ogwake.wav"; + break; + case "monster_knight": + s = "knight/ksight.wav"; + break; + case "monster_shambler": + s = "shambler/ssight.wav"; + break; + case "monster_demon1": + s = "demon/sight2.wav"; + break; + case "monster_wizard": + s = "wizard/wsight.wav"; + break; + case "monster_zombie": + s = "zombie/z_idle.wav"; + break; + case "monster_dog": + s = "dog/dsight.wav"; + break; + case "monster_hell_knight": + s = "hknight/sight1.wav"; + break; + case "monster_tarbaby": + s = "blob/sight1.wav"; + break; + case "monster_enforcer": + rsnd = random(); + if (rsnd < 0.25) + s = "enforcer/sight1.wav"; + else if (rsnd < 0.5) + s = "enforcer/sight2.wav"; + else if (rsnd < 0.75) + s = "enforcer/sight3.wav"; + else + s = "enforcer/sight4.wav"; + break; + case "monster_shalrath": + s = "shalrath/sight.wav"; + break; + default: + s = "soldier/sight1.wav"; + } + + sound (self, CHAN_VOICE, s, 1, ATTN_NORM); +}; + +void() FoundTarget = +{ + if (self.enemy.classname == "player") + { // let other monsters see this monster for a while + sight_entity = self; + sight_entity_time = time; + } + + self.show_hostile = time + 1; // wake up other monsters + + SightSound (); + HuntTarget (); +}; + +/* +=========== +FindTarget + +Self is currently not attacking anything, so try to find a target + +Returns TRUE if an enemy was sighted + +When a player fires a missile, the point of impact becomes a fakeplayer so +that monsters that see the impact will respond as if they had seen the +player. + +To avoid spending too much time, only a single client (or fakeclient) is +checked each frame. This means multi player games will have slightly +slower noticing monsters. +============ +*/ +BOOL() FindTarget = +{ + local entity client; + local float r; + +// if the first spawnflag bit is set, the monster will only wake up on +// really seeing the player, not another monster getting angry + +// spawnflags & 3 is a big hack, because zombie crucified used the first +// spawn flag prior to the ambush flag, and I forgot about it, so the second +// spawn flag works as well + if (sight_entity_time >= time - 0.1 && !(self.spawnflags & 3) ) + { + client = sight_entity; + if (client.enemy == self.enemy) + return TRUE; + } + else + { + client = checkclient (); + if (!client) + return FALSE; // current check entity isn't in PVS + } + + if (client == self.enemy) + return FALSE; + + if (client.flags & FL_NOTARGET) + return FALSE; + if (client.items & IT_INVISIBILITY) + return FALSE; + + r = range (client); + if (r == RANGE_FAR) + return FALSE; + + if (!visible (client)) + return FALSE; + + if (r == RANGE_NEAR) + { + if (client.show_hostile < time && !infront (client)) + return FALSE; + } + else if (r == RANGE_MID) + { + if ( /* client.show_hostile < time || */ !infront (client)) + return FALSE; + } + +// +// got one +// + self.enemy = client; + if (self.enemy.classname != "player") + { + self.enemy = self.enemy.enemy; + if (self.enemy.classname != "player") + { + self.enemy = world; + return FALSE; + } + } + + FoundTarget (); + + return TRUE; +}; + + +//============================================================================= + +void(float dist) ai_forward = +{ + walkmove (self.angles_y, dist); +}; + +void(float dist) ai_back = +{ + walkmove ( (self.angles_y+180), dist); +}; + + +/* +============= +ai_pain + +stagger back a bit +============= +*/ +void(float dist) ai_pain = +{ + ai_back (dist); +/* + local float away; + + away = anglemod (vectoyaw (self.origin - self.enemy.origin) + + 180*(random()- 0.5) ); + + walkmove (away, dist); +*/ +}; + +/* +============= +ai_painforward + +stagger back a bit +============= +*/ +void(float dist) ai_painforward = +{ + walkmove (self.ideal_yaw, dist); +}; + +/* +============= +ai_walk + +The monster is walking it's beat +============= +*/ +void(float dist) ai_walk = +{ +// movedist = dist; + + /* + There are no dragons! + if (self.classname == "monster_dragon") + { + movetogoal (dist); + return; + } + */ + + // check for noticing a player + if (FindTarget ()) + return; + + movetogoal (dist); +}; + + +/* +============= +ai_stand + +The monster is staying in one place for a while, with slight angle turns +============= +*/ +void() ai_stand = +{ + if (FindTarget ()) + return; + + if (time > self.pausetime) + { + self.th_walk (); + return; + } + +// change angle slightly + +}; + +/* +============= +ai_turn + +don't move, but turn towards ideal_yaw +============= +*/ +void() ai_turn = +{ + if (FindTarget ()) + return; + + ChangeYaw (); +}; + +//============================================================================= + +/* +============= +ChooseTurn +============= +*/ +/* +void(vector dest3) ChooseTurn = +{ + local vector dir, newdir; + + dir = self.origin - dest3; + + newdir_x = trace_plane_normal_y; + newdir_y = 0 - trace_plane_normal_x; + newdir_z = 0; + + if (dir * newdir > 0) + { + dir_x = 0 - trace_plane_normal_y; + dir_y = trace_plane_normal_x; + } + else + { + dir_x = trace_plane_normal_y; + dir_y = 0 - trace_plane_normal_x; + } + + dir_z = 0; + self.ideal_yaw = vectoyaw(dir); +}; +*/ + +/* +============ +FacingIdeal + +============ +*/ +BOOL() FacingIdeal = +{ + local float delta; + + delta = anglemod(self.angles_y - self.ideal_yaw); + if (delta > 45 && delta < 315) + return FALSE; + return TRUE; +}; + + +//============================================================================= +BOOL(float enemy_range) DogCheckAttack; +BOOL(float enemy_range) WizardCheckAttack; +BOOL(float enemy_range) DemonCheckAttack; + +BOOL(float enemy_range) CheckAnyAttack = +{ + + switch (self.classname) + { + case "monster_army": + return SoldierCheckAttack (enemy_range); + case "monster_ogre": + return OgreCheckAttack (enemy_range); + case "monster_shambler": + return ShamCheckAttack (enemy_range); + case "monster_demon1": + return DemonCheckAttack (enemy_range); + case "monster_dog": + return DogCheckAttack (enemy_range); + case "monster_wizard": + return WizardCheckAttack (enemy_range); + } + + return CheckAttack (enemy_range); +}; + + +/* +============= +ai_run_melee + +Turn and close until within an angle to launch a melee attack +============= +*/ +void(float enemy_yaw) ai_run_melee = +{ + self.ideal_yaw = enemy_yaw; + ChangeYaw (); + + if (FacingIdeal()) + { + self.th_melee (); + self.attack_state = AS_STRAIGHT; + } +}; + + +/* +============= +ai_run_missile + +Turn in place until within an angle to launch a missile attack +============= +*/ +void(float enemy_yaw) ai_run_missile = +{ + self.ideal_yaw = enemy_yaw; + ChangeYaw (); + if (FacingIdeal()) + { + self.th_missile (); + self.attack_state = AS_STRAIGHT; + } +}; + + +/* +============= +ai_run_slide + +Strafe sideways, but stay at aproximately the same range +============= +*/ +void(float enemy_yaw, float movedist) ai_run_slide = +{ + local float ofs; + + self.ideal_yaw = enemy_yaw; + ChangeYaw (); + if (self.lefty) + ofs = 90; + else + ofs = -90; + + if (walkmove (self.ideal_yaw + ofs, movedist)) + return; + + self.lefty = 1 - self.lefty; + + walkmove (self.ideal_yaw - ofs, movedist); +}; + +/* +============= +ai_run + +The monster has an enemy it is trying to kill +============= +*/ +void(float dist) ai_run = +{ + local float enemy_vis, enemy_yaw; + +// see if the enemy is dead + if (self.enemy.health <= 0) + { + self.enemy = world; + // FIXME: look all around for other targets + if (self.oldenemy.health > 0) + { + self.enemy = self.oldenemy; + HuntTarget (); + } + else + { + if (self.movetarget) + self.th_walk (); + else + self.th_stand (); + return; + } + } + + self.show_hostile = time + 1; // wake up other monsters + +// check knowledge of enemy + enemy_vis = visible(self.enemy); + if (enemy_vis) + self.search_time = time + 5; + +// look for other coop players + if (coop && self.search_time < time) + { + if (FindTarget ()) + return; + } + + enemy_yaw = vectoyaw(self.enemy.origin - self.origin); + + if (self.attack_state == AS_MISSILE) + { + ai_run_missile (enemy_yaw); + return; + } + if (self.attack_state == AS_MELEE) + { + ai_run_melee (enemy_yaw); + return; + } + + if (!enemy_vis) + return; + + if (CheckAnyAttack (range(self.enemy))) + return; // beginning an attack + + if (self.attack_state == AS_SLIDING) + { + ai_run_slide (enemy_yaw, dist); + return; + } + +// head straight in + movetogoal (dist); // done in C code... +}; + + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/basemod.txt b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/basemod.txt new file mode 100755 index 00000000..d93e8ef0 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/basemod.txt @@ -0,0 +1,42 @@ +Incomplete - +Triggered kills (explobox, etc) +Q2/Q3 ents +HL ents + +Done - +Cleanup warnings +Fix QW bugs +Heal decay (over maxhealth) +INTEGER mod +Nailgun frame seperation +Body queue change +Suicide timer limit +Suicide backpack/quad/ring drop +Condense bprint, sprint, centerprints +te_explode sprite +NQ/QW cross compatibility +Track oldbutton presses/weaponstate +Generic projectile spawning +Usage of ammo_shells, etc as display + +In progress - +Item fixing for SP +Add monsters back + +Todo - +Fix ammo_shells, etc for monsters/backpacks +Samelevel 4 (exit acts as a spawnpoint teleporter) +Effects/decal system +Fix weird deathmatch modes, cvar checking +Rogue/hipnotic weapons/monsters/hud stuffs +H2 ents +Coop friendly finale +Add in shambler resistance in a better way + +Stray Ideas - +Advanced heal decay (only decay health that the megahealth added?) +Clean up backpack pickup prints? +Decal system based on visibility from players? +CSQC? +Don't use newmis/spawn projectiles in front? +sv_gravity change? diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/bindings.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/bindings.qc new file mode 100755 index 00000000..120486db --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/bindings.qc @@ -0,0 +1,42 @@ +void () +player_bindings = +{ + stuffcmd (self, "r_novis 0\n"); + stuffcmd (self, "alias r_novis \n"); + stuffcmd (self, "r_wateralpha 1\n"); + stuffcmd (self, "alias r_wateralpha echo r_wateralpha has been disabled on this server.\n"); + stuffcmd (self, "chase_active 0\n"); + stuffcmd (self, "alias chase_active echo chase_active has been disabled on this server.\n"); + stuffcmd (self, "r_draworder 0\n"); + stuffcmd (self, "alias r_draworder echo r_draworder has been disabled on this server.\n"); + stuffcmd (self, "alias scr_ofsx echo screen offsets have been disabled on this server.\n"); + stuffcmd (self, "alias scr_ofsy echo screen offsets have been disabled on this server.\n"); + stuffcmd (self, "alias scr_ofsz echo screen offsets have been disabled on this server.\n"); + + vote_aliases (); + self.pflag = self.pflag | POQ_BINDINGS_SENT; + + bprint ("Player Bindings Sent\n"); +}; + +void () +player_bindings_think = +{ + local entity e; + + e = self; + self = e.owner; + remove (e); + player_bindings (); +}; + +void () +player_bindings_begin = +{ + local entity e; + + e = spawn (); + e.owner = self; + e.think = player_bindings_think; + e.nextthink = time + 2; +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/buttons.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/buttons.qc new file mode 100755 index 00000000..4e85b3e8 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/buttons.qc @@ -0,0 +1,138 @@ +// button and multiple button + +void() button_wait; +void() button_return; + +void() button_wait = +{ + self.state = STATE_TOP; + self.nextthink = self.ltime + self.wait; + self.think = button_return; + activator = self.enemy; + SUB_UseTargets(); + self.frame = 1; // use alternate textures +}; + +void() button_done = +{ + self.state = STATE_BOTTOM; +}; + +void() button_return = +{ + self.state = STATE_DOWN; + SUB_CalcMove (self.pos1, self.speed, button_done); + self.frame = 0; // use normal textures + if (self.health) + self.takedamage = DAMAGE_YES; // can be shot again +}; + + +void() button_blocked = +{ // do nothing, just don't ome all the way back out +}; + + +void() button_fire = +{ + if (self.state == STATE_UP || self.state == STATE_TOP) + return; + + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + + self.state = STATE_UP; + SUB_CalcMove (self.pos2, self.speed, button_wait); +}; + + +void() button_use = +{ + self.enemy = activator; + button_fire (); +}; + +void() button_touch = +{ + if (other.classname != "player") + return; + self.enemy = other; + button_fire (); +}; + +void() button_killed = +{ + self.enemy = damage_attacker; + self.health = self.max_health; + self.takedamage = DAMAGE_NO; // wil be reset upon return + button_fire (); +}; + + +/*QUAKED func_button (0 .5 .8) ? +When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again. + +"angle" determines the opening direction +"target" all entities with a matching targetname will be used +"speed" override the default 40 speed +"wait" override the default 1 second wait (-1 = never return) +"lip" override the default 4 pixel lip remaining at end of move +"health" if set, the button must be killed instead of touched +"sounds" +0) steam metal +1) wooden clunk +2) metallic click +3) in-out +*/ +void() func_button = +{ + switch (self.sounds) + { + case 0: + precache_sound ("buttons/airbut1.wav"); + self.noise = "buttons/airbut1.wav"; + break; + case 1: + precache_sound ("buttons/switch21.wav"); + self.noise = "buttons/switch21.wav"; + break; + case 2: + precache_sound ("buttons/switch02.wav"); + self.noise = "buttons/switch02.wav"; + break; + case 3: + precache_sound ("buttons/switch04.wav"); + self.noise = "buttons/switch04.wav"; + break; + } + + SetMovedir (); + + self.movetype = MOVETYPE_PUSH; + self.solid = SOLID_BSP; + setmodel (self, self.model); + + self.blocked = button_blocked; + self.use = button_use; + + if (self.health) + { + self.max_health = self.health; + self.th_die = button_killed; + self.takedamage = DAMAGE_YES; + } + else + self.touch = button_touch; + + if (!self.speed) + self.speed = 40; + if (!self.wait) + self.wait = 1; + if (!self.lip) + self.lip = 4; + + self.state = STATE_BOTTOM; + + self.pos1 = self.origin; + self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip); +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/client.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/client.qc new file mode 100755 index 00000000..e93215d8 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/client.qc @@ -0,0 +1,1518 @@ + +// prototypes +void () W_WeaponFrame; +void (float weap) W_WeaponSwitch; +void() player_pain; +void() player_stand1; +void (vector org) spawn_tfog; +void (vector org, entity death_owner) spawn_tdeath; + +float modelindex_eyes, modelindex_player; + +/* +============================================================================= + + LEVEL CHANGING / INTERMISSION + +============================================================================= +*/ + +string nextmap; + +/*QUAKED info_intermission (1 0.5 0.5) (-16 -16 -16) (16 16 16) +This is the camera point for the intermission. +Use mangle instead of angle, so you can set pitch or roll as well as yaw. 'pitch roll yaw' +*/ +void() info_intermission = +{ + self.angles = self.mangle; // so C can get at it +}; + + + +void() SetChangeParms = +{ + if (self.health <= 0) + { + SetNewParms (); + return; + } + +// cap super health + if (self.health > 130) + self.health = 130; + if (self.health < 50) + self.health = 50; + parm1 = self.items; + parm2 = self.health; + parm3 = self.armorvalue; + parm4 = 12; + /* + if (self.ammo_shells_real < 25) + parm4 = 25; + else + parm4 = self.ammo_shells_real; + */ + parm5 = self.ammo_nails_real; + parm6 = self.ammo_rockets_real; + parm7 = self.ammo_cells_real; + parm8 = self.weapon; + parm9 = self.armortype; + // Solitude + parm10 = self.exshells; + parm11 = self.exnails; + parm12 = self.exrockets; + parm13 = self.excells; + parm14 = self.ammo_shells2; + parm15 = self.exshells2; + parm16 = self.nade_lives; +}; + +void() SetNewParms = +{ + parm1 = WEAPON_AR + WEAPON_PPISTOL; // start Assault rifle + parm2 = 130; + parm3 = 0; + parm4 = 0; + //parm4 = 25; + parm5 = 0; + parm6 = 0; + parm7 = 0; + parm8 = WEAPON_AR; // start Assault rifle + parm9 = 0; + // Solitude + parm10 = 60; + parm11 = 560; + parm12 = MSG_BROADCAST; + parm13 = MSG_BROADCAST; + parm14 = SVC_INTERMISSION; + parm15 = 60; + parm16 = 4; +}; + +void() DecodeLevelParms = +{ + if (!deathmatch) + { + if (world.model == "maps/start.bsp") + SetNewParms (); // take away all stuff on starting new episode + } + + self.items = parm1; + self.health = parm2; + self.armorvalue = parm3; + self.ammo_shells_real = parm4; + self.ammo_nails_real = parm5; + self.ammo_rockets_real = parm6; + self.ammo_cells_real = parm7; + self.weapon = parm8; + self.armortype = parm9; + // solitude + self.ammo_hshells = 0; + self.exhshells = 0; + self.exshells = 0; + self.exnails = 0; + self.exrockets = 0; + self.excells = 0; + self.ammo_shells2 = 0; + self.exshells2 = 0; + self.nade_lives = parm16; + self.plasma_lives = parm16; + // weapon we start with: +}; + +/* +============ +FindIntermission + +Returns the entity to view from +============ +*/ +entity() FindIntermission = +{ + local entity spot; + local float cyc; + +// look for info_intermission first + spot = find (world, classname, "info_intermission"); + if (spot) + { // pick a random one + cyc = random() * 4; + while (cyc > 1) + { + spot = find (spot, classname, "info_intermission"); + if (!spot) + spot = find (spot, classname, "info_intermission"); + cyc = cyc - 1; + } + return spot; + } + +// then look for the start position + spot = find (world, classname, "info_player_start"); + if (spot) + return spot; + + objerror ("FindIntermission: no spot"); + return world; // remove warning +}; + +void() GotoNextMap = +{ + local string newmap; + +//ZOID: 12-13-96, samelevel is overloaded, only 1 works for same level + + if (cvar("samelevel") == 1) // if samelevel is set, stay on same level + changelevel (mapname); + else { + // configurable map lists, see if the current map exists as a + // serverinfo/localinfo var + newmap = stringserverinfokey(mapname); + if (newmap != "") + changelevel (newmap); + else + changelevel (nextmap); + } +}; + +void() ExitIntermission= +{ +// skip any text in deathmatch + if (deathmatch) + { + GotoNextMap (); + return; + } + + intermission_exittime = time + 1; + intermission_running = intermission_running + 1; + +// +// run some text if at the end of an episode +// + if (intermission_running == 2) + { + if (world.model == "maps/e1m7.bsp") + { + ENG_SwitchTrack(2, 3); + if (!cvar("registered")) + { + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task in the other three\nhaunted lands of Quake. Or are you? If\nyou don't register Quake, you'll never\nknow what awaits you in the Realm of\nBlack Magic, the Netherworld, and the\nElder World!"); + } + else + { + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task. A Rune of magic\npower lies at the end of each haunted\nland of Quake. Go forth, seek the\ntotality of the four Runes!"); + } + return; + } + else if (world.model == "maps/e2m6.bsp") + { + ENG_SwitchTrack(2, 3); + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "The Rune of Black Magic throbs evilly in\nyour hand and whispers dark thoughts\ninto your brain. You learn the inmost\nlore of the Hell-Mother; Shub-Niggurath!\nYou now know that she is behind all the\nterrible plotting which has led to so\nmuch death and horror. But she is not\ninviolate! Armed with this Rune, you\nrealize that once all four Runes are\ncombined, the gate to Shub-Niggurath's\nPit will open, and you can face the\nWitch-Goddess herself in her frightful\notherworld cathedral."); + return; + } + else if (world.model == "maps/e3m6.bsp") + { + ENG_SwitchTrack(2, 3); + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "The charred viscera of diabolic horrors\nbubble viscously as you seize the Rune\nof Hell Magic. Its heat scorches your\nhand, and its terrible secrets blight\nyour mind. Gathering the shreds of your\ncourage, you shake the devil's shackles\nfrom your soul, and become ever more\nhard and determined to destroy the\nhideous creatures whose mere existence\nthreatens the souls and psyches of all\nthe population of Earth."); + return; + } + else if (world.model == "maps/e4m7.bsp") + { + ENG_SwitchTrack(2, 3); + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "Despite the awful might of the Elder\nWorld, you have achieved the Rune of\nElder Magic, capstone of all types of\narcane wisdom. Beyond good and evil,\nbeyond life and death, the Rune\npulsates, heavy with import. Patient and\npotent, the Elder Being Shub-Niggurath\nweaves her dire plans to clear off all\nlife from the Earth, and bring her own\nfoul offspring to our world! For all the\ndwellers in these nightmare dimensions\nare her descendants! Once all Runes of\nmagic power are united, the energy\nbehind them will blast open the Gateway\nto Shub-Niggurath, and you can travel\nthere to foil the Hell-Mother's plots\nin person."); + return; + } + + GotoNextMap(); + } + + if (intermission_running == 3) + { + if (!cvar("registered")) + { // shareware episode has been completed, go to sell screen + WriteByte (MSG_ALL, SVC_SELLSCREEN); + return; + } + + if ( (serverflags&15) == 15) + { + WriteByte (MSG_ALL, SVC_FINALE); + WriteString (MSG_ALL, "Now, you have all four Runes. You sense\ntremendous invisible forces moving to\nunseal ancient barriers. Shub-Niggurath\nhad hoped to use the Runes Herself to\nclear off the Earth, but now instead,\nyou will use them to enter her home and\nconfront her as an avatar of avenging\nEarth-life. If you defeat her, you will\nbe remembered forever as the savior of\nthe planet. If she conquers, it will be\nas if you had never been born."); + return; + } + + } + + GotoNextMap(); +}; + +/* +============ +IntermissionThink + +When the player presses attack or jump, change to the next level +============ +*/ +void() IntermissionThink = +{ + if (time < intermission_exittime) + return; + + if (!self.button0 && !self.button1 && !self.button2) + return; + + ExitIntermission (); +}; + +/* +============ +execute_changelevel + +The global "nextmap" has been set previously. +Take the players to the intermission spot +============ +*/ +void() execute_changelevel = +{ + local entity pos; + + intermission_running = 1; + +// enforce a wait time before allowing changelevel + if (deathmatch) + intermission_exittime = time + 5; + else + intermission_exittime = time + 2; + + pos = FindIntermission (); + +// play intermission music + ENG_SwitchTrack(3, 3); + +#ifdef NETQUAKE + pos = FindIntermission (); + + other = find (world, classname, "player"); + while (other != world) + { + other.view_ofs = '0 0 0'; + other.angles = other.v_angle = pos.mangle; + other.fixangle = TRUE; // turn this way immediately + other.nextthink = time + 0.5; + other.takedamage = DAMAGE_NO; + other.solid = SOLID_NOT; + other.movetype = MOVETYPE_NONE; + other.modelindex = 0; + setorigin (other, pos.origin); + other = find (other, classname, "player"); + } + + WriteByte (MSG_ALL, SVC_INTERMISSION); +#else + WriteByte (MSG_ALL, SVC_INTERMISSION); + WriteCoord (MSG_ALL, pos.origin_x); + WriteCoord (MSG_ALL, pos.origin_y); + WriteCoord (MSG_ALL, pos.origin_z); + WriteAngle (MSG_ALL, pos.mangle_x); + WriteAngle (MSG_ALL, pos.mangle_y); + WriteAngle (MSG_ALL, pos.mangle_z); + + other = find (world, classname, "player"); + while (other != world) + { + other.takedamage = DAMAGE_NO; + other.solid = SOLID_NOT; + other.movetype = MOVETYPE_NONE; + other.modelindex = 0; + other = find (other, classname, "player"); + } +#endif +}; + + +void() changelevel_touch = +{ + if (other.classname != "player") + return; + +// if "noexit" is set, blow up the player trying to leave +//ZOID, 12-13-96, noexit isn't supported in QW. Overload samelevel +// if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start"))) + if (deathmatch) + { + if ((cvar("samelevel") == 2) || ((cvar("samelevel") == 3) && (mapname != "start"))) + { + T_Damage (other, self, self, 50000, MOD_EXIT); + return; + } + } + + bprint2 (PRINT_HIGH, other.netname, " exited the level\n"); + + nextmap = self.map; + + SUB_UseTargets (); + + self.touch = SUB_Null; + +// we can't move people right now, because touch functions are called +// in the middle of C movement code, so set a think time to do it + self.think = execute_changelevel; + self.nextthink = time + 0.1; +}; + +/*QUAKED trigger_changelevel (0.5 0.5 0.5) ? NO_INTERMISSION +When the player touches this, he gets sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats. +*/ +void() trigger_changelevel = +{ + if (!self.map) + objerror ("chagnelevel trigger doesn't have map"); + + InitTrigger (); + self.touch = changelevel_touch; +}; + + +/* +============================================================================= + + PLAYER GAME EDGE FUNCTIONS + +============================================================================= +*/ + +void() set_suicide_frame; + +// create a deadbody ent that is removed over time +void(entity ent) CopyToDeadbody = +{ + local entity deadbody; + + deadbody = spawn(); + deadbody.angles = ent.angles; + deadbody.model = ent.model; + deadbody.modelindex = ent.modelindex; + deadbody.frame = ent.frame; + deadbody.colormap = ent.colormap; + deadbody.movetype = ent.movetype; + deadbody.velocity = ent.velocity; + deadbody.flags = 0; + setorigin (deadbody, ent.origin); + setsize (deadbody, ent.mins, ent.maxs); + + deadbody.think = SUB_Remove; + deadbody.nextthink = time + 5; +}; + +// called by ClientKill and DeadThink +void() respawn = +{ + if (self.setup_death == #TRUE) { + Player_SetupDeath(); + } +}; + +void () true_respawn = +{ + if (coop) + { + // make a copy of the dead body for appearances sake + CopyToDeadbody (self); + // get the spawn parms as they were at level start + setspawnparms (self); + // respawn + PutClientInServer (); + } + else if (deathmatch) + { + // make a copy of the dead body for appearances sake + CopyToDeadbody (self); + // set default spawn parms + SetNewParms (); + // respawn + PutClientInServer (); + } + else + { // restart the entire server + localcmd ("restart\n"); + } +}; + +/* +============ +ClientKill + +Player entered the suicide command +============ +*/ +void() PlayerDropStuff; + +void() ClientKill = +{ + if (intermission_running) + return; + + if (self.suicide_time > time) + return; + + stuffcmd(self,"chase_active 1\n"); + self.setup_death = #TRUE; + self.health = 0; + + bprint2 (PRINT_MEDIUM, self.netname, " suicides\n"); + PlayerDropStuff (); + set_suicide_frame (); +CTF_Flag_Drop(); + self.modelindex = modelindex_player; + logfrag (self, self) + self.frags = self.frags - 2; // extra penalty + + respawn (); +}; + +/* +============ +SelectSpawnPoint + +Returns the entity to spawn at +============ +*/ +entity() SelectSpawnPoint = +{ + local entity spot, thing; + local float numspots, totalspots; + local float pcount; + local entity spots; + + if (coop) // coop spawning + { + if (!spotspawn) + { + spotspawn = 1; + spot = find (world, classname, "info_player_start"); + if (spot) + return spot; + } + lastspawn = find(lastspawn, classname, "info_player_coop"); + if (lastspawn) + return lastspawn; + } + + if (!deathmatch) // single player spawning + { + if (serverflags) + { // return with a rune to start + spot = find (world, classname, "info_player_start2"); + if (spot) + return spot; + } + + spot = find (world, classname, "info_player_start"); + if (spot) + return spot; + } + + // QuakeWorld style deathmatch spawning + numspots = 0; + totalspots = 0; + + // choose a info_player_deathmatch point + // ok, find all spots that don't have players nearby + spots = world; + spot = find (world, classname, "info_player_deathmatch"); + while (spot) + { + totalspots = totalspots + 1; + + thing=findradius(spot.origin, 84); + pcount=0; + while (thing) + { + if (thing.classname == "player") + pcount=pcount + 1; + thing=thing.chain; + } + if (pcount == 0) { + spot.goalentity = spots; + spots = spot; + numspots = numspots + 1; + } + + // Get the next spot in the chain + spot = find (spot, classname, "info_player_deathmatch"); + } + totalspots=totalspots - 1; + if (!numspots) { + // ack, they are all full, just pick one at random + totalspots = rint((random() * totalspots)); + spot = find (world, classname, "info_player_deathmatch"); + while (totalspots > 0) { + totalspots = totalspots - 1; + spot = find (spot, classname, "info_player_deathmatch"); + } + return spot; + } + + // We now have the number of spots available on the map in numspots + // Generate a random number between 1 and numspots + numspots = numspots - 1; + numspots = rint((random() * numspots)); + + spot = spots; + while (numspots > 0) { + spot = spot.goalentity; + numspots = numspots - 1; + } + return spot; + +}; +void() DecodeLevelParms; +void() PlayerDie; + +/* +=========== +PutClientInServer + +called each time a player enters a new level +============ +*/ +void() PutClientInServer = +{ + local entity spot; + local float wtemp; + + self.classname = "player"; + self.health = 130; + self.takedamage = DAMAGE_AIM; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_WALK; + self.show_hostile = 0; + self.max_health = 130; + self.flags = FL_CLIENT; + self.air_finished = time + 12; + self.waterdmg = 2; // initial water damage + self.super_damage_finished = 0; + self.radsuit_finished = 0; + self.invisible_finished = 0; + self.invincible_finished = 0; + self.effects = 0; + self.invincible_time = 0; + self.suicide_time = time + 3; + self.weaponstate = WS_IDLE; + DecodeLevelParms (); + // dumb hack until I get the real weapon system in + wtemp = self.weapon; + + if (deathmatch == 4) + { + self.ammo_shells_real = 0; + if (numberserverinfokey("axe") == 0) + { + self.ammo_nails_real = 255; + self.ammo_shells_real = 255; + self.ammo_rockets_real = 255; + self.ammo_cells_real = 255; + self.items |= IT_NAILGUN + | IT_SUPER_NAILGUN + | IT_SUPER_SHOTGUN + | IT_ROCKET_LAUNCHER + | IT_LIGHTNING; + } + else + wtemp = IT_AXE; + + self.items |= IT_ARMOR3 | IT_INVULNERABILITY; + self.items = self.items - (self.items & (IT_ARMOR1 | IT_ARMOR2)); + self.armorvalue = 200; + self.armortype = 0.8; + self.health = 250; + self.invincible_time = 1; + self.invincible_finished = time + 3; + } + + if (deathmatch == 5) + { + self.ammo_nails_real = 80; + self.ammo_shells_real = 30; + self.ammo_rockets_real = 10; + self.ammo_cells_real = 30; + self.items |= IT_NAILGUN + | IT_SUPER_NAILGUN + | IT_SUPER_SHOTGUN + | IT_ROCKET_LAUNCHER + | IT_GRENADE_LAUNCHER + | IT_LIGHTNING + | IT_ARMOR3 + | IT_INVULNERABILITY; + self.items = self.items - (self.items & (IT_ARMOR1 | IT_ARMOR2)); + self.armorvalue = 200; + self.armortype = 0.8; + self.health = 200; + self.invincible_time = 1; + self.invincible_finished = time + 3; + } + + self.weapon = 0; + W_WeaponSwitch (wtemp); + + self.attack_finished = time; + self.th_pain = player_pain; + self.th_die = PlayerDie; + + self.deadflag = DEAD_NO; + + spot = SelectSpawnPoint (); + + self.origin = spot.origin + '0 0 1'; + self.angles = spot.angles; + self.fixangle = TRUE; // turn this way immediately + +// oh, this is a hack! + setmodel (self, "progs/eyes.mdl"); + modelindex_eyes = self.modelindex; + + setmodel (self, "progs/player.mdl"); + modelindex_player = self.modelindex; + + setsize (self, VEC_HULL_MIN, VEC_HULL_MAX); + + self.view_ofs = '0 0 22'; + +// Mod - Xian (May.20.97) +// Bug where player would have velocity from their last kill + + self.velocity = '0 0 0'; + + player_stand1 (); + + makevectors(self.angles); + spawn_tfog (self.origin + v_forward*20); + + spawn_tdeath (self.origin, self); + + // Set Rocket Jump Modifiers + rj = numberserverinfokey("rj"); + + W_StartWeapon (); + + self.needles = 0; + + + self.pfov = FOV_DEFAULT; + Set_FOV( self.pfov ); + + self.reset = 0; + self.groundwep = 0; + self.weaponheat = 0; + + stuffcmd(self,"chase_active 0\n"); + NadeCounter(); + AmmoCounter(); +}; + + +/* +============================================================================= + + QUAKED FUNCTIONS + +============================================================================= +*/ + + +/*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 24) +The normal starting point for a level. +*/ +void() info_player_start = +{ +}; + + +/*QUAKED info_player_start2 (1 0 0) (-16 -16 -24) (16 16 24) +Only used on start map for the return point from an episode. +*/ +void() info_player_start2 = +{ +}; + +/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 24) +potential spawning position for deathmatch games +*/ +void() info_player_deathmatch = +{ +}; + +/*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24) +potential spawning position for coop games +*/ +void() info_player_coop = +{ +}; + +/* +=============================================================================== + +RULES + +=============================================================================== +*/ + +/* +go to the next level for deathmatch +*/ +void() NextLevel = +{ + local entity o; + + if (nextmap != "") + return; // already done + + if (mapname == "start") + { + if (!cvar("registered")) + { + mapname = "e1m1"; + } + else if (!(serverflags & 1)) + { + mapname = "e1m1"; + serverflags = serverflags | 1; + } + else if (!(serverflags & 2)) + { + mapname = "e2m1"; + serverflags = serverflags | 2; + } + else if (!(serverflags & 4)) + { + mapname = "e3m1"; + serverflags = serverflags | 4; + } + else if (!(serverflags & 8)) + { + mapname = "e4m1"; + serverflags = serverflags - 7; + } + + o = spawn(); + o.map = mapname; + } + else + { + // find a trigger changelevel + o = find(world, classname, "trigger_changelevel"); + if (!o || mapname == "start") + { // go back to same map if no trigger_changelevel + o = spawn(); + o.map = mapname; + } + } + + nextmap = o.map; + + if (o.nextthink < time) + { + o.think = execute_changelevel; + o.nextthink = time + 0.1; + } +}; + +/* +============ +CheckRules + +Exit deathmatch games upon conditions +============ +*/ +void() CheckRules = +{ + if (deathmatch && timelimit && time >= timelimit) + NextLevel (); + + if (deathmatch && fraglimit && self.frags >= fraglimit) + NextLevel (); +}; + +void () player_respawn_think = +{ + local entity oself; + + if (self.owner.classname != "player" || self.owner == world || self.owner.health > 0) { + remove(self); + return; + } + self.health -= 1; + sprint(self.owner, "You will respawn in "); + sprint(self.owner, ftos(self.health)); + sprint(self.owner, " seconds.\n"); + + if (self.health < 1) { + oself = self; + + self = self.owner; + self.impulse = 0; + self.button0 = 0; + self.button1 = 0; + self.button2 = 0; + true_respawn(); + + self = oself; + remove(self); + return; + } + + self.nextthink = time + 1; +}; + +void () Player_SetupDeath = +{ + local entity dt; + + dt = spawn(); + dt.health = 8; + dt.owner = self; + dt.think = player_respawn_think; + dt.nextthink = time + 1; + sprint(self, "You will respawn in "); + sprint(self, ftos(dt.health)); + sprint(self, " seconds.\n"); + self.setup_death = #FALSE; + self.weaponframe = 0; +}; + + +//============================================================================ + +void() PlayerDeathThink = +{ + local float forward; + + if (self.setup_death == #TRUE) { + Player_SetupDeath(); + } + + if ((self.flags & FL_ONGROUND)) + { + forward = vlen (self.velocity); + forward = forward - 20; + if (forward <= 0) + self.velocity = '0 0 0'; + else + self.velocity = forward * normalize(self.velocity); + } + +// wait for all buttons released + if (self.deadflag == DEAD_DEAD) + { + if (self.button2 || self.button1 || self.button0) + return; + self.deadflag = DEAD_RESPAWNABLE; + return; + } + +// wait for any button down + if (!self.button2 && !self.button1 && !self.button0) + return; + + self.button0 = 0; + self.button1 = 0; + self.button2 = 0; + respawn(); +}; + + +void() PlayerJump = +{ + local float vjump; + vjump = cvar("sol_jump"); + + if (self.flags & FL_WATERJUMP) + return; + + if (self.next_jump_time > time) { + stuffcmd( self, "-jump\n" ); + return; + } + + if (self.waterlevel >= 2) + { +// play swiming sound + if (self.swim_flag < time) + { + self.swim_flag = time + 1; + if (random() < 0.5) + sound (self, CHAN_BODY, "misc/water1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_BODY, "misc/water2.wav", 1, ATTN_NORM); + } + + return; + } + +if (!(self.flags & FL_ONGROUND)) + return; + + if ( !(self.flags & FL_JUMPRELEASED) ) + return; // don't pogo stick + + self.flags = self.flags - (self.flags & FL_JUMPRELEASED); + self.button2 = 0; + +// player jumping sound + sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM); + + if (vjump) { + self.velocity_z = self.velocity_z + vjump; + } + else { +#ifdef NETQUAKE + self.flags = self.flags - FL_ONGROUND; + self.velocity_z = self.velocity_z + 225; +#endif + } + self.jump_time = time + .15; +}; + + +/* +=========== +WaterMove + +============ +*/ +void() WaterMove = +{ +//dprint (ftos(self.waterlevel)); + if (self.movetype == MOVETYPE_NOCLIP) + return; + if (self.health < 0) + return; + + if (self.waterlevel != 3) + { + if (self.air_finished < time) + sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM); + else if (self.air_finished < time + 9) + sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM); + self.air_finished = time + 12; + self.waterdmg = 2; + } + else if (self.air_finished < time) + { // drown! + if (self.pain_finished < time) + { + self.waterdmg = self.waterdmg + 2; + if (self.waterdmg > 15) + self.waterdmg = 10; + T_Damage (self, world, world, self.waterdmg, MOD_DROWN); + self.pain_finished = time + 1; + } + } + + if (!self.waterlevel) + { + if (self.flags & FL_INWATER) + { + // play leave water sound + sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM); + self.flags = self.flags - FL_INWATER; + } + return; + } + + if ( !(self.flags & FL_INWATER) ) + { + // player enter water sound + switch (self.watertype) + { + case CONTENT_LAVA: + sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM); + break; + case CONTENT_WATER: + sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM); + break; + case CONTENT_SLIME: + sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM); + break; + } + + self.flags = self.flags + FL_INWATER; + self.dmgtime = 0; + } + + if (self.watertype == CONTENT_LAVA) + { // do damage + if (self.dmgtime < time) + { + if (self.radsuit_finished > time) + self.dmgtime = time + 1; + else + self.dmgtime = time + 0.2; + + T_Damage (self, world, world, 10*self.waterlevel, MOD_LAVA); + } + } + else if (self.watertype == CONTENT_SLIME) + { // do damage + if (self.dmgtime < time && self.radsuit_finished < time) + { + self.dmgtime = time + 1; + T_Damage (self, world, world, 4*self.waterlevel, MOD_SLIME); + } + } + +}; + +void() CheckWaterJump = +{ + local vector start, end; + +// check for a jump-out-of-water + makevectors (self.angles); + start = self.origin; + start_z = start_z + 8; + v_forward_z = 0; + normalize(v_forward); + end = start + v_forward*24; + traceline (start, end, TRUE, self); + if (trace_fraction < 1) + { // solid at waist + start_z = start_z + self.maxs_z - 8; + end = start + v_forward*24; + self.movedir = trace_plane_normal * -50; + traceline (start, end, TRUE, self); + if (trace_fraction == 1) + { // open at eye level + self.flags = self.flags | FL_WATERJUMP; + self.velocity_z = 225; + self.flags = self.flags - (self.flags & FL_JUMPRELEASED); + self.teleport_time = time + 2; // safety net + return; + } + } +}; + +/* +================ +PlayerPreThink + +Called every frame before physics are run +================ +*/ +void() PlayerPreThink = +{ +if (self.weapon == IT_SKULL) +{ + if (score_lastTic < time) + { + self.frags = self.frags + 1; + score_lastTic = time + 1; + } +} + if (BotPreFrame()) // FrikBot + return; + if (intermission_running) + { + IntermissionThink (); // otherwise a button could be missed between + return; // the think tics + } + +// if intermission is running what is the point of this? +// if (self.view_ofs == '0 0 0') +// return; + + makevectors (self.v_angle); // is this still used + + CheckRules (); + WaterMove (); +/* + if (self.waterlevel == 2) + CheckWaterJump (); +*/ + + if (self.deadflag >= DEAD_DEAD) + { + PlayerDeathThink (); + return; + } + + if (self.deadflag == DEAD_DYING) + return; // dying, so do nothing + + if (self.button2) + PlayerJump (); + else + self.flags = self.flags | FL_JUMPRELEASED; + + if(time > self.attack_finished && self.currentammo == 0 && self.weapon != IT_AXE) + { + W_WeaponSwitch (W_BestWeapon ()); + } +self.reset = self.reset + 0.005; +self.groundwep = self.groundwep - 0.5; + + if (self.groundwep <= 0.0) + { + stuffcmd (self, "cl_ww 0\n"); + } + +/*( if (self.reset >= 1.000) + { +// localcmd ("cl_doublek 0\n"); +// localcmd ("cl_triplek 0\n"); +// localcmd ("cl_killt 0\n"); + localcmd ("cl_killtrocity 0\n"); + self.reset = 0; + }*/ + + + +}; + +/* +================ +CheckPowerups + +Check for turning off powerups +================ +*/ +void() CheckPowerups = +{ + if (self.health <= 0) + return; + +// invisibility + if (self.invisible_finished) + { +// sound and screen flash when items starts to run out + if (self.invisible_sound < time) + { + sound (self, CHAN_AUTO, "items/inv3.wav", 0.5, ATTN_IDLE); + self.invisible_sound = time + ((random() * 3) + 1); + } + + + if (self.invisible_finished < time + 3) + { + if (self.invisible_time == 1) + { + sprint1 (self, PRINT_HIGH, "Ring of Shadows magic is fading\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/inv2.wav", 1, ATTN_NORM); + self.invisible_time = time + 1; + } + + if (self.invisible_time < time) + { + self.invisible_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.invisible_finished < time) + { // just stopped + self.items = self.items - IT_INVISIBILITY; + self.invisible_finished = 0; + self.invisible_time = 0; + } + + // use the eyes + self.frame = 0; + self.modelindex = modelindex_eyes; + } + else + self.modelindex = modelindex_player; // don't use eyes + +// invincibility + if (self.invincible_finished) + { +// sound and screen flash when items starts to run out + if (self.invincible_finished < time + 3) + { + if (self.invincible_time == 1) + { + sprint1 (self, PRINT_HIGH, "Protection is almost burned out\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/protect2.wav", 1, ATTN_NORM); + self.invincible_time = time + 1; + } + + if (self.invincible_time < time) + { + self.invincible_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.invincible_finished < time) + { // just stopped + self.items = self.items - IT_INVULNERABILITY; + self.invincible_time = 0; + self.invincible_finished = 0; + } + if (self.invincible_finished > time) + self.effects = self.effects | ef_pent; + else + self.effects = self.effects - (self.effects & ef_pent); + } + +// super damage + if (self.super_damage_finished) + { + +// sound and screen flash when items starts to run out + + if (self.super_damage_finished < time + 3) + { + if (self.super_time == 1) + { + if (deathmatch == 4) + sprint1 (self, PRINT_HIGH, "OctaPower is wearing off\n"); + else + sprint1 (self, PRINT_HIGH, "Quad Damage is wearing off\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/damage2.wav", 1, ATTN_NORM); + self.super_time = time + 1; + } + + if (self.super_time < time) + { + self.super_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.super_damage_finished < time) + { // just stopped + self.items = self.items - IT_QUAD; + if (deathmatch == 4) + { + self.ammo_cells_real = 255; + W_UpdateAmmoCounts(self); + self.armorvalue = 1; + self.armortype = 0.8; + self.health = 100; + } + self.super_damage_finished = 0; + self.super_time = 0; + } + if (self.super_damage_finished > time) + self.effects = self.effects | ef_quad; + else + self.effects = self.effects - (self.effects & ef_quad); + } + +// suit + if (self.radsuit_finished) + { + self.air_finished = time + 12; // don't drown + +// sound and screen flash when items starts to run out + if (self.radsuit_finished < time + 3) + { + if (self.rad_time == 1) + { + sprint1 (self, PRINT_HIGH, "Air supply in Biosuit expiring\n"); + stuffcmd (self, "bf\n"); + sound (self, CHAN_AUTO, "items/suit2.wav", 1, ATTN_NORM); + self.rad_time = time + 1; + } + + if (self.rad_time < time) + { + self.rad_time = time + 1; + stuffcmd (self, "bf\n"); + } + } + + if (self.radsuit_finished < time) + { // just stopped + self.items = self.items - IT_SUIT; + self.rad_time = 0; + self.radsuit_finished = 0; + } + } + +}; + + +/* +================ +PlayerPostThink + +Called every frame after physics are run +================ +*/ +void() PlayerPostThink = +{ + if (BotPostFrame()) // FrikBot + return; +//dprint ("post think\n"); + if (intermission_running) + return; +// if (self.view_ofs == '0 0 0') +// return; + if (self.deadflag) + return; + + if (!self.flags & FL_ONGROUND) + if (self.next_jump_time < time) + self.next_jump_time = time + .05; + + self.jump_flag = self.velocity_z; + + + //CheckPowerups (); + + W_WeaponFrame (); + +}; + + +/* +=========== +ClientConnect + +called when a player connects to a server +============ +*/ +void() ClientConnect = +{ + ClientInRankings(); // FrikBot + bprint2 (PRINT_HIGH, self.netname, " entered the game\n"); + +// a client connecting during an intermission can cause problems + if (intermission_running) + GotoNextMap (); +}; + + +void() ClientDisconnect = +{ + ClientDisconnected(); // FrikBot + // let everyone else know + bprint4 (PRINT_HIGH, self.netname, " left the game with ", ftos(self.frags), " frags\n"); + sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE); + set_suicide_frame (); +}; +void(entity playermedal, float howmany) killmedals = +{ + if (howmany == 10) + centerprint(playermedal, "Killpocalypse!\n"); + else if (howmany == 9) + centerprint(playermedal, "Killpocalypse!\n"); + else if (howmany == 8) + centerprint(playermedal, "Killtastrophe!\n"); + else if (howmany == 7) + centerprint(playermedal, "Killimanjaro!\n"); + else if (howmany == 6) + { + playermedal.reset = 0.000; + stuffcmd (playermedal, "cl_killtrocity 0\n"); + centerprint(playermedal, "Overkill!\n"); + } + else if (howmany == 5) + { + playermedal.reset = 0.000; + centerprint(playermedal, "Killtrocity!\n"); + stuffcmd (playermedal, "play killtrocity.wav\n"); + stuffcmd (playermedal, "cl_killtrocity 1\n"); + stuffcmd (playermedal, "cl_killt 0\n"); + stuffcmd (playermedal, "cl_triplek 0\n"); + stuffcmd (playermedal, "cl_doublek 0\n"); + } + else if (howmany == 4) + { + playermedal.reset = 0.000; + centerprint(playermedal, "KillTacular!\n"); + stuffcmd (playermedal, "play killtacular.wav\n"); + stuffcmd (playermedal, "cl_killt 1\n"); + stuffcmd (playermedal, "cl_killtrocity 0\n"); + stuffcmd (playermedal, "cl_triplek 0\n"); + stuffcmd (playermedal, "cl_doublek 0\n"); + } + else if (howmany == 3) { + playermedal.reset = 0.000; + centerprint(playermedal, "Triple Kill!\n"); + stuffcmd (playermedal, "play triple.wav\n"); + stuffcmd (playermedal, "cl_triplek 1\n"); + stuffcmd (playermedal, "cl_doublek 0\n"); + stuffcmd (playermedal, "cl_killt 0\n"); + stuffcmd (playermedal, "cl_killtrocity 0\n"); + } + else if (howmany == 2) { + playermedal.reset = 0.000; + centerprint(playermedal, "Double Kill!\n"); + stuffcmd(playermedal,"play double.wav\n"); + stuffcmd (playermedal, "cl_doublek 1\n"); + stuffcmd (playermedal, "cl_triplek 0\n"); + stuffcmd (playermedal, "cl_killt 0\n"); + stuffcmd (playermedal, "cl_killtrocity 0\n"); + } + else + return; +}; +/* +=========== +ClientObituary + +called when a player dies +============ +*/ +BOOL(entity targ, entity attacker) OnSameTeam; + +void(entity targ, entity attacker, INTEGER mod) ClientObituary = +{ + //Kill Medals +if (attacker.kill_time >= time) +{ + attacker.kill_amount = attacker.kill_amount + 1; + killmedals (attacker, attacker.kill_amount); +} +else + attacker.kill_amount = 1; +if (targ.classname == "player") + attacker.kill_time = time + 4; + +if (attacker.flags & FL_CLIENT) + { + if (attacker == targ) + { + SuicideMessage(targ.netname, mod); + targ.frags = targ.frags - 1; + logfrag(targ, targ) + return; + } // else if anything else + + if (OnSameTeam(targ, attacker)) + { + TeamKillMessage(targ.netname, attacker.netname, mod); + logfrag(attacker, attacker) + attacker.frags = attacker.frags - 1; + return; + } + + if (targ.flags & FL_CLIENT) + { + KillMessage(targ.netname, attacker.netname, mod); + attacker.frags = attacker.frags + 1; + logfrag(attacker, targ) + } + return; + } // else if attacker != player + + if (targ.flags & FL_CLIENT) + { + WorldKillMessage(targ.netname, mod); + targ.frags = targ.frags - 1; + logfrag(targ, targ) + } +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/combat.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/combat.qc new file mode 100755 index 00000000..88a5a32a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/combat.qc differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/ctf.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/ctf.qc new file mode 100755 index 00000000..36118e2d --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/ctf.qc @@ -0,0 +1,246 @@ +.vector flag_base; + +.entity flag_ent; + +.float update_print; + +.float flag_state; +float FLAG_STATE_BASE = 0; +float FLAG_STATE_DROPPED = 1; +float FLAG_STATE_CARRIED = 2; + +float TEAM_BLUE = 14; +float TEAM_RED = 5; + +vector(entity e) realorg = +{ + return ((e.absmin + e.absmax) * 0.5); +}; + +string(float whichteam) CTF_TeamString = +{ + if (whichteam == TEAM_BLUE) + return "\bBLUE"; + else + return "\bRED"; +}; + +void(float st) CTF_Flag_SetState = +{ + self.flag_state = st; + + if ( (st == FLAG_STATE_BASE) || (st == FLAG_STATE_DROPPED) ) + { + self.owner = world; + self.solid = SOLID_TRIGGER; + } + else if (st == FLAG_STATE_CARRIED) + self.solid = SOLID_NOT; +}; + +// go back home +void() CTF_Flag_SendToBase = +{ + if (self.flag_state == FLAG_STATE_DROPPED) + { + bprint(CTF_TeamString(self.team)); + bprint(" flag was returned to base!\n"); + } + + setorigin(self, self.flag_base); + CTF_Flag_SetState(FLAG_STATE_BASE); + +}; + +// give the team points! +void() CTF_Flag_Capture = +{ + local entity e, oself; + + bprint(other.netname); + bprint(" captured the "); + bprint(CTF_TeamString(other.flag_ent.team)); + bprint(" flag!\n"); + + centerprint(other, "\n"); + + e = find(world, classname, "player"); + while (e) + { + if (e.team == other.team) + e.frags = e.frags + 10; + + e = find(e, classname, "player"); + } + + // todo: play some noise and do happy dance + + oself = self; + self = other.flag_ent; + CTF_Flag_SendToBase(); + self = oself; + + other.flag_ent = world; +}; + +// braaaaains +void() CTF_Flag_Think = +{ + if (self.flag_state == FLAG_STATE_CARRIED) + { + // stay tracking with them, behind a little bit + makevectors(self.owner.v_angle); + setorigin (self, realorg(self.owner) + (v_forward * -14)); + + if (self.owner.update_print < time) + { + centerprint(self.owner, " \n \n \n \n \n \n \n \n \nYou have the flag!\nReturn to your base."); + self.owner.update_print = time + 1.5; + } + + self.think = CTF_Flag_Think; + self.nextthink = time; + } + else if (self.flag_state == FLAG_STATE_DROPPED) + { + self.nextthink = time + 30; + self.think = CTF_Flag_SendToBase; + } +}; + +void() CTF_Flag_Drop = +{ + local vector deviance; + local entity oself; + + if (!self.flag_ent) + return; + + bprint(self.netname); + bprint(" has dropped the "); + bprint(CTF_TeamString(self.flag_ent.team)); + bprint(" flag!\n"); + + // throw it out in the direction of the owners velocity, plus a bit random + deviance_x = random() * 20; + deviance_y = random() * 20; + deviance_z = 200; + + self.flag_ent.velocity = (self.flag_ent.velocity * 0.5) + deviance; + + oself = self; + self = self.flag_ent; + CTF_Flag_SetState(FLAG_STATE_DROPPED); + self = oself; + + self.flag_ent.think = CTF_Flag_Think; + self.flag_ent.nextthink = time; + + self.flag_ent = world; +}; + +// flag has been touched! +void() CTF_Flag_Touch = +{ + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + // not on my team + if (other.team != self.team) + { + bprint(other.netname); + bprint(" has picked up the "); + bprint(CTF_TeamString(self.team)); + bprint(" flag!\n"); + + self.owner = other; + other.flag_ent = self; + + CTF_Flag_SetState(FLAG_STATE_CARRIED); + + self.think = CTF_Flag_Think; + self.nextthink = time; + } + else + { + // on my team + // dropped, return to base + if (self.flag_state == FLAG_STATE_DROPPED) + { + bprint(other.netname); + bprint(" returned the "); + bprint(CTF_TeamString(other.team)); + bprint(" flag\n"); + + CTF_Flag_SendToBase(); + } + else if (self.flag_state == FLAG_STATE_BASE) + { + if (other.flag_ent) + CTF_Flag_Capture(); // OH YEAH! + } + } +}; + +void() CTF_Flag_Finalise = +{ + self.movetype = MOVETYPE_TOSS; + + CTF_Flag_SetState(FLAG_STATE_BASE); +}; + +void(float whichteam) CTF_Flag_Init = +{ + local string m, s; + local vector v; + local entity flag; + + flag = spawn(); + + flag.touch = CTF_Flag_Touch; + flag.flags = FL_ITEM; + flag.team = whichteam; + + if (whichteam == TEAM_BLUE) + { + m = "progs/b_s_key.mdl"; + s = "misc/basekey.wav"; + flag.items = IT_KEY1; + } + else + { + m = "progs/b_g_key.mdl"; + s = "misc/basekey.wav"; + flag.items = IT_KEY2; + } + + precache_model (m); + setmodel (flag, m); + + precache_sound (s); + flag.noise = s; + + v = self.origin + '0 0 4'; + + flag.flag_base = v; + flag.owner = world; + flag.team = whichteam; + + setsize (flag, VEC_HULL_MIN, VEC_HULL_MAX); + setorigin(flag, v); + + flag.nextthink = time + 0.2; + flag.think = CTF_Flag_Finalise; +}; + +void() info_flag_blue = +{ + CTF_Flag_Init(TEAM_BLUE); +}; + +void() info_flag_red = +{ + CTF_Flag_Init(TEAM_RED); +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/defs.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/defs.qc new file mode 100755 index 00000000..df662356 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/defs.qc @@ -0,0 +1,852 @@ +#ifdef FTE +// use real int if using FTE type progs +#define INTEGER int +#else +#define INTEGER float +#endif + +#define BOOL INTEGER + + +#define FALSE ((BOOL)0) +#define TRUE ((BOOL)1) + +/* +============================================================================== + + SOURCE FOR GLOBALVARS_T C STRUCTURE + +============================================================================== +*/ + +// +// system globals +// +entity self; +entity other; +entity world; +float time; +float frametime; + +#ifndef NETQUAKE +entity newmis; // if this is set, the entity that just + // run created a new missile that should + // be simulated immediately +#endif + +float force_retouch; // force all entities to touch triggers + // next frame. this is needed because + // non-moving things don't normally scan + // for triggers, and when a trigger is + // created (like a teleport trigger), it + // needs to catch everything. + // decremented each frame, so set to 2 + // to guarantee everything is touched +string mapname; + +#ifdef NETQUAKE +float deathmatch; +float coop; +float teamplay; +#endif + +float serverflags; // propagated from level to level, used to + // keep track of completed episodes + +float total_secrets; +float total_monsters; + +float found_secrets; // number of secrets found +float killed_monsters; // number of monsters killed + + +// spawnparms are used to encode information about clients across server +// level changes +float parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16; + +// +// global variables set by built in functions +// +vector v_forward, v_up, v_right; // set by makevectors() + +// set by traceline / tracebox +float trace_allsolid; +float trace_startsolid; +float trace_fraction; +vector trace_endpos; +vector trace_plane_normal; +float trace_plane_dist; +entity trace_ent; +float trace_inopen; +float trace_inwater; + +entity msg_entity; // destination of single entity writes + +// +// required prog functions +// +void() main; // only for testing + +void() StartFrame; + +void() PlayerPreThink; +void() PlayerPostThink; + +void() ClientKill; +void() ClientConnect; +void() PutClientInServer; // call after setting the parm1... parms +void() ClientDisconnect; + +void() SetNewParms; // called when a client first connects to + // a server. sets parms so they can be + // saved off for restarts + +void() SetChangeParms; // call to set parms for self so they can + // be saved for a level transition + + +//================================================ +void end_sys_globals; // flag for structure dumping +//================================================ + +/* +============================================================================== + + SOURCE FOR ENTVARS_T C STRUCTURE + +============================================================================== +*/ + +// +// system fields (*** = do not set in prog code, maintained by C code) +// +.float modelindex; // *** model index in the precached list +.vector absmin, absmax; // *** origin + mins / maxs + +.float ltime; // local time for entity +#ifndef NETQUAKE +.float lastruntime; // *** to allow entities to run out of sequence +#endif + +.float movetype; +.float solid; + +.vector origin; // *** +.vector oldorigin; // *** +.vector velocity; +.vector angles; +.vector avelocity; + +#ifdef NETQUAKE +.vector punchangle; +#endif + +.string classname; // spawn function +.string model; +.float frame; +.float skin; +.float effects; + +.vector mins, maxs; // bounding box extents reletive to origin +.vector size; // maxs - mins + +.void() touch; +.void() use; +.void() think; +.void() blocked; // for doors or plats, called when can't push other + +.float nextthink; +.entity groundentity; + +// stats +.float health; +.float frags; +.float weapon; // one of the IT_SHOTGUN, etc flags +.string weaponmodel; +.float weaponframe; +.float currentammo; +.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells; + +.float items; // bit flags + +.float takedamage; +.entity chain; +.float deadflag; + +.vector view_ofs; // add to origin to get eye point + + +.float button0; // fire +.float button1; // use +.float button2; // jump + +.float impulse; // weapon changes + +.float fixangle; +.vector v_angle; // view / targeting angle for players + +#ifdef NETQUAKE +.float idealpitch; +#endif + +.string netname; + +.entity enemy; + +.float flags; + +.float colormap; +.float team; + +.float max_health; // players maximum health is stored here + +.float teleport_time; // don't back up + +.float armortype; // save this fraction of incoming damage +.float armorvalue; + +.float waterlevel; // 0 = not in, 1 = feet, 2 = wast, 3 = eyes +.float watertype; // a contents value + +.float ideal_yaw; +.float yaw_speed; + +.entity aiment; + +.entity goalentity; // a movetarget or an enemy + +.float spawnflags; + +.string target; +.string targetname; + +// damage is accumulated through a frame. and sent as one single +// message, so the super shotgun doesn't generate huge messages +.float dmg_take; +.float dmg_save; +.entity dmg_inflictor; + +.entity owner; // who launched a missile +.vector movedir; // mostly for doors, but also used for waterjump + +.string message; // trigger messages + +.float sounds; // either a cd track number or sound number + +.string noise, noise1, noise2, noise3; // contains names of wavs to play + +//================================================ +void end_sys_fields; // flag for structure dumping +//================================================ + +/* +============================================================================== + + VARS NOT REFERENCED BY C CODE + +============================================================================== +*/ + + +// +// constants +// + +// edict.flags +#define FL_FLY 1 +#define FL_SWIM 2 +#define FL_CLIENT 8 // set for all client edicts +#define FL_INWATER 16 // for enter / leave water splash +#define FL_MONSTER 32 +#define FL_GODMODE 64 // player cheat +#define FL_NOTARGET 128 // player cheat +#define FL_ITEM 256 // extra wide size for bonus items +#define FL_ONGROUND 512 // standing on something +#define FL_PARTIALGROUND 1024 // not all corners are valid +#define FL_WATERJUMP 2048 // player jumping out of water +#define FL_JUMPRELEASED 4096 // for jump debouncing + +// edict.movetype values +#define MOVETYPE_NONE 0 // never moves +#define MOVETYPE_WALK 3 // players only +#define MOVETYPE_STEP 4 // discrete, not real time unless fall +#define MOVETYPE_FLY 5 +#define MOVETYPE_TOSS 6 +#define MOVETYPE_PUSH 7 // no clip to world, push and crush +#define MOVETYPE_NOCLIP 8 +#define MOVETYPE_FLYMISSILE 9 // fly with extra size against monsters +#define MOVETYPE_BOUNCE 10 + +// edict.solid values +#define SOLID_NOT 0 // no interaction with other objects +#define SOLID_TRIGGER 1 // touch on edge, but not blocking +#define SOLID_BBOX 2 // touch on edge, block +#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground +#define SOLID_BSP 4 // bsp clip, touch on edge, block + + +// deadflag values +#define DEAD_NO 0 +#define DEAD_DYING 1 +#define DEAD_DEAD 2 +#define DEAD_RESPAWNABLE 3 + +// takedamage values +#define DAMAGE_NO 0 +#define DAMAGE_YES 1 +#define DAMAGE_AIM 2 + +// items +float IT_AXE = 4096; +float IT_SHOTGUN = 1; +float IT_SUPER_SHOTGUN = 2; +float IT_NAILGUN = 4; +float IT_SUPER_NAILGUN = 8; +float IT_GRENADE_LAUNCHER = 16; +float IT_ROCKET_LAUNCHER = 32; +float IT_LIGHTNING = 64; +float IT_EXTRA_WEAPON = 128; +float IT_EXTRA_WEAPON2 = 8388608; // solitude +float IT_SKULL = 16777216; // solitude + +float IT_SHELLS = 256; +float IT_NAILS = 512; +float IT_ROCKETS = 1024; +float IT_CELLS = 2048; + +float IT_ARMOR1 = 8192; +float IT_ARMOR2 = 16384; +float IT_ARMOR3 = 32768; +float IT_SUPERHEALTH = 65536; + +float IT_KEY1 = 131072; +float IT_KEY2 = 262144; + +float IT_INVISIBILITY = 524288; +float IT_INVULNERABILITY = 1048576; +float IT_SUIT = 2097152; +float IT_QUAD = 4194304; + +// point content values + +float CONTENT_EMPTY = -1; +float CONTENT_SOLID = -2; +float CONTENT_WATER = -3; +float CONTENT_SLIME = -4; +float CONTENT_LAVA = -5; +float CONTENT_SKY = -6; + +vector VEC_ORIGIN = '0 0 0'; +vector VEC_HULL_MIN = '-16 -16 -24'; +vector VEC_HULL_MAX = '16 16 32'; + +vector VEC_HULL2_MIN = '-32 -32 -24'; +vector VEC_HULL2_MAX = '32 32 64'; + +// protocol bytes +float SVC_TEMPENTITY = 23; +float SVC_KILLEDMONSTER = 27; +float SVC_FOUNDSECRET = 28; +float SVC_INTERMISSION = 30; +float SVC_FINALE = 31; +float SVC_CDTRACK = 32; +float SVC_SELLSCREEN = 33; +float SVC_SMALLKICK = 34; +float SVC_BIGKICK = 35; +float SVC_MUZZLEFLASH = 39; + +float TE_SPIKE = 0; +float TE_SUPERSPIKE = 1; +float TE_GUNSHOT = 2; +float TE_EXPLOSION = 3; +float TE_TAREXPLOSION = 4; +float TE_LIGHTNING1 = 5; +float TE_LIGHTNING2 = 6; +float TE_WIZSPIKE = 7; +float TE_KNIGHTSPIKE = 8; +float TE_LIGHTNING3 = 9; +float TE_LAVASPLASH = 10; +float TE_TELEPORT = 11; +float TE_BLOOD = 12; +float TE_LIGHTNINGBLOOD = 13; + +// sound channels +// channel 0 never willingly overrides +// other channels (1-7) allways override a playing sound on that channel +#define CHAN_AUTO 0 +#define CHAN_WEAPON 1 +#define CHAN_VOICE 2 +#define CHAN_ITEM 3 +#define CHAN_BODY 4 +// chan_no_phs_add is defined in engine.qc + +#define ATTN_NONE 0.0 // no volume fall off due to range +#define ATTN_NORM 1.0 // small volume fall off (1000 range) +#define ATTN_IDLE 2.0 // medium volume fall off (500 range) +#define ATTN_STATIC 3.0 // large volume fall off (333 range) + +// entity effects + +//float EF_BRIGHTFIELD = 1; +float EF_MUZZLEFLASH = 2; +float EF_BRIGHTLIGHT = 4; +float EF_DIMLIGHT = 8; +float EF_FLAG1 = 16; +float EF_FLAG2 = 32; +// GLQuakeWorld Stuff +// float EF_BLUE = 64; // Blue Globe effect for Quad +// float EF_RED = 128; // Red Globe effect for Pentagram + +// messages +#define MSG_BROADCAST 0 // unreliable to all +#define MSG_ONE 1 // reliable to one (msg_entity) +#define MSG_ALL 2 // reliable to all +#define MSG_INIT 3 // write to the init string +#define MSG_MULTICAST 4 // for multicast() call + +// message levels +#define PRINT_LOW 0 +#define PRINT_MEDIUM 1 +#define PRINT_HIGH 2 +#define PRINT_CHAT 3 + +// multicast sets +#define MULTICAST_ALL 0 // every client +#define MULTICAST_PHS 1 // within hearing +#define MULTICAST_PVS 2 // within sight +#define MULTICAST_ALL_R 3 // every client, reliable +#define MULTICAST_PHS_R 4 // within hearing, reliable +#define MULTICAST_PVS_R 5 // within sight, reliable + + + + +//================================================ + +// +// globals +// +// float movedist; + +string string_null; // null string, nothing should be held here + +entity activator; // the entity that activated a trigger or brush + +entity damage_attacker; // set by T_Damage +entity damage_inflictor; // set by T_Damage +INTEGER damage_mod; // set by T_Damage + +float framecount; + +// +// cvars checked each frame +// +float timelimit; +float fraglimit; +float rj; + +#ifndef NETQUAKE +// these variables are not a part of QW's system fields +float deathmatch; +float swat; +float coop; +float teamplay; +#endif + +float skill; + +// coop spawning globals +entity lastspawn; +float spotspawn; + +entity shub; // boss entity + +//================================================ + +#define WT_MEDIEVAL 0 +#define WT_METAL 1 +#define WT_BASE 2 + +//================================================ + +.string killtarget; // used by anything using SUB_UseTargets (items/triggers/etc) + +.void(entity attacker, float damage) th_pain; // used by secret doors, monsters, players +.void() th_die; // used by anything damagable (doors/buttons/players/monsters/explobox/triggermultiple) + +.float speed; // used with door/plats/fireball spawner, inherited +.string map; // used with world/trigger_changelevel, inherited + +// used with monsters/players +.INTEGER ammo_shells_real; // real shells count +.INTEGER ammo_nails_real; // real nails count +.INTEGER ammo_rockets_real; // real rockets count +.INTEGER ammo_cells_real; // real cells count + +// Zoid Additions +noref .float maxspeed; // Used to set Maxspeed on a player +noref .float gravity; // Gravity Multiplier (0 to 1.0) + +.float attack_finished; // used with lots of stuff... +.float pain_finished; // used with monsters/players + +.float invincible_finished; // only used for players but object check needed for T_Damage +.float super_damage_finished; // only used for players but object check needed for T_Damage + +// +// misc +// +.float cnt; // misc flag used by trains/dropped pent and quad/monsters + +// intermission +float intermission_running; +float intermission_exittime; + +#ifdef NETQUAKE +entity newmis; +#endif + +// extensions +.float alpha; // DP_ENT_ALPHA + +// enums +// ai ranges +enum +{ + RANGE_MELEE, + RANGE_NEAR, + RANGE_MID, + RANGE_FAR +}; + +// monster attack states +enum +{ + AS_NONE, + AS_STRAIGHT, + AS_SLIDING, + AS_MELEE, + AS_MISSILE +}; + +// door/plat states +enum { + STATE_TOP, + STATE_BOTTOM, + STATE_UP, + STATE_DOWN +}; + +// heal defines +enumflags { + H_ROTTEN, + H_MEGA +}; + +// weaponstate defines +enum { + WS_IDLE, + WS_FIRING1, + WS_FIRING2 // used with nailgun +}; + +// ammo type defines +enum { + AT_NONE, + AT_SHELLS, + AT_NAILS, + AT_ROCKETS, + AT_CELLS +}; + +// unions +//floats (includes vectors) +.union { + struct { // fields used with world object + float worldtype; // world type, 0=medieval 1=metal 2=base + }; + struct { // fields used with triggers/doors/plats + float delay; // time from activation to firing + float wait; // time from firing to restarting + float t_length; // override length to move sideways + float t_width; // override length to move upwards/downwards + vector finaldest; // used with SUB_CalcMove + vector finalangle; // used with SUB_CalcMove + float count; // for counting triggers + float dmg; // damage done by door/train/trigger hurt + vector mangle; // initial angle (doors/teleporter/intermission) + float lip; // position adjustment (func_door/func_button) + float state; // object state (doors/buttons/plats) + vector pos1; // top position (doors/buttons/plats) + vector pos2; // bottom position (doors/buttons/plats) + float height; // height (plats/trigger_monsterjump) + vector dest1; // passed to CalcMove (doors) + vector dest2; // passed to CalcMove (doors) + }; + struct { // fields used with players + float weaponframe_time; // weapon frame advance time + float suicide_time; // time to allow suicide after spawn + float healdecay; // time when health will decay + float show_hostile; // used to alert monsters + float lightning_sound; // used for lightning sound playback + float fly_sound; // used with trigger_push and maintaining wind sound + float invincible_time; // pentagram state + float invincible_sound; // pentagram sound playback + float invisible_time; // ring state + float invisible_sound; // ring sound playback + float invisible_finished; // ring current duration + float super_time; // quad state + float super_sound; // quad sound playback + float rad_time; // rad suit state + float radsuit_finished; // rad suit current duration + float dmgtime; // time slime/lava will damage + float swim_flag; // swim sound playback + float air_finished; // when time > air_finished, start drowning + float waterdmg; // damage water will deal when drowning + float jump_flag; // last z velocity used for falling damage + }; + struct { // fields used with items + float healamount; // amount healed with health item + //float ammo_count; // ammo amount + }; + struct { // fields used with generic projectiles + float damage_direct; // damage done with a direct hit + float damage_exp; // damage done from radius damage + float radius_exp; // radius of radius damage + float expire_time; // time when projectile dies + float proj_think_time; // interval between thinks + }; + struct { // fields used with lights + float light_lev; // not used by game, but parsed by light util + float style; // lightstyle to use for light + }; + struct { // fields used with monsters + float search_time; // search time intervals + float attack_state; // current AI attack state + float pausetime; // time to pause for monsters + float hknightattack; // hell knight attack pattern + float lefty; // ai slide move + float wizardidle; // wizard idle sound timer + float inpain; // zombie in pain + }; + // fields used with ambient sounds? + /* + struct { + float waitmin; + float waitmax; + float distance; + float volume; + }; + */ +}; + +//integers +.union { + + struct { // fields used with players + INTEGER weaponstate; // firing state of current weapon + INTEGER walkframe; // used with walking animation + INTEGER ammo_type; // ammo type in use + }; + struct { // fields used with bubbles spawned from drowning + INTEGER bubble_count; // keeps track of the number of bubbles + INTEGER bubble_state; // associated with bubble progression + }; + struct { // fields used with items + INTEGER healtype; // type of health with health item + }; + struct { // fields used with generic projectiles + INTEGER mod_direct; // mod type for direct hit + INTEGER mod_exp; // mod type for radius damage + INTEGER proj_effect; // effect used with projectile + INTEGER voided; // projectile has been voided + }; +}; + +//functions +.union { + struct { // fields used with triggers/doors/plats + void() think1; // used with SUB_CalcMove + }; + struct { // fields used with generic projectiles + void() proj_think; // extra think function used with projectile + float() proj_touch; // extra touch function used with projectile + }; + struct { // fields used with monsters + void() th_stand; // standing animation + void() th_walk; // walking animation + void() th_run; // running animation + void() th_missile; // ranged animation + void() th_melee; // melee animation + }; +}; + + +//entities +.union { + struct { // fields used with triggers/doors/plats + entity trigger_field; // used with linking (doors) + }; + + struct { // fields used with monsters + entity oldenemy; // old enemy + entity movetarget; // target entity to move to + }; +}; + +//strings +.union { + struct { // fields used with world object + string wad; //mute it + }; + struct { // fields used with triggers/doors/plats + string noise4; // extra sound (doors) + }; + struct { // fields used with items + string mdl; // model used with SUB_regen + }; +}; + +//mute those warnings (unions/structs do not support noref mid-struct, but a later def will propogate the noref flag) +noref .string wad; +noref .float light_lev; + +//=========================================================================== + + +// +// builtin functions +// + +void(vector ang) makevectors = #1; // sets v_forward, etc globals +void(entity e, vector o) setorigin = #2; +void(entity e, string m) setmodel = #3; // set movetype and solid first +void(entity e, vector min, vector max) setsize = #4; +// #5 was removed +// void() break = #6; +float() random = #7; // returns 0 - 1 +//void(entity e, float chan, string samp, float vol, float atten) sound = #8; //FBX +vector(vector v) normalize = #9; +void(string e) error = #10; +void(string e) objerror = #11; +float(vector v) vlen = #12; +float(vector v) vectoyaw = #13; +entity() spawn = #14; +void(entity e) remove = #15; + +// sets trace_* globals +// nomonsters can be: +// An entity will also be ignored for testing if forent == test, +// forent->owner == test, or test->owner == forent +// a forent of world is ignored +void(vector v1, vector v2, float nomonsters, entity forent) traceline = #16; + +entity() checkclient = #17; // returns a client to look for +entity(entity start, .string fld, string match) find = #18; +string(string s) precache_sound = #19; +string(string s) precache_model = #20; +//void(entity client, string s)stuffcmd = #21; // FBX +entity(vector org, float rad) findradius = #22; +// bprint moved to engine.qc +// sprint moved to engine.qc +void(string s) dprint = #25; +string(float f) ftos = #26; +string(vector v) vtos = #27; +void() coredump = #28; // prints all edicts +void() traceon = #29; // turns statment trace on +void() traceoff = #30; +void(entity e) eprint = #31; // prints an entire edict +float(float yaw, float dist) walkmove = #32; // returns TRUE or FALSE +// #33 was removed +float() droptofloor= #34; // TRUE if landed on floor +void(float style, string value) lightstyle = #35; +float(float v) rint = #36; // round to nearest int +float(float v) floor = #37; // largest integer <= v +float(float v) ceil = #38; // smallest integer >= v +// #39 was removed +float(entity e) checkbottom = #40; // true if self is on ground +float(vector v) pointcontents = #41; // returns a CONTENT_* +// #42 was removed +float(float f) fabs = #43; +//vector(entity e, float speed) aim = #44; // returns the shooting vector // FBX +// cvar moved to engine.qc +void(string s) localcmd = #46; // put string into local que +entity(entity e) nextent = #47; // for looping through all ents +// #48 was removed +void() ChangeYaw = #49; // turn towards self.ideal_yaw + // at self.yaw_speed +// #50 was removed +vector(vector v) vectoangles = #51; + +// +// direct client message generation +// +/* +void(float to, float f) WriteByte = #52; +void(float to, float f) WriteChar = #53; +void(float to, float f) WriteShort = #54; +void(float to, float f) WriteLong = #55; +void(float to, float f) WriteCoord = #56; +void(float to, float f) WriteAngle = #57; +void(float to, string s) WriteString = #58; +void(float to, entity s) WriteEntity = #59; +// FBX'd +*/ +// several removed + +void(float step) movetogoal = #67; + +string(string s) precache_file = #68; // no effect except for -copy +void(entity e) makestatic = #69; +void(string s) changelevel = #70; + +//#71 was removed + +void(string var, string val) cvar_set = #72; // sets cvar.value + +//void(entity client, string s) centerprint = #73; // sprint, but in middle // FBX + +void(vector pos, string samp, float vol, float atten) ambientsound = #74; + +string(string s) precache_model2 = #75; // registered version only +string(string s) precache_sound2 = #76; // registered version only +string(string s) precache_file2 = #77; // registered version only + +//void(entity e) setspawnparms = #78; // set parm1... to the // FBX + // values at level start + // for coop respawn +// logfrag moved to engine.qc +// infokey moved to engine.qc +// stof moved to engine.qc + +//============================================================================ + +// +// subs.qc +// +void(vector tdest, float tspeed, void() func) SUB_CalcMove; +void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt; +void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove; +void() SUB_CalcMoveDone; +void() SUB_CalcAngleMoveDone; +void() SUB_Null; +void() SUB_UseTargets; +void() SUB_Remove; + +// +// combat.qc +// +void(entity targ, entity inflictor, entity attacker, float damage, INTEGER mod) T_Damage; + +float (entity e, float healamount, float ignore) T_Heal; // health function + +BOOL(entity targ, entity inflictor) CanDamage; +.float crouch; +float score_lastTic; +.float alpha; +.float nade_lives; // The number of Grenades a player has. +.float plasma_lives; +.float kill_time; +.float kill_amount; //For reseting kill medals +.float groundwep; //For weapon pickup Icons +.float reset; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/doors.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/doors.qc new file mode 100755 index 00000000..1d76f425 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/doors.qc @@ -0,0 +1,770 @@ + +float DOOR_START_OPEN = 1; +float DOOR_DONT_LINK = 4; +float DOOR_GOLD_KEY = 8; +float DOOR_SILVER_KEY = 16; +float DOOR_TOGGLE = 32; + +/* + +Doors are similar to buttons, but can spawn a fat trigger field around them +to open without a touch, and they link together to form simultanious +double/quad doors. + +Door.owner is the master door. If there is only one door, it points to itself. +If multiple doors, all will point to a single one. + +Door.enemy chains from the master door through all doors linked in the chain. + +*/ + +/* +============================================================================= + +THINK FUNCTIONS + +============================================================================= +*/ + +void() door_go_down; +void() door_go_up; + +void() door_blocked = +{ + T_Damage (other, self, self.goalentity, self.dmg, MOD_SQUISH); + +// if a door has a negative wait, it would never come back if blocked, +// so let it just squash the object to death real fast + if (self.wait >= 0) + { + if (self.state == STATE_DOWN) + door_go_up (); + else + door_go_down (); + } +}; + + +void() door_hit_top = +{ + sound (self, chan_no_phs_add|CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_TOP; + if (self.spawnflags & DOOR_TOGGLE) + return; // don't come down automatically + self.think = door_go_down; + self.nextthink = self.ltime + self.wait; +}; + +void() door_hit_bottom = +{ + sound (self, chan_no_phs_add|CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_BOTTOM; +}; + +void() door_go_down = +{ + sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + if (self.max_health) + { + self.takedamage = DAMAGE_YES; + self.health = self.max_health; + } + + self.state = STATE_DOWN; + SUB_CalcMove (self.pos1, self.speed, door_hit_bottom); +}; + +void() door_go_up = +{ + if (self.state == STATE_UP) + return; // allready going up + + if (self.state == STATE_TOP) + { // reset top wait time + self.nextthink = self.ltime + self.wait; + return; + } + + sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + self.state = STATE_UP; + SUB_CalcMove (self.pos2, self.speed, door_hit_top); + + SUB_UseTargets(); +}; + + +/* +============================================================================= + +ACTIVATION FUNCTIONS + +============================================================================= +*/ + +void() door_fire = +{ + local entity oself; + local entity starte; + + if (self.owner != self) + objerror ("door_fire: self.owner != self"); + +// play use key sound + + if (self.items) + sound (self, CHAN_ITEM, self.noise4, 1, ATTN_NORM); + + self.message = string_null; // no more message + oself = self; + + if (self.spawnflags & DOOR_TOGGLE) + { + if (self.state == STATE_UP || self.state == STATE_TOP) + { + starte = self; + do + { + door_go_down (); + self = self.enemy; + } while ( (self != starte) && (self != world) ); + self = oself; + return; + } + } + +// trigger all paired doors + starte = self; + + do + { + self.goalentity = activator; // Who fired us + door_go_up (); + self = self.enemy; + } while ( (self != starte) && (self != world) ); + self = oself; +}; + + +void() door_use = +{ + local entity oself; + + self.message = ""; // door message are for touch only + self.owner.message = ""; + self.enemy.message = ""; + + oself = self; + self = self.owner; + door_fire (); + self = oself; +}; + + +void() door_trigger_touch = +{ + if (other.health <= 0) + return; + + if (time < self.attack_finished) + return; + self.attack_finished = time + 1; + + activator = other; + + self = self.owner; + door_use (); +}; + + +void() door_killed = +{ + local entity oself; + + oself = self; + self = self.owner; + self.health = self.max_health; + self.takedamage = DAMAGE_NO; // wil be reset upon return + door_use (); + self = oself; +}; + + +/* +================ +door_touch + +Prints messages and opens key doors +================ +*/ +void() door_touch = +{ + if (other.classname != "player") + return; + if (self.owner.attack_finished > time) + return; + + self.owner.attack_finished = time + 2; + + if (self.owner.message != "") + { + centerprint (other, self.owner.message); + sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM); + } + +// key door stuff + if (!self.items) + return; + +// FIXME: blink key on player's status bar + if ( (self.items & other.items) != self.items ) + { + if (self.owner.items == IT_KEY1) + { + switch (world.worldtype) + { + case WT_MEDIEVAL: + centerprint (other, "You need the silver key"); + break; + case WT_METAL: + centerprint (other, "You need the silver runekey"); + break; + case WT_BASE: + centerprint (other, "You need the silver keycard"); + break; + } + } + else + { + switch (world.worldtype) + { + case WT_MEDIEVAL: + centerprint (other, "You need the gold key"); + break; + case WT_METAL: + centerprint (other, "You need the gold runekey"); + break; + case WT_BASE: + centerprint (other, "You need the gold keycard"); + break; + } + } + + sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + return; + } + + other.items = other.items - self.items; + self.touch = SUB_Null; + if (self.enemy) + self.enemy.touch = SUB_Null; // get paired door + door_use (); +}; + +/* +============================================================================= + +SPAWNING FUNCTIONS + +============================================================================= +*/ + + +entity(vector fmins, vector fmaxs) spawn_field = +{ + local entity trigger; + local vector t1, t2; + + trigger = spawn(); + trigger.movetype = MOVETYPE_NONE; + trigger.solid = SOLID_TRIGGER; + trigger.owner = self; + trigger.touch = door_trigger_touch; + + t1 = fmins; + t2 = fmaxs; + setsize (trigger, t1 - '60 60 8', t2 + '60 60 8'); + return (trigger); +}; + + +BOOL (entity e1, entity e2) EntitiesTouching = +{ + if (e1.mins_x > e2.maxs_x) + return FALSE; + if (e1.mins_y > e2.maxs_y) + return FALSE; + if (e1.mins_z > e2.maxs_z) + return FALSE; + if (e1.maxs_x < e2.mins_x) + return FALSE; + if (e1.maxs_y < e2.mins_y) + return FALSE; + if (e1.maxs_z < e2.mins_z) + return FALSE; + return TRUE; +}; + + +/* +============= +LinkDoors + + +============= +*/ +void() LinkDoors = +{ + local entity t, starte; + local vector cmins, cmaxs; + + if (self.enemy) + return; // already linked by another door + if (self.spawnflags & 4) + { + self.owner = self.enemy = self; + return; // don't want to link this door + } + + cmins = self.mins; + cmaxs = self.maxs; + + starte = self; + t = self; + + do + { + self.owner = starte; // master door + + if (self.health) + starte.health = self.health; + if (self.targetname) + starte.targetname = self.targetname; + if (self.message != "") + starte.message = self.message; + + t = find (t, classname, self.classname); + if (!t) + { + self.enemy = starte; // make the chain a loop + + // shootable, fired, or key doors just needed the owner/enemy links, + // they don't spawn a field + + self = self.owner; + + if (self.health) + return; + if (self.targetname) + return; + if (self.items) + return; + + self.owner.trigger_field = spawn_field(cmins, cmaxs); + + return; + } + + if (EntitiesTouching(self,t)) + { + if (t.enemy) + objerror ("cross connected doors"); + + self.enemy = t; + self = t; + + if (t.mins_x < cmins_x) + cmins_x = t.mins_x; + if (t.mins_y < cmins_y) + cmins_y = t.mins_y; + if (t.mins_z < cmins_z) + cmins_z = t.mins_z; + if (t.maxs_x > cmaxs_x) + cmaxs_x = t.maxs_x; + if (t.maxs_y > cmaxs_y) + cmaxs_y = t.maxs_y; + if (t.maxs_z > cmaxs_z) + cmaxs_z = t.maxs_z; + } + } while (1 ); + +}; + + +/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE +if two doors touch, they are assumed to be connected and operate as a unit. + +TOGGLE causes the door to wait in both the start and end states for a trigger event. + +START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not usefull for touch or takedamage doors). + +Key doors are allways wait -1. + +"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet +"angle" determines the opening direction +"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door. +"health" if set, door must be shot open +"speed" movement speed (100 default) +"wait" wait before returning (3 default, -1 = never return) +"lip" lip remaining at end of move (8 default) +"dmg" damage to inflict when blocked (2 default) +"sounds" +0) no sound +1) stone +2) base +3) stone chain +4) screechy metal +*/ + +void() func_door = +{ + switch (world.worldtype) + { + case WT_MEDIEVAL: + precache_sound ("doors/medtry.wav"); + precache_sound ("doors/meduse.wav"); + self.noise3 = "doors/medtry.wav"; + self.noise4 = "doors/meduse.wav"; + break; + case WT_METAL: + precache_sound ("doors/runetry.wav"); + precache_sound ("doors/runeuse.wav"); + self.noise3 = "doors/runetry.wav"; + self.noise4 = "doors/runeuse.wav"; + break; + case WT_BASE: + precache_sound ("doors/basetry.wav"); + precache_sound ("doors/baseuse.wav"); + self.noise3 = "doors/basetry.wav"; + self.noise4 = "doors/baseuse.wav"; + break; + default: + dprint ("no worldtype set!\n"); + } + + switch (self.sounds) + { + case 0: + precache_sound ("misc/null.wav"); + precache_sound ("misc/null.wav"); + self.noise1 = "misc/null.wav"; + self.noise2 = "misc/null.wav"; + break; + case 1: + precache_sound ("doors/drclos4.wav"); + precache_sound ("doors/doormv1.wav"); + self.noise1 = "doors/drclos4.wav"; + self.noise2 = "doors/doormv1.wav"; + break; + case 2: + precache_sound ("doors/hydro1.wav"); + precache_sound ("doors/hydro2.wav"); + self.noise2 = "doors/hydro1.wav"; + self.noise1 = "doors/hydro2.wav"; + break; + case 3: + precache_sound ("doors/stndr1.wav"); + precache_sound ("doors/stndr2.wav"); + self.noise2 = "doors/stndr1.wav"; + self.noise1 = "doors/stndr2.wav"; + break; + case 4: + precache_sound ("doors/ddoor1.wav"); + precache_sound ("doors/ddoor2.wav"); + self.noise1 = "doors/ddoor2.wav"; + self.noise2 = "doors/ddoor1.wav"; + break; + } + + SetMovedir (); + + self.max_health = self.health; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + setorigin (self, self.origin); + setmodel (self, self.model); + self.classname = "door"; + + self.blocked = door_blocked; + self.use = door_use; + + if (self.spawnflags & DOOR_SILVER_KEY) + self.items = IT_KEY1; + if (self.spawnflags & DOOR_GOLD_KEY) + self.items = IT_KEY2; + + if (!self.speed) + self.speed = 100; + if (!self.wait) + self.wait = 3; + if (!self.lip) + self.lip = 8; + if (!self.dmg) + self.dmg = 2; + + self.pos1 = self.origin; + self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip); + +// DOOR_START_OPEN is to allow an entity to be lighted in the closed position +// but spawn in the open position + if (self.spawnflags & DOOR_START_OPEN) + { + setorigin (self, self.pos2); + self.pos2 = self.pos1; + self.pos1 = self.origin; + } + + self.state = STATE_BOTTOM; + + if (self.health) + { + self.takedamage = DAMAGE_YES; + self.th_die = door_killed; + } + + if (self.items) + self.wait = -1; + + self.touch = door_touch; + +// LinkDoors can't be done until all of the doors have been spawned, so +// the sizes can be detected properly. + self.think = LinkDoors; + self.nextthink = self.ltime + 0.1; +}; + +/* +============================================================================= + +SECRET DOORS + +============================================================================= +*/ + +void() fd_secret_move1; +void() fd_secret_move2; +void() fd_secret_move3; +void() fd_secret_move4; +void() fd_secret_move5; +void() fd_secret_move6; +void() fd_secret_done; + +float SECRET_OPEN_ONCE = 1; // stays open +float SECRET_1ST_LEFT = 2; // 1st move is left of arrow +float SECRET_1ST_DOWN = 4; // 1st move is down from arrow +float SECRET_NO_SHOOT = 8; // only opened by trigger +float SECRET_YES_SHOOT = 16; // shootable even if targeted + + +void () fd_secret_use = +{ + local float temp; + + self.health = 10000; + + // exit if still moving around... + if (self.origin != self.oldorigin) + return; + + self.message = string_null; // no more message + + SUB_UseTargets(); // fire all targets / killtargets + + if (!(self.spawnflags & SECRET_NO_SHOOT)) + { + self.th_pain = SUB_Null; + self.takedamage = DAMAGE_NO; + } + self.velocity = '0 0 0'; + + // Make a sound, wait a little... + + sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.nextthink = self.ltime + 0.1; + + temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1 + makevectors(self.mangle); + + if (!self.t_width) + { + if (self.spawnflags & SECRET_1ST_DOWN) + self.t_width = fabs(v_up * self.size); + else + self.t_width = fabs(v_right * self.size); + } + + if (!self.t_length) + self.t_length = fabs(v_forward * self.size); + + if (self.spawnflags & SECRET_1ST_DOWN) + self.dest1 = self.origin - v_up * self.t_width; + else + self.dest1 = self.origin + v_right * (self.t_width * temp); + + self.dest2 = self.dest1 + v_forward * self.t_length; + SUB_CalcMove(self.dest1, self.speed, fd_secret_move1); + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); +}; + +// Wait after first movement... +void () fd_secret_move1 = +{ + self.nextthink = self.ltime + 1.0; + self.think = fd_secret_move2; + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); +}; + +// Start moving sideways w/sound... +void () fd_secret_move2 = +{ + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + SUB_CalcMove(self.dest2, self.speed, fd_secret_move3); +}; + +// Wait here until time to go back... +void () fd_secret_move3 = +{ + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + if (!(self.spawnflags & SECRET_OPEN_ONCE)) + { + self.nextthink = self.ltime + self.wait; + self.think = fd_secret_move4; + } +}; + +// Move backward... +void () fd_secret_move4 = +{ + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + SUB_CalcMove(self.dest1, self.speed, fd_secret_move5); +}; + +// Wait 1 second... +void () fd_secret_move5 = +{ + self.nextthink = self.ltime + 1.0; + self.think = fd_secret_move6; + sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); +}; + +void () fd_secret_move6 = +{ + sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); + SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done); +}; + +void () fd_secret_done = +{ + if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT) + { + self.health = 10000; + self.takedamage = DAMAGE_YES; + self.th_pain = fd_secret_use; + self.th_die = fd_secret_use; + } + sound(self, chan_no_phs_add|CHAN_VOICE, self.noise3, 1, ATTN_NORM); +}; + +void () secret_blocked = +{ + if (time < self.attack_finished) + return; + self.attack_finished = time + 0.5; + T_Damage (other, self, self, self.dmg, MOD_SQUISH); +}; + +/* +================ +secret_touch + +Prints messages +================ +*/ +void() secret_touch = +{ + if (other.classname != "player") + return; + if (self.attack_finished > time) + return; + + self.attack_finished = time + 2; + + if (self.message) + { + centerprint (other, self.message); + sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM); + } +}; + + +/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot +Basic secret door. Slides back, then to the side. Angle determines direction. +wait = # of seconds before coming back +1st_left = 1st move is left of arrow +1st_down = 1st move is down from arrow +always_shoot = even if targeted, keep shootable +t_width = override WIDTH to move back (or height if going down) +t_length = override LENGTH to move sideways +"dmg" damage to inflict when blocked (2 default) + +If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage. +"sounds" +1) medieval +2) metal +3) base +*/ + +void () func_door_secret = +{ + switch (self.sounds) + { + case 0: + case 3: + precache_sound ("doors/basesec1.wav"); + precache_sound ("doors/basesec2.wav"); + self.noise2 = "doors/basesec1.wav"; + self.noise1 = "doors/basesec2.wav"; + self.noise3 = "doors/basesec2.wav"; + break; + case 1: + precache_sound ("doors/latch2.wav"); + precache_sound ("doors/winch2.wav"); + precache_sound ("doors/drclos4.wav"); + self.noise1 = "doors/latch2.wav"; + self.noise2 = "doors/winch2.wav"; + self.noise3 = "doors/drclos4.wav"; + break; + case 2: + precache_sound ("doors/airdoor1.wav"); + precache_sound ("doors/airdoor2.wav"); + self.noise2 = "doors/airdoor1.wav"; + self.noise1 = "doors/airdoor2.wav"; + self.noise3 = "doors/airdoor2.wav"; + break; + } + + if (!self.dmg) + self.dmg = 2; + + // Magic formula... + self.mangle = self.angles; + self.angles = '0 0 0'; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + self.classname = "door"; + setmodel (self, self.model); + setorigin (self, self.origin); + + self.touch = secret_touch; + self.blocked = secret_blocked; + self.speed = 50; + self.use = fd_secret_use; + if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT) + { + self.health = 10000; + self.takedamage = DAMAGE_YES; + self.th_pain = fd_secret_use; + } + self.oldorigin = self.origin; + if (!self.wait) + self.wait = 5; // 5 seconds before closing +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/effects.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/effects.qc new file mode 100755 index 00000000..9c511eb8 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/effects.qc @@ -0,0 +1,708 @@ + +// Effects code (EFF) -- + +// TE effects/muzzleflash/messages + +// modular efs +var float ef_red = 0; // used for glow on pent item +var float ef_pent = EF_DIMLIGHT; // used for pent effect on player +var float ef_blue = 0; // used for glow on quad +var float ef_quad = EF_DIMLIGHT; // used for quad effect on player + +// base te write functions +void WriteVector (float msg, vector org) = +{ + WriteCoord (msg, org_x); + WriteCoord (msg, org_y); + WriteCoord (msg, org_z); +}; + +#ifdef NETQUAKE +void(vector org, float effect) _EFF_PointEffect = +{ + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, effect); + WriteVector (MSG_BROADCAST, org); +}; + +void(entity ent, vector org, vector org2, float effect) _EFF_BeamEffect = +{ + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, effect); + WriteEntity (MSG_BROADCAST, ent); + WriteVector (MSG_BROADCAST, org); + WriteVector (MSG_BROADCAST, org2); +}; + +void(vector org, float damage, float effect) _EFF_CountEffect = +{ + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, effect); + WriteByte (MSG_BROADCAST, damage); + WriteVector (MSG_BROADCAST, org); +}; + +#define EFF_PointEffect(a,b,c) _EFF_PointEffect(a,b) +#define EFF_BeamEffect(a,b,c,d,e) _EFF_BeamEffect(a,b,c,d) +#define EFF_CountEffect(a,b,c,d) _EFF_CountEffect(a,b,c) +#else +void(vector org, float effect, float mcast) EFF_PointEffect = +{ + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, effect); + WriteVector (MSG_MULTICAST, org); + multicast (org, mcast); +}; + +void(entity ent, vector org, vector org2, float effect, float mcast) EFF_BeamEffect = +{ + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, effect); + WriteEntity (MSG_MULTICAST, ent); + WriteVector (MSG_MULTICAST, org); + WriteVector (MSG_MULTICAST, org2); + multicast (org, mcast); +}; + +void(vector org, float damage, float effect, float mcast) EFF_CountEffect = +{ + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, effect); + WriteByte (MSG_MULTICAST, damage); + WriteVector (MSG_MULTICAST, org); + multicast (org, mcast); +}; +#endif + +/* +================ +SpawnBlood +================ +*/ +void(vector org, float damage) _SpawnBlood_TEBlood = +{ + te_blood(org, '0 0 0', damage*2); +}; + +void(vector org, float damage) _SpawnBlood = +{ +#ifdef NETQUAKE + particle (org, '0 0 0', 73, damage*2); +#else + EFF_CountEffect(org, damage, TE_BLOOD, MULTICAST_PVS); +#endif +}; +/* +void() NadeTouch = +{ +if (other.nade_lives > 4) +{ +sprint (other, "Can't pick up anymore grenades/n"); +return; +} +other.nade_lives = other.nade_lives + 1; +}; + +*/ +void() s_smokee6 = [5, SUB_Remove] {}; +void() s_smokee5 = [4, s_smokee6] {}; +void() s_smokee4 = [3, s_smokee5] {}; +void() s_smokee3 = [2, s_smokee4] {}; +void() s_smokee2 = [1, s_smokee3] {}; +void() s_smokee1 = [0, s_smokee2] {}; + +void() s_needle3 = [2, SUB_Remove] {}; +void() s_needle2 = [1, s_needle3] {}; +void() s_needle1 = [0, s_needle2] {}; + +void() s_plasma14 = [13, SUB_Remove] {}; +void() s_plasma13 = [12, s_plasma14] {}; +void() s_plasma12 = [11, s_plasma13] {}; +void() s_plasma11 = [10, s_plasma12] {}; +void() s_plasma10 = [9, s_plasma11] {}; +void() s_plasma9 = [8, s_plasma10] {}; +void() s_plasma8 = [7, s_plasma9] {}; +void() s_plasma7 = [6, s_plasma8] {}; +void() s_plasma6 = [5, s_plasma7] {}; +void() s_plasma5 = [4, s_plasma6] {}; +void() s_plasma4 = [3, s_plasma5] {}; +void() s_plasma3 = [2, s_plasma4] {}; +void() s_plasma2 = [1, s_plasma3] {}; +void() s_plasma1 = [0, s_plasma2] {}; + +void(vector org) createpinkdust = +{ + local entity s; + + + s = self; // save old self + + self = spawn(); + + self.movetype = MOVETYPE_NONE; + self.velocity = '0 0 0'; + self.touch = SUB_Null; + setmodel (self, "progs/needler_dust.spr"); + setorigin (self, org); + self.solid = SOLID_NOT; + s_needle1(); + self = s; // restore old self + +}; +void(vector org) createplasma = +{ + local entity s; + + + s = self; // save old self + + self = spawn(); + + self.movetype = MOVETYPE_NONE; + self.velocity = '0 0 0'; + self.touch = SUB_Null; + setmodel (self, "sprites/s_plasma4.spr"); + setorigin (self, org); + self.solid = SOLID_NOT; + s_plasma1(); + self = s; // restore old self + +}; + +void() s_plasmaa5 = [4, SUB_Remove] {}; +void() s_plasmaa4 = [3, s_plasmaa5] {createplasma(self.origin);}; +void() s_plasmaa3 = [2, s_plasmaa4] {}; +void() s_plasmaa2 = [1, s_plasmaa3] {}; +void() s_plasmaa1 = [0, s_plasmaa2] {}; + +void(vector org) plasmaexplo = +{ + local entity s; + local float r; + r = random(); + + + s = self; // save old self + + self = spawn(); + + self.movetype = MOVETYPE_NONE; + self.velocity = '0 0 0'; + self.touch = SUB_Null; + setmodel (self, "sprites/plasma3.spr"); + setorigin (self, org); + self.solid = SOLID_NOT; + + // So that debris comes out in random spurts over It coming out in the same number every time --Mexicouger + + s_plasmaa1 (); + + self = s; // restore old self +}; +void(vector org) pistolsmoke = +{ + local entity s; + + + s = self; // save old self + + self = spawn(); + + self.movetype = MOVETYPE_FLY; + + + self.velocity = v_forward; + self.velocity = (self.velocity * 80); + self.touch = SUB_Null; + setmodel (self, "sprites/s_smoke2.spr"); + setorigin (self, ((org + (v_forward * 15)) + '0 0 12')); + self.solid = SOLID_NOT; + s_smokee1(); + self = s; // restore old self +}; + +// #if defined(NETQUAKE) || defined(MONSTERS) + + +void() s_explode14 = [13, SUB_Remove] {}; +void() s_explode13 = [12, s_explode14] {}; +void() s_explode12 = [11, s_explode13] {}; +void() s_explode11 = [10, s_explode12] {}; +void() s_explode10 = [9, s_explode11] {}; +void() s_explode9 = [8, s_explode10] {}; +void() s_explode8 = [7, s_explode9] {}; +void() s_explode7 = [6, s_explode8] {}; +void() s_explode6 = [5, s_explode7] {}; +void() s_explode5 = [4, s_explode6] {}; +void() s_explode4 = [3, s_explode5] {}; +void() s_explode3 = [2, s_explode4] {}; +void() s_explode2 = [1, s_explode3] {}; +void() s_explode1 = [0, s_explode2] {}; + +void(vector org) CreateExplosion = +{ + local entity s; + local float r; + r = random(); + + + s = self; // save old self + + self = spawn(); + + self.movetype = MOVETYPE_NONE; + self.velocity = '0 0 0'; + self.touch = SUB_Null; + setmodel (self, "progs/s_explod.spr"); + setorigin (self, org); + self.solid = SOLID_NOT; + sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); + // So that debris comes out in random spurts over It coming out in the same number every time --Mexicouger + s_explode1 (); + + self = s; // restore old self +}; +// #endif + +void(vector org) _TE_explosion = +{ + EFF_PointEffect(org, TE_EXPLOSION, MULTICAST_PHS); +#ifdef NETQUAKE + CreateExplosion(org); +#endif +}; + +void(vector org) _TE_gunshot = +{ +#ifdef NETQUAKE + EFF_PointEffect(org, TE_GUNSHOT, MULTICAST_PVS); +#else + EFF_CountEffect(org, 3, TE_GUNSHOT, MULTICAST_PVS); +#endif +}; + +void(vector org) _TE_spike = +{ + EFF_PointEffect(org, TE_SPIKE, MULTICAST_PHS); +}; + +void(vector org) _TE_knightspike = +{ + EFF_PointEffect(org, TE_KNIGHTSPIKE, MULTICAST_PHS); +}; + +void(vector org) _TE_wizspike = +{ + EFF_PointEffect(org, TE_WIZSPIKE, MULTICAST_PHS); +}; + +void(vector org) _TE_superspike = +{ + EFF_PointEffect(org, TE_SUPERSPIKE, MULTICAST_PHS); +}; + +void(vector org) _TE_teleport = +{ + EFF_PointEffect(org, TE_TELEPORT, MULTICAST_PHS); +}; + +void(vector org) _TE_lavasplash = +{ + EFF_PointEffect(org, TE_LAVASPLASH, MULTICAST_PVS); +}; + +void(vector org) _TE_tarexplosion = +{ + EFF_PointEffect(org, TE_TAREXPLOSION, MULTICAST_PHS); +}; + +void(entity ent, vector start, vector end) _TE_lightning1 = +{ + EFF_BeamEffect (ent, start, end, TE_LIGHTNING1, MULTICAST_PHS); +}; + +void(entity ent, vector start, vector end) _TE_lightning2 = +{ + EFF_BeamEffect (ent, start, end, TE_LIGHTNING2, MULTICAST_PHS); +}; + +void(entity ent, vector start, vector end) _TE_lightning3 = +{ + EFF_BeamEffect (ent, start, end, TE_LIGHTNING3, MULTICAST_PHS); +}; + +void(vector org) TE_lightningblood = +{ +#ifdef NETQUAKE + particle(org, '0 0 100', 225, 120); +#else + EFF_PointEffect(org, TE_LIGHTNINGBLOOD, MULTICAST_PVS); +#endif +}; + +// function pointers for TE calls +var void(vector org, float damage) SpawnBlood = _SpawnBlood; +var void(vector org) TE_explosion = _TE_explosion; +var void(vector org) TE_gunshot = _TE_gunshot; +var void(vector org) TE_spike = _TE_spike; +var void(vector org) TE_knightspike = _TE_knightspike; +var void(vector org) TE_wizspike = _TE_wizspike; +var void(vector org) TE_superspike = _TE_superspike; +var void(vector org) TE_teleport = _TE_teleport; +var void(vector org) TE_lavasplash = _TE_lavasplash; +var void(vector org) TE_tarexplosion = _TE_tarexplosion; +var void(entity ent, vector start, vector end) TE_lightning1 = _TE_lightning1; +var void(entity ent, vector start, vector end) TE_lightning2 = _TE_lightning2; +var void(entity ent, vector start, vector end) TE_lightning3 = _TE_lightning3; + +// set effects function, takes function pointers and assigns them based on detected builtins +void() EFF_SetEffects = +{ + if (eng_support & ENG_EFRED) + { + ef_pent = 128; + ef_red = 128; + } + + if (eng_support & ENG_EFBLUE) + { + ef_blue = 64; + ef_quad = 64; + } + + if (eng_support & ENG_TEBUILTINS) + { + // use TE_ builtins instead + TE_explosion = _te_explosion; + TE_gunshot = _te_gunshot; + TE_spike = _te_spike; + TE_knightspike = _te_knightspike; + TE_wizspike = _te_wizspike; + TE_superspike = _te_superspike; + TE_teleport = _te_teleport; + TE_lavasplash = _te_lavasplash; + TE_tarexplosion = _te_tarexplosion; + TE_lightning1 = _te_lightning1; + TE_lightning2 = _te_lightning2; + TE_lightning3 = _te_lightning3; + } + + if (eng_support & ENG_TEBLOOD) + SpawnBlood = _SpawnBlood_TEBlood; // use TE_Blood builtin instead +}; + +// view kicks +void(entity ent) VK_smallkick = +{ +#ifdef NETQUAKE + self.punchangle_x = -2; +#else + msg_entity = ent; + WriteByte (MSG_ONE, SVC_SMALLKICK); +#endif +} + +void(entity ent) VK_bigkick = +{ +#ifdef NETQUAKE + self.punchangle_x = -4; +#else + msg_entity = ent; + WriteByte (MSG_ONE, SVC_BIGKICK); +#endif +} +void(entity ent) VK_hugekick = +{ +#ifdef NETQUAKE + self.punchangle_x = -8; +#else + msg_entity = ent; + WriteByte (MSG_ONE, SVC_HUGEKICK); +#endif +} + +// muzzle flash +void() muzzleflash = +{ +#ifdef NETQUAKE + self.effects |= EF_MUZZLEFLASH; +#else + WriteByte (MSG_MULTICAST, SVC_MUZZLEFLASH); + WriteEntity (MSG_MULTICAST, self); + multicast (self.origin, MULTICAST_PVS); +#endif +}; + +// touch blood functions +void(float damage) spawn_touchblood = +{ + local vector vel; + + vel = normalize (self.velocity); + vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5)); + vel = vel + 2*trace_plane_normal; + vel = vel * 0.4; + SpawnBlood (self.origin + vel, damage); +}; +/* +============================================ +HUD weapon ammo counter. Counts ammo and displays +Number of bullets. + +============================================ +*/ +void() AmmoCounter = +{ +if (self.weapon == IT_SHOTGUN) +{ + /*stuffcmd (self, "cl_ar_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_needler_ammo 0\n"); + stuffcmd (self, "cl_rocket_ammo 0\n"); + stuffcmd (self, "cl_weaponhud 0\n");*/ + + /*if (self.ammo_shells == 12) + stuffcmd (self, "cl_pistol_ammo 12\n"); + if (self.ammo_shells == 11) + stuffcmd (self, "cl_pistol_ammo 11\n"); + if (self.ammo_shells == 10) + stuffcmd (self, "cl_pistol_ammo 10\n"); + if (self.ammo_shells == 9) + stuffcmd (self, "cl_pistol_ammo 9\n"); + if (self.ammo_shells == 8) + stuffcmd (self, "cl_pistol_ammo 8\n"); + if (self.ammo_shells == 7) + stuffcmd (self, "cl_pistol_ammo 7\n"); + if (self.ammo_shells == 6) + stuffcmd (self, "cl_pistol_ammo 6\n"); + if (self.ammo_shells == 5) + stuffcmd (self, "cl_pistol_ammo 5\n"); + if (self.ammo_shells == 4) + stuffcmd (self, "cl_pistol_ammo 4\n"); + if (self.ammo_shells == 3) + stuffcmd (self, "cl_pistol_ammo 3\n"); + if (self.ammo_shells == 2) + stuffcmd (self, "cl_pistol_ammo 2\n"); + if (self.ammo_shells == 1) + stuffcmd (self, "cl_pistol_ammo 1\n"); + if (self.ammo_shells == 0) + stuffcmd (self, "cl_pistol_ammo 0\n"); + } + if (self.weapon == IT_SUPER_SHOTGUN) + { + if (self.ammo_shells2 == 6) + stuffcmd (self, "cl_shotgun_ammo 6\n"); + if (self.ammo_shells2 == 5) + stuffcmd (self, "cl_shotgun_ammo 5\n"); + if (self.ammo_shells2 == 4) + stuffcmd (self, "cl_shotgun_ammo 4\n"); + if (self.ammo_shells2 == 3) + stuffcmd (self, "cl_shotgun_ammo 3\n"); + if (self.ammo_shells2 == 2) + stuffcmd (self, "cl_shotgun_ammo 2\n"); + if (self.ammo_shells2 == 1) + stuffcmd (self, "cl_shotgun_ammo 1\n"); + if (self.ammo_shells2 == 0) + stuffcmd (self, "cl_shotgun_ammo 0\n"); + } + if (self.weapon == IT_NAILGUN) + { + if (self.ammo_nails == 32) + stuffcmd (self, "cl_ar_ammo 32\n"); + if (self.ammo_nails == 31) + stuffcmd (self, "cl_ar_ammo 31\n"); + if (self.ammo_nails == 30) + stuffcmd (self, "cl_ar_ammo 30\n"); + if (self.ammo_nails == 29) + stuffcmd (self, "cl_ar_ammo 29\n"); + if (self.ammo_nails == 28) + stuffcmd (self, "cl_ar_ammo 28\n"); + if (self.ammo_nails == 27) + stuffcmd (self, "cl_ar_ammo 27\n"); + if (self.ammo_nails == 26) + stuffcmd (self, "cl_ar_ammo 26\n"); + if (self.ammo_nails == 25) + stuffcmd (self, "cl_ar_ammo 25\n"); + if (self.ammo_nails == 24) + stuffcmd (self, "cl_ar_ammo 24\n"); + if (self.ammo_nails == 23) + stuffcmd (self, "cl_ar_ammo 23\n"); + if (self.ammo_nails == 22) + stuffcmd (self, "cl_ar_ammo 22\n"); + if (self.ammo_nails == 21) + stuffcmd (self, "cl_ar_ammo 21\n"); + if (self.ammo_nails == 20) + stuffcmd (self, "cl_ar_ammo 20\n"); + if (self.ammo_nails == 19) + stuffcmd (self, "cl_ar_ammo 19\n"); + if (self.ammo_nails == 18) + stuffcmd (self, "cl_ar_ammo 18\n"); + if (self.ammo_nails == 17) + stuffcmd (self, "cl_ar_ammo 17\n"); + if (self.ammo_nails == 16) + stuffcmd (self, "cl_ar_ammo 16\n"); + if (self.ammo_nails == 15) + stuffcmd (self, "cl_ar_ammo 15\n"); + if (self.ammo_nails == 14) + stuffcmd (self, "cl_ar_ammo 14\n"); + if (self.ammo_nails == 13) + stuffcmd (self, "cl_ar_ammo 13\n"); + if (self.ammo_nails == 12) + stuffcmd (self, "cl_ar_ammo 12\n"); + if (self.ammo_nails == 11) + stuffcmd (self, "cl_ar_ammo 11\n"); + if (self.ammo_nails == 10) + stuffcmd (self, "cl_ar_ammo 10\n"); + if (self.ammo_nails == 9) + stuffcmd (self, "cl_ar_ammo 9\n"); + if (self.ammo_nails == 8) + stuffcmd (self, "cl_ar_ammo 8\n"); + if (self.ammo_nails == 7) + stuffcmd (self, "cl_ar_ammo 7\n"); + if (self.ammo_nails == 6) + stuffcmd (self, "cl_ar_ammo 6\n"); + if (self.ammo_nails == 5) + stuffcmd (self, "cl_ar_ammo 5\n"); + if (self.ammo_nails == 4) + stuffcmd (self, "cl_ar_ammo 4\n"); + if (self.ammo_nails == 3) + stuffcmd (self, "cl_ar_ammo 3\n"); + if (self.ammo_nails == 2) + stuffcmd (self, "cl_ar_ammo 2\n"); + if (self.ammo_nails == 1) + stuffcmd (self, "cl_ar_ammo 1\n"); + if (self.ammo_nails == 0) + stuffcmd (self, "cl_ar_ammo 0\n"); + } + if (self.weapon == IT_ROCKET_LAUNCHER) + { + /*stuffcmd (self, "cl_ar_ammo 0\n"); //Turns off other ammo counters + stuffcmd (self, "cl_pistol_ammo 0\n"); + stuffcmd (self, "cl_needler_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_weaponhud 0\n"); //Keeps Needler Weapon Icon off*/ + + /*if (self.ammo_rockets == 2) + stuffcmd (self, "cl_rocket_ammo 2\n"); + if (self.ammo_rockets == 1) + stuffcmd (self, "cl_rocket_ammo 1\n"); + if (self.ammo_rockets == 0) + stuffcmd (self, "cl_rocket_ammo 0\n"); + } + if (self.weapon == IT_LIGHTNING) + { + stuffcmd (self, "cl_ar_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_needler_ammo 0\n"); + stuffcmd (self, "cl_rocket_ammo 0\n"); + stuffcmd (self, "cl_pistol_ammo 0\n"); + } + if (self.weapon == IT_AXE) + { + stuffcmd (self, "cl_ar_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_needler_ammo 0\n"); + stuffcmd (self, "cl_rocket_ammo 0\n"); + stuffcmd (self, "cl_pistol_ammo 0\n"); + } + if (self.weapon == WEAPON_NEEDLER) + { + /*stuffcmd (self, "cl_weaponhud 1\n"); //Turns needler Icon on. + stuffcmd (self, "cl_pistol_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_ar_ammo 0\n"); + stuffcmd (self, "cl_rocket_ammo 0\n");*/ + + /*if (self.ammo_needler == 20) + stuffcmd (self, "cl_needler_ammo 20\n"); + if (self.ammo_needler == 19) + stuffcmd (self, "cl_needler_ammo 19\n"); + if (self.ammo_needler == 18) + stuffcmd (self, "cl_needler_ammo 18\n"); + if (self.ammo_needler == 17) + stuffcmd (self, "cl_needler_ammo 17\n"); + if (self.ammo_needler == 16) + stuffcmd (self, "cl_needler_ammo 16\n"); + if (self.ammo_needler == 15) + stuffcmd (self, "cl_needler_ammo 15\n"); + if (self.ammo_needler == 14) + stuffcmd (self, "cl_needler_ammo 14\n"); + if (self.ammo_needler == 13) + stuffcmd (self, "cl_needler_ammo 13\n"); + if (self.ammo_needler == 12) + stuffcmd (self, "cl_needler_ammo 12\n"); + if (self.ammo_needler == 11) + stuffcmd (self, "cl_needler_ammo 11\n"); + if (self.ammo_needler == 10) + stuffcmd (self, "cl_needler_ammo 10\n"); + if (self.ammo_needler == 9) + stuffcmd (self, "cl_needler_ammo 9\n"); + if (self.ammo_needler == 8) + stuffcmd (self, "cl_needler_ammo 8\n"); + if (self.ammo_needler == 7) + stuffcmd (self, "cl_needler_ammo 7\n"); + if (self.ammo_needler == 6) + stuffcmd (self, "cl_needler_ammo 6\n"); + if (self.ammo_needler == 5) + stuffcmd (self, "cl_needler_ammo 5\n"); + if (self.ammo_needler == 4) + stuffcmd (self, "cl_needler_ammo 4\n"); + if (self.ammo_needler == 3) + stuffcmd (self, "cl_needler_ammo 3\n"); + if (self.ammo_needler == 2) + stuffcmd (self, "cl_needler_ammo 2\n"); + if (self.ammo_needler == 1) + stuffcmd (self, "cl_needler_ammo 1\n"); + if (self.ammo_needler == 0) + stuffcmd (self, "cl_needler_ammo 0\n"); + } + if (self.weapon == WEAPON_PRIFLE) + { + stuffcmd (self, "cl_ar_ammo 0\n"); + stuffcmd (self, "cl_shotgun_ammo 0\n"); + stuffcmd (self, "cl_needler_ammo 0\n"); + stuffcmd (self, "cl_rocket_ammo 0\n"); + stuffcmd (self, "cl_pistol_ammo 0\n");*/ + } +}; +/* +========================================== + +Grenade counter for the HUD. Displays a players Number +Of nades. + +========================================== +*/ +void() NadeCounter = +{ +if (self.selnade == GRENADE_REGULAR) + { + stuffcmd (self, "cl_plasmanade 2\n"); + if (self.nade_lives == 4) + stuffcmd (self, "cl_nadenum 5\n"); + if (self.nade_lives == 3) + stuffcmd (self, "cl_nadenum 4\n"); + if (self.nade_lives == 2) + stuffcmd (self, "cl_nadenum 3\n"); + if (self.nade_lives == 1) + stuffcmd (self, "cl_nadenum 2\n"); + if (self.nade_lives == 0) + stuffcmd (self, "cl_nadenum 1\n"); + } +else if (self.selnade == GRENADE_STICKY) + { + stuffcmd (self, "cl_plasmanade 1\n"); + if (self.plasma_lives == 4) + stuffcmd (self, "cl_nadenum 5\n"); + if (self.plasma_lives == 3) + stuffcmd (self, "cl_nadenum 4\n"); + if (self.plasma_lives == 2) + stuffcmd (self, "cl_nadenum 3\n"); + if (self.plasma_lives == 1) + stuffcmd (self, "cl_nadenum 2\n"); + if (self.plasma_lives == 0) + stuffcmd (self, "cl_nadenum 1\n"); + } + + +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/engine.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/engine.qc new file mode 100755 index 00000000..d7e53052 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/engine.qc differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/fight.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/fight.qc new file mode 100755 index 00000000..84717540 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/fight.qc differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot.qc new file mode 100755 index 00000000..41dcaf0b --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot.qc @@ -0,0 +1,1281 @@ + +/* +====================================== +FrikBot X (Version 0.10.2) +====================================== + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +====================================== +These installation instructions only apply to Normal Quake (as does this +entire file). For QuakeWorld, please refer to bot_qw.qc + +-------------------------------------- +To install on a new mod, do all this: +-------------------------------------- +Place all included bot*.qc files in the subdirectory "frikbot" +in your source folder, then... + +* Add the following lines to progs.src right after the defs.qc line +frikbot/bot.qc +frikbot/bot_way.qc +frikbot/bot_fight.qc +frikbot/bot_ai.qc +frikbot/bot_misc.qc +frikbot/bot_phys.qc +frikbot/bot_move.qc +frikbot/bot_ed.qc + +-------------------------------------- +* Comment out the following functions in defs.qc +sound, stuffcmd, sprint, aim, centerprint, setspawnparms +WriteByte, WriteChar, WriteShort, WriteLong, WriteCoord +WriteAngle, WriteString, WriteEntity +-------------------------------------- +* Add this to worldspawn() in world.qc, right at the very top, before InitBodyQue(); +BotInit(); // FrikBot +-------------------------------------- +* add this line to StartFrame() in world.qc, at the very top +BotFrame(); // FrikBot +-------------------------------------- +* Add these two lines to PlayerPreThink in client.qc at the very top +if (BotPreFrame()) // FrikBot + return; +-------------------------------------- +* Add this line to PlayerPostThink in client.qc at the very top +if (BotPostFrame()) // FrikBot + return; +-------------------------------------- +* Add the following line to the very top of Client Connect in client.qc +ClientInRankings(); // FrikBot +-------------------------------------- +* Add these lines to the very top of ClientDisconnect in client.qc +ClientDisconnected(); // FrikBot +-------------------------------------- + +To install the waypoints: + +add + +waypoints/map_dm1.qc +waypoints/map_dm2.qc +waypoints/map_dm3.qc +waypoints/map_dm4.qc +waypoints/map_dm5.qc +waypoints/map_dm6.qc + +To progs.src, immediately after defs.qc + +To remove these waypoints: + +Delete the code in bot_map_load, located below. +*/ + + +void() bot_map_load = +{ +/* + // place your qc loaded waypoints here + + if (mapname == "dm1") + map_dm1(); + else if (mapname == "dm2") + map_dm2(); + else if (mapname == "dm3") + map_dm3(); + else if (mapname == "dm4") + map_dm4(); + else if (mapname == "dm5") + map_dm5(); + else if (mapname == "dm6") + map_dm6(); +*/ +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Variables and shtuff + +bot.qc has become pretty much a header file +for all variable in the bot... + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +// ----- entity fields --- +.float wallhug, keys, oldkeys, ishuman; +.float b_frags, b_clientno, b_shirt, b_pants; +.float /*priority, */ai_time, b_sound, missile_speed; +.float portal_time, b_skill, switch_wallhug; +.float b_aiflags, b_num, b_chattime; +.float b_menu, b_menu_time, b_menu_value; +.float route_failed, dyn_flags, dyn_time; +.float dyn_plat; +.entity temp_way, last_way, phys_obj; +.entity target1, target2, target3, target4; +.entity _next, _last; +.entity current_way; +.vector b_angle/*, b_dest*/, mouse_emu, obs_dir; +.vector movevect, b_dir; +.vector dyn_dest; + +// --------defines----- +float SVC_UPDATENAME = 13; +float SVC_UPDATEFRAGS = 14; +float SVC_UPDATECOLORS = 17; + +// used for the physics & movement AI +float KEY_MOVEUP = 1; +float KEY_MOVEDOWN = 2; +float KEY_MOVELEFT = 4; +float KEY_MOVERIGHT = 8; +float KEY_MOVEFORWARD = 16; +float KEY_MOVEBACK = 32; +float KEY_LOOKUP = 64; +float KEY_LOOKDOWN = 128; +float KEY_LOOKLEFT = 256; +float KEY_LOOKRIGHT = 512; + +// these are aiflags for waypoints +// some overlap to the bot +float AI_TELELINK_1 = 1; // link type +float AI_TELELINK_2 = 2; // link type +float AI_TELELINK_3 = 4; // link type +float AI_TELELINK_4 = 8; // link type +float AI_DOORFLAG = 16; // read ahead +float AI_PRECISION = 32; // read ahead + point +float AI_SURFACE = 64; // point +float AI_BLIND = 128; // read ahead + point +float AI_JUMP = 256; // point + ignore +float AI_DIRECTIONAL = 512; // read ahead + ignore +float AI_PLAT_BOTTOM = 1024; // read ahead +float AI_RIDE_TRAIN = 2048; // read ahead +float AI_SUPER_JUMP = 4096; // point + ignore + route test +float AI_SNIPER = 8192; // point type +float AI_AMBUSH = 16384; // point type +float AI_DOOR_NO_OPEN = 32768; // read ahead +float AI_DIFFICULT = 65536; // route test +float AI_TRACE_TEST = 131072; // route test + +// these are flags for bots/players (dynamic/editor flags) +float AI_OBSTRUCTED = 1; +float AI_HOLD_SELECT = 2; +float AI_ROUTE_FAILED = 2; +float AI_WAIT = 4; +float AI_DANGER = 8; + + +// addition masks +float AI_POINT_TYPES = 29152; +float AI_READAHEAD_TYPES = 36528; +float AI_IGNORE_TYPES = 4864; + +float WM_UNINIT = 0; +float WM_DYNAMIC = 1; +float WM_LOADING = 2; +float WM_LOADED = 3; +float WM_EDITOR = 4; +float WM_EDITOR_DYNAMIC = 5; +float WM_EDITOR_DYNLINK = 6; + + +float OPT_SAVEBOTS = 1; +float OPT_NOCHAT = 2; + +// -------globals----- +float active_clients; +float max_clients, real_frametime; +float bot_count, b_options; +float waypoint_mode, dump_mode; +float waypoints, direct_route; +float sv_friction, sv_gravity; +float sv_accelerate, sv_maxspeed, sv_stopspeed; +entity fixer; +entity route_table; +entity b_temp1, b_temp2, b_temp3; +entity player_head, phys_head, way_head; +float busy_waypoints; +float saved_bots, saved_skills1, saved_skills2, current_bots; + +// -------ProtoTypes------ +// external +void() ClientConnect; +void() ClientDisconnect; +void() SetNewParms; + +// rankings +float(float clientno) ClientBitFlag; +float() ClientNextAvailable; +void(float whichteam, float whatbot, float whatskill) BotConnect; +void(entity bot) BotDisconnect; +void(float clientno) BotInvalidClientNo; +void(entity who) UpdateClient; + +// waypointing +void() DynamicWaypoint; +entity(vector org) make_waypoint; +void() ClearAllWays; +void() FixWaypoints; +float() begin_route; +void(entity this, float direct) bot_get_path; +void() WaypointThink; +entity(entity start) FindWayPoint; + +// physics & movement +float(entity e) bot_can_rj; +void() bot_jump; +void() frik_bot_roam; +float(vector weird) frik_walkmove; +void() frik_movetogoal; +void() frik_obstacles; +float(float flag) frik_recognize_plat; +float(vector sdir) frik_KeysForDir; +void(vector whichway, float danger) frik_obstructed; +void() SV_Physics_Client; +void() SV_ClientThink; +void() CL_KeyMove; + +// ai & misc +string() PickARandomName; +float(entity targ) fov; +float(float y1, float y2) angcomp; +float(entity targ1, entity targ2) wisible; +float(entity targ) sisible; +float(entity targ) fisible; +vector(entity ent) realorigin; +void(entity ent) target_drop; +void(entity ent) target_add; +void() KickABot; +void() BotImpulses; +void(entity targ, float success) bot_lost; +string(float r) BotName; +float(float v) frik_anglemod; +void() bot_chat; +void(float tpic) bot_start_topic; + + +// editor stuffs + +void() bot_way_edit; +void() bot_menu_display; + + +// ----------Commands--------- +void(entity e, float chan, string samp, float vol, float atten) frik_sound = #8; +void(entity client, string s) frik_stuffcmd = #21; +void(entity client, string s) frik_sprint = #24; +vector(entity e, float sped) frik_aim = #44; +void(entity client, string s) frik_centerprint = #73; +void(entity e) frik_setspawnparms = #78; +void(float to, float f) frik_WriteByte = #52; +void(float to, float f) frik_WriteChar = #53; +void(float to, float f) frik_WriteShort = #54; +void(float to, float f) frik_WriteLong = #55; +void(float to, float f) frik_WriteCoord = #56; +void(float to, float f) frik_WriteAngle = #57; +void(float to, string s) frik_WriteString = #58; +void(float to, entity s) frik_WriteEntity = #59; + +void(entity client, string s1, string s2, string s3, string s4, string s5, string s6, string s7) +frik_big_centerprint = #73; + +//---------------------------------------------------------------------------- + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Function redclarations. These allow function +designed to work for clients (sprint, so forth) +to mainly not complain when working with a bot + +Although these shouldn't be needed anymore, +as the bots truly are clients now, if you don't +stop the SZ_ buffer from filling up by disabling +direct messages to the bots, it crashes quake :-( + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(entity client, string s) stuffcmd = +{ + if (client.ishuman == 1) + frik_stuffcmd(client, s); + b_temp1 = player_head; + + while(b_temp1) + { + if (b_temp1.classname == "botcam") + { + if ((b_temp1.enemy == client) && b_temp1.ishuman) + frik_stuffcmd(b_temp1, s); + } + b_temp1 = b_temp1._next; + } +}; + +void(entity e) setspawnparms = +{ + if (e.ishuman == 1) + frik_setspawnparms(e); + else + { + b_temp1 = player_head; + while(b_temp1) + { + if (b_temp1.ishuman) + { + frik_setspawnparms(b_temp1); + return; + } + b_temp1 = b_temp1._next; + } + SetNewParms(); + } +}; +void(entity client, string s) sprint = +{ + if (client.ishuman == 1) + frik_sprint(client, s); + b_temp1 = player_head; + + while(b_temp1) + { + if (b_temp1.classname == "botcam") + { + if ((b_temp1.enemy == client) && b_temp1.ishuman) + frik_sprint(b_temp1, s); + } + b_temp1 = b_temp1._next; + } + +}; +void( string s ) bprint = +{ + _bprint( s ); + +}; + +void(entity client, string s) centerprint = +{ + if (client.ishuman == 1) + frik_centerprint(client, s); + b_temp1 = player_head; + + while(b_temp1) + { + if (b_temp1.classname == "botcam") + { + if ((b_temp1.enemy == client) && b_temp1.ishuman) + frik_centerprint(b_temp1, s); + } + b_temp1 = b_temp1._next; + } +}; + +vector(entity e, float sped) aim = +{ + e.missile_speed = sped; + return frik_aim(e, sped); +}; + +void(entity e, float chan, string samp, float vol, float atten) sound = +{ + + frik_sound(e, chan, samp, vol, atten); + if (samp == "items/inv3.wav") + return; + else if (e.classname == "player") + e.b_sound = time + 1; + else if (other.classname == "player") + other.b_sound = time + 1; + +}; +void(float to, float f) WriteByte = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteByte(to, f); +}; +void(float to, float f) WriteChar = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteChar(to, f); +}; +void(float to, float f) WriteShort = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteShort(to, f); +}; +void(float to, float f) WriteLong = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteLong(to, f); +}; +void(float to, float f) WriteCoord = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteCoord(to, f); +}; +void(float to, float f) WriteAngle = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteAngle(to, f); +}; +void(float to, string s) WriteString = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteString(to, s); +}; +void(float to, entity s) WriteEntity = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteEntity(to, s); +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Cam, see what the bot sees (or any other player) + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float() botcam = +{ + if (self.classname != "botcam") + return FALSE; + setorigin(self, self.enemy.origin); + self.items = self.enemy.items; + self.weapon = self.enemy.weapon; + self.weaponmodel = self.enemy.weaponmodel; + self.currentammo = self.enemy.currentammo; + self.weaponframe = self.enemy.weaponframe; + self.ammo_shells = self.enemy.ammo_shells; + self.ammo_nails = self.enemy.ammo_nails; + self.ammo_rockets= self.enemy.ammo_rockets; + self.ammo_cells = self.enemy.ammo_cells; + self.view_ofs = self.enemy.view_ofs; + self.health = self.enemy.health; + self.armorvalue = self.enemy.armorvalue; + self.dmg_take = self.enemy.dmg_take; + self.dmg_save = self.enemy.dmg_save; + self.dmg_inflictor = self.enemy.dmg_inflictor; + self.punchangle = self.enemy.punchangle; + self.deadflag = self.enemy.deadflag; + msg_entity = self; + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE, self.enemy); + WriteByte (MSG_ONE, 10); + WriteAngle (MSG_ONE,self.enemy.v_angle_x); + WriteAngle (MSG_ONE,self.enemy.v_angle_y); + WriteAngle (MSG_ONE,self.enemy.v_angle_z); + self.modelindex = 0; + + self.impulse = 0; + return TRUE; + +}; + +void() botcam_u = +{ + + // sloppy cycling code + if (self.classname != "botcam") + { + self.enemy = player_head; + } + else + { + do + self.enemy = self.enemy._next; + while (self.enemy.classname == "botcam"); + } + if (self.enemy == self) + { + do + self.enemy = self.enemy._next; + while (self.enemy.classname == "botcam"); + } + + self.classname = "botcam"; + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_NONE; + self.takedamage = DAMAGE_NO; + + + if (!self.enemy) + { + sprint(self, "No one left to track!\n"); + msg_entity = self; + WriteByte (MSG_ONE,5); + WriteEntity (MSG_ONE, self); + PutClientInServer(); + return; + } + if (!self.enemy.ishuman) + { + self.enemy.dmg_take = 0; + self.enemy.dmg_save = 0; + } + sprint(self, "Now tracking "); + sprint(self, self.enemy.netname); + sprint(self, "\n"); +}; + + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Stuff mentioned up top +it just links the bot into the mod + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClientFixRankings = +{ + local float cno; + + if (self.switch_wallhug > time) + return; + self.switch_wallhug = 0; + + b_temp2 = nextent(world); + cno = 0; + + while (cno < max_clients) + { + if ((!b_temp2.ishuman) && (active_clients & ClientBitFlag(cno))) + UpdateClient(b_temp2); + cno = cno + 1; + b_temp2 = nextent(b_temp2); + } +}; + +void() ClientInRankings = +{ + local float cno; + + cno = self.colormap - 1; + BotInvalidClientNo (cno); + + if (player_head) + player_head._last = self; + + self._next = player_head; + self._last = world; + player_head = self; + + if (!self.phys_obj) + { + b_temp2 = phys_head; + while (b_temp2 != world && b_temp2.owner != self) + b_temp2 = b_temp2._next; + self.phys_obj = b_temp2; + } + + if (self.ishuman == 2) + { + self.ishuman = FALSE; + return; + } + active_clients = active_clients | ClientBitFlag(cno); + + self.b_clientno = cno; + self.ishuman = TRUE; + self.switch_wallhug = time + 1; +}; + + +void() ClientDisconnected = +{ + if (player_head == self) + player_head = self._next; + if (self._next) + self._next._last = self._last; + if (self._last) + self._last._next = self._next; + + active_clients = active_clients - active_clients & ClientBitFlag(self.b_clientno); +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotPreFrame & BotPostFrame, used to make the +bot easier to install + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float () BotPreFrame = +{ + if (self.b_clientno == -1) + return TRUE; + if (self.ishuman) + { + if (self.switch_wallhug) + ClientFixRankings(); + if (self.classname == "botcam") + return TRUE; + + } + if (self.b_frags != self.frags) + { + + if (self.b_frags > self.frags) + { + if (pointcontents(self.origin) == CONTENT_LAVA) + bot_start_topic(10); + else + bot_start_topic(9); + } + else + bot_start_topic(2); + self.b_frags = self.frags; + } + DynamicWaypoint(); + return FALSE; +}; +float () BotPostFrame = +{ + if (self.b_clientno == -1) + return TRUE; + if (self.ishuman) + { + + if (waypoint_mode > WM_LOADED) + bot_menu_display(); + + BotImpulses(); + + if (botcam()) + return TRUE; + } + return FALSE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Chat code + +The rest of this code is in bot_misc.qc + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(string h) BotSay = // simulate talking by composing a 'chat' message +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, self.netname); + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 2); + WriteString(MSG_ALL, h); +}; +void() BotSayInit = +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, self.netname); +}; +void(string h) BotSay2 = +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 2); + WriteString(MSG_ALL, h); +}; +void(string h) BotSayTeam = +{ + local entity t; + if (!teamplay) + return; + t = player_head; + while(t) + { + if (t.team == self.team) + { + msg_entity = t; + WriteByte(MSG_ONE, 8); + WriteByte(MSG_ONE, 1); + WriteByte(MSG_ONE, 40); + WriteString(MSG_ONE, self.netname); + WriteByte(MSG_ONE, 8); + WriteByte(MSG_ONE, 2); + WriteByte(MSG_ONE, 41); + WriteString(MSG_ONE, h); + } + t = t._next; + } +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotInit + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void() BotInit = +{ + local entity ent, fisent; + local float numents; + + // spawn entities for the physics + ent = nextent(world); + max_clients = 0; + + while(ent != world) + { + max_clients = max_clients + 1; + ent = nextent(ent); + } + if (max_clients > 16) + max_clients = 16; + + ent = nextent(world); + fisent = world; + while (numents < max_clients) + { + + phys_head = spawn(); + if (fisent) + fisent._next = phys_head; + phys_head._last = fisent; + fisent = phys_head; + ent.phys_obj = phys_head; + phys_head.classname = "phys_obj"; + phys_head.owner = ent; + numents = numents + 1; + ent = nextent(ent); + } + precache_model("progs/s_light.spr"); + precache_model("progs/s_bubble.spr"); + + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Rankings 'utilities'. Written by Alan Kivlin, +this code just fools clients by sending precisely +the same network messages as when a real player +signs on to the server. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void(entity who) UpdateClient = +{ + WriteByte (MSG_ALL, SVC_UPDATENAME); + WriteByte (MSG_ALL, who.b_clientno); + WriteString (MSG_ALL, who.netname); + WriteByte (MSG_ALL, SVC_UPDATECOLORS); + WriteByte (MSG_ALL, who.b_clientno); + WriteByte (MSG_ALL, who.b_shirt * 16 + who.b_pants); + WriteByte (MSG_ALL, SVC_UPDATEFRAGS); + WriteByte (MSG_ALL, who.b_clientno); + WriteShort (MSG_ALL, who.frags); +}; + +float(float clientno) ClientBitFlag = +{ + // bigger, but faster + if (clientno == 0) + return 1; + else if (clientno == 1) + return 2; + else if (clientno == 2) + return 4; + else if (clientno == 3) + return 8; + else if (clientno == 4) + return 16; + else if (clientno == 5) + return 32; + else if (clientno == 6) + return 64; + else if (clientno == 7) + return 128; + else if (clientno == 8) + return 256; + else if (clientno == 9) + return 512; + else if (clientno == 10) + return 1024; + else if (clientno == 11) + return 2048; + else if (clientno == 12) + return 4096; + else if (clientno == 13) + return 8192; + else if (clientno == 14) + return 16384; + else if (clientno == 15) + return 32768; + return 0; +}; + +float() ClientNextAvailable = +{ + local float clientno; + + clientno = max_clients; + while(clientno > 0) + { + clientno = clientno - 1; + + if(!(active_clients & ClientBitFlag(clientno))) + return clientno; + } + + return -1; +}; + + +void(entity e1, entity e2, float flag) DeveloperLightning = +{ + // used to show waypoint links for debugging + WriteByte (MSG_BROADCAST, 23); + if (flag) + WriteByte (MSG_BROADCAST, 6); + else + WriteByte (MSG_BROADCAST, 13); + WriteEntity (MSG_BROADCAST, e2); + WriteCoord (MSG_BROADCAST, e1.origin_x); + WriteCoord (MSG_BROADCAST, e1.origin_y); + WriteCoord (MSG_BROADCAST, e1.origin_z); + WriteCoord (MSG_BROADCAST, e2.origin_x); + WriteCoord (MSG_BROADCAST, e2.origin_y); + WriteCoord (MSG_BROADCAST, e2.origin_z); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Find Another Color + +Team finding code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float(float tcolor) FindAnotherColor = +{ + local float bestbet, scolor, pcount, bestp; + bestbet = -1; + bestp = 16; + while(scolor < 14) + { + if (scolor != tcolor) + { + b_temp2 = player_head; + pcount = 0; + while(b_temp2 != world) + { + if (b_temp2.team == scolor + 1) + pcount = pcount + 1; + b_temp2 = b_temp2._next; + } + if ((pcount < bestp) && pcount) + { + bestbet = scolor; + bestp = pcount; + } + } + scolor = scolor + 1; + } + if (bestbet < 0) + { + bestbet = tcolor; + while (bestbet == tcolor) + { + bestbet = floor(random() * 13); + } + } + return bestbet; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotConnect and related functions. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +entity(float num) GetClientEntity = +{ + local entity upsy; + upsy = world; + num = num + 1; + while (num > 0) + { + num = num - 1; + upsy = nextent(upsy); + } + return upsy; +}; + +void(float whichteam, float whatbot, float whatskill) BotConnect = +{ + local float f; + local string h; + local entity uself; + + f = ClientNextAvailable(); + uself = self; + if(f == -1) + { + bprint("Unable to connect a bot, server is full.\n"); + return; + } + + // chat thing + + bot_count = bot_count + 1; + self = GetClientEntity(f); + if (!saved_bots) + bot_start_topic(1); + self.b_clientno = f; + self.colormap = f + 1; + if (whatbot) + self.netname = BotName(whatbot); + else + self.netname = PickARandomName(); + + + // players can set skill all weird, so leave these checks in + whatskill = rint(whatskill); + if (whatskill > 3) + whatskill = 3; + else if (whatskill < 0) + whatskill = 0; + self.b_skill = whatskill; + + if (teamplay && !coop) + { + if (whichteam) + self.b_pants = FindAnotherColor(uself.team - 1); + else + self.b_pants = uself.team - 1; + self.b_shirt = self.b_pants; + } + + self.team = self.b_pants + 1; + UpdateClient(self); + SetNewParms(); + self.ishuman = 2; + ClientConnect(); + PutClientInServer(); + + active_clients = active_clients | ClientBitFlag(f); + + // this is risky... could corrupt .way files if done wrong + // If you're not the gambling type, comment this out + + f = ClientBitFlag(self.b_num - 1); + current_bots = current_bots | f; + + if (self.b_num <= 8) + saved_skills1 = (saved_skills1 & (65536 - (3 * f)) | (self.b_skill * f)); + else + { + f = ClientBitFlag(self.b_num - 9); + saved_skills2 = (saved_skills2 & (65536 - (3 * f)) | (self.b_skill * f)); + } + + h = ftos(current_bots); + cvar_set("scratch1", h); + h = ftos(saved_skills1); + cvar_set("scratch2", h); + h = ftos(saved_skills2); + cvar_set("scratch3", h); + self = uself; + +}; + +void(entity bot) BotDisconnect = +{ + local string h; + local entity uself; + uself = self; + self = bot; + + bot_count = bot_count - 1; + current_bots = current_bots - (current_bots & ClientBitFlag(self.b_num - 1)); + h = ftos(current_bots); + cvar_set("scratch1", h); + + + ClientDisconnect(); + + if (self.b_clientno != -1) + { + // the bot's client number is not in use by a real player so we + // must remove it's entry in the rankings + // Quake engine sets all fields to 0, can only do the most important here + self.b_frags = self.frags = 0; + self.netname = ""; + self.classname = ""; + self.health = 0; + self.items = 0; + self.armorvalue = 0; + self.weaponmodel = ""; + self.b_pants = 0; + self.b_shirt = 0; + self.ammo_shells = self.ammo_nails = self.ammo_rockets = self.ammo_cells = 0; + UpdateClient(self); + active_clients = active_clients - (active_clients & ClientBitFlag(self.b_clientno)); + self.b_clientno = -1; + } + self = uself; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotInvalidClientNo +kicks a bot if a player connects and takes the bot's space + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(float clientno) BotInvalidClientNo = +{ + local entity bot; + + bot = GetClientEntity(clientno); + if(bot.b_clientno > 0) + { + if (active_clients & ClientBitFlag(self.b_clientno)) + { + bot.b_clientno = -1; + BotDisconnect(bot); + active_clients = active_clients | ClientBitFlag(self.b_clientno); + BotConnect(0, bot.b_num, bot.b_skill); + return; + } + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Loading from file + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void() LoadWaypoint = +{ + local vector org; + local entity tep; + local float r; + org_x = cvar("saved1"); + org_y = cvar("saved2"); + org_z = cvar("saved3"); + + tep = make_waypoint(org); + + r = cvar("saved4"); + + tep.b_aiflags = floor(r / 4); + tep.b_pants = cvar("scratch1"); + tep.b_skill = cvar("scratch2"); + tep.b_shirt = cvar("scratch3"); + tep.b_frags = cvar("scratch4"); +}; + +void() bot_return = +{ + if (time > 2) + { + if ((waypoint_mode == WM_DYNAMIC) || (waypoint_mode == WM_LOADED)) + { + // minor precaution + + if (saved_bots & 1) BotConnect(0, 1, saved_skills1 & 3); + if (saved_bots & 2) BotConnect(0, 2, (saved_skills1 & 12) / 4); + if (saved_bots & 4) BotConnect(0, 3, (saved_skills1 & 48) / 16); + if (saved_bots & 8) BotConnect(0, 4, (saved_skills1 & 192) / 64); + if (saved_bots & 16) BotConnect(0, 5, (saved_skills1 & 768) / 256); + if (saved_bots & 32) BotConnect(0, 6, (saved_skills1 & 3072) / 1024); + if (saved_bots & 64) BotConnect(0, 7, (saved_skills1 & 12288) / 4096); + if (saved_bots & 128) BotConnect(0, 8, (saved_skills1 & 49152) / 16384); + if (saved_bots & 256) BotConnect(0, 9, saved_skills2 & 3); + if (saved_bots & 512) BotConnect(0, 10, (saved_skills2 & 12) / 4); + if (saved_bots & 1024) BotConnect(0, 11, (saved_skills2& 48) / 16); + if (saved_bots & 2048) BotConnect(0, 12, (saved_skills2 & 192) / 64); + if (saved_bots & 4096) BotConnect(0, 13, (saved_skills2 & 768) / 256); + if (saved_bots & 8192) BotConnect(0, 14, (saved_skills2 & 3072) / 1024); + if (saved_bots & 16384) BotConnect(0, 15, (saved_skills2 & 12288) / 4096); + if (saved_bots & 32768) BotConnect(0, 16, (saved_skills2 & 49152) / 16384); + saved_bots = 0; + } + } +}; + + +void() WaypointWatch = +{ + // Waypoint Baywatch + local float bigboobs; + local string h; + if (framecount < 4) + return; + if (max_clients < 2) + return; + if (waypoint_mode != WM_UNINIT) + { + bigboobs = cvar("saved4"); + if (bigboobs != 0) + { + if ((bigboobs & 3) == 1) + ClearAllWays(); + else if ((bigboobs & 3) == 3) + { + FixWaypoints(); + h = ftos(b_options); + cvar_set("saved1", h); + cvar_set("saved4", "0"); + cvar_set("scratch1", "0"); + waypoint_mode = WM_LOADED; + return; + } + LoadWaypoint(); + waypoint_mode = WM_LOADING; + cvar_set("saved4", "0"); + } + } + else + { + // the bots return! + b_options = cvar("saved1"); + if (coop || (b_options & OPT_SAVEBOTS)) + { + saved_bots = cvar("scratch1"); + saved_skills1 = cvar("scratch2"); + saved_skills2 = cvar("scratch3"); + } + cvar_set ("saved4", "0"); + if (max_clients > 1) + { + localcmd("exec maps/"); + localcmd(mapname); + localcmd(".way\n"); + waypoint_mode = WM_DYNAMIC; + bot_map_load(); + } + else + waypoint_mode = WM_LOADED; + } +}; +void() BotFrame = +{ + local float num; + + // for the sake of speed + sv_maxspeed = cvar("sv_maxspeed"); + sv_gravity = cvar("sv_gravity"); + sv_friction = cvar("sv_friction"); + sv_accelerate = cvar("sv_accelerate"); + sv_stopspeed = cvar("sv_stopspeed"); + real_frametime = frametime; // in NQ this is alright + + self = nextent(world); + num = 0; + while (num < max_clients) + { + if (self.ishuman == FALSE) + { + if (active_clients & ClientBitFlag(num)) + { + frik_obstacles(); + CL_KeyMove(); + SV_ClientThink(); + SV_Physics_Client(); + } + } + self = nextent(self); + num = num + 1; + } + WaypointWatch(); + + if (saved_bots) + bot_return(); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Impulses. Allows the player to perform bot +related functions. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() BotImpulses = +{ + local float f; + + if (self.impulse == 100) + { + f = cvar("skill"); + BotConnect(0, 0, f); + } + else if (self.impulse == 101) + { + f = cvar("skill"); + BotConnect(1, 0, f); + } + else if (self.impulse == 102) + KickABot(); + else if (self.impulse == 103) + botcam_u(); + else if (self.impulse == 104) + bot_way_edit(); + else + return; + + self.impulse = 0; +}; + + + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_ai.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_ai.qc new file mode 100755 index 00000000..60fe6730 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_ai.qc @@ -0,0 +1,1017 @@ +/*********************************************** +* * +* FrikBot General AI * +* "The I'd rather be playing Quake AI" * +* * +***********************************************/ + +/* + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +target_onstack + +checks to see if an entity is on the bot's stack + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float(entity scot) target_onstack = +{ + if (scot == world) + return FALSE; + else if (self.target1 == scot) + return 1; + else if (self.target2 == scot) + return 2; + else if (self.target3 == scot) + return 3; + else if (self.target4 == scot) + return 4; + else + return FALSE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +target_add + +adds a new entity to the stack, since it's a +LIFO stack, this will be the bot's new target1 + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity ent) target_add = +{ + if (ent == world) + return; + if (target_onstack(ent)) + return; + self.target4 = self.target3; + self.target3 = self.target2; + self.target2 = self.target1; + self.target1 = ent; + self.search_time = time + 5; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +target_drop + +Removes an entity from the bot's target stack. +The stack will empty everything up to the object +So if you have target2 item_health, target1 +waypoint, and you drop the health, the waypoint +is gone too. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity ent) target_drop = +{ + local float tg; + + tg = target_onstack(ent); + if (tg == 1) + { + self.target1 = self.target2; + self.target2 = self.target3; + self.target3 = self.target4; + self.target4 = world; + } + else if (tg == 2) + { + self.target1 = self.target3; + self.target2 = self.target4; + self.target3 = self.target4 = world; + } + else if (tg == 3) + { + self.target1 = self.target4; + self.target2 = self.target3 = self.target4 = world; + } + else if (tg == 4) + self.target1 = self.target2 = self.target3 = self.target4 = world; + self.search_time = time + 5; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_lost + +Bot has lost its target. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity targ, float success) bot_lost = +{ + if (!targ) + return; + + target_drop(targ); + if (targ.classname == "waypoint") + targ.b_sound = targ.b_sound - (targ.b_sound & ClientBitFlag(self.b_clientno)); + + // find a new route + if (!success) + { + self.target1 = self.target2 = self.target3 = self.target4 = world; + self.last_way = FindWayPoint(self.current_way); + ClearMyRoute(); + self.b_aiflags = 0; + } + else + { + if (targ.classname == "item_artifact_invisibility") + if (self.items & 524288) + bot_start_topic(3); + + if (targ.flags & FL_ITEM) + { + if (targ.model == string_null) + targ._last = world; + else + targ._last = self; + } + } + + + if (targ.classname != "player") + targ.search_time = time + 5; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_check_lost + +decide if my most immediate target should be +removed. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(entity targ) bot_check_lost = +{ + local vector dist; + dist = realorigin(targ) - self.origin; + dist_z = 0; + if (targ == world) + return; + + // waypoints and items are lost if you get close enough to them + + else if (targ.flags & FL_ITEM) + { + if (vlen(targ.origin - self.origin) < 32) + bot_lost(targ, TRUE); + else if (targ.model == string_null) + bot_lost(targ, TRUE); + } + else if (targ.classname == "waypoint") + { + if (!(self.b_aiflags & (AI_SNIPER | AI_AMBUSH))) + { + if (self.b_aiflags & AI_RIDE_TRAIN) + { + if (vlen(targ.origin - self.origin) < 48) + bot_lost(targ, TRUE); + } + else if (self.b_aiflags & AI_PRECISION) + { + if (vlen(targ.origin - self.origin) < 24) + bot_lost(targ, TRUE); + } + else if (vlen(targ.origin - self.origin) < 32) + bot_lost(targ, TRUE); + } + } + else if (targ.classname == "temp_waypoint") + { + if (vlen(targ.origin - self.origin) < 32) + bot_lost(targ, TRUE); + } + else if (targ.classname == "player") + { + if (targ.health <= 0) + bot_lost(targ, TRUE); + else if ((coop) || (teamplay && targ.team == self.team)) + { + if (targ.target1.classname == "player") + { + if (!targ.target1.ishuman) + bot_lost(targ, TRUE); + } + else if (targ.teleport_time > time) + { + // try not to telefrag teammates + self.keys = self.keys & 960; + } + else if (vlen(targ.origin - self.origin) < 128) + { + if (vlen(targ.origin - self.origin) < 48) + frik_walkmove(self.origin - targ.origin); + else + { + self.keys = self.keys & 960; + bot_start_topic(4); + } + self.search_time = time + 5; // never time out + } + else if (!fisible(targ)) + bot_lost(targ, FALSE); + } + else if (waypoint_mode > WM_LOADED) + { + if (vlen(targ.origin - self.origin) < 128) + { + bot_lost(targ, TRUE); + } + } + } + + // buttons are lost of their frame changes + else if (targ.classname == "func_button") + { + if (targ.frame) + { + bot_lost(targ, TRUE); + if (self.enemy == targ) + self.enemy = world; + //if (self.target1) + // bot_get_path(self.target1, TRUE); + + } + } + // trigger_multiple style triggers are lost if their thinktime changes + else if ((targ.movetype == MOVETYPE_NONE) && (targ.solid == SOLID_TRIGGER)) + { + if (targ.nextthink >= time) + { + bot_lost(targ, TRUE); + //if (self.target1) + // bot_get_path(self.target1, TRUE); + } + } + // lose any target way above the bot's head + // FIXME: if the bot can fly in your mod.. + if ((targ.origin_z - self.origin_z) > 64) + { + dist = targ.origin - self.origin; + dist_z = 0; + if (vlen(dist) < 32) + if (self.flags & FL_ONGROUND) + if(!frik_recognize_plat(FALSE)) + bot_lost(targ, FALSE); + } + else if (targ.classname == "train") + { + if (frik_recognize_plat(FALSE)) + bot_lost(targ, TRUE); + } + // targets are lost if the bot's search time has expired + if (time > self.search_time) + bot_lost(targ, FALSE); +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_handle_ai + +This is a 0.10 addition. Handles any action +based b_aiflags. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_handle_ai = +{ + local entity newt; + local vector v; + + // handle ai flags -- note, not all aiflags are handled + // here, just those that perform some sort of action + + // wait is used by the ai to stop the bot until his search time expires / or route changes + + if (self.b_aiflags & AI_WAIT) + self.keys = self.keys & 960; + + if (self.b_aiflags & AI_DOORFLAG) // was on a door when spawned + { + b_temp3 = self; + self = self.last_way; + if (!frik_recognize_plat(FALSE)) // if there is nothing there now + { + newt = FindThing("door"); // this is likely the door responsible (crossfingers) + self = b_temp3; + + if (self.b_aiflags & AI_DOOR_NO_OPEN) + { + if (newt.nextthink) + self.keys = self.keys & 960; // wait until it closes + else + { + bot_lost(self.last_way, FALSE); + } + } + else + { + if (newt.targetname) + { + newt = find(world, target, newt.targetname); + if (newt.health > 0) + { + self.enemy = newt; + bot_weapon_switch(1); + } + else + { + // target_drop(self.last_way); + target_add(newt); + // bot_get_path(newt, TRUE); + } + } + self.b_aiflags = self.b_aiflags - AI_DOORFLAG; + } + } + else + self = b_temp3; + } + + if (self.b_aiflags & AI_JUMP) + { + if (self.flags & FL_ONGROUND) + { + bot_jump(); + self.b_aiflags = self.b_aiflags - AI_JUMP; + } + } + else if (self.b_aiflags & AI_SUPER_JUMP) + { + if (self.weapon != 32) + self.impulse = 7; + else if (self.flags & FL_ONGROUND) + { + self.b_aiflags = self.b_aiflags - AI_SUPER_JUMP; + if (bot_can_rj(self)) + { + bot_jump(); + self.v_angle_x = self.b_angle_x = 80; + self.button0 = TRUE; + } + else + bot_lost(self.target1, FALSE); + + } + } + if (self.b_aiflags & AI_SURFACE) + { + if (self.waterlevel > 2) + { + self.keys = KEY_MOVEUP; + self.button2 = TRUE; // swim! + } + else + self.b_aiflags = self.b_aiflags - AI_SURFACE; + } + if (self.b_aiflags & AI_RIDE_TRAIN) + { + // simple, but effective + // this can probably be used for a lot of different + // things, not just trains (door elevators come to mind) + b_temp3 = self; + self = self.last_way; + + if (!frik_recognize_plat(FALSE)) // if there is nothing there now + { + self = b_temp3; + self.keys = self.keys & 960; + } + else + { + self = b_temp3; + if (frik_recognize_plat(FALSE)) + { + v = realorigin(trace_ent) + trace_ent.origin - self.origin; + v_z = 0; + if (vlen(v) < 24) + self.keys = self.keys & 960; + else + { + self.b_aiflags = self.b_aiflags | AI_PRECISION; + self.keys = frik_KeysForDir(v); + } + } + } + } + if (self.b_aiflags & AI_PLAT_BOTTOM) + { + newt = FindThing("plat"); + if (newt.state != 1) + { + v = self.origin - realorigin(newt); + v_z = 0; + if (vlen(v) > 96) + self.keys = self.keys & 960; + else + frik_walkmove(v); + } + else + self.b_aiflags = self.b_aiflags - AI_PLAT_BOTTOM; + } + if (self.b_aiflags & AI_DIRECTIONAL) + { + if ((normalize(self.last_way.origin - self.origin) * self.b_dir) > 0.4) + { + self.b_aiflags = self.b_aiflags - AI_DIRECTIONAL; + bot_lost(self.target1, TRUE); + } + } + if (self.b_aiflags & AI_SNIPER) + { + self.b_aiflags = (self.b_aiflags | AI_WAIT | AI_PRECISION) - AI_SNIPER; + // FIXME: Add a switch to wep command + // FIXME: increase delay? + } + if (self.b_aiflags & AI_AMBUSH) + { + self.b_aiflags = (self.b_aiflags | AI_WAIT) - AI_AMBUSH; + // FIXME: Add a switch to wep command + // FIXME: increase delay? + } + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_path + +Bot will follow a route generated by the +begin_route set of functions in bot_way.qc. +This code, while it works pretty well, can get +confused + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_path = +{ + + local entity jj, tele; + + bot_check_lost(self.target1); + if (!self.target1) + { + self.keys=0; + return; + } + if (target_onstack(self.last_way)) + return; // old waypoint still being hunted + + jj = FindRoute(self.last_way); + if (!jj) + { + // this is an ugly hack + if (self.target1.current_way != self.last_way) + { + if (self.target1.classname != "temp_waypoint") + if (self.target1.classname != "player") + bot_lost(self.target1, FALSE); + } + + return; + } + + // update the bot's special ai features + + // Readahed types are AI conditions to perform while heading to a waypoint + // point types are AI flags that should be executed once reaching a waypoint + + self.b_aiflags = (jj.b_aiflags & AI_READAHEAD_TYPES) | (self.last_way.b_aiflags & AI_POINT_TYPES); + target_add(jj); + if (self.last_way) + { + if (CheckLinked(self.last_way, jj) == 2) // waypoints are telelinked + { + tele = FindThing("trigger_teleport"); // this is probbly the teleport responsible + target_add(tele); + } + traceline(self.last_way.origin, jj.origin, FALSE, self); // check for blockage + if (trace_fraction != 1) + { + if (trace_ent.classname == "door" && !(self.b_aiflags & AI_DOOR_NO_OPEN)) // a door blocks the way + { + // linked doors fix + if (trace_ent.owner) + trace_ent = trace_ent.owner; + if ((trace_ent.health > 0) && (self.enemy == world)) + { + self.enemy = trace_ent; + bot_weapon_switch(1); + self.b_aiflags = self.b_aiflags | AI_BLIND; // nick knack paddy hack + } + else if (trace_ent.targetname) + { + tele = find(world, target, trace_ent.targetname); + if (tele.health > 0) + { + self.enemy = tele; + bot_weapon_switch(1); + } + else + { + // target_drop(jj); + target_add(tele); + // bot_get_path(tele, TRUE); + self.b_aiflags = self.b_aiflags | AI_BLIND; // give a bot a bone + return; + } + } + } + else if (trace_ent.classname == "func_wall") + { + // give up + bot_lost(self.target1, FALSE); + return; + } + } + } + // this is used for AI_DRIECTIONAL + self.b_dir = normalize(jj.origin - self.last_way.origin); + + self.last_way = jj; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Priority Look. What a stupid name. This is where +the bot finds things it wants to kill/grab. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +// priority scale +// 0 - 10 virtually ignore +// 10 - 30 normal item range +// 30 - 50 bot will consider this a target worth changing course for +// 50 - 90 bot will hunt these as vital items + +// *!* Make sure you add code to bot_check_lost to remove the target *!* + +float(entity thing) priority_for_thing = +{ + local float thisp; + thisp = 0; + // This is the most executed function in the bot. Careful what you do here. + + if ((thing.flags & FL_ITEM) && thing.model != string_null && thing.search_time < time) + { + // ugly hack + if (thing._last != self) + thisp = 20; + if (thing.classname == "item_artifact_super_damage") + thisp = 65; + else if (thing.classname == "item_artifact_invulnerability") + thisp = 65; +else if (thing.classname == "weapon_skull") +thisp = 90; + else if (thing.classname == "item_health") + { + if (thing.spawnflags & 2) + thisp = 55; + if (self.health < 40) + thisp = thisp + 50; + } + else if (thing.model == "progs/armor.mdl") + { + if (self.armorvalue < 200) + { + if (thing.skin == 2) + thisp = 60; + else if (self.armorvalue < 100) + thisp = thisp + 25; + } + } + else if (thing.classname == "weapon_pickup") + { + if (!(self.items & thing.weapon)) { // bot weapon pickup is handled in weapon_pickup + //_bprint("SEEK ME WEAPON 2\n"); + thisp = 75; + } + } + else if (thing.classname == "weapon_supershotgun") + { + if (!(self.items & 2)) // IT_SUPER_SHOTGUN + thisp = 25; + } + else if (thing.classname == "weapon_nailgun") + { + if (!(self.items & 4)) // IT_NAILGUN + thisp = 30; + } + else if (thing.classname == "weapon_supernailgun") + { + if (!(self.items & 8)) // IT_SUPER_NAILGUN + thisp = 35; + } + else if (thing.classname == "weapon_grenadelauncher") + { + if (!(self.items & 16)) // IT_GRENADE_LAUNCHER + thisp = 45; + } + else if (thing.classname == "weapon_rocketlauncher") + { + if (!(self.items & 32)) // IT_ROCKET_LAUNCHER + thisp = 60; + } + else if (thing.classname == "weapon_lightning") + { + if (!(self.items & 64)) // IT_LIGHTNING + thisp = 50; + } +else if (thing.classname == "weapon_skull") + { + if (!(self.items & thing.weapon))// IT_SKULL + thisp = 90; + } + } + else if ((thing.flags & FL_MONSTER) && thing.health > 0) + thisp = 45; + else if (thing.classname == "player") + { + if (thing.health > 0) + { + if (thing == self) + return 0; + else + { + if (thing.items & IT_INVISIBILITY) //FIXME + thisp = 2; + else if (coop) + { + thisp = 200; + if (thing.target1.classname == "player") + if (!thing.target1.ishuman) + return 0; + } + else if (teamplay && thing.team == self.team) + { + thisp = 100; + if (thing.target1.classname == "player") + return 0; + } + else thisp = 30; + } + } + } + else if (thing.classname == "waypoint") + { + if (thing.b_aiflags & AI_SNIPER) + thisp = 30; + else if (thing.b_aiflags & AI_AMBUSH) + thisp = 30; + } + if (pointcontents(thing.origin) < -3) + return 0; + if (thisp) + { + if (thing.current_way) + { + // check to see if it's unreachable + if (thing.current_way.items == -1) + return 0; + else + thisp = thisp + (13000 - thing.current_way.items) * 0.05; + } + } + return thisp; +}; + +void(float scope) bot_look_for_crap = +{ + local entity foe, best; + local float thatp, bestp, dist; + + if (scope == 1) + foe = findradius(self.origin, 13000); + else + foe = findradius(self.origin, 500); + + bestp = 1; + while(foe) + { + thatp = priority_for_thing(foe); + if (thatp) + if (!scope) + if (!sisible(foe)) + thatp = 0; + if (thatp > bestp) + { + bestp = thatp; + best = foe; + dist = vlen(self.origin - foe.origin); + } + foe = foe.chain; + } + if (best == world) + return; + if (!target_onstack(best)) + { + target_add(best); + if (scope) + { + bot_get_path(best, FALSE); + self.b_aiflags = self.b_aiflags | AI_WAIT; + } + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_angle_set + +Sets the bots look keys & b_angle to point at +the target - used for fighting and just +generally making the bot look good. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_angle_set = +{ + local float h; + local vector view; + + if (self.enemy) + { + if (self.enemy.items & 524288) + if (random() > 0.01) + return; + if (self.missile_speed == 0) + self.missile_speed = 10000; + if (self.enemy.solid == SOLID_BSP) + { + view = (((self.enemy.absmin + self.enemy.absmax) * 0.5) - self.origin); + } + else + { + + local float levels; + + levels = 3; + + view = self.enemy.origin; + + while (levels) + { + h = vlen(view - self.origin) / self.missile_speed; + if (self.enemy.flags & FL_ONGROUND) + view = self.enemy.velocity * h + '0 0 -20'; + else + view = (self.enemy.velocity - (sv_gravity * '0 0 1') * h) * h; + view = self.enemy.origin + view; + traceline(self.enemy.origin, view, FALSE, self); + view = trace_endpos; + levels = levels - 1; + } + view = normalize(view - self.origin); + } + view = vectoangles(view); + view_x = view_x * -1; + self.b_angle = view; + } + else if (self.target1) + { + view = realorigin(self.target1); + if (self.target1.flags & FL_ITEM) + view = view + '0 0 48'; + view = view - (self.origin + self.view_ofs); + view = vectoangles(view); + view_x = view_x * -1; + self.b_angle = view; + } + else + self.b_angle_x = 0; + // HACK HACK HACK HACK + // The bot falls off ledges a lot because of "turning around" + // so let the bot use instant turn around when not hunting a player + if (self.b_skill == 3) + { + self.keys = self.keys & 63; + self.v_angle = self.b_angle; + while (self.v_angle_x < -180) + self.v_angle_x = self.v_angle_x + 360; + while (self.v_angle_x > 180) + self.v_angle_x = self.v_angle_x - 360; + + } + else if ((self.enemy == world || self.enemy.movetype == MOVETYPE_PUSH) && self.target1.classname != "player") + { + self.keys = self.keys & 63; + self.v_angle = self.b_angle; + while (self.v_angle_x < -180) + self.v_angle_x = self.v_angle_x + 360; + while (self.v_angle_x > 180) + self.v_angle_x = self.v_angle_x - 360; + } + else if (self.b_skill < 2) // skill 2 handled in bot_phys + { + if (self.b_angle_x > 180) + self.b_angle_x = self.b_angle_x - 360; + self.keys = self.keys & 63; + + if (angcomp(self.b_angle_y, self.v_angle_y) > 10) + self.keys = self.keys | KEY_LOOKLEFT; + else if (angcomp(self.b_angle_y, self.v_angle_y) < -10) + self.keys = self.keys | KEY_LOOKRIGHT; + if (angcomp(self.b_angle_x, self.v_angle_x) < -10) + self.keys = self.keys | KEY_LOOKUP; + else if (angcomp(self.b_angle_x, self.v_angle_x) > 10) + self.keys = self.keys | KEY_LOOKDOWN; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotAI + +This is the main ai loop. Though called every +frame, the ai_time limits it's actual updating + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float stagger_think; + +void() BotAI = +{ + // am I dead? Fire randomly until I respawn + // health < 1 is used because fractional healths show up as 0 on normal player + // status bars, and the mod probably already compensated for that + + if (self.health < 1) + { + self.button0 = floor(random() * 2); + self.button2 = 0; + self.keys = 0; + self.b_aiflags = 0; + ClearMyRoute(); + self.target1 = self.target2 = self.target3 = self.target4 = self.enemy = world; + self.last_way = world; + return; + } + + // stagger the bot's AI out so they all don't think at the same time, causing game + // 'spikes' + if (self.b_skill < 2) + { + if (self.ai_time > time) + return; + + self.ai_time = time + 0.05; + if (bot_count > 0) + { + if ((time - stagger_think) < (0.1 / bot_count)) + self.ai_time = self.ai_time + 0.1 / (2 * bot_count); + } + else + return; + } + if (self.view_ofs == '0 0 0') + bot_start_topic(7); + stagger_think = time; + + // shut the bot's buttons off, various functions will turn them on by AI end + + self.button2 = 0; + self.button0 = 0; + + + // target1 is like goalentity in normal Quake monster AI. + // it's the bot's most immediate target + if (route_table == self) + { + if (busy_waypoints <= 0) + { + if (waypoint_mode < WM_EDITOR) + bot_look_for_crap(TRUE); + } + self.b_aiflags = 0; + self.keys = 0; + } + else if (self.target1) + { + frik_movetogoal(); + bot_path(); + } + else + { + if (waypoint_mode < WM_EDITOR) + { + if(self.route_failed) + { + if (waypoint_mode == WM_DYNAMIC) + frik_bot_roam(); + else + self.keys = 0; + self.route_failed = 0; + } + else if(!begin_route()) + { + bot_look_for_crap(FALSE); + self.keys = 0; + } + + } + else + { + self.b_aiflags = AI_WAIT; + self.keys = 0; + } + } + + // bot_angle_set points the bot at it's goal (self.enemy or target1) + + bot_angle_set(); + + // fight my enemy. Enemy is probably a field QC coders will most likely use a lot + // for their own needs, since it's unused on a normal player + // FIXME + if (self.enemy) + bot_fight_style(); + else if (random() < 0.2) + if (random() < 0.2) + bot_weapon_switch(-1); + bot_dodge_stuff(); + + // checks to see if bot needs to start going up for air + if (self.waterlevel > 2) + { + if (time > (self.air_finished - 2)) + { + traceline (self.origin, self.origin + '0 0 6800', TRUE, self); + if (trace_inopen) + { + self.keys = KEY_MOVEUP; + self.button2 = TRUE; // swim! + return; // skip ai flags for now - this is life or death + } + } + } + + // b_aiflags handling + + + if (self.b_aiflags) + bot_handle_ai(); + else + bot_chat(); // don't want chat to screw him up if he's rjing or something +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_ed.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_ed.qc new file mode 100755 index 00000000..fb2c84a6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_ed.qc @@ -0,0 +1,1638 @@ +/*********************************************** +* * +* FrikBot Waypoint Editor * +* "The 'wtf is this doing in my mod' code" * +* * +***********************************************/ + +/* + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + +float saved1, saved2, saved3, scratch1, scratch2, scratch3, scratch4; +float bytecounter, filecount; + +float MENU_MAIN = 1; +float MENU_WAYPOINTS = 2; +float MENU_LINKS = 3; +float MENU_FLAGS = 4; +float MENU_FLAGS2 = 5; +float MENU_BOTS = 6; +float MENU_WAYLIST = 7; +// 8 = link way +// 9 = telelink way +// 10 = delete link +// 11 = create link X2 +// 12 = delete link x2 +// 13 = confirmation of delete all +// 14 = Teleport to way +// 15 = confirmation of delete point + +void() BSPDumpWaypoints; +void() QCDumpWaypoints; +void() DumpWaypoints; +void() SaveWays; +/* +// source for the menu strings... + +\b-- Main Menu --\b\n +\[\1\] >>Waypoint Management\n +\[\2\] >>Link Management \n +\[\3\] >>AI Flag Management \n +\[\4\] >>Bot Management \n +\[\5\] >>Waylist Management \n +\[\6\] \[\{133}\] Noclip \n +\[\7\] \[\{133}\] Godmode \n +\[\8\] \[\{133}\] Hold Select \n +\[\9\] Teleport to Way # \n +\[\0\] Close Menu \n + +// missing from main is show way info +// iffy on the teleport to way thing being on main...seems like either a bot or way list thing + +\b-- Waypoint Management --\b\n +\[\1\] Move Waypoint \n +\[\2\] Delete Waypoint \n +\[\3\] Make Waypoint \n +\[\4\] Make Way + Link \n +\[\5\] Make Way + Link X2 \n +\[\6\] Make Way + Telelink \n +\[\7\] Show waypoint info \n +\[\8\] >>Link Management \n +\[\9\] >>AI Flag Management \n +\[\0\] >>Main Menu \n + +\b-- Link Management --\b\n +\[\1\] Unlink Waypoint \n +\[\2\] Create Link \n +\[\3\] Create Telelink \n +\[\4\] Delete Link \n +\[\5\] Create Link X2 \n +\[\6\] Delete Link X2 \n +\[\7\] >Make Waypoint \n +\[\8\] >>Waypoint Management\n +\[\9\] >>AI Flag Management \n +\[\0\] >>Main Menu \n + +// Ai flags...ugh + +\b-- AI Flag Management --\b\n +\[\1\] \[\{133}\] Door Flag \n +\[\2\] \[\{133}\] Precision \n +\[\3\] \[\{133}\] Surface for air \n +\[\4\] \[\{133}\] Blind mode \n +\[\5\] \[\{133}\] Jump \n +\[\6\] \[\{133}\] Directional \n +\[\7\] \[\{133}\] Super Jump \n +\n +\[\9\] >>AI Flags page 2 \n +\[\0\] >>Main Menu \n + +\b-- AI Flags pg. 2--\b\n +\[\1\] \[\{133}\] Difficult \n +\[\2\] \[\{133}\] Wait for plat \n +\[\3\] \[\{133}\] Ride train \n +\[\4\] \[\{133}\] Door flag no open\n +\[\5\] \[\{133}\] Ambush \n +\[\6\] \[\{133}\] Snipe \n +\[\7\] \[\{133}\] Trace Test \n +\n +\[\9\] >>AI Flag Management \n +\[\0\] >>Main Menu \n + +\b-- Bot Management --\b\n +\[\1\] Add a Test Bot \n +\[\2\] Order Test Bot here \n +\[\3\] Remove Test Bot \n +\[\4\] Stop Test Bot \n +\[\5\] Teleport Bot here \n +\[\6\] Teleport to Way # \n +\n +\n +\n +\[\0\] >>Main Menu \n + +\b-- Waylist Management --\b\n +\[\1\] Delete ALL Waypoints \n +\[\2\] Dump Waypoints \n +\[\3\] Check For Errors \n +\[\4\] Save Waypoints \n +\[\5\] \[\{133}\] Dynamic Mode \n +\[\6\] \[\{133}\] Dynamic Link \n +\[\7\] \[\{133}\] WAY output \n +\[\8\] \[\{133}\] QC output \n +\[\9\] \[\{133}\] BSP ents output \n +\[\0\] Main Menu \n + +\b-- Misc Commands --\b\n +\[\1\] Teleport to Selected \n +\[\2\] Select \n +\[\3\] Swap to old \n +\[\4\] Trace select \n +\[\5\] Create way in path \n +\[\6\] Delete Way from path \n + + +\b-- Editor Memory --\b\n +\[\1\] Store as slot 1 \n +\[\2\] Store as slot 2 \n +\[\3\] Store as slot 3 \n +\[\4\] Store as slot 4 \n +\[\5\] Recall slot 1 \n +\[\6\] Recall slot 2 \n +\[\7\] Recall slot 3 \n +\[\8\] Recall slot 4 \n + +*/ + +void() bot_menu_display = +{ +// build options + local string s1, s2, s3, s4, s5, s6, s7, h; + local entity t; + +// check impulses + if (self.impulse > 0 && self.impulse < 11 && self.b_menu) + { + if (self.b_menu == MENU_MAIN) + { + if (self.impulse == 1) + { + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + else if (self.impulse == 3) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 4) + { + self.b_menu = MENU_BOTS; + self.b_menu_time = time; + } + else if (self.impulse == 5) + { + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + else if (self.impulse == 6) + { + if (self.movetype == MOVETYPE_NOCLIP) + self.movetype = MOVETYPE_WALK; + else + self.movetype = MOVETYPE_NOCLIP; + self.b_menu_time = time; + + } + else if (self.impulse == 7) + { + if (self.flags & FL_GODMODE) + self.flags = self.flags - FL_GODMODE; + else + self.flags = self.flags | FL_GODMODE; + self.b_menu_time = time; + + } + else if (self.impulse == 8) + { + if (self.b_aiflags & AI_HOLD_SELECT) + self.b_aiflags = self.b_aiflags - AI_HOLD_SELECT; + else + self.b_aiflags = self.b_aiflags | AI_HOLD_SELECT; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + self.b_menu = 14; + self.b_menu_time = time; + } + else if (self.impulse == 10) + bot_way_edit(); + } + else if (self.b_menu == MENU_WAYPOINTS) + { + if (self.impulse == 1) + { + if (self.current_way) + setorigin(self.current_way, self.origin + self.view_ofs); + } + else if (self.impulse == 2) + { + if (self.current_way) + { + self.b_menu = 15; + self.b_menu_time = time; + self.last_way = self.current_way; + } + } + else if (self.impulse == 3) + { + make_waypoint(self.origin + self.view_ofs); + } + else if (self.impulse == 4) + { + t = make_waypoint(self.origin + self.view_ofs); + if (!LinkWays(self.current_way, t)) + sprint(self, "Unable to link them\n"); + } + else if (self.impulse == 5) + { + t = make_waypoint(self.origin + self.view_ofs); + if (!LinkWays(self.current_way, t)) + sprint(self, "Unable to link old to new\n"); + LinkWays(t, self.current_way); + } + else if (self.impulse == 6) + { + t = make_waypoint(self.origin + self.view_ofs); + if (!TeleLinkWays(self.current_way, t)) + sprint(self, "Unable to link them\n"); + } + else if (self.impulse == 7) + { + if (self.current_way) + { + sprint(self, "\nwaypoint info for waypoint #"); + h = ftos(self.current_way.count); + sprint(self, h); + sprint(self, "\nAI Flag value: "); + h = ftos(self.current_way.b_aiflags); + sprint(self, h); + + if (self.current_way.target1) + { + h = ftos(self.current_way.target1.count); + if (self.current_way.b_aiflags & AI_TELELINK_1) + sprint(self, "\nTelelink1 to:"); + else + sprint(self, "\nLink1 to:"); + sprint(self, h); + } + if (self.current_way.target2) + { + h = ftos(self.current_way.target2.count); + if (self.current_way.b_aiflags & AI_TELELINK_2) + sprint(self, "\nTelelink2 to:"); + else + sprint(self, "\nLink2 to:"); + sprint(self, h); + } + if (self.current_way.target3) + { + h = ftos(self.current_way.target3.count); + if (self.current_way.b_aiflags & AI_TELELINK_3) + sprint(self, "\nTelelink3 to:"); + else + sprint(self, "\nLink3 to:"); + sprint(self, h); + } + if (self.current_way.target4) + { + h = ftos(self.current_way.target4.count); + if (self.current_way.b_aiflags & AI_TELELINK_4) + sprint(self, "\nTelelink4 to:"); + else + sprint(self, "\nLink4 to:"); + sprint(self, h); + } + sprint(self, "\n\n"); + } + + } + if (self.impulse == 8) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_LINKS) + { + if (self.impulse == 1) + { + self.b_menu = 16; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 2) + { + self.b_menu = 8; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 3) + { + self.b_menu = 9; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 4) + { + self.b_menu = 10; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 5) + { + self.b_menu = 11; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 6) + { + self.b_menu = 12; + self.b_menu_time = time; + self.last_way = self.current_way; + } + else if (self.impulse == 7) + make_waypoint(self.origin + self.view_ofs); + else if (self.impulse == 8) + { + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_FLAGS) + { + + if (self.current_way) + { + if (self.impulse == 1) + { + if (self.current_way.b_aiflags & AI_DOORFLAG) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DOORFLAG); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DOORFLAG; + + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + if (self.current_way.b_aiflags & AI_PRECISION) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_PRECISION); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_PRECISION; + self.b_menu_time = time; + } + else if (self.impulse == 3) + { + if (self.current_way.b_aiflags & AI_SURFACE) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_SURFACE); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_SURFACE; + self.b_menu_time = time; + } + else if (self.impulse == 4) + { + if (self.current_way.b_aiflags & AI_BLIND) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_BLIND); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_BLIND; + self.b_menu_time = time; + } + else if (self.impulse == 5) + { + if (self.current_way.b_aiflags & AI_JUMP) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_JUMP); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_JUMP; + self.b_menu_time = time; + } + else if (self.impulse == 6) + { + if (self.current_way.b_aiflags & AI_DIRECTIONAL) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DIRECTIONAL); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DIRECTIONAL; + self.b_menu_time = time; + } + else if (self.impulse == 7) + { + if (self.current_way.b_aiflags & AI_SUPER_JUMP) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_SUPER_JUMP); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_SUPER_JUMP; + self.b_menu_time = time; + } + } + if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS2; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_FLAGS2) + { + + if (self.current_way) + { + if (self.impulse == 1) + { + if (self.current_way.b_aiflags & AI_DIFFICULT) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DIFFICULT); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DIFFICULT; self.b_menu_time = time; + } + else if (self.impulse == 2) + { + if (self.current_way.b_aiflags & AI_PLAT_BOTTOM) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_PLAT_BOTTOM); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_PLAT_BOTTOM; + self.b_menu_time = time; + } + else if (self.impulse == 3) + { + if (self.current_way.b_aiflags & AI_RIDE_TRAIN) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_RIDE_TRAIN); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_RIDE_TRAIN; + self.b_menu_time = time; + } + else if (self.impulse == 4) + { + if (self.current_way.b_aiflags & AI_DOOR_NO_OPEN) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_DOOR_NO_OPEN); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_DOOR_NO_OPEN; + self.b_menu_time = time; + } + else if (self.impulse == 5) + { + if (self.current_way.b_aiflags & AI_AMBUSH) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_AMBUSH); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_AMBUSH; + self.b_menu_time = time; + } + else if (self.impulse == 6) + { + if (self.current_way.b_aiflags & AI_SNIPER) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_SNIPER); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_SNIPER; + self.b_menu_time = time; + } + else if (self.impulse == 7) + { + if (self.current_way.b_aiflags & AI_TRACE_TEST) + self.current_way.b_aiflags = self.current_way.b_aiflags - (self.current_way.b_aiflags & AI_TRACE_TEST); + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_TRACE_TEST; + self.b_menu_time = time; + } + + } + if (self.impulse == 9) + { + self.b_menu = MENU_FLAGS; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + + else if (self.b_menu == MENU_BOTS) + { + if (self.impulse == 1) + { + self.impulse = 100; + return; + } + else if (self.impulse == 2) + { + b_temp3 = self; + self = player_head; + while(self) + { + if (!self.ishuman) + { + target_add(b_temp3); + bot_get_path(b_temp3, TRUE); + self = world; + } + else + self = self._next; + } + self = b_temp3; + } + else if (self.impulse == 3) + { + self.impulse = 102; + return; + } + else if (self.impulse == 4) + { + b_temp1 = self; + self = player_head; + while(self) + { + if (!self.ishuman) + { + self.target1 = self.target2 = self.target3 = self.target4 = world; + route_table = world; + } + self = self._next; + } + self = b_temp1; + } + else if (self.impulse == 5) + { + if (self.current_way) + { + b_temp1 = self; + self = player_head; + while(self) + { + if (!self.ishuman) + { + setorigin(self, b_temp1.current_way.origin); + } + self = self._next; + } + self = b_temp1; + } + else + sprint(self, "select a waypoint first\n"); + } + else if (self.impulse == 6) + { + self.b_menu = 14; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == MENU_WAYLIST) + { + if (self.impulse == 1) + { + self.b_menu = 13; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + if (dump_mode == 0) + DumpWaypoints(); + else if (dump_mode == 1) + QCDumpWaypoints(); + else if (dump_mode == 2) + BSPDumpWaypoints(); + } + else if (self.impulse == 3) + { + t = way_head; + while(t) + { + if ((t.target1 == world) && (t.target2 == world) && (t.target3 == world) && (t.target4 == world)) + { + sprint(self, "Waypoint #"); + h = ftos(t.count); + sprint(self, h); + sprint(self, " has no outbound links\n"); + } + if ((t.target1 == t) || (t.target2 == t) || (t.target3 == t) || (t.target4 == t)) + { + sprint(self, "Waypoint #"); + h = ftos(t.count); + sprint(self, h); + sprint(self, " links to itself (??)\n"); + } + t = t._next; + } + sprint(self, "Error check complete\n"); + } + else if (self.impulse == 4) + { + // FIXME: detect engine feature and skip prompt + + self.b_menu = 17; + self.b_menu_time = time; + //SaveWays(); + } + else if (self.impulse == 5) + { + if (waypoint_mode == WM_EDITOR_DYNAMIC) + waypoint_mode = WM_EDITOR; + else + waypoint_mode = WM_EDITOR_DYNAMIC; + self.b_menu_time = time; + + } + else if (self.impulse == 6) + { + if (waypoint_mode == WM_EDITOR_DYNLINK) + waypoint_mode = WM_EDITOR; + else + waypoint_mode = WM_EDITOR_DYNLINK; + self.b_menu_time = time; + } + else if (self.impulse == 7) + { + dump_mode = 0; + self.b_menu_time = time; + } + else if (self.impulse == 8) + { + dump_mode = 1; + self.b_menu_time = time; + } + else if (self.impulse == 9) + { + dump_mode = 2; + self.b_menu_time = time; + } + else if (self.impulse == 10) + { + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + } + else if (self.b_menu == 8) + { + if (self.impulse == 1) + { + if (self.current_way) + { + if (!LinkWays(self.last_way, self.current_way)) + sprint(self, "Unable to link them\n"); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 9) + { + if (self.impulse == 1) + { + if (self.current_way) + { + if (!TeleLinkWays(self.last_way, self.current_way)) + sprint(self, "Unable to link them\n"); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 10) + { + if (self.impulse == 1) + { + if (self.current_way) + { + UnlinkWays(self.last_way, self.current_way); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 11) + { + if (self.impulse == 1) + { + if (self.current_way) + { + if (!LinkWays(self.last_way, self.current_way)) + sprint(self, "Unable to link 1 to 2\n"); + if (!LinkWays(self.current_way, self.last_way)) + sprint(self, "Unable to link 2 to 1\n"); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 12) + { + if (self.impulse == 1) + { + if (self.current_way) + { + UnlinkWays(self.last_way, self.current_way); + UnlinkWays(self.current_way, self.last_way); + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 13) + { + if (self.impulse == 1) + { + ClearAllWays(); + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + } + else if (self.b_menu == 14) + { + if (self.impulse == 10) + self.impulse = 0; + self.b_menu_value = self.b_menu_value * 10 + self.impulse; + self.b_menu_time = 0; + } + else if (self.b_menu == 15) + { + if (self.impulse == 1) + { + delete_waypoint(self.last_way); + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_WAYPOINTS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 16) + { + if (self.impulse == 1) + { + if (self.last_way) + { + self.last_way.target1 = self.last_way.target2 = self.last_way.target3 = self.last_way.target4 = world; + self.last_way.b_aiflags = self.last_way.b_aiflags - (self.last_way.b_aiflags & 15); + } + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + else if (self.impulse == 2) + { + self.b_menu = MENU_LINKS; + self.b_menu_time = time; + } + } + else if (self.b_menu == 17) + { + + if (self.impulse == 1) + SaveWays(); + if (self.impulse < 3) + { + self.b_menu = MENU_WAYLIST; + self.b_menu_time = time; + } + } + self.impulse = 0; + } + if (self.b_menu_time <= time) + { + if (self.b_menu == MENU_MAIN) + { + s1 = "\b-- Main Menu --\b\n\[\1\] >>Waypoint Management\n\[\2\] >>Link Management \n\[\3\] >>AI Flag Management \n\[\4\] >>Bot Management \n\[\5\] >>Waylist Management \n"; + if (self.movetype == MOVETYPE_NOCLIP) + s2 = "\[\6\] \[\{133}\] Noclip \n"; + else + s2 = "\[\6\] \[ \] Noclip \n"; + + if (self.flags & FL_GODMODE) + s3 = "\[\7\] \[\{133}\] Godmode \n"; + else + s3 = "\[\7\] \[ \] Godmode \n"; + if (self.b_aiflags & AI_HOLD_SELECT) + s4 = "\[\8\] \[\{133}\] Hold Select \n"; + else + s4 = "\[\8\] \[ \] Hold Select \n"; + s5 = "\[\9\] Teleport to Way # \n\[\0\] Close Menu \n"; + } + else if (self.b_menu == MENU_WAYPOINTS) + { + s1 = "\b-- Waypoint Management --\b\n\[\1\] Move Waypoint \n\[\2\] Delete Waypoint \n\[\3\] Make Waypoint \n\[\4\] Make Way + Link \n\[\5\] Make Way + Link X2 \n\[\6\] Make Way + Telelink \n\[\7\] Show waypoint info \n\[\8\] >>Link Management \n\[\9\] >>AI Flag Management \n\[\0\] >>Main Menu \n"; + } + else if (self.b_menu == MENU_LINKS) + { + s1 = "\b-- Link Management --\b\n\[\1\] Unlink Waypoint \n\[\2\] Create Link \n\[\3\] Create Telelink \n\[\4\] Delete Link \n\[\5\] Create Link X2 \n\[\6\] Delete Link X2 \n\[\7\] >Make Waypoint \n\[\8\] >>Waypoint Management\n\[\9\] >>AI Flag Management \n\[\0\] >>Main Menu \n"; + } + else if (self.b_menu == MENU_FLAGS) + { + if (self.current_way.b_aiflags & AI_DOORFLAG) + s1 = "\b-- AI Flag Management --\b\n\[\1\] \[\{133}\] Door Flag \n"; + else + s1 = "\b-- AI Flag Management --\b\n\[\1\] \[ \] Door Flag \n"; + + if (self.current_way.b_aiflags & AI_PRECISION) + s2 = "\[\2\] \[\{133}\] Precision \n"; + else + s2 = "\[\2\] \[ \] Precision \n"; + + if (self.current_way.b_aiflags & AI_SURFACE) + s3 = "\[\3\] \[\{133}\] Surface for air \n"; + else + s3 = "\[\3\] \[ \] Surface for air \n"; + + if (self.current_way.b_aiflags & AI_BLIND) + s4 = "\[\4\] \[\{133}\] Blind mode \n"; + else + s4 = "\[\4\] \[ \] Blind mode \n"; + + if (self.current_way.b_aiflags & AI_JUMP) + s5 = "\[\5\] \[\{133}\] Jump \n"; + else + s5 = "\[\5\] \[ \] Jump \n"; + + if (self.current_way.b_aiflags & AI_DIRECTIONAL) + s6 = "\[\6\] \[\{133}\] Directional \n"; + else + s6 = "\[\6\] \[ \] Directional \n"; + + if (self.current_way.b_aiflags & AI_SUPER_JUMP) + s7 = "\[\7\] \[\{133}\] Super Jump \n\n\[\9\] >>AI Flags page 2 \n\[\0\] >>Main Menu \n"; + else + s7 = "\[\7\] \[ \] Super Jump \n\n\[\9\] >>AI Flags page 2 \n\[\0\] >>Main Menu \n"; + } + else if (self.b_menu == MENU_FLAGS2) + { + if (self.current_way.b_aiflags & AI_DIFFICULT) + s1 = "\b-- AI Flags pg. 2--\b\n\[\1\] \[\{133}\] Difficult \n"; + else + s1 = "\b-- AI Flags pg. 2--\b\n\[\1\] \[ \] Difficult \n"; + + if (self.current_way.b_aiflags & AI_PLAT_BOTTOM) + s2 = "\[\2\] \[\{133}\] Wait for plat \n"; + else + s2 = "\[\2\] \[ \] Wait for plat \n"; + + if (self.current_way.b_aiflags & AI_RIDE_TRAIN) + s3 = "\[\3\] \[\{133}\] Ride train \n"; + else + s3 = "\[\3\] \[ \] Ride train \n"; + + if (self.current_way.b_aiflags & AI_DOOR_NO_OPEN) + s4 = "\[\4\] \[\{133}\] Door flag no open\n"; + else + s4 = "\[\4\] \[ \] Door flag no open\n"; + + if (self.current_way.b_aiflags & AI_AMBUSH) + s5 = "\[\5\] \[\{133}\] Ambush \n"; + else + s5 = "\[\5\] \[ \] Ambush \n"; + + if (self.current_way.b_aiflags & AI_SNIPER) + s6 = "\[\6\] \[\{133}\] Snipe \n"; + else + s6 = "\[\6\] \[ \] Snipe \n"; + + if (self.current_way.b_aiflags & AI_TRACE_TEST) + s7 = "\[\7\] \[\{133}\] Trace Test \n\n\[\9\] >>AI Flag Management \n\[\0\] >>Main Menu \n"; + else + s7 = "\[\7\] \[ \] Trace Test \n\n\[\9\] >>AI Flag Management \n\[\0\] >>Main Menu \n"; + + } + else if (self.b_menu == MENU_BOTS) + { + s1 = "\b-- Bot Management --\b\n\[\1\] Add a Test Bot \n\[\2\] Order Test Bot here \n\[\3\] Remove Test Bot \n\[\4\] Stop Test Bot \n\[\5\] Teleport Bot here \n\[\6\] Teleport to Way # \n\n\n\n\[\0\] >>Main Menu \n"; + } + else if (self.b_menu == MENU_WAYLIST) + { + s1 = "\b-- Waylist Management --\b\n\[\1\] Delete ALL Waypoints \n\[\2\] Dump Waypoints \n\[\3\] Check For Errors \n\[\4\] Save Waypoints \n"; + + if (waypoint_mode == WM_EDITOR_DYNAMIC) + s2 = "\[\5\] \[\{133}\] Dynamic Mode \n\[\6\] \[\{133}\] Dynamic Link \n"; + else if (waypoint_mode == WM_EDITOR_DYNLINK) + s2 = "\[\5\] \[ \] Dynamic Mode \n\[\6\] \[\{133}\] Dynamic Link \n"; + else + s2 = "\[\5\] \[ \] Dynamic Mode \n\[\6\] \[ \] Dynamic Link \n"; + if (dump_mode == 0) + s3 = "\[\7\] \[\{133}\] WAY output \n\[\8\] \[ \] QC output \n\[\9\] \[ \] BSP ents output \n\[\0\] Main Menu \n"; + else if (dump_mode == 1) + s3 = "\[\7\] \[ \] WAY output \n\[\8\] \[\{133}\] QC output \n\[\9\] \[ \] BSP ents output \n\[\0\] Main Menu \n"; + else if (dump_mode == 2) + s3 = "\[\7\] \[ \] WAY output \n\[\8\] \[ \] QC output \n\[\9\] \[\{133}\] BSP ents output \n\[\0\] Main Menu \n"; + + } + else if (self.b_menu == 8) + s1 = "\b-- Link Ways --\b\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 9) + s1 = "\b-- Telelink Ways --\b\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 10) + s1 = "\b-- Delete Link --\b\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 11) + s1 = "\b-- Create Link X2 --\b\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 12) + s1 = "\b-- Delete Link X2 --\b\n\nSelect another way and push 1\nor press 2 to cancel"; + else if (self.b_menu == 13) + s1 = "\b-- Delete ALL Ways --\b\n\nAre you sure? Push 1 to go\nthrough with it, 2 to cancel"; + else if (self.b_menu == 14) + { + s1 = "\b-- Teleport to Way # --\b\n\nEnter way number and press\nimpulse 104 to warp\n\nWaypoint #"; + s2 = ftos(self.b_menu_value); + + } + else if (self.b_menu == 15) + s1 = "\b-- Delete Waypoint --\b\n\nAre you sure? Push 1 to go\nthrough with it, 2 to cancel"; + else if (self.b_menu == 16) + s1 = "\b-- Unlink Waypoint --\b\n\nAre you sure? Push 1 to go\nthrough with it, 2 to cancel"; + else if (self.b_menu == 17) + s1 = "\b-- Save Waypoints --\b\n\nSave Waypoints requires\nFrikaC's file access tutorial from\nwww.quakesrc.org to be present\n in the engine code.\n Push 1 to continue, 2 to cancel"; + + frik_big_centerprint(self, s1, s2, s3, s4, s5, s6, s7); + self.b_menu_time = time + 1.25; + } +}; + + +// engage menu +void() bot_way_edit = +{ + local entity t; + local float f; + if (self.b_menu_value) + { + if (self.b_menu == 14) + { + t = WaypointForNum(self.b_menu_value); + if (t) + setorigin(self, t.origin - self.view_ofs); + else + sprint(self, "No waypoint with that number\n"); + + self.b_menu = MENU_MAIN; + self.b_menu_time = time; + } + self.b_menu_value = 0; + return; + } + if (waypoint_mode < WM_EDITOR) + { + self.b_menu = MENU_MAIN; + waypoint_mode = WM_EDITOR; + self.b_menu_time = 0; + cvar_set("saved2", "0"); + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, "MAKE SURE THE FOLLOWING LINE CONTAINS -CONDEBUG BEFORE PROCEEDING\n"); + localcmd("cmdline\n"); + t = way_head; + while (t) + { + setmodel(t, "progs/s_bubble.spr"); // show the waypoints + t = t._next; + } + if (self.current_way) + setmodel(self.current_way, "progs/s_light.spr"); + } + else + { + saved2 = cvar("saved2"); + if (saved2 != 0) + { + f = self.b_menu; + self.b_menu = floor(saved2/16); + self.impulse = saved2 & 15; + bot_menu_display(); + if (self.b_menu == floor(saved2/16)) + self.b_menu = f; + cvar_set("saved2", "0"); + return; + } + self.b_menu = 0; + waypoint_mode = WM_LOADED; + t = way_head; + while (t) + { + setmodel(t, string_null); // hide the waypoints + t = t._next; + } + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Saving to file. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +// bytecount is really iffy +// since there is no true way to determine the length of an ftos +// it uses an approximate of 5 +// various other things are guesses, but I don't cut it at the absolute +// max so it should be okay + +void() PrintWaypoint = +{ + local entity t; + local float needcolon; + local string h; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + if (bytecounter >= 8000) + { + bprint("exec maps/"); + bprint(mapname); + bprint(".wa"); + h = ftos(filecount); + bprint(h); + filecount = filecount + 1; + bprint("\n// **** break here ****\n"); // 2001-09-10 FrikBot support by FrikaC/Maddes + bytecounter = 26; + } + if (t == world) + { + remove(self); + fixer = world; + bprint("saved4 3\n// end waypoint dump\n"); + bytecounter = bytecounter + 27; + return; + } +// 2001-09-10 FrikBot support by FrikaC/Maddes start + t.origin_x = rint(t.origin_x); + t.origin_y = rint(t.origin_y); + t.origin_z = rint(t.origin_z); +// 2001-09-10 FrikBot support by FrikaC/Maddes end + if ((t.origin_x != saved1) || (t.count == 1)) + { + bprint("saved1 "); + h = ftos(t.origin_x); + bprint(h); + saved1 = t.origin_x; + bytecounter = bytecounter + 12; + needcolon = TRUE; + } + if ((t.origin_y != saved2) || (t.count == 1)) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("saved2 "); + h = ftos(t.origin_y); + bprint(h); + bytecounter = bytecounter + 12; + saved2 = t.origin_y; + } + if ((t.origin_z != saved3) || (t.count == 1)) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("saved3 "); + h = ftos(t.origin_z); + bprint(h); + bytecounter = bytecounter + 12; + saved3 = t.origin_z; + } + if (needcolon) // 2001-09-10 FrikBot support by FrikaC/Maddes + { + bytecounter = bytecounter + 1; + bprint("\n"); + needcolon = FALSE; + } + if ((scratch1 != t.target1.count) || t.count == 1) + { + needcolon = TRUE; + bprint("scratch1 "); + bytecounter = bytecounter + 14; + h = ftos(t.target1.count); + bprint(h); + scratch1 = t.target1.count; + } + if ((scratch2 != t.target2.count) || t.count == 1) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("scratch2 "); + bytecounter = bytecounter + 14; + h = ftos(t.target2.count); + bprint(h); + scratch2 = t.target2.count; + } + if ((scratch3 != t.target3.count) || t.count == 1) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("scratch3 "); + bytecounter = bytecounter + 14; + h = ftos(t.target3.count); + bprint(h); + scratch3 = t.target3.count; + } + if ((scratch4 != t.target4.count) || t.count == 1) + { + if (needcolon) + { + bprint("; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + bprint("scratch4 "); + bytecounter = bytecounter + 14; + h = ftos(t.target4.count); + bprint(h); + scratch4 = t.target4.count; + } + if (needcolon) // 2001-09-10 FrikBot support by FrikaC/Maddes + { + bprint("\n"); + needcolon = FALSE; + } + bprint("saved4 "); + bytecounter = bytecounter + 19; + if (t.count != 1) + h = ftos(t.b_aiflags * 4 + 2); + else + h = ftos(t.b_aiflags * 4 + 1); + bprint(h); + bprint ("; wait\n"); + self.nextthink = time + 0.01; + self.enemy = t; +}; + +// to allow for 100+ waypoints, we need to trick the runaway loop counter +void() DumpWaypoints = +{ + bytecounter = 50; + filecount = 1; + + bprint("// "); + bprint(world.message); + bprint(" - maps/"); // 2001-09-10 FrikBot support by FrikaC/Maddes + bprint(mapname); + bprint(".way\n"); + bprint("// Ways by "); + bprint(self.netname); + bprint("\n"); + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = PrintWaypoint; + fixer.enemy = world; + } +}; + +void() PrintQCWaypoint = +{ + local entity t; + local string h; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + + if (t == world) + { + remove(self); + fixer = world; + bprint("};\n// End dump\n"); // 2001-09-10 FrikBot support by FrikaC/Maddes + return; + } + bprint(" make_way("); +// 2001-09-10 FrikBot support by FrikaC/Maddes start + t.origin_x = rint(t.origin_x); + t.origin_y = rint(t.origin_y); + t.origin_z = rint(t.origin_z); +// 2001-09-10 FrikBot support by FrikaC/Maddes end + h = vtos(t.origin); + bprint(h); + bprint(", '"); + h = ftos(t.target1.count); + bprint(h); + bprint(" "); + h = ftos(t.target2.count); + bprint(h); + bprint(" "); + h = ftos(t.target3.count); + bprint(h); + bprint("', "); + h = ftos(t.target4.count); + bprint(h); + bprint(", "); + h = ftos(t.b_aiflags); + bprint(h); + bprint(");\n"); + self.nextthink = time + 0.01; + self.enemy = t; + +}; + +void() QCDumpWaypoints = +{ + bprint("/* QC Waypoint Dump - src/frikbot/map_"); + + bprint(mapname); + bprint(".qc\nFor instructions please read the\nreadme.html that comes with FrikBot */\n\nvoid(vector org, vector bit1, float bit4, float flargs) make_way;\n"); + bprint("// Ways by "); + bprint(self.netname); + bprint("\n\n"); + + bprint("void() map_"); + bprint(mapname); + bprint(" =\n{\n"); + + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = PrintQCWaypoint; + fixer.enemy = world; + } +}; + +void() PrintBSPWaypoint = +{ + local entity t; + local string h; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + + if (t == world) + { + bprint("// End dump\n"); // 2001-09-10 FrikBot support by FrikaC/Maddes + remove(self); + fixer = world; + return; + } + bprint("{\n\"classname\" \"waypoint\"\n\"origin\" \""); +// 2001-09-10 FrikBot support by FrikaC/Maddes start + t.origin_x = rint(t.origin_x); + t.origin_y = rint(t.origin_y); + t.origin_z = rint(t.origin_z); +// 2001-09-10 FrikBot support by FrikaC/Maddes end + h = ftos(t.origin_x); + bprint(h); + bprint(" "); + h = ftos(t.origin_y); + bprint(h); + bprint(" "); + h = ftos(t.origin_z); + bprint(h); + if (t.target1.count) + { + bprint("\"\n\"b_pants\" \""); + h = ftos(t.target1.count); + bprint(h); + } + if (t.target2.count) + { + bprint("\"\n\"b_skill\" \""); + h = ftos(t.target2.count); + bprint(h); + } + if (t.target3.count) + { + bprint("\"\n\"b_shirt\" \""); + h = ftos(t.target3.count); + bprint(h); + } + if (t.target4.count) + { + bprint("\"\n\"b_frags\" \""); + h = ftos(t.target4.count); + bprint(h); + } + if (t.b_aiflags) + { + bprint("\"\n\"b_aiflags\" \""); + h = ftos(t.b_aiflags); + bprint(h); + } + bprint("\"\n}\n"); + self.nextthink = time + 0.01; + self.enemy = t; + +}; + +void() BSPDumpWaypoints = +{ + bprint("/* BSP entities Dump - maps/"); + + bprint(mapname); + bprint(".ent\nFor instructions please read the\nreadme.html that comes with FrikBot */\n\n"); // 2001-09-10 FrikBot support by FrikaC/Maddes + + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = PrintBSPWaypoint; + fixer.enemy = world; + } +}; + + +// FrikaC's file access tutorial... +string(string s1, string s2) strcat = #82; +float(string filename, float mode) open = #86; +string(string s) zone = #79; +void(string s) unzone = #80; +void(float handle) close = #87; +void(float handle, string s) write = #89; +float file; + +void() SaveWaypoint = +{ + local entity t; + local float needcolon; + local string h, j, k, l; + + if (self.enemy == world) + t = way_head; + else + t = self.enemy._next; + if (bytecounter >= 8000) + { + h = "maps/"; + j = ftos(filecount); + k = h = zone(strcat("maps/", mapname)); + l = h = zone(strcat(h, ".wa")); + unzone(k); + h = zone(strcat(h, j)); + unzone(l); + write(file, "exec "); + write(file, h); + write(file, "\n"); + filecount = filecount + 1; + close(file); + file = open(h, 2); + unzone(h); + if (file == -1) + { + remove(self); + fixer = world; + bprint("Error: failed to save file\n"); + return; + } + bytecounter = 0; + } + if (t == world) + { + remove(self); + fixer = world; + write(file, "saved4 3\n"); + close(file); + bprint("waypoints saved.\n"); + bytecounter = bytecounter + 27; + return; + } +// 2001-09-10 FrikBot support by FrikaC/Maddes start + t.origin_x = rint(t.origin_x); + t.origin_y = rint(t.origin_y); + t.origin_z = rint(t.origin_z); +// 2001-09-10 FrikBot support by FrikaC/Maddes end + if ((t.origin_x != saved1) || (t.count == 1)) + { + write(file, "saved1 "); + h = ftos(t.origin_x); + write(file, h); + saved1 = t.origin_x; + bytecounter = bytecounter + 12; + needcolon = TRUE; + } + if ((t.origin_y != saved2) || (t.count == 1)) + { + if (needcolon) + { + write(file, "; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + write(file, "saved2 "); + h = ftos(t.origin_y); + write(file, h); + bytecounter = bytecounter + 12; + saved2 = t.origin_y; + } + if ((t.origin_z != saved3) || (t.count == 1)) + { + if (needcolon) + { + write(file, "; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + write(file, "saved3 "); + h = ftos(t.origin_z); + write(file, h); + bytecounter = bytecounter + 12; + saved3 = t.origin_z; + } + if (needcolon) // 2001-09-10 FrikBot support by FrikaC/Maddes + { + bytecounter = bytecounter + 1; + write(file, "\n"); + needcolon = FALSE; + } + if ((scratch1 != t.target1.count) || t.count == 1) + { + needcolon = TRUE; + write(file, "scratch1 "); + bytecounter = bytecounter + 14; + h = ftos(t.target1.count); + write(file, h); + scratch1 = t.target1.count; + } + if ((scratch2 != t.target2.count) || t.count == 1) + { + if (needcolon) + { + write(file, "; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + write(file, "scratch2 "); + bytecounter = bytecounter + 14; + h = ftos(t.target2.count); + write(file, h); + scratch2 = t.target2.count; + } + if ((scratch3 != t.target3.count) || t.count == 1) + { + if (needcolon) + { + write(file, "; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + write(file, "scratch3 "); + bytecounter = bytecounter + 14; + h = ftos(t.target3.count); + write(file, h); + scratch3 = t.target3.count; + } + if ((scratch4 != t.target4.count) || t.count == 1) + { + if (needcolon) + { + write(file, "; "); + bytecounter = bytecounter + 2; + } + else + needcolon = TRUE; + write(file, "scratch4 "); + bytecounter = bytecounter + 14; + h = ftos(t.target4.count); + write(file, h); + scratch4 = t.target4.count; + } + if (needcolon) // 2001-09-10 FrikBot support by FrikaC/Maddes + { + write(file, "\n"); + needcolon = FALSE; + } + write(file, "saved4 "); + bytecounter = bytecounter + 19; + if (t.count != 1) + h = ftos(t.b_aiflags * 4 + 2); + else + h = ftos(t.b_aiflags * 4 + 1); + write(file, h); + write(file, "; wait\n"); + self.nextthink = time + 0.01; + self.enemy = t; +}; + +// to allow for 100+ waypoints, we need to trick the runaway loop counter +void() SaveWays = +{ + local string h, f; + bytecounter = 50; + filecount = 1; + h = strcat("maps/", mapname); + f = h = zone(h); + h = strcat(h, ".way"); + unzone(f); + file = open(h, 2); + if (file == -1) + { + bprint("Error: failed to open file\n"); + return; + } + if (!fixer) + { + fixer = spawn(); + fixer.nextthink = time + 0.01; + fixer.think = SaveWaypoint; + fixer.enemy = world; + } +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_fight.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_fight.qc new file mode 100755 index 00000000..21eb1e50 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_fight.qc @@ -0,0 +1,472 @@ +/*********************************************** +* * +* FrikBot Fight Code * +* "Because I ain't no Ghandi code" * +* * +***********************************************/ + +/* + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + +.entity avoid; + +float(entity e) bot_size_player = +{ + local float sz; + + sz = e.health + e.armorvalue * e.armortype; + if (e.weapon == 32) + sz = sz + 60; + else if (e.weapon == 64) + sz = sz + 60; + else if (e.weapon == 16) + sz = sz + 50; + else if (e.weapon == 8) + sz = sz + 50; + else if (e.weapon == 4) + sz = sz + 40; + else if (e.weapon == 2) + sz = sz + 40; + else if (e.weapon == 1) + sz = sz + 10; + else if (e.weapon == 4096) + sz = sz - 50; + if (e.items & 4194304) // Quad + sz = sz + 200; + if (e.items & 1048576) // Invul + sz = sz + 300; + if (e.items & 524288) // Invis + sz = sz + 250; + return sz; +}; + +void() bot_dodge_stuff = +{ + local entity foe, head; + local float avdist, foesz, flen, tsz; + local vector v; + + if (waypoint_mode > WM_LOADED) + return; + + self.avoid = world; + + + if (self.enemy) + { + v = self.origin - realorigin(self.enemy); + + foesz = bot_size_player(self.enemy); + foesz = foesz + vlen(v) * 0.5; + } + else + foesz = 9999999; + avdist = 256; + + foe = find(world, classname, "grenade"); + while(foe) + { + flen = vlen(foe.origin - self.origin); + if (flen < avdist) + { + avdist = flen; + self.avoid = foe; + } + foe = find(foe, classname, "grenade"); + } + if (!self.avoid) + { + foe = find(world, classname, "missile"); + while(foe) + { + if (foe.owner != self) + { + flen = vlen(foe.origin - self.origin); + if (flen < avdist) + { + avdist = flen; + self.avoid = foe; + } + } + foe = find(foe, classname, "missile"); + } + if (!self.avoid) + { + foe = find(world, classname, "spike"); + while(foe) + { + if (foe.owner != self) + { + flen = vlen(foe.origin - self.origin); + if (flen < avdist) + { + avdist = flen; + self.avoid = foe; + } + } + foe = find(foe, classname, "spike"); + } + } + } + if (coop) + { + if (!self.enemy) + { + foe = findradius(self.origin, 9999); + while(foe) + { + if(foe.flags & FL_MONSTER) + { + if(foe.health > 0) + { + tsz = bot_size_player(foe) + vlen(foe.origin - self.origin) * 0.5; + if (tsz < foesz) + { + if (fisible(foe)) + { + self.enemy = foe; + foesz = tsz; + } + } + } + } + foe = foe.chain; + } + } + } + else + { + head = findradius(self.origin, 9999); +while(head) +{ + if(head.classname == "Needle-spikes") + { + if(head.health > 0) + { + tsz = bot_size_player(head) + vlen(head.origin - self.origin) * 0.5; + if (tsz < foesz) + { + if (fov(head) || head.b_sound > time || self.b_skill == 3) + { + if (fisible(head)) + { + self.enemy = head; + foesz = tsz; + } + } + } + } + } + head = head.chain; +} + foe = player_head; + while(foe) + { + if(foe != self) + { + if (foe.modelindex != 0) + { + if (foe.health > 0) + { + if (!(teamplay && self.team == foe.team)) + { + tsz = bot_size_player(foe) + vlen(foe.origin - self.origin) * 0.5; + if (tsz < foesz) + { + if (fov(foe) || foe.b_sound > time || self.b_skill == 3) + { + if (fisible(foe)) + { + self.enemy = foe; + foesz = tsz; + } + } + } + } + } + } + } + foe = foe._next; + } + } +}; + + + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +weapon_range + +_x "sweet spot range" - try to maintain this range if possible +_y minimum range bot can be to be effective (rl/gl) (move away) +_z maximum range bot can be to be effective (lg/axe) (move in) +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +vector(float wep) weapon_range = +{ + if (wep == 4096) // IT_AXE + return '48 0 64'; + else if (wep == 1) // IT_SHOTGUN + return '128 0 99999'; + else if (wep == 2) // IT_SUPER_SHOTGUN + return '128 0 99999'; + else if (wep == 4) // IT_NAILGUN + return '180 0 3000'; + else if (wep == 8) // IT_SUPER_NAILGUN + return '180 0 3000'; + else if (wep == 16) // IT_GRENADE_LAUNCHER + return '180 48 3000'; + else if (wep == 32) // IT_ROCKET_LAUNCHER + return '180 48 3000'; + else if (wep == 64) // IT_LIGHTNING + return '350 0 512'; + return '128 0 99999'; + +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bot_weapon_switch + +Pick a weapon based on range / ammo + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(float brange) bot_weapon_switch = +{ + local float it, flag, pulse; + local vector v; + + it = self.items & 127; + + while(it) + { + if ((self.ammo_rockets >= 1) && (it & 32)) + { + flag = 32; + pulse = 7; + } + else if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & 64)) + { + flag = 64; + pulse = 8; + } + else if(self.ammo_nails >= 2 && (it & 8)) + { + flag = 8; + pulse = 5; + } + else if ((self.ammo_rockets >= 1) && (it & 16)) + { + flag = 16; + pulse = 6; + } + else if(self.ammo_shells >= 2 && (it & 2)) + { + flag = 2; + pulse = 3; + } + else if(self.ammo_nails >= 1 && (it & 4)) + { + flag = 4; + pulse = 4; + } + else if(self.ammo_shells >= 1 && (it & 1)) + { + flag = 1; + pulse = 2; + } + else + { + if (pulse) + self.impulse = pulse; + return; + } + + if (brange == -1) + { + if (pulse) + self.impulse = pulse; + return; + } + + v = weapon_range(flag); + if (brange < v_y || brange > v_z) + it = it - flag; + else + { + if (pulse) + self.impulse = pulse; + return; + } + } +}; + +void() bot_shoot = +{ + // quick little function to stop making him shoot the wrong way ! Argh + local float g; + g = angcomp(self.v_angle_x, self.b_angle_x); + if (fabs(g) > 30) + return; // argh, too far away + g = angcomp(self.v_angle_y, self.b_angle_y); + if (fabs(g) > 30) + return; // not again! + self.button0 = TRUE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot_fight_style + +This is the core of the bot's thinking when +attacking an enemy. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() bot_fight_style = +{ + local vector v, v1, v2, org; + local float foedist, mysz, foesz; + + + if (self.enemy.health <= 0) + { + self.enemy = world; + return; + } + else if (!self.enemy.takedamage) + { + self.enemy = world; + return; + } + else if (!fisible(self.enemy)) + { + self.enemy = world; + return; + } + + org = realorigin(self.enemy); + makevectors(self.v_angle); + + // decide if I should shoot + + foedist = vlen(org - self.origin); + v = weapon_range(self.weapon); + if (foedist > v_y && foedist < v_z) + { + traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * v_z, FALSE, self); + if (vlen(trace_endpos - (self.origin + self.view_ofs)) >= v_y) + { + // try to avoid shooting teammates + if (trace_ent.classname == "player") + if ((trace_ent.team == self.team && teamplay) || (coop)) + return; + bot_shoot(); + } + } + else + bot_weapon_switch(foedist); + + if (!(self.b_aiflags & (AI_PRECISION | AI_BLIND | AI_OBSTRUCTED))) + { + foesz = bot_size_player(self.enemy); + mysz = bot_size_player(self) + 5; + + if (foesz > mysz) + { + if (teamplay) + { + if (random() < 0.02) + { + bot_start_topic(5); + self.b_chattime = 1; + } + } + + return; + } + else if (mysz < 140) + return; + else if (self.avoid) + { + if (self.avoid.velocity) + v = self.avoid.velocity; + else + v = normalize(self.avoid.origin - self.origin); + v1_x = v_y * -1; + v1_y = v_x; + v2_x = v_y; + v2_y = v_x * -1; + foedist = vlen(self.avoid.origin - (self.origin + v1)); + if (foedist < vlen(self.avoid.origin - (self.origin + v2))) + frik_walkmove(v2); + else + frik_walkmove(v1); + } + else if (!self.enemy.flags & FL_MONSTER) + { + if (foedist + 32 < v_x) + frik_walkmove(self.origin - org); + else if (foedist - 32 > v_x) + frik_walkmove(org - self.origin); + else if (self.wallhug) + frik_walkmove(v_right); + else + frik_walkmove(v_right * -1); + } + } + else + { + foesz = bot_size_player(self.enemy); + mysz = bot_size_player(self) + 5; + + if (foesz > mysz) + return; + else if (mysz < 140) + return; + self.keys = self.keys & 960; + } +}; + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_misc.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_misc.qc new file mode 100755 index 00000000..7d01b5cf --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_misc.qc @@ -0,0 +1,779 @@ +/*********************************************** +* * +* FrikBot Misc Code * +* "Because you can't name it anything else" * +* * +***********************************************/ + +/* +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotName + +Sets bot's name and colors + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +string(float r) BotName = +{ + self.b_num = r; + if (r == 1) + { + self.b_pants = 11; + self.b_shirt = 0; + return "Vincent"; + } + else if (r == 2) + { + self.b_pants = 1; + self.b_shirt = 3; + return "Bishop"; + } + else if (r == 3) + { + self.b_pants = 13; + self.b_shirt = 2; + return "Nomad"; + } + else if (r == 4) + { + self.b_pants = 7; + self.b_shirt = 6; + return "Hudson"; + } + else if (r == 5) + { + self.b_pants = 12; + self.b_shirt = 6; + return "Lore"; + } + else if (r == 6) + { + self.b_pants = 4; + self.b_shirt = 4; + return "Servo"; + } + else if (r == 7) + { + self.b_pants = 2; + self.b_shirt = 5; + return "Gort"; + } + else if (r == 8) + { + self.b_pants = 10; + self.b_shirt = 3; + return "Kryten"; + } + else if (r == 9) + { + self.b_pants = 9; + self.b_shirt = 4; + return "Pimp Bot"; + } + else if (r == 10) + { + self.b_pants = 4; + self.b_shirt = 7; + return "Max"; + } + else if (r == 11) + { + self.b_pants = 3; + self.b_shirt = 11; + return "Marvin"; + } + else if (r == 12) + { + self.b_pants = 13; + self.b_shirt = 12; + return "Erwin"; + } + else if (r == 13) + { + self.b_pants = 11; + self.b_shirt = 2; + return "FrikBot"; + } + else if (r == 14) + { + self.b_pants = 0; + self.b_shirt = 2; + return "Krosis"; + } + else if (r == 15) + { + self.b_pants = 8; + self.b_shirt = 9; + return "Gypsy"; + } + else if (r == 16) + { + self.b_pants = 5; + self.b_shirt = 10; + return "Hal"; + } + return "Noname"; +}; +string () PickARandomName = +{ + if (bot_count > 16) + return "player"; + + local float y, test; + local string h; + local entity t; + y = TRUE; + while(y) + { + test = ceil(random() * 16); + h = BotName(test); + t = find(world, netname, h); + if (t == world) + y = FALSE; + } + return h; +}; + + + +// I didn't like the old code so this is very stripped down + +entity b_originator; +float b_topic; +/* FBX Topics + +b_originator == self + 1 - sign on + 2 - killed targ + 3 - team message "friendly eyes" + 4 - team message "on your back" + 5 - team message "need back up" + 6 - excuses + ---- + 7 - gameover + ---- + 8 - welcoming someone onto server + 9 - ridicule lost frag (killed self?) + 10 - ridicule lost frag (lava) + 11 - lag +b_originator == targ + + +*/ +void(float tpic) bot_start_topic = +{ + if (random() < 0.2) + { + b_topic = tpic; + b_originator = self; + } + else + b_topic = 0; +}; + +void() bot_chat = +{ + local float r; + if (b_options & OPT_NOCHAT) + return; + r = ceil (random() * 6); + + if (self.b_chattime > time) + { + if (self.b_skill < 2) + self.keys = self.button0 = self.button2 = 0; + return; + } + else if (self.b_chattime) + { + if (b_topic == 1) + { + if (b_originator == self) + { + if (r == 1) + { + BotSay(": lo all\n"); + bot_start_topic(8); + } + else if (r == 2) + { + BotSay(": hey everyone\n"); + bot_start_topic(8); + } + else if (r == 3) + { + BotSay(": prepare to be fragged!\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSay(": boy this is laggy\n"); + bot_start_topic(11); + } + else if (r == 5) + { + BotSay(": #mm getting some lag here\n"); + bot_start_topic(11); + } + else + { + BotSay(": hi everyone\n"); + bot_start_topic(8); + } + } + } + else if (b_topic == 2) + { + if (b_originator == self) + { + if (r == 1) + BotSay(": take that\n"); + else if (r == 2) + BotSay(": yehaww!\n"); + else if (r == 3) + BotSay(": wh00p\n"); + else if (r == 4) + BotSay(": j00_sawk();\n"); + else if (r == 5) + BotSay(": i rule\n"); + else + BotSay(": eat that\n"); + bot_start_topic(0); + } + } + else if (b_topic == 3) + { + if (b_originator == self) + { + if (r < 3) + BotSayTeam(": friendly eyes\n"); + else + BotSayTeam(": team eyes\n"); + bot_start_topic(0); + } + } + else if (b_topic == 4) + { + if (b_originator == self) + { + if (r < 3) + BotSayTeam(": on your back\n"); + else + BotSayTeam(": I'm with you\n"); + bot_start_topic(0); + } + } + else if (b_topic == 5) + { + if (b_originator == self) + { + if (r < 3) + BotSayTeam(": I need help\n"); + else + BotSayTeam(": need backup\n"); + bot_start_topic(0); + } + } + else if (b_topic == 6) + { + if (b_originator == self) + { + if (r == 1) + { + BotSay(": sun got in my eyes\n"); + bot_start_topic(0); + } + else if (r == 2) + { + BotSay(": mouse needs cleaning\n"); + bot_start_topic(0); + } + else if (r == 3) + { + BotSay(": i meant to do that\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSay(": lag\n"); + bot_start_topic(11); + } + else if (r == 5) + { + BotSay(": killer lag\n"); + bot_start_topic(11); + } + else + { + BotSay(": 100% lag\n"); + bot_start_topic(11); + } + } + } + else if (b_topic == 7) + { + if (r == 1) + BotSay(": gg\n"); + else if (r == 2) + BotSay(": gg all\n"); + else if (r == 3) + BotSay(": that was fun\n"); + else if (r == 4) + BotSay(": good game\n"); + else if (r == 5) + BotSay(": pah\n"); + else + BotSay(": hrm\n"); + bot_start_topic(0); + } + else if (b_topic == 8) + { + if (b_originator != self) + { + if (r == 1) + { + BotSay(": heya\n"); + bot_start_topic(0); + } + else if (r == 2) + { + BotSay(": welcome\n"); + bot_start_topic(0); + } + else if (r == 3) + { + BotSayInit(); + BotSay2(": hi "); + BotSay2(b_originator.netname); + BotSay2("\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSayInit(); + BotSay2(": hey "); + BotSay2(b_originator.netname); + BotSay2("\n"); + bot_start_topic(0); + } + else if (r == 5) + { + BotSay(": howdy\n"); + bot_start_topic(0); + } + else + { + BotSay(": lo\n"); + bot_start_topic(0); + } + } + } + + else if (b_topic == 9) + { + if (b_originator != self) + { + if (r == 1) + BotSay(": hah\n"); + else if (r == 2) + BotSay(": heheh\n"); + else if (r == 3) + { + BotSayInit(); + BotSay2(": good work "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 4) + { + BotSayInit(); + BotSay2(": nice1 "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 5) + BotSay(": lol\n"); + else + BotSay(": :)\n"); + b_topic = 6; + } + } + else if (b_topic == 10) + { + if (b_originator != self) + { + if (r == 1) + BotSay(": have a nice dip?\n"); + else if (r == 2) + BotSay(": bah I hate levels with lava\n"); + else if (r == 3) + { + BotSayInit(); + BotSay2(": good job "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 4) + { + BotSayInit(); + BotSay2(": nice backflip "); + BotSay2(b_originator.netname); + BotSay2("\n"); + } + else if (r == 5) + BotSay(": watch your step\n"); + else + BotSay(": hehe\n"); + b_topic = 6; + } + } + + else if (b_topic == 11) + { + if (b_originator != self) + { + if (r == 1) + { + BotSayInit(); + BotSay2(": yeah right "); + BotSay2(b_originator.netname); + BotSay2("\n"); + bot_start_topic(0); + } + else if (r == 2) + { + BotSay(": ping\n"); + bot_start_topic(0); + } + else if (r == 3) + { + BotSay(": shuddup, you're an lpb\n"); + bot_start_topic(0); + } + else if (r == 4) + { + BotSay(": lag my eye\n"); + bot_start_topic(0); + } + else if (r == 5) + { + BotSay(": yeah\n"); + bot_start_topic(11); + } + else + { + BotSay(": totally\n"); + bot_start_topic(11); + } + } + } + self.b_chattime = 0; + } + else if (b_topic) + { + if (random() < 0.5) + { + if (self == b_originator) + { + if (b_topic <= 7) + self.b_chattime = time + 2; + } + else + { + if (b_topic >= 7) + self.b_chattime = time + 2; + } + } + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Kick A Bot. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() KickABot = +{ + local entity ty; + ty = find(world, classname, "player"); + while (ty != world) + { + if (!(ty.ishuman)) + { + + BotDisconnect(ty); + ty.ishuman = TRUE; + ty = world; + } + else + ty = find(ty, classname, "player"); + } + +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Simplified origin checking. + +God, I wish I had inline + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +vector(entity ent) realorigin = +{ +// even more simplified... + return (ent.absmin + ent.absmax) * 0.5; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +fisible + +a version of visible that checks for corners +of the bounding boxes + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float (entity targ) fisible = +{ + local vector spot1, org; + local float thruwater, pc1, pc2; + + org = realorigin(targ); + spot1 = self.origin + self.view_ofs; + + if (targ.solid == SOLID_BSP) + { + traceline (spot1, org, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; + } + else + { + pc1 = pointcontents(org); + pc2 = pointcontents(spot1); + if (targ.classname == "player") + thruwater = FALSE; + else if (pc1 == CONTENT_LAVA) + return FALSE; + else + thruwater = TRUE; + } + + if (pc1 < -1) // targ's origin is in water or other liquid + { + if (pc2 != pc1) + { + // look for their head + traceline (spot1, org + targ.mins, TRUE, self); + // cross the water check + if (trace_inopen) + if (trace_inwater) + if (!thruwater) + return FALSE; + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; + } + } + else + { + if (pc2 != pc1) + { + traceline (spot1, org + targ.maxs, TRUE, self); + if (trace_inopen) + if (trace_inwater) + if (!thruwater) + return FALSE; + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; + } + } + traceline (spot1, org, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + traceline (spot1, org + targ.maxs, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + traceline (spot1, org + targ.mins, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return FALSE; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Wisible + +goes through movable brushes/entities, used +for waypoints + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +// this is used for waypoint stuff.... +float (entity targ1, entity targ2) wisible = +{ + local vector spot1, spot2; + local entity ignore; + + spot1 = targ1.origin; + spot2 = realorigin(targ2); + + ignore = self; + do + { + traceline (spot1, spot2, TRUE, ignore); + spot1 = realorigin(trace_ent); + ignore = trace_ent; + } while ((trace_ent != world) && (trace_fraction != 1)); + if (trace_endpos == spot2) + return TRUE; + else + return FALSE; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +sisible + +Now this is getting ridiculous. Simple visible, +used when we need just a simple traceline nothing else + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float (entity targ) sisible = +{ + traceline (self.origin, targ.origin, TRUE, self); + if (trace_ent == targ) + return TRUE; + else if (trace_fraction == 1) + return TRUE; + return TRUE; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +angcomp + +subtracts one angle from another + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float (float y1, float y2) angcomp = +{ + y1 = frik_anglemod(y1); + y2 = frik_anglemod(y2); + + local float answer; + answer = y1 - y2; + if (answer > 180) + answer = answer - 360; + else if (answer < -180) + answer = answer + 360; + return answer; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +fov + +is the entity in the bot's field of view + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float (entity targ) fov = +{ + local vector yawn; + local float g; + yawn = realorigin(targ); + yawn = (yawn + targ.view_ofs) - (self.origin + self.view_ofs); + yawn = normalize(yawn); + yawn = vectoangles(yawn); + g = angcomp(self.v_angle_x, yawn_x); + if (fabs(g) > 45) + return FALSE; + g = angcomp(self.v_angle_y, yawn_y); + if (fabs(g) > 60) + return FALSE; + + return TRUE; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +frik_anglemod + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float(float v) frik_anglemod = +{ + return v - floor(v/360) * 360; +} \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_move.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_move.qc new file mode 100755 index 00000000..cc1e3d9c --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_move.qc @@ -0,0 +1,520 @@ +/*********************************************** +* * +* FrikBot Movement AI * +* "The slightly better movement AI" * +* * +***********************************************/ + +/* + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + +void() bot_jump = +{ + // TODO check for precision, etc. + self.button2 = TRUE; +}; + +float(entity e) bot_can_rj = +{ + // this returns true of the bot can rocket/superjump/hook + // if your mod doesn't have an RL you can just return FALSE all the time + // if it has a hook or some other means for the bot to get to high places + // you can check here for that capability + + // am I dumb? + if (e.b_skill == 0) + return FALSE; + + // quad = bad + if (e.items & 4194304) + return FALSE; + + // do I have rockets & RL? + if (!((e.items & 32) && (e.ammo_rockets > 0))) + return FALSE; + + // do I have pent? + if (e.items & 1048576) + return TRUE; + + if (e.health > 50) + return TRUE; + else + return FALSE; +}; + +float(float flag) frik_recognize_plat = +{ + if ((self.classname != "waypoint") && !(self.flags & FL_ONGROUND)) + return FALSE; + traceline(self.origin, self.origin - '0 0 64', TRUE, self); + if (trace_ent != world) + { + if (flag) // afect bot movement too + { + if (self.keys & KEY_MOVEUP) + { + if (trace_ent.velocity_z > 0) + self.keys = self.keys & 960; // 960 is all view keys + } + else if (self.keys & KEY_MOVEDOWN) + { + if (trace_ent.velocity_z < 0) + self.keys = self.keys & 960; + } + } + return TRUE; + } + else + return FALSE; +}; + +float(vector sdir) frik_KeysForDir = +{ + + local vector keydir; + local float outkeys, tang; + outkeys = 0; + if (sdir_x || sdir_y) + { + // Everything is tested against 60 degrees, + // this allows the bot to overlap the keys + // 30 degrees on each diagonal 45 degrees + // might look more realistic + + keydir = vectoangles(sdir); + tang = angcomp(keydir_y, self.v_angle_y); + if ((tang <= 150) && (tang >= 30)) + outkeys = outkeys + KEY_MOVELEFT; + else if ((tang >= -150) && (tang <= -30)) + outkeys = outkeys + KEY_MOVERIGHT; + if (fabs(tang) <= 60) + outkeys = outkeys + KEY_MOVEFORWARD; + else if (fabs(tang) >= 120) + outkeys = outkeys + KEY_MOVEBACK; + } + if (sdir_z > 0) + outkeys = outkeys + KEY_MOVEUP; + else if (sdir_z < 0) + outkeys = outkeys + KEY_MOVEDOWN; + return outkeys; + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +frik_obstructed + +Bot has hit a ledge or wall that he should +manuever around. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(vector whichway, float danger) frik_obstructed = +{ + local float dist; + local vector disway, org; +// TODO: something + if (self.b_aiflags & AI_BLIND) + return; + org = realorigin(self.target1); + + if (danger) + { + self.b_aiflags = self.b_aiflags | AI_DANGER; + self.keys = frik_KeysForDir('0 0 0' - whichway); + } + if (self.b_aiflags & AI_PRECISION) + return; + + + if (self.target1) + { + if (self.b_aiflags & AI_OBSTRUCTED) + { + if (!(self.b_aiflags & AI_DANGER)) + { + self.b_aiflags = self.b_aiflags - AI_OBSTRUCTED; + return; + } + else if (!danger) + return; + } + self.obs_dir = whichway; + disway_x = whichway_y * -1; + disway_y = whichway_x; + dist = vlen(org - (self.origin + disway)); + disway_x = whichway_y; + disway_y = whichway_x * -1; + self.wallhug = vlen(org - (self.origin + disway)) > dist; + self.b_aiflags = self.b_aiflags | AI_OBSTRUCTED; + + } + else + { + disway_x = whichway_y * -1; + disway_y = whichway_x; + dist = vlen(disway - self.obs_dir); + disway_x = whichway_y; + disway_y = whichway_x * -1; + self.wallhug = vlen(disway - self.obs_dir) < dist; + self.obs_dir = whichway; + + self.b_aiflags = self.b_aiflags | AI_OBSTRUCTED; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +frik_obstacles + +Detects small bumps the bot needs to jump over +or ledges the bot should avoid falling in. + +Also responsible for jumping gaps. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_obstacles = +{ + local vector start, stop, ang; + local float test, conts, dist, hgt; + + if (!(self.flags & FL_ONGROUND)) + return; + if (self.b_aiflags & AI_BLIND) + return; + + ang = normalize(self.velocity); + ang_z = 0; + start = self.origin + ang * 32; // ahem + start_z = self.origin_z + self.maxs_z; + stop = start; + stop_z = self.origin_z + self.mins_z; + traceline(start, stop - '0 0 256', TRUE, self); + if (trace_allsolid || trace_startsolid) + return; + hgt = trace_endpos_z - stop_z; + + if (hgt > 18) + { + bot_jump(); + return; + } + if (hgt >= 0) + return; + + conts = pointcontents(trace_endpos + '0 0 4'); + start = stop - '0 0 8'; + stop = start + ang * 256; + traceline(start, stop, TRUE, self); + test = vlen(trace_endpos - start); + if (test <= 20) + return; // it's a walkable gap, do nothing + ang_x = self.velocity_y * -1; + ang_y = self.velocity_x; + ang = normalize(ang); + traceline(start - (ang * 10), start + (ang * 10), TRUE, self); + if ((trace_fraction != 1) || trace_startsolid) + return; // gap is only 20 wide, walkable + ang = self.velocity; + ang_z = 0; + dist = ((540 / sv_gravity) * vlen(ang))/* + 32*/; + if (test > dist) // I can't make it + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + else + { + if (self.target1) + { + stop = realorigin(self.target1); + if ((stop_z - self.origin_z) < -32) + return; // safe to fall + } + frik_obstructed(ang, FALSE); + return; + } + } + else + { + ang = normalize(ang); + //look for a ledge + traceline(self.origin, self.origin + (ang * (test + 20)), TRUE, self); + if (trace_fraction != 1) + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + else + { + if (self.target1) + { + stop = realorigin(self.target1); + if ((stop_z - self.origin_z) < -32) + return; // safe to fall + } + frik_obstructed(ang, FALSE); + return; + } + } + + if (self.target1) + { + // getting furter away from my target? + test = vlen(self.target1.origin - (ang + self.origin)); + if (test > vlen(self.target1.origin - self.origin)) + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + else + { + frik_obstructed(ang, FALSE); + return; + } + } + } + } + if (hgt < -18) + { + if (conts < -3) // bad stuff down dare + { + frik_obstructed(ang, TRUE); + return; + } + if (self.target1) + { + stop = realorigin(self.target1); + if ((stop_z - self.origin_z) < -32) + { + + return; // safe to fall + } + } + bot_jump(); + } + // go for it +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +After frik_obstructed, the bot uses the +following funtion to move "around" the obstacle + +I have no idea how well it will work + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_dodge_obstruction = +{ + local vector way, org; + local float oflags, yaw; + + if (!(self.b_aiflags & AI_OBSTRUCTED)) + return; + if ((self.b_aiflags & (AI_BLIND | AI_PRECISION)) || !(self.flags & FL_ONGROUND)) + { + self.b_aiflags = self.b_aiflags - AI_OBSTRUCTED; + return; + } + + // perform a walkmove check to see if the obs_dir is still obstructed + // walkmove is less forgiving than frik_obstacles, so I dunno + // how well this will work + + oflags = self.flags; + org = self.origin; + + yaw = vectoyaw(self.obs_dir); + if (walkmove(yaw, 32)) + self.b_aiflags = self.b_aiflags - AI_OBSTRUCTED; + else + { + if (self.b_aiflags & AI_DANGER) + { + way = '0 0 0' - self.obs_dir; + } + else if (self.wallhug) + { + way_x = self.obs_dir_y * -1; + way_y = self.obs_dir_x; + } + else + { + way_x = self.obs_dir_y; + way_y = self.obs_dir_x * -1; + } + self.keys = self.keys & 960 + frik_KeysForDir(way); + } + + // fix the bot + + self.origin = org; + self.flags = oflags; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +movetogoal and walkmove replacements + +blah + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_movetogoal = +{ + local vector way/*, start, stop, ang*/; + local float g; + + if (self.target1 == world) + { + makevectors(self.v_angle); + frik_walkmove(v_forward); + return; + } + way = realorigin(self.target1) - self.origin; + if (vlen(way) < 25) + { + self.keys = self.keys & 960; + return; + } + + way = normalize(way); + self.keys = self.keys & 960 + frik_KeysForDir(way); + + frik_dodge_obstruction(); + frik_recognize_plat(TRUE); + + if (self.b_aiflags & AI_PRECISION) + { + g = angcomp(self.v_angle_x, self.b_angle_x); + if (fabs(g) > 10) + self.keys = self.keys & 960; + g = angcomp(self.v_angle_y, self.b_angle_y); + if (fabs(g) > 10) + self.keys = self.keys & 960; + } +}; + +float(vector weird) frik_walkmove = +{ + // okay so it's not walkmove + // sue me + self.keys = self.keys & 960 + frik_KeysForDir(weird); + + frik_dodge_obstruction(); + frik_recognize_plat(TRUE); + if (self.b_aiflags & AI_OBSTRUCTED) + return FALSE; + else + return TRUE; +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +The "hook" method of navigation. This nav +system is copyrighted 1999 by Ryan "Frika C" +Smith, keep that in mind when you steal it. + +I brought this back because normal roaming +won't work - the bot gets distracted by it's +own waypoints. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() frik_bot_roam = +{ + local vector org, ang, org1; + local float loopcount, flag, dist; + + loopcount = 26; + flag = FALSE; + while((loopcount > 0) && !flag) + { + loopcount = loopcount - 1; + org = self.origin + self.view_ofs; + ang = self.angles; + ang_y = frik_anglemod(ang_y - 90 + (random() * 180)); + ang_x = 0; // avoid upward sloping + makevectors(ang); + traceline(org, org + v_forward * 2300, TRUE, self); + if (trace_fraction != 1) + { + org1 = trace_endpos; + ang = normalize(trace_plane_normal); + ang_z = 0; // avoid upward sloping + traceline(org1, org1 + (ang * 2300), TRUE, self); + if ((trace_fraction != 1) && (vlen(trace_endpos - org1) >= 64)) + { + org = trace_endpos; + traceline(org, self.origin + self.view_ofs, TRUE, self); + if (trace_fraction != 1) + { + dist = vlen(org1 - org) /2; + org = org1 + (ang * dist); + traceline(org, org - '0 0 48', TRUE, self); + if (trace_fraction != 1) + { + SpawnTempWaypoint(org); + flag = TRUE; + } + } + } + } + } + self.b_angle_y = self.v_angle_y + 10; + frik_walkmove(v_forward); +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_phys.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_phys.qc new file mode 100755 index 00000000..3dc3c8d2 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_phys.qc @@ -0,0 +1,681 @@ +/*********************************************** +* * +* FrikBot Physics * +* The near-perfect emulation of * +* Client movement * +* * +* Special Thanks to: Asdf, Frog * +* Alan "Strider" Kivlin * +* * +* * +***********************************************/ + +/* + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + +/* +========================================= + +Stuff mimicking cl_input.c code + +========================================= +*/ +float(float key) CL_KeyState = +{ + return ((self.keys & key) > 0); +}; + +void() CL_KeyMove = // CL_BaseMove + CL_AdjustAngles +{ + local float anglespeed; + local vector view; + if (self.keys != self.oldkeys) + { + self.movevect = '0 0 0'; + self.movevect_y = self.movevect_y + (350 * CL_KeyState(KEY_MOVERIGHT)); + // 350 is the default cl_sidespeed + self.movevect_y = self.movevect_y - (350 * CL_KeyState(KEY_MOVELEFT)); + // 350 is the default cl_sidespeed + self.movevect_x = self.movevect_x + (200 * CL_KeyState(KEY_MOVEFORWARD)); + // 200 is the default cl_forwardspeed + self.movevect_x = self.movevect_x - (200 * CL_KeyState(KEY_MOVEBACK)); + // 200 is the default cl_backspeed + self.movevect_z = self.movevect_z + (200 * CL_KeyState(KEY_MOVEUP)); + // 200 is the default cl_upspeed + self.movevect_z = self.movevect_z - (200 * CL_KeyState(KEY_MOVEDOWN)); + // 200 is the default cl_upspeed + if (!self.b_aiflags & AI_PRECISION) + self.movevect = self.movevect * 2; + // 2 is the default cl_movespeedkey & bot always has +speed + } + self.oldkeys = self.keys; + + if (self.b_skill != 2) // use mouse emulation + { + anglespeed = 1.5 * real_frametime; + // 1.5 is the default cl_anglespeedkey & bot always has +speed + self.v_angle_y = self.v_angle_y + anglespeed * CL_KeyState(KEY_LOOKLEFT) * 140; + // 140 is default cl_yawspeed + self.v_angle_y = self.v_angle_y - anglespeed * CL_KeyState(KEY_LOOKRIGHT) * 140; + // 140 is default cl_yawspeed + self.v_angle_x = self.v_angle_x - anglespeed * CL_KeyState(KEY_LOOKUP) * 150; + // 150 is default cl_pitchspeed + self.v_angle_x = self.v_angle_x + anglespeed * CL_KeyState(KEY_LOOKDOWN) * 150; + // 150 is default cl_pitchspeed + } + else + { + view_x = angcomp(self.b_angle_x, self.v_angle_x); + view_y = angcomp(self.b_angle_y, self.v_angle_y); + if (vlen(view) > 30) + { + self.mouse_emu = self.mouse_emu + (view * 30); + if (vlen(self.mouse_emu) > 180) + self.mouse_emu = normalize(self.mouse_emu) * 180; + } + else + self.mouse_emu = view * (1 / real_frametime); + self.v_angle = self.v_angle + self.mouse_emu * real_frametime; + + + } + if (self.v_angle_x > 80) + self.v_angle_x = 80; + else if (self.v_angle_x < -70) + self.v_angle_x = -70; + + if (self.v_angle_z > 50) + self.v_angle_z = 50; + else if (self.v_angle_z < -50) + self.v_angle_z = -50; + self.v_angle_y = frik_anglemod(self.v_angle_y); + +}; + +/* +========================================= + +Stuff mimicking sv_user.c + +========================================= +*/ +void() SV_UserFriction = +{ + local vector vel, start, stop; + local float sped, friction, newspeed; + + vel = self.velocity; + vel_z =0; + sped = vlen(vel); + vel = self.velocity; + + if (!sped) + return; + +// if the leading edge is over a dropoff, increase friction + + start_x = stop_x = self.origin_x + vel_x / (sped * 16); + start_y = stop_y = self.origin_y + vel_y / (sped * 16); + start_z = self.origin_z + self.mins_z; + stop_z = start_z - 34; + + traceline(start, stop, TRUE, self); + + if (trace_fraction == 1) + friction = sv_friction * 2; // 2 is default edgefriction, removed for QW compatability + else + friction = sv_friction; + if (sped < sv_stopspeed) + newspeed = sped - real_frametime * sv_stopspeed * friction; + else + newspeed = sped - real_frametime * sped * friction; + + if (newspeed < 0) + newspeed = 0; + newspeed = newspeed / sped; + + self.velocity_y = vel_y * newspeed; + self.velocity_x = vel_x * newspeed; +}; +void() SV_WaterJump = +{ + if (time > self.teleport_time || !self.waterlevel) + { + self.flags = self.flags - (self.flags & FL_WATERJUMP); + self.teleport_time = 0; + } + self.velocity_x = self.movedir_x; + self.velocity_y = self.movedir_y; +}; + +void() DropPunchAngle = +{ + local float len; + len = vlen(self.punchangle); + self.punchangle = normalize(self.punchangle); + len = len - 10 * real_frametime; + if (len < 0) + len = 0; + self.punchangle = self.punchangle * len; +}; + + +void(vector wishvel) SV_AirAccelerate = +{ + local float addspeed, wishspd, accelspeed, currentspeed; + + wishspd = vlen(wishvel); + wishvel = normalize(wishvel); + if (wishspd > 30) + wishspd = 30; + currentspeed = self.velocity * wishvel; + addspeed = wishspd - currentspeed; + if (addspeed <= 0) + return; + accelspeed = 10 * sv_accelerate * wishspd * real_frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + self.velocity = self.velocity + accelspeed * wishvel; +}; + +void(vector wishvel) SV_Accelerate = +{ + local float addspeed, wishspd, accelspeed, currentspeed; + + wishspd = vlen(wishvel); + wishvel = normalize(wishvel); + + currentspeed = self.velocity * wishvel; + addspeed = wishspd - currentspeed; + if (addspeed <= 0) + return; + accelspeed = sv_accelerate * wishspd * real_frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + self.velocity = self.velocity + accelspeed * wishvel; +}; +void() SV_WaterMove = +{ + local vector wishvel; + local float wishspeed, addspeed, cspeed, newspeed; + makevectors(self.v_angle); + wishvel = v_right * self.movevect_y + v_forward * self.movevect_x; + + if (self.movevect == '0 0 0') + wishvel_z = wishvel_z - 60; + else + wishvel_z = wishvel_z + self.movevect_z; + wishspeed = vlen(wishvel); + + if (wishspeed > sv_maxspeed) + { + wishvel = (sv_maxspeed / wishspeed) * wishvel; + wishspeed = sv_maxspeed; + } + wishspeed = wishspeed * 0.7; + cspeed = vlen(self.velocity); + if (cspeed) + { + newspeed = cspeed - (real_frametime * cspeed * sv_friction); + if (newspeed < 0) + newspeed = 0; + self.velocity = self.velocity * (newspeed / cspeed); + + } + else + newspeed = 0; + + if (!wishspeed) + return; + addspeed = wishspeed - newspeed; + if (addspeed <= 0) + return; + wishvel = normalize(wishvel); + cspeed = sv_accelerate * wishspeed * real_frametime; + if (cspeed > addspeed) + cspeed = addspeed; + self.velocity = self.velocity + cspeed * wishvel; +}; +void() SV_AirMove = +{ + local vector wishvel, vangle; + + vangle = self.v_angle; + vangle_x = vangle_z = 0; + makevectors(vangle); + if (time < self.teleport_time && (self.movevect_x < 0)) + self.movevect_x = 0; + wishvel = v_right * self.movevect_y + v_forward * self.movevect_x; + + + if (self.movetype != MOVETYPE_WALK) + wishvel_z = self.movevect_z; + else + wishvel_z = 0; + if (vlen(wishvel) > sv_maxspeed) + wishvel = normalize(wishvel) * sv_maxspeed; + if (self.movetype == MOVETYPE_NOCLIP) + self.velocity = wishvel; + else if (self.flags & FL_ONGROUND) + { + SV_UserFriction(); + SV_Accelerate(wishvel); + } + else + SV_AirAccelerate (wishvel); +}; + +void() SV_ClientThink = +{ + local vector vangle; + + if (self.movetype == MOVETYPE_NONE) + return; + DropPunchAngle(); + if (self.health <= 0) + return; + self.v_angle_z = 0; // V_CalcRoll removed, sucks + self.angles_z = self.v_angle_z * 4; + vangle = self.v_angle + self.punchangle; + if (!self.fixangle) + { + self.angles_x = (vangle_x / -3); + self.angles_y = vangle_y; + } else + { + self.v_angle = self.angles; + self.fixangle = 0; + } + if (self.flags & FL_WATERJUMP) + { + SV_WaterJump(); + return; + } + if ((self.waterlevel >= 2) && (self.movetype != MOVETYPE_NOCLIP)) + { + SV_WaterMove(); + return; + } + SV_AirMove(); + +}; +/* +========================================= + +Stuff mimicking sv_phys.c + +========================================= +*/ + +float() SV_RunThink = +{ + local float thinktime, bkuptime; + thinktime = self.nextthink; + bkuptime = time; + if (thinktime <= 0 || thinktime > (time + real_frametime)) + return TRUE; + if (thinktime < time) + thinktime = time; + self.nextthink = 0; + time = thinktime; + other = world; + makevectors(self.v_angle); // hack + self.think(); + time = bkuptime; + return TRUE; +}; + +void(float scale) SV_AddGravity = +{ + self.velocity_z = self.velocity_z - (scale * sv_gravity * real_frametime); +}; + +float() SV_CheckWater = +{ + local vector point; + local float cont; + + point_x = self.origin_x; + point_y = self.origin_y; + self.waterlevel = 0; + self.watertype = CONTENT_EMPTY; + point_z = self.origin_z + self.mins_z + 1; + cont = pointcontents(point); + if (cont <= CONTENT_WATER) + { + self.watertype = cont; + self.waterlevel = 1; + point_z = self.origin_z + (self.mins_z + self.maxs_z) * 0.5; + cont = pointcontents(point); + if (cont <= CONTENT_WATER) + { + self.waterlevel = 2; + point_z = self.origin_z + self.view_ofs_z; + cont = pointcontents(point); + if (cont <= CONTENT_WATER) + self.waterlevel = 3; + } + } + return (self.waterlevel > 1); + +}; +void() RemoveThud = // well sometimes +{ + local entity oself; + if (other == world) + { + if (self.flags & FL_ONGROUND) + { + self.flags = self.flags - FL_ONGROUND; + } + } + else + { + if (other.solid == SOLID_BSP && (self.flags & FL_ONGROUND)) + { + // RM: Does this break anything? + // If not, then some more thuds have been removed. + self.flags = self.flags - FL_ONGROUND; + } + if (other == self.owner) + return; + if (self.owner.solid == SOLID_NOT) + return; + oself = other; + other = self.owner; + self = oself; + if (self.solid == SOLID_BSP) + if (self.touch) + self.touch(); + } + +}; +void() SV_CheckOnGround = +{ + local vector org, v; + org = self.origin; + local float currentflags; + currentflags = self.flags; + self.flags = self.flags | FL_ONGROUND | FL_PARTIALGROUND; + walkmove(0,0); // perform C touch function + self.flags = currentflags | FL_ONGROUND; + if ((org_x != self.origin_x) || (org_y != self.origin_y)) + org = self.origin; + else + self.origin = org; + v = org; + v_z = self.maxs_z + org_z + 1; + traceline (org, v, TRUE, self); + if ((self.waterlevel == 3) && (self.movetype == MOVETYPE_WALK)) + self.flags = self.flags - FL_ONGROUND; + else if ((trace_plane_normal_z <= 0.7) && (trace_fraction != 1)) + self.flags = self.flags - FL_ONGROUND; + else if (!droptofloor(/*0,0*/)) + self.flags = self.flags - FL_ONGROUND; + else if (org_z - self.origin_z < 2) + self.flags = self.flags | FL_ONGROUND; + else + self.flags = self.flags - FL_ONGROUND; + setorigin(self, org); +}; +// Thanks to Alan Kivlin for this function +// modified heavily by me +float(vector dir) botCheckForStep = +{ + local vector currentorigin, v; + local float currentflags, yaw, stepdistance, movedistance; + currentorigin = self.origin; + currentflags = self.flags; + self.flags = FL_ONGROUND | FL_PARTIALGROUND; + dir = normalize(dir); + dir_z = 0; + yaw = vectoyaw(dir); + if(walkmove(yaw, 3)) + { + if(droptofloor(/*0,0*/)) + { + stepdistance = self.origin_z - currentorigin_z; + v = self.origin - currentorigin; + v_z = 0; + movedistance = vlen(v); + if((stepdistance > 0 && stepdistance <= 16) && movedistance != 0) + { + self.flags = currentflags | FL_PARTIALGROUND; + return 1; + } + } + } + self.flags = currentflags; + v = currentorigin; + v_z = self.origin_z; + if (vlen(v - self.origin) <= 4) + setorigin(self, currentorigin); + return 0; +}; +// this is merely here to fix a problem with e3m5 +void(vector dir) BruteForceStep = +{ + local vector currentorigin; + local float currentflags, i, len; + + currentorigin = self.origin; + currentflags = self.flags; + len = vlen(dir); + if (len > 16) + dir = normalize(dir) * 16; + + setorigin(self, currentorigin + dir); + + while(i < 18 && !walkmove(0, 0)) + { + self.origin_z = currentorigin_z + i; + i = i + 2; + } + self.flags = currentflags; + if (i >=18) + setorigin(self, currentorigin); +}; + +void() PostPhysics = +{ + local vector obstr, org; + local float back, dst,cflags; + + self = self.owner; + + self.velocity = self.velocity - self.phys_obj.dest1 + self.phys_obj.velocity; + if (self.phys_obj.dest2 == self.origin) + { + setorigin(self, self.phys_obj.origin); + // might've been moved during other person's physics + // (teleporters / plats) + + if (self.movetype == MOVETYPE_WALK) + { + + if (self.phys_obj.dest1_x || self.phys_obj.dest1_y) + { + if ((self.flags & FL_ONGROUND) || (self.waterlevel <= 2)) + { + obstr = self.phys_obj.movedir - self.origin; + obstr_z = 0; + if (vlen(obstr) > 0.1) + { + dst = vlen(obstr); + back = vectoyaw(obstr); + cflags = self.flags; + self.flags = self.flags | FL_PARTIALGROUND; + if(walkmove(back, dst)) + { + self.flags = cflags; + self.phys_obj.dest1_z = 0; + self.velocity = self.velocity + self.phys_obj.dest1 - self.phys_obj.velocity; + } + else + { + if (dst > 1) + frik_obstructed(obstr, FALSE); + + org = self.origin; + self.flags = cflags; + obstr = self.phys_obj.dest1; + obstr_x = 0; + if (!botCheckForStep(obstr)) + { + obstr = self.phys_obj.dest1; + obstr_y = 0; + if (!botCheckForStep(obstr)) + { + // if no steps were found, bot is really obstucted + BruteForceStep(self.phys_obj.dest1); + } + } + } + } + } + } + } + } + + SV_CheckOnGround(); + + PlayerPostThink(); + BotAI(); + self.dmg_take = self.dmg_save = 0; + +}; +// Avoid calling BotAI and the physics at the same time +// Can trip the runaway loop counter + +void() SV_FlyMove = +{ + // This is nothing like the Quake function. + + if (self.phys_obj == world) + { + self.phys_obj = find(world,classname,"phys_obj"); + while (self.phys_obj.owner != self) + { + self.phys_obj = find(self.phys_obj,classname,"phys_obj"); + if (self.phys_obj == world) + { + error("No physics entity spawned!\nMake sure BotInit was called\n"); + } + } + } + + setmodel (self.phys_obj, string_null); + self.phys_obj.movetype = MOVETYPE_STEP; + + self.phys_obj.solid = SOLID_TRIGGER; + self.phys_obj.touch = RemoveThud; + setsize(self.phys_obj, self.mins, self.maxs); + self.phys_obj.dest2 = self.phys_obj.origin = self.origin; + self.phys_obj.watertype = 0; + self.phys_obj.movedir = self.origin + real_frametime * self.velocity; + self.phys_obj.dest1 = self.phys_obj.velocity = self.velocity; + self.phys_obj.velocity_z = self.phys_obj.velocity_z + sv_gravity * real_frametime; + self.phys_obj.flags = 0; + self.phys_obj.think = PostPhysics; + self.phys_obj.nextthink = time; +}; + + +void() SV_Physics_Toss = +{ + if (!SV_RunThink()) + return; + if (self.flags & FL_ONGROUND) + { + self.velocity = '0 0 0'; + BotAI(); + return; + } + if (self.movetype != MOVETYPE_FLY) + SV_AddGravity(1); + self.angles = self.angles + real_frametime * self.avelocity; + SV_FlyMove(); + +}; +void() SV_Physics_Client = +{ + + PlayerPreThink(); + + if (self.movetype == MOVETYPE_NONE) + { + if (!SV_RunThink()) + return; + PlayerPostThink(); + BotAI(); + + } + else if ((self.movetype == MOVETYPE_WALK) || (self.movetype == MOVETYPE_STEP)) + { + if (!SV_RunThink()) + return; + if (!(SV_CheckWater()) && (!(self.flags & FL_WATERJUMP))) + SV_AddGravity(1); + SV_FlyMove(); + } + else if ((self.movetype == MOVETYPE_TOSS) || (self.movetype == MOVETYPE_BOUNCE)) + { + SV_Physics_Toss(); + } + else if (self.movetype == MOVETYPE_FLY) + { + if (!SV_RunThink()) + return; + SV_FlyMove(); + } + else if (self.movetype == MOVETYPE_NOCLIP) + { + if (!SV_RunThink()) + return; + self.origin = self.origin + real_frametime * self.velocity; + + PlayerPostThink(); + BotAI(); + } + else + error ("SV_Physics_Client: Bad Movetype (BOT)"); + +}; + + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_qw.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_qw.qc new file mode 100755 index 00000000..fc5798b6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_qw.qc @@ -0,0 +1,964 @@ + +/* +====================================== +FrikBot X (Version 0.10.2) QW +====================================== + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + + +====================================== +These installation instructions only apply to QuakeWorld (as does this entire +file). For Normal Quake, please refer to bot.qc + +-------------------------------------- +To install on a new mod, do all this: +-------------------------------------- +Place all included bot*.qc files in the subdirectory "frikbot" +in your source folder, then... + +* Add the following lines to progs.src right after the defs.qc line +frikbot/bot_qw.qc +frikbot/bot_way.qc +frikbot/bot_fight.qc +frikbot/bot_ai.qc +frikbot/bot_misc.qc +frikbot/bot_phys.qc +frikbot/bot_move.qc +-------------------------------------- +* Comment out the following functions in defs.qc +sound, stuffcmd, sprint, aim, centerprint, setspawnparms +WriteByte, WriteChar, WriteShort, WriteLong, WriteCoord +WriteAngle, WriteString, WriteEntity +-------------------------------------- +* Add this to worldspawn() in world.qc, right at the very top, before InitBodyQue(); +BotInit(); // FrikBot +-------------------------------------- +* add this line to StartFrame() in world.qc, at the very top +BotFrame(); // FrikBot +-------------------------------------- +* Add these two lines to PlayerPreThink in client.qc at the very top +if (BotPreFrame()) // FrikBot + return; +-------------------------------------- +* Add this line to PlayerPostThink in client.qc at the very top +if (BotPostFrame()) // FrikBot + return; +-------------------------------------- +* Add the following line to the very top of Client Connect in client.qc +ClientInRankings(); // FrikBot +-------------------------------------- +* Add these lines to the very top of ClientDisconnect in client.qc +ClientDisconnected(); // FrikBot +-------------------------------------- +* Add these lines to the very top of SpectatorConnect in spectate.qc +ClientFixRankings(); // FrikBot +-------------------------------------- + +To install the waypoints: + +add + +waypoints/map_dm1.qc +waypoints/map_dm2.qc +waypoints/map_dm3.qc +waypoints/map_dm4.qc +waypoints/map_dm5.qc +waypoints/map_dm6.qc + +To progs.src, immediately after defs.qc + +To remove these waypoints: + +Delete the code in bot_map_load, located below. +*/ + +void() bot_map_load = +{ + // place your qc loaded waypoints here + + if (mapname == "dm1") + map_dm1(); + else if (mapname == "dm2") + map_dm2(); + else if (mapname == "dm3") + map_dm3(); + else if (mapname == "dm4") + map_dm4(); + else if (mapname == "dm5") + map_dm5(); + else if (mapname == "dm6") + map_dm6(); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Variables and shtuff + +bot.qc has become pretty much a header file +for all variable in the bot... + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +// ----- entity fields --- +.float wallhug, keys, oldkeys, ishuman; +.float b_frags, b_clientno, b_shirt, b_pants; +.float priority, ai_time, b_sound, missile_speed; +.float portal_time, b_skill, switch_wallhug; +.float b_aiflags, b_num, b_chattime; +.float b_entertime, b_userid; // QW shtuff +.float b_menu, b_menu_time, b_menu_value; +.float route_failed, dyn_flags, dyn_time; +.float dyn_plat; +.entity temp_way, last_way, phys_obj; +.entity target1, target2, target3, target4; +.entity _next, _last; +.entity current_way; +.vector b_angle, b_dest, mouse_emu, obs_dir; +.vector movevect, b_dir; +.vector dyn_dest; +.vector punchangle; // HACK - Don't want to screw with bot_phys + +// --------defines----- +float SVC_UPDATENAME = 13; +float SVC_UPDATEFRAGS = 14; +float SVC_UPDATECOLORS = 17; + +// used for the physics & movement AI +float KEY_MOVEUP = 1; +float KEY_MOVEDOWN = 2; +float KEY_MOVELEFT = 4; +float KEY_MOVERIGHT = 8; +float KEY_MOVEFORWARD = 16; +float KEY_MOVEBACK = 32; +float KEY_LOOKUP = 64; +float KEY_LOOKDOWN = 128; +float KEY_LOOKLEFT = 256; +float KEY_LOOKRIGHT = 512; + +// these are aiflags for waypoints +// some overlap to the bot +float AI_TELELINK_1 = 1; // link type +float AI_TELELINK_2 = 2; // link type +float AI_TELELINK_3 = 4; // link type +float AI_TELELINK_4 = 8; // link type +float AI_DOORFLAG = 16; // read ahead +float AI_PRECISION = 32; // read ahead + point +float AI_SURFACE = 64; // point +float AI_BLIND = 128; // read ahead + point +float AI_JUMP = 256; // point + ignore +float AI_DIRECTIONAL = 512; // read ahead + ignore +float AI_PLAT_BOTTOM = 1024; // read ahead +float AI_RIDE_TRAIN = 2048; // read ahead +float AI_SUPER_JUMP = 4096; // point + ignore + route test +float AI_SNIPER = 8192; // point type +float AI_AMBUSH = 16384; // point type +float AI_DOOR_NO_OPEN = 32768; // read ahead +float AI_DIFFICULT = 65536; // route test +float AI_TRACE_TEST = 131072; // route test + +// these are flags for bots/players (dynamic/editor flags) +float AI_OBSTRUCTED = 1; +float AI_HOLD_SELECT = 2; +float AI_ROUTE_FAILED = 2; +float AI_WAIT = 4; +float AI_DANGER = 8; + +// addition masks +float AI_POINT_TYPES = 29152; +float AI_READAHEAD_TYPES = 36528; +float AI_IGNORE_TYPES = 4864; + +float WM_UNINIT = 0; +float WM_DYNAMIC = 1; +float WM_LOADING = 2; +float WM_LOADED = 3; +// editor modes aren't available in QW, but we retain support of them +// since the editor is still built into the AI in places +float WM_EDITOR = 4; +float WM_EDITOR_DYNAMIC = 5; +float WM_EDITOR_DYNLINK = 6; + +float OPT_NOCHAT = 2; + +// -------globals----- +float active_clients1, active_clients2; +float max_clients, real_frametime; +float bot_count, b_options, lasttime; +float waypoint_mode, dump_mode; +float waypoints, direct_route, userid; +float sv_friction, sv_gravity; +float sv_accelerate, sv_maxspeed, sv_stopspeed; +entity fixer; +entity route_table; +entity b_temp1, b_temp2, b_temp3; +entity player_head, phys_head, way_head; +float busy_waypoints; + +float coop = 0; // hack + +// -------ProtoTypes------ +// external +void() ClientConnect; +void() ClientDisconnect; +void() SetNewParms; + +// rankings +float(float clientno) ClientBitFlag; +float() ClientNextAvailable; +void(float whatbot, float whatskill) BotConnect; +void(entity bot) BotDisconnect; +void(float clientno) BotInvalidClientNo; +void(entity who) UpdateClient; + +// waypointing +void() DynamicWaypoint; +entity(vector org) make_waypoint; +void() ClearAllWays; +void() FixWaypoints; +float() begin_route; +void(entity this, float direct) bot_get_path; +void() WaypointThink; +entity(entity start) FindWayPoint; + +// physics & movement +float(entity e) bot_can_rj; +void() bot_jump; +void() frik_bot_roam; +float(vector weird) frik_walkmove; +void() frik_movetogoal; +void() frik_obstacles; +float(float flag) frik_recognize_plat; +float(vector sdir) frik_KeysForDir; +void(vector whichway, float danger) frik_obstructed; +void() SV_Physics_Client; +void() SV_ClientThink; +void() CL_KeyMove; + +// ai & misc +string() PickARandomName; +float(entity targ) fov; +float(float y1, float y2) angcomp; +float(entity targ1, entity targ2) wisible; +float(entity targ) sisible; +float(entity targ) fisible; +vector(entity ent) realorigin; +void(entity ent) target_drop; +void(entity ent) target_add; +void() KickABot; +void() BotImpulses; +void(entity targ, float success) bot_lost; +string(float r) BotName; +float(float v) frik_anglemod; +void() bot_chat; +void(float tpic) bot_start_topic; + + +// ----------Commands--------- +void(entity e, float chan, string samp, float vol, float atten) frik_sound = #8; +void(entity client, string s) frik_stuffcmd = #21; +void(entity client, float level, string s) frik_sprint = #24; +vector(entity e, float sped) frik_aim = #44; +void(entity client, string s) frik_centerprint = #73; +void(entity e) frik_setspawnparms = #78; +void(float to, float f) frik_WriteByte = #52; +void(float to, float f) frik_WriteChar = #53; +void(float to, float f) frik_WriteShort = #54; +void(float to, float f) frik_WriteLong = #55; +void(float to, float f) frik_WriteCoord = #56; +void(float to, float f) frik_WriteAngle = #57; +void(float to, string s) frik_WriteString = #58; +void(float to, entity s) frik_WriteEntity = #59; + +//---------------------------------------------------------------------------- + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Function redclarations. These allow function +designed to work for clients (sprint, so forth) +to mainly not complain when working with a bot + +Although these shouldn't be needed anymore, +as the bots truly are clients now, if you don't +stop the SZ_ buffer from filling up by disabling +direct messages to the bots, it crashes quake :-( + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(entity client, string s) stuffcmd = +{ + if (client.ishuman) + frik_stuffcmd(client, s); +}; + +void(entity e) setspawnparms = +{ + if (e.ishuman) + frik_setspawnparms(e); + else + SetNewParms(); +}; +void(entity client, float level, string s) sprint = +{ + if (client.ishuman) + frik_sprint(client, level, s); +}; +void(entity client, string s) centerprint = +{ + if (client.ishuman) + frik_centerprint(client, s); +}; + +vector(entity e, float sped) aim = +{ + e.missile_speed = sped; + return frik_aim(e, sped); +}; + +void(entity e, float chan, string samp, float vol, float atten) sound = +{ + frik_sound(e, chan, samp, vol, atten); + if (samp == "items/inv3.wav") + return; + else if (e.classname == "player") + e.b_sound = time + 1; + else if (other.classname == "player") + other.b_sound = time + 1; +}; +void(float to, float f) WriteByte = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteByte(to, f); +}; +void(float to, float f) WriteChar = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteChar(to, f); +}; +void(float to, float f) WriteShort = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteShort(to, f); +}; +void(float to, float f) WriteLong = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteLong(to, f); +}; +void(float to, float f) WriteCoord = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteCoord(to, f); +}; +void(float to, float f) WriteAngle = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteAngle(to, f); +}; +void(float to, string s) WriteString = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteString(to, s); +}; +void(float to, entity s) WriteEntity = +{ + if ((to == MSG_ONE) && (msg_entity.ishuman != TRUE)) + return; + frik_WriteEntity(to, s); +}; + + +float(float clientno) ClientIsActive = +{ + if(clientno > 16) + { + if(active_clients2 & ClientBitFlag(clientno - 16)) + return TRUE; + else + return FALSE; + } + else + { + if(active_clients1 & ClientBitFlag(clientno)) + return TRUE; + else + return FALSE; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Stuff mentioned up top +it just links the bot into the mod + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClientFixRankings = +{ + local float cno; + if (self.switch_wallhug > time) + return; + self.switch_wallhug = 0; + + b_temp2 = nextent(world); + cno = 0; + + while (cno < max_clients) + { + if (!b_temp2.ishuman) + { + if (ClientIsActive(cno)) + UpdateClient(b_temp2); + } + cno = cno + 1; + b_temp2 = nextent(b_temp2); + } +}; + +void() ClientInRankings = +{ + local float cno; + + cno = self.colormap - 1; + BotInvalidClientNo (cno); + + if (player_head) + player_head._last = self; + self._next = player_head; + player_head = self; + userid = userid + 1; + self.b_userid = userid; + + if (!self.phys_obj) + { + b_temp2 = phys_head; + while (b_temp2 != world && b_temp2.owner != self) + b_temp2 = b_temp2._next; + self.phys_obj = b_temp2; + } + + if (self.ishuman == 2) + { + self.ishuman = FALSE; + return; + } + if(cno > 16) + active_clients2 = active_clients2 | ClientBitFlag(cno - 16); + else + active_clients1 = active_clients1 | ClientBitFlag(cno); + self.b_clientno = cno; + self.ishuman = TRUE; + self.switch_wallhug = time + 1; +}; + + +void() ClientDisconnected = +{ + if (player_head == self) + player_head = self._next; + if (self._next) + self._next._last = self._last; + if (self._last) + self._last._next = self._next; + if(self.b_clientno > 16) + active_clients2 = active_clients2 - (active_clients2 & ClientBitFlag(self.b_clientno - 16)); + else + active_clients1 = active_clients1 - (active_clients1 & ClientBitFlag(self.b_clientno)); +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotPreFrame & BotPostFrame, used to make the +bot easier to install + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +float () BotPreFrame = +{ + if (self.b_clientno == -1) + return TRUE; + if (self.ishuman) + if (self.switch_wallhug) + ClientFixRankings(); + if (self.b_frags != self.frags) + { + if (self.b_frags > self.frags) + { + if (pointcontents(self.origin) == CONTENT_LAVA) + bot_start_topic(10); + else + bot_start_topic(9); + } + else + bot_start_topic(2); + self.b_frags = self.frags; + if (!self.ishuman) + { + WriteByte(2, 14); + WriteByte(2, self.b_clientno); + WriteShort(2, self.frags); + } + } + DynamicWaypoint(); + return FALSE; +}; +float () BotPostFrame = +{ + if (self.b_clientno == -1) + return TRUE; + if (self.ishuman) + BotImpulses(); + return FALSE; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Chat code + +The rest of this code is in bot_rank.qc + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +void(string h) BotSay = // simulate talking by composing a 'chat' message +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 3); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, self.netname); + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 3); + WriteByte(MSG_ALL, 2); + WriteString(MSG_ALL, h); +}; +void() BotSayInit = +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 3); + WriteByte(MSG_ALL, 1); + WriteString(MSG_ALL, self.netname); +}; +void(string h) BotSay2 = +{ + WriteByte(MSG_ALL, 8); + WriteByte(MSG_ALL, 3); + WriteByte(MSG_ALL, 2); + WriteString(MSG_ALL, h); +}; +void(string h) BotSayTeam = +{ + // FBX QW doesn't support teamplay...yet +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotInit + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void() BotInit = +{ + local entity ent, fisent; + local float numents; + + // spawn entities for the physics + ent = nextent(world); + max_clients = 0; + + while(ent != world) + { + max_clients = max_clients + 1; + ent = nextent(ent); + } + + ent = nextent(world); + fisent = world; + while (numents < max_clients) + { + + phys_head = spawn(); + if (fisent) + fisent._next = phys_head; + phys_head._last = fisent; + fisent = phys_head; + ent.phys_obj = phys_head; + phys_head.classname = "phys_obj"; + phys_head.owner = ent; + numents = numents + 1; + ent = nextent(ent); + } + bot_map_load(); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Rankings 'utilities'. Written by Alan Kivlin, +this code just fools clients by sending precisely +the same network messages as when a real player +signs on to the server. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void(entity who) UpdateClient = +{ + WriteByte(2, 14 ); + WriteByte(2, who.b_clientno); + WriteShort(2, who.frags); + WriteByte(2, 36); + WriteByte(2, who.b_clientno); + WriteShort(2, 100 * (3 - who.b_skill)); + WriteByte(2, 37); // update entertime + WriteByte(2, who.b_clientno); // client number + WriteLong(2, time - who.b_entertime); // client entertime + WriteByte(2, 40 ); // update userinfo + WriteByte(2, who.b_clientno); // client number + WriteLong(2, who.b_userid); // client userid + WriteByte(2, 92); // \ + WriteByte(2, 98); // b + WriteByte(2, 111); // o + WriteByte(2, 116); // t + WriteByte(2, 116); // t + WriteByte(2, 111); // o + WriteByte(2, 109); // m + WriteByte(2, 99); // c + WriteByte(2, 111); // o + WriteByte(2, 108); // l + WriteByte(2, 111); // o + WriteByte(2, 114); // r + WriteByte(2, 92); // \ + if(who.b_pants > 9) + { + WriteByte(2, 49); + WriteByte(2, 38 + who.b_pants); + } + else + WriteByte(2, 48 + who.b_pants); + WriteByte(2, 92); // \ + WriteByte(2, 116); // t + WriteByte(2, 111); // o + WriteByte(2, 112); // p + WriteByte(2, 99); // c + WriteByte(2, 111); // o + WriteByte(2, 108); // l + WriteByte(2, 111); // o + WriteByte(2, 114); // r + WriteByte(2, 92); // \ + if(who.b_shirt > 9) + { + WriteByte(2, 49); + WriteByte(2, 38 + who.b_shirt); + } + else + WriteByte(2, 48 + who.b_shirt); + WriteByte(2, 92); // \ + WriteByte(2, 116); // t + WriteByte(2, 101); // e + WriteByte(2, 97); // a + WriteByte(2, 109); // m + WriteByte(2, 92); // \ + WriteByte(2, 98); // b + WriteByte(2, 111); // o + WriteByte(2, 116); // t + // FIXME: do teams properly + // note this has no effect on infokey + WriteByte(2, 92 ); // \ + WriteByte(2, 115); // s + WriteByte(2, 107); // k + WriteByte(2, 105); // i + WriteByte(2, 110); // n + WriteByte(2, 92); // \ + WriteByte(2, 98); // b + WriteByte(2, 97); // a + WriteByte(2, 115); // s + WriteByte(2, 101); // e + WriteByte(2, 92); // \ + WriteByte(2, 110); // n + WriteByte(2, 97); // a + WriteByte(2, 109); // m + WriteByte(2, 101); // e + WriteByte(2, 92); // \ + WriteString( 2, who.netname); +}; + +float(float clientno) ClientBitFlag = +{ + local float bitflag; + bitflag = 1; + while(clientno > 0) + { + bitflag = bitflag * 2; + clientno = clientno - 1; + } + return bitflag; +}; + +float() ClientNextAvailable = +{ + local float clientno; + // I want to do this top down, but QW won't let me + clientno = 0; + while(clientno < max_clients) + { + clientno = clientno + 1; + + if(!ClientIsActive(clientno)) + return clientno; + } + return -1; +}; + + +void(entity e1, entity e2, float flag) DeveloperLightning = {}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotConnect and related functions. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +entity(float num) GetClientEntity = +{ + local entity upsy; + upsy = world; + num = num + 1; + while (num > 0) + { + num = num - 1; + upsy = nextent(upsy); + } + return upsy; +}; + +void(float whatbot, float whatskill) BotConnect = +{ + local float f; + local string h; + local entity uself; + + f = ClientNextAvailable(); + uself = self; + if(f == -1) + { + bprint(PRINT_HIGH, "Unable to connect a bot, server is full.\n"); + return; + } + + bot_count = bot_count + 1; + self = GetClientEntity(f); + bot_start_topic(1); + self.b_clientno = f; + self.colormap = f + 1; + if (whatbot) + self.netname = BotName(whatbot); + else + self.netname = PickARandomName(); + // players can set skill all weird, so leave these checks in + whatskill = rint(whatskill); + if (whatskill > 3) + whatskill = 3; + else if (whatskill < 0) + whatskill = 0; + self.b_skill = whatskill; + self.b_entertime = time; + self.team = self.b_pants + 1; + UpdateClient(self); + SetNewParms(); + self.ishuman = 2; + ClientConnect(); + PutClientInServer(); + if(f > 16) + active_clients2 = active_clients2 | ClientBitFlag(f - 16); + else + active_clients1 = active_clients1 | ClientBitFlag(f); + self = uself; +}; + +void(entity bot) BotDisconnect = +{ + local string h; + local entity uself; + uself = self; + self = bot; + + bot_count = bot_count - 1; + + ClientDisconnect(); + + //if (self.b_clientno != -1) + //{ + // the bot's client number is not in use by a real player so we + // must remove it's entry in the rankings + // Quake engine sets all fields to 0, can only do the most important here + self.b_frags = self.frags = 0; + self.netname = ""; + self.classname = ""; + self.health = 0; + self.items = 0; + self.armorvalue = 0; + self.weaponmodel = ""; + self.b_pants = 0; + self.b_shirt = 0; + self.ammo_shells = self.ammo_nails = self.ammo_rockets = self.ammo_cells = 0; + UpdateClient(self); + if(self.b_clientno > 16) + active_clients2 = active_clients2 - (active_clients2 & ClientBitFlag(self.b_clientno - 16)); + else + active_clients1 = active_clients1 - (active_clients1 & ClientBitFlag(self.b_clientno)); + self.b_clientno = -1; + //} + self = uself; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BotInvalidClientNo +kicks a bot if a player connects and takes the bot's space + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(float clientno) BotInvalidClientNo = +{ + local entity bot; + + if (ClientIsActive(clientno)) + { + bot = GetClientEntity (clientno); + + if (bot.b_clientno == clientno) + { + bot.b_clientno = -1; + BotDisconnect(bot); + if(clientno > 16) + active_clients2 = active_clients2 | (active_clients2 & ClientBitFlag(clientno - 16)); + else + active_clients1 = active_clients1 | (active_clients1 & ClientBitFlag(clientno)); + BotConnect(self.b_num, self.b_skill); + return; + } + } +}; + +void() BotFrame = +{ + local float num; + local string h; + + h = infokey(world, "bot_options"); + b_options = stof(h); + + // for the sake of speed + sv_maxspeed = cvar("sv_maxspeed"); + sv_gravity = cvar("sv_gravity"); + sv_friction = cvar("sv_friction"); + sv_accelerate = cvar("sv_accelerate"); + sv_stopspeed = cvar("sv_stopspeed"); + real_frametime = time - lasttime; // in QW frametime is fuxx0red + lasttime = time; + + self = nextent(world); + num = 0; + while (num < max_clients) + { + if (self.ishuman == FALSE) + { + if (self.b_clientno > 0) + { + frik_obstacles(); + CL_KeyMove(); + SV_ClientThink(); + SV_Physics_Client(); + // this is sickening + if (self.phys_obj) + { + if (self.phys_obj.modelindex != self.modelindex) + { + setmodel(self.phys_obj, "progs/player.mdl"); + self.phys_obj.modelindex = self.modelindex; + } + self.phys_obj.frame = self.frame; + self.phys_obj.angles = self.angles; + self.phys_obj.colormap = self.colormap; + self.phys_obj.effects = self.effects; + } + } + } + self = nextent(self); + num = num + 1; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bot Impulses. Allows the player to perform bot +related functions. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() BotImpulses = +{ + local float f; + local string h; + + if (self.impulse == 100) + { + h = infokey(world, "skill"); + f = stof(h); + BotConnect(0, f); + } + else if (self.impulse == 102) + KickABot(); + else + return; + self.impulse = 0; +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_way.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_way.qc new file mode 100755 index 00000000..5dfc841e --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/frikbot/bot_way.qc @@ -0,0 +1,1007 @@ + /*********************************************** +* * +* FrikBot Waypoints * +* "The better than roaming AI" * +* * +***********************************************/ + +/* + +This program is in the Public Domain. My crack legal +team would like to add: + +RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS" +AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE +ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR +FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN +NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY +GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, +EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC" +SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES. + +You accept this software on the condition that you +indemnify and hold harmless Ryan "FrikaC" Smith from +any and all liability or damages to third parties, +including attorney fees, court costs, and other +related costs and expenses, arising out of your use +of this software irrespective of the cause of said +liability. + +The export from the United States or the subsequent +reexport of this software is subject to compliance +with United States export control and munitions +control restrictions. You agree that in the event you +seek to export this software, you assume full +responsibility for obtaining all necessary export +licenses and approvals and for assuring compliance +with applicable reexport restrictions. + +Any reproduction of this software must contain +this notice in its entirety. + +*/ + + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Linking code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +float (entity e1, entity e2) CheckLinked = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return FALSE; + else if (e1.target1 == e2) + { + if (e1.b_aiflags & AI_TELELINK_1) + return 2; + else return TRUE; + } + else if (e1.target2 == e2) + { + if (e1.b_aiflags & AI_TELELINK_2) + return 2; + else return TRUE; + } + else if (e1.target3 == e2) + { + if (e1.b_aiflags & AI_TELELINK_3) + return 2; + else return TRUE; + } + else if (e1.target4 == e2) + { + if (e1.b_aiflags & AI_TELELINK_4) + return 2; + else return TRUE; + } + + else return FALSE; +}; + + +float (entity e1, entity e2) LinkWays = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return FALSE; + else if (CheckLinked(e1, e2)) + return FALSE; // already linked!!! + + if (e1.target1 == world) + { + e1.target1 = e2; + return TRUE; + } + else if (e1.target2 == world) + { + e1.target2 = e2; + return TRUE; + } + else if (e1.target3 == world) + { + e1.target3 = e2; + return TRUE; + } + else if (e1.target4 == world) + { + e1.target4 = e2; + return TRUE; + } + else return FALSE; + +}; +// Link Ways part 2, used only for teleporters + +float (entity e1, entity e2) TeleLinkWays = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return FALSE; + else if (CheckLinked(e1, e2)) + return FALSE; // already linked!!! + + if (e1.target1 == world) + { + e1.target1 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_1; + return TRUE; + } + else if (e1.target2 == world) + { + e1.target2 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_2; + return TRUE; + } + else if (e1.target3 == world) + { + e1.target3 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_3; + return TRUE; + } + else if (e1.target4 == world) + { + e1.target4 = e2; + e1.b_aiflags = e1.b_aiflags | AI_TELELINK_4; + return TRUE; + } + else + return FALSE; + +}; + +void (entity e1, entity e2) UnlinkWays = +{ + if ((e1 == e2) || (e2 == world) || (e1 == world)) + return; + else if (!CheckLinked(e1, e2)) + return; + + if (e1.target1 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_1); + e1.target1 = world; + } + if (e1.target2 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_2); + e1.target2 = world; + } + if (e1.target3 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_3); + e1.target3 = world; + } + if (e1.target4 == e2) + { + e1.b_aiflags = e1.b_aiflags - (e1.b_aiflags & AI_TELELINK_4); + e1.target4 = world; + } + +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +FindWaypoint + +This is used quite a bit, by many different +functions big lag causer + +Finds the closest, fisible, waypoint to e + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +entity(entity start) FindWayPoint = +{ + local entity t; + local vector org; + local float dst, tdst; + local entity best; + + org = realorigin(self); + + t = way_head; + if (start != world) + { + dst = vlen(start.origin - org); + best = start; + } + else + { + dst = 100000; + best = world; + } + while(t) + { + // real players cut through ignore types + if (dst < 20) + return best; + if (!(t.b_aiflags & AI_IGNORE_TYPES) || self.ishuman) + { + tdst = vlen(t.origin - org); + if (tdst < dst) + { + if (sisible(t)) + { + dst = tdst; + best = t; + } + } + } + t = t._next; + } + return best; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Spawning Code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +entity way_foot; // Ugh. Do I need a foot for this or not? + +entity(vector org) make_waypoint = +{ + local entity point; + point = spawn(); + point.classname = "waypoint"; + point.solid = SOLID_TRIGGER; + point.movetype = MOVETYPE_NONE; + point.items = -1; + setorigin(point, org); + + setsize(point, VEC_HULL_MIN, VEC_HULL_MAX); + waypoints = waypoints + 1; + if (!way_head) + { + way_head = point; + way_foot = point; + } + else + { + way_foot._next = point; + point._last = way_foot; + way_foot = point; + } + + point.count = waypoints; + if (waypoint_mode > WM_LOADED) // editor modes + setmodel(point, "progs/s_bubble.spr"); + return point; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Dynamic Waypoint spawning and linking. Not +very good all things considered. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() DynamicWaypoint = +{ + local entity t; + local float dist, dynlink, dynpoint, editor; + + if (self.teleport_time > self.portal_time) + { + if (!self.flags & FL_WATERJUMP) + { + self.dyn_flags = 2; + if (!self.ishuman) + { + bot_lost(self.target1, TRUE); + self.enemy = world; + } + } + self.portal_time = self.teleport_time; + } +// stacking everything on waypoint_mode might've been good for the editor, +// but it sucks to beat hell for this code. + + +// convert waypoint_mode to something more usable.. + if (waypoint_mode > WM_LOADED) + { + if (self.ishuman) + { + if (waypoint_mode == WM_EDITOR_DYNLINK) + dynlink = 1; + else if (waypoint_mode == WM_EDITOR_DYNAMIC) + dynlink = dynpoint = 1; + editor = 1; + } + } + else if (waypoint_mode == WM_DYNAMIC) + dynlink = dynpoint = 1; + +// if there's nothing for dynamic to do.. + if (!dynpoint) + { + if (!editor) + return; + } +// for speed sake, I won't have bots dynamic waypoint in coop + if (!self.ishuman) + if (coop) + return; + +// don't waypoint in single player + if (max_clients < 2) + return; +// if you're dead + else if (self.health <= 0) + { + if (dynpoint) + { + if (self.current_way) + { + if (pointcontents(self.origin) < -4) + { + if (self.current_way.b_aiflags & AI_BLIND) + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_PRECISION; + else + self.current_way.b_aiflags = self.current_way.b_aiflags | AI_BLIND; + } + } + } + self.dyn_dest = '0 0 0'; + self.current_way = world; + self.dyn_flags = 0; + return; + } + +// you shouldn't be making waypoints mid air + if (dynpoint) + { + if (!((self.flags & FL_ONGROUND) || self.waterlevel == 3)) + { + if (self.dyn_flags != 2) + { + self.dyn_flags = 1; + } + return; + } + } +// keep from doing the rest of this every frame + if (self.dyn_time > time) + return; + self.dyn_time = time + 0.2; + +// display the links for editor mode + if (editor) + { + if (self.current_way) + { + if (self.current_way.target1) + DeveloperLightning(self.current_way, self.current_way.target1, self.current_way.b_aiflags & AI_TELELINK_1); + if (self.current_way.target2) + DeveloperLightning(self.current_way, self.current_way.target2, self.current_way.b_aiflags & AI_TELELINK_2); + if (self.current_way.target3) + DeveloperLightning(self.current_way, self.current_way.target3, self.current_way.b_aiflags & AI_TELELINK_3); + if (self.current_way.target4) + DeveloperLightning(self.current_way, self.current_way.target4, self.current_way.b_aiflags & AI_TELELINK_4); + } + if (self.b_aiflags & AI_HOLD_SELECT) + return; + } + + t = FindWayPoint(self.current_way); + if (t) + { + dist = vlen(self.origin - t.origin); + if (dist < 192) + { + if (dist < 64) + { + + if (t != self.current_way) + { + if (dynlink) + { + if (!self.dyn_flags) + { + if (wisible(t, self.current_way)) + LinkWays(t, self.current_way); + } + if (self.dyn_flags == 2) + TeleLinkWays(self.current_way, t); + else if (wisible(t, self.current_way)) + LinkWays(self.current_way, t); + } + if (editor) + { + setmodel(t, "progs/s_light.spr"); + if (self.current_way) + setmodel(self.current_way, "progs/s_bubble.spr"); + } + } + self.current_way = t; + self.dyn_flags = 0; + } + self.dyn_dest = self.origin + self.view_ofs; + return; + } + } + + if (frik_recognize_plat(FALSE)) + { + if (vlen(trace_ent.velocity) > 0) + { + if (self.dyn_plat) + return; + self.dyn_plat = TRUE; + if (!self.dyn_flags) + self.dyn_flags = 1; + //bprint("on a plat!!!!!\n"); + } + else + self.dyn_plat = FALSE; + } + else + self.dyn_plat = FALSE; + + if (self.dyn_flags == 2) + self.dyn_dest = self.origin + self.view_ofs; + else if (self.dyn_dest == '0 0 0') + self.dyn_dest = self.origin + self.view_ofs; + if (!dynpoint) + return; + t = make_waypoint(self.dyn_dest); + + if (!self.dyn_flags) + { + if (wisible(t, self.current_way)) + LinkWays(t, self.current_way); + } + if (self.dyn_flags == 2) + TeleLinkWays(self.current_way, t); + else if (wisible(t, self.current_way)) + LinkWays(self.current_way, t); + + if (editor) + { + setmodel(t, "progs/s_light.spr"); + if (self.current_way) + setmodel(self.current_way, "progs/s_bubble.spr"); + } + self.current_way = t; + self.dyn_flags = 0; + + self.dyn_dest = self.origin + self.view_ofs; + + if (frik_recognize_plat(FALSE)) + { + if (trace_ent.classname == "door") + t.b_aiflags = t.b_aiflags | AI_DOORFLAG; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Waypoint Loading from file + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClearAllWays = +{ + + local entity t, n; + t = way_head; + while(t) + { + n = t._next; + remove(t); + t = n; + } + way_head = world; + way_foot = world; + waypoints = 0; +}; + +entity(float num) WaypointForNum = +{ + local entity t; + if (!num) + return world; + + t = way_head; + while (t) + { + if (t.count == num) + return t; + t = t._next; + } + return world; +}; + +void() FixThisWaypoint = +{ + self.enemy.target1 = WaypointForNum(self.enemy.b_pants); + self.enemy.target2 = WaypointForNum(self.enemy.b_skill); + self.enemy.target3 = WaypointForNum(self.enemy.b_shirt); + self.enemy.target4 = WaypointForNum(self.enemy.b_frags); + self.enemy = self.enemy._next; + self.nextthink = time; + if (self.enemy == world) + { + remove(self); + fixer = world; + } +}; + +void() FixWaypoints = +{ + if (!fixer) + fixer = spawn(); + fixer.nextthink = time; + fixer.think = FixThisWaypoint; + fixer.enemy = way_head; +}; + + + +void(entity what) delete_waypoint = +{ + local entity t; + + if (way_head == what) + way_head = what._next; + if (way_foot == what) + way_foot = what._last; + if (what._last) + what._last._next = what._next; + if (what._next) + what._next._last = what._last; + waypoints = 0; + t = way_head; + while(t) + { + t.count = waypoints = waypoints + 1; + if (CheckLinked(t, what)) + UnlinkWays(t, what); + t = t._next; + } + if (self.current_way == what) + self.current_way = world; + remove(what); +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +FindRoute & FindThing used by the pathing code +in bot_ai.qc + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +entity(string s) FindThing = +{ + local entity t; + local float tdst, dst; + local entity best; + dst = 100000; + best = world; + t = find (world, classname, s); + while (t != world) + { + tdst = vlen(((t.absmin + t.absmax) * 0.5) - self.origin); + if (tdst < dst) + { + dst = tdst; + best = t; + } + t = find(t, classname, s); + } + return best; +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +FindRoute, this is a key function in the +pathing. The name is a bit misleading, this +code finds the closest waypoint that is part +of a route calculated by the begin_route and +end_route routines This is a definite path to +an object. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +entity(entity lastone) FindRoute = +{ + // kinda like FindWaypoint, only of this bots route though + local entity t, best; + local float dst, tdst, flag; + flag = ClientBitFlag(self.b_clientno); + + if (lastone) + { + if (lastone.target1.b_sound & flag) + return lastone.target1; + else if (lastone.target2.b_sound & flag) + return lastone.target2; + else if (lastone.target3.b_sound & flag) + return lastone.target3; + else if (lastone.target4.b_sound & flag) + return lastone.target4; + } + + t = way_head; + dst = 100000; + best = world; + while(t) + { + tdst = vlen(t.origin - self.origin); + if ((tdst < dst) && (t.b_sound & flag)) + { + dst = tdst; + best = t; + } + t = t._next; + } + return best; +}; +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Route & path table management + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() ClearRouteTable = +{ + // cleans up route table + + local entity t; + t = way_head; + while (t) + { + t. keys = FALSE; + t.enemy = world; + t.items = -1; // not in table + t = t._next; + } +}; + +void() ClearMyRoute = +{ + local float flag; + local entity t; + + flag = ClientBitFlag(self.b_clientno); + + t = way_head; + while (t) + { + t.b_sound = t.b_sound - (t.b_sound & flag); + t = t._next; + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Mark_path + +After the route has been found, mark it with +bitflags so the table can be used for a +different bot. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + + +void(entity this) mark_path = +{ + local entity t, oself; + local float flag; + + ClearMyRoute(); + + oself = self; + self = this; + t = FindWayPoint(this.current_way); + self = oself; + // FIXME + // ugh, better way to find players please!!! + if (this.classname != "player") + this.current_way = t; + + if (t.enemy == world) + { + bot_lost(this, FALSE); + self.route_failed = TRUE; + return; + } + + flag = ClientBitFlag(self.b_clientno); + + while(t) + { + if (t.b_sound & flag) + return; + if (t == self.last_way) + return; + t.b_sound = t.b_sound | flag; + t = t.enemy; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +WaypointThink + +Calculates the routes. We use thinks to avoid +tripping the runaway loop counter + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(entity e2, float b_bit) FollowLink = +{ + local float dist; + + if (self.b_aiflags & b_bit) + dist = self.items; + else + dist = vlen(self.origin - e2.origin) + self.items; + + // check if this is an RJ link + if (e2.b_aiflags & AI_SUPER_JUMP) + { + if (!bot_can_rj(route_table)) + return; + } + if (e2.b_aiflags & AI_DIFFICULT) + dist = dist + 1000; + + if ((dist < e2.items) || (e2.items == -1)) + { + if (!e2.keys) + busy_waypoints = busy_waypoints + 1; + e2.keys = TRUE; + e2.items = dist; + e2.think = WaypointThink; + e2.nextthink = time; + e2.enemy = self; + } +}; + +void() WaypointThink = +{ + local entity oself; + + if (self.items == -1) + return; + // can you say ugly? + if (self.b_aiflags & AI_TRACE_TEST) + { + if (self.target1) + { + traceline(self.origin, self.target1.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target1, AI_TELELINK_1); + } + if (self.target2) + { + traceline(self.origin, self.target2.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target2, AI_TELELINK_2); + } + if (self.target3) + { + traceline(self.origin, self.target3.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target3, AI_TELELINK_3); + } + if (self.target4) + { + traceline(self.origin, self.target4.origin, TRUE, self); + if (trace_fraction == 1) + FollowLink(self.target4, AI_TELELINK_4); + } + } + else + { + if (self.target1) + FollowLink(self.target1, AI_TELELINK_1); + if (self.target2) + FollowLink(self.target2, AI_TELELINK_2); + if (self.target3) + FollowLink(self.target3, AI_TELELINK_3); + if (self.target4) + FollowLink(self.target4, AI_TELELINK_4); + } + + busy_waypoints = busy_waypoints - 1; + self.keys = FALSE; + + if (busy_waypoints <= 0) + { + if (direct_route) + { + oself = self; + self = route_table; + bot_get_path(self.target1, FALSE); + self = oself; + direct_route = FALSE; + } + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +begin_route and bot_get_path + +PLEASE NOTE: bot_get_path replaces the old +calls to begin_route. + +Routing isn't done all at once now, but in two +stages, the bot will calc a route *THEN* +choose a target, *THEN* mark a path. + +Boy it's confusing. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +float() begin_route = +{ + if (busy_waypoints > 0) + return FALSE; + + if (route_table != world) + { + if (!route_table.ishuman) + { + if (route_table.b_clientno != -1) + return FALSE; + } + } + + route_table = self; + ClearRouteTable(); + self.last_way = FindWayPoint(self.current_way); + + if (self.last_way != world) + { + self.last_way.items = vlen(self.last_way.origin - self.origin); + self.last_way.nextthink = time; + self.last_way.think = WaypointThink; + self.last_way.keys = TRUE; + busy_waypoints = 1; + return TRUE; + } + else + { + route_table = world; + busy_waypoints = 0; + return FALSE; + } +}; + +void(entity this, float direct) bot_get_path = +{ + if (this == world) + return; + + if (route_table == self) + { + if (busy_waypoints <= 0) + { + route_table = world; + mark_path(this); + } + return; + } + if (direct) + { + if(begin_route()) + direct_route = TRUE; + else + bot_lost(this, FALSE); + return; + } +}; + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BSP/QC Waypoint loading + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void() waypoint = +{ + self.solid = SOLID_TRIGGER; + self.movetype = MOVETYPE_NONE; + setorigin(self, self.origin); + + setsize(self, VEC_HULL_MIN, VEC_HULL_MAX); + waypoints = waypoints + 1; + if (!way_head) + { + way_head = self; + way_foot = self; + } + else + { + way_foot._next = self; + self._last = way_foot; + way_foot = self; + } + + self.count = waypoints; + waypoint_mode = WM_LOADED; + if (self.count == 1) + { + localcmd("echo BSP waypoints detected\n"); + self.think = FixWaypoints; // wait until all bsp loaded points are spawned + self.nextthink = time; + } +}; + +void(vector org, vector bit1, float bit4, float flargs) make_way = +{ + local entity y; + waypoint_mode = WM_LOADED; + y = make_waypoint(org); + y.b_aiflags = flargs; + y.b_pants = bit1_x; + y.b_skill = bit1_y; + y.b_shirt = bit1_z; + y.b_frags = bit4; + if (y.count == 1) + { + localcmd("echo QuakeC waypoints detected\n"); + y.think = FixWaypoints; // wait until all qc loaded points are spawned + y.nextthink = time; + } +}; + + +/* +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Temporary Marker code + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +void(vector org) SpawnTempWaypoint = +{ + local entity tep; + + if (!self.temp_way) + self.temp_way = tep = spawn(); + else + tep = self.temp_way; + + tep.classname = "temp_waypoint"; + tep.solid = SOLID_TRIGGER; + tep.movetype = MOVETYPE_NOCLIP; + setorigin(tep, org); + target_add(tep); + setsize(tep, VEC_HULL_MIN, VEC_HULL_MAX); // FIXME: convert these to numerical +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/fteqccgui.exe b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/fteqccgui.exe new file mode 100755 index 00000000..03ae0933 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/fteqccgui.exe differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/items.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/items.qc new file mode 100755 index 00000000..989313ee --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/items.qc @@ -0,0 +1,1503 @@ +/* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD +BE .8 .3 .4 IN COLOR */ +void () W_SetCurrentAmmo; +void (float weap) W_WeaponSwitch; +void (entity ent) W_UpdateAmmoCounts; + +void() SUB_regen = +{ + self.model = self.mdl; // restore original model + self.solid = SOLID_TRIGGER; // allow it to be touched again + sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM); // play respawn sound + setorigin (self, self.origin); +}; + + + +/*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8) +prints a warning message when spawned +*/ +void() noclass = +{ + dprint ("noclass spawned at"); + dprint (vtos(self.origin)); + dprint ("\n"); + remove (self); +}; + +// names of weapons function +string(float weap) I_WeaponName = +{ + switch (weap) + { + case IT_AXE: + return "Axe"; + case IT_SHOTGUN: + return "Shotgun"; + case IT_SUPER_SHOTGUN: + return "Double-barrelled Shotgun"; + case IT_NAILGUN: + return "Nailgun"; + case IT_SUPER_NAILGUN: + return "Super Nailgun"; + case IT_GRENADE_LAUNCHER: + return "Grenade Launcher"; + case IT_ROCKET_LAUNCHER: + return "Rocket Launcher"; + case IT_LIGHTNING: + return "Thunderbolt"; + } + + return ""; +} + + + +void() q_touch; + +void() q_touch = +{ + local string s, t; + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + self.mdl = self.model; + + sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + other.items = other.items | IT_QUAD; + self.model = string_null; + if (deathmatch == 4) + { + other.armortype = 0; + other.armorvalue = 0; + other.ammo_cells_real = 0; + W_UpdateAmmoCounts(other); + } + +// do the apropriate action + other.super_time = 1; + other.super_damage_finished = self.cnt; + + s=ftos(rint(other.super_damage_finished - time)); + t = " recovered a Quad with "; + if (deathmatch == 4) + t = " recovered an OctaPower with "; + + bprint4 (PRINT_LOW, other.netname, t, s, " seconds remaining!\n"); + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +void(float timeleft) DropQuad = +{ + local entity item; + + item = spawn(); + item.origin = self.origin; + + item.velocity_z = 300; + item.velocity_x = -100 + (random() * 200); + item.velocity_y = -100 + (random() * 200); + + item.flags = FL_ITEM; + item.solid = SOLID_TRIGGER; + item.movetype = MOVETYPE_TOSS; + item.noise = "items/damage.wav"; + setmodel (item, "progs/quaddama.mdl"); + setsize (item, '-16 -16 -24', '16 16 32'); + item.cnt = time + timeleft; + item.touch = q_touch; + item.nextthink = time + timeleft; // remove it with the time left on it + item.think = SUB_Remove; +}; + + +void() r_touch; + +void() r_touch = +{ +local string s; + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + self.mdl = self.model; + + sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + other.items = other.items | IT_INVISIBILITY; + self.model = string_null; + +// do the apropriate action + other.invisible_time = 1; + other.invisible_finished = self.cnt; + s=ftos(rint(other.invisible_finished - time)); + bprint4 (PRINT_LOW, other.netname, " recovered a Ring with ", s, " seconds remaining!\n"); + + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +void(float timeleft) DropRing = +{ + local entity item; + + item = spawn(); + item.origin = self.origin; + + item.velocity_z = 300; + item.velocity_x = -100 + (random() * 200); + item.velocity_y = -100 + (random() * 200); + + item.flags = FL_ITEM; + item.solid = SOLID_TRIGGER; + item.movetype = MOVETYPE_TOSS; + item.noise = "items/inv1.wav"; + setmodel (item, "progs/invisibl.mdl"); + setsize (item, '-16 -16 -24', '16 16 32'); + item.cnt = time + timeleft; + item.touch = r_touch; + item.nextthink = time + timeleft; // remove after 30 seconds + item.think = SUB_Remove; +}; + +/* +============ +PlaceItem + +plants the object on the floor +============ +*/ +void() PlaceItem = +{ + local float oldz; + + self.mdl = self.model; // so it can be restored on respawn + self.flags = FL_ITEM; // make extra wide + self.solid = SOLID_TRIGGER; + self.movetype = MOVETYPE_TOSS; + self.velocity = '0 0 0'; + self.origin_z = self.origin_z + 6; + oldz = self.origin_z; + if (!droptofloor()) + { + dprint ("Bonus item fell out of level at "); + dprint (vtos(self.origin)); + dprint ("\n"); + remove(self); + return; + } +}; + +/* +============ +StartItem + +Sets the clipping size and plants the object on the floor +============ +*/ +void() StartItem = +{ + self.nextthink = time + 0.2; // items start after other solids + self.think = PlaceItem; +}; + +/* +========================================================================= + +HEALTH BOX + +========================================================================= +*/ +// +// T_Heal: add health to an entity, limiting health to max_health +// "ignore" will ignore max_health limit +// +float (entity e, float hamount, float ignore) T_Heal = +{ + if (e.health <= 0) + return 0; + if ((!ignore) && (e.health >= other.max_health)) + return 0; + hamount = ceil(hamount); + + e.health = e.health + hamount; + if ((!ignore) && (e.health >= other.max_health)) + e.health = other.max_health; + + + if (e.health > e.max_health + 150) + e.health = e.max_health + 150; + + e.healdecay = time + 5; + return 1; +}; + +/*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth +Health box. Normally gives 25 points. +Rotten box heals 5-10 points, +megahealth will add 100 health, then +rot you down to your maximum health limit, +one point per second. +*/ + +void() health_touch; + +void() item_health = +{ + self.touch = health_touch; + + if (self.spawnflags & H_ROTTEN) + { + precache_model("progs/health.mdl"); + + precache_sound("items/r_item1.wav"); + setmodel(self, "progs/health.mdl"); + self.noise = "items/r_item1.wav"; + self.healamount = 15; + self.healtype = 0; + } + else + if (self.spawnflags & H_MEGA) + { + precache_model("progs/health.mdl"); + precache_sound("items/r_item2.wav"); + setmodel(self, "progs/health.mdl"); + self.noise = "items/r_item2.wav"; + self.healamount = 100; + self.healtype = 2; + } + else + { + precache_model("progs/health.mdl"); + precache_sound("items/health1.wav"); + setmodel(self, "progs/health.mdl"); + self.noise = "items/health1.wav"; + self.healamount = 25; + self.healtype = 1; + } + setsize (self, '0 0 0', '32 32 56'); + StartItem (); +}; + + +void() health_touch = +{ + local string s; + + if (deathmatch == 4) + if (other.invincible_time > time) + return; + + if (other.classname != "player") + return; + + if (self.healtype == H_MEGA) // Megahealth? Ignore max_health... + { + if (other.health >= other.max_health + 150) + return; + if (!T_Heal(other, self.healamount, 1)) + return; + } + else + { + if (!T_Heal(other, self.healamount, 0)) + return; + } + + s = ftos(self.healamount); + sprint3(other, PRINT_LOW, "You receive ", s, " health\n"); + +// health touch sound + sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM); + + stuffcmd (other, "bf\n"); + + self.model = string_null; + self.solid = SOLID_NOT; + + // Megahealth = rot down the player's super health + if (deathmatch) // TODO: are these rules right? + { + if (deathmatch != 2) // deathmatch 2 is the silly old rules + { + if (self.healtype == H_MEGA) + self.nextthink = time + 45; // should I account for health healed instead? + else + self.nextthink = time + 20; + self.think = SUB_regen; + } + } + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + +/* +=============================================================================== + +ARMOR + +=============================================================================== +*/ + +void() armor_touch; + +void() armor_touch = +{ + local float type, value, bit; + + if (other.health <= 0) + return; + if (other.classname != "player") + return; + + if (deathmatch == 4) + + if (other.invincible_time > 0) + return; + + switch (self.classname) + { + case "item_armor1": + type = 0.3; + value = 100; + bit = IT_ARMOR1; + break; + case "item_armor2": + type = 0.6; + value = 150; + bit = IT_ARMOR2; + break; + case "item_armorInv": + type = 0.8; + value = 200; + bit = IT_ARMOR3; + break; + } + + if (other.armortype*other.armorvalue >= type*value) + return; + + other.armortype = type; + other.armorvalue = value; + other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit; + + self.solid = SOLID_NOT; + self.model = string_null; + if (deathmatch && deathmatch != 2) + { + self.nextthink = time + 20; + self.think = SUB_regen; + } + + sprint1(other, PRINT_LOW, "You got armor\n"); +// armor touch sound + sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +/*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() item_armor1 = +{ + self.touch = armor_touch; + precache_model ("progs/armor.mdl"); + setmodel (self, "progs/armor.mdl"); + self.skin = 0; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() item_armor2 = +{ + self.touch = armor_touch; + precache_model ("progs/armor.mdl"); + setmodel (self, "progs/armor.mdl"); + self.skin = 1; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32) +*/ + +void() item_armorInv = +{ + self.touch = armor_touch; + precache_model ("progs/armor.mdl"); + setmodel (self, "progs/armor.mdl"); + self.skin = 2; + setsize (self, '-16 -16 0', '16 16 56'); + StartItem (); +}; + +/* +=============================================================================== + +WEAPONS + +=============================================================================== +*/ + +void() bound_other_ammo = +{ + if (other.ammo_shells_real > 100) + other.ammo_shells_real = 100; + if (other.ammo_nails_real > 200) + other.ammo_nails_real = 200; + if (other.ammo_rockets_real > 100) + other.ammo_rockets_real = 100; + if (other.ammo_cells_real > 100) + other.ammo_cells_real = 100; + + if ((other.exshells > 100)) + { + other.exshells = 100; + } + if ((other.exnails > 200)) + { + other.exnails = 200; + } + if ((other.exrockets > 100)) + { + other.exrockets = 100; + } + if ((other.excells > 100)) + { + other.excells = 100; + } +}; + + +float(float w) RankForWeapon = +{ + if (w == IT_LIGHTNING) + return 1; + if (w == IT_ROCKET_LAUNCHER) + return 2; + if (w == IT_SUPER_NAILGUN) + return 3; + if (w == IT_GRENADE_LAUNCHER) + return 4; + if (w == IT_SUPER_SHOTGUN) + return 5; + if (w == IT_NAILGUN) + return 6; + return 7; +}; + +float (float w) WeaponCode = +{ + if (w == IT_SUPER_SHOTGUN) + return 3; + if (w == IT_NAILGUN) + return 4; + if (w == IT_SUPER_NAILGUN) + return 5; + if (w == IT_GRENADE_LAUNCHER) + return 6; + if (w == IT_ROCKET_LAUNCHER) + return 7; + if (w == IT_LIGHTNING) + return 8; + return 1; +}; + +/* +============= +Deathmatch_Weapon + +Deathmatch weapon change rules for picking up a weapon + +.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells; +============= +*/ +void(float old, float new) Deathmatch_Weapon = +{ + local float or, nr; + +// change self.weapon if desired + or = RankForWeapon (self.weapon); + nr = RankForWeapon (new); + + if ( nr == IT_LIGHTNING && self.waterlevel > 1 ) + return; + + if ( nr < or ) + W_WeaponSwitch (new); +}; + +/* +============= +weapon_touch +============= +*/ +float() W_BestWeapon; +void() weapon_touch; // sol_items.qc + + + + +/* +=============================================================================== + +AMMO + +=============================================================================== +*/ + +void () ammo_touch = +{ + local entity stemp; + local float best; + + if ((other.classname != "player")) + { + return; + } + if ((other.health <= MSG_BROADCAST)) + { + return; + } + stemp = self; + self = other; + best = W_BestWeapon (); + self = stemp; + if ((self.weapon == H_ROTTEN)) + { + if ((other.exshells >= 100)) + { + return; + } + other.exshells = (other.exshells + self.aflag); + } + if ((self.weapon == H_MEGA)) + { + if ((other.exnails >= 200)) + { + return; + } + other.exnails = (other.exnails + self.aflag); + } + if ((self.weapon == AS_MELEE)) + { + if ((other.exrockets >= 100)) + { + return; + } + other.exrockets = (other.exrockets + self.aflag); + } + if ((self.weapon == AS_MISSILE)) + { + if ((other.excells >= 100)) + { + return; + } + other.excells = (other.excells + self.aflag); + } + bound_other_ammo (); + sprint (other, "You got the "); + sprint (other, self.netname); + sprint (other, "\n"); + sound (other, CHAN_ITEM, "weapons/lock4.wav", H_ROTTEN, ATTN_NORM); + stuffcmd (other, "bf\n"); + stemp = self; + self = other; + self = stemp; + self.model = string_null; + self.solid = SOLID_NOT; + if ((deathmatch == H_ROTTEN)) + { + self.nextthink = (time + SVC_INTERMISSION); + } + self.think = SUB_regen; + activator = other; + SUB_UseTargets (); +}; +/* +void() ammo_touch = +{ +local entity stemp; +local float best; + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + +// if the player was using his best weapon, change up to the new one if better + stemp = self; + self = other; + best = W_BestWeapon(); + self = stemp; + + + switch (self.weapon) + { + case 1: // shotgun + if (other.ammo_shells_real >= 100) + return; + other.ammo_shells_real = other.ammo_shells_real + self.ammo_count; + break; + case 2: // spikes + if (other.ammo_nails_real >= 200) + return; + other.ammo_nails_real = other.ammo_nails_real + self.ammo_count; + break; + case 3: // rockets + if (other.ammo_rockets_real >= 100) + return; + other.ammo_rockets_real = other.ammo_rockets_real + self.ammo_count; + break; + case 4: // cells + if (other.ammo_cells_real >= 100) + return; + other.ammo_cells_real = other.ammo_cells_real + self.ammo_count; + break; + } + + bound_other_ammo (); + + sprint3 (other, PRINT_LOW, "You got the ", self.netname, "\n"); +// ammo touch sound + sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + +// change to a better weapon if appropriate + + stemp = self; + self = other; + + if ( self.weapon == best ) + W_WeaponSwitch (W_BestWeapon ()); + else + W_UpdateAmmoCounts (self); + + self = stemp; + +// remove it in single player, or setup for respawning in deathmatch + self.model = string_null; + self.solid = SOLID_NOT; + if (deathmatch) + { + if (deathmatch != 2) + self.nextthink = time + 30; + + // Xian -- If playing in DM 3.0 mode, halve the time ammo respawns + if (deathmatch == 3 || deathmatch == 5) + self.nextthink = time + 15; + + self.think = SUB_regen; + } + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; +*/ + + + +float WEAPON_BIG2 = 1; + +void () item_shells = +{ + self.touch = ammo_touch; + if ((self.spawnflags & WEAPON_BIG2)) + { + precache_model ("maps/b_shell1.bsp"); + setmodel (self, "maps/b_shell1.bsp"); + self.aflag = 40; + } + else + { + precache_model ("maps/b_shell0.bsp"); + setmodel (self, "maps/b_shell0.bsp"); + self.aflag = 20; + } + self.weapon = WEAPON_BIG2; + self.netname = "shells"; + setsize (self, VEC_ORIGIN, '32 32 56'); + StartItem (); +}; + +void () item_spikes = +{ + self.touch = ammo_touch; + if ((self.spawnflags & WEAPON_BIG2)) + { + precache_model ("maps/b_nail1.bsp"); + setmodel (self, "maps/b_nail1.bsp"); + self.aflag = 50; + } + else + { + precache_model ("maps/b_nail0.bsp"); + setmodel (self, "maps/b_nail0.bsp"); + self.aflag = 25; + } + self.weapon = H_MEGA; + self.netname = "nails"; + setsize (self, VEC_ORIGIN, '32 32 56'); + StartItem (); +}; + +void () item_rockets = +{ + self.touch = ammo_touch; + if ((self.spawnflags & WEAPON_BIG2)) + { + precache_model ("maps/b_rock1.bsp"); + setmodel (self, "maps/b_rock1.bsp"); + self.aflag = TE_LAVASPLASH; + } + else + { + precache_model ("maps/b_rock0.bsp"); + setmodel (self, "maps/b_rock0.bsp"); + self.aflag = TE_LIGHTNING1; + } + self.weapon = AS_MELEE; + self.netname = "rockets"; + setsize (self, VEC_ORIGIN, '32 32 56'); + StartItem (); +}; + +void () item_cells = +{ + self.touch = ammo_touch; + if ((self.spawnflags & WEAPON_BIG2)) + { + precache_model ("maps/b_batt1.bsp"); + setmodel (self, "maps/b_batt1.bsp"); + self.aflag = 12; + } + else + { + precache_model ("maps/b_batt0.bsp"); + setmodel (self, "maps/b_batt0.bsp"); + self.aflag = TE_LIGHTNING2; + } + self.weapon = AS_MISSILE; + self.netname = "cells"; + setsize (self, VEC_ORIGIN, '32 32 56'); + StartItem (); +}; + + +/*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big +DO NOT USE THIS!!!! IT WILL BE REMOVED! +*/ + +#define WEAPON_SHOTGUN 1 +float WEAPON_ROCKET = 2; +float WEAPON_SPIKES = 4; +float WEAPON_MASK = 7; +float WEAPON_BIG = 8; +void () item_weapon = +{ + self.touch = ammo_touch; + if ((self.spawnflags & WEAPON_SHOTGUN)) + { + if ((self.spawnflags & WEAPON_BIG)) + { + precache_model ("maps/b_shell1.bsp"); + setmodel (self, "maps/b_shell1.bsp"); + self.aflag = 40; + } + else + { + precache_model ("maps/b_shell0.bsp"); + setmodel (self, "maps/b_shell0.bsp"); + self.aflag = 20; + } + self.weapon = WEAPON_SHOTGUN; + self.netname = "shells"; + } + if ((self.spawnflags & WEAPON_SPIKES)) + { + if ((self.spawnflags & WEAPON_BIG)) + { + precache_model ("maps/b_nail1.bsp"); + setmodel (self, "maps/b_nail1.bsp"); + self.aflag = 40; + } + else + { + precache_model ("maps/b_nail0.bsp"); + setmodel (self, "maps/b_nail0.bsp"); + self.aflag = 20; + } + self.weapon = WEAPON_ROCKET; + self.netname = "spikes"; + } + if ((self.spawnflags & WEAPON_ROCKET)) + { + if ((self.spawnflags & WEAPON_BIG)) + { + precache_model ("maps/b_rock1.bsp"); + setmodel (self, "maps/b_rock1.bsp"); + self.aflag = TE_LAVASPLASH; + } + else + { + precache_model ("maps/b_rock0.bsp"); + setmodel (self, "maps/b_rock0.bsp"); + self.aflag = TE_LIGHTNING1; + } + self.weapon = AS_MELEE; + self.netname = "rockets"; + } + setsize (self, VEC_ORIGIN, '32 32 56'); + StartItem (); +}; + + +/* +=============================================================================== + +KEYS + +=============================================================================== +*/ + +void() key_touch = +{ + if (other.classname != "player") + return; + if (other.health <= 0) + return; + if (other.items & self.items) + return; + + sprint3 (other, PRINT_LOW, "You got the ", self.netname, "\n"); + + sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + other.items = other.items | self.items; + + self.solid = SOLID_NOT; + self.model = string_null; + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +void() key_setsounds = +{ + switch (world.worldtype) + { + case WT_MEDIEVAL: + precache_sound ("misc/medkey.wav"); + self.noise = "misc/medkey.wav"; + break; + case WT_METAL: + precache_sound ("misc/runekey.wav"); + self.noise = "misc/runekey.wav"; + break; + case WT_BASE: + precache_sound2 ("misc/basekey.wav"); + self.noise = "misc/basekey.wav"; + break; + } +}; + +/*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) +SILVER key +In order for keys to work +you MUST set your maps +worldtype to one of the +following: +0: medieval +1: metal +2: base +*/ + +void() item_key1 = +{ + if (deathmatch) + { + remove(self); + return; + } + + switch (world.worldtype) + { + case WT_MEDIEVAL: + precache_model ("progs/w_s_key.mdl"); + setmodel (self, "progs/w_s_key.mdl"); + self.netname = "silver key"; + break; + case WT_METAL: + precache_model ("progs/m_s_key.mdl"); + setmodel (self, "progs/m_s_key.mdl"); + self.netname = "silver runekey"; + break; + case WT_BASE: + precache_model2 ("progs/b_s_key.mdl"); + setmodel (self, "progs/b_s_key.mdl"); + self.netname = "silver keycard"; + break; + } + + key_setsounds(); + self.touch = key_touch; + self.items = IT_KEY1; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + +/*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) +GOLD key +In order for keys to work +you MUST set your maps +worldtype to one of the +following: +0: medieval +1: metal +2: base +*/ + +void() item_key2 = +{ + if (deathmatch) + { + remove(self); + return; + } + + switch (world.worldtype) + { + case WT_MEDIEVAL: + precache_model ("progs/w_g_key.mdl"); + setmodel (self, "progs/w_g_key.mdl"); + self.netname = "gold key"; + break; + case WT_METAL: + precache_model ("progs/m_g_key.mdl"); + setmodel (self, "progs/m_g_key.mdl"); + self.netname = "gold runekey"; + break; + case WT_BASE: + precache_model2 ("progs/b_g_key.mdl"); + setmodel (self, "progs/b_g_key.mdl"); + self.netname = "gold keycard"; + break; + } + key_setsounds(); + self.touch = key_touch; + self.items = IT_KEY2; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + + +/* +=============================================================================== + +END OF LEVEL RUNES + +=============================================================================== +*/ + +void() sigil_touch = +{ + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + centerprint (other, "You got the rune!"); + + sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + self.model = string_null; + serverflags = serverflags | (self.spawnflags & 15); + self.classname = ""; // so rune doors won't find it + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +/*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4 +End of level sigil, pick up to end episode and return to jrstart. +*/ + +void() item_sigil = +{ + if (deathmatch) + { + remove(self); + return; + } + + if (!self.spawnflags) + objerror ("no spawnflags"); + + precache_sound ("misc/runekey.wav"); + self.noise = "misc/runekey.wav"; + + switch (self.spawnflags & 15) + { + case 1: + precache_model ("progs/end1.mdl"); + setmodel (self, "progs/end1.mdl"); + break; + case 2: + precache_model2 ("progs/end2.mdl"); + setmodel (self, "progs/end2.mdl"); + break; + case 4: + precache_model2 ("progs/end3.mdl"); + setmodel (self, "progs/end3.mdl"); + break; + case 8: + precache_model2 ("progs/end4.mdl"); + setmodel (self, "progs/end4.mdl"); + break; + } + + self.touch = sigil_touch; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + +/* +=============================================================================== + +POWERUPS + +=============================================================================== +*/ + +void() powerup_touch = +{ + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + sprint3 (other, PRINT_LOW, "You got the ", self.netname, "\n"); + + self.mdl = self.model; + + if (deathmatch) + { + if (self.items & (IT_INVULNERABILITY | IT_INVISIBILITY)) + self.nextthink = time + 60*5; + else + self.nextthink = time + 60; + + self.think = SUB_regen; + } + + sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + other.items = other.items | self.items; + self.model = string_null; + +// do the apropriate action + switch (self.items) + { + case IT_SUIT: + other.rad_time = 1; + other.radsuit_finished = time + 30; + break; + case IT_INVULNERABILITY: + other.invincible_time = 1; + other.invincible_finished = time + 30; + break; + case IT_INVISIBILITY: + other.invisible_time = 1; + other.invisible_finished = time + 30; + break; + case IT_QUAD: + if (deathmatch == 4) + { + other.armortype = 0; + other.armorvalue = 0; + other.ammo_cells_real = 0; + W_UpdateAmmoCounts(other); + } + other.super_time = 1; + other.super_damage_finished = time + 30; + break; + } + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + + +/*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32) +Player is invulnerable for 30 seconds +*/ +void() item_artifact_invulnerability = +{ + self.touch = powerup_touch; + + precache_model ("progs/invulner.mdl"); + precache_sound ("items/protect.wav"); + precache_sound ("items/protect2.wav"); + precache_sound ("items/protect3.wav"); + self.noise = "items/protect.wav"; + setmodel (self, "progs/invulner.mdl"); + self.netname = "Pentagram of Protection"; + self.effects = self.effects | ef_red; + self.items = IT_INVULNERABILITY; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + +/*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32) +Player takes no damage from water or slime for 30 seconds +*/ +void() item_artifact_envirosuit = +{ + self.touch = powerup_touch; + + precache_model ("progs/suit.mdl"); + precache_sound ("items/suit.wav"); + precache_sound ("items/suit2.wav"); + self.noise = "items/suit.wav"; + setmodel (self, "progs/suit.mdl"); + self.netname = "Biosuit"; + self.items = IT_SUIT; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + +/*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32) +Player is invisible for 30 seconds +*/ +void() item_artifact_invisibility = +{ + self.touch = powerup_touch; + + precache_model ("progs/invisibl.mdl"); + precache_sound ("items/inv1.wav"); + precache_sound ("items/inv2.wav"); + precache_sound ("items/inv3.wav"); + self.noise = "items/inv1.wav"; + setmodel (self, "progs/invisibl.mdl"); + self.netname = "Ring of Shadows"; + self.items = IT_INVISIBILITY; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + +/*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32) +The next attack from the player will do 4x damage +*/ +void() item_artifact_super_damage = +{ + self.touch = powerup_touch; + + precache_model ("progs/quaddama.mdl"); + precache_sound ("items/damage.wav"); + precache_sound ("items/damage2.wav"); + precache_sound ("items/damage3.wav"); + self.noise = "items/damage.wav"; + setmodel (self, "progs/quaddama.mdl"); + if (deathmatch == 4) + self.netname = "OctaPower"; + else + self.netname = "Quad Damage"; + self.items = IT_QUAD; + self.effects = self.effects | ef_blue; + setsize (self, '-16 -16 -24', '16 16 32'); + StartItem (); +}; + + + +/* +=============================================================================== + +PLAYER BACKPACKS + +=============================================================================== +*/ + +void () BackpackTouch = +{ + local string s; + local float best; + local float old; + local float new; + local entity stemp; + local float acount; + + if ((other.classname != "player")) + { + return; + } + if ((other.health <= MSG_BROADCAST)) + { + return; + } + acount = MSG_BROADCAST; + sprint (other, "You get "); + if (self.items) + { + if (((other.items & self.items) == MSG_BROADCAST)) + { + acount = WEAPON_SHOTGUN; + sprint (other, "the "); + sprint (other, self.netname); + } + } + stemp = self; + self = other; + best = W_BestWeapon (); + self = stemp; + other.exshells = (other.exshells + self.exshells); + other.exnails = (other.exnails + self.exnails); + other.exrockets = (other.exrockets + self.exrockets); + other.excells = (other.excells + self.excells); + new = self.items; + if (!new) + { + new = other.weapon; + } + old = other.items; + other.items = (other.items | new); + bound_other_ammo (); + if (self.exshells) + { + if (acount) + { + sprint (other, ", "); + } + acount = WEAPON_SHOTGUN; + s = ftos (self.exshells); + sprint (other, s); + sprint (other, " shells"); + } + if (self.exnails) + { + if (acount) + { + sprint (other, ", "); + } + acount = WEAPON_SHOTGUN; + s = ftos (self.exnails); + sprint (other, s); + sprint (other, " nails"); + } + if (self.exrockets) + { + if (acount) + { + sprint (other, ", "); + } + acount = WEAPON_SHOTGUN; + s = ftos (self.exrockets); + sprint (other, s); + sprint (other, " rockets"); + } + if (self.excells) + { + if (acount) + { + sprint (other, ", "); + } + acount = WEAPON_SHOTGUN; + s = ftos (self.excells); + sprint (other, s); + sprint (other, " cells"); + } + sprint (other, "\n"); + sound (other, CHAN_ITEM, "weapons/lock4.wav", WEAPON_SHOTGUN, ATTN_NORM); + stuffcmd (other, "bf\n"); + remove (self); + self = other; +}; + +void () DropBackpack = +{ + local entity item; + + if (!(((self.exshells + self.exnails) + self.exrockets) + self.excells)) + { + return; + } + item = spawn (); + item.origin = (self.origin - '0 0 24'); + item.items = self.weapon; + if ((item.items == IT_AXE)) + { + item.netname = "Axe"; + } + else + { + if ((item.items == IT_SHOTGUN)) + { + item.netname = "Pistol"; + } + else + { + if ((item.items == IT_SUPER_SHOTGUN)) + { + item.netname = "SMG"; + } + else + { + if ((item.items == IT_NAILGUN)) + { + item.netname = "Rifle"; + } + else + { + if ((item.items == IT_SUPER_NAILGUN)) + { + item.netname = "Super Nailgun"; + } + else + { + if ((item.items == IT_GRENADE_LAUNCHER)) + { + item.netname = "Grenade Launcher"; + } + else + { + if ((item.items == IT_ROCKET_LAUNCHER)) + { + item.netname = "Rocket Launcher"; + } + else + { + if ((item.items == IT_LIGHTNING)) + { + item.netname = "Thunderbolt"; + } + else + { + item.netname = ""; + } + } + } + } + } + } + } + } + item.exshells = self.exshells; + item.exnails = self.exnails; + item.exrockets = self.exrockets; + item.excells = self.excells; + item.velocity_z = 300; + item.velocity_x = (-100 + (random () * 200)); + item.velocity_y = (-100 + (random () * 200)); + item.flags = FL_ITEM; + item.solid = SOLID_TRIGGER; + item.movetype = MOVETYPE_TOSS; + setmodel (item, "progs/backpack.mdl"); + setsize (item, '-16 -16 0', '16 16 56'); + item.touch = BackpackTouch; + item.nextthink = (time + 120); + item.think = SUB_Remove; +}; + +/* +======================== +Grenades By mexicouger +------------------------ +*/ +void() plasma_nade_touch = +{ +if (other.classname != "player") + return; + + if (other.plasma_lives >= 4) { + } + + else { + other.plasma_lives += 1; + sprint (other, "picked up a Plasma grenade\n"); + sound (self, CHAN_WEAPON, "weapons/pbounce.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.mdl = self.model; + self.model = string_null; + self.solid = SOLID_NOT; + + if (deathmatch) { + self.nextthink = time + 20; + self.think = SUB_regen; + } + activator = other; + SUB_UseTargets(); +} +}; + +void() nade_touch = +{ +if (other.classname != "player") + return; + + if (other.nade_lives >= 4) { + } + + else { + other.nade_lives += 1; + sprint (other, "picked up a Frag grenade\n"); + sound (self, CHAN_WEAPON, "weapons/grenpick.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.mdl = self.model; + self.model = string_null; + self.solid = SOLID_NOT; + + if (deathmatch) { + self.nextthink = time + 20; + self.think = SUB_regen; + } + activator = other; + SUB_UseTargets(); +} +}; + +void() item_nade = +{ + self.touch = nade_touch; + setmodel(self, "progs/fraggren.mdl"); + precache_sound ("weapons/grenpick.wav"); + setsize (self, '0 0 0', ' 2 2 2'); + StartItem(); +}; + +void() item_plasma_nade = +{ + self.touch = plasma_nade_touch; + setmodel(self, "progs/plasgren.mdl"); + setsize (self, '0 0 0', ' 2 2 2'); + StartItem(); +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/misc.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/misc.qc new file mode 100755 index 00000000..c8bdf218 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/misc.qc @@ -0,0 +1,612 @@ + +/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4) +Used as a positional target for spotlights, etc. +*/ +var void() info_null = SUB_Remove; + +/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4) +Used as a positional target for lightning. +*/ +void() info_notnull = +{ +}; + +//============================================================================ + +float START_OFF = 1; + +void() light_use = +{ + if (self.spawnflags & START_OFF) + { + lightstyle(self.style, "m"); + self.spawnflags = self.spawnflags - START_OFF; + } + else + { + lightstyle(self.style, "a"); + self.spawnflags = self.spawnflags | START_OFF; + } +}; + +/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF +Non-displayed light. +Default light value is 300 +Default style is 0 +If targeted, it will toggle between on or off. +*/ +void() light = +{ + if (!self.targetname) + { // inert light + remove(self); + return; + } + + if (self.style >= 32) + { + self.use = light_use; + if (self.spawnflags & START_OFF) + lightstyle(self.style, "a"); + else + lightstyle(self.style, "m"); + } +}; + +/*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF +Non-displayed light. +Default light value is 300 +Default style is 0 +If targeted, it will toggle between on or off. +Makes steady fluorescent humming sound +*/ +void() light_fluoro = +{ + if (self.style >= 32) + { + self.use = light_use; + if (self.spawnflags & START_OFF) + lightstyle(self.style, "a"); + else + lightstyle(self.style, "m"); + } + + precache_sound ("ambience/fl_hum1.wav"); + ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8) +Non-displayed light. +Default light value is 300 +Default style is 10 +Makes sparking, broken fluorescent sound +*/ +void() light_fluorospark = +{ + if (!self.style) + self.style = 10; + + precache_sound ("ambience/buzz1.wav"); + ambientsound (self.origin, "ambience/buzz1.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8) +Sphere globe light. +Default light value is 300 +Default style is 0 +*/ +void() light_globe = +{ + precache_model ("progs/s_light.spr"); + setmodel (self, "progs/s_light.spr"); + self.alpha = 0.5; + makestatic (self); +}; + +void() FireAmbient = +{ + precache_sound ("ambience/fire1.wav"); +// attenuate fast + ambientsound (self.origin, "ambience/fire1.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20) +Short wall torch +Default light value is 200 +Default style is 0 +*/ +void() light_torch_small_walltorch = +{ + precache_model ("progs/flame.mdl"); + setmodel (self, "progs/flame.mdl"); + FireAmbient (); + makestatic (self); +}; + +/*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18) +Large yellow flame ball +*/ +void() light_flame_large_yellow = +{ + precache_model ("progs/flame2.mdl"); + setmodel (self, "progs/flame2.mdl"); + self.frame = 1; + self.alpha = 0.5; + FireAmbient (); + makestatic (self); +}; + +/*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) START_OFF +Small yellow flame ball +*/ +void() light_flame_small_yellow = +{ + precache_model ("progs/flame2.mdl"); + setmodel (self, "progs/flame2.mdl"); + self.alpha = 0.5; + FireAmbient (); + makestatic (self); +}; + +/*QUAKED light_flame_small_white (0 1 0) (-10 -10 -40) (10 10 40) START_OFF +Small white flame ball +*/ +void() light_flame_small_white = +{ + precache_model ("progs/flame2.mdl"); + setmodel (self, "progs/flame2.mdl"); + self.alpha = 0.5; + FireAmbient (); + makestatic (self); +}; + +//============================================================================ + + +/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8) +Lava Balls +*/ + +void() fire_fly = +{ + local vector vel; + + vel_x = (random() * 100) - 50; + vel_y = (random() * 100) - 50; + vel_z = self.speed + (random() * 200); + + PRJ_FireProjectile (world, "progs/lavaball.mdl", self.origin, vel, PE_NONE, 20, MOD_FIREBALL, 5); + newmis.movetype = MOVETYPE_BOUNCE; + newmis.alpha = 0.9; + + self.nextthink = time + (random() * 5) + 3; + self.think = fire_fly; +}; + +void() misc_fireball = +{ + + precache_model ("progs/lavaball.mdl"); + self.classname = "fireball"; + self.nextthink = time + 0.1 + (random() * 4.9); + self.think = fire_fly; + if (!self.speed) + self.speed = 1000; +}; + +//============================================================================ + + +void() barrel_explode = +{ + self.takedamage = DAMAGE_NO; + self.classname = "explo_box"; + // did say self.owner, self.enemy should be set by Killed function + T_RadiusDamage (self, self.enemy, 160, 200, self, MOD_EXPLOBOX); + TE_explosion(self.origin + '0 0 32'); + remove (self); +}; + + + +/*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64) +TESTING THING +*/ + +void() misc_explobox = +{ + local float oldz; + + self.solid = SOLID_BBOX; + self.movetype = MOVETYPE_NONE; + precache_model ("maps/b_explob.bsp"); + setmodel (self, "maps/b_explob.bsp"); + setsize (self, '0 0 0', '32 32 64'); + precache_sound ("weapons/r_exp3.wav"); + self.health = 20; + self.th_die = barrel_explode; + self.takedamage = DAMAGE_AIM; + + self.origin_z = self.origin_z + 2; + oldz = self.origin_z; + droptofloor(); + if (oldz - self.origin_z > 250) + { + dprint ("item fell out of level at "); + dprint (vtos(self.origin)); + dprint ("\n"); + remove(self); + } +}; + + + + +/*QUAKED misc_explobox2 (0 .5 .8) (0 0 0) (32 32 64) +Smaller exploding box, REGISTERED ONLY +*/ + +void() misc_explobox2 = +{ + local float oldz; + + self.solid = SOLID_BBOX; + self.movetype = MOVETYPE_NONE; + precache_model2 ("maps/b_exbox2.bsp"); + setmodel (self, "maps/b_exbox2.bsp"); + setsize (self, '0 0 0', '32 32 32'); + precache_sound ("weapons/r_exp3.wav"); + self.health = 20; + self.th_die = barrel_explode; + self.takedamage = DAMAGE_AIM; + + self.origin_z = self.origin_z + 2; + oldz = self.origin_z; + droptofloor(); + if (oldz - self.origin_z > 250) + { + dprint ("item fell out of level at "); + dprint (vtos(self.origin)); + dprint ("\n"); + remove(self); + } +}; + +//============================================================================ + +float SPAWNFLAG_SUPERSPIKE = 1; +float SPAWNFLAG_LASER = 2; + +void() spikeshooter_use = +{ + if (self.spawnflags & SPAWNFLAG_LASER) + { + sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM); + PRJ_FireProjectile(self, + "progs/laser.mdl", + self.origin, + self.movedir * 600, + PE_LASER, + 15, + MOD_LASER, + 5); + newmis.effects |= EF_DIMLIGHT; + newmis.alpha = 0.5; + } + else + { + sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM); + if (self.spawnflags & SPAWNFLAG_SUPERSPIKE) + { + PRJ_FireProjectile(self, + "progs/s_spike.mdl", + self.origin, + self.movedir * 500, + PE_SUPERSPIKE, + 18, + MOD_SUPERSPIKE, + 6); + } + else + { + PRJ_FireProjectile(self, + "progs/spike.mdl", + self.origin, + self.movedir * 500, + PE_SPIKE, + 9, + MOD_SPIKE, + 6); + } + } +}; + +void() shooter_think = +{ + spikeshooter_use (); + self.nextthink = time + self.wait; + newmis.velocity = self.movedir * 500; +}; + + +/*QUAKED trap_spikeshooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser +When triggered, fires a spike in the direction set in QuakeEd. +Laser is only for REGISTERED. +*/ + +void() trap_spikeshooter = +{ + SetMovedir (); + self.use = spikeshooter_use; + if (self.spawnflags & SPAWNFLAG_LASER) + { + precache_model2 ("progs/laser.mdl"); + + precache_sound2 ("enforcer/enfire.wav"); + precache_sound2 ("enforcer/enfstop.wav"); + } + else + precache_sound ("weapons/spike2.wav"); +}; + + +/*QUAKED trap_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser +Continuously fires spikes. +"wait" time between spike (1.0 default) +"nextthink" delay before firing first spike, so multiple shooters can be stagered. +*/ +void() trap_shooter = +{ + trap_spikeshooter (); + + if (self.wait == 0) + self.wait = 1; + self.nextthink = time + self.wait; + self.think = shooter_think; +}; + + + +/* +=============================================================================== + + +=============================================================================== +*/ + +void() make_bubbles; +void() bubble_bob; + +/*QUAKED air_bubbles (0 .5 .8) (-8 -8 -8) (8 8 8) + +testing air bubbles +*/ + +noref var void() air_bubbles = SUB_Remove; + +void() make_bubbles = +{ +local entity bubble; + + bubble = spawn(); + setmodel (bubble, "progs/s_bubble.spr"); + setorigin (bubble, self.origin); + bubble.movetype = MOVETYPE_NOCLIP; + bubble.solid = SOLID_NOT; + bubble.velocity = '0 0 15'; + bubble.nextthink = time + 0.5; + bubble.think = bubble_bob; + bubble.classname = "bubble"; + bubble.frame = 0; + bubble.bubble_state = 0; + bubble.alpha = 0.4; + setsize (bubble, '-8 -8 -8', '8 8 8'); + self.nextthink = time + random() + 0.5; + self.think = make_bubbles; +}; + +void() bubble_split = +{ +local entity bubble; + bubble = spawn(); + setmodel (bubble, "progs/s_bubble.spr"); + setorigin (bubble, self.origin); + bubble.movetype = MOVETYPE_NOCLIP; + bubble.solid = SOLID_NOT; + bubble.velocity = self.velocity; + bubble.nextthink = time + 0.5; + bubble.think = bubble_bob; + bubble.classname = "bubble"; + bubble.frame = 1; + bubble.bubble_state = 10; + setsize (bubble, '-8 -8 -8', '8 8 8'); + self.frame = 1; + self.bubble_state = 10; + if (self.waterlevel != 3) + remove (self); +}; + +void() bubble_bob = +{ +local float rnd1, rnd2, rnd3; + + self.bubble_state = self.bubble_state + 1; + if (self.bubble_state == 4) + bubble_split(); + if (self.bubble_state == 20) + remove(self); + + rnd1 = self.velocity_x + (-10 + (random() * 20)); + rnd2 = self.velocity_y + (-10 + (random() * 20)); + rnd3 = self.velocity_z + 10 + random() * 10; + + if (rnd1 > 10) + rnd1 = 5; + if (rnd1 < -10) + rnd1 = -5; + + if (rnd2 > 10) + rnd2 = 5; + if (rnd2 < -10) + rnd2 = -5; + + if (rnd3 < 10) + rnd3 = 15; + if (rnd3 > 30) + rnd3 = 25; + + self.velocity_x = rnd1; + self.velocity_y = rnd2; + self.velocity_z = rnd3; + + self.nextthink = time + 0.5; + self.think = bubble_bob; +}; + +/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~> +~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/ + +/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8) + +Just for the debugging level. Don't use +*/ + +noref var void() viewthing = SUB_Remove; + +/* +============================================================================== + +SIMPLE BMODELS + +============================================================================== +*/ + +void() func_wall_use = +{ // change to alternate textures + self.frame = 1 - self.frame; +}; + +/*QUAKED func_wall (0 .5 .8) ? +This is just a solid wall if not inhibitted +*/ +void() func_wall = +{ + self.angles = '0 0 0'; + self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything + self.solid = SOLID_BSP; + self.use = func_wall_use; + setmodel (self, self.model); +}; + + +/*QUAKED func_illusionary (0 .5 .8) ? +A simple entity that looks solid but lets you walk through it. +*/ +void() func_illusionary = +{ + self.angles = '0 0 0'; + self.movetype = MOVETYPE_NONE; + self.solid = SOLID_NOT; + setmodel (self, self.model); + makestatic (self); +}; + +/*QUAKED func_episodegate (0 .5 .8) ? E1 E2 E3 E4 +This bmodel will appear if the episode has allready been completed, so players can't reenter it. +*/ +void() func_episodegate = +{ + if (!(serverflags & self.spawnflags)) + return; // can still enter episode + + self.angles = '0 0 0'; + self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything + self.solid = SOLID_BSP; + self.use = func_wall_use; + setmodel (self, self.model); +}; + +/*QUAKED func_bossgate (0 .5 .8) ? +This bmodel appears unless players have all of the episode sigils. +*/ +void() func_bossgate = +{ + if ( (serverflags & 15) == 15) + { + remove(self); + return; // all episodes completed + } + self.angles = '0 0 0'; + self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything + self.solid = SOLID_BSP; + self.use = func_wall_use; + setmodel (self, self.model); +}; + +//============================================================================ +/*QUAKED ambient_suck_wind (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_suck_wind = +{ + precache_sound ("ambience/suck1.wav"); + ambientsound (self.origin, "ambience/suck1.wav", 1, ATTN_STATIC); +}; + +/*QUAKED ambient_drone (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_drone = +{ + precache_sound ("ambience/drone6.wav"); + ambientsound (self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC); +}; + +/*QUAKED ambient_flouro_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_flouro_buzz = +{ + precache_sound ("ambience/buzz1.wav"); + ambientsound (self.origin, "ambience/buzz1.wav", 1, ATTN_STATIC); +}; +/*QUAKED ambient_drip (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_drip = +{ + precache_sound ("ambience/drip1.wav"); + ambientsound (self.origin, "ambience/drip1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_comp_hum (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_comp_hum = +{ + precache_sound ("ambience/comp1.wav"); + ambientsound (self.origin, "ambience/comp1.wav", 1, ATTN_STATIC); +}; +/*QUAKED ambient_thunder (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_thunder = +{ + precache_sound ("ambience/thunder1.wav"); + ambientsound (self.origin, "ambience/thunder1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_light_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_light_buzz = +{ + precache_sound ("ambience/fl_hum1.wav"); + ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_swamp1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_swamp1 = +{ + precache_sound ("ambience/swamp1.wav"); + ambientsound (self.origin, "ambience/swamp1.wav", 0.5, ATTN_STATIC); +}; +/*QUAKED ambient_swamp2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) +*/ +void() ambient_swamp2 = +{ + precache_sound ("ambience/swamp2.wav"); + ambientsound (self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC); +}; + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/monsters.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/monsters.qc new file mode 100755 index 00000000..9e261688 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/monsters.qc @@ -0,0 +1,217 @@ +/* ALL MONSTERS SHOULD BE 1 0 0 IN COLOR */ + +/* +================ +monster_use + +Using a monster makes it angry at the current activator +================ +*/ +void() monster_use = +{ + if (self.enemy) + return; + if (self.health <= 0) + return; + if (activator.items & IT_INVISIBILITY) + return; + if (activator.flags & FL_NOTARGET) + return; + if (activator.flags & FL_CLIENT) + return; + + // delay reaction so if the monster is teleported, its sound is still + // heard + self.enemy = activator; + self.nextthink = time + 0.1; + self.think = FoundTarget; +}; + +/* +================ +monster_death_use + +When a mosnter dies, it fires all of its targets with the current +enemy as activator. +================ +*/ +void() monster_death_use = +{ + // fall to ground + if (self.flags & FL_FLY) + self.flags = self.flags - FL_FLY; + if (self.flags & FL_SWIM) + self.flags = self.flags - FL_SWIM; + + if (!self.target) + return; + + activator = self.enemy; + SUB_UseTargets (); +}; + +//============================================================================ + +void() walkmonster_start_go = +{ + self.origin_z = self.origin_z + 1; // raise off floor a bit + droptofloor(); + + if (!walkmove(0,0)) + { + dprint ("walkmonster in wall at: "); + dprint (vtos(self.origin)); + dprint ("\n"); + } + + self.takedamage = DAMAGE_AIM; + + self.ideal_yaw = self.angles * '0 1 0'; + if (!self.yaw_speed) + self.yaw_speed = 20; + self.view_ofs = '0 0 25'; + self.use = monster_use; + + self.flags = self.flags | FL_MONSTER; + + if (self.target) + { + self.goalentity = self.movetarget = find(world, targetname, self.target); + self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); + if (!self.movetarget) + { + dprint ("Monster can't find target at "); + dprint (vtos(self.origin)); + dprint ("\n"); + } +// this used to be an objerror + if (self.movetarget.classname == "path_corner") + self.th_walk (); + else + self.pausetime = 99999999; + self.th_stand (); + } + else + { + self.pausetime = 99999999; + self.th_stand (); + } + +// spread think times so they don't all happen at same time + self.nextthink = time + 0.1 + random()*0.5; +}; + + +void() walkmonster_start = +{ +// delay drop to floor to make sure all doors have been spawned +// spread think times so they don't all happen at same time + self.nextthink = time + 0.1 + random()*0.5; + self.think = walkmonster_start_go; + total_monsters = total_monsters + 1; +}; + + + +void() flymonster_start_go = +{ + self.takedamage = DAMAGE_AIM; + + self.ideal_yaw = self.angles * '0 1 0'; + if (!self.yaw_speed) + self.yaw_speed = 10; + self.view_ofs = '0 0 25'; + self.use = monster_use; + + self.flags = self.flags | FL_FLY | FL_MONSTER; + + if (!walkmove(0,0)) + { + dprint ("flymonster in wall at: "); + dprint (vtos(self.origin)); + dprint ("\n"); + } + + if (self.target) + { + self.goalentity = self.movetarget = find(world, targetname, self.target); + if (!self.movetarget) + { + dprint ("Monster can't find target at "); + dprint (vtos(self.origin)); + dprint ("\n"); + } +// this used to be an objerror + if (self.movetarget.classname == "path_corner") + self.th_walk (); + else + self.pausetime = 99999999; + self.th_stand (); + } + else + { + self.pausetime = 99999999; + self.th_stand (); + } +}; + +void() flymonster_start = +{ +// spread think times so they don't all happen at same time + self.nextthink = time + 0.1 + random()*0.5; + self.think = flymonster_start_go; + total_monsters = total_monsters + 1; +}; + + +void() swimmonster_start_go = +{ + if (deathmatch) + { + remove(self); + return; + } + + self.takedamage = DAMAGE_AIM; +// total_monsters = total_monsters + 1; + + self.ideal_yaw = self.angles * '0 1 0'; + if (!self.yaw_speed) + self.yaw_speed = 10; + self.view_ofs = '0 0 10'; + self.use = monster_use; + + self.flags = self.flags | FL_SWIM | FL_MONSTER; + + if (self.target) + { + self.goalentity = self.movetarget = find(world, targetname, self.target); + if (!self.movetarget) + { + dprint ("Monster can't find target at "); + dprint (vtos(self.origin)); + dprint ("\n"); + } +// this used to be an objerror + self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); + self.th_walk (); + } + else + { + self.pausetime = 99999999; + self.th_stand (); + } + +// spread think times so they don't all happen at same time + self.nextthink = time + 0.1 + random()*0.5; +}; + +void() swimmonster_start = +{ +// spread think times so they don't all happen at same time + self.nextthink = time + 0.1 + random()*0.5; + self.think = swimmonster_start_go; + total_monsters = total_monsters + 1; +}; + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/nomonst.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/nomonst.qc new file mode 100755 index 00000000..21a6d6b2 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/nomonst.qc @@ -0,0 +1,20 @@ + +// QC for a monsterless compile + +var void() monster_ogre = SUB_Remove; +var void() monster_demon1 = SUB_Remove; +var void() monster_shambler = SUB_Remove; +var void() monster_knight = SUB_Remove; +var void() monster_army = SUB_Remove; +var void() monster_wizard = SUB_Remove; +var void() monster_dog = SUB_Remove; +var void() monster_zombie = SUB_Remove; +var void() monster_boss = SUB_Remove; +var void() monster_tarbaby = SUB_Remove; +var void() monster_hell_knight = SUB_Remove; +var void() monster_fish = SUB_Remove; +var void() monster_shalrath = SUB_Remove; +var void() monster_enforcer = SUB_Remove; +var void() monster_oldone = SUB_Remove; +var void() event_lightning = SUB_Remove; +var void() path_corner = SUB_Remove; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/obituary.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/obituary.qc new file mode 100755 index 00000000..d9249cea --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/obituary.qc @@ -0,0 +1,359 @@ +// client death messages +enum { + MOD_NONE, + MOD_AXE, + MOD_SHOTGUN, + MOD_SUPERSHOTGUN, + MOD_SPIKE, + MOD_SUPERSPIKE, + MOD_GRENADE, + MOD_ROCKET, + MOD_ROCKETRADIUS, + MOD_SHAFT, + MOD_SHAFTWATER, + MOD_SHAFTSLIME, + MOD_SHAFTLAVA, + MOD_TELEFRAG, + MOD_TELEFRAGDEFLECT, + MOD_SQUISH, + MOD_DROWN, + MOD_SLIME, + MOD_LAVA, + MOD_EXPLOBOX, + MOD_FALL, + MOD_FIREBALL, + MOD_EXIT, + MOD_LASER, + MOD_SELFWATER, + MOD_HURT, + MOD_DOG, + MOD_SOLDIER, + MOD_ENFORCER, + MOD_OGRE, + MOD_WIZARD, + MOD_DEMON, + MOD_KNIGHT, + MOD_HKNIGHT, + MOD_SHALRATH, + MOD_SHAMBLER, + MOD_FISH, + MOD_TARBABY, + MOD_ZOMBIE, + MOD_CHTHON +}; + +void(string targ, INTEGER mod) SuicideMessage = +{ + string s, t, u; + + s = ""; + t = ""; + u = ""; + + switch (mod) + { + case MOD_GRENADE: + s = targ; + t = " tries to put the pin back in"; + break; + case MOD_SHAFTWATER: + s = targ; + t = " discharges into the water."; + break; + case MOD_SHAFTSLIME: + s = targ; + t = " discharges into the slime"; + break; + case MOD_SHAFTLAVA: + s = targ; + t = " discharges into the lava"; + break; + case MOD_TELEFRAGDEFLECT: + s = "Satan's power deflects "; + t = targ; + u = "'s telefrag"; + break; + case MOD_SELFWATER: + s = targ; + t = " electrocutes himself."; + break; + case MOD_EXPLOBOX: + s = targ; + t = " blew himself up"; + break; + default: + s = targ; + t = " becomes bored with life"; + } + + bprint4(PRINT_MEDIUM, s, t, u, "\n"); +} + +void(string targ, string attacker, INTEGER mod) KillMessage = +{ + string s, t, u, v, w; + + s = ""; + t = ""; + u = ""; + v = ""; + w = ""; + + switch (mod) + { + case MOD_AXE: + s = targ; + t = " was ax-murdered by "; + u = attacker; + break; + case MOD_SHOTGUN: + s = targ; + t = " chewed on "; + u = attacker; + v = "'s boomstick"; + break; + case MOD_SUPERSHOTGUN: + s = targ; + t = " ate two loads of "; + u = attacker; + v = "'s buckshot"; + break; + case MOD_SPIKE: + s = targ; + t = " was nailed by "; + u = attacker; + break; + case MOD_SUPERSPIKE: + s = targ; + t = " was punctured by "; + u = attacker; + break; + case MOD_GRENADE: + s = targ; + t = " eats "; + u = attacker; + v = "'s pineapple"; + break; + case MOD_ROCKET: + case MOD_ROCKETRADIUS: + s = targ; + t = " rides "; + u = attacker; + v = "'s rocket"; + break; + case MOD_SHAFT: + s = targ; + t = " accepts "; + u = attacker; + v = "'s shaft"; + break; + case MOD_SHAFTWATER: + case MOD_SHAFTSLIME: + case MOD_SHAFTLAVA: + s = targ; + t = " accepts "; + u = attacker; + v = "'s discharge"; + break; + case MOD_TELEFRAG: + s = targ; + t = " was telefragged by "; + u = attacker; + break; + case MOD_TELEFRAGDEFLECT: + s = targ; + t = " was telefragged by "; + u = attacker; + v = "'s Satan's power"; + break; + case MOD_SQUISH: + s = attacker; + t = " squishes "; + u = targ; + break; + case MOD_EXPLOBOX: + s = targ; + t = " was blown up by "; + u = attacker; + break; + default: + s = targ; + t = " was killed by "; + u = attacker; + } + + bprint6(PRINT_MEDIUM, s, t, u, v, w, "\n"); +} + +void(string targ, string attacker, INTEGER mod) TeamKillMessage = +{ + string s, t, u, v, w; + float rnum; + + s = ""; + t = ""; + u = ""; + v = ""; + w = ""; + + switch (mod) + { + case MOD_SQUISH: + s = attacker; + t = " squishes teammate "; + u = targ; + break; + default: + rnum = random(); + + s = attacker; + + if (rnum < 0.25) + t = " mows down teammate "; + else if (rnum < 0.5) + { + t = " checks his glasses and sees "; + v = " dead"; + } + else if (rnum < 0.75) + { + t = " frags "; + v = " for the other team"; + } + else + t = " loses his friend "; + + u = targ; + } + + bprint6(PRINT_MEDIUM, s, t, u, v, w, "\n"); +} + +void(string targ, INTEGER mod) WorldKillMessage = +{ + string s, t, u; + + s = ""; + t = ""; + u = ""; + + switch (mod) + { + case MOD_SPIKE: + case MOD_SUPERSPIKE: + s = targ; + t = " was spiked"; + break; + case MOD_SQUISH: + s = targ; + t = " was squished"; + break; + case MOD_DROWN: + s = targ; + + if (random() < 0.5) + t = " sleeps with the fishes"; + else + t = " sucks it down"; + break; + case MOD_SLIME: + s = targ; + + if (random() < 0.5) + t = " gulped a load of slime"; + else + t = " can't exist on slime alone"; + break; + case MOD_LAVA: + s = targ; + + if (random() < 0.5) + t = " turned into hot slag"; + else + t = " visits the Volcano God"; + break; + case MOD_EXPLOBOX: + s = targ; + t = " blew up"; + break; + case MOD_FALL: + s = targ; + t = " fell to his death"; + break; + case MOD_FIREBALL: + s = targ; + t = " ate a lavaball"; + break; + case MOD_EXIT: + s = targ; + t = " tried to leave"; + break; + case MOD_LASER: + s = targ; + t = " was zapped"; + break; +#ifdef MONSTERS + case MOD_DOG: + s = targ; + t = " was mauled by a Rottweiler"; + break; + case MOD_SOLDIER: + s = targ; + t = " was shot by a Grunt"; + break; + case MOD_ENFORCER: + s = targ; + t = " was blasted by an Enforcer"; + break; + case MOD_OGRE: + s = targ; + t = " was destroyed by an Ogre"; + break; + case MOD_WIZARD: + s = targ; + t = " was scragged by a Scrag"; + break; + case MOD_DEMON: + s = targ; + t = " was eviscerated by a Fiend"; + break; + case MOD_KNIGHT: + s = targ; + t = " was slashed by a Knight"; + break; + case MOD_HKNIGHT: + s = targ; + t = " was slain by a Death Knight"; + break; + case MOD_SHALRATH: + s = targ; + t = " was exploded by a Vore"; + break; + case MOD_SHAMBLER: + s = targ; + t = " was smashed by a Shambler"; + break; + case MOD_FISH: + s = targ; + t = " was fed to the Rotfish"; + break; + case MOD_TARBABY: + s = targ; + t = " was slimed by a Spawn"; + break; + case MOD_ZOMBIE: + s = targ; + t = " joins the Zombies"; + break; + case MOD_CHTHON: + s = targ; + t = " fell to Chthon's wrath"; + break; +#endif + default: + s = targ; + t = " died"; + } + + bprint4(PRINT_MEDIUM, s, t, u, "\n"); +} \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/plats.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/plats.qc new file mode 100755 index 00000000..1c739d7f --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/plats.qc @@ -0,0 +1,363 @@ + + +void() plat_center_touch; +void() plat_outside_touch; +void() plat_trigger_use; +void() plat_go_up; +void() plat_go_down; +void() plat_crush; +float PLAT_LOW_TRIGGER = 1; + +void() plat_spawn_inside_trigger = +{ + local entity trigger; + local vector tmin, tmax; + +// +// middle trigger +// + trigger = spawn(); + trigger.touch = plat_center_touch; + trigger.movetype = MOVETYPE_NONE; + trigger.solid = SOLID_TRIGGER; + trigger.enemy = self; + + tmin = self.mins + '25 25 0'; + tmax = self.maxs - '25 25 -8'; + tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8); + if (self.spawnflags & PLAT_LOW_TRIGGER) + tmax_z = tmin_z + 8; + + if (self.size_x <= 50) + { + tmin_x = (self.mins_x + self.maxs_x) / 2; + tmax_x = tmin_x + 1; + } + if (self.size_y <= 50) + { + tmin_y = (self.mins_y + self.maxs_y) / 2; + tmax_y = tmin_y + 1; + } + + setsize (trigger, tmin, tmax); +}; + +void() plat_hit_top = +{ + sound (self, chan_no_phs_add|CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_TOP; + self.think = plat_go_down; + self.nextthink = self.ltime + 3; +}; + +void() plat_hit_bottom = +{ + sound (self, chan_no_phs_add|CHAN_VOICE, self.noise1, 1, ATTN_NORM); + self.state = STATE_BOTTOM; +}; + +void() plat_go_down = +{ + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + self.state = STATE_DOWN; + SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom); +}; + +void() plat_go_up = +{ + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + self.state = STATE_UP; + SUB_CalcMove (self.pos1, self.speed, plat_hit_top); +}; + +void() plat_center_touch = +{ + if (other.classname != "player") + return; + + if (other.health <= 0) + return; + + self = self.enemy; + if (self.state == STATE_BOTTOM) + plat_go_up (); + else if (self.state == STATE_TOP) + self.nextthink = self.ltime + 1; // delay going down +}; + +void() plat_outside_touch = +{ + if (other.classname != "player") + return; + + if (other.health <= 0) + return; + +//dprint ("plat_outside_touch\n"); + self = self.enemy; + if (self.state == STATE_TOP) + plat_go_down (); +}; + +void() plat_trigger_use = +{ + if (self.think) + return; // allready activated + plat_go_down(); +}; + + +void() plat_crush = +{ +//dprint ("plat_crush\n"); + + T_Damage (other, self, self, 1, MOD_SQUISH); + + if (self.state == STATE_UP) + plat_go_down (); + else if (self.state == STATE_DOWN) + plat_go_up (); + else + objerror ("plat_crush: bad self.state\n"); +}; + +void() plat_use = +{ + self.use = SUB_Null; + if (self.state != STATE_UP) + objerror ("plat_use: not in up state"); + plat_go_down(); +}; + + +/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER +speed default 150 + +Plats are always drawn in the extended position, so they will light correctly. + +If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat. + +If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height. +Set "sounds" to one of the following: +1) base fast +2) chain slow +*/ + + +void() func_plat = + +{ + + if (!self.t_length) + self.t_length = 80; + if (!self.t_width) + self.t_width = 10; + + if (self.sounds == 0) + self.sounds = 2; +// FIX THIS TO LOAD A GENERIC PLAT SOUND + + if (self.sounds == 1) + { + precache_sound ("plats/plat1.wav"); + precache_sound ("plats/plat2.wav"); + self.noise = "plats/plat1.wav"; + self.noise1 = "plats/plat2.wav"; + } + else if (self.sounds == 2) + { + precache_sound ("plats/medplat1.wav"); + precache_sound ("plats/medplat2.wav"); + self.noise = "plats/medplat1.wav"; + self.noise1 = "plats/medplat2.wav"; + } + + + self.mangle = self.angles; + self.angles = '0 0 0'; + + self.classname = "plat"; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + setorigin (self, self.origin); + setmodel (self, self.model); + setsize (self, self.mins , self.maxs); + + self.blocked = plat_crush; + if (!self.speed) + self.speed = 150; + +// pos1 is the top position, pos2 is the bottom + self.pos1 = self.origin; + self.pos2 = self.origin; + if (self.height) + self.pos2_z = self.origin_z - self.height; + else + self.pos2_z = self.origin_z - self.size_z + 8; + + self.use = plat_trigger_use; + + plat_spawn_inside_trigger (); // the "start moving" trigger + + if (self.targetname) + { + self.state = STATE_UP; + self.use = plat_use; + } + else + { + setorigin (self, self.pos2); + self.state = STATE_BOTTOM; + } +}; + +//============================================================================ + +void() train_next; +void() func_train_find; + +void() train_blocked = +{ + if (time < self.attack_finished) + return; + self.attack_finished = time + 0.5; + T_Damage (other, self, self, self.dmg, MOD_SQUISH); +}; + +void() train_use = +{ + if (self.think != func_train_find) + return; // already activated + train_next(); +}; + +void() train_wait = +{ + if (self.wait) + { + self.nextthink = self.ltime + self.wait; + sound (self, chan_no_phs_add|CHAN_VOICE, self.noise, 1, ATTN_NORM); + } + else + self.nextthink = self.ltime + 0.1; + + self.think = train_next; +}; + +void() train_next = +{ + local entity targ; + + targ = find (world, targetname, self.target); + self.target = targ.target; + if (!self.target) + objerror ("train_next: no next target"); + if (targ.wait) + self.wait = targ.wait; + else + self.wait = 0; + sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + SUB_CalcMove (targ.origin - self.mins, self.speed, train_wait); +}; + +void() func_train_find = + +{ + local entity targ; + + targ = find (world, targetname, self.target); + self.target = targ.target; + setorigin (self, targ.origin - self.mins); + if (!self.targetname) + { // not triggered, so start immediately + self.nextthink = self.ltime + 0.1; + self.think = train_next; + } +}; + +/*QUAKED func_train (0 .5 .8) ? +Trains are moving platforms that players can ride. +The targets origin specifies the min point of the train at each corner. +The train spawns at the first target it is pointing at. +If the train is the target of a button or trigger, it will not begin moving until activated. +speed default 100 +dmg default 2 +sounds +1) ratchet metal + +*/ +void() func_train = +{ + if (!self.speed) + self.speed = 100; + if (!self.target) + objerror ("func_train without a target"); + if (!self.dmg) + self.dmg = 2; + + if (self.sounds == 0) + { + self.noise = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + self.noise1 = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + } + + if (self.sounds == 1) + { + self.noise = ("plats/train2.wav"); + precache_sound ("plats/train2.wav"); + self.noise1 = ("plats/train1.wav"); + precache_sound ("plats/train1.wav"); + } + + self.cnt = 1; + self.solid = SOLID_BSP; + self.movetype = MOVETYPE_PUSH; + self.blocked = train_blocked; + self.use = train_use; + self.classname = "train"; + + setmodel (self, self.model); + setsize (self, self.mins , self.maxs); + setorigin (self, self.origin); + +// start trains on the second frame, to make sure their targets have had +// a chance to spawn + self.nextthink = self.ltime + 0.1; + self.think = func_train_find; +}; + +/*QUAKED misc_teleporttrain (0 .5 .8) (-8 -8 -8) (8 8 8) +This is used for the final bos +*/ +void() misc_teleporttrain = +{ + if (!self.speed) + self.speed = 100; + if (!self.target) + objerror ("func_train without a target"); + + self.cnt = 1; + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_PUSH; + self.blocked = train_blocked; + self.use = train_use; + self.avelocity = '100 200 300'; + + self.noise = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + self.noise1 = ("misc/null.wav"); + precache_sound ("misc/null.wav"); + + precache_model2 ("progs/teleport.mdl"); + setmodel (self, "progs/teleport.mdl"); + setsize (self, self.mins , self.maxs); + setorigin (self, self.origin); + +// start trains on the second frame, to make sure their targets have had +// a chance to spawn + self.nextthink = self.ltime + 0.1; + self.think = func_train_find; +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/player.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/player.qc new file mode 100755 index 00000000..ceb46cad --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/player.qc @@ -0,0 +1,1741 @@ +/* +============================================================================== + +SOLITUDE PLAYER ANIMATIONS + +============================================================================== +*/ + +void() bubble_bob; +$cd /raid/quake/id1/models/player_4 +$origin 0 -6 24 +$base base +$skin skin + +#define PLAYER_GUN_IDLE 0 +#define PLAYER_RUN 1 +#define PLAYER_ATTACK1 2 +#define PLAYER_DIE1 3 +#define PLAYER_AXE_IDLE 4 +#define PLAYER_WALK 5 +#define PLAYER_SWIM 6 +#define PLAYER_JUMP 7 +#define PLAYER_ATTACK_STAND 8 +#define PLAYER_ATTACK_SIT 9 +#define PLAYER_THROW_NADE 10 +#define PLAYER_ATTACK_MELEE 11 +#define PLAYER_ATTACK_RUN 12 +#define PLAYER_DEATH1 13 +#define PLAYER_DEATH2 14 +#define PLAYER_RELOAD 15 +#define PLAYER_PAIN 16 // HACK!! (uses death 1 anims) +#define PLAYER_PULL 17 +float (float anim_type, float endframe) Player_GetFrame = +{ + switch (anim_type) + { + case PLAYER_GUN_IDLE: + if (endframe) + return 8; + return 0; + break; + case PLAYER_AXE_IDLE: + return 0; + break; + case PLAYER_RUN: + if (endframe) + return 14; + return 9; + break; + case PLAYER_WALK: + if (endframe) + return 19; + return 15; + break; + case PLAYER_SWIM: + if (endframe) + return 26; + return 19; + break; + case PLAYER_JUMP: + if (endframe) + return 22; + return 20; + break; + case PLAYER_ATTACK_STAND: + if (endframe) + return 25; + return 23; + break; + case PLAYER_ATTACK_SIT: + if (endframe) + return 28; + return 26; + break; + case PLAYER_THROW_NADE: + if (endframe) + return 35; + return 29; + break; + case PLAYER_ATTACK_MELEE: + if (endframe) + return 41; + return 36; + break; + case PLAYER_ATTACK_RUN: + if (endframe) + return 48; + return 42; + break; + case PLAYER_DEATH1: + if (endframe) + return 60; + return 49; + break; + case PLAYER_DEATH2: + if (endframe) + return 71; + return 61; + break; + case PLAYER_RELOAD: + if (endframe) + return 79; + return 70; + break; + case PLAYER_PAIN: + if (endframe) + return 51; + return 49; + break; + case PLAYER_PULL: + if (endframe) + return 79; + return 70; + break; + default: + return 0; + break; + } + + return 0; +}; + +void (entity t_plyr, float t_frame) startwframe = +{ + if (t_plyr.weaponframe < t_frame) + t_plyr.weaponframe = t_frame; +}; + +/* +============================================================================== +PLAYER +============================================================================== +*/ + +void() player_run; + +void() player_stand1 =[ 0, player_stand1 ] +{ + player_run (); // player_run handles most animations. +}; + +void() player_run =[ 0, player_run ] +{ + local float ftype; + + if (vlen(self.velocity) < 150) + ftype = PLAYER_WALK; + else + ftype = PLAYER_RUN; + +// if (self.waterlevel > 0) +// ftype = PLAYER_SWIM; + + if (!self.velocity_x && !self.velocity_y) + { + ftype = PLAYER_GUN_IDLE; + } + + if (self.jump_time > time) + ftype = PLAYER_JUMP; + + if (self.pain_time > time) + ftype = PLAYER_PAIN; + + if (self.weaponstate == WS_FIRING1 && self.weaponframe > 0) { + if (vlen(self.velocity) < 20) + ftype = PLAYER_ATTACK_STAND; + else + ftype = PLAYER_ATTACK_RUN; + } + + self.frame = Player_GetFrame(ftype, 0); + + + if ((self.frame + self.walkframe) > Player_GetFrame(ftype, 1)) + self.walkframe = 0; + + self.frame = self.frame + self.walkframe; + + self.walkframe = self.walkframe + 1; + + //_bprint(ftos(self.frame)," firing anim\n"); +}; + +void () player_shot1 = [ 113, player_shot2 ] +{ + self.weaponframe = 1; + self.effects = (self.effects | EF_MUZZLEFLASH); +}; + +void () player_shot2 = [ 114, player_shot3 ] +{ + self.weaponframe = 2; +}; + +void () player_shot3 = [ 115, player_shot4 ] +{ + self.weaponframe = 3; +}; + +void () player_shot4 = [ 116, player_run ] +{ + self.weaponframe = 0; +}; + +void () player_shot5 = [ 117, player_shot6 ] +{ + self.weaponframe = 5; +}; + +void () player_shot6 = [ 118, player_run ] +{ + self.weaponframe = 6; +}; + +void () player_pistol_reload = +{ + local float amt; + + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if (self.weaponframe == 29) + { + player_run (); + amt = (12 - self.ammo_shells); + if ((self.exshells < amt)) + { + amt = self.exshells; + } + self.exshells = (self.exshells - amt); + self.ammo_shells = (self.ammo_shells + amt); + self.armorvalue = self.exshells; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void () player_skull_reload = +{ + local float amt; + + self.weaponframe = (self.weaponframe + WEAPON_SKULL); + if (self.weaponframe == 29) + { + player_run (); + amt = (12 - self.ammo_shells); + if ((self.exshells < amt)) + { + amt = self.exshells; + } + self.exshells = (self.exshells - amt); + self.ammo_shells = (self.ammo_shells + amt); + self.armorvalue = self.exshells; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +/* +void () player_shotgun_drop = [ 143, player_shotgun_drop ] +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe == SVC_KILLEDMONSTER)) + { + self.weaponframe = 0; + player_run (); + return; + } + self.impulse = MSG_BROADCAST; +}; + +void () player_shotgun_reload = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + + if ((self.weaponframe == 17)) + { + self.exshells2 = (self.exshells2 - 1); + self.ammo_shells2 = (self.ammo_shells2 + 1); + self.armorvalue = self.exshells2; + W_SetCurrentAmmo (); + if ( ((self.ammo_shells2 < W_GetMaxClip( self.weapon, 1 )) || (self.exshells2 == MSG_BROADCAST)) && self.exshells2 > 0) + { + self.weaponframe = 13; + player_shotgun_reload (); + } + else + { + self.weaponframe = 17; + player_shotgun_drop (); + return; + } + } + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +*/ + +void () player_shotgun_reload = +{ + if (self.button0 && self.currentammo > 0) { // Interrupt reload + player_run (); + return; + } + + self.weaponframe += 1; + if (self.weaponframe == 17) + { + self.exshells2 = (self.exshells2 - 1); + self.ammo_shells2 = (self.ammo_shells2 + 1); + self.armorvalue = self.exshells2; + W_UpdateAmmoCounts(self); + if (self.currentammo == W_GetMaxClip( self.weapon, 1 ) || self.armorvalue == 0) { + self.weaponframe = 18; + } + else { + + self.weaponframe = 13; + } + } + else if (self.weaponframe > 17) { + if (self.weaponframe > 20) { + player_run (); + W_SetCurrentAmmo (); + return; + } + } + + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_uzi_reload = +{ + local float amt; + + self.weaponframe += 1; + if ((self.weaponframe > 19)) + { + player_run (); + amt = (W_GetMaxClip(self.weapon, 1) - self.ammo_hshells); + if ((self.exhshells < amt)) + { + amt = self.exhshells; + } + self.exhshells = (self.exhshells - amt); + self.ammo_hshells = (self.ammo_hshells + amt); + self.armorvalue = self.exhshells; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_rl_reload = +{ + local float amt; + + self.weaponframe += 1; + if ((self.weaponframe > 50)) + { + player_run (); + amt = (W_GetMaxClip(self.weapon, 1) - self.ammo_rockets); + if ((self.exrockets < amt)) + { + amt = self.exrockets; + } + self.exrockets = (self.exrockets - amt); + self.ammo_rockets = (self.ammo_rockets + amt); + self.armorvalue = self.exrockets; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_ar_reload = +{ + local float amt; + + self.weaponframe += 1; + if ((self.weaponframe == 29)) + { + player_run (); + amt = (W_GetMaxClip(self.weapon, 1) - self.ammo_nails); + if ((self.exnails < amt)) + { + amt = self.exnails; + } + self.exnails = (self.exnails - amt); + self.ammo_nails = (self.ammo_nails + amt); + self.armorvalue = self.exnails; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_sniper_reload = +{ + local float amt; + + self.weaponframe += 1; + if (self.weaponframe > 27) + { + player_run (); + amt = (W_GetMaxClip(self.weapon, 1) - self.ammo_sniper); + if ((self.exsniper < amt)) + { + amt = self.exsniper; + } + self.exsniper -= amt; + self.ammo_sniper += amt; + self.armorvalue = self.exsniper; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_ppistol_reload = +{ + if (self.weaponframe < 15) // fixme: shouldn't be necessary :\ + self.weaponframe = 15; + self.weaponframe += 1; + if (self.weaponframe > 35) + { + player_run (); + self.exppistol = 0; + self.weaponheat = 0; + W_SetCurrentAmmo (); + return; + } + //self.weaponframe_time = time + 0.1; + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_needler_reload = +{ + local float amt; + + self.weaponframe += 1; + if (self.weaponframe > 29) + { + player_run (); + amt = (W_GetMaxClip(self.weapon, 1) - self.ammo_needler); + if ((self.exneedler < amt)) + { + amt = self.exneedler; + } + self.exneedler -= amt; + self.ammo_needler += amt; + self.armorvalue = self.exneedler; + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_generic_reload = +{ + local float rld_amt; + rld_amt = self.armorvalue; + + if ((Player_GetFrame(PLAYER_RELOAD, 0) + self.fireframe) > Player_GetFrame(PLAYER_RELOAD, 1)) { + + rld_amt = (W_GetMaxClip(self.weapon, 1) - self.currentammo); + if ((self.armorvalue < rld_amt)) + { + rld_amt = self.armorvalue; + } + player_run (); + SetAmmoFor( self, self.weapon, 1, rld_amt ); + SetAmmoFor( self, self.weapon, 0, (-1 * rld_amt) ); + W_SetCurrentAmmo (); + return; + } + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +// Primary player reload function (handles all reloading) +void () player_reload1 = [ 0, player_reload1 ] +{ + // allow players to interrupt reload for melee/nade throw + if (self.impulse == 29) { + pre_player_melee (); + return; + } + else if (self.impulse == 28) { + pre_player_throw_grenade (); + return; + } + else if (self.reload_time == -1) { + self.reload_time = 1; + player_run(); + return; + } + + switch (self.weapon) { + case WEAPON_PISTOL: + player_pistol_reload (); + break; + case WEAPON_SKULL: + player_skull_reload (); + break; + case WEAPON_SHOT: + player_shotgun_reload (); + break; + case WEAPON_AR: + player_ar_reload (); + break; + case WEAPON_UZI: + player_uzi_reload (); + break; + case WEAPON_RL: + player_rl_reload (); + break; + case WEAPON_SNIPER: + player_sniper_reload (); + break; + case WEAPON_PPISTOL: + player_ppistol_reload (); + break; + case WEAPON_NEEDLER: + player_needler_reload (); + break; + default: + player_generic_reload (); + break; + } + self.reload_time = time + .1; + + self.frame = Player_GetFrame(PLAYER_RELOAD, 0); + if ((self.frame + self.fireframe) > Player_GetFrame(PLAYER_RELOAD, 1)) { + if (self.weaponframe == 0) { + self.melee_time = 0; + self.donefire = 0; + self.fireframe = 0; + player_run(); + return; + } + else { + self.fireframe = 5; + //self.frame = Player_GetFrame(PLAYER_RELOAD, 0) + 3; + } + + } + + self.frame = self.frame + self.fireframe; + + self.fireframe = self.fireframe + 1; +}; + +void () player_hshot = [ 103, player_hshot ] +{ + if (!W_CheckNoAmmo ()) + { + return; + } + self.effects = (self.effects | EF_MUZZLEFLASH); + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe == TE_LAVASPLASH)) + { + self.weaponframe = WEAPON_SHOTGUN; + player_run (); + return; + } + self.attack_finished = (time + 0.5); +}; + +void () Melee_Finished = +{ + self.donefire = 1; + self.weaponframe = 0; + player_run (); +}; + +void () player_shot_melee = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 41)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 33)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_skull_melee = +{ + self.weaponframe = (self.weaponframe + WEAPON_SKULL); + if ((self.weaponframe >= 16)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 1)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_rl_melee = +{ + self.weaponframe += 1; + if ( self.weaponframe > 65 ) + { + Melee_Finished (); + return; + } + if ( self.weaponframe == 62 ) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_hshot_melee = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 26)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 23)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_shot2_melee = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 33)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 30)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_nail_melee = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 34)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == SVC_FINALE)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_sniper_melee = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 34)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 32)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_ppistol_melee = +{ + self.weaponframe += 1; + if ((self.weaponframe >= 43)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 38)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_needler_melee = +{ + self.weaponframe += 1; + if ((self.weaponframe >= 47)) + { + Melee_Finished (); + return; + } + if ((self.weaponframe == 34)) + { + W_Melee (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = 0; +}; + +void () player_melee = [ 0, player_melee ] +{ + local float ftype; + ftype = PLAYER_ATTACK_MELEE; + + self.melee_time = time + .6; + switch (self.weapon) { + case WEAPON_SHOT: + startwframe(self, 28); + player_shot2_melee (); + break; + case WEAPON_PISTOL: + startwframe(self, 30); + player_shot_melee (); + break; + case WEAPON_SKULL: + startwframe(self, 1); + player_skull_melee (); + break; + case WEAPON_AR: + startwframe(self, 29); + player_nail_melee (); + break; + case WEAPON_UZI: + startwframe(self, 21); + player_hshot_melee (); + break; + case WEAPON_RL: + startwframe(self, 58); + player_rl_melee (); + break; + case WEAPON_SNIPER: + startwframe(self, 29); + player_sniper_melee (); + break; + case WEAPON_PPISTOL: + startwframe(self, 36); + player_ppistol_melee (); + break; + case WEAPON_NEEDLER: + startwframe(self, 30); + player_needler_melee (); + break; + default: + self.melee_time = 0; + return; + } + + self.frame = Player_GetFrame(ftype, 0); + + if ((self.frame + self.fireframe) > Player_GetFrame(ftype, 1)) { + if (self.weaponframe == 0) { + self.melee_time = 0; + self.donefire = 0; + self.fireframe = 0; + player_run(); + } + else { + self.frame = Player_GetFrame(ftype, 1); + } + return; + } + + self.frame = self.frame + self.fireframe; + + self.fireframe = self.fireframe + 1; +}; + +void () pre_player_melee = +{ + player_melee (); + self.weaponframe = 0; + self.fireframe = 1; + self.frame = Player_GetFrame(PLAYER_ATTACK_MELEE, 0); +}; + +void () Throw_Finished = +{ + self.donefire = 1; + self.weaponframe = 0; + player_run (); +}; + +void () player_shot_throw = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 51)) + { + Throw_Finished (); + return; + } + if ((self.weaponframe == 47)) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_skull_throw = +{ + self.weaponframe = (self.weaponframe + WEAPON_SKULL); + if ((self.weaponframe >= 16)) + { + Throw_Finished (); + return; + } + //if ((self.weaponframe == 47)) + //{ + // W_ThrowGrenade (); + //} + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_shot2_throw = +{ + self.weaponframe += 1; + if (self.weaponframe >= 41) + { + Throw_Finished (); + return; + } + if (self.weaponframe == 39) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_nail_throw = +{ + self.weaponframe = (self.weaponframe + WEAPON_SHOTGUN); + if ((self.weaponframe >= 42)) + { + Throw_Finished (); + return; + } + if ((self.weaponframe == 39)) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_uzi_throw = +{ + self.weaponframe += 1; + + if (self.weaponframe >= 33) + { + Throw_Finished (); + return; + } + if (self.weaponframe == 30) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_sniper_throw = +{ + self.weaponframe += 1; + + if (self.weaponframe >= 42) + { + Throw_Finished (); + return; + } + if (self.weaponframe == 39) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_rl_throw = +{ + self.weaponframe += 1; + + if (self.weaponframe >= 58) + { + Throw_Finished (); + return; + } + if (self.weaponframe == 55) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_ppistol_throw = +{ + self.weaponframe += 1; + + if (self.weaponframe >= 50) + { + Throw_Finished (); + return; + } + if (self.weaponframe == 46) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_needler_throw = +{ + self.weaponframe += 1; + + if (self.weaponframe >= 56) + { + Throw_Finished (); + return; + } + if (self.weaponframe == 52) + { + W_ThrowGrenade (); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void () player_throw_grenade = [ 0, player_throw_grenade ] +{ + local float ftype; + ftype = PLAYER_THROW_NADE; + + self.nade_time = time + .8; + switch (self.weapon) { + case WEAPON_PISTOL: + startwframe(self, 44); + player_shot_throw (); + break; + case WEAPON_SHOT: + startwframe(self, 34); + player_shot2_throw (); + break; + case WEAPON_AR: + startwframe(self, 34); + player_nail_throw (); + break; + case WEAPON_UZI: + startwframe(self, 26); + player_uzi_throw (); + break; + case WEAPON_RL: + startwframe(self, 51); + player_rl_throw (); + break; + case WEAPON_SNIPER: + startwframe(self, 35); + player_sniper_throw (); + break; + case WEAPON_PPISTOL: + startwframe(self, 43); + player_ppistol_throw (); + break; + case WEAPON_NEEDLER: + startwframe(self, 48); + player_needler_throw (); + break; + default: + self.nade_time = 0; + return; + } + + self.frame = Player_GetFrame(ftype, 0); + + if ((self.frame + self.fireframe) > Player_GetFrame(ftype, 1)) { + if (self.weaponframe == 0) { + self.donefire = 0; + self.fireframe = 0; + player_run(); + } + else { + self.frame = Player_GetFrame(ftype, 1); + } + return; + } + + self.frame = self.frame + self.fireframe; + + self.fireframe = self.fireframe + 1; +}; + +void () pre_player_throw_grenade = +{ + player_throw_grenade (); + self.weaponframe = 0; + self.fireframe = 0; + self.frame = Player_GetFrame(PLAYER_THROW_NADE, 0); +}; + +//============================================================================ + +void () player_nail2 = [ 103, player_nail2 ] +{ + if (!W_CheckNoAmmo ()) + { + return; + } + self.effects = (self.effects | EF_MUZZLEFLASH); + if (!self.button0) + { + player_run (); + return; + } + /* + self.weaponframe += 1; + if (self.weaponframe > 3) + { + self.weaponframe = 1; + } + */ + SuperDamageSound (); + W_FireNail2 (); + //self.attack_finished = (time + 0.1); +}; + +void () player_ar1 = [ 103, player_ar1 ] +{ + if (!W_CheckNoAmmo ()) + { + return; + } + self.effects = (self.effects | EF_MUZZLEFLASH); + if (!self.button0) + { + player_run (); + return; + } + + self.weaponframe += 1; + if (self.weaponframe > 3) + { + self.weaponframe = 1; + } + + SuperDamageSound (); + //W_FireNail2 (); + //self.attack_finished = (time + 0.1); +}; + +void(float num_bubbles) DeathBubbles; + +void() PainSound = +{ + + + if (self.health < 0) + return; + + if (self.pain_finished > time) + return; + + // change pain sound depending on means of death + switch (damage_mod) + { + case MOD_TELEFRAG: + case MOD_TELEFRAGDEFLECT: + sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE); + return; + case MOD_DROWN: + DeathBubbles(1); + if (random() > 0.5) + sound (self, CHAN_VOICE, "player/drown1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "player/drown2.wav", 1, ATTN_NORM); + return; + case MOD_SLIME: + // FIX ME: put in some steam here + if (self.waterlevel == 3) + DeathBubbles(1); + case MOD_LAVA: + if (random() > 0.5) + sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM); + return; + default: + if (self.health >= 40) + stuffcmd(self,"play player/hit1.wav\n"); + //else + //stuffcmd(self,"play player/pain1.wav\n"); + + } +}; +void() Player_PainAnimation = +{ + self.pain_time = time + .4; + PainSound(); +}; + +void() player_pain = +{ + if (self.weaponstate != WS_IDLE) + return; + + if (self.invisible_finished > time) + return; // eyes don't have pain frames + + Player_PainAnimation (); +}; + +void() DeathBubblesSpawn = +{ +local entity bubble; + if (self.owner.waterlevel != 3) + { + remove(self); + return; + } + bubble = spawn(); + setmodel (bubble, "progs/s_bubble.spr"); + setorigin (bubble, self.owner.origin + '0 0 24'); + bubble.movetype = MOVETYPE_NOCLIP; + bubble.solid = SOLID_NOT; + bubble.velocity = '0 0 15'; + bubble.nextthink = time + 0.5; + bubble.think = bubble_bob; + bubble.classname = "bubble"; + bubble.frame = 0; + bubble.bubble_state = 0; + setsize (bubble, '-8 -8 -8', '8 8 8'); + self.nextthink = time + 0.1; + self.think = DeathBubblesSpawn; + self.bubble_count = self.bubble_count - 1; + if (self.bubble_count <= 0) + remove(self); +}; + +void(float num_bubbles) DeathBubbles = +{ +local entity bubble_spawner; + + bubble_spawner = spawn(); + setorigin (bubble_spawner, self.origin); + bubble_spawner.movetype = MOVETYPE_NONE; + bubble_spawner.solid = SOLID_NOT; + bubble_spawner.nextthink = time + 0.1; + bubble_spawner.think = DeathBubblesSpawn; + bubble_spawner.owner = self; + bubble_spawner.bubble_count = num_bubbles; +}; + + +void() DeathSound = +{ +local float rs; + + // water death sounds + if (self.waterlevel == 3) + { + DeathBubbles(5); + sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE); + return; + } + + rs = rint ((random() * 1) + 1); + if (rs == 1) + stuffcmd (self, "play player/death1.wav\n"); + if (rs == 2) + stuffcmd (self, "play player/death1.wav\n"); + +}; + +void() PlayerDead = +{ + self.nextthink = -1; +// allow respawn after a certain time + self.deadflag = DEAD_DEAD; +}; + +vector(float dm) VelocityForDamage = +{ + local vector v; + + if (vlen(damage_inflictor.velocity)>0) + { + v = 0.5 * damage_inflictor.velocity; + v = v + (25 * normalize(self.origin-damage_inflictor.origin)); + v_z = 100 + 240 * random(); + v_x = v_x + (200 * crandom()); + v_y = v_y + (200 * crandom()); + //dprint ("Velocity gib\n"); + } + else + { + v_x = 100 * crandom(); + v_y = 100 * crandom(); + v_z = 200 + 100 * random(); + } + + //v_x = 100 * crandom(); + //v_y = 100 * crandom(); + //v_z = 200 + 100 * random(); + + if (dm > -50) + { + // dprint ("level 1\n"); + v = v * 0.7; + } + else if (dm > -200) + { + // dprint ("level 3\n"); + v = v * 2; + } + else + v = v * 10; + + return v; +}; + +void(string gibname, float dm) ThrowGib = +{ + local entity new; + + new = spawn(); + new.origin = self.origin; + setmodel (new, gibname); + setsize (new, '0 0 0', '0 0 0'); + new.velocity = VelocityForDamage (dm); + new.movetype = MOVETYPE_BOUNCE; + new.solid = SOLID_NOT; + new.avelocity_x = random()*600; + new.avelocity_y = random()*600; + new.avelocity_z = random()*600; + new.think = SUB_Remove; + new.nextthink = time + 10 + random()*10; + new.frame = 0; + new.flags = 0; +}; + +void(string gibname, float dm) ThrowHead = +{ + setmodel (self, gibname); + self.frame = 0; + self.nextthink = -1; + self.movetype = MOVETYPE_BOUNCE; + self.takedamage = DAMAGE_NO; + self.solid = SOLID_NOT; + self.view_ofs = '0 0 8'; + setsize (self, '-16 -16 0', '16 16 56'); + self.velocity = VelocityForDamage (dm); + self.origin_z = self.origin_z - 24; + self.flags = self.flags - (self.flags & FL_ONGROUND); + self.avelocity = crandom() * '0 600 0'; +}; + + +void() GibPlayer = +{ + ThrowHead ("progs/h_player.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + + self.deadflag = DEAD_DEAD; + + if (damage_attacker.classname == "teledeath") + { + sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE); + return; + } + + if (random() < 0.5) + sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NONE); + else + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NONE); + + stuffcmd(self,"chase_active 1\n"); + self.setup_death = #TRUE; +}; + +void() PlayerDropStuff = +{ + local string s, t; + + if (numberserverinfokey("dq") != 0) + { + if (self.super_damage_finished > time) + { + DropQuad (self.super_damage_finished - time); + s = ftos(rint(self.super_damage_finished - time)); + t = " lost a quad with "; + if (deathmatch == 4) + t = " lost an OctaPower with "; + bprint4 (PRINT_LOW, self.netname, t, s, " seconds remaining\n"); + } + } + + if (numberserverinfokey("dr") != 0) + { + if (self.invisible_finished > time) + { + s = ftos(rint(self.invisible_finished - time)); + bprint4 (PRINT_LOW, self.netname, " lost a ring with ", s, " seconds remaining\n"); + DropRing (self.invisible_finished - time); + } + } + + //DropBackpack(); + ThrowWeapon(self.weapon, 1); +} + +void () Player_RunDeath = [ 0, Player_RunDeath ] +{ + self.walkframe++; + self.frame = (Player_GetFrame(self.death_type, 0) - 1) + self.walkframe; + if (self.frame >= (Player_GetFrame(self.death_type, 1) - 1)) + { + PlayerDead(); + return; + } +}; + +void () Player_AnimateDeath = +{ + local float i, dtype; + + i = random(); + + if (i < 0.5) + dtype = PLAYER_DEATH1; + else + dtype = PLAYER_DEATH2; + + self.death_type = dtype; + self.walkframe = 0; + self.frame = Player_GetFrame(self.death_type, 0) - 1; + Player_RunDeath (); +}; + + +void() PlayerDie = +{ + self.items = self.items - (self.items & IT_INVISIBILITY); + +CTF_Flag_Drop(); + + PlayerDropStuff(); + + self.invisible_finished = 0; // don't die as eyes + self.invincible_finished = 0; + self.super_damage_finished = 0; + self.radsuit_finished = 0; + self.modelindex = modelindex_player; // don't use eyes + + self.weaponmodel=""; + self.view_ofs = '0 0 -8'; + self.deadflag = DEAD_DYING; + self.solid = SOLID_NOT; + self.flags = self.flags - (self.flags & FL_ONGROUND); + self.movetype = MOVETYPE_TOSS; + if (self.velocity_z < 10) + self.velocity_z = self.velocity_z + random()*300; + /* + if (self.nade_lives == 4) + { + DeathNade(self.origin) + DeathNade(self.origin) + DeathNade(self.origin) + DeathNade(self.origin) + } + if (self.nade_lives == 3) + { + DeathNade(self.origin) + DeathNade(self.origin) + DeathNade(self.origin) + } + if (self.nade_lives == 2) + { + DeathNade(self.origin) + DeathNade(self.origin) + } + if (self.nade_lives == 1) + { + DeathNade(self.origin) + } + */ + DeathSound(); + + self.angles_x = 0; + self.angles_z = 0; + + Set_FOV( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + + stuffcmd(self,"chase_active 1\n"); + self.setup_death = #TRUE; + + Player_AnimateDeath (); +}; + +void() set_suicide_frame = +{ // used by klill command and diconnect command + PlayerDie(); + + /* + if (self.model != "progs/player.mdl") + return; // allready gibbed + self.frame = 0;//$deatha11; // XAVIOR: FIXME + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_TOSS; + self.deadflag = DEAD_DEAD; + self.nextthink = -1; + */ +} + +void () pull_finished = +{ + self.donefire = 1; + self.weaponframe = 0; + player_run (); +}; + +void() player_generic_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 1) + { + pull_finished(); + return; + } +if (self.weaponframe == 2) + { + sound (self, CHAN_WEAPON, "weapons/equip/ppist.wav", 1, ATTN_NORM); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void() player_needler_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 68) + { + pull_finished(); + return; + } +if (self.weaponframe == 59) + { + sound (self, CHAN_WEAPON, "weapons/equip/needler.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void() player_ppist_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 56) + { + pull_finished(); + return; + } +if (self.weaponframe == 51) + { + sound (self, CHAN_WEAPON, "weapons/equip/ppist.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void() player_sniper_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 53) + { + pull_finished(); + return; + } +if (self.weaponframe == 46) + { + sound (self, CHAN_WEAPON, "weapons/equip/sniper.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void() player_rl_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 79) + { + pull_finished(); + return; + } +if (self.weaponframe == 70) + { + sound (self, CHAN_WEAPON, "weapons/equip/rocket.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void() player_uzi_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 40) + { + pull_finished(); + return; + } +if (self.weaponframe == 36) + { + sound (self, CHAN_WEAPON, "weapons/equip/smg.wav", 1, ATTN_NORM); + } + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void() player_shotgun_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 48) + { + pull_finished(); + return; + } +if (self.weaponframe == 46) + { + sound (self, CHAN_WEAPON, "weapons/equip/shotgun.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void() player_ar_pull = +{ +self.weaponframe += 1; +if (self.weaponframe >= 55) + { + pull_finished(); + return; + } +if (self.weaponframe == 46) + { + sound (self, CHAN_WEAPON, "weapons/equip/ar.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; +void() player_shot_pull = +{ + +self.weaponframe += 1; + +if (self.weaponframe >= 62) + { + pull_finished(); + return; + } +if (self.weaponframe == 53) + { + sound (self, CHAN_WEAPON, "weapons/equip/pistol.wav", 1, ATTN_NORM); + } + + SuperDamageSound (); + self.attack_finished = (time + 0.2); + self.impulse = MSG_BROADCAST; +}; + +void() player_pull = [ 0, player_pull ] +{ + local float ftype; + ftype = PLAYER_PULL; + + // allow players to interrupt reload for melee/nade throw + if (self.impulse == 29) { + pre_player_melee (); + return; + } + else if (self.impulse == 28) { + + { + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + if (self.selnade == GRENADE_REGULAR) + { + if (self.nade_lives > 0) { + pre_player_throw_grenade (); + self.nade_lives -= 1; + sprint (self, ftos(self.nade_lives)); + sprint (self, " grenades\n"); + return; } + else + centerprint (self, "No Grenades\n"); + } + else + { + if (self.plasma_lives > 0) { + pre_player_throw_grenade (); + self.plasma_lives -= 1; + sprint (self, ftos(self.plasma_lives)); + sprint (self, " Plasma grenades\n"); + return; } + else + centerprint (self, "No Plasma Grenades\n"); + } + } +} + else if (self.pull_time == -1) { + self.pull_time = time + .6; + player_run(); + return; + } + + switch (self.weapon) { + case WEAPON_PISTOL: + startwframe(self, 52); + player_shot_pull (); + break; + case WEAPON_SHOT: + startwframe(self, 41); + player_shotgun_pull (); + break; + case WEAPON_AR: + startwframe(self, 45); + player_ar_pull (); + break; + case WEAPON_UZI: + startwframe (self, 34); + player_uzi_pull (); + break; + case WEAPON_RL: + startwframe (self, 69); + player_rl_pull (); + break; + case WEAPON_SNIPER: + startwframe (self, 43); + player_sniper_pull (); + break; + case WEAPON_PPISTOL: + startwframe (self, 50); + player_ppist_pull (); + break; + case WEAPON_NEEDLER: + startwframe (self, 58); + player_needler_pull (); + break; + default: + startwframe (self, 1); + player_generic_pull (); + break; + } + + self.frame = Player_GetFrame(ftype, 0); + if ((self.frame + self.fireframe) > Player_GetFrame(ftype, 1)) { + if (self.weaponframe == 0) { + self.melee_time = 0; + self.donefire = 0; + self.fireframe = 0; + player_run(); + return; + } + else { + self.fireframe = 5; + //self.frame = Player_GetFrame(ftype, 0) + 3; + } + + } + + self.frame = self.frame + self.fireframe; + + self.fireframe = self.fireframe + 1; +}; + +void () pre_player_pull = +{ + player_pull (); + self.weaponframe = 0; + self.fireframe = 0; + self.frame = Player_GetFrame(PLAYER_PULL, 0); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/progs.src b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/progs.src new file mode 100755 index 00000000..091348fa --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/progs.src @@ -0,0 +1,74 @@ +// First non-comment character must be # to use +// "new style" progs.src +#pragma PROGS_DAT ../qwprogs.dat + +// uncomment based on desired compile +#define NETQUAKE +// #define FTE +#define MONSTERS +#define REPLACEMENTS + +// compile options +#ifdef NETQUAKE +// if netquake, use progs.dat file name +#pragma PROGS_DAT ../progs.dat +#endif + +#ifdef FTE +// if FTE, use FTE style progs and use fteprogs.dat file name +#pragma target fte +#pragma PROGS_DAT fteprogs.dat +#endif + +// includes +#include "defs.qc" +#include "sol_defs.qc" +#include "engine.qc" + +// frikbot +#include "frikbot/bot.qc" +#include "frikbot/bot_way.qc" +#include "frikbot/bot_fight.qc" +#include "frikbot/bot_ai.qc" +#include "frikbot/bot_misc.qc" +#include "frikbot/bot_phys.qc" +#include "frikbot/bot_move.qc" +#include "frikbot/bot_ed.qc" + +#include "subs.qc" +#include "effects.qc" +#include "obituary.qc" +#include "combat.qc" +#include "items.qc" +#include "proj.qc" +#include "weapons.qc" +#include "NeedleAI.qc" + + + +#include "world.qc" +#include "ctf.qc" +#include "client.qc" +#include "spectate.qc" +#include "player.qc" +#include "doors.qc" +#include "buttons.qc" +#include "triggers.qc" +#include "plats.qc" +#include "misc.qc" + +#include "sol_items.qc" +#include "sol_misc.qc" + +#ifdef MONSTERS +#include "fight.qc" +#include "ai.qc" +#include "monsters.qc" + +#else +#include "nomonst.qc" +#endif + +#ifdef REPLACEMENTS +#include "replace.qc" +#endif \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/proj.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/proj.qc new file mode 100755 index 00000000..1d2f5e98 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/proj.qc @@ -0,0 +1,220 @@ + +// Generic projectile spawning code (PRJ) --- +// projectile effect enumerator +enum { + PE_NONE, + PE_SPIKE, + PE_SUPERSPIKE, + PE_WIZSPIKE, + PE_KNIGHTSPIKE, + PE_GUNSHOT, + PE_EXPLOSION, + PE_EXPLOSIONGROUND, + PE_LASER, + PE_ZOMBIEGIB +}; + +// functions used only by this QC file +float() _PRJ_Bounce = +{ + if (other.takedamage == DAMAGE_AIM) + return 0; // explode + + sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound + if (self.velocity == '0 0 0') + self.avelocity = '0 0 0'; + + return 1; // keep bouncing +}; + +float() _PRJ_Remove = +{ + remove(self); + return 1; // stop execution within touch function +}; + +float() _PRJ_Stop = +{ + if (other.takedamage) + return 0; + + sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound + self.velocity = '0 0 0'; + self.avelocity = '0 0 0'; + self.proj_touch = _PRJ_Remove; + return 1; // keep the entity alive +}; + +void() _PRJ_Touch = +{ + local entity ignore; + + // check validity of projectile + if (other == self.owner) + return; // don't explode on owner + + if (self.voided) { + return; + } + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + + // handle custom touch + if (other != self) // didn't expire + if (self.proj_touch) // is valid function + if (self.proj_touch()) + return; + + // void projectile + self.voided = 1; + + // do projectile damage + ignore = self; + + if (other.health >= 1 && self.damage_direct) + { + T_Damage (other, self, self.owner, self.damage_direct, self.mod_direct); + ignore = other; + } + + if (self.radius_exp) + T_RadiusDamage (self, self.owner, self.damage_exp, self.radius_exp, ignore, self.mod_exp); + + // run projectile effect + switch (self.proj_effect) + { + case PE_SPIKE: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_spike(self.origin); + break; + case PE_SUPERSPIKE: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_superspike(self.origin); + break; + case PE_WIZSPIKE: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_wizspike(self.origin); + break; + case PE_KNIGHTSPIKE: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_knightspike(self.origin); + break; + case PE_LASER: + if (other != self) + sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); + self.origin = self.origin - 8 * normalize(self.velocity); + case PE_GUNSHOT: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_gunshot(self.origin); + break; + case PE_EXPLOSION: + self.origin = self.origin - 8 * normalize(self.velocity); + case PE_EXPLOSIONGROUND: + TE_explosion(self.origin); + break; + case PE_ZOMBIEGIB: + sound (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM); + break; + } + + remove(self); +}; + +void() _PRJ_Expire = +{ + other = self; + _PRJ_Touch(); +}; + +void() _PRJ_Think = +{ + if (self.expire_time > time) + { + _PRJ_Expire(); + return; + } + + self.nextthink = time + self.proj_think_time; + self.proj_think(); // projectile could remove itself here +}; + +// functions used by outside QC files +// set bouncy projectile function +void() PRJ_SetBouncyProjectile = +{ + newmis.proj_touch = _PRJ_Bounce; + newmis.movetype = MOVETYPE_BOUNCE; + newmis.avelocity = '300 300 300'; +}; + +// set tossed projectile (zombie gib) function +void() PRJ_SetTossedProjectile = +{ + newmis.proj_touch = _PRJ_Stop; + newmis.movetype = MOVETYPE_BOUNCE; + newmis.avelocity = '3000 1000 2000'; +}; + +// set radius damage function +void(INTEGER damg, INTEGER damgrad, INTEGER damgmod) PRJ_SetRadiusDamage = +{ + newmis.damage_exp = damg; + newmis.radius_exp = damgrad; + newmis.mod_exp = damgmod; +}; + +// extra think function, should always be called ONCE after the main spawn function +void(void() thinkfunc, float thinktimeinit, float thinkres) PRJ_SetThink = +{ + newmis.think = _PRJ_Think; + newmis.nextthink = time + thinktimeinit; + newmis.proj_think = thinkfunc; + newmis.proj_think_time = thinkres; +}; + +// extra touch function +void(float() touchfunc) PRJ_SetTouch = +{ + newmis.proj_touch = touchfunc; +}; + +// main spawning function +void(entity parent, string modl, vector org, vector vel, INTEGER effect, INTEGER damg, INTEGER damgmod, float expiretime) PRJ_FireProjectile = +{ + newmis = spawn (); + newmis.owner = parent; + newmis.movetype = MOVETYPE_FLYMISSILE; + newmis.solid = SOLID_BBOX; +// newmis.classname = class; + newmis.velocity = vel; + + newmis.damage_direct = damg; + newmis.mod_direct = damgmod; + newmis.proj_effect = effect; + + newmis.touch = _PRJ_Touch; + newmis.expire_time = time + expiretime; + + newmis.think = _PRJ_Expire; + newmis.nextthink = time + expiretime; + + newmis.angles = vectoangles(newmis.velocity); + + setmodel (newmis, modl); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + setorigin (newmis, org); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/Elite.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/Elite.qc new file mode 100755 index 00000000..7e7aaeae --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/Elite.qc @@ -0,0 +1,83 @@ + +//Credit to Frag.machine for partial code! +void () info_elite_think = +{ + local float r; + r = floor(random()*4); + + if (TOTAL_MONS <= MAX_MONS) //Prevents spawning, so Waves can be set. + { + if (r == 0) + { + normal_elite(); + } + else if (r == 1) + { + normal_grunt(); + } + else if (r == 2) + { + if (round < 3) + normal_elite() || normal_grunt(); + else + red_elite(); //Sets a limitation, so Red Elites don't appear until Round 3 + } + else if (r == 3) + { + if (round < 4) + normal_elite() || normal_grunt() || red_elite(); //Randomly picks an enemy to spawn. + else + white_elite(); + } + } + + // finally, let's schedule the execution of our "think" function + self.think = info_elite_think; + self.nextthink = (time + 5); +}; + +void () info_elite_start = +{ + + kill_count(); + FIREFIGHT = 1; //Sets Firefight to 1, so there are lives in play. + localcmd ("teamplay 1\n"); + F_LIVES = 7; + localcmd ("cl_life 8\n"); + + precache_sound ("firefight.wav"); + + precache_model ("progs/elite.mdl"); + precache_model ("progs/h_elite.mdl"); + precache_model ("progs/grenade.mdl"); + + precache_sound ("elite/ogdrag.wav"); + precache_sound ("elite/ogdth.wav"); + precache_sound ("elite/ogpain1.wav"); + precache_sound ("elite/ogsawatk.wav"); + precache_sound ("elite/ogwake.wav"); + precache_sound ("elite/laugh1.wav"); + precache_sound ("elite/laugh2.wav"); + + //Grunts + precache_model ("progs/soldier.mdl"); + precache_model ("progs/h_guard.mdl"); + + precache_sound ("soldier/death1.wav"); + precache_sound ("soldier/idle.wav"); + precache_sound ("soldier/pain1.wav"); + precache_sound ("soldier/pain2.wav"); + precache_sound ("soldier/sight1.wav"); + precache_sound ("soldier/laugh1.wav"); + precache_sound ("soldier/laugh2.wav"); + + precache_sound ("soldier/unstoppable.wav"); + precache_sound ("soldier/kill_all.wav"); + + + self.enemy = world; + + + self.think = info_elite_think; + self.nextthink = time + 5; +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/Firefight_random.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/Firefight_random.qc new file mode 100755 index 00000000..8ad538cc --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/Firefight_random.qc @@ -0,0 +1,192 @@ + + +void() normal_elite = +{ + local entity oldself; + + if (self.enemy != world) + { + if (self.enemy.health <= 0) + { + self.enemy = world; + } + } + + if (self.enemy == world) + { + oldself = self; + self = spawn (); + self.classname = "Needle-spikes"; + setorigin (self, oldself.origin); + self.origin_z = self.origin_z + 2; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + setmodel (self, "progs/elite.mdl"); + self.skin = 0; + setsize (self, VEC_HULL_MIN, VEC_HULL_MAX); + self.health = 200; + self.elite = 0; + self.th_stand = elite_stand1; + self.th_walk = elite_walk1; + self.th_run = elite_run1; + self.th_die = elite_die; + self.th_melee = elite_melee; + self.th_missile = elite_nail1; + self.th_pain = elite_pain; + + if (oldself.target != string_null) + { + self.target = oldself.target; + } + + walkmonster_start(); + + oldself.enemy = self; + self = oldself; + TOTAL_MONS += 1; //Adds a monster to the world, so that waves can be set. + } + +}; + +void() red_elite = +{ + local entity oldself; + + if (self.enemy != world) + { + if (self.enemy.health <= 0) + { + self.enemy = world; + } + } + + if (self.enemy == world) + { + oldself = self; + self = spawn (); + self.classname = "Needle-spikes"; + setorigin (self, oldself.origin); + self.origin_z = self.origin_z + 2; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + setmodel (self, "progs/elite.mdl"); + self.skin = 1; + setsize (self, VEC_HULL_MIN, VEC_HULL_MAX); + self.health = 300; + self.elite = 1; //States what Elite type it is, so Different stats/weapons can be set. + self.th_stand = elite_stand1; + self.th_walk = elite_walk1; + self.th_run = elite_run1; + self.th_die = elite_die; + self.th_melee = elite_melee; + self.th_missile = elite_nail1; + self.th_pain = elite_pain; + + if (oldself.target != string_null) + { + self.target = oldself.target; + } + + walkmonster_start(); + + oldself.enemy = self; + self = oldself; + TOTAL_MONS += 1; + } + +}; +void() white_elite = +{ + local entity oldself; + + if (self.enemy != world) + { + if (self.enemy.health <= 0) + { + self.enemy = world; + } + } + + if (self.enemy == world) + { + oldself = self; + self = spawn (); + self.classname = "Needle-spikes"; + setorigin (self, oldself.origin); + self.origin_z = self.origin_z + 2; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + setmodel (self, "progs/elite.mdl"); + self.skin = 3; + setsize (self, VEC_HULL_MIN, VEC_HULL_MAX); + self.health = 400; + self.elite = 2; + self.th_stand = elite_stand1; + self.th_walk = elite_walk1; + self.th_run = elite_run1; + self.th_die = elite_die; + self.th_melee = elite_melee; + self.th_missile = elite_nail1; + self.th_pain = elite_pain; + + if (oldself.target != string_null) + { + self.target = oldself.target; + } + + walkmonster_start(); + + oldself.enemy = self; + self = oldself; + TOTAL_MONS += 1; + } + +}; + +void() normal_grunt = +{ + local entity oldself; + + if (self.enemy != world) + { + if (self.enemy.health <= 0) + { + self.enemy = world; + } + } + + if (self.enemy == world) + { + oldself = self; + self = spawn (); + self.classname = "Needle-spikes"; + setorigin (self, oldself.origin); + self.origin_z = self.origin_z + 2; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + setmodel (self, "progs/soldier.mdl"); + self.skin = 0; + self.elite = 1; //For Melee damage + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 40 * round/1.5; + self.th_stand = army_stand1; + self.th_walk = army_walk1; + self.th_run = army_run1; + self.th_missile = army_atk1; + self.th_pain = army_pain; + self.th_die = army_die; + self.th_melee = grunt_melee1; + + if (oldself.target != string_null) + { + self.target = oldself.target; + } + + walkmonster_start(); + + oldself.enemy = self; + self = oldself; + TOTAL_MONS += 1; + } + +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/ai_anims.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/ai_anims.qc new file mode 100755 index 00000000..a4e2b7ce --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/ai_anims.qc @@ -0,0 +1,685 @@ +void() info_elite_think; + +void() kill_count = +{ +if (round_kills == 0) +{ +localcmd ("cl_round 1\n"); +TOTAL_MONS = 0; +MAX_MONS = 3; //4 Max Monsters. 0-1-2-3 +round = 1; +} + +if (round_kills == 4) +{ +localcmd ("cl_round 2\n"); +TOTAL_MONS = 0; +MAX_MONS = 5; +round = 2; +} + +if (round_kills == 10) +{ +localcmd ("cl_round 3\n"); +TOTAL_MONS = 0; +MAX_MONS = 9; +round = 3; +} + +if (round_kills == 20) +{ +localcmd ("skill 2\n"); +localcmd ("cl_round 4\n"); +TOTAL_MONS = 0; +MAX_MONS = 9; +round = 4; + +} + +if (round_kills == 30) +{ +F_LIVES += 1; //Increase the players life for making it this far. +localcmd ("cl_round 5\n"); +TOTAL_MONS = 0; +MAX_MONS = 14; +round = 5; +} + +if (round_kills == 45) +{ +localcmd ("cl_round 6\n"); +TOTAL_MONS = 0; +MAX_MONS = 19; +round = 6; +} + +if (round_kills == 65) +{ +localcmd ("skill 3\n"); +localcmd ("cl_round 7\n"); +TOTAL_MONS = 0; +MAX_MONS = 34; +round = 7; +} + +if (round_kills == 100) +{ +TOTAL_MONS = 0; +MAX_MONS = 34; +localcmd ("cl_round 8\n"); +round = 8; +} +if (round_kills == 150) +{ +TOTAL_MONS = 0; +MAX_MONS = 49; +localcmd ("cl_round 8\n"); +round = 9; +centerprint (self, "Congrats! You have completed Firefight! Shoot to Retry.\n"); +if (self.button0) +localcmd ("map spawn\n"); +} + +}; + +/* +=========================================================== + +WEAPON SHOOTING +This Enables Various Weapons to be used by Monster AI +============================================================ +*/ +//Shoot the Plasma Pistol +void() Enemy_Fire_PPist = +{ + local vector dir; + local entity en; + + ai_face(); + + //sound (self, CHAN_WEAPON, "soldier/.wav", 1,ATTN_NORM); + en = self.enemy; + dir = en.origin - en.velocity*0.2; + dir = normalize (dir - self.origin); + + W_FirePPistol( self.weaponheat ); +}; + +//Shoot the Needler +void() Enemy_Fire_Needler = +{ + local vector dir; + local entity en; + + ai_face(); + + //sound (self, CHAN_WEAPON, "soldier/.wav", 1,ATTN_NORM); + en = self.enemy; + dir = en.origin - en.velocity*0.2; + dir = normalize (dir - self.origin); + + W_FireNeedler(); +}; +/* +============================================================================== + +ELITE + +============================================================================== +*/ + +$cd id1/models/elite_c +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 +$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7 +$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 +$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14 + +$frame melee1 melee2 melee3 melee4 melee5 melee6 melee7 +$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 shoot7 shoot8 shoot9 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame painb1 painb2 painb3 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10 +$frame paind11 paind12 paind13 paind14 paind15 paind16 + +$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10 +$frame paine11 paine12 paine13 paine14 paine15 + +$frame death1 death2 death3 death4 death5 death6 +$frame death7 death8 death9 death10 death11 death12 +$frame death13 death14 + +$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6 +$frame bdeath7 bdeath8 bdeath9 bdeath10 + +$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11 + +//============================================================================= + +//============================================================================= + +void() laugh = +{ +local float r; +r = random(); +if (r <= 0.025) +sound (self, CHAN_AUTO, "elite/laugh1.wav", 1, ATTN_NORM); +else if ( r <= 0.05) +sound (self, CHAN_AUTO, "elite/laugh2.wav", 1, ATTN_NORM); +else +{} +}; +/* +================ +Elite Melee + +FIXME +================ +*/ +void(float side) chainsaw = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + if (!CanDamage (self.enemy, self)) + return; + + ai_charge(10); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + if (self.elite == 0) + ldmg = (random() + random() + random()) * 10; + else if (self.elite == 1) + ldmg = (random() + random() + random()) * 15; + else if (self.elite == 2) + ldmg = (random() + random() + random()) * 20; + T_Damage (self.enemy, self, self, ldmg, MOD_OGRE); +}; + + +void() elite_stand1 =[ $stand1, elite_stand2 ] {ai_stand();}; +void() elite_stand2 =[ $stand2, elite_stand3 ] {ai_stand();}; +void() elite_stand3 =[ $stand3, elite_stand4 ] {ai_stand(); laugh();}; +void() elite_stand4 =[ $stand4, elite_stand5 ] {ai_stand();}; +void() elite_stand5 =[ $stand5, elite_stand6 ] { +ai_stand(); +}; +void() elite_stand6 =[ $stand6, elite_stand7 ] {ai_stand();}; +void() elite_stand7 =[ $stand7, elite_stand8 ] {ai_stand();}; +void() elite_stand8 =[ $stand8, elite_stand9 ] {ai_stand();}; +void() elite_stand9 =[ $stand9, elite_stand1 ] {ai_stand();}; + +void() elite_walk1 =[ $walk1, elite_walk2 ] {ai_walk(3);}; +void() elite_walk2 =[ $walk2, elite_walk3 ] {ai_walk(2);}; +void() elite_walk3 =[ $walk3, elite_walk4 ] { +ai_walk(2); +}; +void() elite_walk4 =[ $walk4, elite_walk5 ] {ai_walk(2);}; +void() elite_walk5 =[ $walk5, elite_walk6 ] {ai_walk(2);}; +void() elite_walk6 =[ $walk6, elite_walk7 ] { +ai_walk(5); +if (random() < 0.1) + sound (self, CHAN_VOICE, "elite/ogdrag.wav", 1, ATTN_IDLE); +}; +void() elite_walk7 =[ $walk7, elite_walk8 ] {ai_walk(6);}; +void() elite_walk8 =[ $walk8, elite_walk9 ] {ai_walk(4);}; +void() elite_walk9 =[ $walk9, elite_walk10 ] {ai_walk(6);}; +void() elite_walk10 =[ $walk10, elite_walk11 ] {ai_walk(2);}; +void() elite_walk11 =[ $walk11, elite_walk12 ] {ai_walk(4);}; +void() elite_walk12 =[ $walk12, elite_walk13 ] {ai_walk(6);}; +void() elite_walk13 =[ $walk13, elite_walk14 ] {ai_walk(6);}; +void() elite_walk14 =[ $walk14, elite_walk15 ] {ai_walk(6);}; +void() elite_walk15 =[ $walk15, elite_walk16 ] {ai_walk(6);}; +void() elite_walk16 =[ $walk16, elite_walk1 ] {ai_walk(8);}; + +void() elite_run1 =[ $run1, elite_run2 ] {ai_run(18); +}; +void() elite_run2 =[ $run2, elite_run3 ] {ai_run(15);}; +void() elite_run3 =[ $run3, elite_run4 ] {ai_run(15);}; +void() elite_run4 =[ $run4, elite_run5 ] {ai_run(15);}; +void() elite_run5 =[ $run5, elite_run6 ] {ai_run(15);}; +void() elite_run6 =[ $run6, elite_run7 ] {ai_run(15);}; +void() elite_run7 =[ $run7, elite_run8 ] {ai_run(15);}; +void() elite_run8 =[ $run8, elite_run1 ] {ai_run(15);}; + +void() elite_swing1 =[ $swing1, elite_swing2 ] {ai_charge(11); +sound (self, CHAN_WEAPON, "elite/ogsawatk.wav", 1, ATTN_NORM); +}; +void() elite_swing2 =[ $swing2, elite_swing3 ] {ai_charge(1);}; +void() elite_swing3 =[ $swing3, elite_swing4 ] {ai_charge(4);}; +void() elite_swing4 =[ $swing4, elite_swing5 ] {ai_charge(13);}; +void() elite_swing5 =[ $swing5, elite_swing6 ] {ai_charge(9); }; +void() elite_swing6 =[ $swing6, elite_swing7 ] {}; +void() elite_swing7 =[ $swing7, elite_swing8 ] {}; +void() elite_swing8 =[ $swing8, elite_swing9 ] {}; +void() elite_swing9 =[ $swing9, elite_swing10 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 10;}; +void() elite_swing10 =[ $swing10, elite_swing11 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 10;}; +void() elite_swing11 =[ $swing11, elite_swing12 ] {}; +void() elite_swing12 =[ $swing12, elite_swing13 ] {ai_charge(3);}; +void() elite_swing13 =[ $swing13, elite_swing14 ] {ai_charge(8);}; +void() elite_swing14 =[ $swing14, elite_run1 ] {ai_charge(9);}; + +void() elite_smash1 =[ $smash1, elite_smash2 ] {ai_charge(6); +sound (self, CHAN_WEAPON, "elite/ogsawatk.wav", 1, ATTN_NORM); +}; +void() elite_smash2 =[ $smash2, elite_smash3 ] {ai_charge(0);}; +void() elite_smash3 =[ $smash3, elite_smash4 ] {ai_charge(0);}; +void() elite_smash4 =[ $smash4, elite_smash5 ] {ai_charge(1);}; +void() elite_smash5 =[ $smash5, elite_smash6 ] {ai_charge(4);}; +void() elite_smash6 =[ $smash6, elite_smash7 ] {ai_charge(4); chainsaw(0);}; +void() elite_smash7 =[ $smash7, elite_smash8 ] {ai_charge(4);}; +void() elite_smash8 =[ $smash8, elite_smash9 ] {ai_charge(10);}; +void() elite_smash9 =[ $smash9, elite_smash10 ] {ai_charge(13);}; +void() elite_smash10 =[ $smash10, elite_smash11 ] {chainsaw(1);}; +void() elite_smash11 =[ $smash11, elite_smash12 ] {ai_charge(2); +self.nextthink = time + 0.1 + random()*0.1;}; // slight variation +//void() elite_smash12 =[ $smash12, elite_smash13 ] {ai_charge();}; +void() elite_smash12 =[$smash12, elite_smash13] {ai_charge(0);}; +void() elite_smash13 =[ $smash13, elite_smash14 ] {ai_charge(4);}; +void() elite_smash14 =[ $smash14, elite_run1 ] {ai_charge(12);}; + +void() elite_nail1 =[ $run1, elite_nail2 ] {ai_face();}; +void() elite_nail2 =[ $run2, elite_nail3 ] {ai_face();}; +void() elite_nail3 =[ $run2, elite_nail4 ] {ai_face();}; +void() elite_nail4 =[ $run3, elite_nail5 ] {ai_face(); +if (self.elite == 0 || self.elite == 2) +Enemy_Fire_PPist(); +if (self.elite == 1) +Enemy_Fire_Needler(); +}; +void() elite_nail5 =[ $run4, elite_nail6 ] {ai_face();}; +void() elite_nail6 =[ $run5, elite_nail7 ] {ai_face();}; +void() elite_nail7 =[ $run6, elite_run1 ] {ai_face();}; + +void() elite_pain1 =[ $pain1, elite_pain2 ] {}; +void() elite_pain2 =[ $pain2, elite_pain3 ] {}; +void() elite_pain3 =[ $pain3, elite_pain4 ] {}; +void() elite_pain4 =[ $pain4, elite_pain5 ] {}; +void() elite_pain5 =[ $pain5, elite_run1 ] {}; + + +void() elite_painb1 =[ $painb1, elite_painb2 ] {}; +void() elite_painb2 =[ $painb2, elite_painb3 ] {}; +void() elite_painb3 =[ $painb3, elite_run1 ] {}; + + +void() elite_painc1 =[ $painc1, elite_painc2 ] {}; +void() elite_painc2 =[ $painc2, elite_painc3 ] {}; +void() elite_painc3 =[ $painc3, elite_painc4 ] {}; +void() elite_painc4 =[ $painc4, elite_painc5 ] {}; +void() elite_painc5 =[ $painc5, elite_painc6 ] {}; +void() elite_painc6 =[ $painc6, elite_run1 ] {}; + + +void() elite_paind1 =[ $paind1, elite_paind2 ] {}; +void() elite_paind2 =[ $paind2, elite_paind3 ] {ai_pain(10);}; +void() elite_paind3 =[ $paind3, elite_paind4 ] {ai_pain(9);}; +void() elite_paind4 =[ $paind4, elite_paind5 ] {ai_pain(4);}; +void() elite_paind5 =[ $paind5, elite_paind6 ] {}; +void() elite_paind6 =[ $paind6, elite_paind7 ] {}; +void() elite_paind7 =[ $paind7, elite_paind8 ] {}; +void() elite_paind8 =[ $paind8, elite_paind9 ] {}; +void() elite_paind9 =[ $paind9, elite_paind10 ] {}; +void() elite_paind10=[ $paind10, elite_paind11 ] {}; +void() elite_paind11=[ $paind11, elite_paind12 ] {}; +void() elite_paind12=[ $paind12, elite_paind13 ] {}; +void() elite_paind13=[ $paind13, elite_paind14 ] {}; +void() elite_paind14=[ $paind14, elite_paind15 ] {}; +void() elite_paind15=[ $paind15, elite_paind16 ] {}; +void() elite_paind16=[ $paind16, elite_run1 ] {}; + +void() elite_paine1 =[ $paine1, elite_paine2 ] {}; +void() elite_paine2 =[ $paine2, elite_paine3 ] {ai_pain(10);}; +void() elite_paine3 =[ $paine3, elite_paine4 ] {ai_pain(9);}; +void() elite_paine4 =[ $paine4, elite_paine5 ] {ai_pain(4);}; +void() elite_paine5 =[ $paine5, elite_paine6 ] {}; +void() elite_paine6 =[ $paine6, elite_paine7 ] {}; +void() elite_paine7 =[ $paine7, elite_paine8 ] {}; +void() elite_paine8 =[ $paine8, elite_paine9 ] {}; +void() elite_paine9 =[ $paine9, elite_paine10 ] {}; +void() elite_paine10=[ $paine10, elite_paine11 ] {}; +void() elite_paine11=[ $paine11, elite_paine12 ] {}; +void() elite_paine12=[ $paine12, elite_paine13 ] {}; +void() elite_paine13=[ $paine13, elite_paine14 ] {}; +void() elite_paine14=[ $paine14, elite_paine15 ] {}; +void() elite_paine15=[ $paine15, elite_run1 ] {}; + + +void(entity attacker, float damage) elite_pain = +{ + local float r; + +// don't make multiple pain sounds right after each other + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "elite/ogpain1.wav", 1, ATTN_NORM); + + r = random(); + + if (r < 0.25) + { + elite_pain1 (); + self.pain_finished = time + 1; + } + else if (r < 0.5) + { + elite_painb1 (); + self.pain_finished = time + 1; + } + else if (r < 0.75) + { + elite_painc1 (); + self.pain_finished = time + 1; + } + else if (r < 0.88) + { + elite_paind1 (); + self.pain_finished = time + 2; + } + else + { + elite_paine1 (); + self.pain_finished = time + 2; + } +}; + +void() elite_die1 =[ $death1, elite_die2 ] {}; +void() elite_die2 =[ $death2, elite_die3 ] {}; +void() elite_die3 =[ $death3, elite_die4 ] +{self.solid = SOLID_NOT;DropBackpack();}; +void() elite_die4 =[ $death4, elite_die5 ] {}; +void() elite_die5 =[ $death5, elite_die6 ] {}; +void() elite_die6 =[ $death6, elite_die7 ] {}; +void() elite_die7 =[ $death7, elite_die8 ] {}; +void() elite_die8 =[ $death8, elite_die9 ] {}; +void() elite_die9 =[ $death9, elite_die10 ] {}; +void() elite_die10 =[ $death10, elite_die11 ] {}; +void() elite_die11 =[ $death11, elite_die12 ] {}; +void() elite_die12 =[ $death12, elite_die13 ] {}; +void() elite_die13 =[ $death13, elite_die14 ] {}; +void() elite_die14 =[ $death14, elite_die14 ] {remove(self); round_kills += 1; kill_count();}; + +void() elite_bdie1 =[ $bdeath1, elite_bdie2 ] {}; +void() elite_bdie2 =[ $bdeath2, elite_bdie3 ] {ai_forward(5);}; +void() elite_bdie3 =[ $bdeath3, elite_bdie4 ] +{self.solid = SOLID_NOT;DropBackpack();}; +void() elite_bdie4 =[ $bdeath4, elite_bdie5 ] {ai_forward(1);}; +void() elite_bdie5 =[ $bdeath5, elite_bdie6 ] {ai_forward(3);}; +void() elite_bdie6 =[ $bdeath6, elite_bdie7 ] {ai_forward(7);}; +void() elite_bdie7 =[ $bdeath7, elite_bdie8 ] {ai_forward(25);}; +void() elite_bdie8 =[ $bdeath8, elite_bdie9 ] {}; +void() elite_bdie9 =[ $bdeath9, elite_bdie10 ] {}; +void() elite_bdie10 =[ $bdeath10, elite_bdie10 ] {remove(self); round_kills += 1; kill_count();}; + +void() elite_die = +{ + + sound (self, CHAN_VOICE, "elite/ogdth.wav", 1, ATTN_NORM); + + if (random() < 0.5) + elite_die1 (); + else + elite_bdie1 (); +}; + +void() elite_melee = +{ + if (random() > 0.5) + elite_smash1 (); + else + elite_swing1 (); +}; + + +/* +============================================================================== + +SOLDIER / PLAYER + +============================================================================== +*/ + +$cd id1/models/soldier3 +$origin 0 -6 24 +$base base +$skin skin + +$frame prowl_1 prowl_2 prowl_3 prowl_4 prowl_5 prowl_6 prowl_7 prowl_8 +$frame prowl_9 prowl_10 prowl_11 prowl_12 prowl_13 prowl_14 prowl_15 prowl_16 +$frame prowl_17 prowl_18 prowl_19 prowl_20 prowl_21 prowl_22 prowl_23 prowl_24 + +/* +============================================================================== +SOLDIER CODE +============================================================================== +*/ + +void() laughs = +{ +local float r; +r = random(); +if (r <= 0.025) +{ +self.attack_finished = time + 0.6; +sound (self, CHAN_AUTO, "soldier/laugh1.wav", 0.8, ATTN_NORM); +} +else if ( r <= 0.05) +{ +self.attack_finished = time + 0.6; +sound (self, CHAN_AUTO, "soldier/laugh2.wav", 0.8, ATTN_NORM); +} +else +{} +}; +//For randomy playing a grunt sound +void() g_attack = +{ +local float r; +r = random(); +if (r <= 0.005) +{ +self.attack_finished = time + 0.6; +sound (self, CHAN_AUTO, "soldier/unstoppable.wav", 0.9, ATTN_NORM); +} +else if ( r <= 0.01) +{ +self.attack_finished = time + 0.6; +sound (self, CHAN_AUTO, "soldier/kill_it.wav", 0.9, ATTN_NORM); +} +else {} +}; +void() army_fire; + +void() army_stand1 =[ $stand1, army_stand2 ] {ai_stand();}; +void() army_stand2 =[ $stand2, army_stand3 ] {ai_stand();}; +void() army_stand3 =[ $stand3, army_stand4 ] {ai_stand();}; +void() army_stand4 =[ $stand4, army_stand5 ] {ai_stand();}; +void() army_stand5 =[ $stand5, army_stand6 ] {ai_stand();}; +void() army_stand6 =[ $stand6, army_stand7 ] {ai_stand();laughs();}; +void() army_stand7 =[ $stand7, army_stand8 ] {ai_stand();}; +void() army_stand8 =[ $stand8, army_stand1 ] {ai_stand();}; + +void() army_walk1 =[ $prowl_1, army_walk2 ] { +ai_walk(1);}; +void() army_walk2 =[ $prowl_2, army_walk3 ] {ai_walk(1);}; +void() army_walk3 =[ $prowl_3, army_walk4 ] {ai_walk(1);}; +void() army_walk4 =[ $prowl_4, army_walk5 ] {ai_walk(1);}; +void() army_walk5 =[ $prowl_5, army_walk6 ] {ai_walk(2);}; +void() army_walk6 =[ $prowl_6, army_walk7 ] {ai_walk(3);}; +void() army_walk7 =[ $prowl_7, army_walk8 ] {ai_walk(4);}; +void() army_walk8 =[ $prowl_8, army_walk9 ] {ai_walk(4);}; +void() army_walk9 =[ $prowl_9, army_walk10 ] {ai_walk(2);}; +void() army_walk10 =[ $prowl_10, army_walk11 ] {ai_walk(2);}; +void() army_walk11 =[ $prowl_11, army_walk12 ] {ai_walk(2);}; +void() army_walk12 =[ $prowl_12, army_walk13 ] {ai_walk(1);}; +void() army_walk13 =[ $prowl_13, army_walk14 ] {ai_walk(0);}; +void() army_walk14 =[ $prowl_14, army_walk15 ] {ai_walk(1);}; +void() army_walk15 =[ $prowl_15, army_walk16 ] {ai_walk(1);}; +void() army_walk16 =[ $prowl_16, army_walk17 ] {ai_walk(1);}; +void() army_walk17 =[ $prowl_17, army_walk18 ] {ai_walk(3);}; +void() army_walk18 =[ $prowl_18, army_walk19 ] {ai_walk(3);}; +void() army_walk19 =[ $prowl_19, army_walk20 ] {ai_walk(3);}; +void() army_walk20 =[ $prowl_20, army_walk21 ] {ai_walk(3);}; +void() army_walk21 =[ $prowl_21, army_walk22 ] {ai_walk(2);}; +void() army_walk22 =[ $prowl_22, army_walk23 ] {ai_walk(1);}; +void() army_walk23 =[ $prowl_23, army_walk24 ] {ai_walk(1);}; +void() army_walk24 =[ $prowl_24, army_walk1 ] {ai_walk(1);}; + +void() army_run1 =[ $run1, army_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE); +ai_run(11);}; +void() army_run2 =[ $run2, army_run3 ] {ai_run(15);}; +void() army_run3 =[ $run3, army_run4 ] {ai_run(10);}; +void() army_run4 =[ $run4, army_run5 ] {ai_run(10);}; +void() army_run5 =[ $run5, army_run6 ] {ai_run(8);}; +void() army_run6 =[ $run6, army_run7 ] {ai_run(15);}; +void() army_run7 =[ $run7, army_run8 ] {ai_run(10);}; +void() army_run8 =[ $run8, army_run1 ] {ai_run(8);}; + +void() army_atk1 =[ $shoot1, army_atk2 ] {ai_face();}; +void() army_atk2 =[ $shoot2, army_atk3 ] {ai_face();}; +void() army_atk3 =[ $shoot3, army_atk4 ] {ai_face();}; +void() army_atk4 =[ $shoot4, army_atk5 ] {ai_face();}; +void() army_atk5 =[ $shoot5, army_atk6 ] {ai_face(); Enemy_Fire_PPist();}; +void() army_atk6 =[ $shoot6, army_atk7 ] {ai_face();}; +void() army_atk7 =[ $shoot7, army_atk8 ] {ai_face();SUB_CheckRefire (army_atk1);}; +void() army_atk8 =[ $shoot8, army_atk9 ] {ai_face();}; +void() army_atk9 =[ $shoot9, army_run1 ] {ai_face();}; + +void() grunt_melee1 =[ $melee1, grunt_melee2 ] {ai_charge(1); }; +void() grunt_melee2 =[ $melee2, grunt_melee3 ] {ai_charge(1);}; +void() grunt_melee3 =[ $melee3, grunt_melee4 ] {ai_charge(4); chainsaw(0);self.angles_y = self.angles_y + random()* 10;}; +void() grunt_melee4 =[ $melee4, grunt_melee5 ] {ai_charge(13);}; +void() grunt_melee5 =[ $melee5, grunt_melee6 ] {ai_charge(9); }; +void() grunt_melee6 =[ $melee6, grunt_melee7 ] {}; +void() grunt_melee7 =[ $melee7, army_run1 ] {}; + +void() army_pain1 =[ $pain1, army_pain2 ] {}; +void() army_pain2 =[ $pain2, army_pain3 ] {}; +void() army_pain3 =[ $pain3, army_pain4 ] {}; +void() army_pain4 =[ $pain4, army_pain5 ] {g_attack();}; +void() army_pain5 =[ $pain5, army_pain6 ] {}; +void() army_pain6 =[ $pain6, army_run1 ] {ai_pain(1);}; + +void() army_painb1 =[ $painb1, army_painb2 ] {}; +void() army_painb2 =[ $painb2, army_painb3 ] {ai_painforward(13);}; +void() army_painb3 =[ $painb3, army_painb4 ] {ai_painforward(9);}; +void() army_painb4 =[ $painb4, army_painb5 ] {}; +void() army_painb5 =[ $painb5, army_painb6 ] {}; +void() army_painb6 =[ $painb6, army_painb7 ] {}; +void() army_painb7 =[ $painb7, army_painb8 ] {}; +void() army_painb8 =[ $painb8, army_painb9 ] {}; +void() army_painb9 =[ $painb9, army_painb10] {}; +void() army_painb10=[ $painb10, army_painb11] {}; +void() army_painb11=[ $painb11, army_painb12] {}; +void() army_painb12=[ $painb12, army_painb13] {ai_pain(2);}; +void() army_painb13=[ $painb13, army_painb14] {}; +void() army_painb14=[ $painb14, army_run1 ] {}; + +void() army_painc1 =[ $painc1, army_painc2 ] {}; +void() army_painc2 =[ $painc2, army_painc3 ] {ai_pain(1);}; +void() army_painc3 =[ $painc3, army_painc4 ] {}; +void() army_painc4 =[ $painc4, army_painc5 ] {}; +void() army_painc5 =[ $painc5, army_painc6 ] {ai_painforward(1);}; +void() army_painc6 =[ $painc6, army_painc7 ] {ai_painforward(1);}; +void() army_painc7 =[ $painc7, army_painc8 ] {}; +void() army_painc8 =[ $painc8, army_painc9 ] {ai_pain(1);}; +void() army_painc9 =[ $painc9, army_painc10] {ai_painforward(4);}; +void() army_painc10=[ $painc10, army_painc11] {ai_painforward(3);}; +void() army_painc11=[ $painc11, army_painc12] {ai_painforward(6);}; +void() army_painc12=[ $painc12, army_painc13] {ai_painforward(8);}; +void() army_painc13=[ $painc13, army_run1] {}; + +void(entity attacker, float damage) army_pain = +{ + local float r; + + if (self.pain_finished > time) + return; + + r = random(); + + if (r < 0.2) + { + self.pain_finished = time + 0.6; + army_pain1 (); + sound (self, CHAN_VOICE, "soldier/pain1.wav", 1, ATTN_NORM); + } + else if (r < 0.6) + { + self.pain_finished = time + 1.1; + army_painb1 (); + sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM); + } + else + { + self.pain_finished = time + 1.1; + army_painc1 (); + sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM); + } +}; + + +void() army_fire = +{ + local vector dir; + local entity en; + + ai_face(); + + sound (self, CHAN_WEAPON, "weapons/ppist.wav", 1, ATTN_NORM); + +// fire somewhat behind the player, so a dodging player is harder to hit + en = self.enemy; + + dir = en.origin - en.velocity*0.2; + dir = normalize (dir - self.origin); + + FireBullets (1, dir, '0.1 0.1 0', MOD_SOLDIER); +}; + + + +void() army_die1 =[ $death1, army_die2 ] {remove(self); round_kills += 1; kill_count();}; +void() army_die2 =[ $death2, army_die3 ] {}; +void() army_die3 =[ $death3, army_die4 ] {self.solid = SOLID_NOT;DropBackpack();}; +void() army_die4 =[ $death4, army_die5 ] {}; +void() army_die5 =[ $death5, army_die6 ] {}; +void() army_die6 =[ $death6, army_die7 ] {}; +void() army_die7 =[ $death7, army_die8 ] {}; +void() army_die8 =[ $death8, army_die9 ] {}; +void() army_die9 =[ $death9, army_die10 ] {}; +void() army_die10 =[ $death10, army_die10 ] {}; + + +void() army_die = +{ + +// regular death + sound (self, CHAN_VOICE, "soldier/death1.wav", 1, ATTN_NORM); + army_die1 (); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/boss.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/boss.qc new file mode 100755 index 00000000..caebe26f --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/boss.qc @@ -0,0 +1,373 @@ +/* +============================================================================== + +BOSS-ONE + +============================================================================== +*/ +$cd id1/models/boss1 +$origin 0 0 -15 +$base base +$skin skin +$scale 5 + +$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9 rise10 +$frame rise11 rise12 rise13 rise14 rise15 rise16 rise17 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 +$frame walk9 walk10 walk11 walk12 walk13 walk14 walk15 +$frame walk16 walk17 walk18 walk19 walk20 walk21 walk22 +$frame walk23 walk24 walk25 walk26 walk27 walk28 walk29 walk30 walk31 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 + +$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 +$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15 +$frame attack16 attack17 attack18 attack19 attack20 attack21 attack22 +$frame attack23 + +$frame shocka1 shocka2 shocka3 shocka4 shocka5 shocka6 shocka7 shocka8 +$frame shocka9 shocka10 + +$frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6 + +$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8 +$frame shockc9 shockc10 + + +void(vector p) boss_missile; + +void() boss_face = +{ + +// go for another player if multi player + if (self.enemy.health <= 0 || random() < 0.02) + { + self.enemy = find(self.enemy, classname, "player"); + if (!self.enemy) + self.enemy = find(self.enemy, classname, "player"); + } + ai_face(); +}; + +void() boss_rise1 =[ $rise1, boss_rise2 ] { +sound (self, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM); +}; +void() boss_rise2 =[ $rise2, boss_rise3 ] { +sound (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM); +}; +void() boss_rise3 =[ $rise3, boss_rise4 ] {}; +void() boss_rise4 =[ $rise4, boss_rise5 ] {}; +void() boss_rise5 =[ $rise5, boss_rise6 ] {}; +void() boss_rise6 =[ $rise6, boss_rise7 ] {}; +void() boss_rise7 =[ $rise7, boss_rise8 ] {}; +void() boss_rise8 =[ $rise8, boss_rise9 ] {}; +void() boss_rise9 =[ $rise9, boss_rise10 ] {}; +void() boss_rise10 =[ $rise10, boss_rise11 ] {}; +void() boss_rise11 =[ $rise11, boss_rise12 ] {}; +void() boss_rise12 =[ $rise12, boss_rise13 ] {}; +void() boss_rise13 =[ $rise13, boss_rise14 ] {}; +void() boss_rise14 =[ $rise14, boss_rise15 ] {}; +void() boss_rise15 =[ $rise15, boss_rise16 ] {}; +void() boss_rise16 =[ $rise16, boss_rise17 ] {}; +void() boss_rise17 =[ $rise17, boss_missile1 ] {}; + +void() boss_idle1 =[ $walk1, boss_idle2 ] +{ +// look for other players +}; +void() boss_idle2 =[ $walk2, boss_idle3 ] {boss_face();}; +void() boss_idle3 =[ $walk3, boss_idle4 ] {boss_face();}; +void() boss_idle4 =[ $walk4, boss_idle5 ] {boss_face();}; +void() boss_idle5 =[ $walk5, boss_idle6 ] {boss_face();}; +void() boss_idle6 =[ $walk6, boss_idle7 ] {boss_face();}; +void() boss_idle7 =[ $walk7, boss_idle8 ] {boss_face();}; +void() boss_idle8 =[ $walk8, boss_idle9 ] {boss_face();}; +void() boss_idle9 =[ $walk9, boss_idle10 ] {boss_face();}; +void() boss_idle10 =[ $walk10, boss_idle11 ] {boss_face();}; +void() boss_idle11 =[ $walk11, boss_idle12 ] {boss_face();}; +void() boss_idle12 =[ $walk12, boss_idle13 ] {boss_face();}; +void() boss_idle13 =[ $walk13, boss_idle14 ] {boss_face();}; +void() boss_idle14 =[ $walk14, boss_idle15 ] {boss_face();}; +void() boss_idle15 =[ $walk15, boss_idle16 ] {boss_face();}; +void() boss_idle16 =[ $walk16, boss_idle17 ] {boss_face();}; +void() boss_idle17 =[ $walk17, boss_idle18 ] {boss_face();}; +void() boss_idle18 =[ $walk18, boss_idle19 ] {boss_face();}; +void() boss_idle19 =[ $walk19, boss_idle20 ] {boss_face();}; +void() boss_idle20 =[ $walk20, boss_idle21 ] {boss_face();}; +void() boss_idle21 =[ $walk21, boss_idle22 ] {boss_face();}; +void() boss_idle22 =[ $walk22, boss_idle23 ] {boss_face();}; +void() boss_idle23 =[ $walk23, boss_idle24 ] {boss_face();}; +void() boss_idle24 =[ $walk24, boss_idle25 ] {boss_face();}; +void() boss_idle25 =[ $walk25, boss_idle26 ] {boss_face();}; +void() boss_idle26 =[ $walk26, boss_idle27 ] {boss_face();}; +void() boss_idle27 =[ $walk27, boss_idle28 ] {boss_face();}; +void() boss_idle28 =[ $walk28, boss_idle29 ] {boss_face();}; +void() boss_idle29 =[ $walk29, boss_idle30 ] {boss_face();}; +void() boss_idle30 =[ $walk30, boss_idle31 ] {boss_face();}; +void() boss_idle31 =[ $walk31, boss_idle1 ] {boss_face();}; + +void() boss_missile1 =[ $attack1, boss_missile2 ] {boss_face();}; +void() boss_missile2 =[ $attack2, boss_missile3 ] {boss_face();}; +void() boss_missile3 =[ $attack3, boss_missile4 ] {boss_face();}; +void() boss_missile4 =[ $attack4, boss_missile5 ] {boss_face();}; +void() boss_missile5 =[ $attack5, boss_missile6 ] {boss_face();}; +void() boss_missile6 =[ $attack6, boss_missile7 ] {boss_face();}; +void() boss_missile7 =[ $attack7, boss_missile8 ] {boss_face();}; +void() boss_missile8 =[ $attack8, boss_missile9 ] {boss_face();}; +void() boss_missile9 =[ $attack9, boss_missile10 ] {boss_missile('100 100 200');}; +void() boss_missile10 =[ $attack10, boss_missile11 ] {boss_face();}; +void() boss_missile11 =[ $attack11, boss_missile12 ] {boss_face();}; +void() boss_missile12 =[ $attack12, boss_missile13 ] {boss_face();}; +void() boss_missile13 =[ $attack13, boss_missile14 ] {boss_face();}; +void() boss_missile14 =[ $attack14, boss_missile15 ] {boss_face();}; +void() boss_missile15 =[ $attack15, boss_missile16 ] {boss_face();}; +void() boss_missile16 =[ $attack16, boss_missile17 ] {boss_face();}; +void() boss_missile17 =[ $attack17, boss_missile18 ] {boss_face();}; +void() boss_missile18 =[ $attack18, boss_missile19 ] {boss_face();}; +void() boss_missile19 =[ $attack19, boss_missile20 ] {boss_face();}; +void() boss_missile20 =[ $attack20, boss_missile21 ] {boss_missile('100 -100 200');}; +void() boss_missile21 =[ $attack21, boss_missile22 ] {boss_face();}; +void() boss_missile22 =[ $attack22, boss_missile23 ] {boss_face();}; +void() boss_missile23 =[ $attack23, boss_missile1 ] {boss_face();}; + +void() boss_shocka1 =[ $shocka1, boss_shocka2 ] {}; +void() boss_shocka2 =[ $shocka2, boss_shocka3 ] {}; +void() boss_shocka3 =[ $shocka3, boss_shocka4 ] {}; +void() boss_shocka4 =[ $shocka4, boss_shocka5 ] {}; +void() boss_shocka5 =[ $shocka5, boss_shocka6 ] {}; +void() boss_shocka6 =[ $shocka6, boss_shocka7 ] {}; +void() boss_shocka7 =[ $shocka7, boss_shocka8 ] {}; +void() boss_shocka8 =[ $shocka8, boss_shocka9 ] {}; +void() boss_shocka9 =[ $shocka9, boss_shocka10 ] {}; +void() boss_shocka10 =[ $shocka10, boss_missile1 ] {}; + +void() boss_shockb1 =[ $shockb1, boss_shockb2 ] {}; +void() boss_shockb2 =[ $shockb2, boss_shockb3 ] {}; +void() boss_shockb3 =[ $shockb3, boss_shockb4 ] {}; +void() boss_shockb4 =[ $shockb4, boss_shockb5 ] {}; +void() boss_shockb5 =[ $shockb5, boss_shockb6 ] {}; +void() boss_shockb6 =[ $shockb6, boss_shockb7 ] {}; +void() boss_shockb7 =[ $shockb1, boss_shockb8 ] {}; +void() boss_shockb8 =[ $shockb2, boss_shockb9 ] {}; +void() boss_shockb9 =[ $shockb3, boss_shockb10 ] {}; +void() boss_shockb10 =[ $shockb4, boss_missile1 ] {}; + +void() boss_shockc1 =[ $shockc1, boss_shockc2 ] {}; +void() boss_shockc2 =[ $shockc2, boss_shockc3 ] {}; +void() boss_shockc3 =[ $shockc3, boss_shockc4 ] {}; +void() boss_shockc4 =[ $shockc4, boss_shockc5 ] {}; +void() boss_shockc5 =[ $shockc5, boss_shockc6 ] {}; +void() boss_shockc6 =[ $shockc6, boss_shockc7 ] {}; +void() boss_shockc7 =[ $shockc7, boss_shockc8 ] {}; +void() boss_shockc8 =[ $shockc8, boss_shockc9 ] {}; +void() boss_shockc9 =[ $shockc9, boss_shockc10 ] {}; +void() boss_shockc10 =[ $shockc10, boss_death1 ] {}; + +void() boss_death1 = [$death1, boss_death2] { +sound (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM); +}; +void() boss_death2 = [$death2, boss_death3] {}; +void() boss_death3 = [$death3, boss_death4] {}; +void() boss_death4 = [$death4, boss_death5] {}; +void() boss_death5 = [$death5, boss_death6] {}; +void() boss_death6 = [$death6, boss_death7] {}; +void() boss_death7 = [$death7, boss_death8] {}; +void() boss_death8 = [$death8, boss_death9] {}; +void() boss_death9 = [$death9, boss_death10] +{ + sound (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM); + TE_lavasplash(self.origin); +}; + +void() boss_death10 = [$death9, boss_death10] +{ + killed_monsters = killed_monsters + 1; + WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast + SUB_UseTargets (); + remove (self); +}; + +void(vector p) boss_missile = +{ + local vector offang; + local vector org, vec, d; + local float t; + + offang = vectoangles (self.enemy.origin - self.origin); + makevectors (offang); + + org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1'; + +// lead the player on hard mode + if (skill > 1) + { + t = vlen(self.enemy.origin - org) / 300; + vec = self.enemy.velocity; + vec_z = 0; + d = self.enemy.origin + t * vec; + } + else + { + d = self.enemy.origin; + } + + vec = normalize(d - org) * 300; + + PRJ_FireProjectile(self, "progs/lavaball.mdl", org, vec, PE_EXPLOSION, 100+random()*20, MOD_CHTHON, 5); + PRJ_SetRadiusDamage(120, 160, MOD_CHTHON); + newmis.avelocity = '200 100 300'; + + sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM); + +// check for dead enemy + if (self.enemy.health <= 0) + boss_idle1 (); +}; + + +void() boss_awake = +{ + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + self.takedamage = DAMAGE_NO; + + setmodel (self, "progs/boss.mdl"); + setsize (self, '-128 -128 -24', '128 128 256'); + + if (skill == 0) + self.health = 1; + else + self.health = 3; + + self.enemy = activator; + + TE_lavasplash(self.origin); + + self.yaw_speed = 20; + boss_rise1 (); +}; + + +/*QUAKED monster_boss (1 0 0) (-128 -128 -24) (128 128 256) +*/ +void() monster_boss = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/boss.mdl"); + precache_model ("progs/lavaball.mdl"); + + precache_sound ("weapons/rocket1i.wav"); + precache_sound ("boss1/out1.wav"); + precache_sound ("boss1/sight1.wav"); + precache_sound ("misc/power.wav"); + precache_sound ("boss1/throw.wav"); + precache_sound ("boss1/pain.wav"); + precache_sound ("boss1/death.wav"); + + total_monsters = total_monsters + 1; + + self.use = boss_awake; +}; + +//=========================================================================== + +entity le1, le2; +float lightning_end; + +void() lightning_fire = +{ + local vector p1, p2; + + if (time >= lightning_end) + { // done here, put the terminals back up + self = le1; + door_go_down (); + self = le2; + door_go_down (); + return; + } + + p1 = (le1.mins + le1.maxs) * 0.5; + p1_z = le1.absmin_z - 16; + + p2 = (le2.mins + le2.maxs) * 0.5; + p2_z = le2.absmin_z - 16; + + // compensate for length of bolt + p2 = p2 - normalize(p2-p1)*100; + + self.nextthink = time + 0.1; + self.think = lightning_fire; + + TE_lightning3(world, p1, p2); +}; + +void() lightning_use = +{ + if (lightning_end >= time + 1) + return; + + le1 = find( world, target, "lightning"); + le2 = find( le1, target, "lightning"); + if (!le1 || !le2) + { + dprint ("missing lightning targets\n"); + return; + } + + if ( + (le1.state != STATE_TOP && le1.state != STATE_BOTTOM) + || (le2.state != STATE_TOP && le2.state != STATE_BOTTOM) + || (le1.state != le2.state) ) + { +// dprint ("not aligned\n"); + return; + } + +// don't let the electrodes go back up until the bolt is done + le1.nextthink = -1; + le2.nextthink = -1; + lightning_end = time + 1; + + sound (self, CHAN_VOICE, "misc/power.wav", 1, ATTN_NORM); + lightning_fire (); + +// advance the boss pain if down + self = find (world, classname, "monster_boss"); + if (!self) + return; + self.enemy = activator; + if (le1.state == STATE_TOP && self.health > 0) + { + sound (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM); + self.health = self.health - 1; + if (self.health >= 2) + boss_shocka1(); + else if (self.health == 1) + boss_shockb1(); + else if (self.health == 0) + boss_shockc1(); + } +}; + + +/*QUAKED event_lightning (0 1 1) (-16 -16 -16) (16 16 16) +Just for boss level. +*/ +void() event_lightning = +{ + if (deathmatch) + { + remove(self); + return; + } + + self.use = lightning_use; +}; + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/demon.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/demon.qc new file mode 100755 index 00000000..cb1394e9 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/demon.qc @@ -0,0 +1,357 @@ +/* +============================================================================== + +DEMON + +============================================================================== +*/ + +$cd id1/models/demon3 +$scale 0.8 +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 +$frame stand10 stand11 stand12 stand13 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 + +$frame run1 run2 run3 run4 run5 run6 + +$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 leap10 +$frame leap11 leap12 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 + +$frame attacka1 attacka2 attacka3 attacka4 attacka5 attacka6 attacka7 attacka8 +$frame attacka9 attacka10 attacka11 attacka12 attacka13 attacka14 attacka15 + +//============================================================================ + +void() Demon_JumpTouch; +void(float side) Demon_Melee; + +void() demon1_stand1 =[ $stand1, demon1_stand2 ] {ai_stand();}; +void() demon1_stand2 =[ $stand2, demon1_stand3 ] {ai_stand();}; +void() demon1_stand3 =[ $stand3, demon1_stand4 ] {ai_stand();}; +void() demon1_stand4 =[ $stand4, demon1_stand5 ] {ai_stand();}; +void() demon1_stand5 =[ $stand5, demon1_stand6 ] {ai_stand();}; +void() demon1_stand6 =[ $stand6, demon1_stand7 ] {ai_stand();}; +void() demon1_stand7 =[ $stand7, demon1_stand8 ] {ai_stand();}; +void() demon1_stand8 =[ $stand8, demon1_stand9 ] {ai_stand();}; +void() demon1_stand9 =[ $stand9, demon1_stand10 ] {ai_stand();}; +void() demon1_stand10 =[ $stand10, demon1_stand11 ] {ai_stand();}; +void() demon1_stand11 =[ $stand11, demon1_stand12 ] {ai_stand();}; +void() demon1_stand12 =[ $stand12, demon1_stand13 ] {ai_stand();}; +void() demon1_stand13 =[ $stand13, demon1_stand1 ] {ai_stand();}; + +void() demon1_walk1 =[ $walk1, demon1_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE); +ai_walk(8); +}; +void() demon1_walk2 =[ $walk2, demon1_walk3 ] {ai_walk(6);}; +void() demon1_walk3 =[ $walk3, demon1_walk4 ] {ai_walk(6);}; +void() demon1_walk4 =[ $walk4, demon1_walk5 ] {ai_walk(7);}; +void() demon1_walk5 =[ $walk5, demon1_walk6 ] {ai_walk(4);}; +void() demon1_walk6 =[ $walk6, demon1_walk7 ] {ai_walk(6);}; +void() demon1_walk7 =[ $walk7, demon1_walk8 ] {ai_walk(10);}; +void() demon1_walk8 =[ $walk8, demon1_walk1 ] {ai_walk(10);}; + +void() demon1_run1 =[ $run1, demon1_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE); +ai_run(20);}; +void() demon1_run2 =[ $run2, demon1_run3 ] {ai_run(15);}; +void() demon1_run3 =[ $run3, demon1_run4 ] {ai_run(36);}; +void() demon1_run4 =[ $run4, demon1_run5 ] {ai_run(20);}; +void() demon1_run5 =[ $run5, demon1_run6 ] {ai_run(15);}; +void() demon1_run6 =[ $run6, demon1_run1 ] {ai_run(36);}; + +void() demon1_jump1 =[ $leap1, demon1_jump2 ] {ai_face();}; +void() demon1_jump2 =[ $leap2, demon1_jump3 ] {ai_face();}; +void() demon1_jump3 =[ $leap3, demon1_jump4 ] {ai_face();}; +void() demon1_jump4 =[ $leap4, demon1_jump5 ] +{ + ai_face(); + + self.touch = Demon_JumpTouch; + makevectors (self.angles); + self.origin_z = self.origin_z + 1; + self.velocity = v_forward * 600 + '0 0 250'; + if (self.flags & FL_ONGROUND) + self.flags = self.flags - FL_ONGROUND; +}; +void() demon1_jump5 =[ $leap5, demon1_jump6 ] {}; +void() demon1_jump6 =[ $leap6, demon1_jump7 ] {}; +void() demon1_jump7 =[ $leap7, demon1_jump8 ] {}; +void() demon1_jump8 =[ $leap8, demon1_jump9 ] {}; +void() demon1_jump9 =[ $leap9, demon1_jump10 ] {}; +void() demon1_jump10 =[ $leap10, demon1_jump1 ] { +self.nextthink = time + 3; +// if three seconds pass, assume demon is stuck and jump again +}; + +void() demon1_jump11 =[ $leap11, demon1_jump12 ] {}; +void() demon1_jump12 =[ $leap12, demon1_run1 ] {}; + + +void() demon1_atta1 =[ $attacka1, demon1_atta2 ] {ai_charge(4);}; +void() demon1_atta2 =[ $attacka2, demon1_atta3 ] {ai_charge(0);}; +void() demon1_atta3 =[ $attacka3, demon1_atta4 ] {ai_charge(0);}; +void() demon1_atta4 =[ $attacka4, demon1_atta5 ] {ai_charge(1);}; +void() demon1_atta5 =[ $attacka5, demon1_atta6 ] {ai_charge(2); Demon_Melee(200);}; +void() demon1_atta6 =[ $attacka6, demon1_atta7 ] {ai_charge(1);}; +void() demon1_atta7 =[ $attacka7, demon1_atta8 ] {ai_charge(6);}; +void() demon1_atta8 =[ $attacka8, demon1_atta9 ] {ai_charge(8);}; +void() demon1_atta9 =[ $attacka9, demon1_atta10] {ai_charge(4);}; +void() demon1_atta10 =[ $attacka10, demon1_atta11] {ai_charge(2);}; +void() demon1_atta11 =[ $attacka11, demon1_atta12] {Demon_Melee(-200);}; +void() demon1_atta12 =[ $attacka12, demon1_atta13] {ai_charge(5);}; +void() demon1_atta13 =[ $attacka13, demon1_atta14] {ai_charge(8);}; +void() demon1_atta14 =[ $attacka14, demon1_atta15] {ai_charge(4);}; +void() demon1_atta15 =[ $attacka15, demon1_run1] {ai_charge(4);}; + +void() demon1_pain1 =[ $pain1, demon1_pain2 ] {}; +void() demon1_pain2 =[ $pain2, demon1_pain3 ] {}; +void() demon1_pain3 =[ $pain3, demon1_pain4 ] {}; +void() demon1_pain4 =[ $pain4, demon1_pain5 ] {}; +void() demon1_pain5 =[ $pain5, demon1_pain6 ] {}; +void() demon1_pain6 =[ $pain6, demon1_run1 ] {}; + +void(entity attacker, float damage) demon1_pain = +{ + if (self.touch == Demon_JumpTouch) + return; + + if (self.pain_finished > time) + return; + + self.pain_finished = time + 1; + sound (self, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM); + + if (random()*200 > damage) + return; // didn't flinch + + demon1_pain1 (); +}; + +void() demon1_die1 =[ $death1, demon1_die2 ] { +sound (self, CHAN_VOICE, "demon/ddeath.wav", 1, ATTN_NORM);}; +void() demon1_die2 =[ $death2, demon1_die3 ] {}; +void() demon1_die3 =[ $death3, demon1_die4 ] {}; +void() demon1_die4 =[ $death4, demon1_die5 ] {}; +void() demon1_die5 =[ $death5, demon1_die6 ] {}; +void() demon1_die6 =[ $death6, demon1_die7 ] +{self.solid = SOLID_NOT;}; +void() demon1_die7 =[ $death7, demon1_die8 ] {}; +void() demon1_die8 =[ $death8, demon1_die9 ] {}; +void() demon1_die9 =[ $death9, demon1_die9 ] {}; + +void() demon_die = +{ +// check for gib + if (self.health < -80) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_demon.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + return; + } + +// regular death + demon1_die1 (); +}; + + +void() Demon_MeleeAttack = +{ + demon1_atta1 (); +}; + + +/*QUAKED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) Ambush + +*/ +void() monster_demon1 = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/demon.mdl"); + precache_model ("progs/h_demon.mdl"); + + precache_sound ("demon/ddeath.wav"); + precache_sound ("demon/dhit2.wav"); + precache_sound ("demon/djump.wav"); + precache_sound ("demon/dpain1.wav"); + precache_sound ("demon/idle1.wav"); + precache_sound ("demon/sight2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/demon.mdl"); + + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 300; + + self.th_stand = demon1_stand1; + self.th_walk = demon1_walk1; + self.th_run = demon1_run1; + self.th_die = demon_die; + self.th_melee = Demon_MeleeAttack; // one of two attacks + self.th_missile = demon1_jump1; // jump attack + self.th_pain = demon1_pain; + + walkmonster_start(); +}; + + +/* +============================================================================== + +DEMON + +============================================================================== +*/ + +/* +============== +CheckDemonMelee + +Returns TRUE if a melee attack would hit right now +============== +*/ +BOOL(float enemy_range) CheckDemonMelee = +{ + if (enemy_range == RANGE_MELEE) + { // FIXME: check canreach + self.attack_state = AS_MELEE; + return TRUE; + } + return FALSE; +}; + +/* +============== +CheckDemonJump + +============== +*/ +BOOL() CheckDemonJump = +{ + local vector dist; + local float d; + + if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z + + 0.75 * self.enemy.size_z) + return FALSE; + + if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z + + 0.25 * self.enemy.size_z) + return FALSE; + + dist = self.enemy.origin - self.origin; + dist_z = 0; + + d = vlen(dist); + + if (d < 100) + return FALSE; + + if (d > 200) + { + if (random() < 0.9) + return FALSE; + } + + return TRUE; +}; + +BOOL(float enemy_range) DemonCheckAttack = +{ +// if close enough for slashing, go for it + if (CheckDemonMelee (enemy_range)) + { + self.attack_state = AS_MELEE; + return TRUE; + } + + if (CheckDemonJump ()) + { + self.attack_state = AS_MISSILE; + sound (self, CHAN_VOICE, "demon/djump.wav", 1, ATTN_NORM); + return TRUE; + } + + return FALSE; +}; + + +//=========================================================================== + +void(float side) Demon_Melee = +{ + local float ldmg; + local vector delta; + + ai_face (); + walkmove (self.ideal_yaw, 12); // allow a little closing + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + if (!CanDamage (self.enemy, self)) + return; + + sound (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM); + ldmg = 10 + 5*random(); + T_Damage (self.enemy, self, self, ldmg, MOD_DEMON); + + makevectors (self.angles); + SpawnMeatSpray (self.origin + v_forward*16, side * v_right); +}; + + +void() Demon_JumpTouch = +{ + local float ldmg; + + if (self.health <= 0) + return; + + if (other.takedamage) + { + if ( vlen(self.velocity) > 400 ) + { + ldmg = 40 + 10*random(); + T_Damage (other, self, self, ldmg, MOD_DEMON); + } + } + + if (!checkbottom(self)) + { + if (self.flags & FL_ONGROUND) + { // jump randomly to not get hung up + self.touch = SUB_Null; + self.think = demon1_jump1; + self.nextthink = time + 0.1; + } + return; // not on ground yet + } + + self.touch = SUB_Null; + self.think = demon1_jump11; + self.nextthink = time + 0.1; +}; + + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/dog.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/dog.qc new file mode 100755 index 00000000..155cb850 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/dog.qc @@ -0,0 +1,357 @@ +/* +============================================================================== + +DOG + +============================================================================== +*/ +$cd id1/models/dog +$origin 0 0 24 +$base base +$skin skin + +$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10 +$frame painb11 painb12 painb13 painb14 painb15 painb16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 + +$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 + + +void() dog_leap1; +void() dog_run1; + +/* +================ +dog_bite + +================ +*/ +void() dog_bite = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + + ai_charge(10); + + if (!CanDamage (self.enemy, self)) + return; + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + ldmg = (random() + random() + random()) * 8; + T_Damage (self.enemy, self, self, ldmg, MOD_DOG); +}; + +void() Dog_JumpTouch = +{ + local float ldmg; + + if (self.health <= 0) + return; + + if (other.takedamage) + { + if ( vlen(self.velocity) > 300 ) + { + ldmg = 10 + 10*random(); + T_Damage (other, self, self, ldmg, MOD_DOG); + } + } + + if (!checkbottom(self)) + { + if (self.flags & FL_ONGROUND) + { + // jump randomly to not get hung up + self.touch = SUB_Null; + self.think = dog_leap1; + self.nextthink = time + 0.1; + } + return; // not on ground yet + } + + self.touch = SUB_Null; + self.think = dog_run1; + self.nextthink = time + 0.1; +}; + + +void() dog_stand1 =[ $stand1, dog_stand2 ] {ai_stand();}; +void() dog_stand2 =[ $stand2, dog_stand3 ] {ai_stand();}; +void() dog_stand3 =[ $stand3, dog_stand4 ] {ai_stand();}; +void() dog_stand4 =[ $stand4, dog_stand5 ] {ai_stand();}; +void() dog_stand5 =[ $stand5, dog_stand6 ] {ai_stand();}; +void() dog_stand6 =[ $stand6, dog_stand7 ] {ai_stand();}; +void() dog_stand7 =[ $stand7, dog_stand8 ] {ai_stand();}; +void() dog_stand8 =[ $stand8, dog_stand9 ] {ai_stand();}; +void() dog_stand9 =[ $stand9, dog_stand1 ] {ai_stand();}; + +void() dog_walk1 =[ $walk1 , dog_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); +ai_walk(8);}; +void() dog_walk2 =[ $walk2 , dog_walk3 ] {ai_walk(8);}; +void() dog_walk3 =[ $walk3 , dog_walk4 ] {ai_walk(8);}; +void() dog_walk4 =[ $walk4 , dog_walk5 ] {ai_walk(8);}; +void() dog_walk5 =[ $walk5 , dog_walk6 ] {ai_walk(8);}; +void() dog_walk6 =[ $walk6 , dog_walk7 ] {ai_walk(8);}; +void() dog_walk7 =[ $walk7 , dog_walk8 ] {ai_walk(8);}; +void() dog_walk8 =[ $walk8 , dog_walk1 ] {ai_walk(8);}; + +void() dog_run1 =[ $run1 , dog_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); +ai_run(16);}; +void() dog_run2 =[ $run2 , dog_run3 ] {ai_run(32);}; +void() dog_run3 =[ $run3 , dog_run4 ] {ai_run(32);}; +void() dog_run4 =[ $run4 , dog_run5 ] {ai_run(20);}; +void() dog_run5 =[ $run5 , dog_run6 ] {ai_run(64);}; +void() dog_run6 =[ $run6 , dog_run7 ] {ai_run(32);}; +void() dog_run7 =[ $run7 , dog_run8 ] {ai_run(16);}; +void() dog_run8 =[ $run8 , dog_run9 ] {ai_run(32);}; +void() dog_run9 =[ $run9 , dog_run10 ] {ai_run(32);}; +void() dog_run10 =[ $run10 , dog_run11 ] {ai_run(20);}; +void() dog_run11 =[ $run11 , dog_run12 ] {ai_run(64);}; +void() dog_run12 =[ $run12 , dog_run1 ] {ai_run(32);}; + +void() dog_atta1 =[ $attack1, dog_atta2 ] {ai_charge(10);}; +void() dog_atta2 =[ $attack2, dog_atta3 ] {ai_charge(10);}; +void() dog_atta3 =[ $attack3, dog_atta4 ] {ai_charge(10);}; +void() dog_atta4 =[ $attack4, dog_atta5 ] { +sound (self, CHAN_VOICE, "dog/dattack1.wav", 1, ATTN_NORM); +dog_bite();}; +void() dog_atta5 =[ $attack5, dog_atta6 ] {ai_charge(10);}; +void() dog_atta6 =[ $attack6, dog_atta7 ] {ai_charge(10);}; +void() dog_atta7 =[ $attack7, dog_atta8 ] {ai_charge(10);}; +void() dog_atta8 =[ $attack8, dog_run1 ] {ai_charge(10);}; + +void() dog_leap1 =[ $leap1, dog_leap2 ] {ai_face();}; +void() dog_leap2 =[ $leap2, dog_leap3 ] +{ + ai_face(); + + self.touch = Dog_JumpTouch; + makevectors (self.angles); + self.origin_z = self.origin_z + 1; + self.velocity = v_forward * 300 + '0 0 200'; + if (self.flags & FL_ONGROUND) + self.flags = self.flags - FL_ONGROUND; +}; + +void() dog_leap3 =[ $leap3, dog_leap4 ] {}; +void() dog_leap4 =[ $leap4, dog_leap5 ] {}; +void() dog_leap5 =[ $leap5, dog_leap6 ] {}; +void() dog_leap6 =[ $leap6, dog_leap7 ] {}; +void() dog_leap7 =[ $leap7, dog_leap8 ] {}; +void() dog_leap8 =[ $leap8, dog_leap9 ] {}; +void() dog_leap9 =[ $leap9, dog_leap9 ] {}; + +void() dog_pain1 =[ $pain1 , dog_pain2 ] {}; +void() dog_pain2 =[ $pain2 , dog_pain3 ] {}; +void() dog_pain3 =[ $pain3 , dog_pain4 ] {}; +void() dog_pain4 =[ $pain4 , dog_pain5 ] {}; +void() dog_pain5 =[ $pain5 , dog_pain6 ] {}; +void() dog_pain6 =[ $pain6 , dog_run1 ] {}; + +void() dog_painb1 =[ $painb1 , dog_painb2 ] {}; +void() dog_painb2 =[ $painb2 , dog_painb3 ] {}; +void() dog_painb3 =[ $painb3 , dog_painb4 ] {ai_pain(4);}; +void() dog_painb4 =[ $painb4 , dog_painb5 ] {ai_pain(12);}; +void() dog_painb5 =[ $painb5 , dog_painb6 ] {ai_pain(12);}; +void() dog_painb6 =[ $painb6 , dog_painb7 ] {ai_pain(2);}; +void() dog_painb7 =[ $painb7 , dog_painb8 ] {}; +void() dog_painb8 =[ $painb8 , dog_painb9 ] {ai_pain(4);}; +void() dog_painb9 =[ $painb9 , dog_painb10 ] {}; +void() dog_painb10 =[ $painb10 , dog_painb11 ] {ai_pain(10);}; +void() dog_painb11 =[ $painb11 , dog_painb12 ] {}; +void() dog_painb12 =[ $painb12 , dog_painb13 ] {}; +void() dog_painb13 =[ $painb13 , dog_painb14 ] {}; +void() dog_painb14 =[ $painb14 , dog_painb15 ] {}; +void() dog_painb15 =[ $painb15 , dog_painb16 ] {}; +void() dog_painb16 =[ $painb16 , dog_run1 ] {}; + +void() dog_pain = +{ + sound (self, CHAN_VOICE, "dog/dpain1.wav", 1, ATTN_NORM); + + if (random() > 0.5) + dog_pain1 (); + else + dog_painb1 (); +}; + +void() dog_die1 =[ $death1, dog_die2 ] {}; +void() dog_die2 =[ $death2, dog_die3 ] {}; +void() dog_die3 =[ $death3, dog_die4 ] {}; +void() dog_die4 =[ $death4, dog_die5 ] {}; +void() dog_die5 =[ $death5, dog_die6 ] {}; +void() dog_die6 =[ $death6, dog_die7 ] {}; +void() dog_die7 =[ $death7, dog_die8 ] {}; +void() dog_die8 =[ $death8, dog_die9 ] {}; +void() dog_die9 =[ $death9, dog_die9 ] {}; + +void() dog_dieb1 =[ $deathb1, dog_dieb2 ] {}; +void() dog_dieb2 =[ $deathb2, dog_dieb3 ] {}; +void() dog_dieb3 =[ $deathb3, dog_dieb4 ] {}; +void() dog_dieb4 =[ $deathb4, dog_dieb5 ] {}; +void() dog_dieb5 =[ $deathb5, dog_dieb6 ] {}; +void() dog_dieb6 =[ $deathb6, dog_dieb7 ] {}; +void() dog_dieb7 =[ $deathb7, dog_dieb8 ] {}; +void() dog_dieb8 =[ $deathb8, dog_dieb9 ] {}; +void() dog_dieb9 =[ $deathb9, dog_dieb9 ] {}; + + +void() dog_die = +{ +// check for gib + if (self.health < -35) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + ThrowHead ("progs/h_dog.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "dog/ddeath.wav", 1, ATTN_NORM); + self.solid = SOLID_NOT; + + if (random() > 0.5) + dog_die1 (); + else + dog_dieb1 (); +}; + +//============================================================================ + +/* +============== +CheckDogMelee + +Returns TRUE if a melee attack would hit right now +============== +*/ +BOOL(float enemy_range) CheckDogMelee = +{ + if (enemy_range == RANGE_MELEE) + { // FIXME: check canreach + self.attack_state = AS_MELEE; + return TRUE; + } + return FALSE; +}; + +/* +============== +CheckDogJump + +============== +*/ +BOOL() CheckDogJump = +{ + local vector dist; + local float d; + + if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z + + 0.75 * self.enemy.size_z) + return FALSE; + + if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z + + 0.25 * self.enemy.size_z) + return FALSE; + + dist = self.enemy.origin - self.origin; + dist_z = 0; + + d = vlen(dist); + + if (d < 80) + return FALSE; + + if (d > 150) + return FALSE; + + return TRUE; +}; + +BOOL(float enemy_range) DogCheckAttack = +{ +// if close enough for slashing, go for it + if (CheckDogMelee (enemy_range)) + { + self.attack_state = AS_MELEE; + return TRUE; + } + + if (CheckDogJump ()) + { + self.attack_state = AS_MISSILE; + return TRUE; + } + + return FALSE; +}; + + +//=========================================================================== + +/*QUAKED monster_dog (1 0 0) (-32 -32 -24) (32 32 40) Ambush + +*/ +void() monster_dog = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/h_dog.mdl"); + precache_model ("progs/dog.mdl"); + + precache_sound ("dog/dattack1.wav"); + precache_sound ("dog/ddeath.wav"); + precache_sound ("dog/dpain1.wav"); + precache_sound ("dog/dsight.wav"); + precache_sound ("dog/idle.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/dog.mdl"); + + setsize (self, '-32 -32 -24', '32 32 40'); + self.health = 25; + + self.th_stand = dog_stand1; + self.th_walk = dog_walk1; + self.th_run = dog_run1; + self.th_pain = dog_pain; + self.th_die = dog_die; + self.th_melee = dog_atta1; + self.th_missile = dog_leap1; + + walkmonster_start(); +}; + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/enforcer.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/enforcer.qc new file mode 100755 index 00000000..4f93900d --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/enforcer.qc @@ -0,0 +1,282 @@ +/* +============================================================================== + +SOLDIER / PLAYER + +============================================================================== +*/ + +$cd id1/models/enforcer +$origin 0 -6 24 +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 +$frame walk11 walk12 walk13 walk14 walk15 walk16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame attack1 attack2 attack3 attack4 attack5 attack6 +$frame attack7 attack8 attack9 attack10 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 death11 death12 death13 death14 + +$frame fdeath1 fdeath2 fdeath3 fdeath4 fdeath5 fdeath6 fdeath7 fdeath8 +$frame fdeath9 fdeath10 fdeath11 + +$frame paina1 paina2 paina3 paina4 + +$frame painb1 painb2 painb3 painb4 painb5 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 +$frame paind9 paind10 paind11 paind12 paind13 paind14 paind15 paind16 +$frame paind17 paind18 paind19 + +void() enforcer_fire = +{ + local vector org, vec; + + muzzleflash(); + makevectors (self.angles); + + org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16'; + vec = normalize(self.enemy.origin - self.origin) * 600; + + sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM); + PRJ_FireProjectile(self, "progs/laser.mdl", org, vec, PE_LASER, 15, MOD_ENFORCER, 5); + newmis.effects |= EF_DIMLIGHT; + newmis.alpha = 0.5; +}; + +//============================================================================ + +void() enf_stand1 =[ $stand1, enf_stand2 ] {ai_stand();}; +void() enf_stand2 =[ $stand2, enf_stand3 ] {ai_stand();}; +void() enf_stand3 =[ $stand3, enf_stand4 ] {ai_stand();}; +void() enf_stand4 =[ $stand4, enf_stand5 ] {ai_stand();}; +void() enf_stand5 =[ $stand5, enf_stand6 ] {ai_stand();}; +void() enf_stand6 =[ $stand6, enf_stand7 ] {ai_stand();}; +void() enf_stand7 =[ $stand7, enf_stand1 ] {ai_stand();}; + +void() enf_walk1 =[ $walk1 , enf_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); +ai_walk(2);}; +void() enf_walk2 =[ $walk2 , enf_walk3 ] {ai_walk(4);}; +void() enf_walk3 =[ $walk3 , enf_walk4 ] {ai_walk(4);}; +void() enf_walk4 =[ $walk4 , enf_walk5 ] {ai_walk(3);}; +void() enf_walk5 =[ $walk5 , enf_walk6 ] {ai_walk(1);}; +void() enf_walk6 =[ $walk6 , enf_walk7 ] {ai_walk(2);}; +void() enf_walk7 =[ $walk7 , enf_walk8 ] {ai_walk(2);}; +void() enf_walk8 =[ $walk8 , enf_walk9 ] {ai_walk(1);}; +void() enf_walk9 =[ $walk9 , enf_walk10 ] {ai_walk(2);}; +void() enf_walk10 =[ $walk10, enf_walk11 ] {ai_walk(4);}; +void() enf_walk11 =[ $walk11, enf_walk12 ] {ai_walk(4);}; +void() enf_walk12 =[ $walk12, enf_walk13 ] {ai_walk(1);}; +void() enf_walk13 =[ $walk13, enf_walk14 ] {ai_walk(2);}; +void() enf_walk14 =[ $walk14, enf_walk15 ] {ai_walk(3);}; +void() enf_walk15 =[ $walk15, enf_walk16 ] {ai_walk(4);}; +void() enf_walk16 =[ $walk16, enf_walk1 ] {ai_walk(2);}; + +void() enf_run1 =[ $run1 , enf_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); +ai_run(18);}; +void() enf_run2 =[ $run2 , enf_run3 ] {ai_run(14);}; +void() enf_run3 =[ $run3 , enf_run4 ] {ai_run(7);}; +void() enf_run4 =[ $run4 , enf_run5 ] {ai_run(12);}; +void() enf_run5 =[ $run5 , enf_run6 ] {ai_run(14);}; +void() enf_run6 =[ $run6 , enf_run7 ] {ai_run(14);}; +void() enf_run7 =[ $run7 , enf_run8 ] {ai_run(7);}; +void() enf_run8 =[ $run8 , enf_run1 ] {ai_run(11);}; + +void() enf_atk1 =[ $attack1, enf_atk2 ] {ai_face();}; +void() enf_atk2 =[ $attack2, enf_atk3 ] {ai_face();}; +void() enf_atk3 =[ $attack3, enf_atk4 ] {ai_face();}; +void() enf_atk4 =[ $attack4, enf_atk5 ] {ai_face();}; +void() enf_atk5 =[ $attack5, enf_atk6 ] {ai_face();}; +void() enf_atk6 =[ $attack6, enf_atk7 ] {enforcer_fire();}; +void() enf_atk7 =[ $attack7, enf_atk8 ] {ai_face();}; +void() enf_atk8 =[ $attack8, enf_atk9 ] {ai_face();}; +void() enf_atk9 =[ $attack5, enf_atk10 ] {ai_face();}; +void() enf_atk10 =[ $attack6, enf_atk11 ] {enforcer_fire();}; +void() enf_atk11 =[ $attack7, enf_atk12 ] {ai_face();}; +void() enf_atk12 =[ $attack8, enf_atk13 ] {ai_face();}; +void() enf_atk13 =[ $attack9, enf_atk14 ] {ai_face();}; +void() enf_atk14 =[ $attack10, enf_run1 ] {ai_face(); +SUB_CheckRefire (enf_atk1); +}; + +void() enf_paina1 =[ $paina1, enf_paina2 ] {}; +void() enf_paina2 =[ $paina2, enf_paina3 ] {}; +void() enf_paina3 =[ $paina3, enf_paina4 ] {}; +void() enf_paina4 =[ $paina4, enf_run1 ] {}; + +void() enf_painb1 =[ $painb1, enf_painb2 ] {}; +void() enf_painb2 =[ $painb2, enf_painb3 ] {}; +void() enf_painb3 =[ $painb3, enf_painb4 ] {}; +void() enf_painb4 =[ $painb4, enf_painb5 ] {}; +void() enf_painb5 =[ $painb5, enf_run1 ] {}; + +void() enf_painc1 =[ $painc1, enf_painc2 ] {}; +void() enf_painc2 =[ $painc2, enf_painc3 ] {}; +void() enf_painc3 =[ $painc3, enf_painc4 ] {}; +void() enf_painc4 =[ $painc4, enf_painc5 ] {}; +void() enf_painc5 =[ $painc5, enf_painc6 ] {}; +void() enf_painc6 =[ $painc6, enf_painc7 ] {}; +void() enf_painc7 =[ $painc7, enf_painc8 ] {}; +void() enf_painc8 =[ $painc8, enf_run1 ] {}; + +void() enf_paind1 =[ $paind1, enf_paind2 ] {}; +void() enf_paind2 =[ $paind2, enf_paind3 ] {}; +void() enf_paind3 =[ $paind3, enf_paind4 ] {}; +void() enf_paind4 =[ $paind4, enf_paind5 ] {ai_painforward(2);}; +void() enf_paind5 =[ $paind5, enf_paind6 ] {ai_painforward(1);}; +void() enf_paind6 =[ $paind6, enf_paind7 ] {}; +void() enf_paind7 =[ $paind7, enf_paind8 ] {}; +void() enf_paind8 =[ $paind8, enf_paind9 ] {}; +void() enf_paind9 =[ $paind9, enf_paind10 ] {}; +void() enf_paind10 =[ $paind10, enf_paind11 ] {}; +void() enf_paind11 =[ $paind11, enf_paind12 ] {ai_painforward(1);}; +void() enf_paind12 =[ $paind12, enf_paind13 ] {ai_painforward(1);}; +void() enf_paind13 =[ $paind13, enf_paind14 ] {ai_painforward(1);}; +void() enf_paind14 =[ $paind14, enf_paind15 ] {}; +void() enf_paind15 =[ $paind15, enf_paind16 ] {}; +void() enf_paind16 =[ $paind16, enf_paind17 ] {ai_pain(1);}; +void() enf_paind17 =[ $paind17, enf_paind18 ] {ai_pain(1);}; +void() enf_paind18 =[ $paind18, enf_paind19 ] {}; +void() enf_paind19 =[ $paind19, enf_run1 ] {}; + +void(entity attacker, float damage) enf_pain = +{ + local float r; + + if (self.pain_finished > time) + return; + + r = random (); + if (r < 0.5) + sound (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM); + else + sound (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM); + + self.pain_finished = time + 1; + if (r < 0.2) + enf_paina1 (); + else if (r < 0.4) + enf_painb1 (); + else if (r < 0.7) + enf_painc1 (); + else + enf_paind1 (); +}; + +//============================================================================ + + + + +void() enf_die1 =[ $death1, enf_die2 ] {}; +void() enf_die2 =[ $death2, enf_die3 ] {}; +void() enf_die3 =[ $death3, enf_die4 ] +{self.solid = SOLID_NOT;DropBackpack();}; +void() enf_die4 =[ $death4, enf_die5 ] {ai_forward(14);}; +void() enf_die5 =[ $death5, enf_die6 ] {ai_forward(2);}; +void() enf_die6 =[ $death6, enf_die7 ] {}; +void() enf_die7 =[ $death7, enf_die8 ] {}; +void() enf_die8 =[ $death8, enf_die9 ] {}; +void() enf_die9 =[ $death9, enf_die10 ] {ai_forward(3);}; +void() enf_die10 =[ $death10, enf_die11 ] {ai_forward(5);}; +void() enf_die11 =[ $death11, enf_die12 ] {ai_forward(5);}; +void() enf_die12 =[ $death12, enf_die13 ] {ai_forward(5);}; +void() enf_die13 =[ $death13, enf_die14 ] {}; +void() enf_die14 =[ $death14, enf_die14 ] {}; + +void() enf_fdie1 =[ $fdeath1, enf_fdie2 ] { + +}; +void() enf_fdie2 =[ $fdeath2, enf_fdie3 ] {}; +void() enf_fdie3 =[ $fdeath3, enf_fdie4 ] +{self.solid = SOLID_NOT;DropBackpack();}; +void() enf_fdie4 =[ $fdeath4, enf_fdie5 ] {}; +void() enf_fdie5 =[ $fdeath5, enf_fdie6 ] {}; +void() enf_fdie6 =[ $fdeath6, enf_fdie7 ] {}; +void() enf_fdie7 =[ $fdeath7, enf_fdie8 ] {}; +void() enf_fdie8 =[ $fdeath8, enf_fdie9 ] {}; +void() enf_fdie9 =[ $fdeath9, enf_fdie10 ] {}; +void() enf_fdie10 =[ $fdeath10, enf_fdie11 ] {}; +void() enf_fdie11 =[ $fdeath11, enf_fdie11 ] {}; + + +void() enf_die = +{ +// check for gib + if (self.health < -35) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_mega.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM); + if (random() > 0.5) + enf_die1 (); + else + enf_fdie1 (); +}; + + +/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) Ambush + +*/ +void() monster_enforcer = +{ + if (deathmatch) + { + remove(self); + return; + } + + precache_model2 ("progs/enforcer.mdl"); + precache_model2 ("progs/h_mega.mdl"); + precache_model2 ("progs/laser.mdl"); + + precache_sound2 ("enforcer/death1.wav"); + precache_sound2 ("enforcer/enfire.wav"); + precache_sound2 ("enforcer/enfstop.wav"); + precache_sound2 ("enforcer/idle1.wav"); + precache_sound2 ("enforcer/pain1.wav"); + precache_sound2 ("enforcer/pain2.wav"); + precache_sound2 ("enforcer/sight1.wav"); + precache_sound2 ("enforcer/sight2.wav"); + precache_sound2 ("enforcer/sight3.wav"); + precache_sound2 ("enforcer/sight4.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/enforcer.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 80; + + self.th_stand = enf_stand1; + self.th_walk = enf_walk1; + self.th_run = enf_run1; + self.th_pain = enf_pain; + self.th_die = enf_die; + self.th_missile = enf_atk1; + + self.ammo_cells_real = 5; // drop 5 cells on death + + walkmonster_start(); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/fish.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/fish.qc new file mode 100755 index 00000000..22d2bc51 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/fish.qc @@ -0,0 +1,186 @@ +$cd id1/models/fish +$origin 0 0 24 +$base base +$skin skin + +$frame attack1 attack2 attack3 attack4 attack5 attack6 +$frame attack7 attack8 attack9 attack10 attack11 attack12 attack13 +$frame attack14 attack15 attack16 attack17 attack18 + +$frame death1 death2 death3 death4 death5 death6 death7 +$frame death8 death9 death10 death11 death12 death13 death14 death15 +$frame death16 death17 death18 death19 death20 death21 + +$frame swim1 swim2 swim3 swim4 swim5 swim6 swim7 swim8 +$frame swim9 swim10 swim11 swim12 swim13 swim14 swim15 swim16 swim17 +$frame swim18 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8 +$frame pain9 + +void() swimmonster_start; + +void() f_stand1 =[ $swim1, f_stand2 ] {ai_stand();}; +void() f_stand2 =[ $swim2, f_stand3 ] {ai_stand();}; +void() f_stand3 =[ $swim3, f_stand4 ] {ai_stand();}; +void() f_stand4 =[ $swim4, f_stand5 ] {ai_stand();}; +void() f_stand5 =[ $swim5, f_stand6 ] {ai_stand();}; +void() f_stand6 =[ $swim6, f_stand7 ] {ai_stand();}; +void() f_stand7 =[ $swim7, f_stand8 ] {ai_stand();}; +void() f_stand8 =[ $swim8, f_stand9 ] {ai_stand();}; +void() f_stand9 =[ $swim9, f_stand10 ] {ai_stand();}; +void() f_stand10 =[ $swim10, f_stand11 ] {ai_stand();}; +void() f_stand11 =[ $swim11, f_stand12 ] {ai_stand();}; +void() f_stand12 =[ $swim12, f_stand13 ] {ai_stand();}; +void() f_stand13 =[ $swim13, f_stand14 ] {ai_stand();}; +void() f_stand14 =[ $swim14, f_stand15 ] {ai_stand();}; +void() f_stand15 =[ $swim15, f_stand16 ] {ai_stand();}; +void() f_stand16 =[ $swim16, f_stand17 ] {ai_stand();}; +void() f_stand17 =[ $swim17, f_stand18 ] {ai_stand();}; +void() f_stand18 =[ $swim18, f_stand1 ] {ai_stand();}; + +void() f_walk1 =[ $swim1, f_walk2 ] {ai_walk(8);}; +void() f_walk2 =[ $swim2, f_walk3 ] {ai_walk(8);}; +void() f_walk3 =[ $swim3, f_walk4 ] {ai_walk(8);}; +void() f_walk4 =[ $swim4, f_walk5 ] {ai_walk(8);}; +void() f_walk5 =[ $swim5, f_walk6 ] {ai_walk(8);}; +void() f_walk6 =[ $swim6, f_walk7 ] {ai_walk(8);}; +void() f_walk7 =[ $swim7, f_walk8 ] {ai_walk(8);}; +void() f_walk8 =[ $swim8, f_walk9 ] {ai_walk(8);}; +void() f_walk9 =[ $swim9, f_walk10 ] {ai_walk(8);}; +void() f_walk10 =[ $swim10, f_walk11 ] {ai_walk(8);}; +void() f_walk11 =[ $swim11, f_walk12 ] {ai_walk(8);}; +void() f_walk12 =[ $swim12, f_walk13 ] {ai_walk(8);}; +void() f_walk13 =[ $swim13, f_walk14 ] {ai_walk(8);}; +void() f_walk14 =[ $swim14, f_walk15 ] {ai_walk(8);}; +void() f_walk15 =[ $swim15, f_walk16 ] {ai_walk(8);}; +void() f_walk16 =[ $swim16, f_walk17 ] {ai_walk(8);}; +void() f_walk17 =[ $swim17, f_walk18 ] {ai_walk(8);}; +void() f_walk18 =[ $swim18, f_walk1 ] {ai_walk(8);}; + +void() f_run1 =[ $swim1, f_run2 ] {ai_run(12); + if (random() < 0.5) + sound (self, CHAN_VOICE, "fish/idle.wav", 1, ATTN_NORM); +}; +void() f_run2 =[ $swim3, f_run3 ] {ai_run(12);}; +void() f_run3 =[ $swim5, f_run4 ] {ai_run(12);}; +void() f_run4 =[ $swim7, f_run5 ] {ai_run(12);}; +void() f_run5 =[ $swim9, f_run6 ] {ai_run(12);}; +void() f_run6 =[ $swim11, f_run7 ] {ai_run(12);}; +void() f_run7 =[ $swim13, f_run8 ] {ai_run(12);}; +void() f_run8 =[ $swim15, f_run9 ] {ai_run(12);}; +void() f_run9 =[ $swim17, f_run1 ] {ai_run(12);}; + +void() fish_melee = +{ + local vector delta; + local float ldmg; + + if (!self.enemy) + return; // removed before stroke + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 60) + return; + + sound (self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM); + ldmg = (random() + random()) * 3; + T_Damage (self.enemy, self, self, ldmg, MOD_FISH); +}; + +void() f_attack1 =[ $attack1, f_attack2 ] {ai_charge(10);}; +void() f_attack2 =[ $attack2, f_attack3 ] {ai_charge(10);}; +void() f_attack3 =[ $attack3, f_attack4 ] {fish_melee();}; +void() f_attack4 =[ $attack4, f_attack5 ] {ai_charge(10);}; +void() f_attack5 =[ $attack5, f_attack6 ] {ai_charge(10);}; +void() f_attack6 =[ $attack6, f_attack7 ] {ai_charge(10);}; +void() f_attack7 =[ $attack7, f_attack8 ] {ai_charge(10);}; +void() f_attack8 =[ $attack8, f_attack9 ] {ai_charge(10);}; +void() f_attack9 =[ $attack9, f_attack10] {fish_melee();}; +void() f_attack10 =[ $attack10, f_attack11] {ai_charge(10);}; +void() f_attack11 =[ $attack11, f_attack12] {ai_charge(10);}; +void() f_attack12 =[ $attack12, f_attack13] {ai_charge(10);}; +void() f_attack13 =[ $attack13, f_attack14] {ai_charge(10);}; +void() f_attack14 =[ $attack14, f_attack15] {ai_charge(10);}; +void() f_attack15 =[ $attack15, f_attack16] {fish_melee();}; +void() f_attack16 =[ $attack16, f_attack17] {ai_charge(10);}; +void() f_attack17 =[ $attack17, f_attack18] {ai_charge(10);}; +void() f_attack18 =[ $attack18, f_run1 ] {ai_charge(10);}; + +void() f_death1 =[ $death1, f_death2 ] { +sound (self, CHAN_VOICE, "fish/death.wav", 1, ATTN_NORM); +}; +void() f_death2 =[ $death2, f_death3 ] {}; +void() f_death3 =[ $death3, f_death4 ] {self.solid = SOLID_NOT;}; +void() f_death4 =[ $death4, f_death5 ] {}; +void() f_death5 =[ $death5, f_death6 ] {}; +void() f_death6 =[ $death6, f_death7 ] {}; +void() f_death7 =[ $death7, f_death8 ] {}; +void() f_death8 =[ $death8, f_death9 ] {}; +void() f_death9 =[ $death9, f_death10 ] {}; +void() f_death10 =[ $death10, f_death11 ] {}; +void() f_death11 =[ $death11, f_death12 ] {}; +void() f_death12 =[ $death12, f_death13 ] {}; +void() f_death13 =[ $death13, f_death14 ] {}; +void() f_death14 =[ $death14, f_death15 ] {}; +void() f_death15 =[ $death15, f_death16 ] {}; +void() f_death16 =[ $death16, f_death17 ] {}; +void() f_death17 =[ $death17, f_death18 ] {}; +void() f_death18 =[ $death18, f_death19 ] {}; +void() f_death19 =[ $death19, f_death20 ] {}; +void() f_death20 =[ $death20, f_death21 ] {}; +void() f_death21 =[ $death21, f_death21 ] {}; + +void() f_pain1 =[ $pain1, f_pain2 ] {}; +void() f_pain2 =[ $pain2, f_pain3 ] {ai_pain(6);}; +void() f_pain3 =[ $pain3, f_pain4 ] {ai_pain(6);}; +void() f_pain4 =[ $pain4, f_pain5 ] {ai_pain(6);}; +void() f_pain5 =[ $pain5, f_pain6 ] {ai_pain(6);}; +void() f_pain6 =[ $pain6, f_pain7 ] {ai_pain(6);}; +void() f_pain7 =[ $pain7, f_pain8 ] {ai_pain(6);}; +void() f_pain8 =[ $pain8, f_pain9 ] {ai_pain(6);}; +void() f_pain9 =[ $pain9, f_run1 ] {ai_pain(6);}; + +void(entity attacker, float damage) fish_pain = +{ + +// fish allways do pain frames + f_pain1 (); +}; + + + +/*QUAKED monster_fish (1 0 0) (-16 -16 -24) (16 16 24) Ambush +*/ +void() monster_fish = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/fish.mdl"); + + precache_sound2 ("fish/death.wav"); + precache_sound2 ("fish/bite.wav"); + precache_sound2 ("fish/idle.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/fish.mdl"); + + setsize (self, '-16 -16 -24', '16 16 24'); + self.health = 25; + + self.th_stand = f_stand1; + self.th_walk = f_walk1; + self.th_run = f_run1; + self.th_die = f_death1; + self.th_pain = fish_pain; + self.th_melee = f_attack1; + + swimmonster_start (); +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/hknight.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/hknight.qc new file mode 100755 index 00000000..84ae0295 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/hknight.qc @@ -0,0 +1,442 @@ +/* +============================================================================== + +KNIGHT + +============================================================================== +*/ + +$cd id1/models/knight2 +$origin 0 0 24 +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 +$frame walk10 walk11 walk12 walk13 walk14 walk15 walk16 walk17 +$frame walk18 walk19 walk20 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 death11 death12 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 + +$frame char_a1 char_a2 char_a3 char_a4 char_a5 char_a6 char_a7 char_a8 +$frame char_a9 char_a10 char_a11 char_a12 char_a13 char_a14 char_a15 char_a16 + +$frame magica1 magica2 magica3 magica4 magica5 magica6 magica7 magica8 +$frame magica9 magica10 magica11 magica12 magica13 magica14 + +$frame magicb1 magicb2 magicb3 magicb4 magicb5 magicb6 magicb7 magicb8 +$frame magicb9 magicb10 magicb11 magicb12 magicb13 + +$frame char_b1 char_b2 char_b3 char_b4 char_b5 char_b6 + +$frame slice1 slice2 slice3 slice4 slice5 slice6 slice7 slice8 slice9 slice10 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 smash8 smash9 smash10 +$frame smash11 + +$frame w_attack1 w_attack2 w_attack3 w_attack4 w_attack5 w_attack6 w_attack7 +$frame w_attack8 w_attack9 w_attack10 w_attack11 w_attack12 w_attack13 w_attack14 +$frame w_attack15 w_attack16 w_attack17 w_attack18 w_attack19 w_attack20 +$frame w_attack21 w_attack22 + +$frame magicc1 magicc2 magicc3 magicc4 magicc5 magicc6 magicc7 magicc8 +$frame magicc9 magicc10 magicc11 + + +void() hknight_char_a1; +void() hknight_run1; +void() hk_idle_sound; + +void(float offset) hknight_shot = +{ + local vector offang; + local vector org, vec; + + offang = vectoangles (self.enemy.origin - self.origin); + offang_y = offang_y + offset * 6; + + makevectors (offang); + + org = self.origin + self.mins + self.size*0.5 + v_forward * 20; + +// set missile speed + vec = normalize (v_forward); + vec_z = 0 - vec_z + (random() - 0.5)*0.1; + + sound (self, CHAN_WEAPON, "hknight/attack1.wav", 1, ATTN_NORM); + PRJ_FireProjectile(self, "progs/k_spike.mdl", org, vec * 300, PE_KNIGHTSPIKE, 9, MOD_HKNIGHT, 6); +}; + +void() CheckForCharge = +{ + // check for mad charge + if (!visible(self.enemy)) + return; + if (time < self.attack_finished) + return; + if ( fabs(self.origin_z - self.enemy.origin_z) > 20) + return; // too much height change + if ( vlen (self.origin - self.enemy.origin) < 80) + return; // use regular attack + + // charge + SUB_AttackFinished (2); + hknight_char_a1 (); +}; + +void() CheckContinueCharge = +{ + if (time > self.attack_finished) + { + SUB_AttackFinished (3); + hknight_run1 (); + return; // done charging + } + if (random() > 0.5) + sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM); + else + sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +}; + +//=========================================================================== + +void() hknight_stand1 =[ $stand1, hknight_stand2 ] {ai_stand();}; +void() hknight_stand2 =[ $stand2, hknight_stand3 ] {ai_stand();}; +void() hknight_stand3 =[ $stand3, hknight_stand4 ] {ai_stand();}; +void() hknight_stand4 =[ $stand4, hknight_stand5 ] {ai_stand();}; +void() hknight_stand5 =[ $stand5, hknight_stand6 ] {ai_stand();}; +void() hknight_stand6 =[ $stand6, hknight_stand7 ] {ai_stand();}; +void() hknight_stand7 =[ $stand7, hknight_stand8 ] {ai_stand();}; +void() hknight_stand8 =[ $stand8, hknight_stand9 ] {ai_stand();}; +void() hknight_stand9 =[ $stand9, hknight_stand1 ] {ai_stand();}; + +//=========================================================================== + +void() hknight_walk1 =[ $walk1, hknight_walk2 ] { +hk_idle_sound(); +ai_walk(2);}; +void() hknight_walk2 =[ $walk2, hknight_walk3 ] {ai_walk(5);}; +void() hknight_walk3 =[ $walk3, hknight_walk4 ] {ai_walk(5);}; +void() hknight_walk4 =[ $walk4, hknight_walk5 ] {ai_walk(4);}; +void() hknight_walk5 =[ $walk5, hknight_walk6 ] {ai_walk(4);}; +void() hknight_walk6 =[ $walk6, hknight_walk7 ] {ai_walk(2);}; +void() hknight_walk7 =[ $walk7, hknight_walk8 ] {ai_walk(2);}; +void() hknight_walk8 =[ $walk8, hknight_walk9 ] {ai_walk(3);}; +void() hknight_walk9 =[ $walk9, hknight_walk10 ] {ai_walk(3);}; +void() hknight_walk10 =[ $walk10, hknight_walk11 ] {ai_walk(4);}; +void() hknight_walk11 =[ $walk11, hknight_walk12 ] {ai_walk(3);}; +void() hknight_walk12 =[ $walk12, hknight_walk13 ] {ai_walk(4);}; +void() hknight_walk13 =[ $walk13, hknight_walk14 ] {ai_walk(6);}; +void() hknight_walk14 =[ $walk14, hknight_walk15 ] {ai_walk(2);}; +void() hknight_walk15 =[ $walk15, hknight_walk16 ] {ai_walk(2);}; +void() hknight_walk16 =[ $walk16, hknight_walk17 ] {ai_walk(4);}; +void() hknight_walk17 =[ $walk17, hknight_walk18 ] {ai_walk(3);}; +void() hknight_walk18 =[ $walk18, hknight_walk19 ] {ai_walk(3);}; +void() hknight_walk19 =[ $walk19, hknight_walk20 ] {ai_walk(3);}; +void() hknight_walk20 =[ $walk20, hknight_walk1 ] {ai_walk(2);}; + +//=========================================================================== + +void() hknight_run1 =[ $run1, hknight_run2 ] { +hk_idle_sound(); +ai_run (20); CheckForCharge (); }; +void() hknight_run2 =[ $run2, hknight_run3 ] {ai_run(25);}; +void() hknight_run3 =[ $run3, hknight_run4 ] {ai_run(18);}; +void() hknight_run4 =[ $run4, hknight_run5 ] {ai_run(16);}; +void() hknight_run5 =[ $run5, hknight_run6 ] {ai_run(14);}; +void() hknight_run6 =[ $run6, hknight_run7 ] {ai_run(25);}; +void() hknight_run7 =[ $run7, hknight_run8 ] {ai_run(21);}; +void() hknight_run8 =[ $run8, hknight_run1 ] {ai_run(13);}; + +//============================================================================ + +void() hknight_pain1 =[ $pain1, hknight_pain2 ] {sound (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);}; +void() hknight_pain2 =[ $pain2, hknight_pain3 ] {}; +void() hknight_pain3 =[ $pain3, hknight_pain4 ] {}; +void() hknight_pain4 =[ $pain4, hknight_pain5 ] {}; +void() hknight_pain5 =[ $pain5, hknight_run1 ] {}; + +//============================================================================ + +void() hknight_die1 =[ $death1, hknight_die2 ] {ai_forward(10);}; +void() hknight_die2 =[ $death2, hknight_die3 ] {ai_forward(8);}; +void() hknight_die3 =[ $death3, hknight_die4 ] +{self.solid = SOLID_NOT; ai_forward(7);}; +void() hknight_die4 =[ $death4, hknight_die5 ] {}; +void() hknight_die5 =[ $death5, hknight_die6 ] {}; +void() hknight_die6 =[ $death6, hknight_die7 ] {}; +void() hknight_die7 =[ $death7, hknight_die8 ] {}; +void() hknight_die8 =[ $death8, hknight_die9 ] {ai_forward(10);}; +void() hknight_die9 =[ $death9, hknight_die10 ] {ai_forward(11);}; +void() hknight_die10 =[ $death10, hknight_die11 ] {}; +void() hknight_die11 =[ $death11, hknight_die12 ] {}; +void() hknight_die12 =[ $death12, hknight_die12 ] {}; + +void() hknight_dieb1 =[ $deathb1, hknight_dieb2 ] {}; +void() hknight_dieb2 =[ $deathb2, hknight_dieb3 ] {}; +void() hknight_dieb3 =[ $deathb3, hknight_dieb4 ] +{self.solid = SOLID_NOT;}; +void() hknight_dieb4 =[ $deathb4, hknight_dieb5 ] {}; +void() hknight_dieb5 =[ $deathb5, hknight_dieb6 ] {}; +void() hknight_dieb6 =[ $deathb6, hknight_dieb7 ] {}; +void() hknight_dieb7 =[ $deathb7, hknight_dieb8 ] {}; +void() hknight_dieb8 =[ $deathb8, hknight_dieb9 ] {}; +void() hknight_dieb9 =[ $deathb9, hknight_dieb9 ] {}; + +void() hknight_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_hellkn.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "hknight/death1.wav", 1, ATTN_NORM); + if (random() > 0.5) + hknight_die1 (); + else + hknight_dieb1 (); +}; + + +//============================================================================ +#ifdef 0 +// Not used +void() hknight_magica1 =[ $magica1, hknight_magica2 ] {ai_face();}; +void() hknight_magica2 =[ $magica2, hknight_magica3 ] {ai_face();}; +void() hknight_magica3 =[ $magica3, hknight_magica4 ] {ai_face();}; +void() hknight_magica4 =[ $magica4, hknight_magica5 ] {ai_face();}; +void() hknight_magica5 =[ $magica5, hknight_magica6 ] {ai_face();}; +void() hknight_magica6 =[ $magica6, hknight_magica7 ] {ai_face();}; +void() hknight_magica7 =[ $magica7, hknight_magica8 ] {hknight_shot(-2);}; +void() hknight_magica8 =[ $magica8, hknight_magica9 ] {hknight_shot(-1);}; +void() hknight_magica9 =[ $magica9, hknight_magica10] {hknight_shot(0);}; +void() hknight_magica10 =[ $magica10, hknight_magica11] {hknight_shot(1);}; +void() hknight_magica11 =[ $magica11, hknight_magica12] {hknight_shot(2);}; +void() hknight_magica12 =[ $magica12, hknight_magica13] {hknight_shot(3);}; +void() hknight_magica13 =[ $magica13, hknight_magica14] {ai_face();}; +void() hknight_magica14 =[ $magica14, hknight_run1 ] {ai_face();}; + +//============================================================================ + +void() hknight_magicb1 =[ $magicb1, hknight_magicb2 ] {ai_face();}; +void() hknight_magicb2 =[ $magicb2, hknight_magicb3 ] {ai_face();}; +void() hknight_magicb3 =[ $magicb3, hknight_magicb4 ] {ai_face();}; +void() hknight_magicb4 =[ $magicb4, hknight_magicb5 ] {ai_face();}; +void() hknight_magicb5 =[ $magicb5, hknight_magicb6 ] {ai_face();}; +void() hknight_magicb6 =[ $magicb6, hknight_magicb7 ] {ai_face();}; +void() hknight_magicb7 =[ $magicb7, hknight_magicb8 ] {hknight_shot(-2);}; +void() hknight_magicb8 =[ $magicb8, hknight_magicb9 ] {hknight_shot(-1);}; +void() hknight_magicb9 =[ $magicb9, hknight_magicb10] {hknight_shot(0);}; +void() hknight_magicb10 =[ $magicb10, hknight_magicb11] {hknight_shot(1);}; +void() hknight_magicb11 =[ $magicb11, hknight_magicb12] {hknight_shot(2);}; +void() hknight_magicb12 =[ $magicb12, hknight_magicb13] {hknight_shot(3);}; +void() hknight_magicb13 =[ $magicb13, hknight_run1] {ai_face();}; +#endif + +//============================================================================ + +void() hknight_magicc1 =[ $magicc1, hknight_magicc2 ] {ai_face();}; +void() hknight_magicc2 =[ $magicc2, hknight_magicc3 ] {ai_face();}; +void() hknight_magicc3 =[ $magicc3, hknight_magicc4 ] {ai_face();}; +void() hknight_magicc4 =[ $magicc4, hknight_magicc5 ] {ai_face();}; +void() hknight_magicc5 =[ $magicc5, hknight_magicc6 ] {ai_face();}; +void() hknight_magicc6 =[ $magicc6, hknight_magicc7 ] {hknight_shot(-2);}; +void() hknight_magicc7 =[ $magicc7, hknight_magicc8 ] {hknight_shot(-1);}; +void() hknight_magicc8 =[ $magicc8, hknight_magicc9 ] {hknight_shot(0);}; +void() hknight_magicc9 =[ $magicc9, hknight_magicc10] {hknight_shot(1);}; +void() hknight_magicc10 =[ $magicc10, hknight_magicc11] {hknight_shot(2);}; +void() hknight_magicc11 =[ $magicc11, hknight_run1] {hknight_shot(3);}; + +//=========================================================================== + +void() hknight_char_a1 =[ $char_a1, hknight_char_a2 ] {ai_charge(20);}; +void() hknight_char_a2 =[ $char_a2, hknight_char_a3 ] {ai_charge(25);}; +void() hknight_char_a3 =[ $char_a3, hknight_char_a4 ] {ai_charge(18);}; +void() hknight_char_a4 =[ $char_a4, hknight_char_a5 ] {ai_charge(16);}; +void() hknight_char_a5 =[ $char_a5, hknight_char_a6 ] {ai_charge(14);}; +void() hknight_char_a6 =[ $char_a6, hknight_char_a7 ] {ai_charge(20); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_a7 =[ $char_a7, hknight_char_a8 ] {ai_charge(21); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_a8 =[ $char_a8, hknight_char_a9 ] {ai_charge(13); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_a9 =[ $char_a9, hknight_char_a10 ] {ai_charge(20); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_a10=[ $char_a10, hknight_char_a11 ] {ai_charge(20); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_a11=[ $char_a11, hknight_char_a12 ] {ai_charge(18); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_a12=[ $char_a12, hknight_char_a13 ] {ai_charge(16);}; +void() hknight_char_a13=[ $char_a13, hknight_char_a14 ] {ai_charge(14);}; +void() hknight_char_a14=[ $char_a14, hknight_char_a15 ] {ai_charge(25);}; +void() hknight_char_a15=[ $char_a15, hknight_char_a16 ] {ai_charge(21);}; +void() hknight_char_a16=[ $char_a16, hknight_run1 ] {ai_charge(13);}; + +//=========================================================================== + +#ifdef 0 +// Not used +void() hknight_char_b1 =[ $char_b1, hknight_char_b2 ] +{CheckContinueCharge (); ai_charge(23); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_b2 =[ $char_b2, hknight_char_b3 ] {ai_charge(17); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_b3 =[ $char_b3, hknight_char_b4 ] {ai_charge(12); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_b4 =[ $char_b4, hknight_char_b5 ] {ai_charge(22); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_b5 =[ $char_b5, hknight_char_b6 ] {ai_charge(18); ai_melee(MOD_HKNIGHT);}; +void() hknight_char_b6 =[ $char_b6, hknight_char_b1 ] {ai_charge(8); ai_melee(MOD_HKNIGHT);}; +#endif + +//=========================================================================== + +void() hknight_slice1 =[ $slice1, hknight_slice2 ] {ai_charge(9);}; +void() hknight_slice2 =[ $slice2, hknight_slice3 ] {ai_charge(6);}; +void() hknight_slice3 =[ $slice3, hknight_slice4 ] {ai_charge(13);}; +void() hknight_slice4 =[ $slice4, hknight_slice5 ] {ai_charge(4);}; +void() hknight_slice5 =[ $slice5, hknight_slice6 ] {ai_charge(7); ai_melee(MOD_HKNIGHT);}; +void() hknight_slice6 =[ $slice6, hknight_slice7 ] {ai_charge(15); ai_melee(MOD_HKNIGHT);}; +void() hknight_slice7 =[ $slice7, hknight_slice8 ] {ai_charge(8); ai_melee(MOD_HKNIGHT);}; +void() hknight_slice8 =[ $slice8, hknight_slice9 ] {ai_charge(2); ai_melee(MOD_HKNIGHT);}; +void() hknight_slice9 =[ $slice9, hknight_slice10 ] {ai_melee(MOD_HKNIGHT);}; +void() hknight_slice10 =[ $slice10, hknight_run1 ] {ai_charge(3);}; + +//=========================================================================== + +void() hknight_smash1 =[ $smash1, hknight_smash2 ] {ai_charge(1);}; +void() hknight_smash2 =[ $smash2, hknight_smash3 ] {ai_charge(13);}; +void() hknight_smash3 =[ $smash3, hknight_smash4 ] {ai_charge(9);}; +void() hknight_smash4 =[ $smash4, hknight_smash5 ] {ai_charge(11);}; +void() hknight_smash5 =[ $smash5, hknight_smash6 ] {ai_charge(10); ai_melee(MOD_HKNIGHT);}; +void() hknight_smash6 =[ $smash6, hknight_smash7 ] {ai_charge(7); ai_melee(MOD_HKNIGHT);}; +void() hknight_smash7 =[ $smash7, hknight_smash8 ] {ai_charge(12); ai_melee(MOD_HKNIGHT);}; +void() hknight_smash8 =[ $smash8, hknight_smash9 ] {ai_charge(2); ai_melee(MOD_HKNIGHT);}; +void() hknight_smash9 =[ $smash9, hknight_smash10 ] {ai_charge(3); ai_melee(MOD_HKNIGHT);}; +void() hknight_smash10 =[ $smash10, hknight_smash11 ] {ai_charge(0);}; +void() hknight_smash11 =[ $smash11, hknight_run1 ] {ai_charge(0);}; + +//============================================================================ + +void() hknight_watk1 =[ $w_attack1, hknight_watk2 ] {ai_charge(2);}; +void() hknight_watk2 =[ $w_attack2, hknight_watk3 ] {ai_charge(0);}; +void() hknight_watk3 =[ $w_attack3, hknight_watk4 ] {ai_charge(0);}; +void() hknight_watk4 =[ $w_attack4, hknight_watk5 ] {ai_melee(MOD_HKNIGHT);}; +void() hknight_watk5 =[ $w_attack5, hknight_watk6 ] {ai_melee(MOD_HKNIGHT);}; +void() hknight_watk6 =[ $w_attack6, hknight_watk7 ] {ai_melee(MOD_HKNIGHT);}; +void() hknight_watk7 =[ $w_attack7, hknight_watk8 ] {ai_charge(1);}; +void() hknight_watk8 =[ $w_attack8, hknight_watk9 ] {ai_charge(4);}; +void() hknight_watk9 =[ $w_attack9, hknight_watk10 ] {ai_charge(5);}; +void() hknight_watk10 =[ $w_attack10, hknight_watk11 ] {ai_charge(3); ai_melee(MOD_HKNIGHT);}; +void() hknight_watk11 =[ $w_attack11, hknight_watk12 ] {ai_charge(2); ai_melee(MOD_HKNIGHT);}; +void() hknight_watk12 =[ $w_attack12, hknight_watk13 ] {ai_charge(2); ai_melee(MOD_HKNIGHT);}; +void() hknight_watk13 =[ $w_attack13, hknight_watk14 ] {ai_charge(0);}; +void() hknight_watk14 =[ $w_attack14, hknight_watk15 ] {ai_charge(0);}; +void() hknight_watk15 =[ $w_attack15, hknight_watk16 ] {ai_charge(0);}; +void() hknight_watk16 =[ $w_attack16, hknight_watk17 ] {ai_charge(1);}; +void() hknight_watk17 =[ $w_attack17, hknight_watk18 ] {ai_charge(1); ai_melee(MOD_HKNIGHT);}; +void() hknight_watk18 =[ $w_attack18, hknight_watk19 ] {ai_charge(3); ai_melee(MOD_HKNIGHT);}; +void() hknight_watk19 =[ $w_attack19, hknight_watk20 ] {ai_charge(4); ai_melee(MOD_HKNIGHT);}; +void() hknight_watk20 =[ $w_attack20, hknight_watk21 ] {ai_charge(6);}; +void() hknight_watk21 =[ $w_attack21, hknight_watk22 ] {ai_charge(7);}; +void() hknight_watk22 =[ $w_attack22, hknight_run1 ] {ai_charge(3);}; + +//============================================================================ + +void() hk_idle_sound = +{ + if (random() < 0.2) + sound (self, CHAN_VOICE, "hknight/idle.wav", 1, ATTN_NORM); +}; + +void(entity attacker, float damage) hknight_pain = +{ + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM); + + if (time - self.pain_finished > 5) + { // allways go into pain frame if it has been a while + hknight_pain1 (); + self.pain_finished = time + 1; + return; + } + + if ((random()*30 > damage) ) + return; // didn't flinch + + self.pain_finished = time + 1; + hknight_pain1 (); +}; + +void() hknight_melee = +{ + self.hknightattack += 1; + + sound (self, CHAN_WEAPON, "hknight/slash1.wav", 1, ATTN_NORM); + switch (self.hknightattack) + { + case 1: + hknight_slice1 (); + break; + case 2: + hknight_smash1 (); + break; + default: + hknight_watk1 (); + self.hknightattack = 0; + } +}; + +/*QUAKED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_hell_knight = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/hknight.mdl"); + precache_model2 ("progs/k_spike.mdl"); + precache_model2 ("progs/h_hellkn.mdl"); + + precache_sound2 ("hknight/attack1.wav"); + precache_sound2 ("hknight/death1.wav"); + precache_sound2 ("hknight/pain1.wav"); + precache_sound2 ("hknight/sight1.wav"); + precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2 + precache_sound2 ("hknight/slash1.wav"); + precache_sound2 ("hknight/idle.wav"); + precache_sound2 ("hknight/grunt.wav"); + + precache_sound ("knight/sword1.wav"); + precache_sound ("knight/sword2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/hknight.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 250; + + self.th_stand = hknight_stand1; + self.th_walk = hknight_walk1; + self.th_run = hknight_run1; + self.th_melee = hknight_melee; + self.th_missile = hknight_magicc1; + self.th_pain = hknight_pain; + self.th_die = hknight_die; + + self.hknightattack = floor(random() * 2.99); + + walkmonster_start (); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/knight.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/knight.qc new file mode 100755 index 00000000..257b35bf --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/knight.qc @@ -0,0 +1,278 @@ +/* +============================================================================== + +KNIGHT + +============================================================================== +*/ + +$cd id1/models/knight +$origin 0 0 24 +$base base +$skin badass3 + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame runb1 runb2 runb3 runb4 runb5 runb6 runb7 runb8 + +//frame runc1 runc2 runc3 runc4 runc5 runc6 + +$frame runattack1 runattack2 runattack3 runattack4 runattack5 +$frame runattack6 runattack7 runattack8 runattack9 runattack10 +$frame runattack11 + +$frame pain1 pain2 pain3 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 +$frame painb10 painb11 + +//frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 +//frame attack8 attack9 attack10 attack11 + +$frame attackb0 attackb1 attackb2 attackb3 attackb4 attackb5 +$frame attackb6 attackb7 attackb8 attackb9 attackb10 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 +$frame walk10 walk11 walk12 walk13 walk14 + +$frame kneel1 kneel2 kneel3 kneel4 kneel5 + +$frame standing2 standing3 standing4 standing5 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 + +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 +$frame deathb9 deathb10 deathb11 + +void() knight_stand1 =[ $stand1, knight_stand2 ] {ai_stand();}; +void() knight_stand2 =[ $stand2, knight_stand3 ] {ai_stand();}; +void() knight_stand3 =[ $stand3, knight_stand4 ] {ai_stand();}; +void() knight_stand4 =[ $stand4, knight_stand5 ] {ai_stand();}; +void() knight_stand5 =[ $stand5, knight_stand6 ] {ai_stand();}; +void() knight_stand6 =[ $stand6, knight_stand7 ] {ai_stand();}; +void() knight_stand7 =[ $stand7, knight_stand8 ] {ai_stand();}; +void() knight_stand8 =[ $stand8, knight_stand9 ] {ai_stand();}; +void() knight_stand9 =[ $stand9, knight_stand1 ] {ai_stand();}; + +void() knight_walk1 =[ $walk1, knight_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE); +ai_walk(3);}; +void() knight_walk2 =[ $walk2, knight_walk3 ] {ai_walk(2);}; +void() knight_walk3 =[ $walk3, knight_walk4 ] {ai_walk(3);}; +void() knight_walk4 =[ $walk4, knight_walk5 ] {ai_walk(4);}; +void() knight_walk5 =[ $walk5, knight_walk6 ] {ai_walk(3);}; +void() knight_walk6 =[ $walk6, knight_walk7 ] {ai_walk(3);}; +void() knight_walk7 =[ $walk7, knight_walk8 ] {ai_walk(3);}; +void() knight_walk8 =[ $walk8, knight_walk9 ] {ai_walk(4);}; +void() knight_walk9 =[ $walk9, knight_walk10 ] {ai_walk(3);}; +void() knight_walk10 =[ $walk10, knight_walk11 ] {ai_walk(3);}; +void() knight_walk11 =[ $walk11, knight_walk12 ] {ai_walk(2);}; +void() knight_walk12 =[ $walk12, knight_walk13 ] {ai_walk(3);}; +void() knight_walk13 =[ $walk13, knight_walk14 ] {ai_walk(4);}; +void() knight_walk14 =[ $walk14, knight_walk1 ] {ai_walk(3);}; + + +void() knight_run1 =[ $runb1, knight_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE); +ai_run(16);}; +void() knight_run2 =[ $runb2, knight_run3 ] {ai_run(20);}; +void() knight_run3 =[ $runb3, knight_run4 ] {ai_run(13);}; +void() knight_run4 =[ $runb4, knight_run5 ] {ai_run(7);}; +void() knight_run5 =[ $runb5, knight_run6 ] {ai_run(16);}; +void() knight_run6 =[ $runb6, knight_run7 ] {ai_run(20);}; +void() knight_run7 =[ $runb7, knight_run8 ] {ai_run(14);}; +void() knight_run8 =[ $runb8, knight_run1 ] {ai_run(6);}; + + +void() knight_runatk1 =[ $runattack1, knight_runatk2 ] +{ +if (random() > 0.5) + sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM); +else + sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +ai_charge(20); +}; +void() knight_runatk2 =[ $runattack2, knight_runatk3 ] {ai_charge_side();}; +void() knight_runatk3 =[ $runattack3, knight_runatk4 ] {ai_charge_side();}; +void() knight_runatk4 =[ $runattack4, knight_runatk5 ] {ai_charge_side();}; +void() knight_runatk5 =[ $runattack5, knight_runatk6 ] {ai_melee_side(MOD_KNIGHT);}; +void() knight_runatk6 =[ $runattack6, knight_runatk7 ] {ai_melee_side(MOD_KNIGHT);}; +void() knight_runatk7 =[ $runattack7, knight_runatk8 ] {ai_melee_side(MOD_KNIGHT);}; +void() knight_runatk8 =[ $runattack8, knight_runatk9 ] {ai_melee_side(MOD_KNIGHT);}; +void() knight_runatk9 =[ $runattack9, knight_runatk10 ] {ai_melee_side(MOD_KNIGHT);}; +void() knight_runatk10 =[ $runattack10, knight_runatk11 ] {ai_charge_side();}; +void() knight_runatk11 =[ $runattack11, knight_run1 ] {ai_charge(10);}; + +void() knight_atk1 =[ $attackb1, knight_atk2 ] +{ +sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM); +ai_charge(0);}; +void() knight_atk2 =[ $attackb2, knight_atk3 ] {ai_charge(7);}; +void() knight_atk3 =[ $attackb3, knight_atk4 ] {ai_charge(4);}; +void() knight_atk4 =[ $attackb4, knight_atk5 ] {ai_charge(0);}; +void() knight_atk5 =[ $attackb5, knight_atk6 ] {ai_charge(3);}; +void() knight_atk6 =[ $attackb6, knight_atk7 ] {ai_charge(4); ai_melee(MOD_KNIGHT);}; +void() knight_atk7 =[ $attackb7, knight_atk8 ] {ai_charge(1); ai_melee(MOD_KNIGHT);}; +void() knight_atk8 =[ $attackb8, knight_atk9 ] {ai_charge(3); ai_melee(MOD_KNIGHT);}; +void() knight_atk9 =[ $attackb9, knight_atk10] {ai_charge(1);}; +void() knight_atk10=[ $attackb10, knight_run1 ] {ai_charge(5);}; + +//void() knight_atk9 =[ $attack9, knight_atk10 ] {}; +//void() knight_atk10 =[ $attack10, knight_atk11 ] {}; +//void() knight_atk11 =[ $attack11, knight_run1 ] {}; + +//=========================================================================== + +void() knight_pain1 =[ $pain1, knight_pain2 ] {}; +void() knight_pain2 =[ $pain2, knight_pain3 ] {}; +void() knight_pain3 =[ $pain3, knight_run1 ] {}; + +void() knight_painb1 =[ $painb1, knight_painb2 ] {ai_painforward(0);}; +void() knight_painb2 =[ $painb2, knight_painb3 ] {ai_painforward(3);}; +void() knight_painb3 =[ $painb3, knight_painb4 ] {}; +void() knight_painb4 =[ $painb4, knight_painb5 ] {}; +void() knight_painb5 =[ $painb5, knight_painb6 ] {ai_painforward(2);}; +void() knight_painb6 =[ $painb6, knight_painb7 ] {ai_painforward(4);}; +void() knight_painb7 =[ $painb7, knight_painb8 ] {ai_painforward(2);}; +void() knight_painb8 =[ $painb8, knight_painb9 ] {ai_painforward(5);}; +void() knight_painb9 =[ $painb9, knight_painb10 ] {ai_painforward(5);}; +void() knight_painb10 =[ $painb10, knight_painb11 ] {ai_painforward(0);}; +void() knight_painb11 =[ $painb11, knight_run1 ] {}; + +void(entity attacker, float damage) knight_pain = +{ + local float r; + + if (self.pain_finished > time) + return; + + r = random(); + + sound (self, CHAN_VOICE, "knight/khurt.wav", 1, ATTN_NORM); + self.pain_finished = time + 1; + + if (r < 0.85) + knight_pain1 (); + else + knight_painb1 (); + +}; + +//=========================================================================== + +#ifdef 0 +// Not used +void() knight_bow1 =[ $kneel1, knight_bow2 ] {ai_turn();}; +void() knight_bow2 =[ $kneel2, knight_bow3 ] {ai_turn();}; +void() knight_bow3 =[ $kneel3, knight_bow4 ] {ai_turn();}; +void() knight_bow4 =[ $kneel4, knight_bow5 ] {ai_turn();}; + +void() knight_bow5 =[ $kneel5, knight_bow5 ] {ai_turn();}; + +void() knight_bow6 =[ $kneel4, knight_bow7 ] {ai_turn();}; +void() knight_bow7 =[ $kneel3, knight_bow8 ] {ai_turn();}; +void() knight_bow8 =[ $kneel2, knight_bow9 ] {ai_turn();}; +void() knight_bow9 =[ $kneel1, knight_bow10 ] {ai_turn();}; +void() knight_bow10 =[ $walk1, knight_walk1 ] {ai_turn();}; +#endif + +void() knight_die1 =[ $death1, knight_die2 ] {}; +void() knight_die2 =[ $death2, knight_die3 ] {}; +void() knight_die3 =[ $death3, knight_die4 ] +{self.solid = SOLID_NOT;}; +void() knight_die4 =[ $death4, knight_die5 ] {}; +void() knight_die5 =[ $death5, knight_die6 ] {}; +void() knight_die6 =[ $death6, knight_die7 ] {}; +void() knight_die7 =[ $death7, knight_die8 ] {}; +void() knight_die8 =[ $death8, knight_die9 ] {}; +void() knight_die9 =[ $death9, knight_die10] {}; +void() knight_die10=[ $death10, knight_die10] {}; + + +void() knight_dieb1 =[ $deathb1, knight_dieb2 ] {}; +void() knight_dieb2 =[ $deathb2, knight_dieb3 ] {}; +void() knight_dieb3 =[ $deathb3, knight_dieb4 ] +{self.solid = SOLID_NOT;}; +void() knight_dieb4 =[ $deathb4, knight_dieb5 ] {}; +void() knight_dieb5 =[ $deathb5, knight_dieb6 ] {}; +void() knight_dieb6 =[ $deathb6, knight_dieb7 ] {}; +void() knight_dieb7 =[ $deathb7, knight_dieb8 ] {}; +void() knight_dieb8 =[ $deathb8, knight_dieb9 ] {}; +void() knight_dieb9 =[ $deathb9, knight_dieb10] {}; +void() knight_dieb10 = [ $deathb10, knight_dieb11] {}; +void() knight_dieb11 = [ $deathb11, knight_dieb11] {}; + + +void() knight_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_knight.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "knight/kdeath.wav", 1, ATTN_NORM); + if (random() < 0.5) + knight_die1 (); + else + knight_dieb1 (); +}; + +void() knight_attack = +{ + local float len; + +// decide if now is a good swing time + len = vlen(self.enemy.origin+self.enemy.view_ofs - (self.origin+self.view_ofs)); + + if (len<80) + knight_atk1 (); + else + knight_runatk1 (); +}; + +/*QUAKED monster_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_knight = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/knight.mdl"); + precache_model ("progs/h_knight.mdl"); + + precache_sound ("knight/kdeath.wav"); + precache_sound ("knight/khurt.wav"); + precache_sound ("knight/ksight.wav"); + precache_sound ("knight/sword1.wav"); + precache_sound ("knight/sword2.wav"); + precache_sound ("knight/idle.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/knight.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 75; + + self.th_stand = knight_stand1; + self.th_walk = knight_walk1; + self.th_run = knight_run1; + self.th_melee = knight_attack; + self.th_pain = knight_pain; + self.th_die = knight_die; + + walkmonster_start (); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/ogre.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/ogre.qc new file mode 100755 index 00000000..441a4845 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/ogre.qc @@ -0,0 +1,397 @@ +/* +============================================================================== + +OGRE + +============================================================================== +*/ + +$cd id1/models/ogre_c +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 +$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7 +$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 +$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14 + +$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame painb1 painb2 painb3 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10 +$frame paind11 paind12 paind13 paind14 paind15 paind16 + +$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10 +$frame paine11 paine12 paine13 paine14 paine15 + +$frame death1 death2 death3 death4 death5 death6 +$frame death7 death8 death9 death10 death11 death12 +$frame death13 death14 + +$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6 +$frame bdeath7 bdeath8 bdeath9 bdeath10 + +$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11 + +//============================================================================= + + +void() ogre_fire = +{ + local vector dir; + local entity en; + + ai_face(); + + sound (self, CHAN_WEAPON, "weapons/ppist.wav", 1, ATTN_NORM); + +// fire somewhat behind the player, so a dodging player is harder to hit + en = self.enemy; + + dir = en.origin - en.velocity*0.2; + dir = normalize (dir - self.origin); + + FireBullets (1, dir, '0.1 0.1 0', MOD_OGRE); +}; +//============================================================================= + +void() laugh = +{ +local float r; +r = random(); +if (r <= 0.5) +sound (self, CHAN_AUTO, "ogre/laugh1.wav", 1, ATTN_NORM); +else if ( r <= 0.10) +sound (self, CHAN_AUTO, "ogre/laugh2.wav", 1, ATTN_NORM); +else +{} +}; +/* +================ +chainsaw + +FIXME +================ +*/ +void(float side) chainsaw = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + if (!CanDamage (self.enemy, self)) + return; + + ai_charge(10); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + ldmg = (random() + random() + random()) * 25; + T_Damage (self.enemy, self, self, ldmg, MOD_OGRE); +}; + + +void() ogre_stand1 =[ $stand1, ogre_stand2 ] {ai_stand();}; +void() ogre_stand2 =[ $stand2, ogre_stand3 ] {ai_stand();}; +void() ogre_stand3 =[ $stand3, ogre_stand4 ] {ai_stand(); laugh();}; +void() ogre_stand4 =[ $stand4, ogre_stand5 ] {ai_stand();}; +void() ogre_stand5 =[ $stand5, ogre_stand6 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE); +ai_stand(); +}; +void() ogre_stand6 =[ $stand6, ogre_stand7 ] {ai_stand();}; +void() ogre_stand7 =[ $stand7, ogre_stand8 ] {ai_stand();}; +void() ogre_stand8 =[ $stand8, ogre_stand9 ] {ai_stand();}; +void() ogre_stand9 =[ $stand9, ogre_stand1 ] {ai_stand();}; + +void() ogre_walk1 =[ $walk1, ogre_walk2 ] {ai_walk(3);}; +void() ogre_walk2 =[ $walk2, ogre_walk3 ] {ai_walk(2);}; +void() ogre_walk3 =[ $walk3, ogre_walk4 ] { +ai_walk(2); +if (random() < 0.2) + sound (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE); +}; +void() ogre_walk4 =[ $walk4, ogre_walk5 ] {ai_walk(2);}; +void() ogre_walk5 =[ $walk5, ogre_walk6 ] {ai_walk(2);}; +void() ogre_walk6 =[ $walk6, ogre_walk7 ] { +ai_walk(5); +if (random() < 0.1) + sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE); +}; +void() ogre_walk7 =[ $walk7, ogre_walk8 ] {ai_walk(3);}; +void() ogre_walk8 =[ $walk8, ogre_walk9 ] {ai_walk(2);}; +void() ogre_walk9 =[ $walk9, ogre_walk10 ] {ai_walk(3);}; +void() ogre_walk10 =[ $walk10, ogre_walk11 ] {ai_walk(1);}; +void() ogre_walk11 =[ $walk11, ogre_walk12 ] {ai_walk(2);}; +void() ogre_walk12 =[ $walk12, ogre_walk13 ] {ai_walk(3);}; +void() ogre_walk13 =[ $walk13, ogre_walk14 ] {ai_walk(3);}; +void() ogre_walk14 =[ $walk14, ogre_walk15 ] {ai_walk(3);}; +void() ogre_walk15 =[ $walk15, ogre_walk16 ] {ai_walk(3);}; +void() ogre_walk16 =[ $walk16, ogre_walk1 ] {ai_walk(4);}; + +void() ogre_run1 =[ $run1, ogre_run2 ] {ai_run(9); +if (random() < 0.2) + sound (self, CHAN_VOICE, "ogre/ogidle2.wav", 1, ATTN_IDLE); +}; +void() ogre_run2 =[ $run2, ogre_run3 ] {ai_run(12);}; +void() ogre_run3 =[ $run3, ogre_run4 ] {ai_run(8);}; +void() ogre_run4 =[ $run4, ogre_run5 ] {ai_run(22);}; +void() ogre_run5 =[ $run5, ogre_run6 ] {ai_run(16);}; +void() ogre_run6 =[ $run6, ogre_run7 ] {ai_run(4);}; +void() ogre_run7 =[ $run7, ogre_run8 ] {ai_run(13);}; +void() ogre_run8 =[ $run8, ogre_run1 ] {ai_run(24);}; + +void() ogre_swing1 =[ $swing1, ogre_swing2 ] {ai_charge(11); +sound (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM); +}; +void() ogre_swing2 =[ $swing2, ogre_swing3 ] {ai_charge(1);}; +void() ogre_swing3 =[ $swing3, ogre_swing4 ] {ai_charge(4);}; +void() ogre_swing4 =[ $swing4, ogre_swing5 ] {ai_charge(13);}; +void() ogre_swing5 =[ $swing5, ogre_swing6 ] {ai_charge(9); chainsaw(0);self.angles_y = self.angles_y + random()*25;}; +void() ogre_swing6 =[ $swing6, ogre_swing7 ] {chainsaw(200);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing7 =[ $swing7, ogre_swing8 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing8 =[ $swing8, ogre_swing9 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing9 =[ $swing9, ogre_swing10 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing10 =[ $swing10, ogre_swing11 ] {chainsaw(-200);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing11 =[ $swing11, ogre_swing12 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;}; +void() ogre_swing12 =[ $swing12, ogre_swing13 ] {ai_charge(3);}; +void() ogre_swing13 =[ $swing13, ogre_swing14 ] {ai_charge(8);}; +void() ogre_swing14 =[ $swing14, ogre_run1 ] {ai_charge(9);}; + +void() ogre_smash1 =[ $smash1, ogre_smash2 ] {ai_charge(6); +sound (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM); +}; +void() ogre_smash2 =[ $smash2, ogre_smash3 ] {ai_charge(0);}; +void() ogre_smash3 =[ $smash3, ogre_smash4 ] {ai_charge(0);}; +void() ogre_smash4 =[ $smash4, ogre_smash5 ] {ai_charge(1);}; +void() ogre_smash5 =[ $smash5, ogre_smash6 ] {ai_charge(4);}; +void() ogre_smash6 =[ $smash6, ogre_smash7 ] {ai_charge(4); chainsaw(0);}; +void() ogre_smash7 =[ $smash7, ogre_smash8 ] {ai_charge(4); chainsaw(0);}; +void() ogre_smash8 =[ $smash8, ogre_smash9 ] {ai_charge(10); chainsaw(0);}; +void() ogre_smash9 =[ $smash9, ogre_smash10 ] {ai_charge(13); chainsaw(0);}; +void() ogre_smash10 =[ $smash10, ogre_smash11 ] {chainsaw(1);}; +void() ogre_smash11 =[ $smash11, ogre_smash12 ] {ai_charge(2); chainsaw(0); +self.nextthink = time + 0.1 + random()*0.1;}; // slight variation +//void() ogre_smash12 =[ $smash12, ogre_smash13 ] {ai_charge();}; +void() ogre_smash12 =[$smash12, ogre_smash13] {ai_charge(0);}; +void() ogre_smash13 =[ $smash13, ogre_smash14 ] {ai_charge(4);}; +void() ogre_smash14 =[ $smash14, ogre_run1 ] {ai_charge(12);}; + +void() ogre_nail1 =[ $run1, ogre_nail2 ] {ai_face();}; +void() ogre_nail2 =[ $run2, ogre_nail3 ] {ai_face();}; +void() ogre_nail3 =[ $run2, ogre_nail4 ] {ai_face();}; +void() ogre_nail4 =[ $run3, ogre_nail5 ] {ai_face(); ogre_fire();}; +void() ogre_nail5 =[ $run4, ogre_nail6 ] {ai_face();}; +void() ogre_nail6 =[ $run5, ogre_nail7 ] {ai_face();}; +void() ogre_nail7 =[ $run6, ogre_run1 ] {ai_face();}; + +void() ogre_pain1 =[ $pain1, ogre_pain2 ] {}; +void() ogre_pain2 =[ $pain2, ogre_pain3 ] {}; +void() ogre_pain3 =[ $pain3, ogre_pain4 ] {}; +void() ogre_pain4 =[ $pain4, ogre_pain5 ] {}; +void() ogre_pain5 =[ $pain5, ogre_run1 ] {}; + + +void() ogre_painb1 =[ $painb1, ogre_painb2 ] {}; +void() ogre_painb2 =[ $painb2, ogre_painb3 ] {}; +void() ogre_painb3 =[ $painb3, ogre_run1 ] {}; + + +void() ogre_painc1 =[ $painc1, ogre_painc2 ] {}; +void() ogre_painc2 =[ $painc2, ogre_painc3 ] {}; +void() ogre_painc3 =[ $painc3, ogre_painc4 ] {}; +void() ogre_painc4 =[ $painc4, ogre_painc5 ] {}; +void() ogre_painc5 =[ $painc5, ogre_painc6 ] {}; +void() ogre_painc6 =[ $painc6, ogre_run1 ] {}; + + +void() ogre_paind1 =[ $paind1, ogre_paind2 ] {}; +void() ogre_paind2 =[ $paind2, ogre_paind3 ] {ai_pain(10);}; +void() ogre_paind3 =[ $paind3, ogre_paind4 ] {ai_pain(9);}; +void() ogre_paind4 =[ $paind4, ogre_paind5 ] {ai_pain(4);}; +void() ogre_paind5 =[ $paind5, ogre_paind6 ] {}; +void() ogre_paind6 =[ $paind6, ogre_paind7 ] {}; +void() ogre_paind7 =[ $paind7, ogre_paind8 ] {}; +void() ogre_paind8 =[ $paind8, ogre_paind9 ] {}; +void() ogre_paind9 =[ $paind9, ogre_paind10 ] {}; +void() ogre_paind10=[ $paind10, ogre_paind11 ] {}; +void() ogre_paind11=[ $paind11, ogre_paind12 ] {}; +void() ogre_paind12=[ $paind12, ogre_paind13 ] {}; +void() ogre_paind13=[ $paind13, ogre_paind14 ] {}; +void() ogre_paind14=[ $paind14, ogre_paind15 ] {}; +void() ogre_paind15=[ $paind15, ogre_paind16 ] {}; +void() ogre_paind16=[ $paind16, ogre_run1 ] {}; + +void() ogre_paine1 =[ $paine1, ogre_paine2 ] {}; +void() ogre_paine2 =[ $paine2, ogre_paine3 ] {ai_pain(10);}; +void() ogre_paine3 =[ $paine3, ogre_paine4 ] {ai_pain(9);}; +void() ogre_paine4 =[ $paine4, ogre_paine5 ] {ai_pain(4);}; +void() ogre_paine5 =[ $paine5, ogre_paine6 ] {}; +void() ogre_paine6 =[ $paine6, ogre_paine7 ] {}; +void() ogre_paine7 =[ $paine7, ogre_paine8 ] {}; +void() ogre_paine8 =[ $paine8, ogre_paine9 ] {}; +void() ogre_paine9 =[ $paine9, ogre_paine10 ] {}; +void() ogre_paine10=[ $paine10, ogre_paine11 ] {}; +void() ogre_paine11=[ $paine11, ogre_paine12 ] {}; +void() ogre_paine12=[ $paine12, ogre_paine13 ] {}; +void() ogre_paine13=[ $paine13, ogre_paine14 ] {}; +void() ogre_paine14=[ $paine14, ogre_paine15 ] {}; +void() ogre_paine15=[ $paine15, ogre_run1 ] {}; + + +void(entity attacker, float damage) ogre_pain = +{ + local float r; + +// don't make multiple pain sounds right after each other + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "ogre/ogpain1.wav", 1, ATTN_NORM); + + r = random(); + + if (r < 0.25) + { + ogre_pain1 (); + self.pain_finished = time + 1; + } + else if (r < 0.5) + { + ogre_painb1 (); + self.pain_finished = time + 1; + } + else if (r < 0.75) + { + ogre_painc1 (); + self.pain_finished = time + 1; + } + else if (r < 0.88) + { + ogre_paind1 (); + self.pain_finished = time + 2; + } + else + { + ogre_paine1 (); + self.pain_finished = time + 2; + } +}; + +void() ogre_die1 =[ $death1, ogre_die2 ] {}; +void() ogre_die2 =[ $death2, ogre_die3 ] {}; +void() ogre_die3 =[ $death3, ogre_die4 ] +{self.solid = SOLID_NOT;DropBackpack();}; +void() ogre_die4 =[ $death4, ogre_die5 ] {}; +void() ogre_die5 =[ $death5, ogre_die6 ] {}; +void() ogre_die6 =[ $death6, ogre_die7 ] {}; +void() ogre_die7 =[ $death7, ogre_die8 ] {}; +void() ogre_die8 =[ $death8, ogre_die9 ] {}; +void() ogre_die9 =[ $death9, ogre_die10 ] {}; +void() ogre_die10 =[ $death10, ogre_die11 ] {}; +void() ogre_die11 =[ $death11, ogre_die12 ] {}; +void() ogre_die12 =[ $death12, ogre_die13 ] {}; +void() ogre_die13 =[ $death13, ogre_die14 ] {}; +void() ogre_die14 =[ $death14, ogre_die14 ] {}; + +void() ogre_bdie1 =[ $bdeath1, ogre_bdie2 ] {}; +void() ogre_bdie2 =[ $bdeath2, ogre_bdie3 ] {ai_forward(5);}; +void() ogre_bdie3 =[ $bdeath3, ogre_bdie4 ] +{self.solid = SOLID_NOT;DropBackpack();}; +void() ogre_bdie4 =[ $bdeath4, ogre_bdie5 ] {ai_forward(1);}; +void() ogre_bdie5 =[ $bdeath5, ogre_bdie6 ] {ai_forward(3);}; +void() ogre_bdie6 =[ $bdeath6, ogre_bdie7 ] {ai_forward(7);}; +void() ogre_bdie7 =[ $bdeath7, ogre_bdie8 ] {ai_forward(25);}; +void() ogre_bdie8 =[ $bdeath8, ogre_bdie9 ] {}; +void() ogre_bdie9 =[ $bdeath9, ogre_bdie10 ] {}; +void() ogre_bdie10 =[ $bdeath10, ogre_bdie10 ] {}; + +void() ogre_die = +{ + + sound (self, CHAN_VOICE, "ogre/ogdth.wav", 1, ATTN_NORM); + + if (random() < 0.5) + ogre_die1 (); + else + ogre_bdie1 (); +}; + +void() ogre_melee = +{ + if (random() > 0.5) + ogre_smash1 (); + else + ogre_swing1 (); +}; + + +/*QUAKED monster_ogre (1 0 0) (-32 -32 -24) (32 32 64) Ambush + +*/ +void() monster_ogre = +{ + if (deathmatch) + { + remove(self); + } + precache_model ("progs/ogre.mdl"); + precache_model ("progs/h_ogre.mdl"); + precache_model ("progs/grenade.mdl"); + + precache_sound ("ogre/laugh1.wav"); + precache_sound ("ogre/laugh2.wav"); + precache_sound ("ogre/ogdrag.wav"); + precache_sound ("ogre/ogdth.wav"); + precache_sound ("ogre/ogidle.wav"); + precache_sound ("ogre/ogidle2.wav"); + precache_sound ("ogre/ogpain1.wav"); + precache_sound ("ogre/ogsawatk.wav"); + precache_sound ("ogre/ogwake.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/ogre.mdl"); + + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 800; + + self.th_stand = ogre_stand1; + self.th_walk = ogre_walk1; + self.th_run = ogre_run1; + self.th_die = ogre_die; + self.th_melee = ogre_melee; + self.th_missile = ogre_nail1; + self.th_pain = ogre_pain; + + self.ammo_rockets_real = 2; // drop 2 rockets on death + + walkmonster_start(); +}; + +void() monster_ogre_marksman = +{ + monster_ogre (); +}; + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/oldone.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/oldone.qc new file mode 100755 index 00000000..386c11ac --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/oldone.qc @@ -0,0 +1,278 @@ +/* +============================================================================== + +OLD ONE + +============================================================================== +*/ +$cd id1/models/old_one +$origin 0 0 24 +$base base +$skin skin +$scale 1 + +void() finale_1; +void() finale_2; +void() finale_3; +void() finale_4; + +$frame old1 old2 old3 old4 old5 old6 old7 old8 old9 +$frame old10 old11 old12 old13 old14 old15 old16 old17 old18 old19 +$frame old20 old21 old22 old23 old24 old25 old26 old27 old28 old29 +$frame old30 old31 old32 old33 old34 old35 old36 old37 old38 old39 +$frame old40 old41 old42 old43 old44 old45 old46 + +$frame shake1 shake2 shake3 shake4 shake5 shake6 shake7 shake8 +$frame shake9 shake10 shake11 shakex shake12 shake13 shake14 +$frame shake15 shake16 shake17 shake18 shake19 shake20 + +//void() old_stand =[ $old1, old_stand ] {}; + +void() old_idle1 =[ $old1, old_idle2 ] {}; +void() old_idle2 =[ $old2, old_idle3 ] {}; +void() old_idle3 =[ $old3, old_idle4 ] {}; +void() old_idle4 =[ $old4, old_idle5 ] {}; +void() old_idle5 =[ $old5, old_idle6 ] {}; +void() old_idle6 =[ $old6, old_idle7 ] {}; +void() old_idle7 =[ $old7, old_idle8 ] {}; +void() old_idle8 =[ $old8, old_idle9 ] {}; +void() old_idle9 =[ $old9, old_idle10 ] {}; +void() old_idle10 =[ $old10, old_idle11 ] {}; +void() old_idle11 =[ $old11, old_idle12 ] {}; +void() old_idle12 =[ $old12, old_idle13 ] {}; +void() old_idle13 =[ $old13, old_idle14 ] {}; +void() old_idle14 =[ $old14, old_idle15 ] {}; +void() old_idle15 =[ $old15, old_idle16 ] {}; +void() old_idle16 =[ $old16, old_idle17 ] {}; +void() old_idle17 =[ $old17, old_idle18 ] {}; +void() old_idle18 =[ $old18, old_idle19 ] {}; +void() old_idle19 =[ $old19, old_idle20 ] {}; +void() old_idle20 =[ $old20, old_idle21 ] {}; +void() old_idle21 =[ $old21, old_idle22 ] {}; +void() old_idle22 =[ $old22, old_idle23 ] {}; +void() old_idle23 =[ $old23, old_idle24 ] {}; +void() old_idle24 =[ $old24, old_idle25 ] {}; +void() old_idle25 =[ $old25, old_idle26 ] {}; +void() old_idle26 =[ $old26, old_idle27 ] {}; +void() old_idle27 =[ $old27, old_idle28 ] {}; +void() old_idle28 =[ $old28, old_idle29 ] {}; +void() old_idle29 =[ $old29, old_idle30 ] {}; +void() old_idle30 =[ $old30, old_idle31 ] {}; +void() old_idle31 =[ $old31, old_idle32 ] {}; +void() old_idle32 =[ $old32, old_idle33 ] {}; +void() old_idle33 =[ $old33, old_idle34 ] {}; +void() old_idle34 =[ $old34, old_idle35 ] {}; +void() old_idle35 =[ $old35, old_idle36 ] {}; +void() old_idle36 =[ $old36, old_idle37 ] {}; +void() old_idle37 =[ $old37, old_idle38 ] {}; +void() old_idle38 =[ $old38, old_idle39 ] {}; +void() old_idle39 =[ $old39, old_idle40 ] {}; +void() old_idle40 =[ $old40, old_idle41 ] {}; +void() old_idle41 =[ $old41, old_idle42 ] {}; +void() old_idle42 =[ $old42, old_idle43 ] {}; +void() old_idle43 =[ $old43, old_idle44 ] {}; +void() old_idle44 =[ $old44, old_idle45 ] {}; +void() old_idle45 =[ $old45, old_idle46 ] {}; +void() old_idle46 =[ $old46, old_idle1 ] {}; + + +void() old_thrash1 =[ $shake1, old_thrash2 ] {lightstyle(0, "m");}; +void() old_thrash2 =[ $shake2, old_thrash3 ] {lightstyle(0, "k");}; +void() old_thrash3 =[ $shake3, old_thrash4 ] {lightstyle(0, "k");}; +void() old_thrash4 =[ $shake4, old_thrash5 ] {lightstyle(0, "i");}; +void() old_thrash5 =[ $shake5, old_thrash6 ] {lightstyle(0, "g");}; +void() old_thrash6 =[ $shake6, old_thrash7 ] {lightstyle(0, "e");}; +void() old_thrash7 =[ $shake7, old_thrash8 ] {lightstyle(0, "c");}; +void() old_thrash8 =[ $shake8, old_thrash9 ] {lightstyle(0, "a");}; +void() old_thrash9 =[ $shake9, old_thrash10 ] {lightstyle(0, "c");}; +void() old_thrash10 =[ $shake10, old_thrash11 ] {lightstyle(0, "e");}; +void() old_thrash11 =[ $shake11, old_thrash12 ] {lightstyle(0, "g");}; +void() old_thrash12 =[ $shake12, old_thrash13 ] {lightstyle(0, "i");}; +void() old_thrash13 =[ $shake13, old_thrash14 ] {lightstyle(0, "k");}; +void() old_thrash14 =[ $shake14, old_thrash15 ] {lightstyle(0, "m");}; +void() old_thrash15 =[ $shake15, old_thrash16 ] {lightstyle(0, "m"); +self.cnt = self.cnt + 1; +if (self.cnt < 3) + self.think = old_thrash1; +}; +void() old_thrash16 =[ $shake16, old_thrash17 ] {lightstyle(0, "g");}; +void() old_thrash17 =[ $shake17, old_thrash18 ] {lightstyle(0, "c");}; +void() old_thrash18 =[ $shake18, old_thrash19 ] {lightstyle(0, "b");}; +void() old_thrash19 =[ $shake19, old_thrash20 ] {lightstyle(0, "a");}; +void() old_thrash20 =[ $shake20, old_thrash20 ] {finale_4();}; + +//============================================================================ + +void() finale_1 = +{ + local entity pos, pl; + local entity timer; + + // TODO: Coop friendly finale goes here + + killed_monsters = killed_monsters + 1; + WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast + + intermission_exittime = time + 10000000; // never allow exit + intermission_running = 1; + + // find the intermission spot + pos = find (world, classname, "info_intermission"); + if (!pos) + error ("no info_intermission"); + pl = find (world, classname, "misc_teleporttrain"); + if (!pl) + error ("no teleporttrain"); + remove (pl); + + ENG_Finale(""); + + pl = find (world, classname, "player"); + while (pl != world) + { + pl.view_ofs = '0 0 0'; + pl.angles = other.v_angle = pos.mangle; + pl.fixangle = TRUE; // turn this way immediately + pl.map = self.map; + pl.nextthink = time + 0.5; + pl.takedamage = DAMAGE_NO; + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NONE; + pl.modelindex = 0; + setorigin (pl, pos.origin); + pl = find (pl, classname, "player"); + } + + // make fake versions of all players as standins, and move the real + // players to the intermission spot + + // wait for 1 second + timer = spawn(); + timer.nextthink = time + 1; + timer.think = finale_2; +}; + +void() finale_2 = +{ + local vector o; + + // start a teleport splash inside shub + + o = shub.origin - '0 100 0'; + TE_teleport(o); + + sound (shub, CHAN_VOICE, "misc/r_tele1.wav", 1, ATTN_NORM); + + self.nextthink = time + 2; + self.think = finale_3; +}; + +void() finale_3 = +{ + // start shub thrashing wildly + lightstyle(0, "a"); + shub.think = old_thrash1; + sound (shub, CHAN_VOICE, "boss2/death.wav", 1, ATTN_NORM); + remove(self); +}; + +void() finale_4 = +{ + // throw tons of meat chunks + local vector oldo; + local float x, y, z; + local float r; + local entity n; + + sound (self, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NORM); + + oldo = self.origin; + + z = 16; + while (z <= 144) + { + x = -64; + while (x <= 64) + { + y = -64; + while (y <= 64) + { + self.origin_x = oldo_x + x; + self.origin_y = oldo_y + y; + self.origin_z = oldo_z + z; + + r = random(); + if (r < 0.3) + ThrowGib ("progs/gib1.mdl", -999); + else if (r < 0.6) + ThrowGib ("progs/gib2.mdl", -999); + else + ThrowGib ("progs/gib3.mdl", -999); + y = y + 32; + } + x = x + 32; + } + z = z + 96; + } + // start the end text + ENG_Finale("Congratulations and well done! You have\nbeaten the hideous Shub-Niggurath, and\nher hundreds of ugly changelings and\nmonsters. You have proven that your\nskill and your cunning are greater than\nall the powers of Quake. You are the\nmaster now. Id Software salutes you."); + +// put a player model down + n = spawn(); + setmodel (n, "progs/player.mdl"); + oldo = oldo - '32 264 0'; + setorigin (n, oldo); + n.angles = '0 290 0'; + n.frame = 1; + + remove (self); + +// switch cd track + ENG_SwitchTrack(3, 3); + lightstyle(0, "m"); +}; + +//============================================================================ + +void () nopain = +{ + self.health = 40000; +}; + +//============================================================================ + + +/*QUAKED monster_oldone (1 0 0) (-16 -16 -24) (16 16 32) +*/ +void() monster_oldone = +{ + if (deathmatch) + { + remove(self); + return; + } + + precache_model2 ("progs/oldone.mdl"); + + precache_sound2 ("boss2/death.wav"); + precache_sound2 ("boss2/idle.wav"); + precache_sound2 ("boss2/sight.wav"); + precache_sound2 ("boss2/pop2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/oldone.mdl"); + setsize (self, '-160 -128 -24', '160 128 256'); + + self.health = 40000; // kill by telefrag + self.think = old_idle1; + self.nextthink = time + 0.1; + self.takedamage = DAMAGE_YES; + self.th_pain = nopain; + self.th_die = finale_1; + shub = self; + + total_monsters = total_monsters + 1; +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/shalrath.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/shalrath.qc new file mode 100755 index 00000000..6629c718 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/shalrath.qc @@ -0,0 +1,219 @@ +/* +============================================================================== + +SHAL-RATH + +============================================================================== +*/ +$cd id1/models/shalrath +$origin 0 0 24 +$base base +$skin skin +$scale 0.7 + +$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 +$frame attack9 attack10 attack11 + +$frame pain1 pain2 pain3 pain4 pain5 + +$frame death1 death2 death3 death4 death5 death6 death7 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 +$frame walk11 walk12 + +void() shalrath_pain; +void() ShalMissile; +void() shal_stand =[ $walk1, shal_stand ] {ai_stand();}; + +void() shal_walk1 =[ $walk2, shal_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE); +ai_walk(6);}; +void() shal_walk2 =[ $walk3, shal_walk3 ] {ai_walk(4);}; +void() shal_walk3 =[ $walk4, shal_walk4 ] {ai_walk(0);}; +void() shal_walk4 =[ $walk5, shal_walk5 ] {ai_walk(0);}; +void() shal_walk5 =[ $walk6, shal_walk6 ] {ai_walk(0);}; +void() shal_walk6 =[ $walk7, shal_walk7 ] {ai_walk(0);}; +void() shal_walk7 =[ $walk8, shal_walk8 ] {ai_walk(5);}; +void() shal_walk8 =[ $walk9, shal_walk9 ] {ai_walk(6);}; +void() shal_walk9 =[ $walk10, shal_walk10 ] {ai_walk(5);}; +void() shal_walk10 =[ $walk11, shal_walk11 ] {ai_walk(0);}; +void() shal_walk11 =[ $walk12, shal_walk12 ] {ai_walk(4);}; +void() shal_walk12 =[ $walk1, shal_walk1 ] {ai_walk(5);}; + +void() shal_run1 =[ $walk2, shal_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE); +ai_run(6);}; +void() shal_run2 =[ $walk3, shal_run3 ] {ai_run(4);}; +void() shal_run3 =[ $walk4, shal_run4 ] {ai_run(0);}; +void() shal_run4 =[ $walk5, shal_run5 ] {ai_run(0);}; +void() shal_run5 =[ $walk6, shal_run6 ] {ai_run(0);}; +void() shal_run6 =[ $walk7, shal_run7 ] {ai_run(0);}; +void() shal_run7 =[ $walk8, shal_run8 ] {ai_run(5);}; +void() shal_run8 =[ $walk9, shal_run9 ] {ai_run(6);}; +void() shal_run9 =[ $walk10, shal_run10 ] {ai_run(5);}; +void() shal_run10 =[ $walk11, shal_run11 ] {ai_run(0);}; +void() shal_run11 =[ $walk12, shal_run12 ] {ai_run(4);}; +void() shal_run12 =[ $walk1, shal_run1 ] {ai_run(5);}; + +void() shal_attack1 =[ $attack1, shal_attack2 ] { +sound (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM); +ai_face(); +}; +void() shal_attack2 =[ $attack2, shal_attack3 ] {ai_face();}; +void() shal_attack3 =[ $attack3, shal_attack4 ] {ai_face();}; +void() shal_attack4 =[ $attack4, shal_attack5 ] {ai_face();}; +void() shal_attack5 =[ $attack5, shal_attack6 ] {ai_face();}; +void() shal_attack6 =[ $attack6, shal_attack7 ] {ai_face();}; +void() shal_attack7 =[ $attack7, shal_attack8 ] {ai_face();}; +void() shal_attack8 =[ $attack8, shal_attack9 ] {ai_face();}; +void() shal_attack9 =[ $attack9, shal_attack10 ] {ShalMissile();}; +void() shal_attack10 =[ $attack10, shal_attack11 ] {ai_face();}; +void() shal_attack11 =[ $attack11, shal_run1 ] {}; + +void() shal_pain1 =[ $pain1, shal_pain2 ] {}; +void() shal_pain2 =[ $pain2, shal_pain3 ] {}; +void() shal_pain3 =[ $pain3, shal_pain4 ] {}; +void() shal_pain4 =[ $pain4, shal_pain5 ] {}; +void() shal_pain5 =[ $pain5, shal_run1 ] {}; + +void() shal_death1 =[ $death1, shal_death2 ] {}; +void() shal_death2 =[ $death2, shal_death3 ] {}; +void() shal_death3 =[ $death3, shal_death4 ] {}; +void() shal_death4 =[ $death4, shal_death5 ] {}; +void() shal_death5 =[ $death5, shal_death6 ] {}; +void() shal_death6 =[ $death6, shal_death7 ] {}; +void() shal_death7 =[ $death7, shal_death7 ] {}; + + +void() shalrath_pain = +{ + if (self.pain_finished > time) + return; + + sound (self, CHAN_VOICE, "shalrath/pain.wav", 1, ATTN_NORM); + shal_pain1(); + self.pain_finished = time + 3; +}; + +void() shalrath_die = +{ +// check for gib + if (self.health < -90) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_shal.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + + sound (self, CHAN_VOICE, "shalrath/death.wav", 1, ATTN_NORM); + shal_death1(); + self.solid = SOLID_NOT; + // insert death sounds here +}; + +/* +================ +ShalMissile +================ +*/ +float() ShalMissileTouch; +void() ShalHome; +void() ShalMissile = +{ + local vector dir; + local float dist, flytime; + + dir = normalize((self.enemy.origin + '0 0 10') - self.origin); + dist = vlen (self.enemy.origin - self.origin); + flytime = dist * 0.002; + if (flytime < 0.1) + flytime = 0.1; + + muzzleflash(); + sound (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); + + PRJ_FireProjectile(self, + "progs/v_spike.mdl", + self.origin + '0 0 10', + dir * 400, + PE_EXPLOSION, + 0, + 0, + 30); + PRJ_SetRadiusDamage(40, 80, MOD_SHALRATH); + PRJ_SetThink(ShalHome, flytime, 0.2); + PRJ_SetTouch(ShalMissileTouch); + newmis.avelocity = '300 300 300'; + newmis.enemy = self.enemy; +}; + +void() ShalHome = +{ + local vector dir, vtemp; + vtemp = self.enemy.origin + '0 0 10'; + if (self.enemy.health < 1) + { + remove(self); + return; + } + + dir = normalize(vtemp - self.origin); + if (skill > 2) + self.velocity = dir * 350; + else + self.velocity = dir * 250; +}; + +float() ShalMissileTouch = +{ + if (other.classname == "monster_zombie") + T_Damage (other, self, self, 110, MOD_SHALRATH); + + return 0; // always explode on touch +}; + +//================================================================= + +/*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) Ambush +*/ +void() monster_shalrath = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/shalrath.mdl"); + precache_model2 ("progs/h_shal.mdl"); + precache_model2 ("progs/v_spike.mdl"); + + precache_sound2 ("shalrath/attack.wav"); + precache_sound2 ("shalrath/attack2.wav"); + precache_sound2 ("shalrath/death.wav"); + precache_sound2 ("shalrath/idle.wav"); + precache_sound2 ("shalrath/pain.wav"); + precache_sound2 ("shalrath/sight.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/shalrath.mdl"); + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 400; + + self.th_stand = shal_stand; + self.th_walk = shal_walk1; + self.th_run = shal_run1; + self.th_die = shalrath_die; + self.th_pain = shalrath_pain; + self.th_missile = shal_attack1; + + self.think = walkmonster_start; + self.nextthink = time + 0.1 + random ()*0.1; + +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/shambler.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/shambler.qc new file mode 100755 index 00000000..d90eb38f --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/shambler.qc @@ -0,0 +1,339 @@ +/* +============================================================================== + +SHAMBLER + +============================================================================== +*/ + +$cd id1/models/shams +$origin 0 0 24 +$base base +$skin base + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 +$frame stand10 stand11 stand12 stand13 stand14 stand15 stand16 stand17 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 +$frame walk8 walk9 walk10 walk11 walk12 + +$frame run1 run2 run3 run4 run5 run6 + +$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 +$frame smash8 smash9 smash10 smash11 smash12 + +$frame swingr1 swingr2 swingr3 swingr4 swingr5 +$frame swingr6 swingr7 swingr8 swingr9 + +$frame swingl1 swingl2 swingl3 swingl4 swingl5 +$frame swingl6 swingl7 swingl8 swingl9 + +$frame magic1 magic2 magic3 magic4 magic5 +$frame magic6 magic7 magic8 magic9 magic10 magic11 magic12 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame death1 death2 death3 death4 death5 death6 +$frame death7 death8 death9 death10 death11 + +void(float chrg, float damage, float side, float crnd) ShamClaw = +{ +local vector delta; +local float ldmg; + + if (!self.enemy) + return; + ai_charge(chrg); + + delta = self.enemy.origin - self.origin; + + if (vlen(delta) > 100) + return; + + ldmg = (random() + random() + random()) * damage; + T_Damage (self.enemy, self, self, ldmg, MOD_SHAMBLER); + sound (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM); + + if (side) + { + makevectors (self.angles); + SpawnMeatSpray (self.origin + v_forward*16, (crandom() * crnd + side) * v_right); + } +}; + + +void() sham_stand1 =[ $stand1, sham_stand2 ] {ai_stand();}; +void() sham_stand2 =[ $stand2, sham_stand3 ] {ai_stand();}; +void() sham_stand3 =[ $stand3, sham_stand4 ] {ai_stand();}; +void() sham_stand4 =[ $stand4, sham_stand5 ] {ai_stand();}; +void() sham_stand5 =[ $stand5, sham_stand6 ] {ai_stand();}; +void() sham_stand6 =[ $stand6, sham_stand7 ] {ai_stand();}; +void() sham_stand7 =[ $stand7, sham_stand8 ] {ai_stand();}; +void() sham_stand8 =[ $stand8, sham_stand9 ] {ai_stand();}; +void() sham_stand9 =[ $stand9, sham_stand10] {ai_stand();}; +void() sham_stand10 =[ $stand10, sham_stand11] {ai_stand();}; +void() sham_stand11 =[ $stand11, sham_stand12] {ai_stand();}; +void() sham_stand12 =[ $stand12, sham_stand13] {ai_stand();}; +void() sham_stand13 =[ $stand13, sham_stand14] {ai_stand();}; +void() sham_stand14 =[ $stand14, sham_stand15] {ai_stand();}; +void() sham_stand15 =[ $stand15, sham_stand16] {ai_stand();}; +void() sham_stand16 =[ $stand16, sham_stand17] {ai_stand();}; +void() sham_stand17 =[ $stand17, sham_stand1 ] {ai_stand();}; + +void() sham_walk1 =[ $walk1, sham_walk2 ] {ai_walk(10);}; +void() sham_walk2 =[ $walk2, sham_walk3 ] {ai_walk(9);}; +void() sham_walk3 =[ $walk3, sham_walk4 ] {ai_walk(9);}; +void() sham_walk4 =[ $walk4, sham_walk5 ] {ai_walk(5);}; +void() sham_walk5 =[ $walk5, sham_walk6 ] {ai_walk(6);}; +void() sham_walk6 =[ $walk6, sham_walk7 ] {ai_walk(12);}; +void() sham_walk7 =[ $walk7, sham_walk8 ] {ai_walk(8);}; +void() sham_walk8 =[ $walk8, sham_walk9 ] {ai_walk(3);}; +void() sham_walk9 =[ $walk9, sham_walk10] {ai_walk(13);}; +void() sham_walk10 =[ $walk10, sham_walk11] {ai_walk(9);}; +void() sham_walk11 =[ $walk11, sham_walk12] {ai_walk(7);}; +void() sham_walk12 =[ $walk12, sham_walk1 ] {ai_walk(7); +if (random() > 0.8) + sound (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);}; + +void() sham_run1 =[ $run1, sham_run2 ] {ai_run(20);}; +void() sham_run2 =[ $run2, sham_run3 ] {ai_run(24);}; +void() sham_run3 =[ $run3, sham_run4 ] {ai_run(20);}; +void() sham_run4 =[ $run4, sham_run5 ] {ai_run(20);}; +void() sham_run5 =[ $run5, sham_run6 ] {ai_run(24);}; +void() sham_run6 =[ $run6, sham_run1 ] {ai_run(20); +if (random() > 0.8) + sound (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE); +}; + +void() sham_smash1 =[ $smash1, sham_smash2 ] { +sound (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); +ai_charge(2);}; +void() sham_smash2 =[ $smash2, sham_smash3 ] {ai_charge(6);}; +void() sham_smash3 =[ $smash3, sham_smash4 ] {ai_charge(6);}; +void() sham_smash4 =[ $smash4, sham_smash5 ] {ai_charge(5);}; +void() sham_smash5 =[ $smash5, sham_smash6 ] {ai_charge(4);}; +void() sham_smash6 =[ $smash6, sham_smash7 ] {ai_charge(1);}; +void() sham_smash7 =[ $smash7, sham_smash8 ] {ai_charge(0);}; +void() sham_smash8 =[ $smash8, sham_smash9 ] {ai_charge(0);}; +void() sham_smash9 =[ $smash9, sham_smash10 ] {ai_charge(0);}; +void() sham_smash10 =[ $smash10, sham_smash11 ] {ShamClaw(0, 40, 0, 100);}; +void() sham_smash11 =[ $smash11, sham_smash12 ] {ai_charge(5);}; +void() sham_smash12 =[ $smash12, sham_run1 ] {ai_charge(4);}; + +void() sham_swingr1; + +void() sham_swingl1 =[ $swingl1, sham_swingl2 ] { +sound (self, CHAN_VOICE, "shambler/melee2.wav", 1, ATTN_NORM); +ai_charge(5);}; +void() sham_swingl2 =[ $swingl2, sham_swingl3 ] {ai_charge(3);}; +void() sham_swingl3 =[ $swingl3, sham_swingl4 ] {ai_charge(7);}; +void() sham_swingl4 =[ $swingl4, sham_swingl5 ] {ai_charge(3);}; +void() sham_swingl5 =[ $swingl5, sham_swingl6 ] {ai_charge(7);}; +void() sham_swingl6 =[ $swingl6, sham_swingl7 ] {ai_charge(9);}; +void() sham_swingl7 =[ $swingl7, sham_swingl8 ] {ai_charge(5); ShamClaw(10, 20, 250, 0);}; +void() sham_swingl8 =[ $swingl8, sham_swingl9 ] {ai_charge(4);}; +void() sham_swingl9 =[ $swingl9, sham_run1 ] { +ai_charge(8); +if (random()<0.5) + self.think = sham_swingr1; +}; + +void() sham_swingr1 =[ $swingr1, sham_swingr2 ] { +sound (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); +ai_charge(1);}; +void() sham_swingr2 =[ $swingr2, sham_swingr3 ] {ai_charge(8);}; +void() sham_swingr3 =[ $swingr3, sham_swingr4 ] {ai_charge(14);}; +void() sham_swingr4 =[ $swingr4, sham_swingr5 ] {ai_charge(7);}; +void() sham_swingr5 =[ $swingr5, sham_swingr6 ] {ai_charge(3);}; +void() sham_swingr6 =[ $swingr6, sham_swingr7 ] {ai_charge(6);}; +void() sham_swingr7 =[ $swingr7, sham_swingr8 ] {ai_charge(6); ShamClaw(10, 20, -250, 0);}; +void() sham_swingr8 =[ $swingr8, sham_swingr9 ] {ai_charge(3);}; +void() sham_swingr9 =[ $swingr9, sham_run1 ] {ai_charge(1); +ai_charge(10); +if (random()<0.5) + self.think = sham_swingl1; +}; + +void() sham_melee = +{ + local float chance; + + chance = random(); + if (chance > 0.6 || self.health == 600) + sham_smash1 (); + else if (chance > 0.3) + sham_swingr1 (); + else + sham_swingl1 (); +}; + + +//============================================================================ + +void() CastLightning = +{ + local vector org, dir; + + muzzleflash(); + ai_face (); + + org = self.origin + '0 0 40'; + + dir = self.enemy.origin + '0 0 16' - org; + dir = normalize (dir); + + traceline (org, self.origin + dir*600, TRUE, self); + + TE_lightning1(self, org, trace_endpos); + + LightningDamage (org, trace_endpos, self, 10, MOD_SHAMBLER); +}; + +void() sham_magic1 =[ $magic1, sham_magic2 ] {ai_face(); + sound (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM); +}; +void() sham_magic2 =[ $magic2, sham_magic3 ] {ai_face();}; +void() sham_magic3 =[ $magic3, sham_magic4 ] {ai_face();self.nextthink = time + 0.2; +local entity o; + +muzzleflash(); +ai_face(); +// TODO: Spawn as an effect +self.owner = spawn(); +o = self.owner; +setmodel (o, "progs/s_light.mdl"); +setorigin (o, self.origin); +o.angles = self.angles; +o.nextthink = time + 0.7; +o.think = SUB_Remove; +}; +void() sham_magic4 =[ $magic4, sham_magic5 ] +{ +self.effects = self.effects | EF_MUZZLEFLASH; +self.owner.frame = 1; +}; +void() sham_magic5 =[ $magic5, sham_magic6 ] +{ +self.effects = self.effects | EF_MUZZLEFLASH; +self.owner.frame = 2; +}; +void() sham_magic6 =[ $magic6, sham_magic9 ] +{ +remove (self.owner); +CastLightning(); +sound (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM); +}; +void() sham_magic9 =[ $magic9, sham_magic10 ] +{CastLightning();}; +void() sham_magic10 =[ $magic10, sham_magic11 ] +{CastLightning();}; +void() sham_magic11 =[ $magic11, sham_magic12 ] +{ +if (skill > 2) + CastLightning(); +}; +void() sham_magic12 =[ $magic12, sham_run1 ] {}; + + + +void() sham_pain1 =[ $pain1, sham_pain2 ] {}; +void() sham_pain2 =[ $pain2, sham_pain3 ] {}; +void() sham_pain3 =[ $pain3, sham_pain4 ] {}; +void() sham_pain4 =[ $pain4, sham_pain5 ] {}; +void() sham_pain5 =[ $pain5, sham_pain6 ] {}; +void() sham_pain6 =[ $pain6, sham_run1 ] {}; + +void(entity attacker, float damage) sham_pain = +{ + sound (self, CHAN_VOICE, "shambler/shurt2.wav", 1, ATTN_NORM); + + if (self.health <= 0) + return; // allready dying, don't go into pain frame + + if (random()*400 > damage) + return; // didn't flinch + + if (self.pain_finished > time) + return; + self.pain_finished = time + 2; + + sham_pain1 (); +}; + + +//============================================================================ + +void() sham_death1 =[ $death1, sham_death2 ] {}; +void() sham_death2 =[ $death2, sham_death3 ] {}; +void() sham_death3 =[ $death3, sham_death4 ] {self.solid = SOLID_NOT;}; +void() sham_death4 =[ $death4, sham_death5 ] {}; +void() sham_death5 =[ $death5, sham_death6 ] {}; +void() sham_death6 =[ $death6, sham_death7 ] {}; +void() sham_death7 =[ $death7, sham_death8 ] {}; +void() sham_death8 =[ $death8, sham_death9 ] {}; +void() sham_death9 =[ $death9, sham_death10 ] {}; +void() sham_death10 =[ $death10, sham_death11 ] {}; +void() sham_death11 =[ $death11, sham_death11 ] {}; + +void() sham_die = +{ +// check for gib + if (self.health < -60) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_shams.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); + return; + } + +// regular death + sound (self, CHAN_VOICE, "shambler/sdeath.wav", 1, ATTN_NORM); + sham_death1 (); +}; + +//============================================================================ + + +/*QUAKED monster_shambler (1 0 0) (-32 -32 -24) (32 32 64) Ambush +*/ +void() monster_shambler = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/shambler.mdl"); + precache_model ("progs/s_light.mdl"); + precache_model ("progs/h_shams.mdl"); + precache_model ("progs/bolt.mdl"); + + precache_sound ("shambler/sattck1.wav"); + precache_sound ("shambler/sboom.wav"); + precache_sound ("shambler/sdeath.wav"); + precache_sound ("shambler/shurt2.wav"); + precache_sound ("shambler/sidle.wav"); + precache_sound ("shambler/ssight.wav"); + precache_sound ("shambler/melee1.wav"); + precache_sound ("shambler/melee2.wav"); + precache_sound ("shambler/smack.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + setmodel (self, "progs/shambler.mdl"); + + setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); + self.health = 600; + + self.th_stand = sham_stand1; + self.th_walk = sham_walk1; + self.th_run = sham_run1; + self.th_die = sham_die; + self.th_melee = sham_melee; + self.th_missile = sham_magic1; + self.th_pain = sham_pain; + + walkmonster_start(); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/soldier.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/soldier.qc new file mode 100755 index 00000000..e9e31158 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/soldier.qc @@ -0,0 +1,281 @@ +/* +============================================================================== + +SOLDIER / PLAYER + +============================================================================== +*/ + +$cd id1/models/soldier3 +$origin 0 -6 24 +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 +$frame death9 death10 + +$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8 +$frame deathc9 deathc10 deathc11 + +$frame load1 load2 load3 load4 load5 load6 load7 load8 load9 load10 load11 + +$frame pain1 pain2 pain3 pain4 pain5 pain6 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10 +$frame painb11 painb12 painb13 painb14 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10 +$frame painc11 painc12 painc13 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 + +$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 shoot7 shoot8 shoot9 + +$frame prowl_1 prowl_2 prowl_3 prowl_4 prowl_5 prowl_6 prowl_7 prowl_8 +$frame prowl_9 prowl_10 prowl_11 prowl_12 prowl_13 prowl_14 prowl_15 prowl_16 +$frame prowl_17 prowl_18 prowl_19 prowl_20 prowl_21 prowl_22 prowl_23 prowl_24 + +/* +============================================================================== +SOLDIER CODE +============================================================================== +*/ + +void() laughs = +{ +local float r; +r = random(); +if (r <= 0.5) +sound (self, CHAN_AUTO, "soldier/laugh1.wav", 0.8, ATTN_NORM); +else if ( r <= 0.10) +sound (self, CHAN_AUTO, "soldier/laugh2.wav", 0.8, ATTN_NORM); +else +{} +}; +void() army_fire; + +void() army_stand1 =[ $stand1, army_stand2 ] {ai_stand();}; +void() army_stand2 =[ $stand2, army_stand3 ] {ai_stand();}; +void() army_stand3 =[ $stand3, army_stand4 ] {ai_stand();}; +void() army_stand4 =[ $stand4, army_stand5 ] {ai_stand();}; +void() army_stand5 =[ $stand5, army_stand6 ] {ai_stand();}; +void() army_stand6 =[ $stand6, army_stand7 ] {ai_stand();laughs();}; +void() army_stand7 =[ $stand7, army_stand8 ] {ai_stand();}; +void() army_stand8 =[ $stand8, army_stand1 ] {ai_stand();}; + +void() army_walk1 =[ $prowl_1, army_walk2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE); +ai_walk(1);}; +void() army_walk2 =[ $prowl_2, army_walk3 ] {ai_walk(1);}; +void() army_walk3 =[ $prowl_3, army_walk4 ] {ai_walk(1);}; +void() army_walk4 =[ $prowl_4, army_walk5 ] {ai_walk(1);}; +void() army_walk5 =[ $prowl_5, army_walk6 ] {ai_walk(2);}; +void() army_walk6 =[ $prowl_6, army_walk7 ] {ai_walk(3);}; +void() army_walk7 =[ $prowl_7, army_walk8 ] {ai_walk(4);}; +void() army_walk8 =[ $prowl_8, army_walk9 ] {ai_walk(4);}; +void() army_walk9 =[ $prowl_9, army_walk10 ] {ai_walk(2);}; +void() army_walk10 =[ $prowl_10, army_walk11 ] {ai_walk(2);}; +void() army_walk11 =[ $prowl_11, army_walk12 ] {ai_walk(2);}; +void() army_walk12 =[ $prowl_12, army_walk13 ] {ai_walk(1);}; +void() army_walk13 =[ $prowl_13, army_walk14 ] {ai_walk(0);}; +void() army_walk14 =[ $prowl_14, army_walk15 ] {ai_walk(1);}; +void() army_walk15 =[ $prowl_15, army_walk16 ] {ai_walk(1);}; +void() army_walk16 =[ $prowl_16, army_walk17 ] {ai_walk(1);}; +void() army_walk17 =[ $prowl_17, army_walk18 ] {ai_walk(3);}; +void() army_walk18 =[ $prowl_18, army_walk19 ] {ai_walk(3);}; +void() army_walk19 =[ $prowl_19, army_walk20 ] {ai_walk(3);}; +void() army_walk20 =[ $prowl_20, army_walk21 ] {ai_walk(3);}; +void() army_walk21 =[ $prowl_21, army_walk22 ] {ai_walk(2);}; +void() army_walk22 =[ $prowl_22, army_walk23 ] {ai_walk(1);}; +void() army_walk23 =[ $prowl_23, army_walk24 ] {ai_walk(1);}; +void() army_walk24 =[ $prowl_24, army_walk1 ] {ai_walk(1);}; + +void() army_run1 =[ $run1, army_run2 ] { +if (random() < 0.2) + sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE); +ai_run(11);}; +void() army_run2 =[ $run2, army_run3 ] {ai_run(15);}; +void() army_run3 =[ $run3, army_run4 ] {ai_run(10);}; +void() army_run4 =[ $run4, army_run5 ] {ai_run(10);}; +void() army_run5 =[ $run5, army_run6 ] {ai_run(8);}; +void() army_run6 =[ $run6, army_run7 ] {ai_run(15);}; +void() army_run7 =[ $run7, army_run8 ] {ai_run(10);}; +void() army_run8 =[ $run8, army_run1 ] {ai_run(8);}; + +void() army_atk1 =[ $shoot1, army_atk2 ] {ai_face();}; +void() army_atk2 =[ $shoot2, army_atk3 ] {ai_face();}; +void() army_atk3 =[ $shoot3, army_atk4 ] {ai_face();}; +void() army_atk4 =[ $shoot4, army_atk5 ] {ai_face();}; +void() army_atk5 =[ $shoot5, army_atk6 ] {ai_face(); army_fire(); muzzleflash();}; +void() army_atk6 =[ $shoot6, army_atk7 ] {ai_face();}; +void() army_atk7 =[ $shoot7, army_atk8 ] {ai_face();SUB_CheckRefire (army_atk1);}; +void() army_atk8 =[ $shoot8, army_atk9 ] {ai_face();}; +void() army_atk9 =[ $shoot9, army_run1 ] {ai_face();}; + + +void() army_pain1 =[ $pain1, army_pain2 ] {}; +void() army_pain2 =[ $pain2, army_pain3 ] {}; +void() army_pain3 =[ $pain3, army_pain4 ] {}; +void() army_pain4 =[ $pain4, army_pain5 ] {}; +void() army_pain5 =[ $pain5, army_pain6 ] {}; +void() army_pain6 =[ $pain6, army_run1 ] {ai_pain(1);}; + +void() army_painb1 =[ $painb1, army_painb2 ] {}; +void() army_painb2 =[ $painb2, army_painb3 ] {ai_painforward(13);}; +void() army_painb3 =[ $painb3, army_painb4 ] {ai_painforward(9);}; +void() army_painb4 =[ $painb4, army_painb5 ] {}; +void() army_painb5 =[ $painb5, army_painb6 ] {}; +void() army_painb6 =[ $painb6, army_painb7 ] {}; +void() army_painb7 =[ $painb7, army_painb8 ] {}; +void() army_painb8 =[ $painb8, army_painb9 ] {}; +void() army_painb9 =[ $painb9, army_painb10] {}; +void() army_painb10=[ $painb10, army_painb11] {}; +void() army_painb11=[ $painb11, army_painb12] {}; +void() army_painb12=[ $painb12, army_painb13] {ai_pain(2);}; +void() army_painb13=[ $painb13, army_painb14] {}; +void() army_painb14=[ $painb14, army_run1 ] {}; + +void() army_painc1 =[ $painc1, army_painc2 ] {}; +void() army_painc2 =[ $painc2, army_painc3 ] {ai_pain(1);}; +void() army_painc3 =[ $painc3, army_painc4 ] {}; +void() army_painc4 =[ $painc4, army_painc5 ] {}; +void() army_painc5 =[ $painc5, army_painc6 ] {ai_painforward(1);}; +void() army_painc6 =[ $painc6, army_painc7 ] {ai_painforward(1);}; +void() army_painc7 =[ $painc7, army_painc8 ] {}; +void() army_painc8 =[ $painc8, army_painc9 ] {ai_pain(1);}; +void() army_painc9 =[ $painc9, army_painc10] {ai_painforward(4);}; +void() army_painc10=[ $painc10, army_painc11] {ai_painforward(3);}; +void() army_painc11=[ $painc11, army_painc12] {ai_painforward(6);}; +void() army_painc12=[ $painc12, army_painc13] {ai_painforward(8);}; +void() army_painc13=[ $painc13, army_run1] {}; + +void(entity attacker, float damage) army_pain = +{ + local float r; + + if (self.pain_finished > time) + return; + + r = random(); + + if (r < 0.2) + { + self.pain_finished = time + 0.6; + army_pain1 (); + sound (self, CHAN_VOICE, "soldier/pain1.wav", 1, ATTN_NORM); + } + else if (r < 0.6) + { + self.pain_finished = time + 1.1; + army_painb1 (); + sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM); + } + else + { + self.pain_finished = time + 1.1; + army_painc1 (); + sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM); + } +}; + + +void() army_fire = +{ + local vector dir; + local entity en; + + ai_face(); + + sound (self, CHAN_WEAPON, "weapons/ppist.wav", 1, ATTN_NORM); + +// fire somewhat behind the player, so a dodging player is harder to hit + en = self.enemy; + + dir = en.origin - en.velocity*0.2; + dir = normalize (dir - self.origin); + + FireBullets (1, dir, '0.1 0.1 0', MOD_SOLDIER); +}; + + + +void() army_die1 =[ $death1, army_die2 ] {}; +void() army_die2 =[ $death2, army_die3 ] {}; +void() army_die3 =[ $death3, army_die4 ] {self.solid = SOLID_NOT;DropBackpack();}; +void() army_die4 =[ $death4, army_die5 ] {}; +void() army_die5 =[ $death5, army_die6 ] {}; +void() army_die6 =[ $death6, army_die7 ] {}; +void() army_die7 =[ $death7, army_die8 ] {}; +void() army_die8 =[ $death8, army_die9 ] {}; +void() army_die9 =[ $death9, army_die10 ] {}; +void() army_die10 =[ $death10, army_die10 ] {}; + +void() army_cdie1 =[ $deathc1, army_cdie2 ] {}; +void() army_cdie2 =[ $deathc2, army_cdie3 ] {ai_back(5);}; +void() army_cdie3 =[ $deathc3, army_cdie4 ] {self.solid = SOLID_NOT;DropBackpack();ai_back(4);remove(self);}; +void() army_cdie4 =[ $deathc4, army_cdie5 ] {ai_back(13);}; +void() army_cdie5 =[ $deathc5, army_cdie6 ] {ai_back(3);}; +void() army_cdie6 =[ $deathc6, army_cdie7 ] {ai_back(4);}; +void() army_cdie7 =[ $deathc7, army_cdie8 ] {}; +void() army_cdie8 =[ $deathc8, army_cdie9 ] {}; +void() army_cdie9 =[ $deathc9, army_cdie10 ] {}; +void() army_cdie10 =[ $deathc10, army_cdie11 ] {}; +void() army_cdie11 =[ $deathc11, army_cdie11 ] {}; + + +void() army_die = +{ +// check for gib + +// regular death + sound (self, CHAN_VOICE, "soldier/death1.wav", 1, ATTN_NORM); + if (random() < 0.5) + army_die1 (); + else + army_cdie1 (); +}; + + +/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_army = +{ + if (deathmatch) + { + remove(self); + } + precache_model ("progs/soldier.mdl"); + precache_model ("progs/h_guard.mdl"); + + precache_sound ("soldier/laugh1.wav"); + precache_sound ("soldier/laugh2.wav"); + precache_sound ("soldier/death1.wav"); + precache_sound ("soldier/idle.wav"); + precache_sound ("soldier/pain1.wav"); + precache_sound ("soldier/pain2.wav"); + precache_sound ("soldier/sight1.wav"); + + precache_sound ("player/udeath.wav"); // gib death + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/soldier.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 130; + + self.th_stand = army_stand1; + self.th_walk = army_walk1; + self.th_run = army_run1; + self.th_missile = army_atk1; + self.th_pain = army_pain; + self.th_die = army_die; + + self.ammo_shells_real = 5; // drop 5 shells on death + + walkmonster_start (); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/tarbaby.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/tarbaby.qc new file mode 100755 index 00000000..430bdba2 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/tarbaby.qc @@ -0,0 +1,212 @@ +/* +============================================================================== + +BLOB + +============================================================================== +*/ + +$cd id1/models/tarbaby +$origin 0 0 24 +$base base + +$skin skin + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 +$frame walk11 walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19 +$frame walk20 walk21 walk22 walk23 walk24 walk25 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 run13 +$frame run14 run15 run16 run17 run18 run19 run20 run21 run22 run23 +$frame run24 run25 + +$frame jump1 jump2 jump3 jump4 jump5 jump6 + +$frame fly1 fly2 fly3 fly4 + +$frame exp + +void() tbaby_stand1 =[ $walk1, tbaby_stand1 ] {ai_stand();}; + +void() tbaby_hang1 =[ $walk1, tbaby_hang1 ] {ai_stand();}; + +void() tbaby_walk1 =[ $walk1, tbaby_walk2 ] {ai_turn();}; +void() tbaby_walk2 =[ $walk2, tbaby_walk3 ] {ai_turn();}; +void() tbaby_walk3 =[ $walk3, tbaby_walk4 ] {ai_turn();}; +void() tbaby_walk4 =[ $walk4, tbaby_walk5 ] {ai_turn();}; +void() tbaby_walk5 =[ $walk5, tbaby_walk6 ] {ai_turn();}; +void() tbaby_walk6 =[ $walk6, tbaby_walk7 ] {ai_turn();}; +void() tbaby_walk7 =[ $walk7, tbaby_walk8 ] {ai_turn();}; +void() tbaby_walk8 =[ $walk8, tbaby_walk9 ] {ai_turn();}; +void() tbaby_walk9 =[ $walk9, tbaby_walk10 ] {ai_turn();}; +void() tbaby_walk10 =[ $walk10, tbaby_walk11 ] {ai_turn();}; +void() tbaby_walk11 =[ $walk11, tbaby_walk12 ] {ai_walk(2);}; +void() tbaby_walk12 =[ $walk12, tbaby_walk13 ] {ai_walk(2);}; +void() tbaby_walk13 =[ $walk13, tbaby_walk14 ] {ai_walk(2);}; +void() tbaby_walk14 =[ $walk14, tbaby_walk15 ] {ai_walk(2);}; +void() tbaby_walk15 =[ $walk15, tbaby_walk16 ] {ai_walk(2);}; +void() tbaby_walk16 =[ $walk16, tbaby_walk17 ] {ai_walk(2);}; +void() tbaby_walk17 =[ $walk17, tbaby_walk18 ] {ai_walk(2);}; +void() tbaby_walk18 =[ $walk18, tbaby_walk19 ] {ai_walk(2);}; +void() tbaby_walk19 =[ $walk19, tbaby_walk20 ] {ai_walk(2);}; +void() tbaby_walk20 =[ $walk20, tbaby_walk21 ] {ai_walk(2);}; +void() tbaby_walk21 =[ $walk21, tbaby_walk22 ] {ai_walk(2);}; +void() tbaby_walk22 =[ $walk22, tbaby_walk23 ] {ai_walk(2);}; +void() tbaby_walk23 =[ $walk23, tbaby_walk24 ] {ai_walk(2);}; +void() tbaby_walk24 =[ $walk24, tbaby_walk25 ] {ai_walk(2);}; +void() tbaby_walk25 =[ $walk25, tbaby_walk1 ] {ai_walk(2);}; + +void() tbaby_run1 =[ $run1, tbaby_run2 ] {ai_face();}; +void() tbaby_run2 =[ $run2, tbaby_run3 ] {ai_face();}; +void() tbaby_run3 =[ $run3, tbaby_run4 ] {ai_face();}; +void() tbaby_run4 =[ $run4, tbaby_run5 ] {ai_face();}; +void() tbaby_run5 =[ $run5, tbaby_run6 ] {ai_face();}; +void() tbaby_run6 =[ $run6, tbaby_run7 ] {ai_face();}; +void() tbaby_run7 =[ $run7, tbaby_run8 ] {ai_face();}; +void() tbaby_run8 =[ $run8, tbaby_run9 ] {ai_face();}; +void() tbaby_run9 =[ $run9, tbaby_run10 ] {ai_face();}; +void() tbaby_run10 =[ $run10, tbaby_run11 ] {ai_face();}; +void() tbaby_run11 =[ $run11, tbaby_run12 ] {ai_run(2);}; +void() tbaby_run12 =[ $run12, tbaby_run13 ] {ai_run(2);}; +void() tbaby_run13 =[ $run13, tbaby_run14 ] {ai_run(2);}; +void() tbaby_run14 =[ $run14, tbaby_run15 ] {ai_run(2);}; +void() tbaby_run15 =[ $run15, tbaby_run16 ] {ai_run(2);}; +void() tbaby_run16 =[ $run16, tbaby_run17 ] {ai_run(2);}; +void() tbaby_run17 =[ $run17, tbaby_run18 ] {ai_run(2);}; +void() tbaby_run18 =[ $run18, tbaby_run19 ] {ai_run(2);}; +void() tbaby_run19 =[ $run19, tbaby_run20 ] {ai_run(2);}; +void() tbaby_run20 =[ $run20, tbaby_run21 ] {ai_run(2);}; +void() tbaby_run21 =[ $run21, tbaby_run22 ] {ai_run(2);}; +void() tbaby_run22 =[ $run22, tbaby_run23 ] {ai_run(2);}; +void() tbaby_run23 =[ $run23, tbaby_run24 ] {ai_run(2);}; +void() tbaby_run24 =[ $run24, tbaby_run25 ] {ai_run(2);}; +void() tbaby_run25 =[ $run25, tbaby_run1 ] {ai_run(2);}; + + +//============================================================================ + + +void() tbaby_jump1; + +void() Tar_JumpTouch = +{ + local float ldmg; + + if (other.takedamage && other.classname != self.classname) + { + if ( vlen(self.velocity) > 400 ) + { + ldmg = 10 + 10*random(); + T_Damage (other, self, self, ldmg, MOD_TARBABY); + sound (self, CHAN_WEAPON, "blob/hit1.wav", 1, ATTN_NORM); + } + } + else + sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM); + + + if (!checkbottom(self)) + { + if (self.flags & FL_ONGROUND) + { // jump randomly to not get hung up + self.touch = SUB_Null; + self.think = tbaby_run1; + self.movetype = MOVETYPE_STEP; + self.nextthink = time + 0.1; + } + return; // not on ground yet + } + + self.touch = SUB_Null; + self.think = tbaby_jump1; + self.nextthink = time + 0.1; +}; + +void() tbaby_jump5; + +void() tbaby_fly1 =[ $fly1, tbaby_fly2 ] {}; +void() tbaby_fly2 =[ $fly2, tbaby_fly3 ] {}; +void() tbaby_fly3 =[ $fly3, tbaby_fly4 ] {}; +void() tbaby_fly4 =[ $fly4, tbaby_fly1 ] { +self.cnt = self.cnt + 1; +if (self.cnt == 4) +{ +//dprint ("spawn hop\n"); +tbaby_jump5 (); +} +}; + +void() tbaby_jump1 =[ $jump1, tbaby_jump2 ] {ai_face();}; +void() tbaby_jump2 =[ $jump2, tbaby_jump3 ] {ai_face();}; +void() tbaby_jump3 =[ $jump3, tbaby_jump4 ] {ai_face();}; +void() tbaby_jump4 =[ $jump4, tbaby_jump5 ] {ai_face();}; +void() tbaby_jump5 =[ $jump5, tbaby_jump6 ] +{ + self.movetype = MOVETYPE_BOUNCE; + self.touch = Tar_JumpTouch; + makevectors (self.angles); + self.origin_z = self.origin_z + 1; + self.velocity = v_forward * 600 + '0 0 200'; + self.velocity_z = self.velocity_z + random()*150; + if (self.flags & FL_ONGROUND) + self.flags = self.flags - FL_ONGROUND; + self.cnt = 0; +}; +void() tbaby_jump6 =[ $jump6,tbaby_fly1 ] {}; + + + +//============================================================================= + +void() tbaby_die1 =[ $exp, tbaby_die2 ] { +self.takedamage = DAMAGE_NO; +}; +void() tbaby_die2 =[ $exp, tbaby_run1 ] +{ + T_RadiusDamage (self, self, 120, 160, world, MOD_TARBABY); + + sound (self, CHAN_VOICE, "blob/death1.wav", 1, ATTN_NORM); + self.origin = self.origin - 8*normalize(self.velocity); + + TE_tarexplosion(self.origin); + CreateExplosion(self.origin); + remove(self); +}; + +//============================================================================= + + +/*QUAKED monster_tarbaby (1 0 0) (-16 -16 -24) (16 16 24) Ambush +*/ +void() monster_tarbaby = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model2 ("progs/tarbaby.mdl"); + + precache_sound2 ("blob/death1.wav"); + precache_sound2 ("blob/hit1.wav"); + precache_sound2 ("blob/land1.wav"); + precache_sound2 ("blob/sight1.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/tarbaby.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 80; + + self.th_stand = tbaby_stand1; + self.th_walk = tbaby_walk1; + self.th_run = tbaby_run1; + self.th_missile = tbaby_jump1; + self.th_melee = tbaby_jump1; + self.th_die = tbaby_die1; + + walkmonster_start (); +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/wizard.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/wizard.qc new file mode 100755 index 00000000..fa38681a --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/wizard.qc @@ -0,0 +1,320 @@ +/* +============================================================================== + +WIZARD + +============================================================================== +*/ + +$cd id1/models/a_wizard +$origin 0 0 24 +$base wizbase +$skin wizbase + +$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8 +$frame hover9 hover10 hover11 hover12 hover13 hover14 hover15 + +$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10 +$frame fly11 fly12 fly13 fly14 + +$frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7 +$frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13 + +$frame pain1 pain2 pain3 pain4 + +$frame death1 death2 death3 death4 death5 death6 death7 death8 + +/* +============================================================================== + +WIZARD + +If the player moves behind cover before the missile is launched, launch it +at the last visible spot with no velocity leading, in hopes that the player +will duck back out and catch it. +============================================================================== +*/ + +void() wiz_run1; +void() wiz_side1; + +/* +================= +WizardCheckAttack +================= +*/ +BOOL(float enemy_range) WizardCheckAttack = +{ + local vector spot1, spot2; + local entity targ; + local float chance; + + if (time < self.attack_finished) + return FALSE; + + if (enemy_range == RANGE_FAR) + { + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + wiz_run1 (); + } + return FALSE; + } + + targ = self.enemy; + +// see if any entities are in the way of the shot + spot1 = self.origin + self.view_ofs; + spot2 = targ.origin + targ.view_ofs; + + traceline (spot1, spot2, FALSE, self); + + if (trace_ent != targ) + { // don't have a clear shot, so move to a side + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + wiz_run1 (); + } + return FALSE; + } + + if (enemy_range == RANGE_MELEE) + chance = 0.9; + else if (enemy_range == RANGE_NEAR) + chance = 0.6; + else if (enemy_range == RANGE_MID) + chance = 0.2; + else + chance = 0; + + if (random () < chance) + { + self.attack_state = AS_MISSILE; + return TRUE; + } + + if (enemy_range == RANGE_MID) + { + if (self.attack_state != AS_STRAIGHT) + { + self.attack_state = AS_STRAIGHT; + wiz_run1 (); + } + } + else + { + if (self.attack_state != AS_SLIDING) + { + self.attack_state = AS_SLIDING; + wiz_side1 (); + } + } + + return FALSE; +}; + +/* +================= +WizardAttackFinished +================= +*/ +void() WizardAttackFinished = +{ + if (range(self.enemy) >= RANGE_MID || !visible(self.enemy)) + { + self.attack_state = AS_STRAIGHT; + self.think = wiz_run1; + } + else + { + self.attack_state = AS_SLIDING; + self.think = wiz_side1; + } +}; + +/* +============================================================================== + +FAST ATTACKS + +============================================================================== +*/ + +void(float side) Wiz_FastFire = +{ + local vector org, vec; + + muzzleflash(); + sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM); + + makevectors (self.angles); + org = self.origin + '0 0 30' + v_forward*14 + v_right*side*14; + vec = normalize(self.enemy.origin - v_right*side*13 - org) * 600; + + PRJ_FireProjectile (self, "progs/w_spike.mdl", org, vec, PE_WIZSPIKE, 9, MOD_WIZARD, 6); +}; + +void() Wiz_idlesound = +{ + local float wr; + + if (self.wizardidle < time) + { + wr = random(); + + if (wr > 0.9) + sound (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE); + else if (wr < 0.3) + sound (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE); + + self.wizardidle = time + 2; + } + + return; +}; + +void() wiz_stand1 =[ $hover1, wiz_stand2 ] {ai_stand();}; +void() wiz_stand2 =[ $hover2, wiz_stand3 ] {ai_stand();}; +void() wiz_stand3 =[ $hover3, wiz_stand4 ] {ai_stand();}; +void() wiz_stand4 =[ $hover4, wiz_stand5 ] {ai_stand();}; +void() wiz_stand5 =[ $hover5, wiz_stand6 ] {ai_stand();}; +void() wiz_stand6 =[ $hover6, wiz_stand7 ] {ai_stand();}; +void() wiz_stand7 =[ $hover7, wiz_stand8 ] {ai_stand();}; +void() wiz_stand8 =[ $hover8, wiz_stand1 ] {ai_stand();}; + +void() wiz_walk1 =[ $hover1, wiz_walk2 ] {ai_walk(8); +Wiz_idlesound();}; +void() wiz_walk2 =[ $hover2, wiz_walk3 ] {ai_walk(8);}; +void() wiz_walk3 =[ $hover3, wiz_walk4 ] {ai_walk(8);}; +void() wiz_walk4 =[ $hover4, wiz_walk5 ] {ai_walk(8);}; +void() wiz_walk5 =[ $hover5, wiz_walk6 ] {ai_walk(8);}; +void() wiz_walk6 =[ $hover6, wiz_walk7 ] {ai_walk(8);}; +void() wiz_walk7 =[ $hover7, wiz_walk8 ] {ai_walk(8);}; +void() wiz_walk8 =[ $hover8, wiz_walk1 ] {ai_walk(8);}; + +void() wiz_side1 =[ $hover1, wiz_side2 ] {ai_run(8); +Wiz_idlesound();}; +void() wiz_side2 =[ $hover2, wiz_side3 ] {ai_run(8);}; +void() wiz_side3 =[ $hover3, wiz_side4 ] {ai_run(8);}; +void() wiz_side4 =[ $hover4, wiz_side5 ] {ai_run(8);}; +void() wiz_side5 =[ $hover5, wiz_side6 ] {ai_run(8);}; +void() wiz_side6 =[ $hover6, wiz_side7 ] {ai_run(8);}; +void() wiz_side7 =[ $hover7, wiz_side8 ] {ai_run(8);}; +void() wiz_side8 =[ $hover8, wiz_side1 ] {ai_run(8);}; + +void() wiz_run1 =[ $fly1, wiz_run2 ] {ai_run(16); +Wiz_idlesound(); +}; +void() wiz_run2 =[ $fly2, wiz_run3 ] {ai_run(16);}; +void() wiz_run3 =[ $fly3, wiz_run4 ] {ai_run(16);}; +void() wiz_run4 =[ $fly4, wiz_run5 ] {ai_run(16);}; +void() wiz_run5 =[ $fly5, wiz_run6 ] {ai_run(16);}; +void() wiz_run6 =[ $fly6, wiz_run7 ] {ai_run(16);}; +void() wiz_run7 =[ $fly7, wiz_run8 ] {ai_run(16);}; +void() wiz_run8 =[ $fly8, wiz_run9 ] {ai_run(16);}; +void() wiz_run9 =[ $fly9, wiz_run10 ] {ai_run(16);}; +void() wiz_run10 =[ $fly10, wiz_run11 ] {ai_run(16);}; +void() wiz_run11 =[ $fly11, wiz_run12 ] {ai_run(16);}; +void() wiz_run12 =[ $fly12, wiz_run13 ] {ai_run(16);}; +void() wiz_run13 =[ $fly13, wiz_run14 ] {ai_run(16);}; +void() wiz_run14 =[ $fly14, wiz_run1 ] {ai_run(16);}; + +void() wiz_fast1 =[ $magatt1, wiz_fast2 ] {ai_face();}; +void() wiz_fast2 =[ $magatt2, wiz_fast3 ] {ai_face();}; +void() wiz_fast3 =[ $magatt3, wiz_fast4 ] {ai_face();}; +void() wiz_fast4 =[ $magatt4, wiz_fast5 ] {ai_face();Wiz_FastFire(-1);}; +void() wiz_fast5 =[ $magatt5, wiz_fast6 ] {ai_face();}; +void() wiz_fast6 =[ $magatt6, wiz_fast7 ] {ai_face();}; +void() wiz_fast7 =[ $magatt5, wiz_fast8 ] {ai_face();}; +void() wiz_fast8 =[ $magatt4, wiz_fast9 ] {ai_face();}; +void() wiz_fast9 =[ $magatt3, wiz_fast10 ] {ai_face();Wiz_FastFire(1);}; +void() wiz_fast10 =[ $magatt2, wiz_run1 ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();}; + +void() wiz_pain1 =[ $pain1, wiz_pain2 ] {}; +void() wiz_pain2 =[ $pain2, wiz_pain3 ] {}; +void() wiz_pain3 =[ $pain3, wiz_pain4 ] {}; +void() wiz_pain4 =[ $pain4, wiz_run1 ] {}; + +void() wiz_death1 =[ $death1, wiz_death2 ] { + +self.velocity_x = -200 + 400*random(); +self.velocity_y = -200 + 400*random(); +self.velocity_z = 100 + 100*random(); +self.flags = self.flags - (self.flags & FL_ONGROUND); +sound (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM); +}; +void() wiz_death2 =[ $death2, wiz_death3 ] {}; +void() wiz_death3 =[ $death3, wiz_death4 ]{self.solid = SOLID_NOT;}; +void() wiz_death4 =[ $death4, wiz_death5 ] {}; +void() wiz_death5 =[ $death5, wiz_death6 ] {}; +void() wiz_death6 =[ $death6, wiz_death7 ] {}; +void() wiz_death7 =[ $death7, wiz_death8 ] {}; +void() wiz_death8 =[ $death8, wiz_death8 ] {}; + +void() wiz_die = +{ +// check for gib + if (self.health < -40) + { + sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_wizard.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + return; + } + + wiz_death1 (); +}; + + +void(entity attacker, float damage) Wiz_Pain = +{ + sound (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM); + if (random()*70 > damage) + return; // didn't flinch + + wiz_pain1 (); +}; + +/*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) Ambush +*/ +void() monster_wizard = +{ + if (deathmatch) + { + remove(self); + return; + } + precache_model ("progs/wizard.mdl"); + precache_model ("progs/h_wizard.mdl"); + precache_model ("progs/w_spike.mdl"); + + precache_sound ("wizard/hit.wav"); // used by c code + precache_sound ("wizard/wattack.wav"); + precache_sound ("wizard/wdeath.wav"); + precache_sound ("wizard/widle1.wav"); + precache_sound ("wizard/widle2.wav"); + precache_sound ("wizard/wpain.wav"); + precache_sound ("wizard/wsight.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/wizard.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 80; + + self.th_stand = wiz_stand1; + self.th_walk = wiz_walk1; + self.th_run = wiz_run1; + self.th_missile = wiz_fast1; + self.th_pain = Wiz_Pain; + self.th_die = wiz_die; + + flymonster_start (); +}; + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/zombie.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/zombie.qc new file mode 100755 index 00000000..9a1c0a46 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/quakemons/zombie.qc @@ -0,0 +1,473 @@ +/* +============================================================================== + +ZOMBIE + +============================================================================== +*/ +$cd id1/models/zombie + +$origin 0 0 24 + +$base base +$skin skin + +$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 +$frame stand9 stand10 stand11 stand12 stand13 stand14 stand15 + +$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11 +$frame walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19 + +$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 +$frame run13 run14 run15 run16 run17 run18 + +$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8 atta9 atta10 atta11 +$frame atta12 atta13 + +$frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8 attb9 attb10 attb11 +$frame attb12 attb13 attb14 + +$frame attc1 attc2 attc3 attc4 attc5 attc6 attc7 attc8 attc9 attc10 attc11 +$frame attc12 + +$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10 +$frame paina11 paina12 + +$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10 +$frame painb11 painb12 painb13 painb14 painb15 painb16 painb17 painb18 painb19 +$frame painb20 painb21 painb22 painb23 painb24 painb25 painb26 painb27 painb28 + +$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10 +$frame painc11 painc12 painc13 painc14 painc15 painc16 painc17 painc18 + +$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10 +$frame paind11 paind12 paind13 + +$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10 +$frame paine11 paine12 paine13 paine14 paine15 paine16 paine17 paine18 paine19 +$frame paine20 paine21 paine22 paine23 paine24 paine25 paine26 paine27 paine28 +$frame paine29 paine30 + +$frame cruc_1 cruc_2 cruc_3 cruc_4 cruc_5 cruc_6 + +float SPAWN_CRUCIFIED = 1; + +//============================================================================= + +void() zombie_stand1 =[ $stand1, zombie_stand2 ] {ai_stand();}; +void() zombie_stand2 =[ $stand2, zombie_stand3 ] {ai_stand();}; +void() zombie_stand3 =[ $stand3, zombie_stand4 ] {ai_stand();}; +void() zombie_stand4 =[ $stand4, zombie_stand5 ] {ai_stand();}; +void() zombie_stand5 =[ $stand5, zombie_stand6 ] {ai_stand();}; +void() zombie_stand6 =[ $stand6, zombie_stand7 ] {ai_stand();}; +void() zombie_stand7 =[ $stand7, zombie_stand8 ] {ai_stand();}; +void() zombie_stand8 =[ $stand8, zombie_stand9 ] {ai_stand();}; +void() zombie_stand9 =[ $stand9, zombie_stand10 ] {ai_stand();}; +void() zombie_stand10 =[ $stand10, zombie_stand11 ] {ai_stand();}; +void() zombie_stand11 =[ $stand11, zombie_stand12 ] {ai_stand();}; +void() zombie_stand12 =[ $stand12, zombie_stand13 ] {ai_stand();}; +void() zombie_stand13 =[ $stand13, zombie_stand14 ] {ai_stand();}; +void() zombie_stand14 =[ $stand14, zombie_stand15 ] {ai_stand();}; +void() zombie_stand15 =[ $stand15, zombie_stand1 ] {ai_stand();}; + +void() zombie_cruc1 = [ $cruc_1, zombie_cruc2 ] { +if (random() < 0.1) + sound (self, CHAN_VOICE, "zombie/idle_w2.wav", 1, ATTN_STATIC);}; +void() zombie_cruc2 = [ $cruc_2, zombie_cruc3 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc3 = [ $cruc_3, zombie_cruc4 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc4 = [ $cruc_4, zombie_cruc5 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc5 = [ $cruc_5, zombie_cruc6 ] {self.nextthink = time + 0.1 + random()*0.1;}; +void() zombie_cruc6 = [ $cruc_6, zombie_cruc1 ] {self.nextthink = time + 0.1 + random()*0.1;}; + +void() zombie_walk1 =[ $walk1, zombie_walk2 ] {ai_walk(0);}; +void() zombie_walk2 =[ $walk2, zombie_walk3 ] {ai_walk(2);}; +void() zombie_walk3 =[ $walk3, zombie_walk4 ] {ai_walk(3);}; +void() zombie_walk4 =[ $walk4, zombie_walk5 ] {ai_walk(2);}; +void() zombie_walk5 =[ $walk5, zombie_walk6 ] {ai_walk(1);}; +void() zombie_walk6 =[ $walk6, zombie_walk7 ] {ai_walk(0);}; +void() zombie_walk7 =[ $walk7, zombie_walk8 ] {ai_walk(0);}; +void() zombie_walk8 =[ $walk8, zombie_walk9 ] {ai_walk(0);}; +void() zombie_walk9 =[ $walk9, zombie_walk10 ] {ai_walk(0);}; +void() zombie_walk10 =[ $walk10, zombie_walk11 ] {ai_walk(0);}; +void() zombie_walk11 =[ $walk11, zombie_walk12 ] {ai_walk(2);}; +void() zombie_walk12 =[ $walk12, zombie_walk13 ] {ai_walk(2);}; +void() zombie_walk13 =[ $walk13, zombie_walk14 ] {ai_walk(1);}; +void() zombie_walk14 =[ $walk14, zombie_walk15 ] {ai_walk(0);}; +void() zombie_walk15 =[ $walk15, zombie_walk16 ] {ai_walk(0);}; +void() zombie_walk16 =[ $walk16, zombie_walk17 ] {ai_walk(0);}; +void() zombie_walk17 =[ $walk17, zombie_walk18 ] {ai_walk(0);}; +void() zombie_walk18 =[ $walk18, zombie_walk19 ] {ai_walk(0);}; +void() zombie_walk19 =[ $walk19, zombie_walk1 ] { +ai_walk(0); +if (random() < 0.2) + sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);}; + +void() zombie_run1 =[ $run1, zombie_run2 ] {ai_run(1);self.inpain = 0;}; +void() zombie_run2 =[ $run2, zombie_run3 ] {ai_run(1);}; +void() zombie_run3 =[ $run3, zombie_run4 ] {ai_run(0);}; +void() zombie_run4 =[ $run4, zombie_run5 ] {ai_run(1);}; +void() zombie_run5 =[ $run5, zombie_run6 ] {ai_run(2);}; +void() zombie_run6 =[ $run6, zombie_run7 ] {ai_run(3);}; +void() zombie_run7 =[ $run7, zombie_run8 ] {ai_run(4);}; +void() zombie_run8 =[ $run8, zombie_run9 ] {ai_run(4);}; +void() zombie_run9 =[ $run9, zombie_run10 ] {ai_run(2);}; +void() zombie_run10 =[ $run10, zombie_run11 ] {ai_run(0);}; +void() zombie_run11 =[ $run11, zombie_run12 ] {ai_run(0);}; +void() zombie_run12 =[ $run12, zombie_run13 ] {ai_run(0);}; +void() zombie_run13 =[ $run13, zombie_run14 ] {ai_run(2);}; +void() zombie_run14 =[ $run14, zombie_run15 ] {ai_run(4);}; +void() zombie_run15 =[ $run15, zombie_run16 ] {ai_run(6);}; +void() zombie_run16 =[ $run16, zombie_run17 ] {ai_run(7);}; +void() zombie_run17 =[ $run17, zombie_run18 ] {ai_run(3);}; +void() zombie_run18 =[ $run18, zombie_run1 ] { +ai_run(8); +if (random() < 0.2) + sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE); +if (random() > 0.8) + sound (self, CHAN_VOICE, "zombie/z_idle1.wav", 1, ATTN_IDLE); +}; + +/* +============================================================================= + +ATTACKS + +============================================================================= +*/ + +/* +================ +ZombieFireGrenade +================ +*/ +void(vector st) ZombieFireGrenade = +{ + local vector org, vel; + + sound (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM); + + org = self.origin + st_x * v_forward + st_y * v_right + (st_z - 24) * v_up; + vel = normalize(self.enemy.origin - org) * 600; + vel_z = 200; + PRJ_FireProjectile(self, "progs/zom_gib.mdl", org, vel, PE_ZOMBIEGIB, 10, MOD_ZOMBIE, 2.5); + PRJ_SetTossedProjectile(); +}; + + +void() zombie_atta1 =[ $atta1, zombie_atta2 ] {ai_face();}; +void() zombie_atta2 =[ $atta2, zombie_atta3 ] {ai_face();}; +void() zombie_atta3 =[ $atta3, zombie_atta4 ] {ai_face();}; +void() zombie_atta4 =[ $atta4, zombie_atta5 ] {ai_face();}; +void() zombie_atta5 =[ $atta5, zombie_atta6 ] {ai_face();}; +void() zombie_atta6 =[ $atta6, zombie_atta7 ] {ai_face();}; +void() zombie_atta7 =[ $atta7, zombie_atta8 ] {ai_face();}; +void() zombie_atta8 =[ $atta8, zombie_atta9 ] {ai_face();}; +void() zombie_atta9 =[ $atta9, zombie_atta10 ] {ai_face();}; +void() zombie_atta10 =[ $atta10, zombie_atta11 ] {ai_face();}; +void() zombie_atta11 =[ $atta11, zombie_atta12 ] {ai_face();}; +void() zombie_atta12 =[ $atta12, zombie_atta13 ] {ai_face();}; +void() zombie_atta13 =[ $atta13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -22 30');}; + +void() zombie_attb1 =[ $attb1, zombie_attb2 ] {ai_face();}; +void() zombie_attb2 =[ $attb2, zombie_attb3 ] {ai_face();}; +void() zombie_attb3 =[ $attb3, zombie_attb4 ] {ai_face();}; +void() zombie_attb4 =[ $attb4, zombie_attb5 ] {ai_face();}; +void() zombie_attb5 =[ $attb5, zombie_attb6 ] {ai_face();}; +void() zombie_attb6 =[ $attb6, zombie_attb7 ] {ai_face();}; +void() zombie_attb7 =[ $attb7, zombie_attb8 ] {ai_face();}; +void() zombie_attb8 =[ $attb8, zombie_attb9 ] {ai_face();}; +void() zombie_attb9 =[ $attb9, zombie_attb10 ] {ai_face();}; +void() zombie_attb10 =[ $attb10, zombie_attb11 ] {ai_face();}; +void() zombie_attb11 =[ $attb11, zombie_attb12 ] {ai_face();}; +void() zombie_attb12 =[ $attb12, zombie_attb13 ] {ai_face();}; +void() zombie_attb13 =[ $attb13, zombie_attb14 ] {ai_face();}; +void() zombie_attb14 =[ $attb13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -24 29');}; + +void() zombie_attc1 =[ $attc1, zombie_attc2 ] {ai_face();}; +void() zombie_attc2 =[ $attc2, zombie_attc3 ] {ai_face();}; +void() zombie_attc3 =[ $attc3, zombie_attc4 ] {ai_face();}; +void() zombie_attc4 =[ $attc4, zombie_attc5 ] {ai_face();}; +void() zombie_attc5 =[ $attc5, zombie_attc6 ] {ai_face();}; +void() zombie_attc6 =[ $attc6, zombie_attc7 ] {ai_face();}; +void() zombie_attc7 =[ $attc7, zombie_attc8 ] {ai_face();}; +void() zombie_attc8 =[ $attc8, zombie_attc9 ] {ai_face();}; +void() zombie_attc9 =[ $attc9, zombie_attc10 ] {ai_face();}; +void() zombie_attc10 =[ $attc10, zombie_attc11 ] {ai_face();}; +void() zombie_attc11 =[ $attc11, zombie_attc12 ] {ai_face();}; +void() zombie_attc12 =[ $attc12, zombie_run1 ] {ai_face();ZombieFireGrenade('-12 -19 29');}; + +void() zombie_missile = +{ + local float r; + + r = random(); + + if (r < 0.3) + zombie_atta1 (); + else if (r < 0.6) + zombie_attb1 (); + else + zombie_attc1 (); +}; + + +/* +============================================================================= + +PAIN + +============================================================================= +*/ + +void() zombie_paina1 =[ $paina1, zombie_paina2 ] {sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);}; +void() zombie_paina2 =[ $paina2, zombie_paina3 ] {ai_painforward(3);}; +void() zombie_paina3 =[ $paina3, zombie_paina4 ] {ai_painforward(1);}; +void() zombie_paina4 =[ $paina4, zombie_paina5 ] {ai_pain(1);}; +void() zombie_paina5 =[ $paina5, zombie_paina6 ] {ai_pain(3);}; +void() zombie_paina6 =[ $paina6, zombie_paina7 ] {ai_pain(1);}; +void() zombie_paina7 =[ $paina7, zombie_paina8 ] {}; +void() zombie_paina8 =[ $paina8, zombie_paina9 ] {}; +void() zombie_paina9 =[ $paina9, zombie_paina10 ] {}; +void() zombie_paina10 =[ $paina10, zombie_paina11 ] {}; +void() zombie_paina11 =[ $paina11, zombie_paina12 ] {}; +void() zombie_paina12 =[ $paina12, zombie_run1 ] {}; + +void() zombie_painb1 =[ $painb1, zombie_painb2 ] {sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);}; +void() zombie_painb2 =[ $painb2, zombie_painb3 ] {ai_pain(2);}; +void() zombie_painb3 =[ $painb3, zombie_painb4 ] {ai_pain(8);}; +void() zombie_painb4 =[ $painb4, zombie_painb5 ] {ai_pain(6);}; +void() zombie_painb5 =[ $painb5, zombie_painb6 ] {ai_pain(2);}; +void() zombie_painb6 =[ $painb6, zombie_painb7 ] {}; +void() zombie_painb7 =[ $painb7, zombie_painb8 ] {}; +void() zombie_painb8 =[ $painb8, zombie_painb9 ] {}; +void() zombie_painb9 =[ $painb9, zombie_painb10 ] {sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);}; +void() zombie_painb10 =[ $painb10, zombie_painb11 ] {}; +void() zombie_painb11 =[ $painb11, zombie_painb12 ] {}; +void() zombie_painb12 =[ $painb12, zombie_painb13 ] {}; +void() zombie_painb13 =[ $painb13, zombie_painb14 ] {}; +void() zombie_painb14 =[ $painb14, zombie_painb15 ] {}; +void() zombie_painb15 =[ $painb15, zombie_painb16 ] {}; +void() zombie_painb16 =[ $painb16, zombie_painb17 ] {}; +void() zombie_painb17 =[ $painb17, zombie_painb18 ] {}; +void() zombie_painb18 =[ $painb18, zombie_painb19 ] {}; +void() zombie_painb19 =[ $painb19, zombie_painb20 ] {}; +void() zombie_painb20 =[ $painb20, zombie_painb21 ] {}; +void() zombie_painb21 =[ $painb21, zombie_painb22 ] {}; +void() zombie_painb22 =[ $painb22, zombie_painb23 ] {}; +void() zombie_painb23 =[ $painb23, zombie_painb24 ] {}; +void() zombie_painb24 =[ $painb24, zombie_painb25 ] {}; +void() zombie_painb25 =[ $painb25, zombie_painb26 ] {ai_painforward(1);}; +void() zombie_painb26 =[ $painb26, zombie_painb27 ] {}; +void() zombie_painb27 =[ $painb27, zombie_painb28 ] {}; +void() zombie_painb28 =[ $painb28, zombie_run1 ] {}; + +void() zombie_painc1 =[ $painc1, zombie_painc2 ] {sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);}; +void() zombie_painc2 =[ $painc2, zombie_painc3 ] {}; +void() zombie_painc3 =[ $painc3, zombie_painc4 ] {ai_pain(3);}; +void() zombie_painc4 =[ $painc4, zombie_painc5 ] {ai_pain(1);}; +void() zombie_painc5 =[ $painc5, zombie_painc6 ] {}; +void() zombie_painc6 =[ $painc6, zombie_painc7 ] {}; +void() zombie_painc7 =[ $painc7, zombie_painc8 ] {}; +void() zombie_painc8 =[ $painc8, zombie_painc9 ] {}; +void() zombie_painc9 =[ $painc9, zombie_painc10 ] {}; +void() zombie_painc10 =[ $painc10, zombie_painc11 ] {}; +void() zombie_painc11 =[ $painc11, zombie_painc12 ] {ai_painforward(1);}; +void() zombie_painc12 =[ $painc12, zombie_painc13 ] {ai_painforward(1);}; +void() zombie_painc13 =[ $painc13, zombie_painc14 ] {}; +void() zombie_painc14 =[ $painc14, zombie_painc15 ] {}; +void() zombie_painc15 =[ $painc15, zombie_painc16 ] {}; +void() zombie_painc16 =[ $painc16, zombie_painc17 ] {}; +void() zombie_painc17 =[ $painc17, zombie_painc18 ] {}; +void() zombie_painc18 =[ $painc18, zombie_run1 ] {}; + +void() zombie_paind1 =[ $paind1, zombie_paind2 ] {sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);}; +void() zombie_paind2 =[ $paind2, zombie_paind3 ] {}; +void() zombie_paind3 =[ $paind3, zombie_paind4 ] {}; +void() zombie_paind4 =[ $paind4, zombie_paind5 ] {}; +void() zombie_paind5 =[ $paind5, zombie_paind6 ] {}; +void() zombie_paind6 =[ $paind6, zombie_paind7 ] {}; +void() zombie_paind7 =[ $paind7, zombie_paind8 ] {}; +void() zombie_paind8 =[ $paind8, zombie_paind9 ] {}; +void() zombie_paind9 =[ $paind9, zombie_paind10 ] {ai_pain(1);}; +void() zombie_paind10 =[ $paind10, zombie_paind11 ] {}; +void() zombie_paind11 =[ $paind11, zombie_paind12 ] {}; +void() zombie_paind12 =[ $paind12, zombie_paind13 ] {}; +void() zombie_paind13 =[ $paind13, zombie_run1 ] {}; + +void() zombie_paine1 =[ $paine1, zombie_paine2 ] { +sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM); +self.health = 60; +}; +void() zombie_paine2 =[ $paine2, zombie_paine3 ] {ai_pain(8);}; +void() zombie_paine3 =[ $paine3, zombie_paine4 ] {ai_pain(5);}; +void() zombie_paine4 =[ $paine4, zombie_paine5 ] {ai_pain(3);}; +void() zombie_paine5 =[ $paine5, zombie_paine6 ] {ai_pain(1);}; +void() zombie_paine6 =[ $paine6, zombie_paine7 ] {ai_pain(2);}; +void() zombie_paine7 =[ $paine7, zombie_paine8 ] {ai_pain(1);}; +void() zombie_paine8 =[ $paine8, zombie_paine9 ] {ai_pain(1);}; +void() zombie_paine9 =[ $paine9, zombie_paine10 ] {ai_pain(2);}; +void() zombie_paine10 =[ $paine10, zombie_paine11 ] { +sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM); +self.solid = SOLID_NOT; +}; +void() zombie_paine11 =[ $paine11, zombie_paine12 ] {self.nextthink = time + 5;self.health = 60;}; +void() zombie_paine12 =[ $paine12, zombie_paine13 ]{ +// see if ok to stand up +self.health = 60; +sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE); +self.solid = SOLID_SLIDEBOX; +if (!walkmove (0, 0)) +{ + self.think = zombie_paine11; + self.solid = SOLID_NOT; + return; +} +}; +void() zombie_paine13 =[ $paine13, zombie_paine14 ] {}; +void() zombie_paine14 =[ $paine14, zombie_paine15 ] {}; +void() zombie_paine15 =[ $paine15, zombie_paine16 ] {}; +void() zombie_paine16 =[ $paine16, zombie_paine17 ] {}; +void() zombie_paine17 =[ $paine17, zombie_paine18 ] {}; +void() zombie_paine18 =[ $paine18, zombie_paine19 ] {}; +void() zombie_paine19 =[ $paine19, zombie_paine20 ] {}; +void() zombie_paine20 =[ $paine20, zombie_paine21 ] {}; +void() zombie_paine21 =[ $paine21, zombie_paine22 ] {}; +void() zombie_paine22 =[ $paine22, zombie_paine23 ] {}; +void() zombie_paine23 =[ $paine23, zombie_paine24 ] {}; +void() zombie_paine24 =[ $paine24, zombie_paine25 ] {}; +void() zombie_paine25 =[ $paine25, zombie_paine26 ] {ai_painforward(5);}; +void() zombie_paine26 =[ $paine26, zombie_paine27 ] {ai_painforward(3);}; +void() zombie_paine27 =[ $paine27, zombie_paine28 ] {ai_painforward(1);}; +void() zombie_paine28 =[ $paine28, zombie_paine29 ] {ai_pain(1);}; +void() zombie_paine29 =[ $paine29, zombie_paine30 ] {}; +void() zombie_paine30 =[ $paine30, zombie_run1 ] {}; + +void() zombie_die = +{ + sound (self, CHAN_VOICE, "zombie/z_gib.wav", 1, ATTN_NORM); + ThrowHead ("progs/h_zombie.mdl", self.health); + ThrowGib ("progs/gib1.mdl", self.health); + ThrowGib ("progs/gib2.mdl", self.health); + ThrowGib ("progs/gib3.mdl", self.health); +}; + +/* +================= +zombie_pain + +Zombies can only be killed (gibbed) by doing 60 hit points of damage +in a single frame (rockets, grenades, quad shotgun, quad nailgun). + +A hit of 25 points or more (super shotgun, quad nailgun) will allways put it +down to the ground. + +A hit of from 10 to 40 points in one frame will cause it to go down if it +has been twice in two seconds, otherwise it goes into one of the four +fast pain frames. + +A hit of less than 10 points of damage (winged by a shotgun) will be ignored. + +FIXME: don't use pain_finished because of nightmare hack +================= +*/ +void(entity attacker, float take) zombie_pain = +{ + local float r; + + self.health = 60; // allways reset health + + if (take < 9) + return; // totally ignore + + if (self.inpain == 2) + return; // down on ground, so don't reset any counters + +// go down immediately if a big enough hit + if (take >= 25) + { + self.inpain = 2; + zombie_paine1 (); + return; + } + + if (self.inpain) + { +// if hit again in next gre seconds while not in pain frames, definately drop + self.pain_finished = time + 3; + return; // currently going through an animation, don't change + } + + if (self.pain_finished > time) + { +// hit again, so drop down + self.inpain = 2; + zombie_paine1 (); + return; + } + +// gp into one of the fast pain animations + self.inpain = 1; + + r = random(); + if (r < 0.25) + zombie_paina1 (); + else if (r < 0.5) + zombie_painb1 (); + else if (r < 0.75) + zombie_painc1 (); + else + zombie_paind1 (); +}; + +//============================================================================ + +/*QUAKED monster_zombie (1 0 0) (-16 -16 -24) (16 16 32) Crucified ambush + +If crucified, stick the bounding box 12 pixels back into a wall to look right. +*/ +void() monster_zombie = +{ + if (deathmatch) + { + remove(self); + return; + } + + precache_model ("progs/zombie.mdl"); + precache_model ("progs/h_zombie.mdl"); + precache_model ("progs/zom_gib.mdl"); + + precache_sound ("zombie/z_idle.wav"); + precache_sound ("zombie/z_idle1.wav"); + precache_sound ("zombie/z_shot1.wav"); + precache_sound ("zombie/z_gib.wav"); + precache_sound ("zombie/z_pain.wav"); + precache_sound ("zombie/z_pain1.wav"); + precache_sound ("zombie/z_fall.wav"); + precache_sound ("zombie/z_miss.wav"); + precache_sound ("zombie/z_hit.wav"); + precache_sound ("zombie/idle_w2.wav"); + + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_STEP; + + setmodel (self, "progs/zombie.mdl"); + + setsize (self, '-16 -16 -24', '16 16 40'); + self.health = 60; + + self.th_stand = zombie_stand1; + self.th_walk = zombie_walk1; + self.th_run = zombie_run1; + self.th_pain = zombie_pain; + self.th_die = zombie_die; + self.th_missile = zombie_missile; + + if (self.spawnflags & SPAWN_CRUCIFIED) + { + self.movetype = MOVETYPE_NONE; + zombie_cruc1 (); + } + else + walkmonster_start(); +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/replace.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/replace.qc new file mode 100755 index 00000000..849e4406 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/replace.qc @@ -0,0 +1,129 @@ + +// Basemod replacement ent defines +#define ENT_REPLACE(f,t) void(void) f = { self.classname = #t; t(); } +#define ENT_REPLACE_FUNC(f,t,x) void(void) f = { self.classname = #t; x(); t(); } + +// Replacement functions +void() health_setrotten = { self.spawnflags |= H_ROTTEN; }; +void() health_setmega = { self.spawnflags |= H_MEGA; }; +void() ammo_setlarge = { self.spawnflags |= WEAPON_BIG2; }; + +// -- Quake 3 entities +// weapons +ENT_REPLACE(weapon_gauntlet, weapon_supershotgun); // Gauntlet (not normally used) +ENT_REPLACE(weapon_machinegun, weapon_nailgun); // Machinegun (not normally used) +//ENT_REPLACE(weapon_shotgun, weapon_supershotgun); // Shotgun +ENT_REPLACE(weapon_plasmagun, weapon_supernailgun); // Plasma gun +ENT_REPLACE(weapon_railgun, weapon_rocketlauncher); // Railgun +ENT_REPLACE(weapon_bfg, weapon_lightning); // BFG +// holdables +ENT_REPLACE(holdable_medikit, item_health); // personal medikit +ENT_REPLACE(holdable_teleporter, info_null); // personal teleporter +// armor +ENT_REPLACE(item_armor_body, item_armorInv); // 100 armor +ENT_REPLACE(item_armor_combat, item_armor2); // 50 armor +ENT_REPLACE(item_armor_shard, info_null); // +5 armor shard +// powerups +ENT_REPLACE(item_enviro, item_artifact_envirosuit); // enviro powerup +ENT_REPLACE(item_flight, item_artifact_invisibility); // flight +ENT_REPLACE(item_haste, item_artifact_super_damage); // haste +ENT_REPLACE(item_quad, item_artifact_super_damage); // quad damage +ENT_REPLACE(item_invis, item_artifact_invisibility); // invisibility +ENT_REPLACE(item_regen, item_health); // regeneration +// health +ENT_REPLACE(item_health_large, item_health); // +50 health +ENT_REPLACE_FUNC(item_health_mega, item_health, health_setmega); // +100 health (ignore max) +ENT_REPLACE_FUNC(item_health_small, item_health, health_setrotten); // +5 health (ignore max) +// ammo +ENT_REPLACE(ammo_bullets, item_spikes); // Machinegun ammo +ENT_REPLACE(ammo_grenades, item_rockets); // Grenade launcher ammo +ENT_REPLACE(ammo_lightning, item_cells); // Lightning gun ammo +ENT_REPLACE_FUNC(ammo_slugs, item_rockets, ammo_setlarge); // Railgun ammo +ENT_REPLACE_FUNC(ammo_bfg, item_cells, ammo_setlarge); // BFG ammo +// other ents +ENT_REPLACE(misc_teleporter_dest, info_teleport_destination); // teleport destination +ENT_REPLACE(target_position, info_notnull); // "target" entity +ENT_REPLACE(info_player_intermission, info_intermission); // intermission + +// -- Quake 2 entities +// weapons +ENT_REPLACE(weapon_chaingun, weapon_supernailgun); // chaingun +ENT_REPLACE(weapon_hyperblaster, weapon_lightning); // hyperblaster +// armor +ENT_REPLACE(item_armor_jacket, item_armor1); +ENT_REPLACE(item_power_screen, item_armor2); // power screen (not used often) +ENT_REPLACE(item_power_shield, item_armorInv); // power shield + // powerups +ENT_REPLACE(item_bandolier, item_rockets, ammo_setlarge); // bandolier +ENT_REPLACE(item_breather, item_artifact_envirosuit); // underwater air breather +ENT_REPLACE(item_invulnerability, item_artifact_invulnerability); // invulnerable artifact +ENT_REPLACE(item_pack, item_rockets, ammo_setlarge); // ammo pack +ENT_REPLACE(item_silencer, item_artifact_invisibility); // weapon silencer +// health +ENT_REPLACE_FUNC(item_ancient_head, item_health, health_setmega); // ancient head (+2 max health) +ENT_REPLACE_FUNC(item_adrenaline, item_health, health_setmega); // adrenaline (+1 max health) + +// -- Half-life entities +// weapons +ENT_REPLACE(weapon_357, weapon_grenadelauncher); // 357 magnum +ENT_REPLACE(weapon_9mmAR, weapon_supernailgun); // mp5 +ENT_REPLACE(weapon_9mmhandgun, weapon_nailgun); // handgun +ENT_REPLACE(weapon_crossbow, weapon_grenadelauncher); // crossbow +ENT_REPLACE(weapon_crowbar, info_null); // crowbar +ENT_REPLACE(weapon_egon, weapon_lightning); // ghostbusters gun +ENT_REPLACE(weapon_gauss, weapon_lightning); // tau cannon +ENT_REPLACE(weapon_handgrenade, item_rockets); // hand grenades +ENT_REPLACE(weapon_hornetgun, info_null); // hornet gun +ENT_REPLACE(weapon_rpg, weapon_rocketlauncher); // rpg +ENT_REPLACE(weapon_satchel, item_rockets); // satchel charge +ENT_REPLACE(weapon_snark, item_cells); // snarks +ENT_REPLACE(weapon_tripmine, item_rockets); // tripmines +// armor +ENT_REPLACE(item_battery, info_null); // battery charge +// powerups +ENT_REPLACE(item_airtank, item_artifact_envirosuit); // air tank (not used often) +ENT_REPLACE(item_antidote, item_health); // antidote (not used often) +ENT_REPLACE(item_longjump, weapon_rocketlauncher); // long jump module +ENT_REPLACE(item_suit, item_artifact_envirosuit); // HEV suit +// health +ENT_REPLACE(item_healthkit, item_health); // floor health kit +// ammo +ENT_REPLACE(ammo_357, item_rockets); // 357 ammo +ENT_REPLACE(ammo_9mmAR, item_spikes); // mp5 clip +ENT_REPLACE(ammo_9mmbox, item_spikes, ammo_setlarge); // 9mm box +ENT_REPLACE(ammo_9mmclip, item_spikes); // 9mm clip +ENT_REPLACE(ammo_ARgrenades, item_rockets); // mp5 grenades +ENT_REPLACE(ammo_buckshot, item_shells); // shotgun shells +ENT_REPLACE(ammo_crossbow, item_rockets); // crossbow bolts +ENT_REPLACE(ammo_gaussclip, item_cells); // cells for gauss/egon +ENT_REPLACE(ammo_rpgclip, item_rockets, ammo_setlarge); // RPG ammo + +// special replace +void(void() func) CheckSpawn = +{ + // these ents conflict with q1 field names + switch (self.classname) + { + case "ammo_shells": + self.classname = "item_shells"; + item_shells(); + break; + case "ammo_nails": + self.classname = "item_spikes"; + item_spikes(); + break; + case "ammo_cells": + self.classname = "item_cells"; + item_cells(); + break; + default: + if (func) + func(); + else + { + dprint("Couldn't find spawn function "); + dprint(self.classname); + dprint("\n"); + } + } +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/sol_defs.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/sol_defs.qc new file mode 100755 index 00000000..06bbb88b --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/sol_defs.qc @@ -0,0 +1,107 @@ +// Solitude defs +#define DEFAULT_GRAVITY 340 +#define DEFAULT_MAXSPEED 170 // max walk speed on ground + +.float next_jump_time; // next time the player can jump (usually after landing) +.float setup_death; // setup respawn timer on player death +void () Player_SetupDeath; + +.float needles; // how many needler needles a player has in him + +void () W_StartWeapon; +float (float wep, float cliptype) W_GetMaxClip; +void (float wtype, float ttype) ThrowWeapon; +void () player_throw_grenade; +void () pre_player_throw_grenade; +void () pre_player_melee; +void ( entity t_ent, float weptype, float cliptype, float newamt ) SetAmmoFor; +void () NeedlerHome; + +.float selnade; // the type of nade being thrown +#define GRENADE_REGULAR 0 +#define GRENADE_STICKY 1 + +.float weaponheat; + +.entity pp_cooldown; + +.float aflag; + +.float pickup_time, canpickup_time; + +.float lives; // times an item can respawn + +.float exshells; +.float exshells2; +.float exhshells; +.float exnails; +.float exrockets; +.float excells; + +//sniper rifle +.float ammo_sniper; +.float exsniper; + +// plasma pistol +.float ammo_ppistol; +.float exppistol; + +// plasma rifle +.float ammo_prifle; +.float exprifle; +.float prifle_heat; // plasma rifle fires faster the longer it's fired + +// energy sword +.float ammo_sword; +.float exsword; + +// needler +.float ammo_needler; +.float exneedler; +.float needler_heat; // needler fires faster the longer it's held down + +.float ammo_shells2; +.float ammo_hshells; + +.float axhitme; + +.float ohealth; // for regen +.float regen; /// + + +// animations +//weapon frame +.float donefire; +.float wepanim; +//player frame +.float fireframe; +.float jump_time; +.float pain_time; +.float reload_time; +.float pull_time; +.float nade_time, melee_time; +.float death_type; + +#define MOD_SOLITUDE 666 // undefined mode of death + +// weapons +#define WEAPON_SWORD IT_AXE +#define WEAPON_PISTOL IT_SHOTGUN +#define WEAPON_SHOT IT_SUPER_SHOTGUN +#define WEAPON_AR IT_NAILGUN +#define WEAPON_UZI IT_SUPER_NAILGUN +#define WEAPON_SNIPER IT_GRENADE_LAUNCHER +#define WEAPON_RL IT_ROCKET_LAUNCHER +#define WEAPON_PPISTOL IT_LIGHTNING +#define WEAPON_NEEDLER IT_EXTRA_WEAPON +#define WEAPON_PRIFLE IT_EXTRA_WEAPON2 +#define WEAPON_SKULL IT_SKULL + +// Zooming +.float pfov; +#define FOV_DEFAULT 90 + +// Frikbot +void(float to, float f) WriteByte; +void(float to, string s) WriteString; +void () reload; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/sol_items.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/sol_items.qc new file mode 100755 index 00000000..1b067396 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/sol_items.qc @@ -0,0 +1,565 @@ +// Solitude Items: weapons, ammo, misc. + +// GetPlayerWeapons: +// return how many weapons a player is holding. +// also used for finding out if the player is holding a certain weapon. +float (float pweapons) GetPlayerWeapons = +{ + local float i; + + if (pweapons & WEAPON_PISTOL) + i++; + if (pweapons & WEAPON_SKULL) + i++; + if (pweapons & WEAPON_SHOT) + i++; + if (pweapons & WEAPON_AR) + i++; + if (pweapons & WEAPON_UZI) + i++; + if (pweapons & WEAPON_RL) + i++; + if (pweapons & WEAPON_SNIPER) + i++; + if (pweapons & WEAPON_PPISTOL) + i++; + if (pweapons & WEAPON_SWORD) + i++; + if (pweapons & WEAPON_NEEDLER) + i++; + if (pweapons & WEAPON_PRIFLE) + i++; +/* + if (pweapons & WEAPON_PISTOL) + i++; + if (pweapons & WEAPON_PISTOL) + i++; +*/ + return i; +}; + +// Returns the amount of ammo an entity or player has either in the primary or secondary clip +// PS. It's hackish, but it works :) +float (entity t_plyr, float t_wep, float cliptype) GetAmmoCount = +{ + local float oldweapon, rtval; + + oldweapon = t_plyr.weapon; + t_plyr.weapon = t_wep; + W_UpdateAmmoCounts( t_plyr ); + if (cliptype) + rtval = t_plyr.currentammo; + else + rtval = t_plyr.armorvalue; + + t_plyr.weapon = oldweapon; + W_UpdateAmmoCounts( t_plyr ); + + return rtval; +}; + +// Sets the ammo of a new or dropped weapon, as opposed to the function below which... +void ( entity t_wep, float weptype ) SetWeaponAmmo = +{ + local float stammo; + stammo = W_GetMaxClip( weptype, 1 ); + + switch( weptype ) { + case WEAPON_PISTOL: + t_wep.exshells = 24; + t_wep.ammo_shells = stammo; + break; + case WEAPON_SKULL: + t_wep.exshells = 0; + t_wep.ammo_shells = stammo; + break; + case WEAPON_SHOT: + t_wep.exshells2 = 20; + t_wep.ammo_shells2 = stammo; + break; + case WEAPON_AR: + t_wep.exnails = 24; + t_wep.ammo_nails = stammo; + break; + case WEAPON_UZI: + t_wep.exhshells = 24; + t_wep.ammo_hshells = stammo; + break; + case WEAPON_RL: + t_wep.exrockets = 2; + t_wep.ammo_rockets = stammo; + break; + case WEAPON_SNIPER: + t_wep.exsniper = 10; + t_wep.ammo_sniper = stammo; + break; + case WEAPON_PPISTOL: + t_wep.exppistol = 0; + t_wep.ammo_ppistol = stammo; + break; + case WEAPON_SWORD: + t_wep.exppistol = 0; + t_wep.ammo_ppistol = stammo; + break; + case WEAPON_NEEDLER: + t_wep.exneedler = 90; + t_wep.ammo_needler = stammo; + break; + case WEAPON_PRIFLE: + t_wep.exprifle = 0; + t_wep.ammo_prifle = stammo; + break; + default: + break; + } +}; + +// sets ammo to a specific clip aspect of a weapon (current clip or extended clip) +void ( entity t_ent, float weptype, float cliptype, float newamt ) SetAmmoFor = +{ +/* +_bprint(ftos(GetAmmoCount(t_ent, weptype, cliptype)), "\n"); +_bprint(ftos(newamt), "\n"); +_bprint(ftos(W_GetMaxClip(weptype, cliptype)), "\n"); +*/ + if ( (GetAmmoCount(t_ent, weptype, cliptype)+newamt) > W_GetMaxClip(weptype, cliptype) ) { + newamt = W_GetMaxClip(weptype, cliptype) - GetAmmoCount(t_ent, weptype, cliptype); + if (newamt < 0) + newamt = 0; + } + + switch ( weptype ) { + case WEAPON_PISTOL: + if (!cliptype || cliptype > 1) + t_ent.exshells += newamt; + if (cliptype) + t_ent.ammo_shells += newamt; + break; + case WEAPON_SKULL: + if (!cliptype || cliptype > 1) + t_ent.exshells += newamt; + if (cliptype) + t_ent.ammo_shells += newamt; + break; + case WEAPON_SHOT: + if (!cliptype || cliptype > 1) + t_ent.exshells2 += newamt; + if (cliptype) + t_ent.ammo_shells2 += newamt; + break; + case WEAPON_AR: + if (!cliptype || cliptype > 1) + t_ent.exnails += newamt; + if (cliptype) + t_ent.ammo_nails += newamt; + break; + case WEAPON_UZI: + if (!cliptype || cliptype > 1) + t_ent.exhshells += newamt; + if (cliptype) + t_ent.ammo_hshells += newamt; + break; + case WEAPON_RL: + if (!cliptype || cliptype > 1) + t_ent.exrockets += newamt; + if (cliptype) + t_ent.ammo_rockets += newamt; + break; + case WEAPON_SNIPER: + if (!cliptype || cliptype > 1) + t_ent.exsniper += newamt; + if (cliptype) + t_ent.ammo_sniper += newamt; + break; + case WEAPON_PPISTOL: + if (!cliptype || cliptype > 1) + t_ent.exppistol += newamt; + if (cliptype) + t_ent.ammo_ppistol += newamt; + break; + case WEAPON_SWORD: + if (!cliptype || cliptype > 1) + t_ent.exsword += newamt; + if (cliptype) + t_ent.ammo_sword += newamt; + break; + case WEAPON_NEEDLER: + if (!cliptype || cliptype > 1) + t_ent.exneedler += newamt; + if (cliptype) + t_ent.ammo_needler += newamt; + break; + case WEAPON_PRIFLE: + if (!cliptype || cliptype > 1) + t_ent.exprifle += newamt; + if (cliptype) + t_ent.ammo_prifle += newamt; + break; + default: + _bprint("SetAmmoFor: invalid weapon type specified\n"); + break; + } +}; + +void ( entity t_from, entity t_to, float wtype, float aremove ) CopyAmmo = +{ + W_UpdateAmmoCounts( t_from ); + SetAmmoFor( t_to, wtype, 0, t_from.armorvalue ); + SetAmmoFor( t_to, wtype, 1, t_from.currentammo ); + + if (aremove == 1) { + SetAmmoFor( t_from, wtype, 0, (-1 * t_from.armorvalue) ); + SetAmmoFor( t_from, wtype, 1, (-1 * t_from.currentammo) ); + } +}; + +void () weapon_becometouch = +{ + self.think = SUB_Remove; + self.nextthink = time + 30; + self.touch = weapon_touch; +}; + +string ( float wtype ) weapon_getlaymodel = +{ + switch (wtype) + { + case WEAPON_SHOT: + return ("progs/g_shot.mdl"); + break; + case WEAPON_PISTOL: + return ("progs/g_pistol.mdl"); + break; + case WEAPON_SKULL: + //return ("GameTypes/OddBall/g_skull.mdl"); + break; + case WEAPON_AR: + return ("progs/g_nail.mdl"); + break; + case WEAPON_UZI: + return ("progs/g_uzi.mdl"); + break; + case WEAPON_RL: + return ("progs/g_rocket.mdl"); + break; + case WEAPON_SNIPER: + return ("progs/g_sniper.mdl"); + break; + case WEAPON_PPISTOL: + return ("progs/g_plpist.mdl"); + break; + case WEAPON_SWORD: + return ("progs/g_axe.mdl"); + break; + case WEAPON_NEEDLER: + return ("progs/g_needler.mdl"); + break; + case WEAPON_PRIFLE: + return ("progs/g_plrifl.mdl"); + break; + default: + return ("progs/player.mdl"); + break; + } +}; + +void (float wtype, float ttype) ThrowWeapon = +{ + local entity newthrow; + newthrow = spawn(); + newthrow.owner = self; + newthrow.movetype = MOVETYPE_BOUNCE; + newthrow.solid = SOLID_BBOX; + newthrow.classname = "weapon_pickup"; + newthrow.flags = FL_ITEM; + newthrow.think = weapon_becometouch; + newthrow.nextthink = time + 1; + + newthrow.weapon = wtype; + + if (ttype == 1) { // throwing an existing weapon + CopyAmmo(self, newthrow, wtype, 1); + newthrow.lives = 1; + } + else + SetWeaponAmmo(newthrow, wtype); + + makevectors (self.v_angle); + if (self.v_angle_x) + { + newthrow.velocity = ((((v_forward * 45) + (v_up * 200)) + ((crandom () * v_right) * TE_LAVASPLASH)) + ((crandom () * v_up) * TE_LAVASPLASH)); + } + else + { + newthrow.velocity = aim (self, 10000); + newthrow.velocity = (newthrow.velocity * 45); + newthrow.velocity_z = 200; + } + + newthrow.gravity = 3; + newthrow.solid = SOLID_TRIGGER; + + setsize (newthrow, '-16 -16 0', '16 16 56'); + + setmodel( newthrow, weapon_getlaymodel( wtype ) ); + + setorigin (newthrow, ((self.origin + '0 0 16') + (v_right * CONTENT_SKY))); +}; + +// respawn the weapon +void () weapon_activate = +{ + if (self.lives == 1) { + remove( self ); + return; + } + if (self.mdl) + setmodel(self, self.mdl); + self.touch = weapon_touch; +} + +void () weapon_touch = +{ + local entity oself; + local float addweapon, newweapon; + + oself = self; + // + if (!(other.flags & FL_CLIENT)) + return; + + if (other.ishuman != #TRUE) + if (other.attack_finished < time) + other.canpickup_time = time + .1; + + self.mdl = self.model; + + if ( (other.items & self.weapon) ) { + if (self.weapon & WEAPON_PPISTOL || self.weapon & WEAPON_PRIFLE) // weapons that don't have an extended clip + if ( W_GetMaxClip(self.weapon, 1) <= GetAmmoCount(other, self.weapon, 1) ) + return; + + if ( W_GetMaxClip(self.weapon, 0) <= GetAmmoCount(other, self.weapon, 0) ) + return; + + if (self.weapon & WEAPON_PPISTOL || self.weapon & WEAPON_PRIFLE) + SetAmmoFor( other, self.weapon, 1, self.currentammo ); + else + SetAmmoFor( other, self.weapon, 0, self.armorvalue ); + //SetAmmoFor( other, self.weapon, 1, self.currentammo ); + + W_UpdateAmmoCounts( other ); + self.touch = SUB_Null; + setmodel( self, string_null ); + self.nextthink = time + 30; + self.think = weapon_activate; + return; + } + + if (other.canpickup_time > time) { + if (other.weapon == self.weapon || GetPlayerWeapons(other.items) == 2 ) + addweapon = 2; // drop current weapon and replace it + else + { + addweapon = 1; // add other weapon and switch to it + } + + other.canpickup_time = 0; + } + else { + if (time > other.pickup_time) { + other.pickup_time = time + .5; + return; + } + } + + if (self.weapon == IT_NAILGUN) //Assault rifle + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 1\n"); + } + + else if (self.weapon == IT_LIGHTNING)//Plasma Pistol + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 2\n"); + } + + else if (self.weapon == IT_SUPER_SHOTGUN) //Shootie + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 3\n"); + } + + else if (self.weapon == IT_EXTRA_WEAPON) + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 4\n"); + } + + else if (self.weapon == IT_ROCKET_LAUNCHER) + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 5\n"); + } + + else if (self.weapon == IT_SHOTGUN) + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 6\n"); + } + + else if (self.weapon == IT_SUPER_NAILGUN) + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 7\n"); + } + + else if (self.weapon == IT_GRENADE_LAUNCHER) + { + other.groundwep = 1; + stuffcmd (other, "cl_ww 8\n"); + } + + else + stuffcmd (other, "cl_ww 0\n"); + + if (addweapon) + { + other.attack_finished = time + .1; // so the player doesnt reload when picking up a new weapon + if (addweapon == 1) { + other.items = other.items | self.weapon; + sprint(other,"New weapon added to your inv\n"); + } + else if (addweapon == 2) { // replace current weapon + newweapon = self.weapon; + other.items = other.items - other.weapon; + other.items = other.items | self.weapon; + self = other; + ThrowWeapon(self.weapon, 1); + W_WeaponSwitch(newweapon); + W_SetCurrentAmmo(); + self = oself; + } + CopyAmmo( self, other, self.weapon, 0 ); + W_UpdateAmmoCounts(other); + self.touch = SUB_Null; + setmodel( self, string_null ); + self.nextthink = time + 30; + self.think = weapon_activate; + return; + } +}; + +void () weapon_start = +{ + if (!self.weapon) { + _bprint("weapon_start: weapon with no .weapon set!\n"); + remove(self); + } + + self.classname = "weapon_pickup"; // so bots can recognize it + self.flags = FL_ITEM; + + precache_model( weapon_getlaymodel( self.weapon ) ); + setmodel( self, weapon_getlaymodel( self.weapon ) ); + + self.gravity = 3; + self.solid = SOLID_TRIGGER; + + setsize (self, '-16 -16 0', '16 16 56'); + + SetWeaponAmmo( self, self.weapon ); + self.touch = weapon_touch; +}; + +// WEAPONS +void () weapon_shotgun = +{ + self.weapon = WEAPON_PISTOL; + weapon_start (); +}; +void () weapon_pistol = +{ + weapon_shotgun(); +}; +void() weapon_skull = +{ + self.weapon = WEAPON_SKULL; + weapon_start (); +}; +void() weapon_supershotgun = +{ + self.weapon = WEAPON_SHOT; + weapon_start (); +}; + +void() weapon_nailgun = +{ + self.weapon = WEAPON_AR; + weapon_start (); +}; +void() weapon_ar = +{ + weapon_nailgun(); +}; + +void() weapon_supernailgun = +{ + self.weapon = WEAPON_UZI; + weapon_start (); +}; +void() weapon_uzi = +{ + weapon_supernailgun (); +}; + +void() weapon_grenadelauncher = +{ + self.weapon = WEAPON_PPISTOL; + weapon_start (); +}; +void() weapon_ppistol = +{ + weapon_grenadelauncher (); +}; + +void() weapon_rocketlauncher = +{ + self.weapon = WEAPON_RL; + weapon_start (); +}; + +void() weapon_lightning = +{ + self.weapon = WEAPON_SNIPER; + weapon_start (); +}; +void() weapon_sniperrifle = +{ + weapon_lightning (); +}; + +void() weapon_sword = +{ + self.weapon = WEAPON_SWORD; + weapon_start (); +}; + +void() weapon_plasmapistol = +{ + self.weapon = WEAPON_PPISTOL; + weapon_start (); +}; + +void() weapon_plasmarifle = +{ + self.weapon = WEAPON_PRIFLE; + weapon_start (); +}; + +void() weapon_needler = +{ + self.weapon = WEAPON_NEEDLER; + weapon_start (); +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/sol_misc.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/sol_misc.qc new file mode 100755 index 00000000..fa822cd5 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/sol_misc.qc @@ -0,0 +1,13 @@ +// miscellaneous stuff + +// Spawn some model. +void() func_model = +{ + precache_model( self.model ); + setmodel( self, self.model ); + setorigin( self, self.origin ); + + self.movetype = MOVETYPE_NONE; + self.solid = SOLID_BBOX; + setsize(self, '-8 -8 -8', '8 8 8'); +}; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/spectate.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/spectate.qc new file mode 100755 index 00000000..bdb8d58a --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/spectate.qc @@ -0,0 +1,83 @@ +// Spectator functions +// Added Aug11'97 by Zoid +// +// These functions are called from the server if they exist. +// Note that Spectators only have one think since they movement code doesn't +// track them much. Impulse commands work as usual, but don't call +// the regular ImpulseCommand handler in weapons.qc since Spectators don't +// have any weapons and things can explode. +// +// --- Zoid. + +#ifndef NETQUAKE + +/* +=========== +SpectatorConnect + +called when a spectator connects to a server +============ +*/ +void() SpectatorConnect = +{ + bprint3 (PRINT_MEDIUM, "Spectator ", self.netname, " entered the game\n"); + + self.goalentity = world; // used for impulse 1 below +}; + +/* +=========== +SpectatorDisconnect + +called when a spectator disconnects from a server +============ +*/ +void() SpectatorDisconnect = +{ + bprint3 (PRINT_MEDIUM, "Spectator ", self.netname, " left the game\n"); +}; + +/* +================ +SpectatorImpulseCommand + +Called by SpectatorThink if the spectator entered an impulse +================ +*/ +void() SpectatorImpulseCommand = +{ + if (self.impulse == 1) { + // teleport the spectator to the next spawn point + // note that if the spectator is tracking, this doesn't do + // much + self.goalentity = find(self.goalentity, classname, "info_player_deathmatch"); + if (self.goalentity == world) + self.goalentity = find(self.goalentity, classname, "info_player_deathmatch"); + if (self.goalentity != world) { + setorigin(self, self.goalentity.origin); + self.angles = self.goalentity.angles; + self.fixangle = TRUE; // turn this way immediately + } + } + + self.impulse = 0; +}; + +/* +================ +SpectatorThink + +Called every frame after physics are run +================ +*/ +void() SpectatorThink = +{ + // self.origin, etc contains spectator position, so you could + // do some neat stuff here + + if (self.impulse) + SpectatorImpulseCommand(); +}; + +#endif + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/sprites.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/sprites.qc new file mode 100755 index 00000000..98fac355 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/sprites.qc @@ -0,0 +1,26 @@ + +// these are the only sprites still in the game... + +$spritename s_explod +$type vp_parallel +$load /raid/quake/id1/gfx/sprites/explod03.lbm +$frame 24 24 56 56 +$frame 120 24 56 56 +$frame 216 24 56 56 +$frame 24 88 56 56 +$frame 120 88 56 56 +$frame 216 88 56 56 + + +$spritename s_bubble +$type vp_parallel +$load /raid/quake/id1/gfx/sprites/bubble.lbm +$frame 16 16 16 16 +$frame 40 16 16 16 + + +$spritename s_light +$type vp_parallel +$load /raid/quake/id1/gfx/sprites/light.lbm +$frame 104 32 32 32 + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/subs.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/subs.qc new file mode 100755 index 00000000..c7a8a1ac Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/subs.qc differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/triggers.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/triggers.qc new file mode 100755 index 00000000..addf7ed0 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/triggers.qc @@ -0,0 +1,637 @@ +void() trigger_reactivate = +{ + self.solid = SOLID_TRIGGER; +}; + +//============================================================================= + +float SPAWNFLAG_NOMESSAGE = 1; +float SPAWNFLAG_NOTOUCH = 1; + +// the wait time has passed, so set back up for another activation +void() multi_wait = +{ + if (self.max_health) + { + self.health = self.max_health; + self.takedamage = DAMAGE_YES; + self.solid = SOLID_BBOX; + } +}; + + +// the trigger was just touched/killed/used +// self.enemy should be set to the activator so it can be held through a delay +// so wait for the delay time before firing +void() multi_trigger = +{ + if (self.nextthink > time) + { + return; // allready been triggered + } + + if (self.classname == "trigger_secret") + { + if (self.enemy.classname != "player") + return; + found_secrets = found_secrets + 1; + WriteByte (MSG_ALL, SVC_FOUNDSECRET); + } + + if (self.noise) + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + +// don't trigger again until reset + self.takedamage = DAMAGE_NO; + + activator = self.enemy; + + SUB_UseTargets(); + + if (self.wait > 0) + { + self.think = multi_wait; + self.nextthink = time + self.wait; + } + else + { // we can't just remove (self) here, because this is a touch function + // called wheil C code is looping through area links... + self.touch = SUB_Null; + self.nextthink = time + 0.1; + self.think = SUB_Remove; + } +}; + +void() multi_killed = +{ + self.enemy = damage_attacker; + multi_trigger(); +}; + +void() multi_use = +{ + self.enemy = activator; + multi_trigger(); +}; + +void() multi_touch = +{ + if (other.classname != "player") + return; + +// if the trigger has an angles field, check player's facing direction + if (self.movedir != '0 0 0') + { + makevectors (other.angles); + if (v_forward * self.movedir < 0) + return; // not facing the right way + } + + self.enemy = other; + multi_trigger (); +}; + +/*QUAKED trigger_multiple (.5 .5 .5) ? notouch +Variable sized repeatable trigger. Must be targeted at one or more entities. If "health" is set, the trigger must be killed to activate each time. +If "delay" is set, the trigger waits some time after activating before firing. +"wait" : Seconds between triggerings. (.2 default) +If notouch is set, the trigger is only fired by other entities, not by touching. +NOTOUCH has been obsoleted by trigger_relay! +sounds +1) secret +2) beep beep +3) large switch +4) +set "message" to text string +*/ +void() trigger_multiple = +{ + switch (self.sounds) + { + case 1: + precache_sound ("misc/secret.wav"); + self.noise = "misc/secret.wav"; + break; + case 2: + precache_sound ("misc/talk.wav"); + self.noise = "misc/talk.wav"; + break; + case 3: + precache_sound ("misc/trigger1.wav"); + self.noise = "misc/trigger1.wav"; + break; + } + + if (!self.wait) + self.wait = 0.2; + self.use = multi_use; + + InitTrigger (); + + if (self.health) + { + if (self.spawnflags & SPAWNFLAG_NOTOUCH) + objerror ("health and notouch don't make sense\n"); + self.max_health = self.health; + self.th_die = multi_killed; + self.takedamage = DAMAGE_YES; + self.solid = SOLID_BBOX; + setorigin (self, self.origin); // make sure it links into the world + } + else + { + if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) ) + { + self.touch = multi_touch; + } + } +}; + + +/*QUAKED trigger_once (.5 .5 .5) ? notouch +Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching +"targetname". If "health" is set, the trigger must be killed to activate. +If notouch is set, the trigger is only fired by other entities, not by touching. +if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired. +if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0. +sounds +1) secret +2) beep beep +3) large switch +4) +set "message" to text string +*/ +void() trigger_once = +{ + self.wait = -1; + trigger_multiple(); +}; + +//============================================================================= + +/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) +This fixed size trigger cannot be touched, it can only be fired by other events. It can contain killtargets, targets, delays, and messages. +*/ +void() trigger_relay = +{ + self.use = SUB_UseTargets; +}; + + +//============================================================================= + +/*QUAKED trigger_secret (.5 .5 .5) ? +secret counter trigger +sounds +1) secret +2) beep beep +3) +4) +set "message" to text string +*/ +void() trigger_secret = +{ + total_secrets = total_secrets + 1; + self.wait = -1; + if (!self.message) + self.message = "You found a secret area!"; + if (!self.sounds) + self.sounds = 1; + + if (self.sounds == 1) + { + precache_sound ("misc/secret.wav"); + self.noise = "misc/secret.wav"; + } + else if (self.sounds == 2) + { + precache_sound ("misc/talk.wav"); + self.noise = "misc/talk.wav"; + } + + trigger_multiple (); +}; + +//============================================================================= + + +void() counter_use = +{ + self.count = self.count - 1; + if (self.count < 0) + return; + + if (self.count != 0) + { + if (activator.classname == "player" + && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0) + { + if (self.count >= 4) + centerprint (activator, "There are more to go..."); + else if (self.count == 3) + centerprint (activator, "Only 3 more to go..."); + else if (self.count == 2) + centerprint (activator, "Only 2 more to go..."); + else + centerprint (activator, "Only 1 more to go..."); + } + return; + } + + if (activator.classname == "player" + && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0) + centerprint(activator, "Sequence completed!"); + self.enemy = activator; + multi_trigger (); +}; + +/*QUAKED trigger_counter (.5 .5 .5) ? nomessage +Acts as an intermediary for an action that takes multiple inputs. + +If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished. + +After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself. +*/ +void() trigger_counter = +{ + self.wait = -1; + if (!self.count) + self.count = 2; + + self.use = counter_use; +}; + + +/* +============================================================================== + +TELEPORT TRIGGERS + +============================================================================== +*/ + +float PLAYER_ONLY = 1; +float SILENT = 2; + +void() play_teleport = +{ + local float v; + local string tmpstr; + + v = random(); + if (v < 0.2) + tmpstr = "misc/r_tele1.wav"; + else if (v < 0.4) + tmpstr = "misc/r_tele2.wav"; + else if (v < 0.6) + tmpstr = "misc/r_tele3.wav"; + else if (v < 0.8) + tmpstr = "misc/r_tele4.wav"; + else + tmpstr = "misc/r_tele5.wav"; + + sound (self, CHAN_VOICE, tmpstr, 1, ATTN_NORM); + remove (self); +}; + +void(vector org) spawn_tfog = +{ + local entity s; + s = spawn (); + s.origin = org; + s.nextthink = time + 0.2; + s.think = play_teleport; + + TE_teleport(org); +}; + + +void() tdeath_touch = +{ + if (other == self.owner) + return; + +// frag anyone who teleports in on top of an invincible player + if (other.classname == "player") + { + if (other.invincible_finished > time && + self.owner.invincible_finished > time) { + other.invincible_finished = 0; + self.owner.invincible_finished = 0; + T_Damage (other, self, self.owner, 50000, MOD_TELEFRAGDEFLECT); + T_Damage (self.owner, self, other, 50000, MOD_TELEFRAGDEFLECT); + return; + } + + if (other.invincible_finished > time) + { + T_Damage (self.owner, self, self.owner, 50000, MOD_TELEFRAGDEFLECT); + return; + } + + } + + if (other.health) + { + T_Damage (other, self, self.owner, 50000, MOD_TELEFRAG); + } +}; + + +void(vector org, entity death_owner) spawn_tdeath = +{ +local entity death; + + death = spawn(); + death.classname = "teledeath"; + death.movetype = MOVETYPE_NONE; + death.solid = SOLID_TRIGGER; + death.angles = '0 0 0'; + setsize (death, death_owner.mins - '1 1 1', death_owner.maxs + '1 1 1'); + setorigin (death, org); + death.touch = tdeath_touch; + death.nextthink = time + 0.2; + death.think = SUB_Remove; + death.owner = death_owner; + + force_retouch = 2; // make sure even still objects get hit +}; + +void() teleport_touch = +{ +local entity t; +local vector org; + + if (self.targetname) + { + if (self.nextthink < time) + { + return; // not fired yet + } + } + + if (self.spawnflags & PLAYER_ONLY) + { + if (other.classname != "player") + return; + } + +// only teleport living creatures + if (other.health <= 0 || other.solid != SOLID_SLIDEBOX) + return; + + SUB_UseTargets (); + +// put a tfog where the player was + spawn_tfog (other.origin); + + t = find (world, targetname, self.target); + if (!t) + objerror ("couldn't find target"); + +// spawn a tfog flash in front of the destination + makevectors (t.mangle); + org = t.origin + 32 * v_forward; + + spawn_tfog (org); + spawn_tdeath(t.origin, other); + +// move the player and lock him down for a little while + if (!other.health) + { + other.origin = t.origin; + other.velocity = (v_forward * other.velocity_x) + (v_forward * other.velocity_y); + return; + } + + setorigin (other, t.origin); + other.angles = t.mangle; + if (other.classname == "player") + { + other.fixangle = 1; // turn this way immediately + other.teleport_time = time + 0.7; + if (other.flags & FL_ONGROUND) + other.flags = other.flags - FL_ONGROUND; + other.velocity = v_forward * 300; + } + other.flags = other.flags - other.flags & FL_ONGROUND; +}; + +/*QUAKED info_teleport_destination (.5 .5 .5) (-8 -8 -8) (8 8 32) +This is the destination marker for a teleporter. It should have a "targetname" field with the same value as a teleporter's "target" field. +*/ +void() info_teleport_destination = +{ +// this does nothing, just serves as a target spot + self.mangle = self.angles; + self.angles = '0 0 0'; + self.model = ""; + self.origin = self.origin + '0 0 27'; + if (!self.targetname) + objerror ("no targetname"); +}; + +void() teleport_use = +{ + self.nextthink = time + 0.2; + force_retouch = 2; // make sure even still objects get hit + self.think = SUB_Null; +}; + +/*QUAKED trigger_teleport (.5 .5 .5) ? PLAYER_ONLY SILENT +Any object touching this will be transported to the corresponding info_teleport_destination entity. You must set the "target" field, and create an object with a "targetname" field that matches. + +If the trigger_teleport has a targetname, it will only teleport entities when it has been fired. +*/ +void() trigger_teleport = +{ + local vector o; + + InitTrigger (); + self.touch = teleport_touch; + // find the destination + if (!self.target) + objerror ("no target"); + self.use = teleport_use; + + if (!(self.spawnflags & SILENT)) + { + precache_sound ("ambience/hum1.wav"); + o = (self.mins + self.maxs)*0.5; + ambientsound (o, "ambience/hum1.wav",0.5 , ATTN_STATIC); + } +}; + +/* +============================================================================== + +trigger_setskill + +============================================================================== +*/ + +/*QUAKED trigger_setskill (.5 .5 .5) ? +sets skill level to the value of "message". +Only used on start map. +*/ +void() trigger_setskill = +{ + remove (self); +}; + + +/* +============================================================================== + +ONLY REGISTERED TRIGGERS + +============================================================================== +*/ + +void() trigger_onlyregistered_touch = +{ + if (other.classname != "player") + return; + if (self.attack_finished > time) + return; + + self.attack_finished = time + 2; + if (cvar("registered")) + { + self.message = ""; + SUB_UseTargets (); + remove (self); + } + else + { + if (self.message != "") + { + centerprint (other, self.message); + sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM); + } + } +}; + +/*QUAKED trigger_onlyregistered (.5 .5 .5) ? +Only fires if playing the registered version, otherwise prints the message +*/ +void() trigger_onlyregistered = +{ + precache_sound ("misc/talk.wav"); + InitTrigger (); + self.touch = trigger_onlyregistered_touch; +}; + +//============================================================================ + +void() hurt_on = +{ + self.solid = SOLID_TRIGGER; + self.nextthink = -1; +}; + +void() hurt_touch = +{ + if (other.takedamage) + { + self.solid = SOLID_NOT; + T_Damage (other, self, self, self.dmg, MOD_HURT); + self.think = hurt_on; + self.nextthink = time + 1; + } + + return; +}; + +/*QUAKED trigger_hurt (.5 .5 .5) ? +Any object touching this will be hurt +set dmg to damage amount +defalt dmg = 5 +*/ +void() trigger_hurt = +{ + InitTrigger (); + self.touch = hurt_touch; + if (!self.dmg) + self.dmg = 5; +}; + +//============================================================================ + +float PUSH_ONCE = 1; + +void() trigger_push_touch = +{ + if (other.classname == "grenade") + other.velocity = self.speed * self.movedir * 10; + else if (other.health > 0) + { + 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); + } + } + } + if (self.spawnflags & PUSH_ONCE) + remove(self); +}; + + +/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE +Pushes the player +*/ +void() trigger_push = +{ + InitTrigger (); + precache_sound ("ambience/windfly.wav"); + self.touch = trigger_push_touch; + if (!self.speed) + self.speed = 1000; +}; + +//============================================================================ + +void() trigger_monsterjump_touch = +{ + if ( other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER ) + return; + +// set XY even if not on ground, so the jump will clear lips + other.velocity_x = self.movedir_x * self.speed; + other.velocity_y = self.movedir_y * self.speed; + + if ( !(other.flags & FL_ONGROUND) ) + return; + + other.flags = other.flags - FL_ONGROUND; + + other.velocity_z = self.height; +}; + +/*QUAKED trigger_monsterjump (.5 .5 .5) ? +Walking monsters that touch this will jump in the direction of the trigger's angle +"speed" default to 200, the speed thrown forward +"height" default to 200, the speed thrown upwards +*/ +void() trigger_monsterjump = +{ + if (deathmatch) + { + remove(self); + return; + } + + if (!self.speed) + self.speed = 200; + if (!self.height) + self.height = 200; + if (self.angles == '0 0 0') + self.angles = '0 360 0'; + InitTrigger (); + self.touch = trigger_monsterjump_touch; +}; + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/weapons.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/weapons.qc new file mode 100755 index 00000000..cb5faacb --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/weapons.qc @@ -0,0 +1,3277 @@ +/* +*/ +vector puff_org; +void (entity targ, entity inflictor, entity attacker, float damage, INTEGER mod) T_Damage; +void () player_run; +void(entity inflictor, entity attacker, float damage, float radius, entity ignore, INTEGER mod) T_RadiusDamage; +void(vector org, float damage) SpawnBlood; +void() SuperDamageSound; +void () player_reload1; +void () player_stand1; +// called by worldspawn +void() W_Precache = +{ + precache_sound ("weapons/r_exp3.wav"); // new rocket explosion + precache_sound ("weapons/rocket1i.wav"); // spike gun + precache_sound ("weapons/uzi.wav"); // Uzi + precache_sound ("weapons/sgun1.wav"); //RL + precache_sound ("weapons/pistol.wav"); // player shotgun + precache_sound ("weapons/grenade.wav"); // grenade launcher + precache_sound ("weapons/bounce.wav"); // grenade bounce + precache_sound ("weapons/sniper.wav"); // sniperrifle + precache_sound ("weapons/shottie.wav"); // shottie + precache_sound ("weapons/shotgn2.wav"); // Ar2 + precache_sound ("weapons/needler.wav"); // needler + precache_sound ("weapons/ar1.wav"); //Sound effects for asault rifle + precache_model ("GFX/s_fblood.spr"); //Flood blood + precache_model ("progs/PL_BULL.spr"); //Flood blood + precache_model ("progs/h_dog.mdl"); // Head for floodpod + precache_model ("sprites/s_smoke2.spr"); //Flood blood + precache_sound ("weapons/bigneedler.wav"); // + precache_model ("progs/needler_dust.spr"); + + // Solitude precaches + + // Weapons (first-person) + precache_model ("progs/v_shotgun.mdl"); + precache_model ("progs/v_rocket.mdl"); + precache_model ("progs/v_uzi.mdl"); + precache_model ("progs/v_sniper.mdl"); + precache_model ("progs/v_plpist.mdl"); + precache_model ("progs/v_needle.mdl"); + precache_model ("progs/v_plrifle.mdl"); + + // Weapons sounds + //Reload + precache_sound ("weapons/reload/pistol.wav"); + precache_sound ("weapons/reload/needler.wav"); + precache_sound ("weapons/reload/ar.wav"); + precache_sound ("weapons/reload/sniper.wav"); + precache_sound ("weapons/reload/uzi.wav"); + precache_sound ("weapons/reload/rocket.wav"); + precache_sound ("weapons/reload/shottie.wav"); // reload sounds + + //melee + precache_sound ("weapons/melee/needler.wav"); + precache_sound ("weapons/melee/pistol.wav"); + + // Grenades + precache_model ("progs/fraggren.mdl"); + precache_model ("progs/plasgren.mdl"); + precache_model ("sprites/s_plasma4.spr"); + precache_model ("sprites/plasma3.spr"); + precache_sound ("weapons/plasma_blow.wav"); + precache_sound ("weapons/plasma_throw.wav"); + precache_sound ("weapons/pbounce.wav"); + precache_model ("progs/s_smoke1.spr"); // Smoke from explosion + + + // Dropped weapons + precache_model ("progs/g_shot.mdl"); + precache_model ("progs/g_pistol.mdl"); + precache_model ("progs/g_nail.mdl"); + precache_model ("progs/g_uzi.mdl"); + precache_model ("progs/g_rocket.mdl"); + precache_model ("progs/g_sniper.mdl"); + precache_model ("progs/g_needler.mdl"); + precache_model ("progs/g_plpist.mdl"); + precache_sound ("weapons/ppist.wav"); + + // projectiles + precache_model ("progs/sniperbullet.mdl"); + precache_model ("progs/needproy.mdl"); // Needler Projectile + precache_model ("progs/Bigneedproy.mdl"); // Needler Projectile + precache_model ("progs/needpro2.mdl"); // Embedded needle + precache_model ("sprites/muzzleflash.spr"); + precache_model ("sprites/muzzleflash1.spr"); //ar original flash + precache_model ("sprites/muzzleflash2.spr"); + precache_model ("sprites/pistolmuzzleflash.spr"); + precache_model ("sprites/muzzleN.spr"); // Needler Muzzle flash + precache_model ("progs/plasma.spr"); + + //misc precaches + precache_sound ("weapons/zoom.wav"); + precache_sound ("weapons/zoom2.wav"); + precache_sound ("weapons/coil.wav"); + + + //Needler Extra + precache_sound ("weapons/nb.wav"); + precache_sound ("weapons/crystal.wav"); + precache_sound ("weapons/coil.wav"); + + //Equip sounds + precache_sound ("weapons/equip/ar.wav"); + precache_sound ("weapons/equip/needler.wav"); + precache_sound ("weapons/equip/rocket.wav"); + precache_sound ("weapons/equip/pistol.wav"); + precache_sound ("weapons/equip/shotgun.wav"); + precache_sound ("weapons/equip/sniper.wav"); + precache_sound ("weapons/equip/ppist.wav"); + precache_sound ("weapons/equip/smg.wav"); + + + //Shells + precache_model ("progs/shell.mdl"); + precache_model ("progs/shellshot.mdl"); + + + + +}; + + + +/* +=================================== +Muzzle flashes +================================== +*/ + +void() muzzleflash_think = { +self.frame = self.frame + 1; +self.think = SUB_Remove; +self.nextthink = time + 0.02; +}; + +void() muzzleflash2 = { +local entity muzzle; +muzzle = spawn(); +muzzle.owner = self; + + +muzzle.solid = SOLID_NOT; + +setmodel(muzzle,"sprites/muzzleflash1.spr"); +setorigin(muzzle,self.origin + v_forward * 23 + v_right * 6 + '0 0 19'); +muzzle.think = muzzleflash_think; +muzzle.nextthink = time + 0.01; +};void() muzzleflash_think1 = { +self.frame = self.frame + 1; +self.think = SUB_Remove; +self.nextthink = time + 0.01; +}; + +void() muzzleflash3 = { +local entity muzzle; +muzzle = spawn(); +muzzle.owner = self; + + +muzzle.solid = SOLID_NOT; +muzzle.movetype = MOVETYPE_NONE; + + +setmodel(muzzle,"sprites/muzzleflash.spr"); +setorigin(muzzle,self.origin + v_forward * 35 + v_right * 6 + '0 0 15'); +muzzle.think = muzzleflash_think1; +muzzle.nextthink = time + 0.01; +};void() muzzleflash_think2 = { +self.frame = self.frame + 1; +self.think = SUB_Remove; +self.nextthink = time + 0.02; +}; + +void() muzzleflash4 = { +local entity muzzle; +muzzle = spawn(); +muzzle.owner = self; + + +muzzle.solid = SOLID_NOT; +muzzle.movetype = MOVETYPE_NONE; + + +setmodel(muzzle,"sprites/muzzleflash2.spr"); +setorigin(muzzle,self.origin + v_forward * 55 + v_right * 10 + '0 0 13'); +muzzle.think = muzzleflash_think1; +muzzle.nextthink = time + 0.01; +}; + +void() muzzleflash5 = { +local entity muzzle; +muzzle = spawn(); +muzzle.owner = self; + + +muzzle.solid = SOLID_NOT; +muzzle.movetype = MOVETYPE_NONE; + + +setmodel(muzzle,"sprites/pistolmuzzleflash.spr"); +setorigin(muzzle,self.origin + v_forward * 30 + v_right * 8 + '0 0 20'); +muzzle.think = muzzleflash_think2; +muzzle.nextthink = time + 0.01; +};void() muzzleflash_think3 = { +self.frame = self.frame + 1; +self.think = SUB_Remove; +self.nextthink = time + 0.01; +}; +void() muzzleflash_think6 = { +self.frame = self.frame + 2; +self.think = SUB_Remove; +self.nextthink = time + 0.02; +}; +void() muzzleflash6 = { +local entity muzzle; +muzzle = spawn(); +muzzle.owner = self; + + +muzzle.solid = SOLID_NOT; +muzzle.movetype = MOVETYPE_NONE; + + +setmodel(muzzle,"sprites/muzzleN.spr"); +setorigin(muzzle,self.origin + v_forward * 35 + v_right * 10 + '0 0 17'); +muzzle.think = muzzleflash_think6; +muzzle.nextthink = time + 0.01; +}; + +void() muzzleflash7 = { +local entity muzzle; +muzzle = spawn(); +muzzle.owner = self; + + +muzzle.solid = SOLID_NOT; +muzzle.movetype = MOVETYPE_NONE; + + +setmodel(muzzle,"sprites/muzzleflash.spr"); +setorigin(muzzle,self.origin + v_forward * 45 + v_right * 2 + '0 0 17'); +muzzle.think = muzzleflash_think1; +muzzle.nextthink = time + 0.01; +}; + +#define crandom() (2*(random()-0.5)) + +void() W_UpdateWeapon; + +// The weapon the player spawns with +void () W_StartWeapon = +{ + self.items = WEAPON_AR + WEAPON_PPISTOL; + self.ammo_nails = W_GetMaxClip(self.weapon, 4); + self.exnails = 560; + self.ammo_ppistol = 100; + self.currentammo = W_GetMaxClip(self.weapon, 4); + + self.weapon = WEAPON_AR; + W_UpdateWeapon(); + + W_UpdateAmmoCounts(self); +}; +/* +Ammo update functions +*/ +// xavior: FIXME instead of using W_SetCurrentAmmo! +//Mexicouger: Handle the Ammo count HUD here, rather than PlayerPreThink. It is way more efficient Memory wise.(10-15 fps) +void(entity ent) W_UpdateAmmoCounts = +{ + AmmoCounter(); + // solitude + switch (ent.weapon) + { + case WEAPON_PISTOL: + ent.currentammo = ent.ammo_shells; + ent.armorvalue = ent.exshells; + break; + case WEAPON_SKULL: + ent.currentammo = ent.ammo_shells; + ent.armorvalue = ent.exshells; + break; + case WEAPON_SHOT: + ent.currentammo = ent.ammo_shells2; + ent.armorvalue = ent.exshells2; + break; + case WEAPON_AR: + ent.currentammo = ent.ammo_nails; + ent.armorvalue = ent.exnails; + break; + case WEAPON_UZI: + ent.currentammo = ent.ammo_hshells; + ent.armorvalue = ent.exhshells; + break; + case WEAPON_RL: + ent.currentammo = ent.ammo_rockets; + ent.armorvalue = ent.exrockets; + break; + case WEAPON_SNIPER: + ent.currentammo = ent.ammo_sniper; + ent.armorvalue = ent.exsniper; + break; + case WEAPON_PPISTOL: + ent.currentammo = ent.ammo_ppistol; + ent.armorvalue = ent.exppistol; + break; + case WEAPON_SWORD: + ent.currentammo = ent.ammo_sword; + ent.armorvalue = ent.exsword; + break; + case WEAPON_NEEDLER: + ent.currentammo = ent.ammo_needler; + ent.armorvalue = ent.exneedler; + break; + case WEAPON_PRIFLE: + ent.currentammo = ent.ammo_prifle; + ent.armorvalue = ent.exprifle; + break; + default: + ent.currentammo = 12; + break; + } +}; + +// Damage per individual bullets +float (float t_wep) W_BulletDamage = +{ + switch (t_wep) { + case WEAPON_SHOT: + return 8; + break; + default: + return 4; + break; + } + return 4; +}; + +// cliptype 1 = max size per clip +// cliptype 0 = max extra ammo the player can carry +float (float wep, float cliptype) W_GetMaxClip = +{ + // solitude + switch (wep) + { + case WEAPON_PISTOL: + if (cliptype) + return 12; + else + return 90; + break; + case WEAPON_SKULL: + if (cliptype) + return 12; + else + return 90; + break; + case WEAPON_SHOT: + if (cliptype) + return 6; + else + return 30; + break; + case WEAPON_AR: + if (cliptype) + return 32; + else + return 560; + break; + case WEAPON_UZI: + if (cliptype) + return 60; + else + return 560; + break; + case WEAPON_RL: + if (cliptype) + return 2; + else + return 6; + break; + case WEAPON_SNIPER: + if (cliptype) + return 4; + else + return 20; + break; + case WEAPON_PPISTOL: + if (cliptype) + return 100; + else + return 90; + break; + case WEAPON_SWORD: + if (cliptype) + return 0; // should be 0 - infinite + else + return 0; + break; + case WEAPON_NEEDLER: + if (cliptype) + return 20; + else + return 80; + break; + case WEAPON_PRIFLE: + if (cliptype) + return 100; + else + return 90; + break; + default: + if (cliptype) + return 1; + else + return 90; + break; + } + return 1; +}; + +float (entity ent) W_CanFire = +{ + switch (ent.weapon) + { + case IT_AXE: + return TRUE; + break; + case WEAPON_PISTOL: + if (ent.ammo_shells <= 0) + return FALSE; + break; + case WEAPON_SKULL: + if (ent.ammo_shells <= 0) + return TRUE; + break; + case WEAPON_SHOT: + if (ent.ammo_shells2 <= 0) + return FALSE; + break; + case WEAPON_AR: + if (ent.ammo_nails <= 0) + return FALSE; + break; + case WEAPON_UZI: + if (ent.ammo_hshells <= 0) + return FALSE; + break; + case WEAPON_RL: + if (ent.ammo_rockets <= 0) + return FALSE; + break; + case WEAPON_SNIPER: + if (ent.ammo_sniper <= 0) + return FALSE; + break; + case WEAPON_PPISTOL: + if (ent.ammo_ppistol <= 0) + return FALSE; + break; + case WEAPON_SWORD: + if (ent.ammo_sword <= 0) + return FALSE; + break; + case WEAPON_NEEDLER: + if (ent.ammo_needler <= 0) + return FALSE; + break; + case WEAPON_PRIFLE: + if (ent.ammo_prifle <= 0) + return FALSE; + break; + default: + return TRUE; + break; + } + return TRUE; +}; + +void ( float famt ) Set_FOV = +{ + stuffcmd( self, "fov " ); + stuffcmd( self, ftos( famt ) ); + stuffcmd( self, "\n" ); +}; + +void () WeaponZoom = +{ + float tozoom; + + if (self.health < 1) + return; + + switch (self.weapon) + { + case WEAPON_SNIPER: + if (self.pfov < FOV_DEFAULT) + { tozoom = 15; + sound (self, CHAN_AUTO, "weapons/zoom.wav", 1, ATTN_NORM); + } + else { + tozoom = 45; + sound (self, CHAN_AUTO, "weapons/zoom2.wav", 1, ATTN_NORM); + } + break; + default: + tozoom = 45; + break; + } + if (self.pfov == tozoom) + tozoom = FOV_DEFAULT; + + Set_FOV( tozoom ); + self.pfov = tozoom; +}; + +/* +================ +W_FireAxe +================ +*/ +void(float lunge) W_FireSword = +{ + local vector source; + local vector org; + + makevectors (self.v_angle); + source = self.origin + '0 0 16'; + traceline (source, source + v_forward*64, FALSE, self); + + if (trace_fraction == 1.0) + return; + + org = trace_endpos - v_forward*4; + + if (trace_ent.takedamage) + { + SpawnBlood (org, 20); + if (lunge) + T_Damage (trace_ent, self, self, 150, MOD_AXE); + else + T_Damage (trace_ent, self, self, 75, MOD_AXE); + + } + else + { // hit wall + + sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM); + + TE_gunshot(org); + } +}; + + +//============================================================================ + +/* +================ +SpawnMeatSpray +================ +*/ +void(vector org, vector vel) SpawnMeatSpray = +{ + local entity missile; + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_BOUNCE; + missile.solid = SOLID_NOT; + + makevectors (self.angles); + + missile.velocity = vel; + missile.velocity_z = missile.velocity_z + 250 + 50*random(); + + missile.avelocity = '3000 1000 2000'; + +// set missile duration + missile.nextthink = time + 1; + missile.think = SUB_Remove; + + setmodel (missile, "progs/zom_gib.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, org); +}; + +/* +============================================================================== + +MULTI-DAMAGE + +Collects multiple small damages into a single damage + +============================================================================== +*/ + +entity multi_ent; +float multi_damage; +INTEGER multi_mod; + +vector blood_org; +float blood_count; + + +float puff_count; + +void() ClearMultiDamage = +{ + multi_ent = world; + multi_damage = 0; + blood_count = 0; + puff_count = 0; + multi_mod = MOD_NONE; +}; + +void() ApplyMultiDamage = +{ + if (!multi_ent) + return; + T_Damage (multi_ent, self, self, multi_damage, multi_mod); +}; + +void(entity hit, float damage, INTEGER mod) AddMultiDamage = +{ + if (!hit) + return; + + if (hit != multi_ent || mod != multi_mod) + { + ApplyMultiDamage (); + multi_damage = damage; + multi_ent = hit; + } + else + multi_damage = multi_damage + damage; +}; + +void() Multi_Finish = +{ + if (puff_count) + TE_gunshot(puff_org); + + if (blood_count) + SpawnBlood(blood_org, blood_count); +}; + +/* +============================================================================== +BULLETS +============================================================================== +*/ + +/* +================ +TraceAttack +================ +*/ +void(float damage, vector dir, INTEGER mod) TraceAttack = +{ + local vector vel, org; + + vel = normalize(dir + v_up*crandom() + v_right*crandom()); + vel = vel + 2*trace_plane_normal; + vel = vel * 200; + + org = trace_endpos - dir*4; + + if (trace_ent.takedamage) + { + blood_count = blood_count + 1; + blood_org = org; + AddMultiDamage (trace_ent, damage, mod); + } + else + { + puff_count = puff_count + 1; + } +}; + +/* +================ +FireBullets + +Used by shotgun, super shotgun, and enemy soldier firing +Go to the trouble of combining multiple pellets into a single damage call. +================ +*/ +void(float shotcount, vector dir, vector spread, INTEGER mod) FireBullets = +{ + local vector direction; + local vector src; + + makevectors(self.v_angle); + + src = self.origin + v_forward*10; + src_z = self.absmin_z + self.size_z * 0.7; + + ClearMultiDamage (); + + traceline (src, src + dir*2048, FALSE, self); + puff_org = trace_endpos - dir*4; + + while (shotcount > 0) + { + direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + traceline (src, src + direction*2048, FALSE, self); + if (trace_fraction != 1.0) + TraceAttack (W_BulletDamage(self.weapon), direction, mod); + + shotcount = shotcount - 1; + } + ApplyMultiDamage (); + Multi_Finish (); +}; + +/* +======================================== +################################################### + +Touch Functions (explosions, Bullets, etc) + +################################################## +======================================== +*/ +/* +============================== + +Rocket Launcher Explosion + +============================== +*/ +void() Rocket_Explode0 = +{ + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + T_RadiusDamage (self, self.owner, 190, 160, world, MOD_ROCKET); + + self.origin = self.origin - 8*normalize(self.velocity); + + + CreateExplosion (self.origin); + remove(self); +}; +/* +============================== + +Pistol Touch + +============================== +*/ +void(vector org) PistolTouch = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + if (other.health >= 30) + { + particle (self.origin, '0 4 5', 110, 6); + particle (self.origin, '0 4 5', 109, 6); + } + else + spawn_touchblood (8); + if (other.health <= 30) + T_Damage (other, self, self.owner, 15); + else + T_Damage (other, self, self.owner, 20); + + + } + else + { + particle (self.origin, '0 0 0', 6, 8); + particle (self.origin, '0 0 0', 11, 8); + puff_org = self.origin; + } + remove(self); +}; +/* +============================== + +Assault rifle Touch + +============================== +*/ +void(vector org) ARTouch = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + if (other.health >= 30) + { + particle (self.origin, '0 4 5', 110, 6); + particle (self.origin, '0 4 5', 109, 6); + } + else + spawn_touchblood (8); + if (other.health <= 30) + T_Damage (other, self, self.owner, 5); + else + T_Damage (other, self, self.owner, 5.3); + + + } + else + { + //particle (self.origin, '0 0 0', 6, 8); + particle (self.origin, '0 0 0', 11, 6); + puff_org = self.origin; + } + + remove(self); +}; + +/* +============================== + +SMG Touch + +============================== +*/ +void(vector org) SMGTouch = +{ + self.velocity = '0 0 0'; + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + else if (other.takedamage) { + if (other.health >= 30) + { + particle (self.origin, '0 4 5', 110, 6); + particle (self.origin, '0 4 5', 109, 6); + } + else + spawn_touchblood (8); + if (other.health <= 30) + T_Damage (other, self, self.owner, 4); + else + T_Damage (other, self, self.owner, 4.8); + + + } + else + { + particle (self.origin, '0 0 0', 6, 8); + particle (self.origin, '0 0 0', 11, 8); + puff_org = self.origin; + } + remove(self); +}; + +void(vector org) shotshells = +{ +local entity rock; +local float rand; +local vector dir; +rand = random(); +rock = spawn (); +rock.classname = "gun_shells"; +rock.movetype = MOVETYPE_BOUNCE; +rock.owner = self; +// This is all about how fast the debris goes. (My biggest problem) +makevectors (self.v_angle); +rock.velocity = v_right; +rock.velocity = (rock.velocity * 50); + + +rock.angles = vectoangles (rock.velocity); +rock.avelocity = '300 300 300' * random(); + +rock.solid = SOLID_NOT; + +dir = aim (self, 1000); +// Rock duration (How long the rocks are alive until they disapear +//rock.touch = Debrisbounce; +rock.nextthink = time + 3; +rock.think = SUB_Remove; + +// The whole setting up the model thing. Sets up the sprite and location. +setorigin (rock, ((org + (v_forward * 5)) + '0 0 12')); +if (self.weapon == WEAPON_SHOT) { +setmodel (rock, "progs/shellshot.mdl"); +} +else +setmodel (rock, "progs/shell.mdl"); +}; +void() player_pull; +/* +================ +W_FirePistol +================ +*/ +void() W_FirePistol = +{ + local vector dir; + local entity missile; + + sound (self, CHAN_WEAPON, "weapons/pistol.wav", 1, ATTN_NORM); + + VK_smallkick(self); + + self.ammo_shells -= 1; + W_UpdateAmmoCounts(self); + shotshells(self.origin + (v_forward * 13) + '0 0 12'); + + dir = aim (self, 1000); + pistolsmoke (self.origin); + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_FLYMISSILE; + missile.solid = SOLID_BBOX; + missile.classname = "Pistol"; + +// set missile speed + + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = v_forward; + missile.velocity = missile.velocity * 100000; + missile.angles = vectoangles(missile.velocity); + + missile.touch = PistolTouch; + +// set missile duration + missile.nextthink = time + 5; + missile.think = SUB_Remove; + + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + v_forward*8 + '0 0 16'); + + + +}; +/* +================ +W_FireSkull +================ +*/ +void() W_FireSkull = +{ + local vector dir; + + sound (self, CHAN_WEAPON, "weapons/oddball.wav", 1, ATTN_NORM); + + VK_smallkick(self); + + self.ammo_shells -= 1; + W_UpdateAmmoCounts(self); + + dir = aim (self, 100000); + FireBullets (1, dir, '0 0 0', MOD_SOLITUDE); +}; + +void () Cooldown_Think = +{ + local entity oself; + oself = self; + + if (self.owner == world || self.owner.classname != "player") { + remove(self); + return; + } + if (self.owner.items & WEAPON_PPISTOL) { + if (self.owner.exppistol > 0) { + self.owner.exppistol -= 1; + W_UpdateAmmoCounts(self.owner); + } + } + if (self.owner.items & WEAPON_PRIFLE) { + if (self.owner.exprifle > 0) { + self.owner.exprifle -= 1; + W_UpdateAmmoCounts(self.owner); + } + } + + self.nextthink = time + .05; +}; + +void ( float t_weap, float w_heat ) W_AddHeat = +{ + if (self.pp_cooldown == world) { + self.pp_cooldown = spawn(); + self.pp_cooldown.owner = self; + self.pp_cooldown.weapon = t_weap; + self.pp_cooldown.think = Cooldown_Think; + self.pp_cooldown.nextthink = time + .05; + } + + switch ( t_weap ) { + case WEAPON_PPISTOL: + self.exppistol += w_heat; + break; + case WEAPON_PRIFLE: + self.exprifle += w_heat; + break; + } +}; + +void () Plasma_Diffuse = +{ + self.velocity = '0 0 0'; + self.think = SUB_Remove; + self.nextthink = time + .3; + self.touch = SUB_Null; + if (other.classname == "player") + { + if (other.health >= 30) + { + particle (self.origin, '0 0 0', 110, 6); + particle (self.origin, '0 0 0', 109, 6); + } + else + spawn_touchblood (8); + T_Damage (other, self, self.owner, 10*self.health, MOD_SOLITUDE); + self.nextthink = time + .15; + } +}; + +void( float w_heat ) W_FirePPistol = +{ + local entity plasma; + local float ptake; + local vector dir; + muzzleflash4(); + sound (self, CHAN_WEAPON, "weapons/ppist.wav", 1, ATTN_NORM); + + VK_smallkick(self); + + if (w_heat < 3) + ptake = 1; + else if (w_heat < 7) + ptake = 2; + else if (w_heat < 12) + ptake = 3; + else if (w_heat < 15) + ptake = 4; + else + ptake = 6; + + self.ammo_ppistol -= ptake; + if (self.ammo_ppistol < 0) + self.ammo_ppistol = 0; + W_UpdateAmmoCounts(self); + + plasma = spawn (); + plasma.health = ptake; + plasma.owner = self; + plasma.movetype = 9; + plasma.solid = 2; + makevectors (self.v_angle); + plasma.velocity = v_forward; + plasma.velocity = (plasma.velocity * 3000); // Note: needs sv_maxvelocity set to something like 10,000 at least! + plasma.angles = vectoangles (plasma.velocity); + plasma.touch = Plasma_Diffuse; + plasma.nextthink = (time + 5); + plasma.think = Plasma_Diffuse; + setmodel (plasma, "progs/plasma.spr"); + setsize (plasma, '0 0 0', '0 0 0'); + setorigin (plasma, ((self.origin + (v_forward * 8)) + '0 0 16')); //setorigin (plasma, ((self.origin + (v_forward * 8)) + '0 0 16')); + FireBullets(1, dir, '0.01 0.01 0', MOD_SOLITUDE); + if (ptake > 5) + ptake = 10; + + W_AddHeat ( self.weapon, ptake * 10); +}; + +/* +================================== +Fire The Shotgun +================================= +*/ +void () W_FireShotgun = +{ + local vector dir; + + sound (self, CHAN_WEAPON, "weapons/shottie.wav", 1, ATTN_NORM); + muzzleflash3(); // shottie flash + //self.punchangle_x = CONTENT_EMPTY; + self.ammo_shells2 -= 1; + self.currentammo -= 1; + W_UpdateAmmoCounts(self); + dir = aim (self, 100000); + FireBullets (10, dir, '0.15 0.15 0', MOD_SOLITUDE); + shotshells(self.origin); + pistolsmoke (self.origin + (v_forward * 13) + '0 0 14'); +}; + +/* +=============================== +Fire the Assault rifle +================================= +*/ +void () W_FireAR = +{ + local vector spread; + local entity missile; + local float r; + spread = '0.05 0.05 0.02'; + r = random(); + muzzleflash2(); //ar flash + + self.ammo_nails -= 1; + W_UpdateAmmoCounts(self); + if (r <= 0.5) +sound (self, CHAN_WEAPON, "weapons/ar1.wav", 1, ATTN_NORM); + else if (r <= 1) +sound (self, CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM); + self.punchangle_x = -2; + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_FLYMISSILE; + missile.solid = SOLID_BBOX; + missile.classname = "AR"; + +// set missile speed + + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = v_forward + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + missile.velocity = missile.velocity * 100000; + missile.angles = vectoangles(missile.velocity); + + missile.touch = ARTouch; + +// set missile duration + missile.nextthink = time + 5; + missile.think = SUB_Remove; + + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + v_forward*8 + '0 0 16'); + +}; + + +void (float int) W_FireSpikes; +/* +==================================== +Fire the SMG +==================================== +*/ +void() W_FireUzi = +{ + local vector dir, spread; + local float r; + local entity missile; + spread = '0.06 0.06 0.02'; + + r = random(); + muzzleflash3(); + sound (self, CHAN_WEAPON, "weapons/uzi.wav", 1, ATTN_NORM); + VK_smallkick(self); + self.punchangle_x = CONTENT_EMPTY; + self.ammo_hshells -= 1; + self.currentammo = self.ammo_hshells; + W_UpdateAmmoCounts(self); + dir = aim (self, 1000); +if (r <= 0.33) { +} +else if (r <= 0.66) { +} +else if (r <= 0.99) { +shotshells(self.origin); +} +else{} + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_FLYMISSILE; + missile.solid = SOLID_BBOX; + missile.classname = "SMG"; + +// set missile speed + + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = v_forward + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + missile.velocity = missile.velocity * 100000; + missile.angles = vectoangles(missile.velocity); + + missile.touch = SMGTouch; + +// set missile duration + missile.nextthink = time + 5; + missile.think = SUB_Remove; + + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + v_forward*8 + '0 0 16'); +}; + +void () W_FireNail2 = +{ + local vector dir; + + sound (self, CHAN_WEAPON, "weapons/shotgn2.wav", WEAPON_SHOTGUN, ATTN_NORM); + self.punchangle_x = CONTENT_EMPTY; + self.ammo_shells2 = (self.ammo_shells2 - WEAPON_SHOTGUN); + self.currentammo = (self.ammo_shells2 - WEAPON_SHOTGUN); + dir = aim (self, 100000); + FireBullets (WEAPON_SHOTGUN, dir, '0.07 0.07 0', MOD_SOLITUDE); +}; + +/* +============================ +What happens when the sniper bullet touches something +============================= +*/ +void () SB_Touch = +{ + local vector p_a, p_b; + local float zdif; + + self.velocity = '0 0 0'; + + if (other.takedamage) { + p_a_z = self.origin_z; + p_b_z = other.origin_z; + + zdif = vlen(p_a - p_b); + //_bprint(ftos(zdif),"\n"); + if (zdif > 20) { + T_Damage (other, self, self.owner, 150, MOD_SOLITUDE); + centerprint (self, "Headshot!\n"); } + else + { + if (other.health >= 30) + { + particle (self.origin, '0 0 0', 110, 6); + particle (self.origin, '0 0 0', 109, 6); + } + else + spawn_touchblood (8); + T_Damage (other, self, self.owner, 70, MOD_SOLITUDE); + } + } + else + { + particle (self.origin, '0 0 0', 6, 6); + particle (self.origin, '0 0 0', 11, 6); + puff_org = self.origin; + } + remove(self); +}; + +/* +==================================== +Fire the Sniper Rifle +===================================== +*/ +void() W_FireSniper = +{ + local entity fshell; + + sound (self, CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM); + + VK_bigkick(self); + shotshells(self.origin + (v_forward * 13) + '0 0 16'); + self.ammo_sniper -= 1; + W_UpdateAmmoCounts(self); + + muzzleflash2(); + fshell = spawn (); + fshell.owner = self; + fshell.movetype = 9; + fshell.solid = 2; + makevectors (self.v_angle); + fshell.velocity = v_forward; + fshell.velocity = (fshell.velocity * 999999); // Note: needs sv_maxvelocity set to something like 10,000 at least! + fshell.angles = vectoangles (fshell.velocity); + fshell.touch = SB_Touch; + fshell.nextthink = (time + 5); + fshell.think = SUB_Remove; + setmodel (fshell, "progs/sniperbullet.mdl"); + setsize (fshell, '0 0 0', '0 0 0'); + setorigin (fshell, ((self.origin + (v_forward * 8)) + '0 0 16')); //setorigin (fshell, ((self.origin + (v_forward * 8)) + '0 0 16')); + pistolsmoke (self.origin + (v_forward * 13) + '0 0 8'); +}; + +void () NeedleExplode = +{ + self.enemy.needles -= 1; + T_Damage (self.enemy, self, self.owner, 4, MOD_SOLITUDE); + sound (self, CHAN_WEAPON, "weapons/crystal.wav", 1, ATTN_NORM); + particle (self.origin, '6 6 6', 149, 20); + particle (self.origin, '12 12 0', 149, 20); + particle (self.origin, '-12 -12 0', 149, 20); + particle (self.origin, '-6 -6 -6', 149, 20); + createpinkdust(self.origin); + remove(self); +}; + +void () NeedlePreExplode = +{ + local vector m_height; + m_height_x = self.armorvalue; + + if (self.enemy.health <= 0) { + remove(self); + return; + } + + if (time > self.health) { + NeedleExplode(); + return; + } + + self.origin = self.enemy.origin + m_height; + + self.nextthink = time + .02; +}; + +void ( entity f_plyr, entity t_plyr, float at_height ) Add_Needle = +{ + local entity needle; + local float f_p_height; + f_p_height = at_height - t_plyr.origin_x; + + if (other == world) { + _bprint( "Add_Needle: Cannot assign to world! FIX!!\n"); + return; + } + + if (other.health <= 0) + return; + + t_plyr.needles += 1; + + if (t_plyr.needles >= 12) { + t_plyr.needles -= 7; + sound (self, CHAN_WEAPON, "weapons/crystal.wav", 1, ATTN_NORM); + particle (self.origin, '0 0 8', 149, 60); + createpinkdust(self.origin); + T_Damage (t_plyr, self, f_plyr, 150, MOD_SOLITUDE); + remove(self); + return; + } + + needle = spawn(); + needle.classname = "needle"; + needle.touch = SUB_Null; + needle.solid = SOLID_NOT; + needle.movetype = MOVETYPE_FLY; + needle.health = time + 3; + needle.armorvalue = f_p_height; + needle.enemy = t_plyr; + needle.owner = f_plyr; + setmodel (needle, "progs/needpro2.mdl"); + needle.think = NeedlePreExplode; + needle.nextthink = time; +}; + + +vector(entity proj) bounce_off_wall = // returns the velocity for bouncing off walls +{ + local vector vec; + local float backoff, change; + +// get the trace_plane_normal of the surface we hit + makevectors (proj.angles); + v_forward_z = v_forward_z * -1; + traceline (proj.origin, proj.origin + v_forward*64, FALSE, proj); + + if (trace_fraction == 1) + return proj.velocity; + +// the entity's velocity is not what we want, so set default + proj.velocity = v_forward * 500;//proj.old_velocity; + +// calculate dot product + backoff = (proj.velocity * trace_plane_normal); + backoff = backoff * 1.5; + +// finish + change = trace_plane_normal_x * backoff; + vec_x = proj.velocity_x - change; + + if (vec_x > -0.1 && vec_x < 0.1) + vec_x = 0; + + change = trace_plane_normal_y * backoff; + vec_y = proj.velocity_y - change; + + if (vec_y > -0.1 && vec_y < 0.1) + vec_y = 0; + + change = trace_plane_normal_z * backoff; + vec_z = proj.velocity_z - change; + + if (vec_z > -0.1 && vec_z < 0.1) + vec_z = 0; + sound (self, CHAN_WEAPON, "weapons/nb.wav", 1, ATTN_NORM); +// set correct angles of our new velocity + proj.angles = vectoangles (vec); + // this is required to make downward slopes not stop the projectile + proj.flags = proj.flags - ( proj.flags & FL_ONGROUND ); + return vec; +} + +void () bounce_a = +{ + self.velocity = bounce_off_wall( self ); + + self.nextthink = (time + 0.2); + self.think = NeedlerHome; +}; + +void () Bounce_Off_Walls = +{ + self.nextthink = time; + self.think = bounce_a; + + if (self.velocity == '0 0 0') + remove (self); +}; + + +void () Needler_Touch = +{ + if (other.takedamage != FALSE && other.health > 0) { + T_Damage (other, self, self.owner, 7, MOD_SOLITUDE); + Add_Needle(self.owner, other, self.origin_x); + } + else if (self.lives > 0) { + Bounce_Off_Walls (); + self.lives -= 1; + return; + } + + remove(self); +}; + +void() NeedlerHome = +{ + local vector dir, vtemp, wantdir; + local entity te; + local float maxmove; + maxmove = 55; // maximum xyz value we're allowed to change in mid-air + + if (self.enemy != world && self.enemy.health > 0) { + vtemp = (self.enemy.origin + '0 0 10'); + dir = normalize ((vtemp - self.origin)); + wantdir = (dir * 550); + wantdir_x = wantdir_x - self.velocity_x; + if (wantdir_x > maxmove) + wantdir_x = maxmove; + if (wantdir_x < -maxmove) + wantdir_x = -maxmove; + wantdir_y = wantdir_y - self.velocity_y; + if (wantdir_y > maxmove) + wantdir_y = maxmove; + if (wantdir_y < -maxmove) + wantdir_y = -maxmove; + wantdir_z = wantdir_z - self.velocity_z; + if (wantdir_z > maxmove) + wantdir_z = maxmove; + if (wantdir_z < -maxmove) + wantdir_z = -maxmove; + + + self.velocity += wantdir;//(dir * 550); + } + else { + te = findradius(self.origin, 950); + while (te) + { + if ( (te.classname == "player" || te.flags & FL_MONSTER) && te.health > 0 && te != self.owner) + { + self.enemy = te; + //bprint("found enemy!\n"); + } + te = te.chain; + } + } + self.angles = vectoangles (self.velocity); + + self.nextthink = (time + 0.5); + self.think = NeedlerHome; +}; + +void() W_FireNeedler = +{ + local entity fshell; + local float r; + local vector spread; + r = random(); + muzzleflash6(); + sound (self, CHAN_WEAPON, "weapons/needler.wav", 1, ATTN_NORM); + + spread = '0.04 0.04 0'; + + VK_smallkick(self); + + self.needler_heat += 1; + self.ammo_needler -= 1; + W_UpdateAmmoCounts(self); + + fshell = spawn (); + fshell.owner = self; + fshell.movetype = 9; + fshell.solid = 2; + makevectors (self.v_angle); + fshell.velocity = v_forward + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + fshell.velocity = (fshell.velocity * 550); + fshell.angles = vectoangles (fshell.velocity); + fshell.touch = Needler_Touch; + fshell.armorvalue = time + 15; // amount of time the needler projectile should stay alive + fshell.nextthink = (time + 0.2); + fshell.think = NeedlerHome; + fshell.lives = 1; + + setmodel (fshell, "progs/needproy.mdl"); + setsize (fshell, '0 0 0', '0 0 0'); + setorigin (fshell, ((self.origin + (v_forward * 8)) + '0 0 16')); //setorigin (fshell, ((self.origin + (v_forward * 8)) + '0 0 16')); + if (pointcontents(self.origin) == CONTENT_SKY) { + remove(self); + return; + } +}; + +void () W_FirePlasmaRifle = +{ + local entity plasma; + local vector spread; + spread = '0.02 0.02 0'; + + self.prifle_heat += 1; + sound (self, CHAN_WEAPON, "weapons/tink1.wav", 1, ATTN_NORM); + + + //VK_smallkick(self); + + self.ammo_prifle -= 1; + if (self.ammo_prifle < 0) + self.ammo_prifle = 0; + W_UpdateAmmoCounts(self); + + plasma = spawn (); + plasma.health = 1; + plasma.owner = self; + plasma.movetype = 9; + plasma.solid = 2; + makevectors (self.v_angle); + plasma.velocity = v_forward + crandom()*spread_x*v_right + crandom()*spread_y*v_up; + plasma.velocity = (plasma.velocity * 6000); // Note: needs sv_maxvelocity set to something like 10,000 at least! + plasma.angles = vectoangles (plasma.velocity); + plasma.touch = Plasma_Diffuse; + plasma.nextthink = (time + 5); + plasma.think = Plasma_Diffuse; + setmodel (plasma, "progs/PL_BULL.spr"); + setsize (plasma, '0 0 0', '0 0 0'); + setorigin (plasma, ((self.origin + (v_forward * 8)) + '0 0 16')); //setorigin (plasma, ((self.origin + (v_forward * 8)) + '0 0 16')); + + W_AddHeat ( self.weapon, 10); +}; + +float(vector veca, vector vecb) crossproduct = +{ + local float result; + result = veca_x * vecb_y - vecb_x * veca_y; + return result; +}; + +void () W_Melee = +{ + local vector source; local vector org; + local vector def; + + makevectors (self.v_angle); + source = (self.origin + '0 0 16'); + traceline (source, (source + (v_forward * IT_LIGHTNING)), FALSE, self); + if ((trace_fraction == 1)) + { + self.punchangle_x = -2; + return; + } + self.punchangle_x = CONTENT_SOLID; + org = (trace_endpos - (v_forward * 2)); + + makevectors (trace_ent.v_angle); + def = v_right; + + if (trace_ent.takedamage) + { + trace_ent.axhitme = 1; + SpawnBlood (org, 20); + + makevectors (self.v_angle); + if (crossproduct (def, v_forward) > 0) + T_Damage (trace_ent, self, self, 100, MOD_SOLITUDE); + else + T_Damage (trace_ent, self, self, 50, MOD_SOLITUDE); + } + +}; + +/* +============================================================================== + +ROCKETS + +============================================================================== +*/ + +/* +================ +W_FireRocket +================ +*/ +void() W_FireRocket = +{ + + local entity missile; + + self.ammo_rockets -= 1; + W_UpdateAmmoCounts(self); + muzzleflash3(); + sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM); + + self.punchangle_x = -2; + + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_FLYMISSILE; + missile.solid = SOLID_BBOX; + missile.classname = "Rocket"; + +// set missile speed + + makevectors (self.v_angle); + missile.velocity = aim(self, 1000); + missile.velocity = missile.velocity * 1000; + missile.angles = vectoangles(missile.velocity); + + missile.touch = Rocket_Explode0; + +// set missile duration + missile.nextthink = time + 5; + missile.think = SUB_Remove; + + setmodel (missile, "progs/missile.mdl"); + setsize (missile, '0 0 0', '0 0 0'); + setorigin (missile, self.origin + v_forward*8 + '0 0 16'); + +}; + +/* +=============================================================================== +LIGHTNING +=============================================================================== +*/ + +void(entity from, float damage, INTEGER lmod) LightningHit = +{ + TE_lightningblood(trace_endpos); + + T_Damage (trace_ent, from, from, damage, lmod); +}; + +/* +================= +LightningDamage +================= +*/ +void(vector p1, vector p2, entity from, float damage, INTEGER lmod) LightningDamage = +{ + local entity e1, e2; + local vector f; + + f = p2 - p1; + f = normalize(f); + f_x = 0 - f_y; + f_y = f_x; + f_z = 0; + f = f*16; + + e1 = e2 = world; + + traceline (p1, p2, FALSE, self); + + if (trace_ent.takedamage) + LightningHit (from, damage, lmod); + e1 = trace_ent; + + traceline (p1 + f, p2 + f, FALSE, self); + if (trace_ent != e1 && trace_ent.takedamage) + LightningHit (from, damage, lmod); + e2 = trace_ent; + + traceline (p1 - f, p2 - f, FALSE, self); + if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage) + LightningHit (from, damage, lmod); +}; + + +void() W_FireLightning = +{ + local vector org; + local float cells; + local INTEGER expmod; + + if (self.ammo_cells_real < 1) + { + W_WeaponSwitch (W_BestWeapon ()); + return; + } + +// explode if under water + if (self.waterlevel > 1) + { + if (deathmatch > 3) + { + if (random() <= 0.5) + { + T_Damage (self, self, self.owner, 4000, MOD_SELFWATER); + return; + } + } + + cells = self.ammo_cells_real; + self.ammo_cells_real = 0; + W_WeaponSwitch (W_BestWeapon ()); + expmod = MOD_SHAFTWATER; + if (self.watertype == CONTENT_SLIME) + expmod = MOD_SHAFTSLIME; + else if (self.watertype == CONTENT_LAVA) + expmod = MOD_SHAFTLAVA; + T_RadiusDamage (self, self, 35*cells, 40+35*cells, world, expmod); + return; + } + + if (self.lightning_sound < time) + { + sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM); + self.lightning_sound = time + 0.6; + } + VK_smallkick(self); + + if (deathmatch != 4) + { + self.ammo_cells_real -= 1; + W_UpdateAmmoCounts(self); + } + + org = self.origin + '0 0 16'; + + traceline (org, org + v_forward*600, TRUE, self); + + TE_lightning2(self, org, trace_endpos); + + LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30, MOD_SHAFT); +}; + +void () GrenadeExplode = +{ + if (self.selnade == GRENADE_REGULAR) + CreateExplosion(self.origin); + + else { + plasmaexplo(self.origin); + sound (self, CHAN_WEAPON, "weapons/plasma_blow.wav", 1, ATTN_NORM); + } + + T_RadiusDamage (self, self.owner, 190, 160, world, MOD_SOLITUDE); + + remove(self); +}; + +void () Stick = +{ + if (((self.enemy != world) && (self.enemy.health > 1))) + { + self.think = Stick; + self.touch = Stick; + self.origin = self.enemy.origin; + } + else + { + GrenadeExplode (); + return; + } + self.exshells = (self.exshells + 1); + if ((self.exshells > 15)) + { + GrenadeExplode (); + return; + } + self.nextthink = (time + 0.1); +}; +void () StickyTouch = +{ + if (((other == self.owner) || (other == world))) + { + return; + } + self.exshells = MSG_BROADCAST; + self.movetype = MOVETYPE_NOCLIP; + self.think = Stick; + self.touch = Stick; + self.nextthink = (time + 0.1); + self.avelocity = VEC_ORIGIN; + self.velocity = VEC_ORIGIN; + self.enemy = other; +}; + +float (entity p1, entity p2) Get_ZDiff = +{ + local vector p_a, p_b; + local float zdif; + + p_a_z = p1.origin_z; + + p_b_z = p2.origin_z; + + zdif = vlen(p_a - p_b); + + return (zdif); +} + +void () StickyNade_Stick = +{ + local vector zd; + + if (self.enemy != world && self.enemy.health > 0) { + zd_z = self.armorvalue; + + self.origin = self.enemy.origin + zd; + } + + if (self.weapon < time) { + GrenadeExplode(); + return; + } + + self.nextthink = time + 0.1; +}; + +void () GrenadeBounce = +{ + local vector spot1; + local vector spot2; + + if (self.selnade == GRENADE_STICKY) + { + if ((pointcontents (self.origin) == -6.000000)) + { + remove (self); + return; + } + if (other.takedamage) + { + if (other.origin != '0 0 0') { + self.armorvalue = Get_ZDiff( self, other ); + self.weapon = self.nextthink; + self.think = StickyNade_Stick; + self.enemy = other; + self.nextthink = time; + } + else { + sound (self, 1, "effects/bodyhit2.wav", 1, 1); + } + return; + } + if (other.speed) + { + sound (self, 1, "weapons/bounce.wav", 1, 1); + return; + } + else + { + if (self.selnade == GRENADE_REGULAR) + sound (self, 1, "weapons/bounce.wav", 1, 1); + else + sound (self, 1, "weapons/pbounce.wav", 1, 1); + self.movetype = 0.000000; +// self.solid = 0.000000; + self.solid = 2.000000; // so they can be EMP'd + spot1 = self.origin - (normalize (self.velocity) * 20.000000); + spot2 = self.origin + (normalize (self.velocity) * 20.000000); + traceline (spot1, spot2, 0.000000, self); + self.angles = (vectoangles (trace_plane_normal) + '90.000000 0.000000 0.000000'); + setorigin (self, (self.origin + (trace_plane_normal * 6.000000))); + } + } + else + { + sound (self, 1.000000, "weapons/bounce.wav", 1.000000, 1.000000); + } + if ((self.velocity == '0.000000 0.000000 0.000000')) + { + self.avelocity = '0.000000 0.000000 0.000000'; + } + self.nextthink = (time + 1.5); + self.think = GrenadeExplode; +}; +void () W_ThrowGrenade = +{ + local entity missile; + //local entity mpuff; + local float vel_up; + if (self.selnade == GRENADE_REGULAR) + sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM); + else + sound (self, CHAN_WEAPON, "weapons/plasma_throw.wav", 1, ATTN_NORM); + missile = spawn (); + missile.owner = self; + missile.movetype = MOVETYPE_BOUNCE; + missile.solid = SOLID_BBOX; + missile.classname = "grenade"; + makevectors (self.v_angle); + // looking straight up, don't do "up" velocity + if (self.v_angle_x <= -80) + vel_up = 150 + (self.v_angle_x * 2); + else + vel_up = 130; + + missile.velocity = (v_forward * 320) + (v_up * vel_up) + (v_right * 5); + + missile.avelocity = '300 300 300'; // FIXME: position your grenade model properly! it orbits instead of spinning! + missile.angles = vectoangles (missile.velocity); + missile.selnade = self.selnade; + missile.touch = GrenadeBounce; + //missile.nextthink = (time + 1.5); + //missile.think = GrenadeExplode; + if (self.selnade == GRENADE_STICKY) + setmodel (missile, "progs/plasgren.mdl"); + else + setmodel (missile, "progs/fraggren.mdl"); + + setsize (missile, VEC_ORIGIN, VEC_ORIGIN); + setorigin (missile, ((self.origin + '0 0 16') + (v_right * CONTENT_SKY))); +}; + +//============================================================================= +void(float ox) W_FireSpikes = +{ + if (self.ammo_nails_real < 1) + { + W_WeaponSwitch (W_BestWeapon ()); + return; + } + + sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM); + if (deathmatch != 4) + { + self.ammo_nails_real -= 1; + W_UpdateAmmoCounts(self); + } + + VK_smallkick(self); + PRJ_FireProjectile(self, + "progs/spike.mdl", + self.origin + '0 0 16' + v_right*ox, + aim(self, 1000) * 1000, + PE_SPIKE, + 9, + MOD_SPIKE, + 6); +}; + +void() W_FireSuperSpikes22 = +{ + if (self.ammo_nails_real < 2) + { + W_FireSpikes(0); + return; + } + + sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM); + if (deathmatch != 4) + { + //self.ammo_nails_real -= 2; + self.ammo_hshells -= 2; + W_UpdateAmmoCounts(self); + } + + VK_smallkick(self); + PRJ_FireProjectile(self, + "progs/s_spike.mdl", + self.origin + '0 0 16', + aim(self, 1000) * 1000, + PE_SUPERSPIKE, + 18, + MOD_SUPERSPIKE, + 6); +}; + +/* +=============================================================================== + +PLAYER WEAPON USE + +=============================================================================== +*/ +// different from W_CheckNoAmmo due to SSG/SNG being able to fire 1 shot instead of 2... +BOOL(float wep) W_HasAmmo = +{ + switch (wep) + { + case IT_SHOTGUN: + return self.ammo_shells_real >= 1; + case IT_SUPER_SHOTGUN: + return self.ammo_shells_real >= 2; + case IT_NAILGUN: + return self.ammo_nails_real >= 1; + case IT_SUPER_NAILGUN: + return self.ammo_nails_real >= 2; + case IT_GRENADE_LAUNCHER: + case IT_ROCKET_LAUNCHER: + return self.ammo_rockets_real >= 1; + case IT_LIGHTNING: + return self.ammo_cells_real >= 1; + } + + return TRUE; +}; + +void() W_UpdateWeapon = +{ + player_run (); // get out of any weapon firing states + + self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) ); + + switch (self.weapon) + { + case WEAPON_PISTOL: + self.weaponmodel = "progs/v_shot.mdl"; + self.items = self.items | IT_SHELLS; + self.ammo_type = AT_SHELLS; + break; + case WEAPON_SKULL: + self.weaponmodel = "GameTypes/OddBall/v_skull.mdl"; + self.items = self.items | IT_SHELLS; + self.ammo_type = AT_SHELLS; + break; + case WEAPON_SHOT: + self.weaponmodel = "progs/v_shot2.mdl"; + self.items = self.items | IT_SHELLS; + self.ammo_type = AT_SHELLS; + break; + case WEAPON_AR: + self.weaponmodel = "progs/v_nail.mdl"; + self.items = self.items | IT_NAILS; + self.ammo_type = AT_NAILS; + break; + case WEAPON_UZI: + self.weaponmodel = "progs/v_uzi.mdl"; + self.items = self.items | IT_NAILS; + self.ammo_type = AT_NAILS; // solitude: ammo_hshells + break; + case WEAPON_SNIPER: + self.weaponmodel = "progs/v_sniper.mdl"; + self.items = self.items | IT_SHELLS; + self.ammo_type = AT_SHELLS; + break; + case WEAPON_RL: + self.weaponmodel = "progs/v_rocket.mdl"; + self.items = self.items | IT_ROCKETS; + self.ammo_type = AT_ROCKETS; + break; + case WEAPON_PPISTOL: + self.weaponmodel = "progs/v_plpist.mdl"; + self.items = self.items | IT_CELLS; + self.ammo_type = AT_CELLS; + break; + case WEAPON_SWORD: + self.weaponmodel = "progs/v_axe.mdl"; + self.items = self.items | IT_CELLS; + self.ammo_type = AT_CELLS; + break; + case WEAPON_NEEDLER: + self.weaponmodel = "progs/v_needle.mdl"; + self.items = self.items | IT_CELLS; + self.ammo_type = AT_CELLS; + break; + case WEAPON_PRIFLE: + self.weaponmodel = "progs/v_plrifle.mdl"; + self.items = self.items | IT_CELLS; + self.ammo_type = AT_CELLS; + break; + default: + self.weaponmodel = ""; + } + + self.weaponframe = 0; +}; + +void(float weap) W_WeaponSwitch = +{ + if (self.weaponmodel != "" && self.weaponframe > 0 && self.weaponframe < 4) // xavior: hackish - may need other checks in the future (frames 1 - 4 are generally firing frames) + return; + + // skip weapon model/ammo_type update if this isn't a new weapon + if (self.weapon != weap) + { + self.weapon = weap; + W_UpdateWeapon(); + } + + // always update ammo count + W_UpdateAmmoCounts(self); + + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; +}; + +float() W_BestWeapon = +{ + float fl; + + if (cvar("nobest") == 0) // solitude: debug + return (self.weapon); + + if (self.waterlevel <= 1) + fl = IT_LIGHTNING; + else + fl = IT_SUPER_NAILGUN; + + while (1) + { + if ( (self.items & fl) && W_HasAmmo(fl) ) + return fl; + + // best weapon order + switch (fl) + { + case IT_SKULL: + fl = IT_LIGHTNING; + break; + case IT_LIGHTNING: + fl = IT_SUPER_NAILGUN; + break; + case IT_SUPER_NAILGUN: + fl = IT_SUPER_SHOTGUN; + break; + case IT_SUPER_SHOTGUN: + fl = IT_NAILGUN; + break; + case IT_NAILGUN: + fl = IT_SHOTGUN; + break; + case IT_SHOTGUN: + default: + return IT_AXE; // so we don't get an infinite loop with certain engines + } + } +}; + +BOOL() W_CheckNoAmmo = +{ + if (self.currentammo > 0) + return TRUE; + + if (self.weapon == IT_AXE) + return TRUE; + + W_WeaponSwitch (W_BestWeapon ()); + +// drop the weapon down + return FALSE; +}; + +/* +============ +W_Attack + +An attack impulse can be triggered now +============ +*/ +void() player_shot1; + +// Solitude stuff +void () player_hshot; +void () player_hshot_melee; +void () player_uzi_reload; +void () player_shot_melee; +void () player_shot2_melee; +void () player_nail_melee; +void () player_shot_throw; +void () player_shot2_throw; +void () player_nail_throw; + +void () player_rl_reload; +void () player_rl_throw; +void () player_rl_melee; + +void () player_uzi_throw; + +void () player_sniper_melee; +void () player_sniper_throw; + +//void() player_nail1; +void() player_nail2; +void() muzzleflash; + +void() W_Attack = +{ + float r; + local float heat_multi, i; + local vector source; + + if (!W_CanFire (self)) { + if (self.currentammo == 0) { + if (self.reload_time > time) + return; + reload (); + if (self.needler_heat > 0) + self.needler_heat = 0; + if (self.prifle_heat > 0) + self.prifle_heat = 0; + } + return; + } + + makevectors (self.v_angle); // calculate forward angle for velocity + self.show_hostile = time + 1; // wake monsters up + + if (self.weaponstate == WS_IDLE) // start delay + self.delay = time + 0.1; + + // animations are dealt with here + switch (self.weapon) + { + case WEAPON_PISTOL: + muzzleflash(); + //_bprint(ftos(self.weaponframe), "\n"); + self.weaponframe = 1; + self.wepanim = 1; + self.weaponframe_time = time + 0.1; + break; + case IT_SKULL: + muzzleflash(); + self.weaponframe = 1; + self.wepanim = 1; + break; + case IT_NAILGUN: + muzzleflash(); + self.weaponframe = 1; + self.wepanim = 1; + break; + case IT_SUPER_NAILGUN: + self.weaponframe = WEAPON_SHOTGUN; + player_nail2(); + /* + muzzleflash(); + if (self.weaponframe == 0) + self.weaponframe = 1; + + if (self.weaponframe & 1) + player_nail1(); + else + player_nail2(); + break; + */ + case IT_GRENADE_LAUNCHER: + case IT_ROCKET_LAUNCHER: + self.weaponframe = 1; + muzzleflash(); + //player_rocket1(); + break; + case WEAPON_PPISTOL: + heat_multi = 1; + + i = 0; + while (i < 8) { + i++; + if (self.weaponheat < i*heat_multi) { + self.weaponframe = 4 + i; + break; + } + } + + self.weaponheat++; + if (i >= 8) { + if (self.weaponframe > 13) + self.weaponframe = 12; + else + self.weaponframe++; + } + + if (self.weaponheat > 14) + self.weaponheat = 15; + if (!self.button0 || self.weaponheat > 15) { + muzzleflash(); + W_FirePPistol ( self.weaponheat ); + self.weaponheat = 0; + self.weaponframe_time = time + 0.1; + + if (self.exppistol >= 100) { + self.wepanim = 0; + self.exppistol = 99; + W_UpdateAmmoCounts(self); + self.weaponframe = 16; + player_reload1(); + } + else { + self.weaponframe = 1; + self.wepanim = 1; + } + } + else + self.weaponframe_time = time + 0.2; + + break; + case WEAPON_SWORD: + // See if we should perform a lunge + makevectors (self.v_angle); + source = self.origin + '0 0 16'; + traceline (source, source + v_forward*120, FALSE, self); + + if (trace_ent.classname == "player" && trace_ent.health > 0) { + self.weaponframe = 9; + self.velocity = v_forward*620; + } + else { + r = random(); + + if (r < 0.5) + self.weaponframe = 19; + else + self.weaponframe = 26; + } + self.wepanim = 1; + self.weaponframe_time = time + 0.1; + break; + case WEAPON_PRIFLE: + muzzleflash(); + self.weaponframe = 1; + self.wepanim = 1; + self.weaponframe_time = time + 0.065; + break; + case WEAPON_PISTOL: + muzzleflash(); + self.weaponframe = 1; + self.wepanim = 1; + self.weaponframe_time = time + 0.1; + break; + case WEAPON_SKULL: + muzzleflash(); + self.weaponframe = 1; + self.wepanim = 1; + self.weaponframe_time = time + 0.1; + break; + default: + muzzleflash(); + self.weaponframe = 1; + self.wepanim = 1; + self.weaponframe_time = time + 0.1; + break; + } + + SuperDamageSound(); + + // firing is done here (r is used for round time instead of a temp here) + switch (self.weapon) + { + case WEAPON_PISTOL: + W_FirePistol (); + r = 0.3; + break; + case WEAPON_SKULL: + W_FireSkull (); + r = 0.3; + break; + case WEAPON_SHOT: + W_FireShotgun (); + r = 0.65; + break; + case WEAPON_AR: + W_FireAR(); + r = 0.11; + break; + case WEAPON_RL: + W_FireRocket(); + r = 1.6; + break; + case WEAPON_UZI: + W_FireUzi(); + r = 0.06; + break; + case WEAPON_SNIPER: + W_FireSniper(); + r = 0.8; + break; + case WEAPON_PPISTOL: + //W_FirePPistol(); + r = 0.15; + break; + case WEAPON_SWORD: + //W_FireSword(0); + r = 0.6; + break; + case WEAPON_NEEDLER: + W_FireNeedler(); + if (self.needler_heat > 10) + r = 0.07; + else if (self.needler_heat > 5) + r = 0.12; + else + r = 0.17; + break; + case WEAPON_PRIFLE: + W_FirePlasmaRifle(); + if (self.prifle_heat > 8) + r = 0.125; + else if (self.prifle_heat > 3) + r = 0.15; + else + r = 0.175; + break; + } + + + if (self.weaponstate == WS_IDLE) + self.weaponstate = WS_FIRING1; + + // advance attack time + if (self.attack_finished <= time) + self.attack_finished = self.attack_finished + r; + + // Frikbot - reloading + if (self.ishuman != TRUE) { + //_bprint(ftos(self.currentammo),"\n"); + if (self.currentammo <= 0) { + reload (); + self.currentammo = 1; // so he doesn't run to the player + return; + } + } +}; + +/* +============ +W_ChangeWeapon + +============ +*/ +void() W_ChangeWeapon = +{ + local float fl; + + switch (self.impulse) + { + case 1: + fl = IT_AXE; + break; + case 2: + fl = IT_SHOTGUN; + break; + case 3: + fl = IT_SUPER_SHOTGUN; + break; + case 4: + fl = IT_NAILGUN; + break; + case 5: + fl = IT_SUPER_NAILGUN; + break; + case 6: + fl = IT_GRENADE_LAUNCHER; + break; + case 7: + fl = IT_ROCKET_LAUNCHER; + break; + case 8: + fl = IT_LIGHTNING; + break; + } + + + if (!(self.items & fl)) + { // don't have the weapon or the ammo + sprint1 (self, PRINT_HIGH, "no weapon.\n"); + return; + } + +/* if (!W_HasAmmo(fl)) + { // don't have the ammo + sprint1 (self, PRINT_HIGH, "not enough ammo.\n"); + return; + }*/ + +// +// set weapon, set ammo +// + W_WeaponSwitch (fl); +}; + +/* +============ +CheatCommand +============ +*/ +void() CheatCommand = +{ + if (deathmatch || coop) + return; + +#ifndef IMPULSE9 + bprint("Impulse 9 disabled. Use Impulses 14 through 26 to spawn all weapons.\n"); +#else + self.ammo_rockets_real = 100; + self.ammo_nails_real = 200; + self.ammo_shells_real = 100; + self.ammo_cells_real = 100; + self.items |= IT_AXE | + IT_SHOTGUN | + IT_SUPER_SHOTGUN | + IT_NAILGUN | + IT_SUPER_NAILGUN | + IT_GRENADE_LAUNCHER | + IT_ROCKET_LAUNCHER | + IT_LIGHTNING | + IT_AXE | + WEAPON_NEEDLER | + WEAPON_PRIFLE | + WEAPON_SKULL | + IT_KEY1 | IT_KEY2; + W_WeaponSwitch (IT_ROCKET_LAUNCHER); +#endif +}; + +/* +============ +CycleWeaponCommand + +Go to the next weapon with ammo +============ +*/ +void() CycleWeaponCommand = +{ + local float w; + w = self.weapon; + + while (1) + { + switch (w) + { + case IT_LIGHTNING: + w = IT_AXE; + break; + case IT_AXE: + w = IT_SHOTGUN; + break; + case IT_SHOTGUN: + w = IT_SUPER_SHOTGUN; + break; + case IT_SUPER_SHOTGUN: + w = IT_NAILGUN; + break; + case IT_NAILGUN: + w = IT_SUPER_NAILGUN; + break; + case IT_SUPER_NAILGUN: + w = IT_GRENADE_LAUNCHER; + break; + case IT_GRENADE_LAUNCHER: + w = IT_ROCKET_LAUNCHER; + break; + case IT_ROCKET_LAUNCHER: + w = WEAPON_NEEDLER; + break; + case WEAPON_NEEDLER: + w = WEAPON_PRIFLE; + break; + case WEAPON_PRIFLE: + w = WEAPON_SKULL; + break; + case WEAPON_SKULL: + w = IT_LIGHTNING; + break; + } + + if ( (self.items & w) /*&& W_HasAmmo(w)*/ ) + { + W_WeaponSwitch (w); + return; + } + } + +}; + + +/* +============ +CycleWeaponReverseCommand + +Go to the prev weapon with ammo +============ +*/ +void() CycleWeaponReverseCommand = +{ + local float w; + w = self.weapon; + + while (1) + { + switch (w) + { + case IT_LIGHTNING: + w = IT_ROCKET_LAUNCHER; + break; + case IT_ROCKET_LAUNCHER: + w = IT_GRENADE_LAUNCHER; + break; + case IT_GRENADE_LAUNCHER: + w = IT_SUPER_NAILGUN; + break; + case IT_SUPER_NAILGUN: + w = IT_NAILGUN; + break; + case IT_NAILGUN: + w = IT_SUPER_SHOTGUN; + break; + case IT_SUPER_SHOTGUN: + w = IT_SHOTGUN; + break; + case IT_SHOTGUN: + w = IT_AXE; + break; + case IT_AXE: + w = IT_LIGHTNING; + break; + } + + if ( (self.items & w) && W_HasAmmo(w) ) + { + W_WeaponSwitch (w); + return; + } + } + +}; + + +/* +============ +ServerflagsCommand + +Just for development +============ +*/ +void() ServerflagsCommand = +{ + if (deathmatch || coop) + return; + + serverflags = serverflags * 2 + 1; +}; + +// self heal +void () Heal = +{ +if (self.health >= 120) +particle (self.origin, '0 0 15',110, 10); +else +particle (self.origin, '0 0 10', 110, 1); + self.health = (self.health + 0.5); +}; + +// Solitude Reload +void () reload = +{ + if (self.reload_time > time) + return; + if ( (self.weapon == WEAPON_SHOT) && (self.weaponframe != 0) ) + return; + if (self.armorvalue > 0 && self.currentammo != W_GetMaxClip(self.weapon, 1)) { + switch (self.weapon) { + case WEAPON_PISTOL: + { + sound (self, CHAN_WEAPON, "weapons/reload/pistol.wav", 1, ATTN_NORM); + self.weaponframe = WEAPON_BIG; + break; + } + case WEAPON_SHOT: + { + sound (self, CHAN_WEAPON, "weapons/reload/shottie.wav", 1, ATTN_NORM); + self.weaponframe = 10; + break; + } + case WEAPON_AR: + { + sound (self, CHAN_WEAPON, "weapons/reload/ar.wav", 1, ATTN_NORM); + self.weaponframe = 5; + break; + } + case WEAPON_SNIPER: + { + sound (self, CHAN_WEAPON, "weapons/reload/sniper.wav", 1, ATTN_NORM); + self.weaponframe = 7; + break; + } + case WEAPON_RL: + { + sound (self, CHAN_WEAPON, "weapons/reload/rocket.wav", 1, ATTN_NORM); + self.weaponframe = 11; + break; + } + case WEAPON_NEEDLER: + { + sound (self, CHAN_WEAPON, "weapons/reload/needler.wav", 1, ATTN_NORM); + self.weaponframe = 5; + break; + } + case WEAPON_PPISTOL: + { + return; // No manual reload + } + default: + { + sound (self, CHAN_WEAPON, "weapons/reload/uzi.wav", 1, ATTN_NORM); + self.weaponframe = 4; + break; + } + } + self.attack_finished = (time + 0.2); + player_reload1 (); // now that we set the start frame, begin the reload + } +}; + +/* +============ +ImpulseCommands + +============ +*/ +void() ImpulseCommands = +{ + if (self.impulse == 106) + { + if (self.crouch == 0) + { + self.crouch = 1; + setsize (self, '-16 -16 -24', '16 16 0'); + self.view_ofs = '0 0 10'; + stuffcmd(self,"cl_forwardspeed 100 \n"); + stuffcmd(self,"cl_backspeed 90 \n"); + stuffcmd(self,"cl_sidespeed 100 \n"); + } + else if (self.crouch== 1) + { + self.crouch= 0; + setsize (self, '-16 -16 -24', '16 16 32'); + self.view_ofs = '0 0 22'; + stuffcmd(self,"cl_forwardspeed 200 \n"); + stuffcmd(self,"cl_backspeed 200 \n"); + stuffcmd(self,"cl_sidespeed 200 \n"); + player_stand1 (); + } + } + if (self.weaponheat) + return; + + switch (self.impulse) { + case 1 .. 8: + W_ChangeWeapon (); + break; + case 9: + CheatCommand (); + break; + case 10: + CycleWeaponCommand(); + player_pull(); + break; + case 11: + WeaponZoom (); + break; + case 13: + W_UpdateAmmoCounts(self); + if (self.pickup_time > time) { + self.canpickup_time = time + .1; + return; + } + if (self.pickup_time > time) { + self.canpickup_time = time + .1; + return; + } +// if (time < self.attack_finished) +// return; + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + reload (); + break; + case 14: + ThrowWeapon(WEAPON_PISTOL, 0); + break; + case 30: + ThrowWeapon(WEAPON_SKULL, 0); + break; + case 15: + ThrowWeapon(WEAPON_SHOT, 0); + break; + case 16: + ThrowWeapon(WEAPON_AR, 0); + break; + case 17: + ThrowWeapon(WEAPON_UZI, 0); + break; + case 18: + ThrowWeapon(WEAPON_RL, 0); + break; + case 19: + ThrowWeapon(WEAPON_SNIPER, 0); + break; + case 20: + ThrowWeapon(WEAPON_PPISTOL, 0); + break; + case 21: + ThrowWeapon(WEAPON_SWORD, 0); + break; + case 22: + ThrowWeapon(WEAPON_NEEDLER, 0); + break; + case 23: + ThrowWeapon(WEAPON_PRIFLE, 0); + break; + case 25: + ThrowWeapon(666, 0); + break; + case 26: + ThrowWeapon(667, 0); + break; + case 50: + stuffcmd( self, "play sound/music/Solitude_MainTheme_Low.wav\n" ); + break; + case 29: + { + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + pre_player_melee (); + break; + } + case 29: + { + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + pre_player_melee (); + break; + } + case 27: + { + if (self.selnade == 1) + { + if (self.nade_lives <= 0) + return; + self.nade_lives = self.nade_lives; + self.selnade = 0; + NadeCounter(); + sound (self, CHAN_WEAPON, "weapons/grenpick.wav", 1, ATTN_NORM); + + } + else + { + if (self.selnade == 0) + { + if (self.plasma_lives <= 0) + return; + self.plasma_lives = self.plasma_lives; + self.selnade = 1; + NadeCounter(); + sound (self, CHAN_WEAPON, "weapons/pbounce.wav", 1, ATTN_NORM); + } + } + break; + } + case 28: //Limiter for stopping a Nade throw if you don't have enough nades. + { + Set_FOV ( FOV_DEFAULT ); + self.pfov = FOV_DEFAULT; + if (self.selnade == GRENADE_REGULAR) + { + if (self.nade_lives > 0) + { + pre_player_throw_grenade (); + self.nade_lives -= 1; + NadeCounter(); + return; + } + else + centerprint (self, "No Grenades\n"); + } + else + { + if (self.plasma_lives > 0) { + pre_player_throw_grenade (); + self.plasma_lives -= 1; + NadeCounter(); + return; } + else + centerprint (self, "No Plasma Grenades\n"); + } + break; + } + } + + + self.impulse = 0; +}; + +/* +============ +W_HandlePlayerFrame + +Handle player weapon model +============ +*/ +// ADDME: This function is actually very useful, but my lazy self is not making full use out of it. +// what shoudl be done in the future is allow this function to handle ALL first-person weapon anims +// including melee, throwgren, fire, etc. Right now it only handles a few weapons firing. The rest +// is done in player.qc >.< +// - avirox +void() W_HandlePlayerFrame = +{ + if (!self.weaponframe && !self.wepanim) + return; + + if (self.weaponframe_time >= time) + return; + + switch (self.weapon) + { + case WEAPON_PISTOL: + if (self.weaponframe > 3) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 3) + self.weaponframe = 0; + + //_bprint(ftos(self.weaponframe),"\n"); + break; + case WEAPON_SKULL: + self.wepanim = 0; // No Current Animations + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 16) + self.weaponframe = 0; + break; + case WEAPON_SHOT: + if (self.weaponframe > 9) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 9) + self.weaponframe = 0; + + //_bprint(ftos(self.weaponframe),"\n"); + break; + case WEAPON_AR: + if (self.weaponframe > 3) + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 3) + self.weaponframe = 0; + break; + + case WEAPON_UZI: + // cycle until fire button is released + if (self.weaponframe > 3) + return; + if (self.currentammo == 0) { + self.weaponframe = 0; + return; + } + if (self.weaponstate != WS_IDLE) + { + self.weaponframe_time = time + 0.1; + self.weaponframe = self.weaponframe + 1; + if (self.weaponframe > 2) + self.weaponframe = 1; + } + else + self.weaponframe = 0; + + break; + case WEAPON_RL: + if (self.weaponframe > 11) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 10) + self.weaponframe = 0; + break; + case WEAPON_SNIPER: + if (self.weaponframe > 3) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 3) + self.weaponframe = 0; + break; + case WEAPON_PPISTOL: + if (self.weaponframe > 3) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 3) + self.weaponframe = 0; + break; + case WEAPON_SWORD: + if (self.weaponframe > 18 && self.weaponframe < 25) { // Lunge attack + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe == 21) + W_FireSword(1); + if (self.weaponframe > 24) + self.weaponframe = 0; + } + else if (self.weaponframe > 25 && self.weaponframe < 32) { + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe == 29) + W_FireSword(0); + if (self.weaponframe > 31) + self.weaponframe = 0; + } + else { + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe == 15) + W_FireSword(0); + if (self.weaponframe > 18) + self.weaponframe = 0; + } + break; + case WEAPON_NEEDLER: + if (self.weaponframe > 3) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 3) + self.weaponframe = 0; + break; + case WEAPON_PRIFLE: + if (self.weaponframe > 3) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 3) + self.weaponframe = 0; + break; + default: + // Solitude + if (self.weaponframe > 4) // assume that we're not firing and that animations should be handled in player.qc or elsewhere + return; + self.weaponframe = self.weaponframe + 1; + self.weaponframe_time = time + 0.1; + if (self.weaponframe > 6) + self.weaponframe = 0; + } + + self.wepanim = 0; // turn hack off +}; + +/* +============ +W_WeaponFrame + +Called every frame so impulse events can be handled as well as possible +============ +*/ +void() W_WeaponFrame = +{ + local INTEGER scount; + + W_HandlePlayerFrame(); + + + if ((self.health < self.ohealth)) + { + self.regen = (time + 3); + } + self.ohealth = self.health; + if (((time > self.regen) && (self.health < 130))) + { + Heal (); + } + + if (time < self.attack_finished) + return; + + if (self.impulse) + ImpulseCommands (); + + + +// check for attack + if (self.button0) + { + scount = 0; + // play catchup but don't allow more than 4 shots per frame + while (self.attack_finished <= time) + { + if (scount >= 4) + { + self.attack_finished = time; + break; + } + + W_Attack(); + scount++; + } + } + else + { + if (self.weaponheat > 0) { + W_Attack(); + } + if (self.needler_heat > 0) + self.needler_heat = 0; + if (self.prifle_heat > 0) + self.prifle_heat = 0; + self.attack_finished = time; + self.weaponstate = WS_IDLE; + } +}; + +/* +======== +SuperDamageSound + +Plays sound if needed +======== +*/ +void() SuperDamageSound = +{ + if (self.super_damage_finished > time) + { + if (self.super_sound < time) + { + self.super_sound = time + 1; + sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM); + } + } + return; +}; + +/* +void() testfunction = +{ + local vector v; + local float a, b, c; + + a = 2; + b = 4; + c = 6; + a *= 2; + b *= 2; + c *= 2; + v = '2 4 6'; + v *= 2; + if (!a && !b && !c) + return; + + if (!v) + return; + + v_x = 23; + + if (self.health && self.ammo_shells && self.ammo_cells) + return; +}; +*/ + +// GOLD: this is now a wrapper for W_UpdateAmmoCounts +void () W_SetCurrentAmmo = +{ + self.weaponframe = 0; + W_UpdateAmmoCounts(self); +/* + player_run (); + self.items = (self.items - (self.items & (((IT_SHELLS | IT_NAILS) | IT_ROCKETS) | IT_CELLS))); + if ((self.weapon == IT_AXE)) + { + self.currentammo = MSG_BROADCAST; + self.weaponmodel = "progs/v_axe.mdl"; + self.weaponframe = MSG_BROADCAST; + } + else + { + if ((self.weapon == IT_SHOTGUN)) + { + self.currentammo = self.ammo_shells; + self.weaponmodel = "progs/v_shot.mdl"; + self.weaponframe = MSG_BROADCAST; + self.items = (self.items | IT_SHELLS); + } + else + { + if ((self.weapon == IT_SUPER_SHOTGUN)) + { + self.currentammo = self.ammo_shells2; + self.weaponmodel = "progs/v_shot2.mdl"; + self.weaponframe = MSG_BROADCAST; + } + else + { + if ((self.weapon == IT_NAILGUN)) + { + self.currentammo = self.ammo_nails; + self.weaponmodel = "progs/v_nail.mdl"; + self.weaponframe = MSG_BROADCAST; + } + else + { + if ((self.weapon == IT_SUPER_NAILGUN)) + { + self.currentammo = self.ammo_hshells; + self.weaponmodel = "progs/v_shotgun.mdl"; + self.weaponframe = MSG_BROADCAST; + } + else + { + if ((self.weapon == IT_GRENADE_LAUNCHER)) + { + self.currentammo = self.ammo_rockets; + self.weaponmodel = "progs/v_rock.mdl"; + self.weaponframe = MSG_BROADCAST; + self.items = (self.items | IT_ROCKETS); + } + else + { + if ((self.weapon == IT_ROCKET_LAUNCHER)) + { + self.currentammo = self.ammo_rockets; + self.weaponmodel = "progs/v_rocket.mdl"; + self.weaponframe = MSG_BROADCAST; + self.items = (self.items | IT_ROCKETS); + } + else + { + if ((self.weapon == IT_LIGHTNING)) + { + self.currentammo = self.ammo_cells; + self.weaponmodel = "progs/v_light.mdl"; + self.weaponframe = MSG_BROADCAST; + self.items = (self.items | IT_CELLS); + } + else + { + self.currentammo = MSG_BROADCAST; + self.weaponmodel = ""; + self.weaponframe = MSG_BROADCAST; + } + } + } + } + } + } + } + } + */ +} + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/world.qc b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/world.qc new file mode 100755 index 00000000..3f2c31a7 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/Revamped QC/world.qc @@ -0,0 +1,387 @@ + +void() main = +{ +// these are just commands the the prog compiler to copy these files + + precache_file ("progs.dat"); + precache_file ("gfx.wad"); + precache_file ("quake.rc"); + precache_file ("default.cfg"); + + precache_file ("end1.bin"); + precache_file2 ("end2.bin"); + + precache_file ("demo1.dem"); + precache_file ("demo2.dem"); + precache_file ("demo3.dem"); + +// +// these are all of the lumps from the cached.ls files +// + precache_file ("gfx/palette.lmp"); + precache_file ("gfx/colormap.lmp"); + + precache_file2 ("gfx/pop.lmp"); + + precache_file ("gfx/complete.lmp"); + precache_file ("gfx/inter.lmp"); + + precache_file ("gfx/ranking.lmp"); + precache_file ("gfx/vidmodes.lmp"); + precache_file ("gfx/finale.lmp"); + precache_file ("gfx/conback.lmp"); + precache_file ("gfx/qplaque.lmp"); + + precache_file ("gfx/menudot1.lmp"); + precache_file ("gfx/menudot2.lmp"); + precache_file ("gfx/menudot3.lmp"); + precache_file ("gfx/menudot4.lmp"); + precache_file ("gfx/menudot5.lmp"); + precache_file ("gfx/menudot6.lmp"); + + precache_file ("gfx/menuplyr.lmp"); + precache_file ("gfx/bigbox.lmp"); + precache_file ("gfx/dim_modm.lmp"); + precache_file ("gfx/dim_drct.lmp"); + precache_file ("gfx/dim_ipx.lmp"); + precache_file ("gfx/dim_tcp.lmp"); + precache_file ("gfx/dim_mult.lmp"); + precache_file ("gfx/mainmenu.lmp"); + + precache_file ("gfx/box_tl.lmp"); + precache_file ("gfx/box_tm.lmp"); + precache_file ("gfx/box_tr.lmp"); + + precache_file ("gfx/box_ml.lmp"); + precache_file ("gfx/box_mm.lmp"); + precache_file ("gfx/box_mm2.lmp"); + precache_file ("gfx/box_mr.lmp"); + + precache_file ("gfx/box_bl.lmp"); + precache_file ("gfx/box_bm.lmp"); + precache_file ("gfx/box_br.lmp"); + + precache_file ("gfx/sp_menu.lmp"); + precache_file ("gfx/ttl_sgl.lmp"); + precache_file ("gfx/ttl_main.lmp"); + precache_file ("gfx/ttl_cstm.lmp"); + + precache_file ("gfx/mp_menu.lmp"); + + precache_file ("gfx/netmen1.lmp"); + precache_file ("gfx/netmen2.lmp"); + precache_file ("gfx/netmen3.lmp"); + precache_file ("gfx/netmen4.lmp"); + precache_file ("gfx/netmen5.lmp"); + + precache_file ("gfx/sell.lmp"); + + precache_file ("gfx/help0.lmp"); + precache_file ("gfx/help1.lmp"); + precache_file ("gfx/help2.lmp"); + precache_file ("gfx/help3.lmp"); + precache_file ("gfx/help4.lmp"); + precache_file ("gfx/help5.lmp"); + + precache_file ("gfx/pause.lmp"); + precache_file ("gfx/loading.lmp"); + + precache_file ("gfx/p_option.lmp"); + precache_file ("gfx/p_load.lmp"); + precache_file ("gfx/p_save.lmp"); + precache_file ("gfx/p_multi.lmp"); + + + + +// sounds loaded by C code + precache_sound ("misc/menu1.wav"); + precache_sound ("misc/menu2.wav"); + precache_sound ("misc/menu3.wav"); + + precache_sound ("ambience/water1.wav"); + precache_sound ("ambience/wind2.wav"); + +// shareware + precache_file ("maps/start.bsp"); + +// registered + precache_file2 ("gfx/pop.lmp"); + + }; + +//======================= +/*QUAKED worldspawn (0 0 0) ? +Only used for the world entity. +Set message to the level name. +Set sounds to the cd track to play. + +World Types: +0: medieval +1: metal +2: base +*/ +//======================= +void() worldspawn = +{ + local float sol_grav, sol_ms; + + lastspawn = world; + spotspawn = 0; + + BotInit(); // FrikBot + ENG_Check(); + + sol_grav = cvar("sol_gravity"); + sol_ms = cvar("sol_maxspeed"); + + if (sol_grav) + cvar_set ("sv_gravity", ftos(sol_grav)); + else + cvar_set ("sv_gravity", "#DEFAULT_GRAVITY"); + + if (sol_ms) + cvar_set ("sv_maxspeed", ftos(sol_ms)); + else + cvar_set ("sv_maxspeed", "#DEFAULT_MAXSPEED"); + + cvar_set ("sv_maxvelocity", "10000"); // for the sniper projectile +#ifndef NETQUAKE +// custom map attributes + if (self.model == "maps/e1m8.bsp") + cvar_set ("sv_gravity", "100"); +#endif + +// the area based ambient sounds MUST be the first precache_sounds + +// player precaches + W_Precache (); // get weapon precaches + +// sounds used from C physics code + precache_sound ("demon/dland2.wav"); // landing thud + precache_sound ("misc/h2ohit1.wav"); // landing splash + +// setup precaches allways needed + precache_sound ("items/itembk2.wav"); // item respawn sound + precache_sound ("player/plyrjmp8.wav"); // player jump + precache_sound ("player/land.wav"); // player landing + precache_sound ("player/land2.wav"); // player hurt landing + precache_sound ("player/drown1.wav"); // drowning pain + precache_sound ("player/drown2.wav"); // drowning pain + precache_sound ("player/gasp1.wav"); // gasping for air + precache_sound ("player/gasp2.wav"); // taking breath + precache_sound ("player/h2odeath.wav"); // drowning death + + precache_sound ("misc/talk.wav"); // talk + precache_sound ("player/teledth1.wav"); // telefrag + precache_sound ("misc/r_tele1.wav"); // teleport sounds + precache_sound ("misc/r_tele4.wav"); // teleport sounds + precache_sound ("misc/r_tele5.wav"); // teleport sounds + precache_sound ("misc/r_tele2.wav"); // teleport sounds + precache_sound ("misc/r_tele3.wav"); // teleport sounds + precache_sound ("weapons/lock4.wav"); // ammo pick up + precache_sound ("weapons/pkup.wav"); // weapon up + precache_sound ("items/armor1.wav"); // armor up + precache_sound ("weapons/lhit.wav"); //lightning + precache_sound ("weapons/lstart.wav"); //lightning start + precache_sound ("items/damage3.wav"); + + precache_sound ("misc/power.wav"); //lightning for boss + +// player pain sounds + + precache_sound ("player/pain1.wav"); + +// player death sounds + precache_sound ("player/death1.wav"); + + precache_sound ("boss1/sight1.wav"); + +// ax sounds + precache_sound ("weapons/ax1.wav"); // ax swoosh + precache_sound ("player/axhit1.wav"); // ax hit meat + precache_sound ("player/axhit2.wav"); // ax hit world + + precache_sound ("player/h2ojump.wav"); // player jumping into water + precache_sound ("player/slimbrn2.wav"); // player enter slime + precache_sound ("player/inh2o.wav"); // player enter water + precache_sound ("player/inlava.wav"); // player enter lava + precache_sound ("misc/outwater.wav"); // leaving water sound + + precache_sound ("player/lburn1.wav"); // lava burn + precache_sound ("player/lburn2.wav"); // lava burn + + precache_sound ("misc/water1.wav"); // swimming + precache_sound ("misc/water2.wav"); // swimming + +// Invulnerability sounds + precache_sound ("items/protect.wav"); + precache_sound ("items/protect2.wav"); + precache_sound ("items/protect3.wav"); + + + precache_model ("progs/player.mdl"); + precache_model ("progs/eyes.mdl"); + precache_model ("progs/h_player.mdl"); + precache_sound ("player/tornoff2.wav"); + + precache_model ("progs/s_bubble.spr"); // drowning bubbles + precache_model ("progs/s_explod.spr"); // sprite explosion + + precache_model ("progs/v_axe.mdl"); + precache_model ("progs/v_shot.mdl"); + precache_model ("progs/v_nail.mdl"); + precache_model ("progs/v_rock.mdl"); + precache_model ("progs/v_shot2.mdl"); + precache_model ("progs/v_nail2.mdl"); + + precache_model ("progs/bolt.mdl"); // for lightning gun + precache_model ("progs/bolt2.mdl"); // for lightning gun + precache_model ("progs/bolt3.mdl"); // for boss shock + precache_model ("progs/lavaball.mdl"); // for testing + + precache_model ("progs/missile.mdl"); + precache_model ("progs/grenade.mdl"); + precache_model ("progs/spike.mdl"); + precache_model ("progs/s_spike.mdl"); + + precache_model ("progs/backpack.mdl"); + + precache_model ("progs/zom_gib.mdl"); + + precache_model ("progs/v_light.mdl"); + + +// +// Setup light animation tables. 'a' is total darkness, 'z' is maxbright. +// + + // 0 normal + lightstyle(0, "m"); + + // 1 FLICKER (first variety) + lightstyle(1, "mmnmmommommnonmmonqnmmo"); + + // 2 SLOW STRONG PULSE + lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); + + // 3 CANDLE (first variety) + lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); + + // 4 FAST STROBE + lightstyle(4, "mamamamamama"); + + // 5 GENTLE PULSE 1 + lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj"); + + // 6 FLICKER (second variety) + lightstyle(6, "nmonqnmomnmomomno"); + + // 7 CANDLE (second variety) + lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm"); + + // 8 CANDLE (third variety) + lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); + + // 9 SLOW STROBE (fourth variety) + lightstyle(9, "aaaaaaaazzzzzzzz"); + + // 10 FLUORESCENT FLICKER + lightstyle(10, "mmamammmmammamamaaamammma"); + + // 11 SLOW PULSE NOT FADE TO BLACK + lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba"); + + // styles 32-62 are assigned by the light program for switchable lights + + // 63 testing + lightstyle(63, "a"); +}; + +void() StartFrame = +{ + BotFrame(); // FrikBot + timelimit = cvar("timelimit") * 60; + fraglimit = cvar("fraglimit"); +#ifdef NETQUAKE + deathmatch = cvar("deathmatch"); + coop = cvar("coop"); + teamplay = cvar("teamplay"); +#endif + skill = cvar("skill"); + + framecount = framecount + 1; +}; +void() func_rotating = + +{ + + self.solid = SOLID_BSP; + + self.movetype = MOVETYPE_PUSH; + + setorigin (self, self.origin); + + setmodel (self, self.model); + + self.classname = "func_rotating"; + + setsize (self, self.mins, self.maxs); + + + + if (!self.speed) + + self.speed = 100; + + + + if (self.spawnflags & 2) // reverse direction + + self.speed = 0 - self.speed; + + + + if (self.spawnflags & 64) // not solid + + self.solid = SOLID_NOT; + + + + if (self.spawnflags & 4) + + { + + self.avelocity_z = self.speed; + + self.avelocity_x = 0; + + self.avelocity_y = 0; + + } + + else if (self.spawnflags & 8) + + { + + self.avelocity_z = 0; + + self.avelocity_x = self.speed; + + self.avelocity_y = 0; + + } + + else + + { + + self.avelocity_z = 0; + + self.avelocity_x = 0; + + self.avelocity_y = self.speed; + + } + +}; diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/autoexec.cfg b/r17/Revamped src/revamped_src/psp/normal/ID1/autoexec.cfg new file mode 100755 index 00000000..1ffba660 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/autoexec.cfg @@ -0,0 +1,2 @@ +fov 80 +impulse 50 \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/default.CFG b/r17/Revamped src/revamped_src/psp/normal/ID1/default.CFG new file mode 100755 index 00000000..0fbc5d71 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/default.CFG @@ -0,0 +1,148 @@ +bind "TAB" "+showscores" +bind "ESCAPE" "togglemenu" +bind "+" "sizeup" +bind "," "+moveleft" +bind "-" "sizedown" +bind "." "+moveright" +bind "0" "impulse 0" +bind "1" "impulse 1" +bind "2" "impulse 2" +bind "3" "impulse 3" +bind "4" "impulse 4" +bind "5" "impulse 5" +bind "6" "impulse 6" +bind "7" "impulse 7" +bind "8" "impulse 8" +bind "=" "sizeup" +bind "\" "+mlook" +bind "`" "impulse 27" +bind "a" "+moveleft" +bind "c" "+movedown" +bind "d" "+moveright" +bind "s" "+back" +bind "t" "messagemode" +bind "w" "+forward" +bind "z" "+lookdown" +bind "~" "impulse 11" +bind "UPARROW" "impulse 10" +bind "DOWNARROW" "+jump" +bind "LEFTARROW" "impulse 13" +bind "RIGHTARROW" "impulse 29" +bind "ALT" "+strafe" +bind "F1" "help" +bind "F2" "menu_save" +bind "F3" "menu_load" +bind "F4" "menu_options" +bind "F5" "menu_multiplayer" +bind "F6" "echo Quicksaving...; wait; save quick" +bind "F9" "echo Quickloading...; wait; load quick" +bind "F10" "quit" +bind "F11" "zoom_in" +bind "F12" "screenshot" +bind "INS" "+klook" +bind "DEL" "+lookdown" +bind "PGDN" "+lookup" +bind "END" "centerview" +bind "MOUSE2" "+forward" +bind "MOUSE3" "+mlook" +bind "TRIANGLE" "+forward" +bind "CIRCLE" "+moveright" +bind "CROSS" "+back" +bind "SQUARE" "+moveleft" +bind "LTRIGGER" "impulse 28" +bind "RTRIGGER" "+attack" +bind "MWHEELDOWN" "impulse 12" +bind "PAUSE" "pause" +m_side "0.8" +m_forward "1" +m_yaw "0.022" +m_pitch "0.022000" +UWF_S "0" +UWF_E "400" +UWF_BLUE "230" +UWF_GREEN "134" +UWF_RED "38" +UWF "1" +r_hudalpha "0.5" +in_y_axis_adjust "4" +in_x_axis_adjust "4" +in_analog_strafe "0" +in_disable_analog "0.000000" +in_freelook_analog "1" +acceleration "3.000000" +tolerance "0.470000" +sensitivity "10" +lookcenter "1" +lookstrafe "1" +lookspring "0" +cl_autoaim "2" +cl_backspeed "200" +cl_forwardspeed "200" +_cl_color "68" +_cl_name "Team Xlink" +_snd_mixahead "0.1" +bgmtype "cd" +bgmvolume "1" +volume "0.500000" +vl_lowcut "60" +vl_highcut "128" +vl_yaw "45" +vl_pitch "45" +vl_light "0" +gl_keeptjunctions "1" +r_model_brightness "1" +r_model_contrast "0" +r_i_model_transform "1" +r_i_model_animation "1" +r_antialias "0" +r_mipmaps_bias "-5.500000" +r_mipmaps_func "0" +r_mipmaps "1" +r_dithering "0" +r_vsync "0" +r_particles_simple "0" +r_tex_scale_down "1" +r_dynamic "0" +r_menufade "0.9" +r_skyclip "2560" +r_skyfog "1" +scr_loadscreen "0" +scr_conheight "0.5" +viewsize "120" +sv_aim "2.0" +accesspoint "9" +_config_modem_hangup "AT H" +_config_modem_init "" +_config_modem_clear "ATZ" +_config_modem_dialtype "T" +_config_com_modem "1" +_config_com_baud "57600" +_config_com_irq "4" +_config_com_port "0x3f8" +gl_subdivide_size "256" +saved4 "0" +saved3 "271" +saved2 "3" +saved1 "-571" +savedgamecfg "1" +max_fps "999" +show_fps "0" +gamma "1" +cl_bobsideup "0.5" +cl_bobsidecycle "0.9" +cl_bobside "0.02" +cl_bobup "0.0" +cl_bobcycle "0.7" +cl_bob "0.015" +r_viewmodeloffset "0" +crosshair "11" +v_idlescale "0.1" +v_ipitch_level "0.30" +v_iroll_level "0.35" +v_iyaw_level "0.40" +v_ipitch_cycle "12" +v_iroll_cycle "6" +v_iyaw_cycle "6" +v_centerspeed "170" +v_centermove "1" +fov "80" diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/demo1.dem b/r17/Revamped src/revamped_src/psp/normal/ID1/demo1.dem new file mode 100755 index 00000000..6b371a91 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/demo1.dem differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/demo2.dem b/r17/Revamped src/revamped_src/psp/normal/ID1/demo2.dem new file mode 100755 index 00000000..6b371a91 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/demo2.dem differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/demo3.dem b/r17/Revamped src/revamped_src/psp/normal/ID1/demo3.dem new file mode 100755 index 00000000..6b371a91 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/demo3.dem differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx.wad b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx.wad new file mode 100755 index 00000000..fc8d109c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx.wad differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BALLOON4.SPR b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BALLOON4.SPR new file mode 100755 index 00000000..f3bb5b28 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BALLOON4.SPR differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BLOOD.SPR b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BLOOD.SPR new file mode 100755 index 00000000..577cef6e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BLOOD.SPR differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BLOOD1.SPR b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BLOOD1.SPR new file mode 100755 index 00000000..72259fa7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BLOOD1.SPR differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_BL.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_BL.LMP new file mode 100755 index 00000000..9e49ba42 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_BL.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_BM.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_BM.LMP new file mode 100755 index 00000000..a1598c89 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_BM.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_BR.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_BR.LMP new file mode 100755 index 00000000..9671c8e6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_BR.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_ML.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_ML.LMP new file mode 100755 index 00000000..a821cecf Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_ML.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_MM.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_MM.LMP new file mode 100755 index 00000000..24afdcf5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_MM.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_MM2.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_MM2.LMP new file mode 100755 index 00000000..24afdcf5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_MM2.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_MR.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_MR.LMP new file mode 100755 index 00000000..049f2244 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_MR.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_TL.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_TL.LMP new file mode 100755 index 00000000..8e5dc279 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_TL.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_TM.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_TM.LMP new file mode 100755 index 00000000..7f7d481e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_TM.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_TR.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_TR.LMP new file mode 100755 index 00000000..e3b3d7ec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BOX_TR.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BUMPMAP.RAW b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BUMPMAP.RAW new file mode 100755 index 00000000..43102d8e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/BUMPMAP.RAW differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_AXE.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_AXE.LMP new file mode 100755 index 00000000..9876fbbc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_AXE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_GL.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_GL.lmp new file mode 100755 index 00000000..a163c20c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_GL.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_LIGHT.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_LIGHT.LMP new file mode 100755 index 00000000..052f081a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_LIGHT.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_NGUN.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_NGUN.LMP new file mode 100755 index 00000000..3576f612 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_NGUN.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_RL.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_RL.LMP new file mode 100755 index 00000000..26d43f8b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_RL.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_SGUN.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_SGUN.LMP new file mode 100755 index 00000000..b058cbb5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_SGUN.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_SNGUN.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_SNGUN.LMP new file mode 100755 index 00000000..3576f612 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_SNGUN.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_SSGUN.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_SSGUN.LMP new file mode 100755 index 00000000..5fbc4107 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_SSGUN.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_TEKBO.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_TEKBO.LMP new file mode 100755 index 00000000..9876fbbc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CH_TEKBO.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/COLORMAP.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/COLORMAP.LMP new file mode 100755 index 00000000..e71995b8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/COLORMAP.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/COMPLETE.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/COMPLETE.LMP new file mode 100755 index 00000000..bd100145 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/COMPLETE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CONBACK.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CONBACK.LMP new file mode 100755 index 00000000..aed8d1fe Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CONBACK.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CONBACKS.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CONBACKS.lmp new file mode 100755 index 00000000..703a1aef Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/CONBACKS.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ConBack2.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ConBack2.lmp new file mode 100755 index 00000000..a92c94b3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ConBack2.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_DRCT.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_DRCT.LMP new file mode 100755 index 00000000..9c3e340b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_DRCT.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_IPX.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_IPX.LMP new file mode 100755 index 00000000..ec5806de Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_IPX.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_MODM.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_MODM.LMP new file mode 100755 index 00000000..d030b34d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_MODM.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_MULT.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_MULT.LMP new file mode 100755 index 00000000..0e4f88f8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_MULT.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_TCP.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_TCP.LMP new file mode 100755 index 00000000..ec00f342 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/DIM_TCP.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/all-wcprops b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/all-wcprops new file mode 100755 index 00000000..209e6f41 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/all-wcprops @@ -0,0 +1,563 @@ +K 25 +svn:wc:ra_dav:version-url +V 45 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV +END +CLIFF_UP.PCX +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/CLIFF_UP.PCX +END +nrblue_512_lf.lmp +K 25 +svn:wc:ra_dav:version-url +V 63 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_512_lf.lmp +END +nrblue_512_dn.lmp +K 25 +svn:wc:ra_dav:version-url +V 63 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_512_dn.lmp +END +SKY_FT.lmp +K 25 +svn:wc:ra_dav:version-url +V 54 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/SKY_FT.lmp +END +stars_up.lmp +K 25 +svn:wc:ra_dav:version-url +V 56 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/stars_up.lmp +END +CLIFF_BK.PCX +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/CLIFF_BK.PCX +END +sky_ringblue256up.pcx +K 25 +svn:wc:ra_dav:version-url +V 67 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/sky_ringblue256up.pcx +END +CLIFF_LF.LMP +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/CLIFF_LF.LMP +END +CLIFF_DN.LMP +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/CLIFF_DN.LMP +END +daybluedn.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/daybluedn.lmp +END +daybluelf.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/daybluelf.lmp +END +desert_dn.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/desert_dn.lmp +END +desert_lf.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/desert_lf.lmp +END +stars_bk.lmp +K 25 +svn:wc:ra_dav:version-url +V 56 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/stars_bk.lmp +END +sky_ringblue256bk.pcx +K 25 +svn:wc:ra_dav:version-url +V 67 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/sky_ringblue256bk.pcx +END +SKY_RT.lmp +K 25 +svn:wc:ra_dav:version-url +V 54 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/SKY_RT.lmp +END +niteblueup.lmp +K 25 +svn:wc:ra_dav:version-url +V 60 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/niteblueup.lmp +END +RingBl.lmp +K 25 +svn:wc:ra_dav:version-url +V 56 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/RingBl.lmp +END +CLIFF_FT.PCX +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/CLIFF_FT.PCX +END +starsdn.lmp +K 25 +svn:wc:ra_dav:version-url +V 57 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/starsdn.lmp +END +starslf.lmp +K 25 +svn:wc:ra_dav:version-url +V 57 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/starslf.lmp +END +nitebluebk.lmp +K 25 +svn:wc:ra_dav:version-url +V 60 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/nitebluebk.lmp +END +stars_ft.lmp +K 25 +svn:wc:ra_dav:version-url +V 56 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/stars_ft.lmp +END +sky_ringblue256ft.pcx +K 25 +svn:wc:ra_dav:version-url +V 67 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/sky_ringblue256ft.pcx +END +ringbl512lf.pcx +K 25 +svn:wc:ra_dav:version-url +V 61 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/ringbl512lf.pcx +END +ringbl512dn.pcx +K 25 +svn:wc:ra_dav:version-url +V 61 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/ringbl512dn.pcx +END +CLIFF_RT.PCX +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/CLIFF_RT.PCX +END +nrblue_up.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_up.lmp +END +ringbllf.lmp +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/ringbllf.lmp +END +ringbldn.lmp +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/ringbldn.lmp +END +sky_512_up.lmp +K 25 +svn:wc:ra_dav:version-url +V 60 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/sky_512_up.lmp +END +stars_rt.lmp +K 25 +svn:wc:ra_dav:version-url +V 56 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/stars_rt.lmp +END +niteblueft.lmp +K 25 +svn:wc:ra_dav:version-url +V 60 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/niteblueft.lmp +END +sky_ringblue256rt.pcx +K 25 +svn:wc:ra_dav:version-url +V 67 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/sky_ringblue256rt.pcx +END +nrblue_bk.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_bk.lmp +END +dayblue_palette.lmp +K 25 +svn:wc:ra_dav:version-url +V 65 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/dayblue_palette.lmp +END +sky_512_bk.lmp +K 25 +svn:wc:ra_dav:version-url +V 60 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/sky_512_bk.lmp +END +sky_512_palette.lmp +K 25 +svn:wc:ra_dav:version-url +V 65 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/sky_512_palette.lmp +END +nitebluert.lmp +K 25 +svn:wc:ra_dav:version-url +V 60 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/nitebluert.lmp +END +nrblue_ft.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_ft.lmp +END +nrblue_512_up.lmp +K 25 +svn:wc:ra_dav:version-url +V 63 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_512_up.lmp +END +sky_palette.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/sky_palette.lmp +END +sky_512_ft.lmp +K 25 +svn:wc:ra_dav:version-url +V 60 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/sky_512_ft.lmp +END +SKY_DN.lmp +K 25 +svn:wc:ra_dav:version-url +V 54 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/SKY_DN.lmp +END +CLIFF_UP.LMP +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/CLIFF_UP.LMP +END +SKY_LF.lmp +K 25 +svn:wc:ra_dav:version-url +V 54 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/SKY_LF.lmp +END +nrblue_512_bk.lmp +K 25 +svn:wc:ra_dav:version-url +V 63 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_512_bk.lmp +END +desert_up.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/desert_up.lmp +END +dayblueup.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/dayblueup.lmp +END +nrblue_rt.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_rt.lmp +END +stars.pcx +K 25 +svn:wc:ra_dav:version-url +V 55 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/stars.pcx +END +CLIFF_BK.LMP +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/CLIFF_BK.LMP +END +cliff_palette.lmp +K 25 +svn:wc:ra_dav:version-url +V 63 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/cliff_palette.lmp +END +starsup.lmp +K 25 +svn:wc:ra_dav:version-url +V 57 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/starsup.lmp +END +daybluebk.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/daybluebk.lmp +END +desert_bk.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/desert_bk.lmp +END +sky_512_rt.lmp +K 25 +svn:wc:ra_dav:version-url +V 60 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/sky_512_rt.lmp +END +CLIFF_LF.PCX +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/CLIFF_LF.PCX +END +CLIFF_DN.PCX +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/CLIFF_DN.PCX +END +nrblue_512_ft.lmp +K 25 +svn:wc:ra_dav:version-url +V 63 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_512_ft.lmp +END +starsbk.lmp +K 25 +svn:wc:ra_dav:version-url +V 57 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/starsbk.lmp +END +ringbl512up.pcx +K 25 +svn:wc:ra_dav:version-url +V 61 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/ringbl512up.pcx +END +CLIFF_FT.LMP +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/CLIFF_FT.LMP +END +stars_dn.lmp +K 25 +svn:wc:ra_dav:version-url +V 56 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/stars_dn.lmp +END +stars_lf.lmp +K 25 +svn:wc:ra_dav:version-url +V 56 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/stars_lf.lmp +END +sky_ringblue256dn.pcx +K 25 +svn:wc:ra_dav:version-url +V 67 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/sky_ringblue256dn.pcx +END +sky_ringblue256lf.pcx +K 25 +svn:wc:ra_dav:version-url +V 67 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/sky_ringblue256lf.pcx +END +dayblueft.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/dayblueft.lmp +END +desert_ft.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/desert_ft.lmp +END +ringblup.lmp +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/ringblup.lmp +END +nrblue_512_rt.lmp +K 25 +svn:wc:ra_dav:version-url +V 63 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_512_rt.lmp +END +ringbl512bk.pcx +K 25 +svn:wc:ra_dav:version-url +V 61 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/ringbl512bk.pcx +END +starsft.lmp +K 25 +svn:wc:ra_dav:version-url +V 57 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/starsft.lmp +END +CLIFF_RT.LMP +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/CLIFF_RT.LMP +END +nitebluelf.lmp +K 25 +svn:wc:ra_dav:version-url +V 60 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/nitebluelf.lmp +END +nitebluedn.lmp +K 25 +svn:wc:ra_dav:version-url +V 60 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/nitebluedn.lmp +END +ringblbk.lmp +K 25 +svn:wc:ra_dav:version-url +V 56 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/ringblbk.lmp +END +desert_rt.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/desert_rt.lmp +END +daybluert.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/daybluert.lmp +END +ringbl512ft.pcx +K 25 +svn:wc:ra_dav:version-url +V 61 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/ringbl512ft.pcx +END +starsrt.lmp +K 25 +svn:wc:ra_dav:version-url +V 57 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/starsrt.lmp +END +desert_palette.lmp +K 25 +svn:wc:ra_dav:version-url +V 62 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/desert_palette.lmp +END +nrblue_palette.lmp +K 25 +svn:wc:ra_dav:version-url +V 64 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_palette.lmp +END +ringblft.lmp +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/ringblft.lmp +END +nrblue_lf.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_lf.lmp +END +nrblue_dn.lmp +K 25 +svn:wc:ra_dav:version-url +V 59 +/Solitude/!svn/ver/429/Solitude/Build/GFX/ENV/nrblue_dn.lmp +END +SKY_UP.lmp +K 25 +svn:wc:ra_dav:version-url +V 54 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/SKY_UP.lmp +END +ringbl512rt.pcx +K 25 +svn:wc:ra_dav:version-url +V 61 +/Solitude/!svn/ver/343/Solitude/Build/GFX/ENV/ringbl512rt.pcx +END +sky_512_dn.lmp +K 25 +svn:wc:ra_dav:version-url +V 60 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/sky_512_dn.lmp +END +sky_512_lf.lmp +K 25 +svn:wc:ra_dav:version-url +V 60 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/sky_512_lf.lmp +END +SKY_BK.lmp +K 25 +svn:wc:ra_dav:version-url +V 54 +/Solitude/!svn/ver/3/Solitude/Build/GFX/ENV/SKY_BK.lmp +END +ringblrt.lmp +K 25 +svn:wc:ra_dav:version-url +V 58 +/Solitude/!svn/ver/244/Solitude/Build/GFX/ENV/ringblrt.lmp +END +niteblue_palette.lmp +K 25 +svn:wc:ra_dav:version-url +V 66 +/Solitude/!svn/ver/235/Solitude/Build/GFX/ENV/niteblue_palette.lmp +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/entries b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/entries new file mode 100755 index 00000000..61284d75 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/entries @@ -0,0 +1,3190 @@ +10 + +dir +512 +http://75.48.194.8/Solitude/Solitude/Build/GFX/ENV +http://75.48.194.8/Solitude + + + +2003-09-24T06:09:54.593750Z +429 +IlDucci + + + + + + + + + + + + + + +14c127e1-643c-4043-9e75-c4f0517262c3 + +CLIFF_UP.PCX +file + + + + +2009-09-08T00:12:09.218750Z +4c875efd0774429e852e70f4f78d1af9 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +41259 + +nrblue_512_lf.lmp +file + + + + +2009-09-08T00:12:09.375000Z +0af808047cc59741ad3e9553d7d22283 +2003-09-24T06:09:54.593750Z +429 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +262152 + +nrblue_512_dn.lmp +file + + + + +2009-09-08T00:12:09.312500Z +3b019dbfeb0db603fc88a86c14bfb8ac +2003-09-24T06:09:54.593750Z +429 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +262152 + +SKY_FT.lmp +file + + + + +2009-09-08T00:12:09.265625Z +fe7232a6b3df07ca6b30dbc2c43a00b8 +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +stars_up.lmp +file + + + + +2009-09-08T00:12:09.406250Z +a7e85f5417eb62bb1d6a24b8c0aa5b52 +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +CLIFF_BK.PCX +file + + + + +2009-09-08T00:12:09.500000Z +ff9013d63f1229ac986e041f710b3a40 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +76209 + +sky_ringblue256up.pcx +file + + + + +2009-09-08T00:12:09.468750Z +1fad5fbb72fd490b3b5930bf722de48c +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +48789 + +CLIFF_LF.LMP +file + + + + +2009-09-08T00:12:09.578125Z +fc8ec2911224965466bc9f8de606d0c9 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +CLIFF_DN.LMP +file + + + + +2009-09-08T00:12:09.531250Z +e318af8ee212759455b5fa3ad6e32fa0 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +daybluedn.lmp +file + + + + +2009-09-08T00:12:09.890625Z +0b89130eceddd7ca5054e10735c209ca +2009-08-06T13:18:46.203125Z +235 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +daybluelf.lmp +file + + + + +2009-09-08T00:12:09.828125Z +d0dca7cbe8c43504a42bbcea536de5b3 +2009-08-06T13:18:46.203125Z +235 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +desert_dn.lmp +file + + + + +2009-09-08T00:12:09.781250Z +e318af8ee212759455b5fa3ad6e32fa0 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +desert_lf.lmp +file + + + + +2009-09-08T00:12:09.703125Z +fc8ec2911224965466bc9f8de606d0c9 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +stars_bk.lmp +file + + + + +2009-09-08T00:12:09.968750Z +a7e85f5417eb62bb1d6a24b8c0aa5b52 +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +sky_ringblue256bk.pcx +file + + + + +2009-09-08T00:12:10.015625Z +35f95fa5e00ee3bcabaea3ba9b3f126c +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +66118 + +SKY_RT.lmp +file + + + + +2009-09-08T00:12:10.078125Z +325313d66a510b5f50d6046bfcf1aee3 +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +niteblueup.lmp +file + + + + +2009-09-08T00:12:10.109375Z +3102c56d3ab6ac4b2c243946e00b1392 +2009-08-06T13:18:46.203125Z +235 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +RingBl.lmp +file + + + + +2009-09-08T00:12:10.140625Z +6d7d1c5a0cd538e47de636103a780f77 +2003-09-25T02:13:38.781250Z +244 +TeamXlink + + + + + + + + + + + + + + + + + + + + + +768 + +CLIFF_FT.PCX +file + + + + +2009-09-08T00:12:10.187500Z +c7a9b22de4040d91b8169b6f12a61679 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +54859 + +starsdn.lmp +file + + + + +2009-09-08T00:12:10.203125Z +a7e85f5417eb62bb1d6a24b8c0aa5b52 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +starslf.lmp +file + + + + +2009-09-08T00:12:10.250000Z +a7e85f5417eb62bb1d6a24b8c0aa5b52 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +nitebluebk.lmp +file + + + + +2009-09-08T00:12:10.312500Z +ce2f1acb228c65038b9c776e3a812aaa +2009-08-06T13:18:46.203125Z +235 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +stars_ft.lmp +file + + + + +2009-09-08T00:12:10.343750Z +a7e85f5417eb62bb1d6a24b8c0aa5b52 +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +sky_ringblue256ft.pcx +file + + + + +2009-09-08T00:12:10.406250Z +100ed043b6eaef8f7eefebe3e16745a6 +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +67490 + +ringbl512lf.pcx +file + + + + +2009-09-08T00:12:10.468750Z +5aee26bb2b1259a042624f48b0a619a9 +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +210537 + +ringbl512dn.pcx +file + + + + +2009-09-08T00:12:10.500000Z +4276e5b6b87a016d510efe6f4cabe017 +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +253903 + +CLIFF_RT.PCX +file + + + + +2009-09-08T00:12:10.531250Z +5b21e6c5f7a5a991ceccae66d499aa82 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65790 + +nrblue_up.lmp +file + + + + +2009-09-08T00:12:10.578125Z +f5d15b2179f719338582ebeed7c14522 +2003-09-24T06:09:54.593750Z +429 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +ringbllf.lmp +file + + + + +2009-09-08T00:12:10.640625Z +6eb2488432e4a6c7920d06cc8706d015 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +ringbldn.lmp +file + + + + +2009-09-08T00:12:10.703125Z +a332ff9247d3ed582510d474b115757e +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +sky_512_up.lmp +file + + + + +2009-09-08T00:12:10.968750Z +35ed7f56366bfa502fb5218905ad9b90 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +262152 + +niteblueft.lmp +file + + + + +2009-09-08T00:12:10.906250Z +4cd6ec85daf63a672208484709e586fd +2009-08-06T13:18:46.203125Z +235 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +stars_rt.lmp +file + + + + +2009-09-08T00:12:10.828125Z +a7e85f5417eb62bb1d6a24b8c0aa5b52 +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +sky_ringblue256rt.pcx +file + + + + +2009-09-08T00:12:11.031250Z +9e065c1845d2e1bbe32e014cd6c9f085 +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +62579 + +nrblue_bk.lmp +file + + + + +2009-09-08T00:12:11.109375Z +51a45a46119c40568167a1028a3532a4 +2003-09-24T06:09:54.593750Z +429 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +dayblue_palette.lmp +file + + + + +2009-09-08T00:12:11.062500Z +0e4963bc7a1e75ccd977e5704d793774 +2009-08-06T13:18:46.203125Z +235 +IlDucci + + + + + + + + + + + + + + + + + + + + + +768 + +sky_512_bk.lmp +file + + + + +2009-09-08T00:12:11.171875Z +f6919350bc6a1ff034a4da6b8b547e9a +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +262152 + +sky_512_palette.lmp +file + + + + +2009-09-08T00:12:11.218750Z +6d7d1c5a0cd538e47de636103a780f77 +2003-09-25T02:13:38.781250Z +244 +TeamXlink + + + + + + + + + + + + + + + + + + + + + +768 + +nitebluert.lmp +file + + + + +2009-09-08T00:12:11.312500Z +3008628e1a864a2a05d96026d56b748e +2009-08-06T13:18:46.203125Z +235 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +nrblue_ft.lmp +file + + + + +2009-09-08T00:12:11.343750Z +7f36e89cb10de14f82bb6ef0de923a8f +2003-09-24T06:09:54.593750Z +429 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +nrblue_512_up.lmp +file + + + + +2009-09-08T00:12:11.375000Z +688d071f27bb52022acc1dca43be19dc +2003-09-24T06:09:54.593750Z +429 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +262152 + +sky_palette.lmp +file + + + + +2009-09-08T00:12:11.406250Z +845cf931e90cbcec6afda8234a143596 +2009-07-25T01:52:00.250000Z +3 + + + + + + + + + + + + + + + + + + + + + + +768 + +sky_512_ft.lmp +file + + + + +2009-09-08T00:12:11.421875Z +094e8a5d3e51e81a5ac2fe48a43964b5 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +262152 + +SKY_DN.lmp +file + + + + +2009-09-08T00:12:11.453125Z +a332ff9247d3ed582510d474b115757e +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +CLIFF_UP.LMP +file + + + + +2009-09-08T00:12:11.453125Z +d7b2e13fa331f9326d9089f35f8b00f1 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +SKY_LF.lmp +file + + + + +2009-09-08T00:12:11.437500Z +6eb2488432e4a6c7920d06cc8706d015 +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +nrblue_512_bk.lmp +file + + + + +2009-09-08T00:12:11.500000Z +d128fc6d3840f5c8576ffea296d8b88b +2003-09-24T06:09:54.593750Z +429 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +262152 + +desert_up.lmp +file + + + + +2009-09-08T00:12:11.484375Z +d7b2e13fa331f9326d9089f35f8b00f1 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +dayblueup.lmp +file + + + + +2009-09-08T00:12:11.468750Z +897bb133e282414d8e9cd8df30f386b0 +2009-08-06T13:18:46.203125Z +235 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +nrblue_rt.lmp +file + + + + +2009-09-08T00:12:11.515625Z +15446a980bb92f41e0b5b9e5752fe2d1 +2003-09-24T06:09:54.593750Z +429 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +stars.pcx +file + + + + +2009-09-08T00:12:11.546875Z +25b34932a9e02d280dfc2197b35efe69 +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +7769 + +CLIFF_BK.LMP +file + + + + +2009-09-08T00:12:11.546875Z +b731ffa41bcb1218162aa22a13f55d00 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +cliff_palette.lmp +file + + + + +2009-09-08T00:12:11.640625Z +6d7d1c5a0cd538e47de636103a780f77 +2003-09-25T02:13:38.781250Z +244 +TeamXlink + + + + + + + + + + + + + + + + + + + + + +768 + +starsup.lmp +file + + + + +2009-09-08T00:12:11.562500Z +a7e85f5417eb62bb1d6a24b8c0aa5b52 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +daybluebk.lmp +file + + + + +2009-09-08T00:12:11.812500Z +d9047c18a1f73f679be12a568945f0f2 +2009-08-06T13:18:46.203125Z +235 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +desert_bk.lmp +file + + + + +2009-09-08T00:12:11.750000Z +b731ffa41bcb1218162aa22a13f55d00 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +sky_512_rt.lmp +file + + + + +2009-09-08T00:12:11.703125Z +043ec4c70df4e6c3adb243dec47eeff7 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +262152 + +CLIFF_LF.PCX +file + + + + +2009-09-08T00:12:11.984375Z +21538ab1787942f6fc8c808a2f2079af +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +60079 + +CLIFF_DN.PCX +file + + + + +2009-09-08T00:12:11.937500Z +ca4eac22512b64efed80a65b586d42f4 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +77645 + +nrblue_512_ft.lmp +file + + + + +2009-09-08T00:12:12.031250Z +c00e4b8b355f483aa7a43c27b49c4e84 +2003-09-24T06:09:54.593750Z +429 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +262152 + +starsbk.lmp +file + + + + +2009-09-08T00:12:12.109375Z +a7e85f5417eb62bb1d6a24b8c0aa5b52 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +ringbl512up.pcx +file + + + + +2009-09-08T00:12:12.203125Z +db8f5b8185ad589202c35f84be38f21f +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +247557 + +CLIFF_FT.LMP +file + + + + +2009-09-08T00:12:12.171875Z +84f88c5c8a7166b7371cfcc31e00bdfe +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +stars_dn.lmp +file + + + + +2009-09-08T00:12:12.250000Z +a7e85f5417eb62bb1d6a24b8c0aa5b52 +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +stars_lf.lmp +file + + + + +2009-09-08T00:12:12.296875Z +a7e85f5417eb62bb1d6a24b8c0aa5b52 +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +sky_ringblue256dn.pcx +file + + + + +2009-09-08T00:12:12.359375Z +2c950b7845d258aa08c594e1bb7219be +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +77127 + +sky_ringblue256lf.pcx +file + + + + +2009-09-08T00:12:12.406250Z +c0e5864505a40974df200b1691f37231 +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +61371 + +dayblueft.lmp +file + + + + +2009-09-08T00:12:12.437500Z +f0c9b2e9bd1dd8033239ddd2d9f300b5 +2009-08-06T13:18:46.203125Z +235 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +desert_ft.lmp +file + + + + +2009-09-08T00:12:12.484375Z +84f88c5c8a7166b7371cfcc31e00bdfe +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +ringblup.lmp +file + + + + +2009-09-08T00:12:12.546875Z +7a4dec8e5e1763f6d701f2ee669da490 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +nrblue_512_rt.lmp +file + + + + +2009-09-08T00:12:12.609375Z +7a64a903da966a35762404700f6e7e99 +2003-09-24T06:09:54.593750Z +429 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +262152 + +ringbl512bk.pcx +file + + + + +2009-09-08T00:12:12.671875Z +440d0342634a4531ab6e11132609bff9 +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +218997 + +starsft.lmp +file + + + + +2009-09-08T00:12:12.703125Z +a7e85f5417eb62bb1d6a24b8c0aa5b52 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +CLIFF_RT.LMP +file + + + + +2009-09-08T00:12:12.765625Z +c0301640dbd1df96199f9704606f779f +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +nitebluelf.lmp +file + + + + +2009-09-08T00:12:12.906250Z +0e5911b658e033a8b52f3dd7321e3135 +2009-08-06T13:18:46.203125Z +235 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +nitebluedn.lmp +file + + + + +2009-09-08T00:12:12.984375Z +83dc376dbf7b3b07aada50b93f50ccc4 +2009-08-06T13:18:46.203125Z +235 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +ringblbk.lmp +file + + + + +2009-09-08T00:12:13.125000Z +7f2bff5f483e52b248a42531131572b3 +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +desert_rt.lmp +file + + + + +2009-09-08T00:12:13.218750Z +c0301640dbd1df96199f9704606f779f +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +daybluert.lmp +file + + + + +2009-09-08T00:12:13.343750Z +6fedbdf05001a395126e3a9db048d391 +2009-08-06T13:18:46.203125Z +235 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +ringbl512ft.pcx +file + + + + +2009-09-08T00:12:13.437500Z +f1ff40fefc0ab810c6e9b7ef64dd1966 +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +237556 + +starsrt.lmp +file + + + + +2009-09-08T00:12:13.484375Z +a7e85f5417eb62bb1d6a24b8c0aa5b52 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +desert_palette.lmp +file + + + + +2009-09-08T00:12:13.562500Z +2cb1cebe3d9ac38ce96910ba7e07070a +2009-07-25T01:52:00.250000Z +3 + + + + + + + + + + + + + + + + + + + + + + +768 + +nrblue_palette.lmp +file + + + + +2009-09-08T00:12:13.609375Z +5e0336342cc148bc8ac6a346c95bff90 +2003-09-24T06:09:54.593750Z +429 +IlDucci + + + + + + + + + + + + + + + + + + + + + +768 + +ringblft.lmp +file + + + + +2009-09-08T00:12:13.671875Z +fe7232a6b3df07ca6b30dbc2c43a00b8 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +nrblue_lf.lmp +file + + + + +2009-09-08T00:12:13.718750Z +5a35dfb619390ebd72f1e362dd8d4a82 +2003-09-24T06:09:54.593750Z +429 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +nrblue_dn.lmp +file + + + + +2009-09-08T00:12:13.765625Z +deb92e69034ca5d5ff7a0568febccd59 +2003-09-24T06:09:54.593750Z +429 +IlDucci +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +SKY_UP.lmp +file + + + + +2009-09-08T00:12:13.859375Z +7a4dec8e5e1763f6d701f2ee669da490 +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +ringbl512rt.pcx +file + + + + +2009-09-08T00:12:13.906250Z +fdfc52fe6f162a9d97ee652d9d91de59 +2003-09-23T06:20:02.609375Z +343 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +232873 + +sky_512_dn.lmp +file + + + + +2009-09-08T00:12:13.968750Z +cd462f898c44be111b3a3c312b2d1565 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +262152 + +sky_512_lf.lmp +file + + + + +2009-09-08T00:12:14.046875Z +9ebca2574af5f39de64f6e1feeeb45fc +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +262152 + +SKY_BK.lmp +file + + + + +2009-09-08T00:12:14.125000Z +7f2bff5f483e52b248a42531131572b3 +2009-07-25T01:52:00.250000Z +3 + +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +ringblrt.lmp +file + + + + +2009-09-08T00:12:14.218750Z +325313d66a510b5f50d6046bfcf1aee3 +2003-09-25T02:13:38.781250Z +244 +TeamXlink +has-props + + + + + + + + + + + + + + + + + + + + +65544 + +niteblue_palette.lmp +file + + + + +2009-09-08T00:12:14.281250Z +12b1a832bad8f297d424913148e1935a +2009-08-06T13:18:46.203125Z +235 +IlDucci + + + + + + + + + + + + + + + + + + + + + +768 + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_BK.LMP.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_BK.LMP.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_BK.LMP.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_BK.PCX.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_BK.PCX.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_BK.PCX.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_DN.LMP.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_DN.LMP.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_DN.LMP.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_DN.PCX.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_DN.PCX.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_DN.PCX.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_FT.LMP.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_FT.LMP.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_FT.LMP.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_FT.PCX.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_FT.PCX.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_FT.PCX.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_LF.LMP.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_LF.LMP.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_LF.LMP.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_LF.PCX.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_LF.PCX.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_LF.PCX.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_RT.LMP.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_RT.LMP.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_RT.LMP.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_RT.PCX.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_RT.PCX.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_RT.PCX.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_UP.LMP.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_UP.LMP.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_UP.LMP.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_UP.PCX.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_UP.PCX.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/CLIFF_UP.PCX.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_BK.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_BK.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_BK.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_DN.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_DN.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_DN.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_FT.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_FT.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_FT.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_LF.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_LF.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_LF.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_RT.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_RT.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_RT.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_UP.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_UP.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/SKY_UP.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/daybluebk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/daybluebk.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/daybluebk.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/daybluedn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/daybluedn.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/daybluedn.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/dayblueft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/dayblueft.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/dayblueft.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/daybluelf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/daybluelf.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/daybluelf.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/daybluert.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/daybluert.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/daybluert.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/dayblueup.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/dayblueup.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/dayblueup.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_bk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_bk.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_bk.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_dn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_dn.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_dn.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_ft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_ft.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_ft.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_lf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_lf.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_lf.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_rt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_rt.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_rt.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_up.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_up.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/desert_up.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nitebluebk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nitebluebk.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nitebluebk.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nitebluedn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nitebluedn.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nitebluedn.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/niteblueft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/niteblueft.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/niteblueft.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nitebluelf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nitebluelf.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nitebluelf.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nitebluert.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nitebluert.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nitebluert.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/niteblueup.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/niteblueup.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/niteblueup.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_bk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_bk.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_bk.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_dn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_dn.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_dn.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_ft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_ft.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_ft.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_lf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_lf.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_lf.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_rt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_rt.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_rt.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_up.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_up.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_512_up.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_bk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_bk.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_bk.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_dn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_dn.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_dn.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_ft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_ft.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_ft.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_lf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_lf.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_lf.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_rt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_rt.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_rt.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_up.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_up.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/nrblue_up.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512bk.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512bk.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512bk.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512dn.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512dn.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512dn.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512ft.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512ft.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512ft.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512lf.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512lf.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512lf.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512rt.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512rt.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512rt.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512up.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512up.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbl512up.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringblbk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringblbk.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringblbk.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbldn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbldn.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbldn.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringblft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringblft.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringblft.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbllf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbllf.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringbllf.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringblrt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringblrt.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringblrt.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringblup.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringblup.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/ringblup.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_bk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_bk.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_bk.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_dn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_dn.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_dn.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_ft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_ft.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_ft.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_lf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_lf.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_lf.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_rt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_rt.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_rt.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_up.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_up.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_512_up.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256bk.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256bk.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256bk.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256dn.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256dn.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256dn.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256ft.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256ft.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256ft.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256lf.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256lf.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256lf.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256rt.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256rt.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256rt.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256up.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256up.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/sky_ringblue256up.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars.pcx.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars.pcx.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_bk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_bk.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_bk.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_dn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_dn.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_dn.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_ft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_ft.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_ft.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_lf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_lf.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_lf.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_rt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_rt.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_rt.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_up.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_up.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/stars_up.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsbk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsbk.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsbk.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsdn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsdn.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsdn.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsft.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsft.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starslf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starslf.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starslf.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsrt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsrt.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsrt.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsup.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsup.lmp.svn-base new file mode 100755 index 00000000..5e9587e6 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/prop-base/starsup.lmp.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_BK.LMP.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_BK.LMP.svn-base new file mode 100755 index 00000000..eb0c0569 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_BK.LMP.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_BK.PCX.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_BK.PCX.svn-base new file mode 100755 index 00000000..0d02892b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_BK.PCX.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_DN.LMP.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_DN.LMP.svn-base new file mode 100755 index 00000000..0ea8a4e6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_DN.LMP.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_DN.PCX.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_DN.PCX.svn-base new file mode 100755 index 00000000..e9654eaa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_DN.PCX.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_FT.LMP.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_FT.LMP.svn-base new file mode 100755 index 00000000..2769d88b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_FT.LMP.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_FT.PCX.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_FT.PCX.svn-base new file mode 100755 index 00000000..1b72af98 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_FT.PCX.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_LF.LMP.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_LF.LMP.svn-base new file mode 100755 index 00000000..68b86cca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_LF.LMP.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_LF.PCX.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_LF.PCX.svn-base new file mode 100755 index 00000000..624e6635 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_LF.PCX.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_RT.LMP.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_RT.LMP.svn-base new file mode 100755 index 00000000..78475641 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_RT.LMP.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_RT.PCX.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_RT.PCX.svn-base new file mode 100755 index 00000000..d45cebec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_RT.PCX.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_UP.LMP.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_UP.LMP.svn-base new file mode 100755 index 00000000..e42e7806 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_UP.LMP.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_UP.PCX.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_UP.PCX.svn-base new file mode 100755 index 00000000..0fbb2e5d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/CLIFF_UP.PCX.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/RingBl.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/RingBl.lmp (1).svn-base new file mode 100755 index 00000000..3262c037 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/RingBl.lmp (1).svn-base @@ -0,0 +1,7 @@ +oo_|rxziceTX[KMPEî*4(39-?I&- 3>.95EO&8C8BFhov +ݡۛ +&6ܨؓӝ猨Ё&2U\hu|vn^zZvZvVrRn".B6Jl*>w|_epȅ|fzttVjRfoNb^vd~J^fVng^zVr՟Άli~ezl]rRfkUjNb^v&6ZrJ^Vn`{FZ=NrCV~NdRj6Fg"2".F +̾ҫntFLZiv{tl}zrVfRb[mHVwN^bv[ncz%Rf^vNb;JlARxK^QfZr+6PWnRj'2L.<[F\t|bj~fnzU^tZd|q~u|lz%*7dr`n@JcdtMZy".[jDQpVf4>W;FcRb&.AN^^rbvJZ)2H^r"*=Vj/:U5BaVjQfAR~+&;J^"6׳ɋNTd>DUz-2@r~5;Ljv&).<06GENfR^VfRbVfRbJZ:Fj&.F2>^""*BZfVb$&-"&4ZfVb,&.J"*F(*2"2*.B&*>"&:"62-.5""+ + +$! + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/RingBl.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/RingBl.lmp.svn-base new file mode 100755 index 00000000..3262c037 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/RingBl.lmp.svn-base @@ -0,0 +1,7 @@ +oo_|rxziceTX[KMPEî*4(39-?I&- 3>.95EO&8C8BFhov +ݡۛ +&6ܨؓӝ猨Ё&2U\hu|vn^zZvZvVrRn".B6Jl*>w|_epȅ|fzttVjRfoNb^vd~J^fVng^zVr՟Άli~ezl]rRfkUjNb^v&6ZrJ^Vn`{FZ=NrCV~NdRj6Fg"2".F +̾ҫntFLZiv{tl}zrVfRb[mHVwN^bv[ncz%Rf^vNb;JlARxK^QfZr+6PWnRj'2L.<[F\t|bj~fnzU^tZd|q~u|lz%*7dr`n@JcdtMZy".[jDQpVf4>W;FcRb&.AN^^rbvJZ)2H^r"*=Vj/:U5BaVjQfAR~+&;J^"6׳ɋNTd>DUz-2@r~5;Ljv&).<06GENfR^VfRbVfRbJZ:Fj&.F2>^""*BZfVb$&-"&4ZfVb,&.J"*F(*2"2*.B&*>"&:"62-.5""+ + +$! + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_BK.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_BK.lmp.svn-base new file mode 100755 index 00000000..e0ad00a0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_BK.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_DN.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_DN.lmp.svn-base new file mode 100755 index 00000000..bb2fd144 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_DN.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_FT.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_FT.lmp.svn-base new file mode 100755 index 00000000..a5565345 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_FT.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_LF.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_LF.lmp.svn-base new file mode 100755 index 00000000..e5d16b0e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_LF.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_RT.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_RT.lmp.svn-base new file mode 100755 index 00000000..71a5c55a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_RT.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_UP.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_UP.lmp.svn-base new file mode 100755 index 00000000..2fc4baad Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/SKY_UP.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/cliff_palette.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/cliff_palette.lmp.svn-base new file mode 100755 index 00000000..3262c037 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/cliff_palette.lmp.svn-base @@ -0,0 +1,7 @@ +oo_|rxziceTX[KMPEî*4(39-?I&- 3>.95EO&8C8BFhov +ݡۛ +&6ܨؓӝ猨Ё&2U\hu|vn^zZvZvVrRn".B6Jl*>w|_epȅ|fzttVjRfoNb^vd~J^fVng^zVr՟Άli~ezl]rRfkUjNb^v&6ZrJ^Vn`{FZ=NrCV~NdRj6Fg"2".F +̾ҫntFLZiv{tl}zrVfRb[mHVwN^bv[ncz%Rf^vNb;JlARxK^QfZr+6PWnRj'2L.<[F\t|bj~fnzU^tZd|q~u|lz%*7dr`n@JcdtMZy".[jDQpVf4>W;FcRb&.AN^^rbvJZ)2H^r"*=Vj/:U5BaVjQfAR~+&;J^"6׳ɋNTd>DUz-2@r~5;Ljv&).<06GENfR^VfRbVfRbJZ:Fj&.F2>^""*BZfVb$&-"&4ZfVb,&.J"*F(*2"2*.B&*>"&:"62-.5""+ + +$! + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/dayblue_palette.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/dayblue_palette.lmp.svn-base new file mode 100755 index 00000000..485290ee --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/dayblue_palette.lmp.svn-base @@ -0,0 +1 @@ +d\Zedb|nu|ɳnlc½utnLLKTTL򡤞ŽZ\Zy|yltl\d\hlk8<< L\dTZ^JcRJZRJ\@JqP=iP>cR=cJB]OMM\rrAAN++4..8EET 11<66BPPc       |{ͯ$#*#   # %%#&     \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nitebluebk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nitebluebk.lmp.svn-base new file mode 100755 index 00000000..5ea02de8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nitebluebk.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nitebluedn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nitebluedn.lmp.svn-base new file mode 100755 index 00000000..cbc45718 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nitebluedn.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/niteblueft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/niteblueft.lmp.svn-base new file mode 100755 index 00000000..f6c44fb2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/niteblueft.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nitebluelf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nitebluelf.lmp.svn-base new file mode 100755 index 00000000..3055f265 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nitebluelf.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nitebluert.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nitebluert.lmp.svn-base new file mode 100755 index 00000000..1f332f15 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nitebluert.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/niteblueup.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/niteblueup.lmp.svn-base new file mode 100755 index 00000000..55288dd0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/niteblueup.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_bk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_bk.lmp.svn-base new file mode 100755 index 00000000..daad6321 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_bk.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_dn.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_dn.lmp (1).svn-base new file mode 100755 index 00000000..e8e1fc33 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_dn.lmp (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_dn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_dn.lmp.svn-base new file mode 100755 index 00000000..e8e1fc33 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_dn.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_ft.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_ft.lmp (1).svn-base new file mode 100755 index 00000000..0993f637 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_ft.lmp (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_ft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_ft.lmp.svn-base new file mode 100755 index 00000000..0993f637 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_ft.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_lf.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_lf.lmp (1).svn-base new file mode 100755 index 00000000..16974f98 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_lf.lmp (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_lf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_lf.lmp.svn-base new file mode 100755 index 00000000..16974f98 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_lf.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_rt.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_rt.lmp (1).svn-base new file mode 100755 index 00000000..b6eeace0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_rt.lmp (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_rt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_rt.lmp.svn-base new file mode 100755 index 00000000..b6eeace0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_rt.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_up.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_up.lmp (1).svn-base new file mode 100755 index 00000000..b15d55d6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_up.lmp (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_up.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_up.lmp.svn-base new file mode 100755 index 00000000..b15d55d6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_512_up.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_bk.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_bk.lmp (1).svn-base new file mode 100755 index 00000000..69d625a5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_bk.lmp (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_bk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_bk.lmp.svn-base new file mode 100755 index 00000000..69d625a5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_bk.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_dn.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_dn.lmp (1).svn-base new file mode 100755 index 00000000..701d0a64 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_dn.lmp (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_dn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_dn.lmp.svn-base new file mode 100755 index 00000000..701d0a64 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_dn.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_ft.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_ft.lmp (1).svn-base new file mode 100755 index 00000000..3477898d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_ft.lmp (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_ft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_ft.lmp.svn-base new file mode 100755 index 00000000..3477898d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_ft.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_lf.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_lf.lmp (1).svn-base new file mode 100755 index 00000000..4f69c281 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_lf.lmp (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_lf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_lf.lmp.svn-base new file mode 100755 index 00000000..4f69c281 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_lf.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_palette.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_palette.lmp (1).svn-base new file mode 100755 index 00000000..0ac31309 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_palette.lmp (1).svn-base @@ -0,0 +1 @@ +wjxeZxgS↷MF{veZLDEA6z~vn~zj~rdLMHC~;v>~6nr/Z6j:r6j2f.^6n2f.b2j*Z.b*^*^ӧҟ~erzvrn~jzvn|~vkrnvmNvSJzCr;f:f;j2^6f4b2^6f:n.Z2b6j.Z.^*V2f.^*Z*Z߳ȝڎ~vnz|m~fv^ni~bvUfez[n^rav|L`e\~_SzHmKrJvAj;aBn7b.Z+V֭ċĞjvzvrdrjz[jriZxQpDfͨz{{~vnzbnfvbrܖr{s~~zvnzjvbrjrfr \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_palette.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_palette.lmp.svn-base new file mode 100755 index 00000000..0ac31309 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_palette.lmp.svn-base @@ -0,0 +1 @@ +wjxeZxgS↷MF{veZLDEA6z~vn~zj~rdLMHC~;v>~6nr/Z6j:r6j2f.^6n2f.b2j*Z.b*^*^ӧҟ~erzvrn~jzvn|~vkrnvmNvSJzCr;f:f;j2^6f4b2^6f:n.Z2b6j.Z.^*V2f.^*Z*Z߳ȝڎ~vnz|m~fv^ni~bvUfez[n^rav|L`e\~_SzHmKrJvAj;aBn7b.Z+V֭ċĞjvzvrdrjz[jriZxQpDfͨz{{~vnzbnfvbrܖr{s~~zvnzjvbrjrfr \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_rt.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_rt.lmp (1).svn-base new file mode 100755 index 00000000..72536344 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_rt.lmp (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_rt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_rt.lmp.svn-base new file mode 100755 index 00000000..72536344 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_rt.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_up.lmp (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_up.lmp (1).svn-base new file mode 100755 index 00000000..03dc1404 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_up.lmp (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_up.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_up.lmp.svn-base new file mode 100755 index 00000000..03dc1404 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/nrblue_up.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512bk.pcx (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512bk.pcx (1).svn-base new file mode 100755 index 00000000..0e4be5bb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512bk.pcx (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512bk.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512bk.pcx.svn-base new file mode 100755 index 00000000..0e4be5bb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512bk.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512dn.pcx (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512dn.pcx (1).svn-base new file mode 100755 index 00000000..d81b4dc5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512dn.pcx (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512dn.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512dn.pcx.svn-base new file mode 100755 index 00000000..d81b4dc5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512dn.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512ft.pcx (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512ft.pcx (1).svn-base new file mode 100755 index 00000000..82e264af Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512ft.pcx (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512ft.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512ft.pcx.svn-base new file mode 100755 index 00000000..82e264af Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512ft.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512lf.pcx (1).svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512lf.pcx (1).svn-base new file mode 100755 index 00000000..2c737bfc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512lf.pcx (1).svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512lf.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512lf.pcx.svn-base new file mode 100755 index 00000000..2c737bfc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512lf.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512rt.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512rt.pcx.svn-base new file mode 100755 index 00000000..e46a2f65 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512rt.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512up.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512up.pcx.svn-base new file mode 100755 index 00000000..3450b926 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbl512up.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringblbk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringblbk.lmp.svn-base new file mode 100755 index 00000000..e0ad00a0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringblbk.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbldn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbldn.lmp.svn-base new file mode 100755 index 00000000..bb2fd144 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbldn.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringblft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringblft.lmp.svn-base new file mode 100755 index 00000000..a5565345 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringblft.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbllf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbllf.lmp.svn-base new file mode 100755 index 00000000..e5d16b0e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringbllf.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringblrt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringblrt.lmp.svn-base new file mode 100755 index 00000000..71a5c55a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringblrt.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringblup.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringblup.lmp.svn-base new file mode 100755 index 00000000..2fc4baad Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/ringblup.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_bk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_bk.lmp.svn-base new file mode 100755 index 00000000..0b47b7c1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_bk.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_dn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_dn.lmp.svn-base new file mode 100755 index 00000000..28dd1753 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_dn.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_ft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_ft.lmp.svn-base new file mode 100755 index 00000000..72eedda2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_ft.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_lf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_lf.lmp.svn-base new file mode 100755 index 00000000..4b8b88e2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_lf.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_palette.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_palette.lmp.svn-base new file mode 100755 index 00000000..3262c037 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_palette.lmp.svn-base @@ -0,0 +1,7 @@ +oo_|rxziceTX[KMPEî*4(39-?I&- 3>.95EO&8C8BFhov +ݡۛ +&6ܨؓӝ猨Ё&2U\hu|vn^zZvZvVrRn".B6Jl*>w|_epȅ|fzttVjRfoNb^vd~J^fVng^zVr՟Άli~ezl]rRfkUjNb^v&6ZrJ^Vn`{FZ=NrCV~NdRj6Fg"2".F +̾ҫntFLZiv{tl}zrVfRb[mHVwN^bv[ncz%Rf^vNb;JlARxK^QfZr+6PWnRj'2L.<[F\t|bj~fnzU^tZd|q~u|lz%*7dr`n@JcdtMZy".[jDQpVf4>W;FcRb&.AN^^rbvJZ)2H^r"*=Vj/:U5BaVjQfAR~+&;J^"6׳ɋNTd>DUz-2@r~5;Ljv&).<06GENfR^VfRbVfRbJZ:Fj&.F2>^""*BZfVb$&-"&4ZfVb,&.J"*F(*2"2*.B&*>"&:"62-.5""+ + +$! + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_rt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_rt.lmp.svn-base new file mode 100755 index 00000000..1f73adbd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_rt.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_up.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_up.lmp.svn-base new file mode 100755 index 00000000..e69a6662 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_512_up.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_palette.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_palette.lmp.svn-base new file mode 100755 index 00000000..1e5b3364 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_palette.lmp.svn-base @@ -0,0 +1 @@ +<77g[ZbVUD=;ZNJl`[PFByib0.-f[U|rtjoeue\vk~j_zfZr^SvbVKC>rcULvfrbn~j]SKzj^ZNEzll]RrbVzvf~jZzfVvbR~non]nzfvbULD~n_sb~jfZNzjZvfVrbRrzfvb|xr^snjk]NbUFnfzoarfWzgr^~nZnj~fvfRzbv^rZzjfZJj~boj~fzbv^nrZuk[mcSznZvjVrfRzlV`ZOf^O\TEjf~bbZJhzbv^vjRj~sZ~b|^f^J{^jaJwZqjVSM=vnVrjRldMdjb\F{sVvnRuq]IF8rlNEDK/DM;KREE[2?T07J+,9%8U*=^-.H%.V$!6$B#O*G3#%-'.E8.72>FBHU[OXkv`hv`cr~z,-3rxv}zv~v~륫ٚ̌Ĕ͋ńÌЂru䟤z~ʢ瘟ڬ~z~–еĠnl{Β:7DICNC=GHDI414NGM{XNRcW[SKM]ST \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256bk.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256bk.pcx.svn-base new file mode 100755 index 00000000..c894f7ef Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256bk.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256dn.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256dn.pcx.svn-base new file mode 100755 index 00000000..c9129d69 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256dn.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256ft.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256ft.pcx.svn-base new file mode 100755 index 00000000..2142f513 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256ft.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256lf.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256lf.pcx.svn-base new file mode 100755 index 00000000..9bc2c7af Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256lf.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256rt.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256rt.pcx.svn-base new file mode 100755 index 00000000..839ecfd5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256rt.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256up.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256up.pcx.svn-base new file mode 100755 index 00000000..0e605425 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/sky_ringblue256up.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars.pcx.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars.pcx.svn-base new file mode 100755 index 00000000..20b50d3d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars.pcx.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_bk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_bk.lmp.svn-base new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_bk.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_dn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_dn.lmp.svn-base new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_dn.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_ft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_ft.lmp.svn-base new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_ft.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_lf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_lf.lmp.svn-base new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_lf.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_rt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_rt.lmp.svn-base new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_rt.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_up.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_up.lmp.svn-base new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/stars_up.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsbk.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsbk.lmp.svn-base new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsbk.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsdn.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsdn.lmp.svn-base new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsdn.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsft.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsft.lmp.svn-base new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsft.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starslf.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starslf.lmp.svn-base new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starslf.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsrt.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsrt.lmp.svn-base new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsrt.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsup.lmp.svn-base b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsup.lmp.svn-base new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/.svn/text-base/starsup.lmp.svn-base differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_BK.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_BK.LMP new file mode 100755 index 00000000..eb0c0569 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_BK.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_BK.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_BK.PCX new file mode 100755 index 00000000..0d02892b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_BK.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_DN.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_DN.LMP new file mode 100755 index 00000000..0ea8a4e6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_DN.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_DN.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_DN.PCX new file mode 100755 index 00000000..e9654eaa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_DN.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_FT.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_FT.LMP new file mode 100755 index 00000000..2769d88b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_FT.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_FT.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_FT.PCX new file mode 100755 index 00000000..1b72af98 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_FT.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_LF.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_LF.LMP new file mode 100755 index 00000000..68b86cca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_LF.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_LF.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_LF.PCX new file mode 100755 index 00000000..624e6635 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_LF.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_RT.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_RT.LMP new file mode 100755 index 00000000..78475641 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_RT.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_RT.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_RT.PCX new file mode 100755 index 00000000..d45cebec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_RT.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_UP.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_UP.LMP new file mode 100755 index 00000000..e42e7806 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_UP.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_UP.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_UP.PCX new file mode 100755 index 00000000..0fbb2e5d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/CLIFF_UP.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_BK.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_BK.PCX new file mode 100755 index 00000000..0d02892b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_BK.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_DN.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_DN.PCX new file mode 100755 index 00000000..e9654eaa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_DN.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_FT.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_FT.PCX new file mode 100755 index 00000000..1b72af98 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_FT.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_LF.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_LF.PCX new file mode 100755 index 00000000..624e6635 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_LF.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_RT.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_RT.PCX new file mode 100755 index 00000000..d45cebec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_RT.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_UP.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_UP.PCX new file mode 100755 index 00000000..0fbb2e5d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/HLCliff/CLIFF_UP.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/NonRing_Daylight.tgd b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/NonRing_Daylight.tgd new file mode 100755 index 00000000..acaac8ba --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/NonRing_Daylight.tgd @@ -0,0 +1,734 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/PaletaCieloAzul.act b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/PaletaCieloAzul.act new file mode 100755 index 00000000..a58a1c4b --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/PaletaCieloAzul.act @@ -0,0 +1 @@ +frjrbrjvnzvz~s~r{brfvbnnzv~{{zDfQpZxir[jjzdrrvzjvě+V.Z7bBn;aAjJvKrHmSz_\~eL`|av^r[nezUfbvi~^nfvm~|ɉnzv~ڝ*Z*Z.^2f*V.^.Z6j2b.Z:n6f2^4b6f2^;j:f;fCrJzSNvmvnrkv~|nvjzn~rvzer~ЧҲ*^*^.b*Z2j.b2f6n.^2f6j:r6j/Z>r~;vC~HMLdrj~zn~v~޸6zAEDLZev昸{FM܆SgxZexjw \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_bk.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_bk.pcx new file mode 100755 index 00000000..c14fbc3b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_bk.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_dn.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_dn.pcx new file mode 100755 index 00000000..d3701559 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_dn.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_ft.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_ft.pcx new file mode 100755 index 00000000..6929db8d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_ft.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_lf.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_lf.pcx new file mode 100755 index 00000000..5370266e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_lf.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_rt.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_rt.pcx new file mode 100755 index 00000000..8d5b3bc8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_rt.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_up.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_up.pcx new file mode 100755 index 00000000..f49e44d5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue256_up.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_bk.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_bk.pcx new file mode 100755 index 00000000..45ae28f7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_bk.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_bk.tga b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_bk.tga new file mode 100755 index 00000000..0b9199aa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_bk.tga differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_dn.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_dn.pcx new file mode 100755 index 00000000..964db096 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_dn.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_dn.tga b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_dn.tga new file mode 100755 index 00000000..a22dfcd4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_dn.tga differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_ft.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_ft.pcx new file mode 100755 index 00000000..ba745db3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_ft.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_ft.tga b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_ft.tga new file mode 100755 index 00000000..a0bce857 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_ft.tga differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_lf.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_lf.pcx new file mode 100755 index 00000000..bc1244c4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_lf.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_lf.tga b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_lf.tga new file mode 100755 index 00000000..62fab38d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_lf.tga differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_rt.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_rt.pcx new file mode 100755 index 00000000..885838a9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_rt.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_rt.tga b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_rt.tga new file mode 100755 index 00000000..a8af6b6f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_rt.tga differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_up.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_up.pcx new file mode 100755 index 00000000..3e38efdf Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_up.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_up.tga b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_up.tga new file mode 100755 index 00000000..02667402 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/NonRing-Daylight/nrblue_up.tga differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_BK.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_BK.LMP new file mode 100755 index 00000000..d8100a98 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_BK.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_BK.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_BK.PCX new file mode 100755 index 00000000..0d02892b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_BK.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_DN.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_DN.LMP new file mode 100755 index 00000000..14579220 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_DN.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_DN.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_DN.PCX new file mode 100755 index 00000000..e9654eaa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_DN.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_FT.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_FT.LMP new file mode 100755 index 00000000..93bee1d7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_FT.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_FT.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_FT.PCX new file mode 100755 index 00000000..1b72af98 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_FT.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_LF.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_LF.LMP new file mode 100755 index 00000000..22311900 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_LF.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_LF.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_LF.PCX new file mode 100755 index 00000000..624e6635 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_LF.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_RT.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_RT.LMP new file mode 100755 index 00000000..0d34d19e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_RT.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_RT.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_RT.PCX new file mode 100755 index 00000000..d45cebec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_RT.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_UP.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_UP.LMP new file mode 100755 index 00000000..8efc7748 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_UP.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_UP.PCX b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_UP.PCX new file mode 100755 index 00000000..0fbb2e5d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/CLIFF_UP.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/DAY_BLUE/DayBlue.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/DAY_BLUE/DayBlue.lmp new file mode 100755 index 00000000..485290ee --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/DAY_BLUE/DayBlue.lmp @@ -0,0 +1 @@ +d\Zedb|nu|ɳnlc½utnLLKTTL򡤞ŽZ\Zy|yltl\d\hlk8<< L\dMM\rrAAN++4..8EET 11<66BPPc       |{ͯ$#*#   # %%#&     \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256bk.lmp new file mode 100755 index 00000000..5ea02de8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256bk.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256bk.pcx new file mode 100755 index 00000000..c894f7ef Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256bk.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256dn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256dn.lmp new file mode 100755 index 00000000..cbc45718 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256dn.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256dn.pcx new file mode 100755 index 00000000..c9129d69 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256dn.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256ft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256ft.lmp new file mode 100755 index 00000000..f6c44fb2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256ft.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256ft.pcx new file mode 100755 index 00000000..2142f513 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256ft.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256lf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256lf.lmp new file mode 100755 index 00000000..3055f265 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256lf.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256lf.pcx new file mode 100755 index 00000000..9bc2c7af Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256lf.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256rt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256rt.lmp new file mode 100755 index 00000000..1f332f15 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256rt.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256rt.pcx new file mode 100755 index 00000000..839ecfd5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256rt.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256up.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256up.lmp new file mode 100755 index 00000000..55288dd0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256up.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256up.pcx new file mode 100755 index 00000000..0e605425 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/night_blue/sky_ringblue256up.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512bk.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512bk.pcx new file mode 100755 index 00000000..0e4be5bb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512bk.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512dn.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512dn.pcx new file mode 100755 index 00000000..d81b4dc5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512dn.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512ft.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512ft.pcx new file mode 100755 index 00000000..82e264af Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512ft.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512lf.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512lf.pcx new file mode 100755 index 00000000..2c737bfc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512lf.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512rt.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512rt.pcx new file mode 100755 index 00000000..e46a2f65 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512rt.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512up.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512up.pcx new file mode 100755 index 00000000..3450b926 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/PCX/ringbl512up.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/RingBl.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/RingBl.lmp new file mode 100755 index 00000000..3262c037 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/RingBl.lmp @@ -0,0 +1,7 @@ +oo_|rxziceTX[KMPEî*4(39-?I&- 3>.95EO&8C8BFhov +ݡۛ +&6ܨؓӝ猨Ё&2U\hu|vn^zZvZvVrRn".B6Jl*>w|_epȅ|fzttVjRfoNb^vd~J^fVng^zVr՟Άli~ezl]rRfkUjNb^v&6ZrJ^Vn`{FZ=NrCV~NdRj6Fg"2".F +̾ҫntFLZiv{tl}zrVfRb[mHVwN^bv[ncz%Rf^vNb;JlARxK^QfZr+6PWnRj'2L.<[F\t|bj~fnzU^tZd|q~u|lz%*7dr`n@JcdtMZy".[jDQpVf4>W;FcRb&.AN^^rbvJZ)2H^r"*=Vj/:U5BaVjQfAR~+&;J^"6׳ɋNTd>DUz-2@r~5;Ljv&).<06GENfR^VfRbVfRbJZ:Fj&.F2>^""*BZfVb$&-"&4ZfVb,&.J"*F(*2"2*.B&*>"&:"62-.5""+ + +$! + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_BK.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_BK.lmp new file mode 100755 index 00000000..5ea02de8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_BK.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_DN.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_DN.lmp new file mode 100755 index 00000000..c981641d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_DN.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_FT.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_FT.lmp new file mode 100755 index 00000000..f6c44fb2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_FT.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_LF.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_LF.lmp new file mode 100755 index 00000000..3055f265 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_LF.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_RT.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_RT.lmp new file mode 100755 index 00000000..1f332f15 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_RT.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_UP.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_UP.lmp new file mode 100755 index 00000000..f8085516 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/SKY_UP.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/cliff_palette.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/cliff_palette.lmp new file mode 100755 index 00000000..3262c037 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/cliff_palette.lmp @@ -0,0 +1,7 @@ +oo_|rxziceTX[KMPEî*4(39-?I&- 3>.95EO&8C8BFhov +ݡۛ +&6ܨؓӝ猨Ё&2U\hu|vn^zZvZvVrRn".B6Jl*>w|_epȅ|fzttVjRfoNb^vd~J^fVng^zVr՟Άli~ezl]rRfkUjNb^v&6ZrJ^Vn`{FZ=NrCV~NdRj6Fg"2".F +̾ҫntFLZiv{tl}zrVfRb[mHVwN^bv[ncz%Rf^vNb;JlARxK^QfZr+6PWnRj'2L.<[F\t|bj~fnzU^tZd|q~u|lz%*7dr`n@JcdtMZy".[jDQpVf4>W;FcRb&.AN^^rbvJZ)2H^r"*=Vj/:U5BaVjQfAR~+&;J^"6׳ɋNTd>DUz-2@r~5;Ljv&).<06GENfR^VfRbVfRbJZ:Fj&.F2>^""*BZfVb$&-"&4ZfVb,&.J"*F(*2"2*.B&*>"&:"62-.5""+ + +$! + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_bk.lmp new file mode 100755 index 00000000..11f858d8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_dn.lmp new file mode 100755 index 00000000..c981641d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ft.lmp new file mode 100755 index 00000000..f400ce2a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_lf.lmp new file mode 100755 index 00000000..e7be5be8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256bk.lmp new file mode 100755 index 00000000..11f858d8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256bk.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256bk.pcx new file mode 100755 index 00000000..c894f7ef Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256bk.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256dn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256dn.lmp new file mode 100755 index 00000000..c981641d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256dn.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256dn.pcx new file mode 100755 index 00000000..c9129d69 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256dn.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256ft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256ft.lmp new file mode 100755 index 00000000..f400ce2a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256ft.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256ft.pcx new file mode 100755 index 00000000..2142f513 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256ft.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256lf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256lf.lmp new file mode 100755 index 00000000..e7be5be8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256lf.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256lf.pcx new file mode 100755 index 00000000..9bc2c7af Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256lf.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256rt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256rt.lmp new file mode 100755 index 00000000..191dc2d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256rt.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256rt.pcx new file mode 100755 index 00000000..839ecfd5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256rt.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256up.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256up.lmp new file mode 100755 index 00000000..f8085516 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256up.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256up.pcx new file mode 100755 index 00000000..0e605425 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringblue256up.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringlblue256bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringlblue256bk.lmp new file mode 100755 index 00000000..11f858d8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_ringlblue256bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_rt.lmp new file mode 100755 index 00000000..191dc2d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_up.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_up.lmp new file mode 100755 index 00000000..f8085516 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/day_blue/sky_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_bk.lmp new file mode 100755 index 00000000..d339f3b6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_dn.lmp new file mode 100755 index 00000000..d5af8006 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_ft.lmp new file mode 100755 index 00000000..d960f9de Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_lf.lmp new file mode 100755 index 00000000..44350c6d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_palette.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_palette.lmp new file mode 100755 index 00000000..485290ee --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/dayblue_palette.lmp @@ -0,0 +1 @@ +d\Zedb|nu|ɳnlc½utnLLKTTL򡤞ŽZ\Zy|yltl\d\hlk8<< L\dTZ^JcRJZRJ\@JqP=iP>cR=cJB]OMM\rrAAN++4..8EET 11<66BPPc       |{ͯ$#*#   # %%#&     \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256bk.lmp new file mode 100755 index 00000000..11f858d8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256bk.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256bk.pcx new file mode 100755 index 00000000..c894f7ef Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256bk.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256dn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256dn.lmp new file mode 100755 index 00000000..c981641d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256dn.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256dn.pcx new file mode 100755 index 00000000..c9129d69 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256dn.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256ft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256ft.lmp new file mode 100755 index 00000000..f400ce2a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256ft.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256ft.pcx new file mode 100755 index 00000000..2142f513 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256ft.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256lf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256lf.lmp new file mode 100755 index 00000000..e7be5be8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256lf.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256lf.pcx new file mode 100755 index 00000000..9bc2c7af Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256lf.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256rt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256rt.lmp new file mode 100755 index 00000000..191dc2d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256rt.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256rt.pcx new file mode 100755 index 00000000..839ecfd5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256rt.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256up.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256up.lmp new file mode 100755 index 00000000..f8085516 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256up.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256up.pcx new file mode 100755 index 00000000..0e605425 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/night_blue/sky_ringblue256up.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_bk.lmp new file mode 100755 index 00000000..5ea02de8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_dn.lmp new file mode 100755 index 00000000..cbc45718 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_ft.lmp new file mode 100755 index 00000000..f6c44fb2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_lf.lmp new file mode 100755 index 00000000..3055f265 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_palette.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_palette.lmp new file mode 100755 index 00000000..12441121 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_palette.lmp @@ -0,0 +1 @@ + !!!###%%%'''888???DDD EC@BA=!! !#!   !          !#$#%'     "@AC     15O9:BOTzTZ),C?Dg%(=X[x]bIMpDHj7:X!#5-0I;?aIJX;MM\rrAAN++4..8EET 11<66BPPc       |{ͯ$#*#   # %%#&     \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_rt.lmp new file mode 100755 index 00000000..1f332f15 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_up.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_up.lmp new file mode 100755 index 00000000..55288dd0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblue_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nitebluebk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nitebluebk.lmp new file mode 100755 index 00000000..5ea02de8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nitebluebk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nitebluedn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nitebluedn.lmp new file mode 100755 index 00000000..cbc45718 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nitebluedn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblueft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblueft.lmp new file mode 100755 index 00000000..f6c44fb2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblueft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nitebluelf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nitebluelf.lmp new file mode 100755 index 00000000..3055f265 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nitebluelf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nitebluert.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nitebluert.lmp new file mode 100755 index 00000000..1f332f15 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nitebluert.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblueup.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblueup.lmp new file mode 100755 index 00000000..55288dd0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/niteblueup.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_bk.lmp new file mode 100755 index 00000000..6b5427d3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_dn.lmp new file mode 100755 index 00000000..6ffaa6ad Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_ft.lmp new file mode 100755 index 00000000..d731724c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_lf.lmp new file mode 100755 index 00000000..f3c24562 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_rt.lmp new file mode 100755 index 00000000..10b766c2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_up.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_up.lmp new file mode 100755 index 00000000..dd3b1276 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_512_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_bk.lmp new file mode 100755 index 00000000..816c5581 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_dn.lmp new file mode 100755 index 00000000..63347950 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_ft.lmp new file mode 100755 index 00000000..e4b26ca2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_lf.lmp new file mode 100755 index 00000000..e452bef8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_palette.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_palette.lmp new file mode 100755 index 00000000..0ac31309 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_palette.lmp @@ -0,0 +1 @@ +wjxeZxgS↷MF{veZLDEA6z~vn~zj~rdLMHC~;v>~6nr/Z6j:r6j2f.^6n2f.b2j*Z.b*^*^ӧҟ~erzvrn~jzvn|~vkrnvmNvSJzCr;f:f;j2^6f4b2^6f:n.Z2b6j.Z.^*V2f.^*Z*Z߳ȝڎ~vnz|m~fv^ni~bvUfez[n^rav|L`e\~_SzHmKrJvAj;aBn7b.Z+V֭ċĞjvzvrdrjz[jriZxQpDfͨz{{~vnzbnfvbrܖr{s~~zvnzjvbrjrfr \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_rt.lmp new file mode 100755 index 00000000..9f23a20d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_up.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_up.lmp new file mode 100755 index 00000000..1796d072 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/nrblue_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512bk.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512bk.pcx new file mode 100755 index 00000000..0e4be5bb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512bk.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512dn.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512dn.pcx new file mode 100755 index 00000000..d81b4dc5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512dn.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512ft.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512ft.pcx new file mode 100755 index 00000000..82e264af Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512ft.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512lf.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512lf.pcx new file mode 100755 index 00000000..2c737bfc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512lf.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512rt.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512rt.pcx new file mode 100755 index 00000000..e46a2f65 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512rt.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512up.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512up.pcx new file mode 100755 index 00000000..3450b926 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl512up.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_bk.lmp new file mode 100755 index 00000000..e0ad00a0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_dn.lmp new file mode 100755 index 00000000..bb2fd144 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_ft.lmp new file mode 100755 index 00000000..a5565345 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_lf.lmp new file mode 100755 index 00000000..e5d16b0e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_rt.lmp new file mode 100755 index 00000000..71a5c55a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_up.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_up.lmp new file mode 100755 index 00000000..2fc4baad Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbl_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblbk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblbk.lmp new file mode 100755 index 00000000..e0ad00a0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblbk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblbk.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblbk.pcx new file mode 100755 index 00000000..9e51e749 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblbk.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbldn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbldn.lmp new file mode 100755 index 00000000..bb2fd144 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbldn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbldn.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbldn.pcx new file mode 100755 index 00000000..fb067a0f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbldn.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblft.lmp new file mode 100755 index 00000000..a5565345 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblft.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblft.pcx new file mode 100755 index 00000000..5d20d9cd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblft.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbllf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbllf.lmp new file mode 100755 index 00000000..e5d16b0e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbllf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbllf.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbllf.pcx new file mode 100755 index 00000000..f8bba06f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringbllf.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblrt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblrt.lmp new file mode 100755 index 00000000..71a5c55a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblrt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblrt.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblrt.pcx new file mode 100755 index 00000000..a9e3e428 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblrt.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblup.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblup.lmp new file mode 100755 index 00000000..2fc4baad Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblup.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblup.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblup.pcx new file mode 100755 index 00000000..a821d541 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/ringblup.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/skty b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/skty new file mode 100755 index 00000000..7e1ed665 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/skty differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_bk.lmp new file mode 100755 index 00000000..c6faaf0e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_dn.lmp new file mode 100755 index 00000000..68ccc943 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_ft.lmp new file mode 100755 index 00000000..e190c800 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_lf.lmp new file mode 100755 index 00000000..7f08d9c2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_palette.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_palette.lmp new file mode 100755 index 00000000..3262c037 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_palette.lmp @@ -0,0 +1,7 @@ +oo_|rxziceTX[KMPEî*4(39-?I&- 3>.95EO&8C8BFhov +ݡۛ +&6ܨؓӝ猨Ё&2U\hu|vn^zZvZvVrRn".B6Jl*>w|_epȅ|fzttVjRfoNb^vd~J^fVng^zVr՟Άli~ezl]rRfkUjNb^v&6ZrJ^Vn`{FZ=NrCV~NdRj6Fg"2".F +̾ҫntFLZiv{tl}zrVfRb[mHVwN^bv[ncz%Rf^vNb;JlARxK^QfZr+6PWnRj'2L.<[F\t|bj~fnzU^tZd|q~u|lz%*7dr`n@JcdtMZy".[jDQpVf4>W;FcRb&.AN^^rbvJZ)2H^r"*=Vj/:U5BaVjQfAR~+&;J^"6׳ɋNTd>DUz-2@r~5;Ljv&).<06GENfR^VfRbVfRbJZ:Fj&.F2>^""*BZfVb$&-"&4ZfVb,&.J"*F(*2"2*.B&*>"&:"62-.5""+ + +$! + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_rt.lmp new file mode 100755 index 00000000..45867c45 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_up.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_up.lmp new file mode 100755 index 00000000..006703a9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_512_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_bk.lm b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_bk.lm new file mode 100755 index 00000000..f9b70a4b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_bk.lm differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_dn.lm b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_dn.lm new file mode 100755 index 00000000..153cbb84 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_dn.lm differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ft.lm b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ft.lm new file mode 100755 index 00000000..7409155e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ft.lm differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_lf.lm b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_lf.lm new file mode 100755 index 00000000..b82cc96f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_lf.lm differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_palette.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_palette.lmp new file mode 100755 index 00000000..12441121 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_palette.lmp @@ -0,0 +1 @@ + !!!###%%%'''888???DDD EC@BA=!! !#!   !          !#$#%'     "@AC     15O9:BOTzTZ),C?Dg%(=X[x]bIMpDHj7:X!#5-0I;?aIJX;MM\rrAAN++4..8EET 11<66BPPc       |{ͯ$#*#   # %%#&     \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256 b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256 new file mode 100755 index 00000000..90ef1866 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256 differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256bk.lmp new file mode 100755 index 00000000..11f858d8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256bk.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256bk.pcx new file mode 100755 index 00000000..c894f7ef Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256bk.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256dn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256dn.lmp new file mode 100755 index 00000000..c981641d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256dn.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256dn.pcx new file mode 100755 index 00000000..c9129d69 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256dn.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256ft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256ft.lmp new file mode 100755 index 00000000..f400ce2a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256ft.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256ft.pcx new file mode 100755 index 00000000..2142f513 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256ft.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256lf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256lf.lmp new file mode 100755 index 00000000..e7be5be8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256lf.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256lf.pcx new file mode 100755 index 00000000..9bc2c7af Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256lf.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256rt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256rt.lmp new file mode 100755 index 00000000..191dc2d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256rt.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256rt.pcx new file mode 100755 index 00000000..839ecfd5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256rt.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256up.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256up.lmp new file mode 100755 index 00000000..f8085516 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256up.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256up.pcx new file mode 100755 index 00000000..0e605425 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringblue256up.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringlblue256bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringlblue256bk.lmp new file mode 100755 index 00000000..11f858d8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_ringlblue256bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_rt.lm b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_rt.lm new file mode 100755 index 00000000..70a74d78 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_rt.lm differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_up.lm b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_up.lm new file mode 100755 index 00000000..ddc32dcd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/sky_up.lm differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/skybox_template.tgd b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/skybox_template.tgd new file mode 100755 index 00000000..33f8b4ac --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/skybox_template.tgd @@ -0,0 +1,599 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars.pcx new file mode 100755 index 00000000..20b50d3d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_bk.lmp new file mode 100755 index 00000000..01352355 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_dn.lmp new file mode 100755 index 00000000..01352355 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_ft.lmp new file mode 100755 index 00000000..01352355 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_lf.lmp new file mode 100755 index 00000000..01352355 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_rt.lmp new file mode 100755 index 00000000..01352355 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_up.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_up.lmp new file mode 100755 index 00000000..01352355 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/stars_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsbk.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsbk.lmp new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsbk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsdn.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsdn.lmp new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsdn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsft.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsft.lmp new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starslf.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starslf.lmp new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starslf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsrt.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsrt.lmp new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsrt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsup.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsup.lmp new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ENV/starsup.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/FINALE.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/FINALE.LMP new file mode 100755 index 00000000..e910f831 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/FINALE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/GLBOOM.SPR b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/GLBOOM.SPR new file mode 100755 index 00000000..a53ef96b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/GLBOOM.SPR differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/GLBOOM_0.TGA b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/GLBOOM_0.TGA new file mode 100755 index 00000000..a368cee7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/GLBOOM_0.TGA differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/GLBOOM_1.TGA b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/GLBOOM_1.TGA new file mode 100755 index 00000000..c3e4b41e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/GLBOOM_1.TGA differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/GLBOOM_2.TGA b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/GLBOOM_2.TGA new file mode 100755 index 00000000..87cb79a0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/GLBOOM_2.TGA differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP0.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP0.LMP new file mode 100755 index 00000000..ff040655 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP0.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP1.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP1.LMP new file mode 100755 index 00000000..1b02c65e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP1.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP2.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP2.LMP new file mode 100755 index 00000000..658463b9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP2.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP3.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP3.LMP new file mode 100755 index 00000000..d0b5dacc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP3.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP4.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP4.LMP new file mode 100755 index 00000000..2c93f096 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP4.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP5.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP5.LMP new file mode 100755 index 00000000..18c33ccc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HELP5.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP0.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP0.LMP new file mode 100755 index 00000000..5e65f01f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP0.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP1.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP1.LMP new file mode 100755 index 00000000..956f7c48 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP1.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP2.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP2.LMP new file mode 100755 index 00000000..8203dfa3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP2.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP3.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP3.LMP new file mode 100755 index 00000000..281bd32b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP3.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP4.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP4.LMP new file mode 100755 index 00000000..56a114ef Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP4.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP5.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP5.LMP new file mode 100755 index 00000000..8c8a0deb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP5.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP6.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP6.LMP new file mode 100755 index 00000000..3532bb4b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP6.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP7.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP7.LMP new file mode 100755 index 00000000..ee04d157 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP7.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP8.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP8.LMP new file mode 100755 index 00000000..58361891 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/HP8.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp0.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp0.pcx new file mode 100755 index 00000000..8f84982b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp0.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp1.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp1.pcx new file mode 100755 index 00000000..2d563eb1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp1.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp2.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp2.pcx new file mode 100755 index 00000000..62002ac1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp2.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp3.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp3.pcx new file mode 100755 index 00000000..22ffbf6b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp3.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp4.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp4.pcx new file mode 100755 index 00000000..d6bd8e86 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp4.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp5.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp5.pcx new file mode 100755 index 00000000..68e0a51a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp5.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp6.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp6.pcx new file mode 100755 index 00000000..1754bbdf Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp6.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp7.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp7.pcx new file mode 100755 index 00000000..25cbf8c6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp7.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp8.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp8.pcx new file mode 100755 index 00000000..c6f34045 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Hp8.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/RADAR.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/RADAR.LMP new file mode 100755 index 00000000..6d87b7ca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/RADAR.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/RADAR.SPR b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/RADAR.SPR new file mode 100755 index 00000000..748a1d77 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/RADAR.SPR differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD0.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD0.LMP new file mode 100755 index 00000000..278d73da Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD0.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD1.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD1.LMP new file mode 100755 index 00000000..81440910 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD1.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD2.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD2.LMP new file mode 100755 index 00000000..5dbaf8cb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD2.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD3.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD3.LMP new file mode 100755 index 00000000..da1e33d8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD3.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD4.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD4.LMP new file mode 100755 index 00000000..bed901b2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD4.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD5.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD5.LMP new file mode 100755 index 00000000..d3de98d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD5.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD6.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD6.LMP new file mode 100755 index 00000000..9fef9f04 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD6.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD7.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD7.LMP new file mode 100755 index 00000000..fdda09d8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/SHIELD7.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield0.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield0.pcx new file mode 100755 index 00000000..251e0c3a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield0.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield1.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield1.pcx new file mode 100755 index 00000000..017ceb86 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield1.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield2.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield2.pcx new file mode 100755 index 00000000..405ab22d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield2.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield3.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield3.pcx new file mode 100755 index 00000000..39521873 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield3.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield4.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield4.pcx new file mode 100755 index 00000000..2f94ca7d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield4.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield5.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield5.pcx new file mode 100755 index 00000000..b6b2642a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield5.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield6.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield6.pcx new file mode 100755 index 00000000..262cf655 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield6.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield7.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield7.pcx new file mode 100755 index 00000000..ce99b320 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/Shield7.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/hp_blue.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/hp_blue.lmp new file mode 100755 index 00000000..1f2d48c4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/hp_blue.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/left.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/left.lmp new file mode 100755 index 00000000..aa007971 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUD/left.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUDSample.bmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUDSample.bmp new file mode 100755 index 00000000..9e2a0db2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/HUDSample.bmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/INTER.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/INTER.LMP new file mode 100755 index 00000000..d62eb0ac Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/INTER.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/LOADING.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/LOADING.LMP new file mode 100755 index 00000000..8594e3aa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/LOADING.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MAINMENU.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MAINMENU.LMP new file mode 100755 index 00000000..c0fb6287 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MAINMENU.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT1.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT1.LMP new file mode 100755 index 00000000..52a2f4f7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT1.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT2.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT2.LMP new file mode 100755 index 00000000..0f9a2266 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT2.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT3.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT3.LMP new file mode 100755 index 00000000..8c7b5d55 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT3.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT4.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT4.LMP new file mode 100755 index 00000000..6d87b7ca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT4.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT5.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT5.LMP new file mode 100755 index 00000000..6d87b7ca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT5.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT6.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT6.LMP new file mode 100755 index 00000000..6d87b7ca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MENUDOT6.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MP_MENU.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MP_MENU.LMP new file mode 100755 index 00000000..bf2a23a6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/MP_MENU.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN1.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN1.LMP new file mode 100755 index 00000000..44f7c0fd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN1.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN2.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN2.LMP new file mode 100755 index 00000000..3b9f915c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN2.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN3.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN3.LMP new file mode 100755 index 00000000..226573a1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN3.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN4.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN4.LMP new file mode 100755 index 00000000..8d36be54 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN4.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN5.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN5.LMP new file mode 100755 index 00000000..0227c525 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/NETMEN5.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/NUM_1.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/NUM_1.lmp new file mode 100755 index 00000000..d76cf27d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/NUM_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/NUM_2.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/NUM_2.lmp new file mode 100755 index 00000000..9440ab7e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/NUM_2.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/NUM_3.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/NUM_3.lmp new file mode 100755 index 00000000..969dabec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/NUM_3.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/NUM_4.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/NUM_4.lmp new file mode 100755 index 00000000..1854ee4f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/NUM_4.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/num_0.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/num_0.lmp new file mode 100755 index 00000000..a10f323c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/Numbers/num_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/PALETTE.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/PALETTE.LMP new file mode 100755 index 00000000..7eefda1d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/PALETTE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/PAUSE.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/PAUSE.LMP new file mode 100755 index 00000000..718bc42a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/PAUSE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/P_LOAD.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/P_LOAD.LMP new file mode 100755 index 00000000..9890b271 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/P_LOAD.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/P_MULTI.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/P_MULTI.LMP new file mode 100755 index 00000000..d178ca47 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/P_MULTI.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/P_OPTION.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/P_OPTION.LMP new file mode 100755 index 00000000..aef89a32 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/P_OPTION.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/P_SAVE.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/P_SAVE.LMP new file mode 100755 index 00000000..dac3203c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/P_SAVE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/QPLAQUE.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/QPLAQUE.LMP new file mode 100755 index 00000000..3832929a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/QPLAQUE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/RANKING.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/RANKING.LMP new file mode 100755 index 00000000..4c33fde0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/RANKING.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/RLBOOM.SPR b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/RLBOOM.SPR new file mode 100755 index 00000000..dd849fed Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/RLBOOM.SPR differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/SHIELD7.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/SHIELD7.lmp new file mode 100755 index 00000000..e8673686 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/SHIELD7.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/SMOKEo.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/SMOKEo.LMP new file mode 100755 index 00000000..cd732f0b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/SMOKEo.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/SPARK.SPR b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/SPARK.SPR new file mode 100755 index 00000000..5d132861 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/SPARK.SPR differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/SP_MENU.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/SP_MENU.LMP new file mode 100755 index 00000000..5f0e657e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/SP_MENU.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/S_PLASMA.SPR b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/S_PLASMA.SPR new file mode 100755 index 00000000..37a9bdf2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/S_PLASMA.SPR differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/TTL_CSTM.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/TTL_CSTM.LMP new file mode 100755 index 00000000..8268e586 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/TTL_CSTM.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/TTL_MAIN.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/TTL_MAIN.LMP new file mode 100755 index 00000000..7636bb08 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/TTL_MAIN.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/TTL_SGL.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/TTL_SGL.LMP new file mode 100755 index 00000000..a2329059 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/TTL_SGL.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/VIDMODES.LMP b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/VIDMODES.LMP new file mode 100755 index 00000000..c6072cc1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/VIDMODES.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ar.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ar.lmp new file mode 100755 index 00000000..f94c1032 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ar.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/bflood.spr b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/bflood.spr new file mode 100755 index 00000000..577cef6e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/bflood.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/bigbox.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/bigbox.lmp new file mode 100755 index 00000000..e73cf932 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/bigbox.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ch_snip.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ch_snip.lmp new file mode 100755 index 00000000..b539dfe9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ch_snip.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ch_uzi.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ch_uzi.lmp new file mode 100755 index 00000000..a8675955 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/ch_uzi.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/dayblue_palette.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/dayblue_palette.lmp new file mode 100755 index 00000000..485290ee --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/dayblue_palette.lmp @@ -0,0 +1 @@ +d\Zedb|nu|ɳnlc½utnLLKTTL򡤞ŽZ\Zy|yltl\d\hlk8<< L\d + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/smoke.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/smoke.lmp new file mode 100755 index 00000000..cd58bbc9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/smoke.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/sniper.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/sniper.lmp new file mode 100755 index 00000000..d5bf302c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/sniper.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/title.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/title.lmp new file mode 100755 index 00000000..20633315 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/title.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/Pistol.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/Pistol.lmp new file mode 100755 index 00000000..ea1862d3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/Pistol.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/RL.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/RL.lmp new file mode 100755 index 00000000..2f6723f9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/RL.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/ar.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/ar.lmp new file mode 100755 index 00000000..db186c00 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/ar.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/needler.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/needler.lmp new file mode 100755 index 00000000..e9ba9670 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/needler.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/ppist.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/ppist.lmp new file mode 100755 index 00000000..65927ff0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/ppist.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/shottie.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/shottie.lmp new file mode 100755 index 00000000..d6157197 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/shottie.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/smg.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/smg.lmp new file mode 100755 index 00000000..c1e0f235 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/smg.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/sniper.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/sniper.lmp new file mode 100755 index 00000000..d5bf302c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/weapons/sniper.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/wip1.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/wip1.pcx new file mode 100755 index 00000000..6e18a629 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/wip1.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/wip2.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/wip2.pcx new file mode 100755 index 00000000..eaf11b8c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/wip2.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/wip3.pcx b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/wip3.pcx new file mode 100755 index 00000000..1bed8fa3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/wip3.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/ar.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/ar.lmp new file mode 100755 index 00000000..0f54131c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/ar.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/needler.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/needler.lmp new file mode 100755 index 00000000..88c9b51b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/needler.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/pistol.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/pistol.lmp new file mode 100755 index 00000000..5b6755d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/pistol.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/ppist.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/ppist.lmp new file mode 100755 index 00000000..c1a5f2ee Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/ppist.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/rl.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/rl.lmp new file mode 100755 index 00000000..21538f45 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/rl.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/shottie.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/shottie.lmp new file mode 100755 index 00000000..27227114 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/shottie.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/smg.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/smg.lmp new file mode 100755 index 00000000..9a9172a3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/smg.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/sniper.lmp b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/sniper.lmp new file mode 100755 index 00000000..c69b5045 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/ID1/gfx/worldweapons/sniper.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/proquake_history.txt b/r17/Revamped src/revamped_src/psp/normal/ID1/proquake_history.txt new file mode 100755 index 00000000..9e70b079 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/proquake_history.txt @@ -0,0 +1 @@ +map maze diff --git a/r17/Revamped src/revamped_src/psp/normal/ID1/quake.rc b/r17/Revamped src/revamped_src/psp/normal/ID1/quake.rc new file mode 100755 index 00000000..6dbf7f0d --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/ID1/quake.rc @@ -0,0 +1,20 @@ +// load the base configuration +exec default.cfg + +// load the last saved configuration +exec config.cfg + +// run a user script file if present +exec autoexec.cfg + +// stuff command line statements +stuffcmds + +// Kurok stuff + +sv_maxspeed 200 +sv_maxvelocity 5000 + +cl_forwardspeed 200 +cl_backspeed 200 +cl_sidespeed 200 \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/Mp3/01.MP3 b/r17/Revamped src/revamped_src/psp/normal/Mp3/01.MP3 new file mode 100755 index 00000000..aec9d6da Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/Mp3/01.MP3 differ diff --git a/r17/Revamped src/revamped_src/psp/normal/Quake.prx b/r17/Revamped src/revamped_src/psp/normal/Quake.prx new file mode 100755 index 00000000..3af0ada7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/Quake.prx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/Revamped v 2.3.txt b/r17/Revamped src/revamped_src/psp/normal/Revamped v 2.3.txt new file mode 100755 index 00000000..ea2dd02b --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/Revamped v 2.3.txt @@ -0,0 +1,13 @@ +Revamped 2.3- + +Features: + +-New HUD + -Ammo counter + -Health Bar + -Weapon Icons + -Pickup weapon Icons + -Grenade and counter +-Weapon damage redone +-New Light effects for Needler, and Plasma pistol +- \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/CONFIG.CFG b/r17/Revamped src/revamped_src/psp/normal/kurok/CONFIG.CFG new file mode 100755 index 00000000..99bba892 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/CONFIG.CFG @@ -0,0 +1,140 @@ +bind "TAB" "+showscores" +bind "ESCAPE" "togglemenu" +bind "+" "sizeup" +bind "," "+moveleft" +bind "-" "sizedown" +bind "." "+moveright" +bind "0" "impulse 0" +bind "1" "impulse 1" +bind "2" "impulse 2" +bind "3" "impulse 3" +bind "4" "impulse 4" +bind "5" "impulse 5" +bind "6" "impulse 6" +bind "7" "impulse 7" +bind "8" "impulse 8" +bind "=" "sizeup" +bind "\" "+mlook" +bind "`" "impulse 27" +bind "a" "+moveleft" +bind "c" "+movedown" +bind "d" "+moveright" +bind "s" "+back" +bind "t" "messagemode" +bind "w" "+forward" +bind "z" "+lookdown" +bind "~" "impulse 11" +bind "UPARROW" "impulse 10" +bind "DOWNARROW" "+jump" +bind "LEFTARROW" "impulse 13" +bind "RIGHTARROW" "impulse 29" +bind "ALT" "+strafe" +bind "F1" "help" +bind "F2" "menu_save" +bind "F3" "menu_load" +bind "F4" "menu_options" +bind "F5" "menu_multiplayer" +bind "F6" "echo Quicksaving...; wait; save quick" +bind "F9" "echo Quickloading...; wait; load quick" +bind "F10" "quit" +bind "F11" "zoom_in" +bind "F12" "screenshot" +bind "INS" "+klook" +bind "DEL" "+lookdown" +bind "PGDN" "+lookup" +bind "END" "centerview" +bind "MOUSE2" "+forward" +bind "MOUSE3" "+mlook" +bind "TRIANGLE" "+forward" +bind "CIRCLE" "+moveright" +bind "CROSS" "+back" +bind "SQUARE" "+moveleft" +bind "LTRIGGER" "impulse 28" +bind "RTRIGGER" "+attack" +bind "MWHEELDOWN" "impulse 12" +bind "PAUSE" "pause" +m_side "0.8" +m_forward "1" +m_yaw "0.022" +m_pitch "0.022000" +in_y_axis_adjust "4" +in_x_axis_adjust "4" +in_analog_strafe "0" +in_disable_analog "0.000000" +in_freelook_analog "1" +acceleration "3.000000" +tolerance "0.470000" +sensitivity "10" +lookcenter "1" +lookstrafe "1" +lookspring "0" +cl_autoaim "1" +cl_backspeed "175" +cl_forwardspeed "175" +_cl_color "68" +_cl_name "Mexicouger" +_snd_mixahead "0.1" +bgmtype "cd" +bgmvolume "1" +volume "0.500000" +vl_lowcut "60" +vl_highcut "128" +vl_yaw "45" +vl_pitch "45" +vl_light "0" +gl_keeptjunctions "1" +r_model_brightness "0" +r_model_contrast "0" +r_i_model_transform "1" +r_i_model_animation "1" +r_antialias "1" +r_mipmaps_bias "-5.500000" +r_mipmaps_func "0" +r_mipmaps "1" +r_dithering "0" +r_vsync "1" +r_particles_simple "0" +r_tex_scale_down "1" +r_dynamic "1" +r_menufade "0.9" +r_skyclip "2560" +r_skyfog "1" +scr_loadscreen "1" +viewsize "120" +accesspoint "1" +_config_modem_hangup "AT H" +_config_modem_init "" +_config_modem_clear "ATZ" +_config_modem_dialtype "T" +_config_com_modem "1" +_config_com_baud "57600" +_config_com_irq "4" +_config_com_port "0x3f8" +gl_subdivide_size "256" +saved4 "0" +saved3 "-417" +saved2 "-975" +saved1 "-571" +savedgamecfg "1" +max_fps "999" +show_fps "0" +chase_right "0" +chase_up "16" +chase_back "100" +gamma "1" +cl_bobsideup "0.5" +cl_bobsidecycle "0.9" +cl_bobside "0.02" +cl_bobup "0.0" +cl_bobcycle "0.7" +cl_bob "0.015" +crosshair "11" +v_idlescale "0.1" +v_ipitch_level "0.30" +v_iroll_level "0.35" +v_iyaw_level "0.40" +v_ipitch_cycle "12" +v_iroll_cycle "6" +v_iyaw_cycle "6" +v_centerspeed "170" +v_centermove "1" diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BALLOON4.SPR b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BALLOON4.SPR new file mode 100755 index 00000000..f3bb5b28 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BALLOON4.SPR differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BLOOD1.SPR b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BLOOD1.SPR new file mode 100755 index 00000000..72259fa7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BLOOD1.SPR differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_BL.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_BL.LMP new file mode 100755 index 00000000..9e49ba42 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_BL.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_BM.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_BM.LMP new file mode 100755 index 00000000..a1598c89 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_BM.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_BR.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_BR.LMP new file mode 100755 index 00000000..9671c8e6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_BR.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_ML.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_ML.LMP new file mode 100755 index 00000000..a821cecf Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_ML.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_MM.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_MM.LMP new file mode 100755 index 00000000..24afdcf5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_MM.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_MM2.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_MM2.LMP new file mode 100755 index 00000000..24afdcf5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_MM2.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_MR.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_MR.LMP new file mode 100755 index 00000000..049f2244 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_MR.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_TL.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_TL.LMP new file mode 100755 index 00000000..8e5dc279 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_TL.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_TM.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_TM.LMP new file mode 100755 index 00000000..7f7d481e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_TM.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_TR.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_TR.LMP new file mode 100755 index 00000000..e3b3d7ec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/BOX_TR.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_AR.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_AR.LMP new file mode 100755 index 00000000..94611a04 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_AR.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_NEEDLER.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_NEEDLER.lmp new file mode 100755 index 00000000..9876fbbc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_NEEDLER.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_PISTOL.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_PISTOL.LMP new file mode 100755 index 00000000..912dfdae Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_PISTOL.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_PPIST.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_PPIST.lmp new file mode 100755 index 00000000..f6b74ff4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_PPIST.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RAR.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RAR.lmp new file mode 100755 index 00000000..0a50f218 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RAR.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RL.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RL.LMP new file mode 100755 index 00000000..c5778742 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RL.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_ROCKET.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_ROCKET.lmp new file mode 100755 index 00000000..73916bf0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_ROCKET.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RPPIST.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RPPIST.lmp new file mode 100755 index 00000000..d005b998 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RPPIST.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RPistol.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RPistol.lmp new file mode 100755 index 00000000..08b45b64 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RPistol.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RRL.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RRL.lmp new file mode 100755 index 00000000..473f68f9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RRL.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RSHOTTIE.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RSHOTTIE.lmp new file mode 100755 index 00000000..f4e7c901 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RSHOTTIE.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RSMG.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RSMG.lmp new file mode 100755 index 00000000..3736bb3b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RSMG.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RSNIPER.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RSNIPER.lmp new file mode 100755 index 00000000..056d5861 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_RSNIPER.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_SHOTTIE.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_SHOTTIE.LMP new file mode 100755 index 00000000..54b8e94f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_SHOTTIE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_SMG.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_SMG.LMP new file mode 100755 index 00000000..b96c8c5b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_SMG.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_SNIPER.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_SNIPER.lmp new file mode 100755 index 00000000..0d54c125 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_SNIPER.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_SWORD.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_SWORD.lmp new file mode 100755 index 00000000..9876fbbc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/CH_SWORD.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/AR.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/AR.tif new file mode 100755 index 00000000..c78cdebc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/AR.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/RAR.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/RAR.tif new file mode 100755 index 00000000..b3533cb8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/RAR.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/RSMG.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/RSMG.tif new file mode 100755 index 00000000..32e05be3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/RSMG.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/SMG.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/SMG.tif new file mode 100755 index 00000000..d07eb62b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/SMG.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/pistolb.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/pistolb.tif new file mode 100755 index 00000000..73953b1e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/pistolb.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/pistolr.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/pistolr.tif new file mode 100755 index 00000000..401af870 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/pistolr.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/ppistb.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/ppistb.tif new file mode 100755 index 00000000..58944a81 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/ppistb.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/ppistr.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/ppistr.tif new file mode 100755 index 00000000..e8feaaf2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/ppistr.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/rocketb.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/rocketb.tif new file mode 100755 index 00000000..9d573921 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/rocketb.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/rocketr.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/rocketr.tif new file mode 100755 index 00000000..3c8879e2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/rocketr.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/shottieb.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/shottieb.tif new file mode 100755 index 00000000..db279787 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/shottieb.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/shottier.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/shottier.tif new file mode 100755 index 00000000..73745b65 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/shottier.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/sniperb.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/sniperb.tif new file mode 100755 index 00000000..d582f2bb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/sniperb.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/sniperr.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/sniperr.tif new file mode 100755 index 00000000..f616e8b3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/raw/sniperr.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/scope.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/scope.lmp new file mode 100755 index 00000000..0ceb4e19 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CH/scope.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/COLORMAP.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/COLORMAP.LMP new file mode 100755 index 00000000..e71995b8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/COLORMAP.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/COMPLETE.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/COMPLETE.LMP new file mode 100755 index 00000000..bd100145 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/COMPLETE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CONBACK.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CONBACK.LMP new file mode 100755 index 00000000..60141910 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/CONBACK.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_DRCT.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_DRCT.LMP new file mode 100755 index 00000000..9c3e340b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_DRCT.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_IPX.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_IPX.LMP new file mode 100755 index 00000000..ec5806de Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_IPX.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_MODM.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_MODM.LMP new file mode 100755 index 00000000..d030b34d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_MODM.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_MULT.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_MULT.LMP new file mode 100755 index 00000000..0e4f88f8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_MULT.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_TCP.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_TCP.LMP new file mode 100755 index 00000000..ec00f342 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/DIM_TCP.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/FINALE.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/FINALE.LMP new file mode 100755 index 00000000..e910f831 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/FINALE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/INTER.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/INTER.LMP new file mode 100755 index 00000000..d62eb0ac Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/INTER.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/LOADING.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/LOADING.LMP new file mode 100755 index 00000000..8594e3aa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/LOADING.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MAINMENU.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MAINMENU.LMP new file mode 100755 index 00000000..c0fb6287 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MAINMENU.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT1.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT1.LMP new file mode 100755 index 00000000..52a2f4f7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT1.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT2.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT2.LMP new file mode 100755 index 00000000..0f9a2266 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT2.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT3.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT3.LMP new file mode 100755 index 00000000..8c7b5d55 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT3.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT4.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT4.LMP new file mode 100755 index 00000000..6d87b7ca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT4.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT5.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT5.LMP new file mode 100755 index 00000000..6d87b7ca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT5.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT6.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT6.LMP new file mode 100755 index 00000000..6d87b7ca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/MENUDOT6.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN1.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN1.LMP new file mode 100755 index 00000000..44f7c0fd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN1.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN2.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN2.LMP new file mode 100755 index 00000000..3b9f915c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN2.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN3.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN3.LMP new file mode 100755 index 00000000..226573a1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN3.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN4.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN4.LMP new file mode 100755 index 00000000..8d36be54 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN4.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN5.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN5.LMP new file mode 100755 index 00000000..0227c525 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/NETMEN5.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/NUM_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/NUM_1.lmp new file mode 100755 index 00000000..d76cf27d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/NUM_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/NUM_2.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/NUM_2.lmp new file mode 100755 index 00000000..9440ab7e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/NUM_2.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/NUM_3.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/NUM_3.lmp new file mode 100755 index 00000000..969dabec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/NUM_3.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/NUM_4.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/NUM_4.lmp new file mode 100755 index 00000000..1854ee4f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/NUM_4.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/num_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/num_0.lmp new file mode 100755 index 00000000..a10f323c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/Numbers/num_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/PALETTE.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/PALETTE.LMP new file mode 100755 index 00000000..7eefda1d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/PALETTE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/PAUSE.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/PAUSE.LMP new file mode 100755 index 00000000..718bc42a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/PAUSE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/QPLAQUE.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/QPLAQUE.LMP new file mode 100755 index 00000000..3832929a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/QPLAQUE.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/RANKING.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/RANKING.LMP new file mode 100755 index 00000000..4c33fde0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/RANKING.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/VIDMODES.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/VIDMODES.LMP new file mode 100755 index 00000000..c6072cc1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/VIDMODES.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/arb.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/arb.lmp new file mode 100755 index 00000000..1d9b6785 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/arb.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/needleb.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/needleb.lmp new file mode 100755 index 00000000..73634d13 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/needleb.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/pistolb.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/pistolb.lmp new file mode 100755 index 00000000..fcb19667 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/pistolb.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/rocketb.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/rocketb.lmp new file mode 100755 index 00000000..1d4314d4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/rocketb.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/shotgunb.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/shotgunb.lmp new file mode 100755 index 00000000..8c6bbbdf Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/shotgunb.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/sniperb.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/sniperb.lmp new file mode 100755 index 00000000..fe5815da Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ammo/sniperb.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ar.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ar.lmp new file mode 100755 index 00000000..f94c1032 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/ar.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/bflood.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/bflood.spr new file mode 100755 index 00000000..577cef6e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/bflood.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/bigbox.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/bigbox.lmp new file mode 100755 index 00000000..e73cf932 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/bigbox.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/blood.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/blood.spr new file mode 100755 index 00000000..577cef6e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/blood.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock1.lmp new file mode 100755 index 00000000..680d66ac Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock2.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock2.lmp new file mode 100755 index 00000000..bc7588a9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock2.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock3.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock3.lmp new file mode 100755 index 00000000..2b24b806 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock3.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock4.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock4.lmp new file mode 100755 index 00000000..43a2b244 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock4.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock5.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock5.lmp new file mode 100755 index 00000000..be8006eb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock5.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock6.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock6.lmp new file mode 100755 index 00000000..0dbd912c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock6.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock7.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock7.lmp new file mode 100755 index 00000000..e08a12c4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock7.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock8.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock8.lmp new file mode 100755 index 00000000..19ea90f0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock8.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock9.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock9.lmp new file mode 100755 index 00000000..dd770460 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/clock9.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/overlay.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/overlay.lmp new file mode 100755 index 00000000..1c0fe257 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/overlay.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock1.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock1.tif new file mode 100755 index 00000000..6d0f95c1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock1.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock2.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock2.tif new file mode 100755 index 00000000..5815d9bd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock2.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock3.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock3.tif new file mode 100755 index 00000000..7998a094 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock3.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock5.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock5.tif new file mode 100755 index 00000000..cfcdfd3a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock5.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock6.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock6.tif new file mode 100755 index 00000000..175f82e5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock6.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock7.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock7.tif new file mode 100755 index 00000000..ce7c20ee Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock7.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock8.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock8.tif new file mode 100755 index 00000000..768e9487 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock8.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock9.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock9.tif new file mode 100755 index 00000000..92f07817 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/clock/raw/clock9.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/energybr.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/energybr.lmp new file mode 100755 index 00000000..8b2da609 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/energybr.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_BK.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_BK.LMP new file mode 100755 index 00000000..eb0c0569 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_BK.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_BK.PCX b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_BK.PCX new file mode 100755 index 00000000..0d02892b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_BK.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_DN.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_DN.LMP new file mode 100755 index 00000000..0ea8a4e6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_DN.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_DN.PCX b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_DN.PCX new file mode 100755 index 00000000..e9654eaa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_DN.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_FT.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_FT.LMP new file mode 100755 index 00000000..2769d88b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_FT.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_FT.PCX b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_FT.PCX new file mode 100755 index 00000000..1b72af98 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_FT.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_LF.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_LF.LMP new file mode 100755 index 00000000..68b86cca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_LF.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_LF.PCX b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_LF.PCX new file mode 100755 index 00000000..624e6635 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_LF.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_RT.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_RT.LMP new file mode 100755 index 00000000..78475641 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_RT.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_RT.PCX b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_RT.PCX new file mode 100755 index 00000000..d45cebec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_RT.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_UP.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_UP.LMP new file mode 100755 index 00000000..e42e7806 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_UP.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_UP.PCX b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_UP.PCX new file mode 100755 index 00000000..0fbb2e5d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/CLIFF_UP.PCX differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/RingBl.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/RingBl.lmp new file mode 100755 index 00000000..3262c037 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/RingBl.lmp @@ -0,0 +1,7 @@ +oo_|rxziceTX[KMPEî*4(39-?I&- 3>.95EO&8C8BFhov +ݡۛ +&6ܨؓӝ猨Ё&2U\hu|vn^zZvZvVrRn".B6Jl*>w|_epȅ|fzttVjRfoNb^vd~J^fVng^zVr՟Άli~ezl]rRfkUjNb^v&6ZrJ^Vn`{FZ=NrCV~NdRj6Fg"2".F +̾ҫntFLZiv{tl}zrVfRb[mHVwN^bv[ncz%Rf^vNb;JlARxK^QfZr+6PWnRj'2L.<[F\t|bj~fnzU^tZd|q~u|lz%*7dr`n@JcdtMZy".[jDQpVf4>W;FcRb&.AN^^rbvJZ)2H^r"*=Vj/:U5BaVjQfAR~+&;J^"6׳ɋNTd>DUz-2@r~5;Ljv&).<06GENfR^VfRbVfRbJZ:Fj&.F2>^""*BZfVb$&-"&4ZfVb,&.J"*F(*2"2*.B&*>"&:"62-.5""+ + +$! + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/cliff_palette.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/cliff_palette.lmp new file mode 100755 index 00000000..3262c037 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/cliff_palette.lmp @@ -0,0 +1,7 @@ +oo_|rxziceTX[KMPEî*4(39-?I&- 3>.95EO&8C8BFhov +ݡۛ +&6ܨؓӝ猨Ё&2U\hu|vn^zZvZvVrRn".B6Jl*>w|_epȅ|fzttVjRfoNb^vd~J^fVng^zVr՟Άli~ezl]rRfkUjNb^v&6ZrJ^Vn`{FZ=NrCV~NdRj6Fg"2".F +̾ҫntFLZiv{tl}zrVfRb[mHVwN^bv[ncz%Rf^vNb;JlARxK^QfZr+6PWnRj'2L.<[F\t|bj~fnzU^tZd|q~u|lz%*7dr`n@JcdtMZy".[jDQpVf4>W;FcRb&.AN^^rbvJZ)2H^r"*=Vj/:U5BaVjQfAR~+&;J^"6׳ɋNTd>DUz-2@r~5;Ljv&).<06GENfR^VfRbVfRbJZ:Fj&.F2>^""*BZfVb$&-"&4ZfVb,&.J"*F(*2"2*.B&*>"&:"62-.5""+ + +$! + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_bk.lmp new file mode 100755 index 00000000..d339f3b6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_dn.lmp new file mode 100755 index 00000000..d5af8006 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_ft.lmp new file mode 100755 index 00000000..d960f9de Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_lf.lmp new file mode 100755 index 00000000..44350c6d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_palette.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_palette.lmp new file mode 100755 index 00000000..485290ee --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/dayblue_palette.lmp @@ -0,0 +1 @@ +d\Zedb|nu|ɳnlc½utnLLKTTL򡤞ŽZ\Zy|yltl\d\hlk8<< L\dTZ^JcRJZRJ\@JqP=iP>cR=cJB]OMM\rrAAN++4..8EET 11<66BPPc       |{ͯ$#*#   # %%#&     \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/niteblue_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/niteblue_rt.lmp new file mode 100755 index 00000000..1f332f15 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/niteblue_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/niteblue_up.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/niteblue_up.lmp new file mode 100755 index 00000000..55288dd0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/niteblue_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nitebluebk.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nitebluebk.lmp new file mode 100755 index 00000000..5ea02de8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nitebluebk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nitebluedn.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nitebluedn.lmp new file mode 100755 index 00000000..cbc45718 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nitebluedn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/niteblueft.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/niteblueft.lmp new file mode 100755 index 00000000..f6c44fb2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/niteblueft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nitebluelf.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nitebluelf.lmp new file mode 100755 index 00000000..3055f265 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nitebluelf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nitebluert.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nitebluert.lmp new file mode 100755 index 00000000..1f332f15 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nitebluert.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/niteblueup.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/niteblueup.lmp new file mode 100755 index 00000000..55288dd0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/niteblueup.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_bk.lmp new file mode 100755 index 00000000..6b5427d3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_dn.lmp new file mode 100755 index 00000000..6ffaa6ad Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_ft.lmp new file mode 100755 index 00000000..d731724c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_lf.lmp new file mode 100755 index 00000000..f3c24562 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_rt.lmp new file mode 100755 index 00000000..10b766c2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_up.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_up.lmp new file mode 100755 index 00000000..dd3b1276 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_512_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_bk.lmp new file mode 100755 index 00000000..816c5581 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_dn.lmp new file mode 100755 index 00000000..63347950 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_ft.lmp new file mode 100755 index 00000000..e4b26ca2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_lf.lmp new file mode 100755 index 00000000..e452bef8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_palette.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_palette.lmp new file mode 100755 index 00000000..0ac31309 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_palette.lmp @@ -0,0 +1 @@ +wjxeZxgS↷MF{veZLDEA6z~vn~zj~rdLMHC~;v>~6nr/Z6j:r6j2f.^6n2f.b2j*Z.b*^*^ӧҟ~erzvrn~jzvn|~vkrnvmNvSJzCr;f:f;j2^6f4b2^6f:n.Z2b6j.Z.^*V2f.^*Z*Z߳ȝڎ~vnz|m~fv^ni~bvUfez[n^rav|L`e\~_SzHmKrJvAj;aBn7b.Z+V֭ċĞjvzvrdrjz[jriZxQpDfͨz{{~vnzbnfvbrܖr{s~~zvnzjvbrjrfr \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_rt.lmp new file mode 100755 index 00000000..9f23a20d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_up.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_up.lmp new file mode 100755 index 00000000..1796d072 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/nrblue_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512bk.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512bk.pcx new file mode 100755 index 00000000..0e4be5bb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512bk.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512dn.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512dn.pcx new file mode 100755 index 00000000..d81b4dc5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512dn.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512ft.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512ft.pcx new file mode 100755 index 00000000..82e264af Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512ft.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512lf.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512lf.pcx new file mode 100755 index 00000000..2c737bfc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512lf.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512rt.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512rt.pcx new file mode 100755 index 00000000..e46a2f65 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512rt.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512up.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512up.pcx new file mode 100755 index 00000000..3450b926 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl512up.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_bk.lmp new file mode 100755 index 00000000..e0ad00a0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_dn.lmp new file mode 100755 index 00000000..bb2fd144 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_ft.lmp new file mode 100755 index 00000000..a5565345 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_lf.lmp new file mode 100755 index 00000000..e5d16b0e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_rt.lmp new file mode 100755 index 00000000..71a5c55a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_up.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_up.lmp new file mode 100755 index 00000000..2fc4baad Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbl_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblbk.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblbk.lmp new file mode 100755 index 00000000..e0ad00a0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblbk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblbk.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblbk.pcx new file mode 100755 index 00000000..9e51e749 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblbk.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbldn.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbldn.lmp new file mode 100755 index 00000000..bb2fd144 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbldn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbldn.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbldn.pcx new file mode 100755 index 00000000..fb067a0f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbldn.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblft.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblft.lmp new file mode 100755 index 00000000..a5565345 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblft.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblft.pcx new file mode 100755 index 00000000..5d20d9cd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblft.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbllf.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbllf.lmp new file mode 100755 index 00000000..e5d16b0e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbllf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbllf.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbllf.pcx new file mode 100755 index 00000000..f8bba06f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringbllf.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblrt.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblrt.lmp new file mode 100755 index 00000000..71a5c55a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblrt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblrt.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblrt.pcx new file mode 100755 index 00000000..a9e3e428 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblrt.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblup.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblup.lmp new file mode 100755 index 00000000..2fc4baad Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblup.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblup.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblup.pcx new file mode 100755 index 00000000..a821d541 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/ringblup.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/skty b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/skty new file mode 100755 index 00000000..7e1ed665 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/skty differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_bk.lmp new file mode 100755 index 00000000..c6faaf0e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_dn.lmp new file mode 100755 index 00000000..68ccc943 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_ft.lmp new file mode 100755 index 00000000..e190c800 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_lf.lmp new file mode 100755 index 00000000..7f08d9c2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_palette.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_palette.lmp new file mode 100755 index 00000000..3262c037 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_palette.lmp @@ -0,0 +1,7 @@ +oo_|rxziceTX[KMPEî*4(39-?I&- 3>.95EO&8C8BFhov +ݡۛ +&6ܨؓӝ猨Ё&2U\hu|vn^zZvZvVrRn".B6Jl*>w|_epȅ|fzttVjRfoNb^vd~J^fVng^zVr՟Άli~ezl]rRfkUjNb^v&6ZrJ^Vn`{FZ=NrCV~NdRj6Fg"2".F +̾ҫntFLZiv{tl}zrVfRb[mHVwN^bv[ncz%Rf^vNb;JlARxK^QfZr+6PWnRj'2L.<[F\t|bj~fnzU^tZd|q~u|lz%*7dr`n@JcdtMZy".[jDQpVf4>W;FcRb&.AN^^rbvJZ)2H^r"*=Vj/:U5BaVjQfAR~+&;J^"6׳ɋNTd>DUz-2@r~5;Ljv&).<06GENfR^VfRbVfRbJZ:Fj&.F2>^""*BZfVb$&-"&4ZfVb,&.J"*F(*2"2*.B&*>"&:"62-.5""+ + +$! + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_rt.lmp new file mode 100755 index 00000000..45867c45 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_up.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_up.lmp new file mode 100755 index 00000000..006703a9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_512_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_bk.lm b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_bk.lm new file mode 100755 index 00000000..f9b70a4b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_bk.lm differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_bk.lmp new file mode 100755 index 00000000..5ea02de8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_dn.lm b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_dn.lm new file mode 100755 index 00000000..153cbb84 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_dn.lm differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_dn.lmp new file mode 100755 index 00000000..c981641d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ft.lm b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ft.lm new file mode 100755 index 00000000..7409155e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ft.lm differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ft.lmp new file mode 100755 index 00000000..f6c44fb2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_lf.lm b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_lf.lm new file mode 100755 index 00000000..b82cc96f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_lf.lm differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_lf.lmp new file mode 100755 index 00000000..3055f265 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_palette.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_palette.lmp new file mode 100755 index 00000000..12441121 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_palette.lmp @@ -0,0 +1 @@ + !!!###%%%'''888???DDD EC@BA=!! !#!   !          !#$#%'     "@AC     15O9:BOTzTZ),C?Dg%(=X[x]bIMpDHj7:X!#5-0I;?aIJX;MM\rrAAN++4..8EET 11<66BPPc       |{ͯ$#*#   # %%#&     \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256 b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256 new file mode 100755 index 00000000..90ef1866 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256 differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256bk.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256bk.lmp new file mode 100755 index 00000000..11f858d8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256bk.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256bk.pcx new file mode 100755 index 00000000..c894f7ef Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256bk.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256dn.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256dn.lmp new file mode 100755 index 00000000..c981641d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256dn.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256dn.pcx new file mode 100755 index 00000000..c9129d69 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256dn.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256ft.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256ft.lmp new file mode 100755 index 00000000..f400ce2a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256ft.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256ft.pcx new file mode 100755 index 00000000..2142f513 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256ft.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256lf.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256lf.lmp new file mode 100755 index 00000000..e7be5be8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256lf.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256lf.pcx new file mode 100755 index 00000000..9bc2c7af Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256lf.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256rt.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256rt.lmp new file mode 100755 index 00000000..191dc2d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256rt.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256rt.pcx new file mode 100755 index 00000000..839ecfd5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256rt.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256up.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256up.lmp new file mode 100755 index 00000000..f8085516 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256up.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256up.pcx new file mode 100755 index 00000000..0e605425 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringblue256up.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringlblue256bk.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringlblue256bk.lmp new file mode 100755 index 00000000..11f858d8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_ringlblue256bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_rt.lm b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_rt.lm new file mode 100755 index 00000000..70a74d78 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_rt.lm differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_rt.lmp new file mode 100755 index 00000000..1f332f15 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_up.lm b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_up.lm new file mode 100755 index 00000000..ddc32dcd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_up.lm differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_up.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_up.lmp new file mode 100755 index 00000000..f8085516 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/sky_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/skybox_template.tgd b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/skybox_template.tgd new file mode 100755 index 00000000..33f8b4ac --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/skybox_template.tgd @@ -0,0 +1,599 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars.pcx b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars.pcx new file mode 100755 index 00000000..20b50d3d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars.pcx differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_bk.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_bk.lmp new file mode 100755 index 00000000..01352355 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_bk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_dn.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_dn.lmp new file mode 100755 index 00000000..01352355 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_dn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_ft.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_ft.lmp new file mode 100755 index 00000000..01352355 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_ft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_lf.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_lf.lmp new file mode 100755 index 00000000..01352355 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_lf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_rt.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_rt.lmp new file mode 100755 index 00000000..01352355 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_rt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_up.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_up.lmp new file mode 100755 index 00000000..01352355 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/stars_up.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsbk.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsbk.lmp new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsbk.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsdn.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsdn.lmp new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsdn.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsft.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsft.lmp new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsft.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starslf.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starslf.lmp new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starslf.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsrt.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsrt.lmp new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsrt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsup.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsup.lmp new file mode 100755 index 00000000..0ba0d80c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/env/starsup.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/fraggrenade.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/fraggrenade.lmp new file mode 100755 index 00000000..24d51a82 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/fraggrenade.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/gamet/Firefight.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/gamet/Firefight.lmp new file mode 100755 index 00000000..6aaebba9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/gamet/Firefight.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/gamet/firefight.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/gamet/firefight.tif new file mode 100755 index 00000000..67952d60 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/gamet/firefight.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/gamet/slayer.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/gamet/slayer.lmp new file mode 100755 index 00000000..f5f680d3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/gamet/slayer.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/gamet/slayer.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/gamet/slayer.tif new file mode 100755 index 00000000..e558e038 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/gamet/slayer.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/healthb.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/healthb.lmp new file mode 100755 index 00000000..236f64f9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/healthb.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/healthback.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/healthback.lmp new file mode 100755 index 00000000..e8eea073 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/healthback.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/healthbackr.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/healthbackr.lmp new file mode 100755 index 00000000..b279c24e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/healthbackr.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/m_bttns.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/m_bttns.lmp new file mode 100755 index 00000000..690f7373 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/m_bttns.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m1.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m1.BSP new file mode 100755 index 00000000..5f3080f1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m1.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m2.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m2.bsp new file mode 100755 index 00000000..a974f6f0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m2.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m3.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m3.bsp new file mode 100755 index 00000000..9999390f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m3.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m4.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m4.bsp new file mode 100755 index 00000000..34da4c3d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m4.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m5.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m5.bsp new file mode 100755 index 00000000..f38fc2da Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m5.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m6.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m6.BSP new file mode 100755 index 00000000..ad29cf23 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m6.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m7.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m7.BSP new file mode 100755 index 00000000..7c892d01 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/maps/e1m7.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/medals/Double.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/medals/Double.lmp new file mode 100755 index 00000000..5d5efee8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/medals/Double.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/medals/Triple.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/medals/Triple.lmp new file mode 100755 index 00000000..0945aee6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/medals/Triple.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/medals/killtacular.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/medals/killtacular.lmp new file mode 100755 index 00000000..f02a7811 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/medals/killtacular.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/medals/killtrocity.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/medals/killtrocity.lmp new file mode 100755 index 00000000..2ab9798c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/medals/killtrocity.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/OPTIONS_0.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/OPTIONS_0.LMP new file mode 100755 index 00000000..c844917b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/OPTIONS_0.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/OPTIONS_1.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/OPTIONS_1.LMP new file mode 100755 index 00000000..e905b379 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/OPTIONS_1.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/OPTION_0.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/OPTION_0.LMP new file mode 100755 index 00000000..c844917b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/OPTION_0.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/OPTION_1.LMP b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/OPTION_1.LMP new file mode 100755 index 00000000..e905b379 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/OPTION_1.LMP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/TEXT_BOX.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/TEXT_BOX.lmp new file mode 100755 index 00000000..6ecbd00a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/TEXT_BOX.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/firefight_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/firefight_0.lmp new file mode 100755 index 00000000..0fed6df6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/firefight_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/firefight_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/firefight_1.lmp new file mode 100755 index 00000000..a4fd562d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/firefight_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/firefight_desc.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/firefight_desc.lmp new file mode 100755 index 00000000..67ba4b76 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/firefight_desc.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/slayer_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/slayer_0.lmp new file mode 100755 index 00000000..b6dafbca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/slayer_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/slayer_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/slayer_1.lmp new file mode 100755 index 00000000..450225a8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/slayer_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/slayer_desc.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/slayer_desc.lmp new file mode 100755 index 00000000..55c3db2d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/slayer_desc.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/swat_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/swat_0.lmp new file mode 100755 index 00000000..1395d950 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/swat_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/swat_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/swat_1.lmp new file mode 100755 index 00000000..bc6a2d0b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/gametypes/swat_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/help_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/help_0.lmp new file mode 100755 index 00000000..5a526692 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/help_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/help_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/help_1.lmp new file mode 100755 index 00000000..460ad496 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/help_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help0.lmp new file mode 100755 index 00000000..ba605847 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help1.lmp new file mode 100755 index 00000000..4f92a0a3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help2.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help2.lmp new file mode 100755 index 00000000..4f92a0a3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help2.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help3.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help3.lmp new file mode 100755 index 00000000..4f92a0a3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help3.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help4.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help4.lmp new file mode 100755 index 00000000..4f92a0a3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help4.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help5.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help5.lmp new file mode 100755 index 00000000..4f92a0a3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/hp/help5.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/loadback.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/loadback.lmp new file mode 100755 index 00000000..8594e3aa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/loadback.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/adhoc_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/adhoc_0.lmp new file mode 100755 index 00000000..eebac604 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/adhoc_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/adhoc_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/adhoc_1.lmp new file mode 100755 index 00000000..5930d5f1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/adhoc_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/create_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/create_0.lmp new file mode 100755 index 00000000..ccc37e76 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/create_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/create_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/create_1.lmp new file mode 100755 index 00000000..50901922 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/create_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/inf_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/inf_0.lmp new file mode 100755 index 00000000..71903535 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/inf_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/inf_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/inf_1.lmp new file mode 100755 index 00000000..2966c844 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/inf_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/join_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/join_0.lmp new file mode 100755 index 00000000..4a1fe9c6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/join_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/join_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/join_1.lmp new file mode 100755 index 00000000..0a7a9f80 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/join_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/setup_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/setup_0.lmp new file mode 100755 index 00000000..cf592bc9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/setup_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/setup_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/setup_1.lmp new file mode 100755 index 00000000..3bb5ab8a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/mp/setup_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/multi_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/multi_0.lmp new file mode 100755 index 00000000..bba94d8f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/multi_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/multi_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/multi_1.lmp new file mode 100755 index 00000000..0f1605fd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/multi_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/quit_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/quit_0.lmp new file mode 100755 index 00000000..2b066a62 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/quit_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/quit_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/quit_1.lmp new file mode 100755 index 00000000..5405eba4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/quit_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sel_gt.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sel_gt.lmp new file mode 100755 index 00000000..fa24f0bb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sel_gt.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/single_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/single_0.lmp new file mode 100755 index 00000000..698e80b0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/single_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/single_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/single_1.lmp new file mode 100755 index 00000000..92f69c49 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/single_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/load_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/load_0.lmp new file mode 100755 index 00000000..d02ea66e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/load_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/load_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/load_1.lmp new file mode 100755 index 00000000..98a2432e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/load_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/new_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/new_0.lmp new file mode 100755 index 00000000..923e5e5f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/new_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/new_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/new_1.lmp new file mode 100755 index 00000000..bf99b2f0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/new_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/save_0.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/save_0.lmp new file mode 100755 index 00000000..c8912fe5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/save_0.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/save_1.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/save_1.lmp new file mode 100755 index 00000000..cb01b7b2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/sp/save_1.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/title.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/title.lmp new file mode 100755 index 00000000..6d87b7ca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menu/title.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menuplyr.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menuplyr.lmp new file mode 100755 index 00000000..72dd619b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/menuplyr.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/plasmanade.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/plasmanade.lmp new file mode 100755 index 00000000..82d7fc1a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/plasmanade.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/pop.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/pop.lmp new file mode 100755 index 00000000..6e64e4c1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/pop.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/sell.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/sell.lmp new file mode 100755 index 00000000..e0173c31 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/sell.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/easy.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/easy.lmp new file mode 100755 index 00000000..a6e88768 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/easy.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/easy.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/easy.tif new file mode 100755 index 00000000..ad1be502 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/easy.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/her.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/her.tif new file mode 100755 index 00000000..9c4fddb1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/her.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/heroic.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/heroic.lmp new file mode 100755 index 00000000..f4d1fcff Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/heroic.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/legendary (1).tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/legendary (1).tif new file mode 100755 index 00000000..3d5f4397 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/legendary (1).tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/legendary.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/legendary.lmp new file mode 100755 index 00000000..604b174a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/legendary.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/legendary.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/legendary.tif new file mode 100755 index 00000000..3d5f4397 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/legendary.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/normal (1).tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/normal (1).tif new file mode 100755 index 00000000..fcf1895c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/normal (1).tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/normal.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/normal.lmp new file mode 100755 index 00000000..8204a449 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/normal.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/normal.tif b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/normal.tif new file mode 100755 index 00000000..fcf1895c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/skill/normal.tif differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/title.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/title.lmp new file mode 100755 index 00000000..20633315 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/title.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/Pistol.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/Pistol.lmp new file mode 100755 index 00000000..ea1862d3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/Pistol.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/RL.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/RL.lmp new file mode 100755 index 00000000..2f6723f9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/RL.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/ar.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/ar.lmp new file mode 100755 index 00000000..db186c00 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/ar.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/needler.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/needler.lmp new file mode 100755 index 00000000..e9ba9670 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/needler.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/ppist.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/ppist.lmp new file mode 100755 index 00000000..65927ff0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/ppist.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/shottie.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/shottie.lmp new file mode 100755 index 00000000..d6157197 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/shottie.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/smg.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/smg.lmp new file mode 100755 index 00000000..c1e0f235 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/smg.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/sniper.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/sniper.lmp new file mode 100755 index 00000000..d5bf302c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/weapons/sniper.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/ar.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/ar.lmp new file mode 100755 index 00000000..0f54131c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/ar.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/needler.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/needler.lmp new file mode 100755 index 00000000..88c9b51b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/needler.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/pistol.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/pistol.lmp new file mode 100755 index 00000000..5b6755d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/pistol.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/ppist.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/ppist.lmp new file mode 100755 index 00000000..c1a5f2ee Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/ppist.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/rl.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/rl.lmp new file mode 100755 index 00000000..21538f45 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/rl.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/shottie.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/shottie.lmp new file mode 100755 index 00000000..27227114 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/shottie.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/smg.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/smg.lmp new file mode 100755 index 00000000..9a9172a3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/smg.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/sniper.lmp b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/sniper.lmp new file mode 100755 index 00000000..c69b5045 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/GFX/worldweapons/sniper.lmp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/autoexec.cfg b/r17/Revamped src/revamped_src/psp/normal/kurok/autoexec.cfg new file mode 100755 index 00000000..1aee2c53 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/autoexec.cfg @@ -0,0 +1,3 @@ + +fov 80 +impulse 50 \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/default.CFG b/r17/Revamped src/revamped_src/psp/normal/kurok/default.CFG new file mode 100755 index 00000000..4ab07fd7 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/default.CFG @@ -0,0 +1,141 @@ +bind "TAB" "+showscores" +bind "ESCAPE" "togglemenu" +bind "+" "sizeup" +bind "," "+moveleft" +bind "-" "sizedown" +bind "." "+moveright" +bind "0" "impulse 0" +bind "1" "impulse 1" +bind "2" "impulse 2" +bind "3" "impulse 3" +bind "4" "impulse 4" +bind "5" "impulse 5" +bind "6" "impulse 6" +bind "7" "impulse 7" +bind "8" "impulse 8" +bind "=" "sizeup" +bind "\" "+mlook" +bind "`" "impulse 27" +bind "a" "+moveleft" +bind "c" "+movedown" +bind "d" "+moveright" +bind "s" "+back" +bind "t" "messagemode" +bind "w" "+forward" +bind "z" "+lookdown" +bind "~" "impulse 11" +bind "UPARROW" "impulse 10" +bind "DOWNARROW" "+jump" +bind "LEFTARROW" "impulse 13" +bind "RIGHTARROW" "impulse 29" +bind "ALT" "+strafe" +bind "F1" "help" +bind "F2" "menu_save" +bind "F3" "menu_load" +bind "F4" "menu_options" +bind "F5" "menu_multiplayer" +bind "F6" "echo Quicksaving...; wait; save quick" +bind "F9" "echo Quickloading...; wait; load quick" +bind "F10" "quit" +bind "F11" "zoom_in" +bind "F12" "screenshot" +bind "INS" "+klook" +bind "DEL" "+lookdown" +bind "PGDN" "+lookup" +bind "END" "centerview" +bind "MOUSE2" "+forward" +bind "MOUSE3" "+mlook" +bind "TRIANGLE" "+forward" +bind "CIRCLE" "+moveright" +bind "CROSS" "+back" +bind "SQUARE" "+moveleft" +bind "LTRIGGER" "impulse 28" +bind "RTRIGGER" "+attack" +bind "MWHEELDOWN" "impulse 12" +bind "PAUSE" "pause" +m_side "0.8" +m_forward "1" +m_yaw "0.022" +m_pitch "0.022000" +in_y_axis_adjust "4" +in_x_axis_adjust "4" +in_analog_strafe "0" +in_disable_analog "0.000000" +in_freelook_analog "1" +acceleration "3.000000" +tolerance "0.470000" +sensitivity "10" +lookcenter "1" +lookstrafe "1" +lookspring "0" +cl_autoaim "2" +cl_backspeed "200" +cl_forwardspeed "200" +_cl_color "68" +_cl_name "Mexicouger" +_snd_mixahead "0.1" +bgmtype "cd" +bgmvolume "1" +volume "0.500000" +vl_lowcut "60" +vl_highcut "128" +vl_yaw "45" +vl_pitch "45" +vl_light "0" +gl_keeptjunctions "1" +r_model_brightness "1" +r_model_contrast "0" +r_i_model_transform "1" +r_i_model_animation "1" +r_antialias "0" +r_mipmaps_bias "-5.500000" +r_mipmaps_func "0" +r_mipmaps "1" +r_dithering "0" +r_vsync "0" +r_particles_simple "0" +r_tex_scale_down "1" +r_dynamic "0" +r_menufade "0.9" +r_skyclip "2560" +r_skyfog "1" +scr_loadscreen "1" +scr_conheight "0.5" +viewsize "120" +sv_aim "2.0" +accesspoint "1" +_config_com_baud "57600" +_config_com_irq "4" +_config_com_modem "1" +_config_com_port "0x3f8" +_config_modem_clear "ATZ" +_config_modem_dialtype "T" +_config_modem_hangup "AT H" +_config_modem_init "" +gl_subdivide_size "256" +saved4 "0" +saved3 "271" +saved2 "3" +saved1 "-571" +savedgamecfg "1" +max_fps "999" +show_fps "0" +gamma "1" +cl_bobsideup "0.5" +cl_bobsidecycle "0.9" +cl_bobside "0.02" +cl_bobup "0.0" +cl_bobcycle "0.7" +cl_bob "0.015" +r_viewmodeloffset "0" +crosshair "11" +v_idlescale "0.1" +v_ipitch_level "0.30" +v_iroll_level "0.35" +v_iyaw_level "0.40" +v_ipitch_cycle "12" +v_iroll_cycle "6" +v_iyaw_cycle "6" +v_centerspeed "170" +v_centermove "1" +fov "80" diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/demo1.dem b/r17/Revamped src/revamped_src/psp/normal/kurok/demo1.dem new file mode 100755 index 00000000..6b371a91 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/demo1.dem differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/demo2.dem b/r17/Revamped src/revamped_src/psp/normal/kurok/demo2.dem new file mode 100755 index 00000000..6b371a91 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/demo2.dem differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/demo3.dem b/r17/Revamped src/revamped_src/psp/normal/kurok/demo3.dem new file mode 100755 index 00000000..6b371a91 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/demo3.dem differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/gfx.wad b/r17/Revamped src/revamped_src/psp/normal/kurok/gfx.wad new file mode 100755 index 00000000..363c5e5c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/gfx.wad differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+Battle.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+Battle.bsp new file mode 100755 index 00000000..1e648e1d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+Battle.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+HangEmHight.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+HangEmHight.bsp new file mode 100755 index 00000000..e45305c1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+HangEmHight.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+Lane.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+Lane.bsp new file mode 100755 index 00000000..5cb06aa9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+Lane.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+LinksTemple.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+LinksTemple.bsp new file mode 100755 index 00000000..e58cd807 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+LinksTemple.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+Maze.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+Maze.bsp new file mode 100755 index 00000000..70ca67b5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+Maze.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+TrapBridgesCTF.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+TrapBridgesCTF.bsp new file mode 100755 index 00000000..63b32445 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+TrapBridgesCTF.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+TrapBridgesCTF.lit b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+TrapBridgesCTF.lit new file mode 100755 index 00000000..e3a68d95 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+TrapBridgesCTF.lit differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+allout.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+allout.bsp new file mode 100755 index 00000000..b8aa60a0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+allout.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+arch.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+arch.bsp new file mode 100755 index 00000000..02d4b035 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+arch.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+battlecreek1.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+battlecreek1.bsp new file mode 100755 index 00000000..ab0b9008 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+battlecreek1.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+battlecreek2.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+battlecreek2.bsp new file mode 100755 index 00000000..544a3067 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+battlecreek2.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+battlecreek3.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+battlecreek3.bsp new file mode 100755 index 00000000..2fc7119e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+battlecreek3.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+beta.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+beta.bsp new file mode 100755 index 00000000..c7e818e3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+beta.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+bloodgulch1.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+bloodgulch1.bsp new file mode 100755 index 00000000..614d67bc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+bloodgulch1.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+bloodgulch2.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+bloodgulch2.bsp new file mode 100755 index 00000000..d22f49ae Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+bloodgulch2.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+darkbattle (1).bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+darkbattle (1).bsp new file mode 100755 index 00000000..137f2d60 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+darkbattle (1).bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+darkbattle.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+darkbattle.bsp new file mode 100755 index 00000000..137f2d60 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+darkbattle.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+desertk19 (1).bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+desertk19 (1).bsp new file mode 100755 index 00000000..5fe0470c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+desertk19 (1).bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+desertk19.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+desertk19.bsp new file mode 100755 index 00000000..5fe0470c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+desertk19.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+ezerctrazo2 (1).bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+ezerctrazo2 (1).bsp new file mode 100755 index 00000000..e9aa78e8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+ezerctrazo2 (1).bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+ezerctrazo2.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+ezerctrazo2.bsp new file mode 100755 index 00000000..e9aa78e8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+ezerctrazo2.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+field (1).bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+field (1).bsp new file mode 100755 index 00000000..b9cdeab0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+field (1).bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+field.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+field.bsp new file mode 100755 index 00000000..b9cdeab0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+field.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+frostbite (1).bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+frostbite (1).bsp new file mode 100755 index 00000000..0705ffd6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+frostbite (1).bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+frostbite.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+frostbite.bsp new file mode 100755 index 00000000..0705ffd6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+frostbite.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+frostbite.lit b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+frostbite.lit new file mode 100755 index 00000000..04788849 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+frostbite.lit differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+jaloarena.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+jaloarena.bsp new file mode 100755 index 00000000..998d8d9b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+jaloarena.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+narrowedctf (1).bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+narrowedctf (1).bsp new file mode 100755 index 00000000..7ae72f2b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+narrowedctf (1).bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+narrowedctf.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+narrowedctf.bsp new file mode 100755 index 00000000..7ae72f2b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+narrowedctf.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+narrowedgrey (1).BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+narrowedgrey (1).BSP new file mode 100755 index 00000000..1c2357cf Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+narrowedgrey (1).BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+narrowedgrey.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+narrowedgrey.BSP new file mode 100755 index 00000000..1c2357cf Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+narrowedgrey.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+open (1).bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+open (1).bsp new file mode 100755 index 00000000..221151a9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+open (1).bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+open.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+open.bsp new file mode 100755 index 00000000..221151a9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+open.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+pit (1).bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+pit (1).bsp new file mode 100755 index 00000000..44754840 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+pit (1).bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+pit.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+pit.bsp new file mode 100755 index 00000000..44754840 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+pit.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+prisoner (1).bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+prisoner (1).bsp new file mode 100755 index 00000000..dbed6ef4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+prisoner (1).bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+prisoner.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+prisoner.bsp new file mode 100755 index 00000000..dbed6ef4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+prisoner.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+sandtrap.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+sandtrap.BSP new file mode 100755 index 00000000..35665061 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+sandtrap.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+separation.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+separation.bsp new file mode 100755 index 00000000..bd60f1bd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+separation.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+space.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+space.bsp new file mode 100755 index 00000000..7d97ea73 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+space.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+station117.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+station117.bsp new file mode 100755 index 00000000..731aadcc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+station117.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+station118.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+station118.bsp new file mode 100755 index 00000000..931ce376 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+station118.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+trapbridges.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+trapbridges.bsp new file mode 100755 index 00000000..f1f80eed Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/+trapbridges.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/118.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/118.bsp new file mode 100755 index 00000000..931ce376 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/118.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/118.way b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/118.way new file mode 100755 index 00000000..0f2a13a3 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/118.way @@ -0,0 +1,187 @@ +// Station 118 By Mexicouger - maps/118.way +// Ways by GreeZy +saved1 -1008; saved2 -1159; saved3 62 +scratch1 2; scratch2 0; scratch3 0; scratch4 0 +saved4 1; wait +saved1 -1001; saved2 -999 +scratch1 1; scratch2 3; scratch3 42 +saved4 2; wait +saved1 -994; saved2 -828 +scratch1 2; scratch2 4; scratch3 0 +saved4 2; wait +saved1 -1012; saved2 -677 +scratch1 3; scratch2 5 +saved4 2; wait +saved1 -1006; saved2 -506 +scratch1 4; scratch2 6 +saved4 2; wait +saved1 -993; saved2 -340 +scratch1 5; scratch2 7 +saved4 2; wait +saved1 -821; saved2 -274; saved3 104 +scratch1 6; scratch2 8 +saved4 2; wait +saved1 -663; saved2 -264; saved3 209 +scratch1 7; scratch2 9 +saved4 2; wait +saved1 -476; saved2 -252; saved3 270 +scratch1 10; scratch2 51; scratch3 52 +saved4 2; wait +saved1 -362; saved2 -363 +scratch1 9; scratch2 11; scratch3 0 +saved4 2; wait +saved1 -341; saved2 -543 +scratch1 10; scratch2 12 +saved4 2; wait +saved1 -310; saved2 -713 +scratch1 11; scratch2 13 +saved4 2; wait +saved1 -277; saved2 -880 +scratch1 12; scratch2 14 +saved4 2; wait +saved1 -221; saved2 -1043 +scratch1 13; scratch2 15 +saved4 2; wait +saved1 -101; saved2 -1166 +scratch1 14; scratch2 16 +saved4 2; wait +saved1 59; saved2 -1225 +scratch1 15; scratch2 17 +saved4 2; wait +saved1 102; saved2 -1233 +scratch1 18; scratch2 45 +saved4 2; wait +saved1 283; saved2 -1254; saved3 169 +scratch1 19; scratch2 0 +saved4 2; wait +saved1 421; saved2 -1247; saved3 77 +scratch1 20 +saved4 2; wait +saved1 540; saved2 -1126; saved3 62 +scratch1 19; scratch2 21 +saved4 2; wait +saved1 546; saved2 -952 +scratch1 20; scratch2 22 +saved4 2; wait +saved1 481; saved2 -796 +scratch1 21; scratch2 23; scratch3 46 +saved4 2; wait +saved1 339; saved2 -775; saved3 30 +scratch1 24; scratch2 0; scratch3 0 +saved4 2; wait +saved1 205; saved2 -759; saved3 -50 +scratch1 25 +saved4 2; wait +saved1 106; saved2 -774; saved3 -114 +scratch1 26 +saved4 2; wait +saved1 -40; saved2 -838; saved3 -130 +scratch1 25; scratch2 27 +saved4 2; wait +saved1 -216; saved2 -837 +scratch1 26; scratch2 28; scratch3 39; scratch4 40 +saved4 2; wait +saved1 -386; saved2 -883 +scratch1 27; scratch2 29; scratch3 0; scratch4 0 +saved4 2; wait +saved1 -498; saved2 -1027 +scratch1 28; scratch2 30 +saved4 2; wait +saved1 -665; saved2 -1045 +scratch1 29; scratch2 31 +saved4 2; wait +saved1 -832; saved2 -1049 +scratch1 30; scratch2 0 +saved4 2; wait +saved1 -985; saved2 -937 +scratch1 33 +saved4 2; wait +saved1 -997; saved2 -774 +scratch1 32; scratch2 34; scratch3 56 +saved4 18; wait +saved1 -995; saved2 -616 +scratch1 33; scratch2 0; scratch3 0 +saved4 2; wait +saved1 -917; saved2 -474 +scratch1 36 +saved4 2; wait +saved1 -733; saved2 -475 +scratch1 35; scratch2 37 +saved4 2; wait +saved1 -561; saved2 -484 +scratch1 36; scratch2 38; scratch3 55 +saved4 2; wait +saved1 -394; saved2 -494 +scratch1 37; scratch2 39; scratch3 0 +saved4 2; wait +saved1 -209; saved2 -502 +scratch1 38; scratch2 27 +saved4 2; wait +saved1 -510; saved2 -779 +scratch1 27; scratch2 41 +saved4 2; wait +saved1 -665; saved2 -794; saved3 -50 +scratch1 40; scratch2 0 +saved4 2; wait +saved1 -846; saved2 -1225; saved3 88 +scratch1 2; scratch2 43 +saved4 2; wait +saved1 -687; saved2 -1251; saved3 194 +scratch1 42; scratch2 44 +saved4 2; wait +saved1 -588; saved2 -1257; saved3 259 +scratch1 45; scratch2 0 +saved4 2; wait +saved1 -432; saved2 -1265; saved3 270 +scratch1 44; scratch2 17 +saved4 2; wait +saved1 523; saved2 -616; saved3 62 +scratch1 22; scratch2 47 +saved4 2; wait +saved1 522; saved2 -443 +scratch1 46; scratch2 48 +saved4 2; wait +saved1 429; saved2 -285; saved3 72 +scratch1 47; scratch2 49 +saved4 2; wait +saved1 294; saved2 -191; saved3 162 +scratch1 48; scratch2 50 +saved4 2; wait +saved1 138; saved2 -224; saved3 266 +scratch1 51; scratch2 0 +saved4 2; wait +saved1 -37; saved2 -250; saved3 270 +scratch1 50; scratch2 9 +saved4 2; wait +saved1 -572; saved2 -241 +scratch1 0; scratch2 0 +saved4 2; wait +saved1 -697; saved2 22; saved3 -88 +scratch1 54 +saved4 2; wait +saved1 -592; saved2 -81; saved3 -130 +scratch1 55 +saved4 2; wait +saved1 -438; saved2 -138 +scratch1 54; scratch2 37 +saved4 2; wait +saved1 674; saved2 -757 +scratch1 57; scratch2 0 +saved4 2; wait +saved1 534; saved2 -841 +scratch1 56; scratch2 58 +saved4 2; wait +saved1 524; saved2 -994 +scratch1 57; scratch2 0 +saved4 2; wait +saved1 345; saved2 -1033 +scratch1 60 +saved4 2; wait +saved1 175; saved2 -1022 +scratch1 59; scratch2 61 +saved4 2; wait +saved1 -85; saved2 -1014 +scratch1 60; scratch2 27 +saved4 2; wait +saved4 3 +// end waypoint dump diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_BH10.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_BH10.BSP new file mode 100755 index 00000000..d239f31f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_BH10.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_BH100.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_BH100.BSP new file mode 100755 index 00000000..61686340 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_BH100.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_BH25.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_BH25.BSP new file mode 100755 index 00000000..71f8e5d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_BH25.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_EXBOX2.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_EXBOX2.BSP new file mode 100755 index 00000000..ed4c768a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_EXBOX2.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_EXPLOB.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_EXPLOB.BSP new file mode 100755 index 00000000..da8128b0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_EXPLOB.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_NAIL0.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_NAIL0.BSP new file mode 100755 index 00000000..d79126ca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_NAIL0.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_NAIL1.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_NAIL1.BSP new file mode 100755 index 00000000..15e225e6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_NAIL1.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_ROCK0.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_ROCK0.BSP new file mode 100755 index 00000000..f9c28637 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_ROCK0.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_ROCK1.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_ROCK1.BSP new file mode 100755 index 00000000..1673dc8c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_ROCK1.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_SHELL0.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_SHELL0.BSP new file mode 100755 index 00000000..78440a65 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_SHELL0.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_SHELL1.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_SHELL1.BSP new file mode 100755 index 00000000..c919aa00 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/B_SHELL1.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Boarding.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Boarding.bsp new file mode 100755 index 00000000..48f049ca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Boarding.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Cestra.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Cestra.bsp new file mode 100755 index 00000000..c221f783 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Cestra.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Cliff.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Cliff.bsp new file mode 100755 index 00000000..4ae5b855 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Cliff.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Desert.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Desert.bsp new file mode 100755 index 00000000..2609ab94 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Desert.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Elite.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Elite.bsp new file mode 100755 index 00000000..62c4e0f6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Elite.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Foundation.way b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Foundation.way new file mode 100755 index 00000000..0d285a21 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Foundation.way @@ -0,0 +1,169 @@ +// Foundation (Halo 2) By Mexicouger - maps/Founda.way +// Ways by GreeZy +saved1 70; saved2 -1920; saved3 -417 +scratch1 2; scratch2 0; scratch3 0; scratch4 0 +saved4 1; wait +saved1 189; saved2 -1783 +scratch1 1; scratch2 3 +saved4 2; wait +saved1 274; saved2 -1617; saved3 -414 +scratch1 4; scratch2 0 +saved4 2; wait +saved1 344; saved2 -1572; saved3 -194 +scratch1 3; scratch2 5 +saved4 2; wait +saved1 384; saved2 -1404 +scratch1 4; scratch2 6 +saved4 2; wait +saved1 312; saved2 -1246 +scratch1 5; scratch2 7 +saved4 2; wait +saved1 266; saved2 -1084 +scratch1 6; scratch2 8 +saved4 2; wait +saved1 160; saved2 -935 +scratch1 7; scratch2 0 +saved4 2; wait +saved1 123; saved2 -762 +scratch1 10 +saved4 2; wait +saved1 235; saved2 -636 +scratch1 9 +saved4 2; wait +saved1 -54; saved2 -804 +scratch1 12 +saved4 2; wait +saved1 -209; saved2 -744 +scratch1 11; scratch2 13 +saved4 2; wait +saved1 -310; saved2 -799 +scratch1 14; scratch2 0 +saved4 2; wait +saved1 -414; saved2 -1036; saved3 -417 +scratch1 13; scratch2 15 +saved4 2; wait +saved1 -434; saved2 -1195 +scratch1 14; scratch2 16; scratch3 38; scratch4 39 +saved4 2; wait +saved1 -407; saved2 -1374 +scratch1 15; scratch2 17; scratch3 0; scratch4 0 +saved4 2; wait +saved1 -408; saved2 -1461; saved3 -407 +scratch1 18; scratch2 16 +saved4 2; wait +saved1 -430; saved2 -1589; saved3 -402 +scratch1 19; scratch2 0 +saved4 2; wait +saved1 -435; saved2 -1739; saved3 -417 +scratch1 18; scratch2 20 +saved4 2; wait +saved1 -396; saved2 -1920 +scratch1 19; scratch2 21 +saved4 2; wait +saved1 -283; saved2 -2039 +scratch1 20; scratch2 22 +saved4 2; wait +saved1 -154; saved2 -2145 +scratch1 21; scratch2 23 +saved4 2; wait +saved1 2; saved2 -2173; saved3 -301 +scratch1 22; scratch2 24 +saved4 2; wait +saved1 153; saved2 -2179; saved3 -194 +scratch1 23; scratch2 25 +saved4 2; wait +saved1 -106; saved2 -2266 +scratch1 24; scratch2 26 +saved4 2; wait +saved1 -285; saved2 -2234 +scratch1 25; scratch2 27 +saved4 2; wait +saved1 -456; saved2 -2228 +scratch1 26; scratch2 28 +saved4 2; wait +saved1 -622; saved2 -2241 +scratch1 27; scratch2 29 +saved4 2; wait +saved1 -777; saved2 -2179 +scratch1 28; scratch2 30 +saved4 2; wait +saved1 -920; saved2 -2071 +scratch1 29; scratch2 31 +saved4 2; wait +saved1 -1034; saved2 -1932 +scratch1 30; scratch2 32 +saved4 2; wait +saved1 -1087; saved2 -1770 +scratch1 31; scratch2 33 +saved4 2; wait +saved1 -1121; saved2 -1602 +scratch1 32; scratch2 34 +saved4 2; wait +saved1 -1130; saved2 -1548 +scratch1 35; scratch2 33; scratch3 45 +saved4 2; wait +saved1 -1098; saved2 -1471; saved3 -417 +scratch1 34; scratch2 36; scratch3 0 +saved4 2; wait +saved1 -957; saved2 -1569 +scratch1 35; scratch2 37 +saved4 2; wait +saved1 -794; saved2 -1516 +scratch1 36; scratch2 38 +saved4 2; wait +saved1 -749; saved2 -1343 +scratch1 37; scratch2 15 +saved4 2; wait +saved1 -271; saved2 -1263 +scratch1 15; scratch2 40 +saved4 2; wait +saved1 -103; saved2 -1347 +scratch1 39; scratch2 41 +saved4 2; wait +saved1 -97; saved2 -1537 +scratch1 40; scratch2 42 +saved4 2; wait +saved1 -163; saved2 -1702 +scratch1 41; scratch2 0 +saved4 2; wait +saved1 -584; saved2 -1794 +scratch1 44 +saved4 2; wait +saved1 -753; saved2 -1734 +scratch1 43 +saved4 2; wait +saved1 -1210; saved2 -1376; saved3 -194 +scratch1 34; scratch2 46 +saved4 2; wait +saved1 -1282; saved2 -1220 +scratch1 45; scratch2 47 +saved4 2; wait +saved1 -1288; saved2 -1031 +scratch1 46; scratch2 48 +saved4 2; wait +saved1 -1362; saved2 -867 +scratch1 47; scratch2 49; scratch3 50 +saved4 2; wait +saved1 -1500; saved2 -767 +scratch1 48; scratch2 0; scratch3 0 +saved4 2; wait +saved1 -1198; saved2 -893 +scratch2 51 +saved4 2; wait +saved1 -1071; saved2 -784 +scratch1 50; scratch2 52 +saved4 2; wait +saved1 -906; saved2 -700 +scratch1 51; scratch2 53 +saved4 2; wait +saved1 -823; saved2 -803 +scratch1 0; scratch2 0 +saved4 2; wait +saved1 -890; saved2 -967; saved3 -417 +scratch1 55 +saved4 2; wait +saved1 -711; saved2 -975 +scratch1 54; scratch2 15 +saved4 2; wait +saved4 3 +// end waypoint dump diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Lockout.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Lockout.bsp new file mode 100755 index 00000000..35e0ca50 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Lockout.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/RAT.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/RAT.BSP new file mode 100755 index 00000000..6ce85df6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/RAT.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/SkyRingbl1.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/SkyRingbl1.bsp new file mode 100755 index 00000000..01b0251c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/SkyRingbl1.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Spiders-web.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Spiders-web.bsp new file mode 100755 index 00000000..f3367bfb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Spiders-web.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Spiders_web.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Spiders_web.bsp new file mode 100755 index 00000000..f3367bfb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Spiders_web.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Trap-bridges.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Trap-bridges.bsp new file mode 100755 index 00000000..877b6ca2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Trap-bridges.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Wizard.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Wizard.bsp new file mode 100755 index 00000000..6eb0c38d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/Wizard.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/b_batt0.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/b_batt0.bsp new file mode 100755 index 00000000..2aa61d36 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/b_batt0.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/b_batt1.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/b_batt1.bsp new file mode 100755 index 00000000..317e7678 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/b_batt1.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/b_box.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/b_box.bsp new file mode 100755 index 00000000..8f26d6f1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/b_box.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/base.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/base.bsp new file mode 100755 index 00000000..23b2f7cf Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/base.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/bloody.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/bloody.bsp new file mode 100755 index 00000000..257d5318 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/bloody.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/buildings.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/buildings.bsp new file mode 100755 index 00000000..4a77351a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/buildings.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/chill.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/chill.bsp new file mode 100755 index 00000000..ed62f4de Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/chill.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/construction.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/construction.bsp new file mode 100755 index 00000000..afc23614 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/construction.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/ezerctrazo.BSP b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/ezerctrazo.BSP new file mode 100755 index 00000000..c0dca29e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/ezerctrazo.BSP differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/fire.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/fire.bsp new file mode 100755 index 00000000..d768355d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/fire.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/foundation.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/foundation.bsp new file mode 100755 index 00000000..d9d69ffe Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/foundation.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/halflife.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/halflife.bsp new file mode 100755 index 00000000..901170a5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/halflife.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/hang.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/hang.bsp new file mode 100755 index 00000000..394491b7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/hang.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l1.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l1.bsp new file mode 100755 index 00000000..eec316d5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l1.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l2.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l2.bsp new file mode 100755 index 00000000..9a70824b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l2.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l2MP.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l2MP.bsp new file mode 100755 index 00000000..3b7c242d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l2MP.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l3.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l3.bsp new file mode 100755 index 00000000..52ca39c8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l3.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l4.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l4.bsp new file mode 100755 index 00000000..5428ef52 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/l4.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/longest.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/longest.bsp new file mode 100755 index 00000000..08bd4d11 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/longest.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/longest.way b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/longest.way new file mode 100755 index 00000000..df2e83dc --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/longest.way @@ -0,0 +1,139 @@ +// Longest - maps/kdm4.way +// Ways by mrgreezy3 +saved1 1363; saved2 253; saved3 -322 +scratch1 2; scratch2 45; scratch3 0; scratch4 0 +saved4 1; wait +saved1 1118; saved2 267 +scratch1 1; scratch2 3 +saved4 2; wait +saved1 547; saved2 270; saved3 -482 +scratch1 2; scratch2 4 +saved4 2; wait +saved1 523; saved2 143 +scratch1 3; scratch2 5; scratch3 42 +saved4 2; wait +saved1 530; saved2 -70 +scratch1 4; scratch2 6; scratch3 43; scratch4 44 +saved4 2; wait +saved1 606; saved2 -275 +scratch1 5; scratch2 7; scratch3 0; scratch4 0 +saved4 2; wait +saved1 597; saved2 -616; saved3 -530 +scratch1 6; scratch2 8 +saved4 2; wait +saved1 912; saved2 -619 +scratch1 7; scratch2 9 +saved4 2; wait +saved1 910; saved2 -440 +scratch1 8; scratch2 10 +saved4 2; wait +saved1 877; saved2 -157; saved3 -482 +scratch1 9; scratch2 11; scratch3 44 +saved4 2; wait +saved1 1076; saved2 -132 +scratch1 10; scratch2 12; scratch3 0 +saved4 2; wait +saved1 1253; saved2 -95 +scratch1 11; scratch2 13; scratch3 39 +saved4 2; wait +saved1 1545; saved2 -142 +scratch1 12; scratch2 14; scratch3 0 +saved4 2; wait +saved1 2003; saved2 -140 +scratch1 13; scratch2 15; scratch3 16; scratch4 37 +saved4 2; wait +saved1 2226; saved2 -179 +scratch1 14; scratch2 26; scratch3 37; scratch4 0 +saved4 2; wait +saved1 2276; saved2 -60 +scratch2 17; scratch3 30 +saved4 2; wait +saved1 2636; saved2 -64 +scratch1 16; scratch2 18; scratch3 26; scratch4 27 +saved4 2; wait +saved1 2992; saved2 -67 +scratch1 17; scratch2 19; scratch3 28; scratch4 0 +saved4 2; wait +saved2 -189 +scratch1 18; scratch2 20; scratch3 27 +saved4 2; wait +saved1 2986; saved2 -317 +scratch1 19; scratch2 21; scratch3 0 +saved4 2; wait +saved1 2769; saved2 -326; saved3 -425 +scratch1 20; scratch2 22 +saved4 2; wait +saved1 2444; saved2 -325; saved3 -322 +scratch1 21; scratch2 23 +saved4 2; wait +saved1 2111; saved2 -317 +scratch1 22; scratch2 24 +saved4 2; wait +saved1 2124; saved2 -222 +scratch1 23; scratch2 25 +saved4 2; wait +saved1 2115; saved2 -147; saved3 -398 +scratch1 24; scratch2 0 +saved4 2; wait +saved1 2361; saved2 -179; saved3 -482 +scratch1 15; scratch2 17 +saved4 2; wait +saved1 2767; saved2 -169 +scratch1 17; scratch2 19 +saved4 2; wait +saved1 2883; saved2 80 +scratch1 18; scratch2 29; scratch3 31 +saved4 2; wait +saved1 2675; saved2 81 +scratch1 28; scratch2 30; scratch3 34 +saved4 2; wait +saved1 2288; saved2 33 +scratch1 29; scratch2 16; scratch3 35 +saved4 2; wait +saved1 2938; saved2 363; saved3 -530 +scratch1 28; scratch2 32; scratch3 34 +saved4 2; wait +saved1 2930; saved2 558 +scratch1 31; scratch2 33; scratch3 0 +saved4 2; wait +saved1 2620; saved2 574 +scratch1 32; scratch2 34 +saved4 2; wait +saved2 377 +scratch1 33; scratch2 29; scratch3 31 +saved4 2; wait +saved1 2022; saved2 66; saved3 -482 +scratch1 30; scratch2 36; scratch3 0 +saved4 2; wait +saved1 1788; saved2 88 +scratch1 35; scratch2 37 +saved4 2; wait +saved1 1428; saved2 61 +scratch1 36; scratch2 38; scratch3 15; scratch4 14 +saved4 2; wait +saved1 1282; saved2 122 +scratch1 37; scratch2 39; scratch3 41; scratch4 0 +saved4 2; wait +saved1 1262; saved2 3 +scratch1 38; scratch2 12; scratch3 40 +saved4 2; wait +saved1 899; saved2 13 +scratch1 39; scratch2 41; scratch3 42; scratch4 43 +saved4 2; wait +saved1 1165; saved2 104 +scratch1 38; scratch2 40; scratch3 0; scratch4 0 +saved4 2; wait +saved1 724 +scratch1 40; scratch2 4 +saved4 2; wait +saved1 671; saved2 7 +scratch2 5 +saved4 2; wait +saved1 527; saved2 -73 +scratch1 5; scratch2 10 +saved4 2; wait +saved1 1396; saved2 103; saved3 -324 +scratch1 1; scratch2 0 +saved4 2; wait +saved4 3 +// end waypoint dump diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/manic.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/manic.bsp new file mode 100755 index 00000000..9c2fa7b1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/manic.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/manic.way b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/manic.way new file mode 100755 index 00000000..95ca8e0e --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/manic.way @@ -0,0 +1,241 @@ +// Arch(unfinished) by mexicouger - maps/manic.way +// Ways by GreeZy +saved1 -1731; saved2 1577; saved3 434 +scratch1 2; scratch2 0; scratch3 0; scratch4 0 +saved4 1; wait +saved1 -1554 +scratch1 1; scratch2 3 +saved4 2; wait +saved1 -1471; saved2 1423 +scratch1 2; scratch2 4 +saved4 2; wait +saved1 -1456; saved2 1251 +scratch1 3; scratch2 5 +saved4 2; wait +saved1 -1448; saved2 1079 +scratch1 4; scratch2 6 +saved4 2; wait +saved1 -1440; saved2 905 +scratch1 5; scratch2 7; scratch3 51 +saved4 2; wait +saved1 -1432; saved2 735 +scratch1 6; scratch2 8; scratch3 52 +saved4 2; wait +saved1 -1373; saved2 576 +scratch1 7; scratch2 9; scratch3 0 +saved4 2; wait +saved1 -1208; saved2 528 +scratch1 8; scratch2 10 +saved4 2; wait +saved1 -1069; saved2 641; saved3 437 +scratch1 9; scratch2 11 +saved4 2; wait +saved1 -1034; saved2 804; saved3 499 +scratch1 10; scratch2 12 +saved4 2; wait +saved1 -1009; saved2 962; saved3 559 +scratch1 11; scratch2 13 +saved4 2; wait +saved1 -1000; saved2 1127; saved3 622 +scratch1 12; scratch2 14 +saved4 2; wait +saved1 -1004; saved2 1286; saved3 682 +scratch1 13; scratch2 15; scratch3 7 +saved4 2; wait +saved1 -881; saved2 1429; saved3 714 +scratch1 16; scratch2 0; scratch3 0 +saved4 2; wait +saved1 -773; saved2 1380; saved3 768 +scratch1 17 +saved4 2; wait +saved1 -628; saved2 1334; saved3 780 +scratch1 16; scratch2 18 +saved4 2; wait +saved1 -462; saved2 1302 +scratch1 17; scratch2 19 +saved4 2; wait +saved1 -291; saved2 1311 +scratch1 18; scratch2 20 +saved4 2; wait +saved1 -122; saved2 1323 +scratch1 19; scratch2 21 +saved4 2; wait +saved1 54; saved2 1308 +scratch1 20; scratch2 22 +saved4 2; wait +saved1 86; saved2 1143 +scratch1 21; scratch2 23 +saved4 2; wait +saved1 106; saved2 968 +scratch1 22; scratch2 24 +saved4 2; wait +saved1 125; saved2 790 +scratch1 23; scratch2 25 +saved4 2; wait +saved1 7; saved2 676 +scratch1 24; scratch2 26 +saved4 2; wait +saved1 -175; saved2 660 +scratch1 25; scratch2 27 +saved4 2; wait +saved1 -344; saved2 645 +scratch1 26; scratch2 28 +saved4 2; wait +saved1 -526; saved2 629 +scratch1 27; scratch2 29; scratch3 78 +saved4 2; wait +saved1 -693; saved2 569 +scratch1 28; scratch2 30; scratch3 0 +saved4 2; wait +saved1 -796; saved2 430 +scratch1 29; scratch2 31 +saved4 2; wait +saved1 -844; saved2 361 +scratch1 32; scratch2 0 +saved4 2; wait +saved1 -1006; saved2 123; saved3 434 +scratch1 31; scratch2 33 +saved4 2; wait +saved1 -832; saved2 196 +scratch1 32; scratch2 34 +saved4 2; wait +saved1 -660; saved2 182 +scratch1 33; scratch2 35 +saved4 2; wait +saved1 -486; saved2 168 +scratch1 34; scratch2 36 +saved4 2; wait +saved1 -383; saved2 305 +scratch1 35; scratch2 37 +saved4 2; wait +saved1 -280; saved2 444 +scratch1 36; scratch2 38 +saved4 2; wait +saved1 -265; saved2 529 +scratch1 39; scratch2 0 +saved4 2; wait +saved2 672; saved3 376 +scratch1 40 +saved4 2; wait +saved1 -317; saved2 818; saved3 321 +scratch1 0 +saved4 2; wait +saved1 -462; saved2 940 +scratch1 42 +saved4 2; wait +saved1 -437; saved2 1106 +scratch1 41; scratch2 43 +saved4 2; wait +saved1 -314; saved2 1226; saved3 327 +scratch1 44; scratch2 0 +saved4 2; wait +saved1 -318; saved2 1391; saved3 409 +scratch1 43; scratch2 45 +saved4 2; wait +saved2 1568; saved3 434 +scratch1 46; scratch2 0 +saved4 2; wait +saved1 -465; saved2 1636 +scratch1 45; scratch2 47 +saved4 2; wait +saved1 -641; saved2 1673 +scratch1 46; scratch2 48 +saved4 2; wait +saved1 -818; saved2 1690 +scratch1 47; scratch2 49 +saved4 2; wait +saved1 -988; saved2 1697 +scratch1 48; scratch2 50 +saved4 2; wait +saved1 -1155; saved2 1655 +scratch1 49; scratch2 51 +saved4 2; wait +saved1 -1253; saved2 1519 +scratch1 50; scratch2 6 +saved4 2; wait +saved1 -1481; saved2 461 +scratch1 7; scratch2 53 +saved4 2; wait +saved1 -1512; saved2 290; saved3 461 +scratch1 52; scratch2 54 +saved4 2; wait +saved1 -1556; saved2 133; saved3 564 +scratch1 53; scratch2 55 +saved4 2; wait +saved1 -1577; saved2 -27; saved3 670 +scratch1 54; scratch2 56 +saved4 2; wait +saved1 -1472; saved2 -182; saved3 691 +scratch1 55; scratch2 57 +saved4 2; wait +saved1 -1313; saved2 -154 +scratch1 56; scratch2 58 +saved4 2; wait +saved1 -1195; saved2 -165 +scratch1 59; scratch2 0 +saved4 2; wait +saved1 -947; saved2 -189; saved3 434 +scratch1 58; scratch2 60 +saved4 2; wait +saved1 -771; saved2 -204 +scratch1 59; scratch2 61 +saved4 2; wait +saved1 -596 +scratch1 60; scratch2 62 +saved4 2; wait +saved1 -422; saved2 -172 +scratch1 61; scratch2 63 +saved4 2; wait +saved1 -253; saved2 -143 +scratch1 62; scratch2 64 +saved4 2; wait +saved1 -108; saved2 -31 +scratch1 63; scratch2 65 +saved4 2; wait +saved1 56; saved2 -68 +scratch1 64; scratch2 66 +saved4 2; wait +saved1 200; saved2 -154 +scratch1 65; scratch2 67 +saved4 2; wait +saved1 339; saved2 -78 +scratch1 66; scratch2 68 +saved4 2; wait +saved1 465; saved2 39 +scratch1 67; scratch2 69 +saved4 2; wait +saved1 586; saved2 166 +scratch1 68; scratch2 70 +saved4 2; wait +saved1 647; saved2 329 +scratch1 69; scratch2 71 +saved4 2; wait +saved1 614; saved2 471 +scratch1 70; scratch2 72 +saved4 2; wait +saved1 508; saved2 626 +scratch1 71; scratch2 73 +saved4 2; wait +saved1 456; saved2 780; saved3 490 +scratch1 72; scratch2 74 +saved4 2; wait +saved2 943; saved3 552 +scratch1 73; scratch2 75 +saved4 2; wait +saved1 454; saved2 1107; saved3 614 +scratch1 74; scratch2 76 +saved4 2; wait +saved1 452; saved2 1267; saved3 674 +scratch1 75; scratch2 77 +saved4 2; wait +saved1 350; saved2 1399; saved3 700 +scratch1 21; scratch2 0 +saved4 2; wait +saved1 -789; saved2 700; saved3 780 +scratch1 28; scratch2 79 +saved4 2; wait +saved1 -849; saved2 872 +scratch1 78; scratch2 0 +saved4 2; wait +saved4 3 +// end waypoint dump diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/maze.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/maze.bsp new file mode 100755 index 00000000..9bb5db7a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/maze.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/narrowed.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/narrowed.bsp new file mode 100755 index 00000000..e37a0c00 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/narrowed.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/narrowed.way b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/narrowed.way new file mode 100755 index 00000000..ad8deabe --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/narrowed.way @@ -0,0 +1,67 @@ +// Narrowed - maps/e1m2.way +// Ways by mrgreezy3 +saved1 1280; saved2 -2416; saved3 -1906 +scratch1 2; scratch2 0; scratch3 0; scratch4 0 +saved4 1; wait +saved1 1281; saved2 -2075; saved3 -1938 +scratch1 3; scratch2 16; scratch3 17; scratch4 15 +saved4 2; wait +saved1 1747; saved2 -2019 +scratch1 2; scratch2 4; scratch3 0; scratch4 0 +saved4 2; wait +saved1 1901; saved2 -1620; saved3 -1961 +scratch1 3; scratch2 5 +saved4 2; wait +saved1 1799; saved2 -1479; saved3 -1970 +scratch1 4; scratch2 6 +saved4 2; wait +saved1 1306; saved2 -1495; saved3 -2034 +scratch1 5; scratch2 7; scratch3 13 +saved4 2; wait +saved1 1274; saved2 -1114 +scratch1 6; scratch2 8; scratch3 12 +saved4 2; wait +saved1 700; saved2 -1076; saved3 -1970 +scratch1 7; scratch2 9; scratch3 0 +saved4 2; wait +saved1 699; saved2 -668; saved3 -1938 +scratch1 8; scratch2 10; scratch3 21 +saved4 2; wait +saved1 1284; saved2 -492 +scratch1 9; scratch2 11; scratch4 20 +saved4 2; wait +saved1 1845; saved2 -679 +scratch1 10; scratch2 12; scratch3 20; scratch4 0 +saved4 2; wait +saved1 1875; saved2 -1090; saved3 -1970 +scratch1 11; scratch2 7; scratch3 0 +saved4 2; wait +saved1 682; saved2 -1508 +scratch1 6; scratch2 14 +saved4 2; wait +saved1 703; saved2 -1804; saved3 -1938 +scratch1 13; scratch2 15; scratch3 16 +saved4 2; wait +saved1 1152; saved2 -1814 +scratch1 14; scratch2 2; scratch3 18 +saved4 2; wait +saved1 756; saved2 -2012 +scratch3 0 +saved4 2; wait +saved1 1380; saved2 -1816 +scratch1 2; scratch2 19 +saved4 2; wait +saved1 1163; saved2 -1308; saved3 -1824 +scratch1 15; scratch3 21 +saved4 2; wait +saved1 1407; saved2 -1286 +scratch1 17; scratch2 18; scratch3 20 +saved4 2; wait +saved1 1393; saved2 -773; saved3 -1933 +scratch1 19; scratch2 10; scratch3 11; scratch4 21 +saved4 2; wait +saved1 1172; saved2 -811; saved3 -1923 +scratch1 18; scratch3 9; scratch4 20 +saved4 2; wait +saved4 3 +// end waypoint dump diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/needle.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/needle.bsp new file mode 100755 index 00000000..07ca0e43 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/needle.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/pit.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/pit.bsp new file mode 100755 index 00000000..44754840 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/pit.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/plaza.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/plaza.bsp new file mode 100755 index 00000000..d7fd2bfd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/plaza.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/prisioner.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/prisioner.bsp new file mode 100755 index 00000000..98d92e36 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/prisioner.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/prisoner.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/prisoner.bsp new file mode 100755 index 00000000..2e518938 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/prisoner.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/prisoner.way b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/prisoner.way new file mode 100755 index 00000000..28e1d05c --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/prisoner.way @@ -0,0 +1,201 @@ +// - maps/Prisoner +saved1 213; saved2 -769; saved3 318 +scratch1 2; scratch2 29; scratch3 0; scratch4 0 +saved4 1; wait +saved1 516; saved2 -805 +scratch1 1; scratch2 3 +saved4 2; wait +saved1 849; saved2 -813 +scratch1 2; scratch2 4 +saved4 2; wait +saved1 895; saved2 -432 +scratch1 3; scratch2 5 +saved4 2; wait +saved1 707; saved2 -382 +scratch1 4; scratch2 6 +saved4 2; wait +saved1 709; saved2 -45 +scratch1 5; scratch2 7 +saved4 2; wait +saved1 499; saved2 -18; saved3 213 +scratch1 6; scratch2 8 +saved4 2; wait +saved1 317; saved2 4; saved3 126 +scratch1 7; scratch2 9 +saved4 2; wait +saved1 666; saved2 26 +scratch1 8; scratch2 10 +saved4 2; wait +saved1 721; saved2 -317 +scratch1 9; scratch2 11 +saved4 2; wait +saved1 707; saved2 -597 +scratch1 10; scratch2 12 +saved4 2; wait +saved1 329; saved2 -611 +scratch1 11; scratch2 13 +saved4 2; wait +saved1 324; saved2 -790 +scratch1 12; scratch2 14 +saved4 2; wait +saved1 62; saved2 -798 +scratch1 13; scratch2 15; scratch3 66 +saved4 2; wait +saved1 -262; saved2 -795 +scratch1 14; scratch2 16; scratch3 33; scratch4 66 +saved4 2; wait +saved1 -434; saved2 -882 +scratch1 15; scratch2 17; scratch3 0; scratch4 0 +saved4 2; wait +saved1 -496; saved2 -911 +scratch1 16; scratch2 18 +saved4 2; wait +saved1 -499; saved2 -996 +scratch1 17; scratch2 19 +saved4 2; wait +saved1 -1115; saved2 -932 +scratch1 18; scratch2 20 +saved4 2; wait +saved1 -1106; saved2 -607; saved3 242 +scratch1 19; scratch2 21 +saved4 2; wait +saved1 -1109; saved2 -128; saved3 318 +scratch1 20; scratch2 22 +saved4 2; wait +saved1 -907; saved2 -87 +scratch1 21; scratch2 23; scratch3 32 +saved4 2; wait +saved1 -768; saved2 -378 +scratch1 22; scratch2 24 +saved4 2; wait +saved1 -729; saved2 -574 +scratch1 23; scratch2 25; scratch3 0 +saved4 2; wait +saved1 -509; saved2 -745 +scratch1 24; scratch2 26 +saved4 2; wait +saved1 -505; saved2 -877 +scratch1 25; scratch2 27 +saved4 2; wait +saved1 -301; saved2 -898 +scratch1 26; scratch2 28 +saved4 2; wait +saved1 -227; saved2 -615 +scratch1 27; scratch2 29 +saved4 2; wait +saved1 169; saved2 -588 +scratch1 28; scratch2 1; scratch3 30 +saved4 2; wait +saved1 -114; saved2 -203 +scratch1 29; scratch2 31; scratch3 0 +saved4 2; wait +saved1 -458; saved2 -165 +scratch1 30; scratch2 32 +saved4 2; wait +saved1 -780; saved2 -147 +scratch1 31; scratch2 22; scratch3 23 +saved4 2; wait +saved1 -220; saved2 -227; saved3 126 +scratch1 15; scratch2 34; scratch3 0 +saved4 2; wait +saved1 -735; saved2 -185 +scratch1 33; scratch2 35 +saved4 2; wait +saved1 -753; saved2 83 +scratch1 34; scratch2 36; scratch3 54 +saved4 2; wait +saved1 -1130; saved2 75 +scratch1 35; scratch2 37; scratch3 0 +saved4 2; wait +saved1 -1236; saved2 -146 +scratch1 36; scratch2 38 +saved4 2; wait +saved1 -1038; saved2 -426 +scratch1 37; scratch2 39 +saved4 2; wait +saved1 -912; saved2 -431 +scratch1 38; scratch2 40 +saved4 2; wait +saved1 -893; saved2 -705 +scratch1 39; scratch2 41 +saved4 2; wait +saved1 -636; saved2 -756; saved3 -7 +scratch1 40; scratch2 0 +saved4 2; wait +saved1 -660; saved2 -763; saved3 -82 +scratch1 43; scratch2 62; scratch3 63 +saved4 2; wait +saved1 -656; saved2 -372 +scratch1 42; scratch2 44; scratch3 46; scratch4 48 +saved4 2; wait +saved1 -1088; saved2 -230; saved3 -66 +scratch1 43; scratch2 45; scratch3 0; scratch4 0 +saved4 2; wait +saved1 -1108; saved2 75 +scratch1 44; scratch2 46 +saved4 2; wait +saved1 -759; saved2 119 +scratch1 45; scratch2 47; scratch3 43 +saved4 2; wait +saved1 -463; saved2 116 +scratch1 46; scratch2 48; scratch3 0 +saved4 2; wait +saved1 -417; saved2 -244 +scratch1 47; scratch2 49; scratch3 60; scratch4 43 +saved4 2; wait +saved1 -13; saved2 -242 +scratch1 48; scratch2 50; scratch3 0; scratch4 0 +saved4 2; wait +saved1 368; saved2 -227 +scratch1 49; scratch2 51; scratch3 58 +saved4 2; wait +saved1 405; saved2 65; saved3 -73 +scratch1 50; scratch2 52; scratch3 55 +saved4 2; wait +saved1 65; saved2 116; saved3 -13 +scratch1 51; scratch2 53; scratch3 0 +saved4 2; wait +saved1 -281; saved2 110; saved3 110 +scratch1 52; scratch2 54 +saved4 2; wait +saved1 -572; saved2 94; saved3 124 +scratch1 53; scratch2 35 +saved4 2; wait +saved1 677; saved2 170; saved3 -66 +scratch1 51; scratch2 56 +saved4 2; wait +saved1 956; saved2 154 +scratch1 55; scratch2 57 +saved4 2; wait +saved1 967; saved2 -250 +scratch1 56; scratch2 58 +saved4 2; wait +saved1 600; saved2 -291 +scratch1 57; scratch2 50; scratch3 59 +saved4 2; wait +saved1 292; saved2 -576 +scratch1 58; scratch2 60; scratch3 0 +saved4 2; wait +saved1 -168; saved2 -526 +scratch1 59; scratch2 61; scratch3 48; scratch4 63 +saved4 2; wait +saved1 -194; saved2 -803 +scratch1 60; scratch2 62; scratch3 64; scratch4 0 +saved4 2; wait +saved1 -539; saved2 -889 +scratch1 61; scratch2 42; scratch3 0 +saved4 2; wait +saved2 -572 +scratch1 60 +saved4 2; wait +saved1 -164; saved2 -946; saved3 -38 +scratch1 65; scratch2 0 +saved4 2; wait +saved1 -153; saved2 -960; saved3 136 +scratch1 0 +saved4 2; wait +saved1 -242; saved2 -804; saved3 126 +scratch1 15; scratch2 14 +saved4 2; wait +saved4 3 +// end waypoint dump diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/skyRingbl2.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/skyRingbl2.bsp new file mode 100755 index 00000000..925327c1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/skyRingbl2.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/spawn.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/spawn.bsp new file mode 100755 index 00000000..8c6036f4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/spawn.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/spiders-web.way b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/spiders-web.way new file mode 100755 index 00000000..af85f7c8 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/spiders-web.way @@ -0,0 +1,148 @@ +// - maps/e1m5.way +// Ways by Player +saved1 1851; saved2 -703; saved3 430 +scratch1 2; scratch2 18; scratch3 0; scratch4 0 +saved4 1; wait +saved1 1891; saved2 -402 +scratch1 1; scratch2 3 +saved4 2; wait +saved1 1837; saved2 167 +scratch1 2; scratch2 4 +saved4 2; wait +saved1 1420; saved2 375 +scratch1 3; scratch2 5; scratch3 46 +saved4 2; wait +saved1 1090; saved2 361 +scratch1 4; scratch2 6 +saved4 2; wait +saved1 1017; saved2 38 +scratch1 5; scratch2 7; scratch3 0 +saved4 2; wait +saved1 1025; saved2 -339 +scratch1 6; scratch2 8; scratch3 12; scratch4 13 +saved4 2; wait +saved1 796; saved2 -333 +scratch1 7; scratch2 9; scratch3 0; scratch4 0 +saved4 2; wait +saved1 746; saved2 -643 +scratch1 8; scratch2 10 +saved4 2; wait +saved1 990; saved2 -700 +scratch1 9; scratch2 11; scratch3 13; scratch4 14 +saved4 2; wait +saved1 1254; saved2 -681 +scratch1 10; scratch2 12; scratch3 0; scratch4 0 +saved4 2; wait +saved1 1291; saved2 -373 +scratch1 11; scratch2 7 +saved4 2; wait +saved1 1158; saved2 -488 +scratch1 7; scratch2 10 +saved4 2; wait +saved1 1030; saved2 -830 +scratch1 10; scratch2 15 +saved4 2; wait +saved1 1020; saved2 -1302 +scratch1 14; scratch2 16 +saved4 2; wait +saved1 1321; saved2 -1370 +scratch1 15; scratch2 17 +saved4 2; wait +saved1 1689; saved2 -1319 +scratch1 16; scratch2 18 +saved4 2; wait +saved1 1892; saved2 -898 +scratch1 17; scratch2 1 +saved4 2; wait +saved1 1027; saved2 -1148; saved3 -210 +scratch1 20; scratch2 39; scratch3 40 +saved4 2; wait +saved1 1020; saved2 -634; saved3 46 +scratch1 19; scratch2 21; scratch3 33 +saved4 2; wait +saved1 1207; saved2 -629 +scratch1 20; scratch2 22; scratch3 0 +saved4 2; wait +saved1 1319; saved2 -534 +scratch1 21; scratch2 23; scratch3 32; scratch4 33 +saved4 2; wait +saved1 1817; saved2 -504; saved3 110 +scratch1 22; scratch2 24; scratch3 0; scratch4 0 +saved4 2; wait +saved1 1874; saved2 -142 +scratch1 23; scratch2 25 +saved4 2; wait +saved1 1802; saved2 200 +scratch1 24; scratch2 26 +saved4 2; wait +saved1 1374; saved2 336 +scratch1 25; scratch2 27 +saved4 2; wait +saved1 868; saved2 353 +scratch1 26; scratch2 28 +saved4 2; wait +saved1 363; saved2 296 +scratch1 27; scratch2 29 +saved4 2; wait +saved1 146; saved2 -10 +scratch1 28; scratch2 30 +saved4 2; wait +saved1 167; saved2 -415 +scratch1 29; scratch2 31 +saved4 2; wait +saved1 416; saved2 -516 +scratch1 30; scratch2 32 +saved4 2; wait +saved1 840; saved2 -511; saved3 46 +scratch1 31; scratch2 22 +saved4 2; wait +saved1 1050; saved2 -336 +scratch1 22; scratch2 34; scratch3 20 +saved4 2; wait +saved1 1006; saved2 157; saved3 -210 +scratch1 33; scratch2 35; scratch3 44 +saved4 2; wait +saved1 730; saved2 167 +scratch1 34; scratch2 36; scratch3 0 +saved4 2; wait +saved1 447; saved2 -48 +scratch1 35; scratch2 37 +saved4 2; wait +saved1 316; saved2 -462 +scratch1 36; scratch2 38 +saved4 2; wait +saved1 470; saved2 -1007 +scratch1 37; scratch2 39 +saved4 2; wait +saved1 808; saved2 -1181 +scratch1 38; scratch2 19 +saved4 2; wait +saved1 1417; saved2 -1081 +scratch1 19; scratch2 41 +saved4 2; wait +saved1 1702; saved2 -796 +scratch1 40; scratch2 42 +saved4 2; wait +saved1 1707; saved2 -340 +scratch1 41; scratch2 43 +saved4 2; wait +saved1 1462; saved2 64 +scratch1 42; scratch2 44 +saved4 2; wait +saved1 1222; saved2 192 +scratch1 43; scratch2 34 +saved4 2; wait +saved1 887; saved2 -492; saved3 430 +scratch1 7; scratch2 10 +saved4 2; wait +saved1 1332; saved2 270 +scratch1 5; scratch2 4; scratch3 47 +saved4 2; wait +saved1 1366; saved2 74; saved3 366 +scratch1 48; scratch2 0; scratch3 0 +saved4 2; wait +saved1 1168; saved2 3; saved3 271 +scratch1 0 +saved4 2; wait +saved4 3 +// end waypoint dump diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/spiders.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/spiders.bsp new file mode 100755 index 00000000..f0b0a44e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/spiders.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/start.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/start.bsp new file mode 100755 index 00000000..afc7b941 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/start.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/station-118.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/station-118.bsp new file mode 100755 index 00000000..931ce376 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/station-118.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/washedup.bsp b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/washedup.bsp new file mode 100755 index 00000000..2b96b1a6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/washedup.bsp differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/maps/washedup.lit b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/washedup.lit new file mode 100755 index 00000000..8d71b1c8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/maps/washedup.lit differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/BigNeedProy.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/BigNeedProy.mdl new file mode 100755 index 00000000..9f8bede6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/BigNeedProy.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/PL_BULL.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/PL_BULL.spr new file mode 100755 index 00000000..ac2136d4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/PL_BULL.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/armor.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/armor.mdl new file mode 100755 index 00000000..43b6b5c1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/armor.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/backpack.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/backpack.mdl new file mode 100755 index 00000000..a0b049f9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/backpack.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/bolt.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/bolt.mdl new file mode 100755 index 00000000..3b9912d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/bolt.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/bolt2.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/bolt2.mdl new file mode 100755 index 00000000..4b5a83ab Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/bolt2.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/bolt3.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/bolt3.mdl new file mode 100755 index 00000000..3700c9a7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/bolt3.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/boss.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/boss.mdl new file mode 100755 index 00000000..a33893d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/boss.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/bullet.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/bullet.mdl new file mode 100755 index 00000000..43a98ef2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/bullet.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/demon.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/demon.mdl new file mode 100755 index 00000000..b828b655 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/demon.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/dog.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/dog.mdl new file mode 100755 index 00000000..7bf0e6a3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/dog.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/elite.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/elite.mdl new file mode 100755 index 00000000..61a31fa3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/elite.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/enforcer.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/enforcer.mdl new file mode 100755 index 00000000..e687f010 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/enforcer.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/eyes.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/eyes.mdl new file mode 100755 index 00000000..40e8cc34 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/eyes.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/fish.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/fish.mdl new file mode 100755 index 00000000..1fef2deb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/fish.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/flame.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/flame.mdl new file mode 100755 index 00000000..48148e0c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/flame.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/flame2.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/flame2.mdl new file mode 100755 index 00000000..b88c4a0a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/flame2.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/fraggren.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/fraggren.mdl new file mode 100755 index 00000000..90b0c6b5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/fraggren.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_ar.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_ar.mdl new file mode 100755 index 00000000..f2b954b0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_ar.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_axe.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_axe.mdl new file mode 100755 index 00000000..c2c04acd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_axe.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_nail.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_nail.mdl new file mode 100755 index 00000000..f2b954b0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_nail.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_needler.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_needler.mdl new file mode 100755 index 00000000..b3747fa7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_needler.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_pistol.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_pistol.mdl new file mode 100755 index 00000000..587c108b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_pistol.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_plpist.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_plpist.mdl new file mode 100755 index 00000000..a9daae3b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_plpist.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_plrifl.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_plrifl.mdl new file mode 100755 index 00000000..4b806203 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_plrifl.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_ppist.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_ppist.mdl new file mode 100755 index 00000000..a9daae3b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_ppist.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_rock.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_rock.mdl new file mode 100755 index 00000000..669c7d94 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_rock.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_rocket.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_rocket.mdl new file mode 100755 index 00000000..ff4637d0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_rocket.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_shot.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_shot.mdl new file mode 100755 index 00000000..d144fd06 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_shot.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_skull.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_skull.mdl new file mode 100755 index 00000000..d1dcc4a3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_skull.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_sniper.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_sniper.mdl new file mode 100755 index 00000000..77f50bd8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_sniper.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_uzi.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_uzi.mdl new file mode 100755 index 00000000..557d8a2c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/g_uzi.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/grenade.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/grenade.mdl new file mode 100755 index 00000000..ac24b34e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/grenade.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/grunt.MDL b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/grunt.MDL new file mode 100755 index 00000000..16881130 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/grunt.MDL differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_demon.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_demon.mdl new file mode 100755 index 00000000..fb3c772e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_demon.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_dog.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_dog.mdl new file mode 100755 index 00000000..eb3556a7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_dog.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_elite.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_elite.mdl new file mode 100755 index 00000000..73b398bc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_elite.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_guard.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_guard.mdl new file mode 100755 index 00000000..a010dff2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_guard.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_hellkn.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_hellkn.mdl new file mode 100755 index 00000000..9fd44aa0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_hellkn.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_infected.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_infected.mdl new file mode 100755 index 00000000..da5fbf85 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_infected.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_knight.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_knight.mdl new file mode 100755 index 00000000..817d770a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_knight.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_mega.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_mega.mdl new file mode 100755 index 00000000..33d89f27 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_mega.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_player.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_player.mdl new file mode 100755 index 00000000..77866f11 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_player.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_pod.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_pod.mdl new file mode 100755 index 00000000..eb3556a7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_pod.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_shal.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_shal.mdl new file mode 100755 index 00000000..a8bfba09 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_shal.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_shams.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_shams.mdl new file mode 100755 index 00000000..66a5e89c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_shams.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_spike.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_spike.mdl new file mode 100755 index 00000000..2358deb7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_spike.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_wizard.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_wizard.mdl new file mode 100755 index 00000000..01015c5d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_wizard.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_zombie.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_zombie.mdl new file mode 100755 index 00000000..f279af73 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/h_zombie.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/hknight.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/hknight.mdl new file mode 100755 index 00000000..ac5feffc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/hknight.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/infectedflood.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/infectedflood.mdl new file mode 100755 index 00000000..ddbd8d07 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/infectedflood.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/invisibl.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/invisibl.mdl new file mode 100755 index 00000000..dd66542b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/invisibl.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/invulner.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/invulner.mdl new file mode 100755 index 00000000..2cd4f26f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/invulner.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/knight.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/knight.mdl new file mode 100755 index 00000000..28007625 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/knight.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/lavaball.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/lavaball.mdl new file mode 100755 index 00000000..95e610a6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/lavaball.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/m_g_key.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/m_g_key.mdl new file mode 100755 index 00000000..988095be Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/m_g_key.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/m_s_key.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/m_s_key.mdl new file mode 100755 index 00000000..e7888e29 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/m_s_key.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/minirocket.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/minirocket.mdl new file mode 100755 index 00000000..a02c6b6e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/minirocket.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/missile.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/missile.mdl new file mode 100755 index 00000000..e2fecb7d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/missile.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/needler_dust.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/needler_dust.spr new file mode 100755 index 00000000..8454414b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/needler_dust.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/needpro2.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/needpro2.mdl new file mode 100755 index 00000000..9c6485b3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/needpro2.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/needproy.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/needproy.mdl new file mode 100755 index 00000000..391a681e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/needproy.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/null.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/null.spr new file mode 100755 index 00000000..da32681e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/null.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/oldone.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/oldone.mdl new file mode 100755 index 00000000..88477521 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/oldone.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plasgren.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plasgren.mdl new file mode 100755 index 00000000..6c35f1e0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plasgren.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plasma.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plasma.mdl new file mode 100755 index 00000000..ef8ab1cb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plasma.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plasma.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plasma.spr new file mode 100755 index 00000000..662d6633 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plasma.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plasma_glow.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plasma_glow.spr new file mode 100755 index 00000000..e3c0ebf8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plasma_glow.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player.mdl new file mode 100755 index 00000000..481ffa8c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_nail.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_nail.mdl new file mode 100755 index 00000000..481ffa8c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_nail.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_needler.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_needler.mdl new file mode 100755 index 00000000..2a7cdbda Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_needler.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_plasma.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_plasma.mdl new file mode 100755 index 00000000..11a06918 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_plasma.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_rocket.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_rocket.mdl new file mode 100755 index 00000000..fb54bec7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_rocket.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_shot.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_shot.mdl new file mode 100755 index 00000000..a089d874 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_shot.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_snail.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_snail.mdl new file mode 100755 index 00000000..4da28e55 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_snail.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_sngun.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_sngun.mdl new file mode 100755 index 00000000..4da28e55 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_sngun.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_sniper.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_sniper.mdl new file mode 100755 index 00000000..a34da94a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_sniper.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_sshot.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_sshot.mdl new file mode 100755 index 00000000..2973bfd5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/player_sshot.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plyr.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plyr.mdl new file mode 100755 index 00000000..5d67a41f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/plyr.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/pod.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/pod.mdl new file mode 100755 index 00000000..7e468406 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/pod.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/quaddama.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/quaddama.mdl new file mode 100755 index 00000000..01e5a2f5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/quaddama.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_bubble.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_bubble.spr new file mode 100755 index 00000000..8fffbf3e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_bubble.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_explod.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_explod.spr new file mode 100755 index 00000000..5e352f4c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_explod.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_fblood.SPR b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_fblood.SPR new file mode 100755 index 00000000..f24840ec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_fblood.SPR differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_light.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_light.spr new file mode 100755 index 00000000..30e78569 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_light.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_mario.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_mario.spr new file mode 100755 index 00000000..9ee46c99 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_mario.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_null.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_null.spr new file mode 100755 index 00000000..da32681e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_null.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_smoke.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_smoke.spr new file mode 100755 index 00000000..002a543c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_smoke.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_smoke1.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_smoke1.spr new file mode 100755 index 00000000..10914a50 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_smoke1.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_spike.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_spike.mdl new file mode 100755 index 00000000..1d931136 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/s_spike.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/shalrath.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/shalrath.mdl new file mode 100755 index 00000000..dc02dfaa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/shalrath.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/shambler.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/shambler.mdl new file mode 100755 index 00000000..e053ea2c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/shambler.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/shell.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/shell.mdl new file mode 100755 index 00000000..b248b70e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/shell.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/shellshot.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/shellshot.mdl new file mode 100755 index 00000000..e61ecceb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/shellshot.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/sniperbullet.MDL b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/sniperbullet.MDL new file mode 100755 index 00000000..86aa52e3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/sniperbullet.MDL differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/soldier.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/soldier.mdl new file mode 100755 index 00000000..daf3f21d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/soldier.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/spike.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/spike.mdl new file mode 100755 index 00000000..89d81cec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/spike.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/suit.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/suit.mdl new file mode 100755 index 00000000..c8a94e56 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/suit.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/tarbaby.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/tarbaby.mdl new file mode 100755 index 00000000..219f4fcf Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/tarbaby.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/teleport.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/teleport.mdl new file mode 100755 index 00000000..04f5d0e6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/teleport.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_ar2.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_ar2.mdl new file mode 100755 index 00000000..6376443b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_ar2.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_axe.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_axe.mdl new file mode 100755 index 00000000..00216de2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_axe.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_br.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_br.mdl new file mode 100755 index 00000000..31463a7b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_br.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_light.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_light.mdl new file mode 100755 index 00000000..3081bc8f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_light.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_nail.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_nail.mdl new file mode 100755 index 00000000..99a70389 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_nail.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_nail2.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_nail2.mdl new file mode 100755 index 00000000..11def7e0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_nail2.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_nailgun.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_nailgun.mdl new file mode 100755 index 00000000..6896ac7c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_nailgun.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_needle.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_needle.mdl new file mode 100755 index 00000000..f9a51237 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_needle.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_plpist.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_plpist.mdl new file mode 100755 index 00000000..b97a4124 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_plpist.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_plrifle.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_plrifle.mdl new file mode 100755 index 00000000..448800e0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_plrifle.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_rock.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_rock.mdl new file mode 100755 index 00000000..2d05b663 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_rock.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_rock2.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_rock2.mdl new file mode 100755 index 00000000..a347bcd0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_rock2.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_rocket.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_rocket.mdl new file mode 100755 index 00000000..f8131098 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_rocket.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_shot.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_shot.mdl new file mode 100755 index 00000000..83fe2504 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_shot.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_shot2.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_shot2.mdl new file mode 100755 index 00000000..f076fb71 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_shot2.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_shotgun.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_shotgun.mdl new file mode 100755 index 00000000..5f484a67 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_shotgun.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_skull.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_skull.mdl new file mode 100755 index 00000000..da5fbf85 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_skull.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_sniper.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_sniper.mdl new file mode 100755 index 00000000..42f47f56 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_sniper.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_uzi.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_uzi.mdl new file mode 100755 index 00000000..e9d021b2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/v_uzi.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/w_g_key.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/w_g_key.mdl new file mode 100755 index 00000000..a538fb48 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/w_g_key.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/w_s_key.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/w_s_key.mdl new file mode 100755 index 00000000..a1a1e9ed Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/w_s_key.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/w_spike.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/w_spike.mdl new file mode 100755 index 00000000..4f7f9fdf Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/w_spike.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/wizard.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/wizard.mdl new file mode 100755 index 00000000..811af9aa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/wizard.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/zom_gib.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/zom_gib.mdl new file mode 100755 index 00000000..07970862 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/zom_gib.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/progs/zombie.mdl b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/zombie.mdl new file mode 100755 index 00000000..1052436c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/progs/zombie.mdl differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/quake.rc b/r17/Revamped src/revamped_src/psp/normal/kurok/quake.rc new file mode 100755 index 00000000..81efaa11 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/kurok/quake.rc @@ -0,0 +1,19 @@ +// load the base configuration +exec default.cfg + +// load the last saved configuration +exec config.cfg + +// run a user script file if present +exec autoexec.cfg + +// stuff command line statements +stuffcmds +// Kurok stuff + +sv_maxspeed 175 +sv_maxvelocity 5000 + +cl_forwardspeed 175 +cl_backspeed 175 +cl_sidespeed 175 \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/buzz1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/buzz1.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/buzz1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/comp1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/comp1.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/comp1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/drip1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/drip1.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/drip1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/drip2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/drip2.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/drip2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/drone6.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/drone6.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/drone6.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/fire1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/fire1.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/fire1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/fl_hum1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/fl_hum1.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/fl_hum1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/hum1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/hum1.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/hum1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/suck1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/suck1.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/suck1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/swamp1.pk b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/swamp1.pk new file mode 100755 index 00000000..d2e63c9c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/swamp1.pk differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/swamp1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/swamp1.wav new file mode 100755 index 00000000..ca8d80bc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/swamp1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/swamp2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/swamp2.wav new file mode 100755 index 00000000..a2d6830a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/swamp2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/thunder1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/thunder1.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/thunder1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/water1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/water1.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/water1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/wind2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/wind2.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/wind2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/windfly.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/windfly.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/ambience/windfly.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/blob/death1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/blob/death1.wav new file mode 100755 index 00000000..c3d7507e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/blob/death1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/blob/hit1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/blob/hit1.wav new file mode 100755 index 00000000..ca235ef2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/blob/hit1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/blob/land1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/blob/land1.wav new file mode 100755 index 00000000..64543e88 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/blob/land1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/blob/sight1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/blob/sight1.wav new file mode 100755 index 00000000..3ee82698 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/blob/sight1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/death.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/death.wav new file mode 100755 index 00000000..aa0c0ee2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/death.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/out1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/out1.wav new file mode 100755 index 00000000..d6fed027 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/out1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/pain.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/pain.wav new file mode 100755 index 00000000..727966fc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/pain.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/sight1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/sight1.wav new file mode 100755 index 00000000..2680a776 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/sight1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/throw.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/throw.wav new file mode 100755 index 00000000..17a570ec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss1/throw.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss2/death.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss2/death.wav new file mode 100755 index 00000000..e752a335 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss2/death.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss2/idle.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss2/idle.wav new file mode 100755 index 00000000..28277033 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss2/idle.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss2/pop2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss2/pop2.wav new file mode 100755 index 00000000..140f5f10 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss2/pop2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss2/sight.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss2/sight.wav new file mode 100755 index 00000000..f222fb5a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/boss2/sight.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/buttons/airbut1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/buttons/airbut1.wav new file mode 100755 index 00000000..f38fd868 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/buttons/airbut1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/buttons/switch02.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/buttons/switch02.wav new file mode 100755 index 00000000..d408993b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/buttons/switch02.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/buttons/switch04.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/buttons/switch04.wav new file mode 100755 index 00000000..206f0596 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/buttons/switch04.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/buttons/switch21.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/buttons/switch21.wav new file mode 100755 index 00000000..9774dc9a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/buttons/switch21.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/ddeath.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/ddeath.wav new file mode 100755 index 00000000..16d15822 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/ddeath.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/dhit2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/dhit2.wav new file mode 100755 index 00000000..a5a21b29 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/dhit2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/djump.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/djump.wav new file mode 100755 index 00000000..c7153e60 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/djump.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/dland2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/dland2.wav new file mode 100755 index 00000000..36bfe878 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/dland2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/dpain1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/dpain1.wav new file mode 100755 index 00000000..9fd21c1a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/dpain1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/idle1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/idle1.wav new file mode 100755 index 00000000..c8fd975c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/idle1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/sight2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/sight2.wav new file mode 100755 index 00000000..dfe17bd4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/demon/sight2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/dattack1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/dattack1.wav new file mode 100755 index 00000000..447cb7b5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/dattack1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/ddeath.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/ddeath.wav new file mode 100755 index 00000000..498dbbec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/ddeath.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/dpain1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/dpain1.wav new file mode 100755 index 00000000..9ec21b98 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/dpain1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/dsight.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/dsight.wav new file mode 100755 index 00000000..593638ba Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/dsight.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/idle.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/idle.wav new file mode 100755 index 00000000..b5cd46fa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/dog/idle.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/airdoor1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/airdoor1.wav new file mode 100755 index 00000000..327caaa5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/airdoor1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/airdoor2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/airdoor2.wav new file mode 100755 index 00000000..c0e8b70c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/airdoor2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/basesec1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/basesec1.wav new file mode 100755 index 00000000..cf14e30e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/basesec1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/basesec2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/basesec2.wav new file mode 100755 index 00000000..f0e517ba Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/basesec2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/basetry.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/basetry.wav new file mode 100755 index 00000000..efecec17 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/basetry.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/baseuse.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/baseuse.wav new file mode 100755 index 00000000..2d5d8769 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/baseuse.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/ddoor1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/ddoor1.wav new file mode 100755 index 00000000..d8e6af64 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/ddoor1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/ddoor2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/ddoor2.wav new file mode 100755 index 00000000..bdb75c6b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/ddoor2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/doormv1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/doormv1.wav new file mode 100755 index 00000000..fd1aed7d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/doormv1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/drclos4.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/drclos4.wav new file mode 100755 index 00000000..91492cf8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/drclos4.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/hydro1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/hydro1.wav new file mode 100755 index 00000000..2db87f27 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/hydro1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/hydro2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/hydro2.wav new file mode 100755 index 00000000..ded66bd1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/hydro2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/latch2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/latch2.wav new file mode 100755 index 00000000..f8ea5f34 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/latch2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/medtry.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/medtry.wav new file mode 100755 index 00000000..64b89f38 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/medtry.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/meduse.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/meduse.wav new file mode 100755 index 00000000..d5d0107d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/meduse.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/runetry.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/runetry.wav new file mode 100755 index 00000000..03f2a399 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/runetry.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/runeuse.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/runeuse.wav new file mode 100755 index 00000000..a71b25f5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/runeuse.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/stndr1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/stndr1.wav new file mode 100755 index 00000000..6a76b370 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/stndr1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/stndr2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/stndr2.wav new file mode 100755 index 00000000..9e25115a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/stndr2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/winch2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/winch2.wav new file mode 100755 index 00000000..c68a389f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/doors/winch2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/double.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/double.wav new file mode 100755 index 00000000..a35f9c3e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/double.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/Laugh1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/Laugh1.wav new file mode 100755 index 00000000..a5445053 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/Laugh1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/elite_see.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/elite_see.wav new file mode 100755 index 00000000..c6323301 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/elite_see.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/laugh2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/laugh2.wav new file mode 100755 index 00000000..0bd7abcb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/laugh2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogdrag.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogdrag.wav new file mode 100755 index 00000000..96414466 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogdrag.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogdth.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogdth.wav new file mode 100755 index 00000000..3af50690 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogdth.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogdth2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogdth2.wav new file mode 100755 index 00000000..8a7e9f04 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogdth2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogdth3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogdth3.wav new file mode 100755 index 00000000..86bd6d35 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogdth3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogidle.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogidle.wav new file mode 100755 index 00000000..83a8bce0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogidle.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogidle2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogidle2.wav new file mode 100755 index 00000000..1992ce92 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogidle2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogpain1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogpain1.wav new file mode 100755 index 00000000..3a6311fc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogpain1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogsawatk.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogsawatk.wav new file mode 100755 index 00000000..92a28602 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogsawatk.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogwake.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogwake.wav new file mode 100755 index 00000000..a5445053 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/elite/ogwake.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/death1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/death1.wav new file mode 100755 index 00000000..a4b69b46 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/death1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/enfire.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/enfire.wav new file mode 100755 index 00000000..f8bee114 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/enfire.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/enfstop.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/enfstop.wav new file mode 100755 index 00000000..f2deebbc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/enfstop.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/idle1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/idle1.wav new file mode 100755 index 00000000..4a77f76f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/idle1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/pain1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/pain1.wav new file mode 100755 index 00000000..e67db1ef Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/pain1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/pain2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/pain2.wav new file mode 100755 index 00000000..65534d14 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/pain2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/sight1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/sight1.wav new file mode 100755 index 00000000..19c1b164 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/sight1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/sight2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/sight2.wav new file mode 100755 index 00000000..04f84f79 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/sight2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/sight3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/sight3.wav new file mode 100755 index 00000000..4cf83b0f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/sight3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/sight4.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/sight4.wav new file mode 100755 index 00000000..b65a811e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/enforcer/sight4.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/firefight.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/firefight.wav new file mode 100755 index 00000000..e1369c7d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/firefight.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/fish/bite.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/fish/bite.wav new file mode 100755 index 00000000..9e769b9c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/fish/bite.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/fish/death.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/fish/death.wav new file mode 100755 index 00000000..5ca0ce05 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/fish/death.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/fish/idle.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/fish/idle.wav new file mode 100755 index 00000000..615aafee Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/fish/idle.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/attack1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/attack1.wav new file mode 100755 index 00000000..95465126 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/attack1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/death1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/death1.wav new file mode 100755 index 00000000..796e728b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/death1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/grunt.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/grunt.wav new file mode 100755 index 00000000..0ec161b8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/grunt.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/hit.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/hit.wav new file mode 100755 index 00000000..8d55634a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/hit.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/idle.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/idle.wav new file mode 100755 index 00000000..dd16fbaa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/idle.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/pain1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/pain1.wav new file mode 100755 index 00000000..92220dd4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/pain1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/sight1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/sight1.wav new file mode 100755 index 00000000..03c8dd7a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/sight1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/slash1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/slash1.wav new file mode 100755 index 00000000..d91b7900 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/hknight/slash1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/inv3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/inv3.wav new file mode 100755 index 00000000..3fb91d31 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/inv3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/armor1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/armor1.wav new file mode 100755 index 00000000..4444c08b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/armor1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/damage.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/damage.wav new file mode 100755 index 00000000..f765ac4a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/damage.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/damage2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/damage2.wav new file mode 100755 index 00000000..f92a770b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/damage2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/damage3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/damage3.wav new file mode 100755 index 00000000..7621077e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/damage3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/health1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/health1.wav new file mode 100755 index 00000000..91ddbd9f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/health1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/inv1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/inv1.wav new file mode 100755 index 00000000..ad12167a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/inv1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/inv2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/inv2.wav new file mode 100755 index 00000000..abf9eaed Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/inv2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/inv3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/inv3.wav new file mode 100755 index 00000000..bdfb2a41 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/inv3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/itembk2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/itembk2.wav new file mode 100755 index 00000000..62f5d3c8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/itembk2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/protect.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/protect.wav new file mode 100755 index 00000000..1747f624 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/protect.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/protect2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/protect2.wav new file mode 100755 index 00000000..3ade5fd1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/protect2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/protect3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/protect3.wav new file mode 100755 index 00000000..dd2bfeae Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/protect3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/r_item1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/r_item1.wav new file mode 100755 index 00000000..36f15a24 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/r_item1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/r_item2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/r_item2.wav new file mode 100755 index 00000000..875d6a95 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/r_item2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/suit.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/suit.wav new file mode 100755 index 00000000..e4c35587 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/suit.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/suit2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/suit2.wav new file mode 100755 index 00000000..aa6a72da Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/items/suit2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/killtacular.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/killtacular.wav new file mode 100755 index 00000000..932c44f9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/killtacular.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/killtrocity.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/killtrocity.wav new file mode 100755 index 00000000..55f4f72e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/killtrocity.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/idle.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/idle.wav new file mode 100755 index 00000000..f3f869df Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/idle.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/kdeath.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/kdeath.wav new file mode 100755 index 00000000..0dbe3e0c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/kdeath.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/khurt.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/khurt.wav new file mode 100755 index 00000000..954b944c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/khurt.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/ksight.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/ksight.wav new file mode 100755 index 00000000..fa65a832 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/ksight.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/sword1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/sword1.wav new file mode 100755 index 00000000..e01c16bd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/sword1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/sword2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/sword2.wav new file mode 100755 index 00000000..67d1e46c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/knight/sword2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/Shortexp.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/Shortexp.wav new file mode 100755 index 00000000..ee8b5373 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/Shortexp.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/basekey.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/basekey.wav new file mode 100755 index 00000000..be21af4f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/basekey.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/h2ohit1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/h2ohit1.wav new file mode 100755 index 00000000..785395f4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/h2ohit1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/medkey.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/medkey.wav new file mode 100755 index 00000000..93ff1d56 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/medkey.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/menu1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/menu1.wav new file mode 100755 index 00000000..40605c36 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/menu1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/menu2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/menu2.wav new file mode 100755 index 00000000..40605c36 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/menu2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/menu3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/menu3.wav new file mode 100755 index 00000000..40605c36 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/menu3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/null.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/null.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/null.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/outwater.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/outwater.wav new file mode 100755 index 00000000..b863dac7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/outwater.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/power.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/power.wav new file mode 100755 index 00000000..57909ad9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/power.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele1.wav new file mode 100755 index 00000000..f1146cc5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele2.wav new file mode 100755 index 00000000..f1146cc5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele3.wav new file mode 100755 index 00000000..f1146cc5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele4.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele4.wav new file mode 100755 index 00000000..f1146cc5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele4.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele5.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele5.wav new file mode 100755 index 00000000..f1146cc5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/r_tele5.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/runekey.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/runekey.wav new file mode 100755 index 00000000..c0c5a2c1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/runekey.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/secret.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/secret.wav new file mode 100755 index 00000000..a10fb2db Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/secret.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/shatter.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/shatter.wav new file mode 100755 index 00000000..fd8bbb91 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/shatter.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/talk.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/talk.wav new file mode 100755 index 00000000..f980d747 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/talk.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/trigger1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/trigger1.wav new file mode 100755 index 00000000..a9e83294 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/trigger1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/water1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/water1.wav new file mode 100755 index 00000000..b0be0d04 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/water1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/water2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/water2.wav new file mode 100755 index 00000000..5bf3423a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/misc/water2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/null.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/null.wav new file mode 100755 index 00000000..c05d4093 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/null.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/medplat1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/medplat1.wav new file mode 100755 index 00000000..28e04c67 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/medplat1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/medplat2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/medplat2.wav new file mode 100755 index 00000000..949d6126 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/medplat2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/plat1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/plat1.wav new file mode 100755 index 00000000..68b28d09 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/plat1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/plat2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/plat2.wav new file mode 100755 index 00000000..825a6a61 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/plat2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/train1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/train1.wav new file mode 100755 index 00000000..ea3dcff8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/train1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/train2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/train2.wav new file mode 100755 index 00000000..a9618ade Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/plats/train2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/OOT2.WAV b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/OOT2.WAV new file mode 100755 index 00000000..ba2d3c75 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/OOT2.WAV differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/axhit1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/axhit1.wav new file mode 100755 index 00000000..7b732d96 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/axhit1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/axhit2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/axhit2.wav new file mode 100755 index 00000000..7263d9f1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/axhit2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/beep1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/beep1.wav new file mode 100755 index 00000000..c45e2b04 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/beep1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/beep2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/beep2.wav new file mode 100755 index 00000000..8435d473 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/beep2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot1.wav new file mode 100755 index 00000000..00d91e77 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot1reserva.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot1reserva.wav new file mode 100755 index 00000000..087640f7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot1reserva.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot2.wav new file mode 100755 index 00000000..566b4c17 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot2r.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot2r.wav new file mode 100755 index 00000000..7a078d50 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot2r.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot3.wav new file mode 100755 index 00000000..d90117b7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot4.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot4.wav new file mode 100755 index 00000000..aadf977a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/boot4.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/death.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/death.wav new file mode 100755 index 00000000..6990eda7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/death.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/death1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/death1.wav new file mode 100755 index 00000000..d49c9169 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/death1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/death2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/death2.wav new file mode 100755 index 00000000..2f03ff9c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/death2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/death3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/death3.wav new file mode 100755 index 00000000..fb4bd0a8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/death3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/drown1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/drown1.wav new file mode 100755 index 00000000..9744409a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/drown1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/drown2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/drown2.wav new file mode 100755 index 00000000..44bba7dc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/drown2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/boot1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/boot1.wav new file mode 100755 index 00000000..29b1e61a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/boot1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/boot2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/boot2.wav new file mode 100755 index 00000000..ba2d3c75 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/boot2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/boot3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/boot3.wav new file mode 100755 index 00000000..73728d54 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/boot3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/boot4.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/boot4.wav new file mode 100755 index 00000000..1499c734 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/boot4.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/step1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/step1.wav new file mode 100755 index 00000000..fe29eac2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/step1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/step2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/step2.wav new file mode 100755 index 00000000..883eba89 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/step2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/step3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/step3.wav new file mode 100755 index 00000000..d0abd0f6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/step3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/step4.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/step4.wav new file mode 100755 index 00000000..603fa142 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/footsteps/step4.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gasp1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gasp1.wav new file mode 100755 index 00000000..ccc85a6d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gasp1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gasp2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gasp2.wav new file mode 100755 index 00000000..2a8932e4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gasp2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gib.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gib.wav new file mode 100755 index 00000000..98a9984d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gib.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gibimp1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gibimp1.wav new file mode 100755 index 00000000..aed19aa9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gibimp1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gibimp2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gibimp2.wav new file mode 100755 index 00000000..1b1433ed Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gibimp2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gibimp3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gibimp3.wav new file mode 100755 index 00000000..e79876c0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gibimp3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gibsplt1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gibsplt1.wav new file mode 100755 index 00000000..13b37ba2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/gibsplt1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/h2odeath.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/h2odeath.wav new file mode 100755 index 00000000..58bf3b06 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/h2odeath.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/h2ojump.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/h2ojump.wav new file mode 100755 index 00000000..7b7975f7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/h2ojump.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/hit1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/hit1.wav new file mode 100755 index 00000000..3bce4b41 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/hit1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/inh2o.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/inh2o.wav new file mode 100755 index 00000000..a1457d21 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/inh2o.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/inlava.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/inlava.wav new file mode 100755 index 00000000..a69dc318 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/inlava.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/land.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/land.wav new file mode 100755 index 00000000..8f8700aa Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/land.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/land2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/land2.wav new file mode 100755 index 00000000..ace4c74b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/land2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/lburn1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/lburn1.wav new file mode 100755 index 00000000..70e39b17 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/lburn1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/lburn2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/lburn2.wav new file mode 100755 index 00000000..2af2b61d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/lburn2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/null.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/null.wav new file mode 100755 index 00000000..6c6f1211 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/null.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/oot3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/oot3.wav new file mode 100755 index 00000000..29b1e61a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/oot3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/pain.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/pain.wav new file mode 100755 index 00000000..a08c52b0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/pain.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/pain1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/pain1.wav new file mode 100755 index 00000000..213a3175 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/pain1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/plyrjmp8.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/plyrjmp8.wav new file mode 100755 index 00000000..0f75b858 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/plyrjmp8.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/reload.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/reload.wav new file mode 100755 index 00000000..0ee7f908 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/reload.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/sheild_recharge.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/sheild_recharge.wav new file mode 100755 index 00000000..ccef3fcb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/sheild_recharge.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/sheilds_low_bleep.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/sheilds_low_bleep.wav new file mode 100755 index 00000000..fd7c1661 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/sheilds_low_bleep.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/slayer.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/slayer.wav new file mode 100755 index 00000000..2680a776 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/slayer.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/slimbrn2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/slimbrn2.wav new file mode 100755 index 00000000..6322f39d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/slimbrn2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/sonic1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/sonic1.wav new file mode 100755 index 00000000..b7526aec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/sonic1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/sonic2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/sonic2.wav new file mode 100755 index 00000000..5d485eeb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/sonic2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/stopsound.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/stopsound.wav new file mode 100755 index 00000000..6c6f1211 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/stopsound.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/teledth1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/teledth1.wav new file mode 100755 index 00000000..35621274 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/teledth1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/termino.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/termino.wav new file mode 100755 index 00000000..fae435ca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/termino.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/tocado.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/tocado.wav new file mode 100755 index 00000000..d6cb094e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/tocado.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/tornoff2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/tornoff2.wav new file mode 100755 index 00000000..0282e2fe Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/tornoff2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/udeath.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/udeath.wav new file mode 100755 index 00000000..6990eda7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/player/udeath.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/attack.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/attack.wav new file mode 100755 index 00000000..75655a92 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/attack.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/attack2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/attack2.wav new file mode 100755 index 00000000..9ad4def9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/attack2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/death.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/death.wav new file mode 100755 index 00000000..d5a750ce Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/death.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/idle.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/idle.wav new file mode 100755 index 00000000..96cb5e88 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/idle.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/pain.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/pain.wav new file mode 100755 index 00000000..de8a54f8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/pain.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/sight.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/sight.wav new file mode 100755 index 00000000..c2b810b8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shalrath/sight.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/melee1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/melee1.wav new file mode 100755 index 00000000..5342e2bf Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/melee1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/melee2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/melee2.wav new file mode 100755 index 00000000..b73fcacf Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/melee2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/sattck1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/sattck1.wav new file mode 100755 index 00000000..260944ca Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/sattck1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/sboom.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/sboom.wav new file mode 100755 index 00000000..29966b68 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/sboom.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/sdeath.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/sdeath.wav new file mode 100755 index 00000000..560aceec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/sdeath.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/shurt2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/shurt2.wav new file mode 100755 index 00000000..5e725778 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/shurt2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/sidle.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/sidle.wav new file mode 100755 index 00000000..f73ce581 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/sidle.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/smack.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/smack.wav new file mode 100755 index 00000000..75d2bd58 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/smack.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/ssight.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/ssight.wav new file mode 100755 index 00000000..e5fa0af4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/shambler/ssight.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/slayer.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/slayer.wav new file mode 100755 index 00000000..44d585f9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/slayer.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/death1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/death1.wav new file mode 100755 index 00000000..d7e09156 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/death1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/idle.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/idle.wav new file mode 100755 index 00000000..50b75814 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/idle.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/kill_all.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/kill_all.wav new file mode 100755 index 00000000..7a8bf9bc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/kill_all.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/laugh1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/laugh1.wav new file mode 100755 index 00000000..1f5e23a0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/laugh1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/laugh2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/laugh2.wav new file mode 100755 index 00000000..050c4623 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/laugh2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/pain1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/pain1.wav new file mode 100755 index 00000000..53c761b1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/pain1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/pain2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/pain2.wav new file mode 100755 index 00000000..53c761b1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/pain2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/sight1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/sight1.wav new file mode 100755 index 00000000..a30c5a28 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/sight1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/unstoppable.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/unstoppable.wav new file mode 100755 index 00000000..77f76810 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/soldier/unstoppable.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/sonic2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/sonic2.wav new file mode 100755 index 00000000..f745086d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/sonic2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/spree.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/spree.wav new file mode 100755 index 00000000..2e5390a0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/spree.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/steps/boot1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/steps/boot1.wav new file mode 100755 index 00000000..29b1e61a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/steps/boot1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/steps/boot2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/steps/boot2.wav new file mode 100755 index 00000000..ba2d3c75 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/steps/boot2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/steps/boot3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/steps/boot3.wav new file mode 100755 index 00000000..73728d54 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/steps/boot3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/steps/boot4.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/steps/boot4.wav new file mode 100755 index 00000000..1499c734 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/steps/boot4.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/triple.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/triple.wav new file mode 100755 index 00000000..fc39e535 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/triple.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/ar.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/ar.wav new file mode 100755 index 00000000..6bb85120 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/ar.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/br.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/br.wav new file mode 100755 index 00000000..8e96b2dd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/br.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/needler.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/needler.wav new file mode 100755 index 00000000..f8817c79 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/needler.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/pistol.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/pistol.wav new file mode 100755 index 00000000..0cdee5cc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/pistol.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/ppist.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/ppist.wav new file mode 100755 index 00000000..01272ad1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/ppist.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/rocket.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/rocket.wav new file mode 100755 index 00000000..2082d046 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/rocket.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/shotgun.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/shotgun.wav new file mode 100755 index 00000000..631bf7ab Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/shotgun.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/smg.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/smg.wav new file mode 100755 index 00000000..481b0b75 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/smg.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/sniper.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/sniper.wav new file mode 100755 index 00000000..eed46171 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/Equip/sniper.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/PR_fire.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/PR_fire.wav new file mode 100755 index 00000000..c2ec12c3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/PR_fire.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/PR_fire1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/PR_fire1.wav new file mode 100755 index 00000000..b8766f4d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/PR_fire1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ar1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ar1.wav new file mode 100755 index 00000000..f2f5ab8a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ar1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ar2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ar2.wav new file mode 100755 index 00000000..ba8f82d6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ar2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ar3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ar3.wav new file mode 100755 index 00000000..92ab35ea Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ar3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ax1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ax1.wav new file mode 100755 index 00000000..f505e765 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ax1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bhit.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bhit.wav new file mode 100755 index 00000000..1fa38916 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bhit.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bhit2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bhit2.wav new file mode 100755 index 00000000..7263d9f1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bhit2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bhit3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bhit3.wav new file mode 100755 index 00000000..936e7d21 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bhit3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bigneedler.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bigneedler.wav new file mode 100755 index 00000000..2aa92f15 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bigneedler.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bota.WAV b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bota.WAV new file mode 100755 index 00000000..29bdb313 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bota.WAV differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bounce.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bounce.wav new file mode 100755 index 00000000..91d03736 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/bounce.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/br.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/br.wav new file mode 100755 index 00000000..66781e4e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/br.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/case.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/case.wav new file mode 100755 index 00000000..a950136b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/case.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/coil.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/coil.wav new file mode 100755 index 00000000..8fbd7e69 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/coil.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/crystal.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/crystal.wav new file mode 100755 index 00000000..7fa69aeb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/crystal.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/grenade.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/grenade.wav new file mode 100755 index 00000000..88363f2b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/grenade.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/grenpick.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/grenpick.wav new file mode 100755 index 00000000..4ce6d103 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/grenpick.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/lhit.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/lhit.wav new file mode 100755 index 00000000..da08d874 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/lhit.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/lock4.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/lock4.wav new file mode 100755 index 00000000..198720a7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/lock4.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/lowammo.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/lowammo.wav new file mode 100755 index 00000000..e3cf737e Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/lowammo.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/lstart.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/lstart.wav new file mode 100755 index 00000000..92716ef7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/lstart.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/magnum-reload.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/magnum-reload.wav new file mode 100755 index 00000000..b92463ec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/magnum-reload.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/magnum.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/magnum.wav new file mode 100755 index 00000000..3e1def35 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/magnum.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/ar.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/ar.wav new file mode 100755 index 00000000..91c5459c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/ar.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/br.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/br.wav new file mode 100755 index 00000000..46b8f9ea Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/br.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/needler.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/needler.wav new file mode 100755 index 00000000..3b891bfc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/needler.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/pistol.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/pistol.wav new file mode 100755 index 00000000..49b43185 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/pistol.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/rocket.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/rocket.wav new file mode 100755 index 00000000..309d0e10 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/rocket.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/shottie.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/shottie.wav new file mode 100755 index 00000000..35012020 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/shottie.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/sniper.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/sniper.wav new file mode 100755 index 00000000..f8598592 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/sniper.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/uzi.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/uzi.wav new file mode 100755 index 00000000..1f6904dc Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/melee/uzi.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/nade.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/nade.wav new file mode 100755 index 00000000..f153bd07 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/nade.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/nb.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/nb.wav new file mode 100755 index 00000000..b2b2e823 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/nb.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/needler.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/needler.wav new file mode 100755 index 00000000..311287dd Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/needler.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/noammo.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/noammo.wav new file mode 100755 index 00000000..a1a0c9e9 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/noammo.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/oddball.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/oddball.wav new file mode 100755 index 00000000..ca385e5a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/oddball.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/open1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/open1.wav new file mode 100755 index 00000000..ef96a05d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/open1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ostia.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ostia.wav new file mode 100755 index 00000000..d74ff93c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ostia.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/pbounce.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/pbounce.wav new file mode 100755 index 00000000..7ca76b7a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/pbounce.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/pistol.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/pistol.wav new file mode 100755 index 00000000..5aaa999a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/pistol.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/pkup.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/pkup.wav new file mode 100755 index 00000000..8f9154ec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/pkup.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/plasma_blow.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/plasma_blow.wav new file mode 100755 index 00000000..d1282d9d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/plasma_blow.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/plasma_throw.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/plasma_throw.wav new file mode 100755 index 00000000..1641fbfb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/plasma_throw.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ppist.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ppist.wav new file mode 100755 index 00000000..70c42489 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ppist.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/r_exp3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/r_exp3.wav new file mode 100755 index 00000000..ee029557 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/r_exp3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/Needler.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/Needler.wav new file mode 100755 index 00000000..32b05478 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/Needler.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/ar.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/ar.wav new file mode 100755 index 00000000..19c2bce8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/ar.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/br.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/br.wav new file mode 100755 index 00000000..9ef62ac2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/br.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/pistol.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/pistol.wav new file mode 100755 index 00000000..116ab7a1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/pistol.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/rocket.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/rocket.wav new file mode 100755 index 00000000..bd8ff3e1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/rocket.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/shottie.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/shottie.wav new file mode 100755 index 00000000..7df17568 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/shottie.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/sniper.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/sniper.wav new file mode 100755 index 00000000..f28d92c4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/sniper.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/uzi.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/uzi.wav new file mode 100755 index 00000000..9f45f99c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reload/uzi.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reloadp.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reloadp.wav new file mode 100755 index 00000000..fc1c4f77 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/reloadp.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric1.wav new file mode 100755 index 00000000..52cf763b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric2.wav new file mode 100755 index 00000000..722231b6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric3.wav new file mode 100755 index 00000000..7520f35a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric4.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric4.wav new file mode 100755 index 00000000..ea381c42 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric4.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric5.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric5.wav new file mode 100755 index 00000000..a1c03eb4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric5.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric6.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric6.wav new file mode 100755 index 00000000..caf92cd1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric6.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric7.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric7.wav new file mode 100755 index 00000000..3b303831 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric7.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric8.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric8.wav new file mode 100755 index 00000000..b09f446f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric8.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric9.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric9.wav new file mode 100755 index 00000000..76d1aaa1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/ric9.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/rocket1i.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/rocket1i.wav new file mode 100755 index 00000000..77a62bd5 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/rocket1i.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/rocket1l.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/rocket1l.wav new file mode 100755 index 00000000..72998d4a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/rocket1l.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/sgun1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/sgun1.wav new file mode 100755 index 00000000..f8bf198a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/sgun1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/shelldrop.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/shelldrop.wav new file mode 100755 index 00000000..649f2d71 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/shelldrop.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/shotgn2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/shotgn2.wav new file mode 100755 index 00000000..ee5cdfa2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/shotgn2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/shottie.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/shottie.wav new file mode 100755 index 00000000..d0572928 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/shottie.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/sni.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/sni.wav new file mode 100755 index 00000000..d2809b58 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/sni.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/sniper.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/sniper.wav new file mode 100755 index 00000000..3424a01d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/sniper.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/sniperf.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/sniperf.wav new file mode 100755 index 00000000..18ca8c0c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/sniperf.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/spike2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/spike2.wav new file mode 100755 index 00000000..754258d4 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/spike2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/tink1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/tink1.wav new file mode 100755 index 00000000..b88c1f56 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/tink1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/tink2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/tink2.wav new file mode 100755 index 00000000..f7323988 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/tink2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/uzi.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/uzi.wav new file mode 100755 index 00000000..f7ffa82a Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/uzi.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/w_drop1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/w_drop1.wav new file mode 100755 index 00000000..19c856c8 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/w_drop1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/w_drop2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/w_drop2.wav new file mode 100755 index 00000000..5a1394fe Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/w_drop2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/w_drop3.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/w_drop3.wav new file mode 100755 index 00000000..fb29a770 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/w_drop3.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/zoom.WAV b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/zoom.WAV new file mode 100755 index 00000000..4c9f022f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/zoom.WAV differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/zoom2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/zoom2.wav new file mode 100755 index 00000000..216551f1 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/weapons/zoom2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/hit.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/hit.wav new file mode 100755 index 00000000..0fdd2cef Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/hit.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/wattack.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/wattack.wav new file mode 100755 index 00000000..fc82770c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/wattack.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/wdeath.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/wdeath.wav new file mode 100755 index 00000000..32309218 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/wdeath.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/widle1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/widle1.wav new file mode 100755 index 00000000..e881c88f Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/widle1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/widle2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/widle2.wav new file mode 100755 index 00000000..ac37c141 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/widle2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/wpain.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/wpain.wav new file mode 100755 index 00000000..1f6cac0b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/wpain.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/wsight.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/wsight.wav new file mode 100755 index 00000000..c4309b77 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/wizard/wsight.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/idle_w2.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/idle_w2.wav new file mode 100755 index 00000000..a298838d Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/idle_w2.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_fall.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_fall.wav new file mode 100755 index 00000000..e3ad3122 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_fall.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_gib.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_gib.wav new file mode 100755 index 00000000..02774037 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_gib.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_hit.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_hit.wav new file mode 100755 index 00000000..bbec647c Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_hit.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_idle.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_idle.wav new file mode 100755 index 00000000..94cfa0eb Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_idle.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_idle1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_idle1.wav new file mode 100755 index 00000000..383b0aec Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_idle1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_miss.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_miss.wav new file mode 100755 index 00000000..43c75690 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_miss.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_pain.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_pain.wav new file mode 100755 index 00000000..2fdb6af3 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_pain.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_pain1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_pain1.wav new file mode 100755 index 00000000..587d63b6 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_pain1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_shot1.wav b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_shot1.wav new file mode 100755 index 00000000..d9772766 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sound/zombie/z_shot1.wav differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/ArMuzzleFlash.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/ArMuzzleFlash.spr new file mode 100755 index 00000000..928fbe28 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/ArMuzzleFlash.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/Pistolmuzzleflash.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/Pistolmuzzleflash.spr new file mode 100755 index 00000000..7f766313 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/Pistolmuzzleflash.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/Plasma_explosion.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/Plasma_explosion.spr new file mode 100755 index 00000000..604e50c7 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/Plasma_explosion.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/muzzleN.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/muzzleN.spr new file mode 100755 index 00000000..a2fd58b0 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/muzzleN.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/muzzleflash.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/muzzleflash.spr new file mode 100755 index 00000000..4c357b71 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/muzzleflash.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/muzzleflash1.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/muzzleflash1.spr new file mode 100755 index 00000000..d1587c40 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/muzzleflash1.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/muzzleflash2.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/muzzleflash2.spr new file mode 100755 index 00000000..9d1ff35b Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/muzzleflash2.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/plasma3.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/plasma3.spr new file mode 100755 index 00000000..69223834 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/plasma3.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/s_plasma4.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/s_plasma4.spr new file mode 100755 index 00000000..9f271876 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/s_plasma4.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/s_smoke2.spr b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/s_smoke2.spr new file mode 100755 index 00000000..4cba2310 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/sprites/s_smoke2.spr differ diff --git a/r17/Revamped src/revamped_src/psp/normal/kurok/title.dem b/r17/Revamped src/revamped_src/psp/normal/kurok/title.dem new file mode 100755 index 00000000..d2df5612 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/normal/kurok/title.dem differ diff --git a/r17/Revamped src/revamped_src/psp/normal/quake.cmdline b/r17/Revamped src/revamped_src/psp/normal/quake.cmdline new file mode 100755 index 00000000..aa0fe08f --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/normal/quake.cmdline @@ -0,0 +1,5 @@ +-cpu333 +-kurok +-listen 8 +-crosshair 9 +-nocdaudio \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/pics/ICON.PNG b/r17/Revamped src/revamped_src/psp/pics/ICON.PNG new file mode 100755 index 00000000..71f8d5ed Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/pics/ICON.PNG differ diff --git a/r17/Revamped src/revamped_src/psp/pics/PIC1.PNG b/r17/Revamped src/revamped_src/psp/pics/PIC1.PNG new file mode 100755 index 00000000..0b355bc2 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/pics/PIC1.PNG differ diff --git a/r17/Revamped src/revamped_src/psp/pics/SND0.AT3 b/r17/Revamped src/revamped_src/psp/pics/SND0.AT3 new file mode 100755 index 00000000..d22706ae Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/pics/SND0.AT3 differ diff --git a/r17/Revamped src/revamped_src/psp/pics/pic2.png b/r17/Revamped src/revamped_src/psp/pics/pic2.png new file mode 100755 index 00000000..8dcb7a72 Binary files /dev/null and b/r17/Revamped src/revamped_src/psp/pics/pic2.png differ diff --git a/r17/Revamped src/revamped_src/psp/prof.c b/r17/Revamped src/revamped_src/psp/prof.c new file mode 100755 index 00000000..56b4f8fe --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/prof.c @@ -0,0 +1,255 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * main.c - Basic sample to demonstrate the profiler + * + * Copyright (c) 2005 urchin + * + * $Id: + */ +#include +#include +#include +#include + +#define GMON_PROF_ON 0 +#define GMON_PROF_BUSY 1 +#define GMON_PROF_ERROR 2 +#define GMON_PROF_OFF 3 + +#define GMONVERSION 0x00051879 + +#include + +/** gmon.out file header */ +struct gmonhdr +{ + int lpc; /* lowest pc address */ + int hpc; /* highest pc address */ + int ncnt; /* size of samples + size of header */ + int version; /* version number */ + int profrate; /* profiling clock rate */ + int resv[3]; /* reserved */ +}; + +/** frompc -> selfpc graph */ +struct rawarc +{ + unsigned int frompc; + unsigned int selfpc; + unsigned int count; +}; + +/** context */ +struct gmonparam +{ + int state; + unsigned int lowpc; + unsigned int highpc; + unsigned int textsize; + unsigned int hashfraction; + + int narcs; + struct rawarc *arcs; + + int nsamples; + unsigned int *samples; + + int timer; + + unsigned int pc; +}; + +/// holds context statistics +static struct gmonparam gp; + +/// one histogram per four bytes of text space +#define HISTFRACTION 4 + +/// define sample frequency - 1000 hz = 1ms +#define SAMPLE_FREQ 1000 + +/// have we allocated memory and registered already +static int initialized = 0; + +/// defined by linker +extern int _ftext; +extern int _etext; + +/* forward declarations */ +void gprof_cleanup(); +static SceUInt timer_handler(SceUID uid, SceKernelSysClock *c1, SceKernelSysClock *c2, void *common); + +/** Initializes pg library + + After calculating the text size, initialize() allocates enough + memory to allow fastest access to arc structures, and some more + for sampling statistics. Note that this also installs a timer that + runs at 1000 hert. +*/ +static void initialize() +{ + initialized = 1; + + memset(&gp, '\0', sizeof(gp)); + gp.state = GMON_PROF_ON; + gp.lowpc = (unsigned int)&_ftext; + gp.highpc = (unsigned int)&_etext; + gp.textsize = gp.highpc - gp.lowpc; + gp.hashfraction = HISTFRACTION; + + gp.narcs = (gp.textsize + gp.hashfraction - 1) / gp.hashfraction; + gp.arcs = (struct rawarc *)malloc(sizeof(struct rawarc) * gp.narcs); + if (gp.arcs == NULL) + { + gp.state = GMON_PROF_ERROR; + return; + } + + gp.nsamples = (gp.textsize + gp.hashfraction - 1) / gp.hashfraction; + gp.samples = (unsigned int *)malloc(sizeof(unsigned int) * gp.nsamples); + if (gp.samples == NULL) + { + free(gp.arcs); + gp.arcs = 0; + gp.state = GMON_PROF_ERROR; + return; + } + + memset((void *)gp.arcs, '\0', gp.narcs * (sizeof(struct rawarc))); + memset((void *)gp.samples, '\0', gp.nsamples * (sizeof(unsigned int ))); + + gp.timer = sceKernelCreateVTimer("gprof timer", NULL); + + SceKernelSysClock sc; + sc.hi = 0; + sc.low = SAMPLE_FREQ; + + int thid = sceKernelGetThreadId(); + + SceKernelThreadInfo info; + info.size = sizeof(info); + int ret = sceKernelReferThreadStatus(thid, &info); + + if(ret == 0) + { + void* timer_addr = timer_handler; + if((info.attr & PSP_THREAD_ATTR_USER) == 0) + { + timer_addr += 0x80000000; + } + + ret = sceKernelSetVTimerHandler(gp.timer, &sc, timer_addr, NULL); + } + + if(ret == 0) + { + sceKernelStartVTimer(gp.timer); + } +} + +/** Writes gmon.out dump file and stops profiling + + Called from atexit() handler; will dump out a host:gmon.out file + with all collected information. +*/ +void gprof_cleanup() +{ + FILE *fp; + int i; + struct gmonhdr hdr; + + if (gp.state != GMON_PROF_ON) + { + /* profiling was disabled anyway */ + return; + } + + /* disable profiling before we make plenty of libc calls */ + gp.state = GMON_PROF_OFF; + + sceKernelStopVTimer(gp.timer); + + fp = fopen("gmon.out", "wb"); + hdr.lpc = gp.lowpc; + hdr.hpc = gp.highpc; + hdr.ncnt = sizeof(hdr) + (sizeof(unsigned int) * gp.nsamples); + hdr.version = GMONVERSION; + hdr.profrate = SAMPLE_FREQ; + hdr.resv[0] = 0; + hdr.resv[1] = 0; + hdr.resv[2] = 0; + fwrite(&hdr, 1, sizeof(hdr), fp); + fwrite(gp.samples, gp.nsamples, sizeof(unsigned int), fp); + + for (i=0; i 0) + { + fwrite(gp.arcs + i, sizeof(struct rawarc), 1, fp); + } + } + + fclose(fp); +} + +/** Internal C handler for _mcount() + @param frompc pc address of caller + @param selfpc pc address of current function + + Called from mcount.S to make life a bit easier. __mcount is called + right before a function starts. GCC generates a tiny stub at the very + beginning of each compiled routine, which eventually brings the + control to here. +*/ +void __mcount(unsigned int frompc, unsigned int selfpc) +{ + int e; + struct rawarc *arc; + + if (initialized == 0) + { + initialize(); + } + + if (gp.state != GMON_PROF_ON) + { + /* returned off for some reason */ + return; + } + + frompc = frompc & 0x0FFFFFFF; + selfpc = selfpc & 0x0FFFFFFF; + + /* call might come from stack */ + if (frompc >= gp.lowpc && frompc <= gp.highpc) + { + gp.pc = selfpc; + e = (frompc - gp.lowpc) / gp.hashfraction; + arc = gp.arcs + e; + arc->frompc = frompc; + arc->selfpc = selfpc; + arc->count++; + } +} + +/** Internal timer handler +*/ +static SceUInt timer_handler(SceUID uid, SceKernelSysClock *requested, SceKernelSysClock *actual, void *common) +{ + unsigned int frompc = gp.pc; + + if (gp.state == GMON_PROF_ON) + { + /* call might come from stack */ + if (frompc >= gp.lowpc && frompc <= gp.highpc) + { + int e = (frompc - gp.lowpc) / gp.hashfraction; + gp.samples[e]++; + } + } + + return SAMPLE_FREQ; +} diff --git a/r17/Revamped src/revamped_src/psp/pspDveManager.S b/r17/Revamped src/revamped_src/psp/pspDveManager.S new file mode 100755 index 00000000..f7b73f61 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/pspDveManager.S @@ -0,0 +1,8 @@ + .set noreorder + +#include "pspstub.s" + + STUB_START "pspDveManager",0x40090000,0x00020005 + STUB_FUNC 0x2ACFCB6D,pspDveMgrCheckVideoOut + STUB_FUNC 0xF9C86C73,pspDveMgrSetVideoOut + STUB_END diff --git a/r17/Revamped src/revamped_src/psp/sed_make.sh b/r17/Revamped src/revamped_src/psp/sed_make.sh new file mode 100755 index 00000000..c5e8ff2d --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/sed_make.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make 2>&1 $@ | sed -e 's/\([^:]*\):\([0-9][0-9]*\)\(.*\)/\1(\2) \3/' \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/psp/sound.cpp b/r17/Revamped src/revamped_src/psp/sound.cpp new file mode 100755 index 00000000..ba550b12 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/sound.cpp @@ -0,0 +1,183 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#include +#include +#include + +extern "C" +{ +#include "../quakedef.h" +} + +namespace quake +{ + namespace sound + { + struct Sample + { + short left; + short right; + }; + + static const unsigned int channelCount = 2; + static const unsigned int inputBufferSize = 16384; + +#ifdef NORMAL_MODE + static const unsigned int inputFrequency = 11025; +#else + static const unsigned int inputFrequency = 22050; +#endif + static const unsigned int outputFrequency = 44100; + static const unsigned int inputSamplesPerOutputSample = outputFrequency / inputFrequency; + static Sample inputBuffer[inputBufferSize]; + static volatile unsigned int samplesRead; + + static inline void copySamples(const Sample* first, const Sample* last, Sample* destination) + { + switch (inputSamplesPerOutputSample) + { + case 1: + memcpy(destination, first, (last - first) * sizeof(Sample)); + break; + + case 2: + for (const Sample* source = first; source != last; ++source) + { + const Sample sample = *source; + *destination++ = sample; + *destination++ = sample; + } + break; + + case 4: + for (const Sample* source = first; source != last; ++source) + { + const Sample sample = *source; + *destination++ = sample; + *destination++ = sample; + *destination++ = sample; + *destination++ = sample; + } + break; + + default: + break; + } + } + + static void fillOutputBuffer(void* buffer, unsigned int samplesToWrite, void* userData) + { + // Where are we writing to? + Sample* const destination = static_cast (buffer); + + // Where are we reading from? + const Sample* const firstSampleToRead = &inputBuffer[samplesRead]; + + // How many samples to read? + const unsigned int samplesToRead = samplesToWrite / inputSamplesPerOutputSample; + + // Going to wrap past the end of the input buffer? + const unsigned int samplesBeforeEndOfInput = inputBufferSize - samplesRead; + if (samplesToRead > samplesBeforeEndOfInput) + { + // Yes, so write the first chunk from the end of the input buffer. + copySamples( + firstSampleToRead, + firstSampleToRead + samplesBeforeEndOfInput, + &destination[0]); + + // Write the second chunk from the start of the input buffer. + const unsigned int samplesToReadFromBeginning = samplesToRead - samplesBeforeEndOfInput; + copySamples( + &inputBuffer[0], + &inputBuffer[samplesToReadFromBeginning], + &destination[samplesBeforeEndOfInput * inputSamplesPerOutputSample]); + } + else + { + // No wrapping, just copy. + copySamples( + firstSampleToRead, + firstSampleToRead + samplesToRead, + &destination[0]); + } + + // Update the read offset. + samplesRead = (samplesRead + samplesToRead) % inputBufferSize; + } + } +} + +using namespace quake; +using namespace quake::sound; + +qboolean SNDDMA_Init(void) +{ + // Set up Quake's audio. + shm = &sn; + shm->channels = channelCount; + shm->samplebits = 16; + shm->speed = inputFrequency; + shm->soundalive = qtrue; + shm->splitbuffer = qfalse; + shm->samples = inputBufferSize * channelCount; + shm->samplepos = 0; + shm->submission_chunk = 1; + shm->buffer = (unsigned char *) inputBuffer; + + // Initialise the audio system. This initialises it for the CD audio module + // too. + pspAudioInit(); + + // Set the channel callback. + // Sound effects use channel 0, CD audio uses channel 1. + pspAudioSetChannelCallback(0, fillOutputBuffer, 0); + + return qtrue; +} + +void SNDDMA_Shutdown(void) +{ + // Clear the mixing buffer so we don't get any noise during cleanup. + memset(inputBuffer, 0, sizeof(inputBuffer)); + + // Clear the channel callback. + pspAudioSetChannelCallback(0, 0, 0); + + // Stop the audio system? + pspAudioEndPre(); + + // Insert a false delay so the thread can be cleaned up. + sceKernelDelayThread(50 * 1000); + + // Shut down the audio system. + pspAudioEnd(); +} + +int SNDDMA_GetDMAPos(void) +{ + return samplesRead * channelCount; +} + +void SNDDMA_Submit(void) +{ +} diff --git a/r17/Revamped src/revamped_src/psp/system.cpp b/r17/Revamped src/revamped_src/psp/system.cpp new file mode 100755 index 00000000..921adcb8 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/system.cpp @@ -0,0 +1,467 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#define ENABLE_PRINTF 0 + +#include "system.hpp" + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern "C" +{ +#include "../sys.h" +#include "../quakedef.h" +} +#include "fnmatch.h" + +void CDAudio_Stop(void); +void CDAudio_Update(void); + +namespace quake +{ + namespace main + { + extern const int cpuClockSpeed; + extern const int ramClockSpeed; + extern const int busClockSpeed; + } + + namespace system + { + struct file + { + // Set on open. + char name[MAX_OSPATH + 1]; + bool write; + + // Set on open, suspend, restore. + FILE* handle; + + // Set on suspend. + long offset; + }; + + static bool debugScreenInitialized = false; + static const std::size_t file_count = 64; + static file files[file_count]; + + void suspend() + { + Con_Printf("Suspend requested \n"); + + Cvar_Set("bgmtype","none"); + CDAudio_Update(); + sceKernelDelayThread(5*10000); + +// CDAudio_Pause(); + // Close each file. + for (std::size_t file_index = 0; file_index < file_count; ++file_index) + { + // Is the file in use? + file& file = files[file_index]; + if (file.name[0]) + { + // Save the offset; + file.offset = ftell(file.handle); + + // Close the file. + fclose(file.handle); + file.handle = 0; + } + } + + Con_Printf("Filesystem sunspended\n"); + } + + void resume() + { + Con_Printf("Resume requested\n"); + // Check each file. + for (std::size_t file_index = 0; file_index < file_count; ++file_index) + { + // Is the file in use? + file& file = files[file_index]; + if (file.name[0]) + { + // Reopen the file. This can repeatedly fail, so we keep trying. + const char* mode = file.write ? "ab" : "rb"; + do + { + file.handle = fopen(file.name, mode); + } + while (!file.handle); + + // Restore the offset; + if (fseek(file.handle, file.offset, SEEK_SET) != 0) + { + throw std::runtime_error("Couldn't seek in file"); + } + } + } + + Con_Printf("CD Audio Initialized\n"); + if(kurok) + { + Cvar_Set("bgmtype","cd"); + CDAudio_Update(); + } +// CDAudio_Resume(); + Con_Printf("Filesystem resumed\n"); + + } + } +} + +using namespace quake; +using namespace quake::system; + +int Sys_FileOpenRead (char *path, int *hndl) +{ + // Find an unused file. + for (std::size_t file_index = 1; file_index < file_count; ++file_index) + { + // Is the file in use? + file& file = files[file_index]; + if (file.name[0]) + { + continue; + } + + // Open the file. + file.handle = fopen(path, "rb"); + if (!file.handle) + { + *hndl = -1; + return -1; + } + + // Get the length. + if (fseek(file.handle, 0, SEEK_END) != 0) + { + Sys_Error("fseek failed"); + } + const long length = ftell(file.handle); + if (fseek(file.handle, 0, SEEK_SET) != 0) + { + Sys_Error("fseek failed"); + } + + // The file is now in use! + Q_strncpy(file.name, path, MAX_OSPATH); + file.write = false; + + // Done. + *hndl = file_index; + return length; + } + + Sys_Error("Out of file slots"); + return -1; +} + +int Sys_FileOpenWrite (char *path) +{ + // Find an unused file. + for (std::size_t file_index = 1; file_index < file_count; ++file_index) + { + // Is the file in use? + file& file = files[file_index]; + if (file.name[0]) + { + continue; + } + + // Open the file. + file.handle = fopen(path, "wb"); + if (!file.handle) + { + return -1; + } + + // The file is now in use! + Q_strncpy(file.name, path, MAX_OSPATH); + file.write = true; + + // Done. + return file_index; + } + + Sys_Error("Out of file slots"); + return -1; +} + +void Sys_FileClose (int handle) +{ + // Close the file. + file& file = files[handle]; + fclose(file.handle); + file.handle = 0; + file.name[0] = 0; +} + +void Sys_FileSeek (int handle, int position) +{ + file& file = files[handle]; + if (fseek(file.handle, position, SEEK_SET) != 0) + { + Sys_Error("fseek failed"); + } +} + +int Sys_FileRead (int handle, void *dest, int count) +{ + file& file = files[handle]; + return fread(dest, 1, count, file.handle); +} + +int Sys_FileWrite (int handle, void *data, int count) +{ + file& file = files[handle]; + return fwrite(data, 1, count, file.handle); +} + +int Sys_FileTime (char *path) +{ + /* +#ifdef _WIN32 + return -1; +#else + */ + struct stat s; + memset(&s, 0, sizeof(s)); + + if (stat(path, &s) < 0) + { + return -1; + } + + return s.st_ctime; + /* +#endif + */ +} + +void Sys_mkdir (char *path) +{ + Sys_Printf("Mkdir: %s\n", path); + sceIoMkdir(path, 0x777); +} + +void Sys_Error (char *error, ...) +{ + // Clear the sound buffer. + S_ClearBuffer(); + + // Put the error message in a buffer. + va_list args; + va_start(args, error); + char buffer[1024]; + memset(buffer, 0, sizeof(buffer)); + vsnprintf(buffer, sizeof(buffer) - 1, error, args); + va_end(args); + + Con_Printf(buffer); + // Print the error message to the debug screen. + if (!debugScreenInitialized) + { + pspDebugScreenInit(); + debugScreenInitialized = true; + } + pspDebugScreenSetTextColor(0xffffff); + pspDebugScreenPrintf("The following error occurred:\n"); + pspDebugScreenSetTextColor(0x0000ff); + pspDebugScreenPrintData(buffer, strlen(buffer)); + pspDebugScreenSetTextColor(0xffffff); + pspDebugScreenPrintf("\n\nPress CROSS to quit.\n"); + + // Wait for a button press. + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); + SceCtrlData pad; + do { + sceCtrlReadBufferPositive(&pad, 1); + } while (pad.Buttons & PSP_CTRL_CROSS); + do { + sceCtrlReadBufferPositive(&pad, 1); + } while ((pad.Buttons & PSP_CTRL_CROSS) == 0); + do { + sceCtrlReadBufferPositive(&pad, 1); + } while (pad.Buttons & PSP_CTRL_CROSS); + + // Quit. + pspDebugScreenPrintf("Shutting down...\n"); + Sys_Quit(); +} + +void Sys_Printf (char *fmt, ...) +{ +#if ENABLE_PRINTF + char buffer[1024]; + + va_list args; + va_start(args, fmt); + memset(buffer, 0, sizeof(buffer)); + vsnprintf(buffer, sizeof(buffer) - 1, fmt, args); + va_end(args); + + if (!debugScreenInitialized) + { + pspDebugScreenInit(); + debugScreenInitialized = true; + } + pspDebugScreenPrintData(buffer, strlen(buffer)); +#endif +} + +void Sys_Quit (void) +{ + // Shut down the host system. + if (host_initialized) + { + Host_Shutdown(); + } + + // Restore the old clock frequency. + scePowerSetClockFrequency(main::cpuClockSpeed, main::ramClockSpeed, main::busClockSpeed); + + // Insert a false delay so files and stuff can be saved before the kernel kills us. + sceKernelDelayThread(50 * 1000); + + // Exit. + sceKernelExitGame(); +} + +double Sys_FloatTime (void) +{ + u64 ticks; + sceRtcGetCurrentTick(&ticks); + return ticks * 0.000001; +} + +char *Sys_ConsoleInput (void) +{ + return 0; +} + +void Sys_SendKeyEvents (void) +{ +} + +void Sys_LowFPPrecision (void) +{ +} + +void Sys_HighFPPrecision (void) +{ +} + +/* +================================================= +simplified findfirst/findnext implementation: +Sys_FindFirstFile and Sys_FindNextFile return +filenames only, not a dirent struct. this is +what we presently need in this engine. +================================================= +*/ + +static DIR *finddir; +static struct dirent *finddata; +static char *findpath, *findpattern; + +char *Sys_FindFirstFile (char *path, char *pattern); +void Sys_FindClose (void); +char *Sys_FindNextFile (void); + +char *Sys_FindFirstFile (char *path, char *pattern) +{ + size_t tmp_len; + + if (finddir) + Sys_Error ("Sys_FindFirst without FindClose"); + + finddir = opendir (path); + if (!finddir) + return NULL; + + tmp_len = strlen (pattern); + findpattern = (char*) malloc (tmp_len + 1); + if (!findpattern) + return NULL; + strcpy (findpattern, pattern); + findpattern[tmp_len] = '\0'; + tmp_len = strlen (path); + findpath = (char*) malloc (tmp_len + 1); + if (!findpath) + return NULL; + strcpy (findpath, path); + findpath[tmp_len] = '\0'; + + return Sys_FindNextFile(); +} + +char *Sys_FindNextFile (void) +{ + struct stat test; + + if (!finddir) + return NULL; + + do { + finddata = readdir(finddir); + if (finddata != NULL) + { + if (!fnmatch (findpattern, finddata->d_name, FNM_PATHNAME)) + { + if ( (stat(va("%s/%s", findpath, finddata->d_name), &test) == 0) && S_ISREG(test.st_mode) ) + return finddata->d_name; + } + } + } while (finddata != NULL); + + return NULL; +} + +void Sys_FindClose (void) +{ + if (finddir != NULL) + closedir(finddir); + if (findpath != NULL) + free (findpath); + if (findpattern != NULL) + free (findpattern); + finddir = NULL; + findpath = NULL; + findpattern = NULL; +} + diff --git a/r17/Revamped src/revamped_src/psp/system.hpp b/r17/Revamped src/revamped_src/psp/system.hpp new file mode 100755 index 00000000..0b64b5ab --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/system.hpp @@ -0,0 +1,37 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#ifndef QUAKE_SYSTEM_HPP +#define QUAKE_SYSTEM_HPP + +namespace quake +{ + namespace system + { + // Prepares the system for suspension. + void suspend(); + + // Restores the system after suspension. + void resume(); + } +} + +#endif diff --git a/r17/Revamped src/revamped_src/psp/video_hardware.cpp b/r17/Revamped src/revamped_src/psp/video_hardware.cpp new file mode 100755 index 00000000..e0256657 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_hardware.cpp @@ -0,0 +1,555 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ +#include +#include +#include + +#include +#include +#include +#include +#include +#include "m33libs/include/kubridge.h" + +extern "C" +{ +#include "../quakedef.h" +} + +#include "vram.hpp" + +#ifdef _WIN32 +# define ALIGNED(x) +#else +# define ALIGNED(x) __attribute__((aligned(x))) +#endif + +namespace quake +{ + namespace video + { + // Types. +#ifdef NORMAL_MODEL + typedef ScePspRGB565 pixel; +#else + typedef ScePspRGBA8888 pixel; +#endif + typedef u8 texel; + typedef u16 depth_value; + + // Constants. + static const std::size_t screen_width = 480; + static const std::size_t screen_height = 272; + static const std::size_t palette_size = 256; + static pixel* display_buffer = 0; + static pixel* draw_buffer = 0; + static depth_value* depth_buffer = 0; + + //! The GU display list. + //! @note Aligned to 64 bytes so it doesn't share a cache line with anything. + unsigned int ALIGNED(64) display_list[262144]; + } +} + +using namespace quake; +using namespace quake::video; + +// Regular globals. +ScePspRGBA8888 ALIGNED(16) d_8to24table[palette_size]; +ScePspRGBA8888 ALIGNED(16) d_8to24tableLM[palette_size]; +ScePspRGBA8888 ALIGNED(16) d_8to24tableSKY[palette_size]; + +void VID_InitPaleteSKY(unsigned char* palette) { + // Convert the palette to PSP format. + for (ScePspRGBA8888* color = &d_8to24tableSKY[0]; color < &d_8to24tableSKY[palette_size]; ++color) + { + const unsigned int r = *palette++; + const unsigned int g = *palette++; + const unsigned int b = *palette++; + *color = GU_RGBA(r, g, b, 0xff); + } + + // Upload the palette. + sceGuClutMode(GU_PSM_8888, 0, palette_size - 1, 0); + sceKernelDcacheWritebackRange(d_8to24tableSKY, sizeof(d_8to24tableSKY)); + sceGuClutLoad(palette_size / 8, d_8to24tableSKY); +} + +void VID_InitPaleteLM() { + // Convert the palette to PSP format. + ScePspRGBA8888* color2 = &d_8to24tableLM[0]; + for (unsigned int i=0; color2 < &d_8to24tableLM[palette_size]; ++color2, i++) + { + *color2 = GU_RGBA(i, i, i, i); + } +} + +void VID_SetPaletteSKY() { + // Upload the palette. + sceGuClutMode(GU_PSM_8888, 0, palette_size - 1, 0); + sceKernelDcacheWritebackRange(d_8to24tableSKY, sizeof(d_8to24tableSKY)); + sceGuClutLoad(palette_size / 8, d_8to24tableSKY); +} + +void VID_SetPaletteLM() { + // Upload the palette. + sceGuClutMode(GU_PSM_8888, 0, palette_size - 1, 0); + sceKernelDcacheWritebackRange(d_8to24tableLM, sizeof(d_8to24tableLM)); + sceGuClutLoad(palette_size / 8, d_8to24tableLM); +} + +void VID_SetPaletteTX() { + // Upload the palette. + sceGuClutMode(GU_PSM_8888, 0, palette_size - 1, 0); + sceKernelDcacheWritebackRange(d_8to24table, sizeof(d_8to24table)); + sceGuClutLoad(palette_size / 8, d_8to24table); +} + +void VID_SetPalette(unsigned char* palette) +{ + // Convert the palette to PSP format. + for (ScePspRGBA8888* color = &d_8to24table[0]; color < &d_8to24table[palette_size]; ++color) + { + const unsigned int r = *palette++; + const unsigned int g = *palette++; + const unsigned int b = *palette++; + *color = GU_RGBA(r, g, b, 0xff); + } + + // Make color 255 transparent black. + // This is a bit of a dirty hack. + d_8to24table[255] = 0; + + // Upload the palette. + sceGuClutMode(GU_PSM_8888, 0, palette_size - 1, 0); + sceKernelDcacheWritebackRange(d_8to24table, sizeof(d_8to24table)); + sceGuClutLoad(palette_size / 8, d_8to24table); +} + +void VID_ShiftPalette(unsigned char* palette) +{ + VID_SetPalette(palette); +} + +void VID_Init(unsigned char* palette) +{ + Sys_Printf("VID_Init\n"); + + // Allocate the buffers. + display_buffer = static_cast(vram::allocate(screen_height * 512 * sizeof(pixel))); + if (!display_buffer) + { + Sys_Error("Couldn't allocate display buffer"); + } + draw_buffer = static_cast(vram::allocate(screen_height * 512 * sizeof(pixel))); + if (!draw_buffer) + { + Sys_Error("Couldn't allocate draw buffer"); + } + depth_buffer = static_cast(vram::allocate(screen_height * 512 * sizeof(depth_value))); + if (!depth_buffer) + { + Sys_Error("Couldn't allocate depth buffer"); + } + + // Initialise the GU. + sceGuInit(); + + // Set up the GU. + sceGuStart(GU_DIRECT, display_list); + { + // Set the draw and display buffers. + void* const vram_base = sceGeEdramGetAddr(); + void* const display_buffer_in_vram = reinterpret_cast(display_buffer) - reinterpret_cast(vram_base); + void* const draw_buffer_in_vram = reinterpret_cast(draw_buffer) - reinterpret_cast(vram_base); + void* const depth_buffer_in_vram = reinterpret_cast(depth_buffer) - reinterpret_cast(vram_base); + +#ifdef NORMAL_MODEL + sceGuDrawBuffer(GU_PSM_5650, draw_buffer_in_vram, 512); +#else + sceGuDrawBuffer(GU_PSM_8888, draw_buffer_in_vram, 512); +#endif + + sceGuDispBuffer(screen_width, screen_height, display_buffer_in_vram, 512); + sceGuDepthBuffer(depth_buffer_in_vram, 512); + + // Set the rendering offset and viewport. + sceGuOffset(2048 - (screen_width / 2), 2048 - (screen_height / 2)); + sceGuViewport(2048, 2048, screen_width, screen_height); + + // Set up scissoring. + sceGuEnable(GU_SCISSOR_TEST); + sceGuScissor(0, 0, screen_width, screen_height); + + // Set up texturing. + sceGuEnable(GU_TEXTURE_2D); + + // Set up clearing. + sceGuClearDepth(65535); + sceGuClearColor(GU_COLOR(0.25f,0.25f,0.25f,0.5f)); + + // Set up depth. + sceGuDepthRange(0, 65535); + sceGuDepthFunc(GU_LEQUAL); + sceGuEnable(GU_DEPTH_TEST); + + // Set the matrices. + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + sceGumUpdateMatrix(); + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + sceGumUpdateMatrix(); + sceGumMatrixMode(GU_MODEL); + sceGumLoadIdentity(); + sceGumUpdateMatrix(); + + // Set up culling. + sceGuFrontFace(GU_CW); + sceGuEnable(GU_CULL_FACE); + sceGuEnable(GU_CLIP_PLANES); + + // Set up blending. + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + } + + sceGuFinish(); + sceGuSync(0,0); + + // Turn on the display. + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // Set up Quake's video parameters. + vid.aspect = (static_cast(screen_height) / static_cast(screen_width)) * (4.0f / 3.0f); + vid.buffer = 0; + vid.colormap = host_colormap; + vid.colormap16 = 0; + vid.conbuffer = 0; + vid.conheight = screen_height; + vid.conrowbytes = 0; + vid.conwidth = screen_width; + vid.direct = 0; + vid.fullbright = palette_size - LittleLong(*((int *) vid.colormap + 2048)); + vid.height = screen_height; + vid.maxwarpheight = screen_width; + vid.maxwarpwidth = screen_height; + vid.numpages = INT_MAX; + vid.recalc_refdef = 0; + vid.rowbytes = 0; + vid.width = screen_width; + + // Start a render. + sceGuStart(GU_DIRECT, display_list); + + // Set the palette. + VID_SetPalette(palette); + VID_InitPaleteLM(); + + Sys_Printf("VID_Init OK\n"); +} + +void VID_Shutdown(void) +{ + // Finish rendering. + sceGuFinish(); + sceGuSync(0,0); + + // Shut down the display. + sceGuTerm(); + + // Free the buffers. + vram::free(depth_buffer); + depth_buffer = 0; + vram::free(draw_buffer); + draw_buffer = 0; + vram::free(display_buffer); + display_buffer = 0; +} + +int DitherMatrix[2][16] = { { 0, 8, 2, 10, + 12, 4, 14, 6, + 3, 11, 1, 9, + 15, 7, 13, 5 }, + { 0, 8, 2, 10, + 12, 10, 14, 12, + 2, 9, 1, 11, + 14, 12, 13, 12 } }; + + /*{ { 0, 8, 0, 8, + 8, 0, 8, 0, + 0, 8, 0, 8, + 8, 0, 8, 0 }, + { 8, 0, 8, 0, + 0, 8, 0, 8, + 8, 0, 8, 0, + 0, 8, 0, 8 } };*/ + +void GL_BeginRendering (int *x, int *y, int *width, int *height) +{ + *x = 2048; + *y = 2048; + + if (r_antialias.value) + { + *width = screen_width + (r_framecount&1)*2; // For fake antialising effect + *height = screen_height + (r_framecount&1)*2; // For fake antialising effect + } + else + { + *width = screen_width; + *height = screen_height; + } + +// sceGuSetDither( (ScePspIMatrix4*)DitherMatrix[(r_framecount&1)] ); + + if (r_dithering.value) + sceGuEnable(GU_DITHER); + else + sceGuDisable(GU_DITHER); +} + +void GL_EndRendering (void) +{ + // Finish rendering. + sceGuFinish(); + sceGuSync(0, 0); + + // At the moment only do this if we are in network mode, once we get above + // 60fps we might as well leave it on for all games + if (tcpipAvailable || r_vsync.value) + sceDisplayWaitVblankStart(); + + // Switch the buffers. + sceGuSwapBuffers(); + std::swap(draw_buffer, display_buffer); + + // Start a new render. + sceGuStart(GU_DIRECT, display_list); +} + +void D_StartParticles (void) +{ + if (r_particles_simple.value == qtrue) { + sceGuDisable(GU_TEXTURE_2D); + } else { + GL_BindLM(particletexture); + + sceGuEnable(GU_ALPHA_TEST); + sceGuDepthMask(GU_TRUE); + sceGuEnable(GU_BLEND); + sceGuDisable(GU_FOG); + sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA); + + if (kurok) + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0xFFFFFFFF); + else + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + } +} + +void D_EndParticles (void) +{ + if (r_particles_simple.value == qtrue) { + sceGuEnable(GU_TEXTURE_2D); + } else { + sceGuDisable(GU_ALPHA_TEST); + sceGuDepthMask(GU_FALSE); + sceGuDisable(GU_BLEND); + sceGuEnable(GU_FOG); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + } +} + + + +static int BufIdx = 0; +static int BufSize = 0; + +psp_particle* D_CreateBuffer (int size) { + psp_particle* const vertices = static_cast(sceGuGetMemory(size*sizeof(psp_particle))); + + BufSize = size; + BufIdx = 0; + + return vertices; +} + + +void D_DeleteBuffer (psp_particle* vertices) { + if (BufIdx > 0) { + sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TEXTURE_32BITF|GU_COLOR_8888, BufIdx, 0, vertices); + BufIdx = 0; + BufSize = -1; + } + +} + +int D_DrawParticleBuffered (psp_particle* vertices, particle_t *pparticle, vec3_t up, vec3_t right, float scale) { + unsigned int color = d_8to24table[static_cast(pparticle->color)]; + int i = BufIdx; + + vertices[i].first.x = pparticle->org[0]; + vertices[i].first.y = pparticle->org[1]; + vertices[i].first.z = pparticle->org[2]; + vertices[i].first.s = 0.0; + vertices[i].first.t = 0.0; + vertices[i].first.color = color; + + vertices[i].second.x = pparticle->org[0] + scale*(up[0] + right[0]); + vertices[i].second.y = pparticle->org[1] + scale*(up[1] + right[1]); + vertices[i].second.z = pparticle->org[2] + scale*(up[2] + right[2]); + vertices[i].second.s = 1.0; + vertices[i].second.t = 1.0; + vertices[i].second.color = color; + + BufIdx++; + + if (BufIdx >= BufSize) { + sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TEXTURE_32BITF|GU_COLOR_8888, BufSize, 0, vertices); + BufIdx = 0; + BufSize = -1; + return -1; + } + + return BufIdx; +} + + +void D_DrawParticle (particle_t *pparticle, vec3_t up, vec3_t right, float scale) +{ + unsigned int color = d_8to24table[static_cast(pparticle->color)]; + + struct part_vertex { + float s, t; + unsigned int color; + float x, y, z; + }; + + part_vertex* const vertices = static_cast(sceGuGetMemory(2*sizeof(part_vertex))); + + vertices[0].x = pparticle->org[0]; + vertices[0].y = pparticle->org[1]; + vertices[0].z = pparticle->org[2]; + vertices[0].s = 0.0; + vertices[0].t = 0.0; + vertices[0].color = color; + + vertices[1].x = pparticle->org[0] + scale*(up[0] + right[0]); + vertices[1].y = pparticle->org[1] + scale*(up[1] + right[1]); + vertices[1].z = pparticle->org[2] + scale*(up[2] + right[2]); + vertices[1].s = 1.0; + vertices[1].t = 1.0; + vertices[1].color = color; + + sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TEXTURE_32BITF|GU_COLOR_8888, 2, 0, vertices); + +} + + +/* +============================================================================== + + SCREEN SHOTS + +============================================================================== +*/ + +typedef struct _TargaHeader { + unsigned char id_length, colormap_type, image_type; + unsigned short colormap_index, colormap_length; + unsigned char colormap_size; + unsigned short x_origin, y_origin, width, height; + unsigned char pixel_size, attributes; +} TargaHeader; + + +/* +================== +SCR_ScreenShot_f +================== +*/ +void SCR_ScreenShot_f (void) +{ + byte *buffer; + char pcxname[80]; + char checkname[MAX_OSPATH]; +// +// find a file name to save it to +// + if (kurok) + strcpy(pcxname,"sshot00.tga"); + else + strcpy(pcxname,"quake00.tga"); + + int i; + for (i=0 ; i<=99 ; i++) + { + pcxname[5] = i/10 + '0'; + pcxname[6] = i%10 + '0'; + sprintf (checkname, "%s/%s", com_gamedir, pcxname); + if (Sys_FileTime(checkname) == -1) + break; // file doesn't exist + } + if (i==100) + { + Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n"); + return; + } + + + buffer = static_cast(malloc(glwidth*glheight*3 + 18)); + memset (buffer, 0, 18); + buffer[2] = 2; // uncompressed type + buffer[12] = glwidth&255; + buffer[13] = glwidth>>8; + buffer[14] = glheight&255; + buffer[15] = glheight>>8; + buffer[16] = 24; // pixel size + + // Get the pixels and swap the colours from ARGB to BGR. + i = 18; + for (int y = 0; y < glheight; ++y) + { + const pixel* src = display_buffer + ((glheight - y - 1) * 512); + for (int x = 0; x < glwidth; ++x) + { + const pixel argb = *src++; + +#ifdef NORMAL_MODEL +// For RGB 565 pixel format + buffer[i++] = ((argb >> 11) & 0x1f) << 3; + buffer[i++] = ((argb >> 5) & 0x3f) << 2; + buffer[i++] = (argb & 0x1f) << 3; +#else +// For RGB 888 pixel format + buffer[i++] = (argb >> 16) & 0xff; + buffer[i++] = (argb >> 8) & 0xff; + buffer[i++] = argb & 0xff; +#endif + } + } + COM_WriteFile (pcxname, buffer, glwidth*glheight*3 + 18 ); + + free (buffer); + Con_Printf ("Wrote %s\n", pcxname); +} diff --git a/r17/Revamped src/revamped_src/psp/video_hardware.h b/r17/Revamped src/revamped_src/psp/video_hardware.h new file mode 100755 index 00000000..ebf11e53 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_hardware.h @@ -0,0 +1,268 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#include + +void GL_BeginRendering (int *x, int *y, int *width, int *height); +void GL_EndRendering (void); + +void GL_Upload8(int texture_index, const byte *data, int width, int height); +void GL_Upload16(int texture_index, const byte *data, int width, int height); +void GL_Upload24(int texture_index, const byte *data, int width, int height); +void GL_Upload32(int texture_index, const byte *data, int width, int height); +int GL_LoadTexture(const char *identifier, int width, int height, const byte *data, qboolean stretch_to_power_of_two, int filter, int mipmap_level); +int GL_LoadTextureLM (const char *identifier, int width, int height, const byte *data,int bpp, int filter, qboolean update); +void GL_UnloadTexture (const int texture_index); + +extern int glx, gly, glwidth, glheight; + +// r_local.h -- private refresh defs + +#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0) + // normalizing factor so player model works out to about + // 1 pixel per triangle +#define MAX_LBM_HEIGHT 480 + +#define TILE_SIZE 128 // size of textures generated by R_GenTiledSurf + +#define SKYSHIFT 7 +#define SKYSIZE (1 << SKYSHIFT) +#define SKYMASK (SKYSIZE - 1) + +#define BACKFACE_EPSILON 0.01 + +void R_TimeRefresh_f (void); +void R_ReadPointFile_f (void); +texture_t *R_TextureAnimation (texture_t *base); + +typedef struct surfcache_s +{ + struct surfcache_s *next; + struct surfcache_s **owner; // NULL is an empty chunk of memory + int lightadj[MAXLIGHTMAPS]; // checked for strobe flush + int dlight; + int size; // including header + unsigned width; + unsigned height; // DEBUG only needed for debug + float mipscale; + struct texture_s *texture; // checked for animating textures + byte data[4]; // width*height elements +} surfcache_t; + + +typedef struct +{ + pixel_t *surfdat; // destination for generated surface + int rowbytes; // destination logical width in bytes + msurface_t *surf; // description for surface to generate + fixed8_t lightadj[MAXLIGHTMAPS]; + // adjust for lightmap levels for dynamic lighting + texture_t *texture; // corrected for animating textures + int surfmip; // mipmapped ratio of surface texels / world pixels + int surfwidth; // in mipmapped texels + int surfheight; // in mipmapped texels +} drawsurf_t; + + +typedef enum { + pt_static, pt_grav, pt_slowgrav, pt_fire, pt_explode, pt_explode2, pt_blob, pt_blob2 +} ptype_t; + +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +typedef struct particle_s +{ +// driver-usable fields + vec3_t org; + float color; +// drivers never touch the following fields + struct particle_s *next; + vec3_t vel; + float ramp; + float die; + ptype_t type; +} particle_t; + +typedef struct cachepic_s +{ + char name[MAX_QPATH]; + qpic_t pic; + byte padding[32]; // for appended glpic +} cachepic_t; + +typedef struct +{ + int index; // index into gltextures[]. +} glpic_t; + +//==================================================== + + +extern entity_t r_worldentity; +extern qboolean r_cache_thrash; // compatability +extern vec3_t modelorg, r_entorigin; +extern entity_t *currententity; +extern int r_visframecount; // ??? what difs? +extern int r_framecount; +extern mplane_t frustum[4]; +extern int c_brush_polys, c_alias_polys; + + +// +// view origin +// +extern vec3_t vup; +extern vec3_t vpn; +extern vec3_t vright; +extern vec3_t r_origin; + +// +// screen size info +// +extern refdef_t r_refdef; +extern mleaf_t *r_viewleaf, *r_oldviewleaf; +extern texture_t *r_notexture_mip; +extern int d_lightstylevalue[256]; // 8.8 fraction of base light value + +extern int skyimage[6]; // Where sky images are stored +extern int lightmap_index[64]; // Where lightmaps are stored + +extern qboolean envmap; +extern int currenttexture; +extern int cnttextures[2]; +extern int particletexture; +extern int playertextures; + +extern int skytexturenum; // index in cl.loadmodel, not gl texture object + +extern cvar_t r_norefresh; +extern cvar_t r_drawentities; +extern cvar_t r_drawworld; +extern cvar_t r_drawviewmodel; +extern cvar_t r_speeds; +extern cvar_t r_waterwarp; +extern cvar_t r_fullbright; +extern cvar_t r_lightmap; +extern cvar_t r_shadows; +extern cvar_t r_mirroralpha; +extern cvar_t r_glassalpha; +extern cvar_t r_wateralpha; +extern cvar_t r_dynamic; +extern cvar_t r_novis; +extern cvar_t r_tex_scale_down; +extern cvar_t r_particles_simple; +extern cvar_t gl_keeptjunctions; +extern cvar_t r_i_model_animation; +extern cvar_t r_i_model_transform; +extern cvar_t r_model_contrast; +extern cvar_t r_model_brightness; +extern cvar_t fog; +extern cvar_t r_vsync; +extern cvar_t r_dithering; +extern cvar_t r_antialias; +extern cvar_t r_mipmaps; +extern cvar_t r_mipmaps_func; +extern cvar_t r_mipmaps_bias; +extern cvar_t r_skyclip; +extern cvar_t r_menufade; +extern cvar_t r_skyfog; +extern cvar_t r_showtris; +extern cvar_t r_test; + +extern cvar_t vlight; // RIOT - Vertex lighting +extern cvar_t vlight_pitch; +extern cvar_t vlight_yaw; +extern cvar_t vlight_lowcut; +extern cvar_t vlight_highcut; + +extern int mirrortexturenum; // quake texturenum, not gltexturenum +extern qboolean mirror; +extern mplane_t *mirror_plane; + +extern ScePspFMatrix4 r_world_matrix; + +void R_TranslatePlayerSkin (int playernum); +void GL_Bind (int texture_index); +void GL_BindLM (int texture_index); + +// Added by PM +int R_LightPoint (vec3_t p); +void R_DrawBrushModel (entity_t *e); +void R_AnimateLight (void); +void R_DrawWorld (void); +void R_RenderDlights (void); +void R_DrawParticles (void); +void R_DrawWaterSurfaces (void); +void R_RenderBrushPoly (msurface_t *fa); +void R_InitParticles (void); +void R_ClearParticles (void); +void R_Fog_f (void); + +void Sky_LoadSkyBox (char *name); +void Sky_NewMap (void); +void Sky_Init (void); + +void R_DrawSkyBox (void); +void R_ClearSkyBox (void); + +void Fog_ParseServerMessage (void); +void Fog_SetupFrame (void); +void Fog_EnableGFog (void); +void Fog_DisableGFog (void); +void Fog_NewMap (void); +void Fog_Init (void); + +void GL_BuildLightmaps (void); +void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr); +void GL_Set2D (void); +void GL_SubdivideSurface (msurface_t *fa); +void GL_Surface (msurface_t *fa); + +void EmitWaterPolys (msurface_t *fa); +void EmitSkyPolys (msurface_t *fa); +void EmitReflectivePolys (msurface_t *fa); +void EmitBothSkyLayers (msurface_t *fa); +void R_DrawSkyChain (msurface_t *s); +qboolean R_CullBox (vec3_t mins, vec3_t maxs); +void R_MarkLights (dlight_t *light, int bit, mnode_t *node); + +//extern float bubblecolor[NUM_DLIGHTTYPES][4]; + +void R_RotateForEntity (entity_t *e); +void R_StoreEfrags (efrag_t **ppefrag); +void D_StartParticles (void); +// void D_DrawParticle (particle_t *pparticle); +void D_DrawParticle (particle_t *pparticle, vec3_t up, vec3_t right, float scale); +void D_EndParticles (void); + +typedef struct { + float s, t; + unsigned int color; + float x, y, z; +} part_vertex; + +typedef struct { + part_vertex first, second; +} psp_particle; + + +psp_particle* D_CreateBuffer (int size); +void D_DeleteBuffer (psp_particle* vertices); +int D_DrawParticleBuffered (psp_particle* vertices, particle_t *pparticle, vec3_t up, vec3_t right, float scale); diff --git a/r17/Revamped src/revamped_src/psp/video_hardware_draw.cpp b/r17/Revamped src/revamped_src/psp/video_hardware_draw.cpp new file mode 100755 index 00000000..47508cc0 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_hardware_draw.cpp @@ -0,0 +1,1419 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +// draw.c -- this is the only file outside the refresh that touches the +// vid buffer + +#include +#include +#include +#include +#include +#include + +extern "C" +{ +#include "../quakedef.h" +} + +#include "vram.hpp" + +byte *draw_chars; // 8*8 graphic characters +qpic_t *draw_disc; +qpic_t *draw_backtile; + +int translate_texture; +int char_texture; + +bool tex_scale_down = true; + +typedef byte texel; + +typedef struct +{ + // Source. + char identifier[64]; + int original_width; + int original_height; + bool stretch_to_power_of_two; + + // Texture description. + int format; + int filter; + int width; + int height; + int mipmaps; + + // Buffers. + texel* ram; + texel* vram; +} gltexture_t; + +byte conback_buffer[sizeof(qpic_t) + sizeof(glpic_t)]; +qpic_t *conback = (qpic_t *)&conback_buffer; + +#define MAX_GLTEXTURES 1024 +gltexture_t gltextures[MAX_GLTEXTURES]; +bool gltextures_used[MAX_GLTEXTURES]; +int numgltextures; + +void GL_InitTextureUsage () { + for (int i=0; i 0 && r_mipmaps.value > 0) + { + float slope = 0.4f; + sceGuTexSlope(slope); // the near from 0 slope is the lower (=best detailed) mipmap it uses + sceGuTexFilter(GU_LINEAR_MIPMAP_LINEAR, GU_LINEAR_MIPMAP_LINEAR); + sceGuTexLevelMode(int(r_mipmaps_func.value), r_mipmaps_bias.value); + } + else + sceGuTexFilter(texture.filter, texture.filter); + + // Set the texture image. + const void* const texture_memory = texture.vram ? texture.vram : texture.ram; + sceGuTexImage(0, texture.width, texture.height, texture.width, texture_memory); + + if (texture.mipmaps > 0 && r_mipmaps.value > 0) { + int size = (texture.width * texture.height); + int offset = size; + int div = 2; + + for (int i = 1; i <= texture.mipmaps; i++) { + void* const texture_memory2 = ((byte*) texture_memory)+offset; + sceGuTexImage(i, texture.width/div, texture.height/div, texture.width/div, texture_memory2); + offset += size/(div*div); + div *=2; + } + } +} + +void GL_BindLM (int texture_index) +{ + // Binding the currently bound texture? + if (currenttexture == texture_index) + { + // Don't bother. + return; + } + + // Remember the current texture. + currenttexture = texture_index; + + // Which texture is it? + const gltexture_t& texture = gltextures[texture_index]; + + // Set the texture mode. + sceGuTexMode(texture.format, 0, 0, GU_FALSE); + sceGuTexFilter(texture.filter, texture.filter); + + // Set the texture image. + const void* const texture_memory = texture.vram ? texture.vram : texture.ram; + sceGuTexImage(0, texture.width, texture.height, texture.width, texture_memory); +} + + +//============================================================================= +/* Support Routines */ + +#define MAX_CACHED_PICS 128 +cachepic_t menu_cachepics[MAX_CACHED_PICS]; +int menu_numcachepics; + +byte menuplyr_pixels[4096]; + +static int GL_LoadPicTexture (qpic_t *pic) +{ + return GL_LoadTexture ("", pic->width, pic->height, pic->data, qfalse, GU_NEAREST, 0); +} + +qpic_t *Draw_PicFromWad (char *name) +{ + qpic_t *p; + glpic_t *gl; + + p = static_cast(W_GetLumpName (name)); + gl = (glpic_t *)p->data; + gl->index = GL_LoadPicTexture (p); + + return p; +} + + +/* +================ +Draw_CachePic +================ +*/ +qpic_t *Draw_CachePic (char *path) +{ + cachepic_t *pic; + int i; + qpic_t *dat; + glpic_t *gl; + + for (pic=menu_cachepics, i=0 ; iname)) + return &pic->pic; + + if (menu_numcachepics == MAX_CACHED_PICS) + Sys_Error ("menu_numcachepics == MAX_CACHED_PICS"); + menu_numcachepics++; + strcpy (pic->name, path); + +// +// load the pic from disk +// + dat = (qpic_t *)COM_LoadTempFile (path); + if (!dat) + Sys_Error ("Draw_CachePic: failed to load %s", path); + SwapPic (dat); + + // HACK HACK HACK --- we need to keep the bytes for + // the translatable player picture just for the menu + // configuration dialog + if (!strcmp (path, "gfx/menuplyr.lmp")) + memcpy (menuplyr_pixels, dat->data, dat->width*dat->height); + + pic->pic.width = dat->width; + pic->pic.height = dat->height; + + gl = (glpic_t *)pic->pic.data; + gl->index = GL_LoadPicTexture (dat); + + return &pic->pic; +} + + +static void Draw_CharToConback (int num, byte *dest) +{ + int row, col; + byte *source; + int drawline; + int x; + + row = num>>4; + col = num&15; + source = draw_chars + (row<<10) + (col<<3); + + drawline = 8; + + while (drawline--) + { + for (x=0 ; x<8 ; x++) + if (source[x] != 255) + dest[x] = 0x60 + source[x]; + source += 128; + dest += 320; + } + +} + +/* +=============== +Draw_Init +=============== +*/ +void Draw_Init (void) +{ + int i; + qpic_t *cb; + byte *dest; + int x, y; + char ver[40]; + glpic_t *gl; + int start; + byte *ncdata; + + // load the console background and the charset + // by hand, because we need to write the version + // string into the background before turning + // it into a texture + draw_chars = static_cast(W_GetLumpName ("conchars")); + for (i=0 ; i<256*64 ; i++) + if (draw_chars[i] == 0) + draw_chars[i] = 255; // proper transparent color + + // now turn them into textures + char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, qfalse, GU_NEAREST, 0); + + start = Hunk_LowMark(); + + cb = (qpic_t *)COM_LoadTempFile ("gfx/conback.lmp"); + if (!cb) + Sys_Error ("Couldn't load gfx/conback.lmp"); + SwapPic (cb); + + // hack the version number directly into the pic + if(!kurok) + { + sprintf (ver, "(gl %4.2f) %4.2f", (float)GLQUAKE_VERSION, (float)VERSION); + dest = cb->data + 320*186 + 320 - 11 - 8*strlen(ver); + y = strlen(ver); + for (x=0 ; xwidth = cb->width; + conback->height = cb->height; + ncdata = cb->data; + + gl = (glpic_t *)conback->data; + gl->index = GL_LoadTexture ("conback", conback->width, conback->height, ncdata, qfalse, GU_LINEAR, 0); + conback->width = vid.width; + conback->height = vid.height; + + // free loaded console + Hunk_FreeToLowMark(start); + + // save a texture slot for translated picture + // TODO Handle translating. + /*translate_texture = texture_extension_number++;*/ + +#if 0 + // save slots for scraps + scrap_texnum = texture_extension_number; + texture_extension_number += MAX_SCRAPS; +#endif + + // + // get the other pics we need + // + draw_disc = Draw_PicFromWad ("disc"); + draw_backtile = Draw_PicFromWad ("backtile"); +} + + + +/* +================ +Draw_Character + +Draws one 8*8 graphics character with 0 being transparent. +It can be clipped to the top of the screen to allow the console to be +smoothly scrolled off. +================ +*/ +void Draw_Character (int x, int y, int num) +{ + int row, col; + + if (num == 32) + return; // space + + num &= 255; + + if (y <= -8) + return; // totally off screen + + row = num>>4; + col = num&15; + + GL_Bind (char_texture); + + struct vertex + { + short u, v; + short x, y, z; + }; + + vertex* const vertices = static_cast(sceGuGetMemory(sizeof(vertex) * 2)); + + vertices[0].u = col * 8; + vertices[0].v = row * 8; + vertices[0].x = x; + vertices[0].y = y; + vertices[0].z = 0; + + vertices[1].u = (col + 1) * 8; + vertices[1].v = (row + 1) * 8; + vertices[1].x = x + 8; + vertices[1].y = y + 8; + vertices[1].z = 0; + + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, 0, vertices); +} + +/* +================ +Draw_String +================ +*/ +void Draw_String (int x, int y, char *str) +{ + while (*str) + { + Draw_Character (x, y, *str); + str++; + x += 8; + } +} + + +/* +============= +Draw_AlphaPic +============= +*/ +void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha) +{ + if (alpha != 1.0f) + { + sceGuTexFunc(GU_TFX_DECAL, GU_TCC_RGBA); + } + + glpic_t *gl; + +#if 0 + if (scrap_dirty) + Scrap_Upload (); +#endif + gl = (glpic_t *)pic->data; + GL_Bind (gl->index); + + struct vertex + { + short u, v; + short x, y, z; + }; + + vertex* const vertices = static_cast(sceGuGetMemory(sizeof(vertex) * 2)); + + vertices[0].u = 0; + vertices[0].v = 0; + vertices[0].x = x; + vertices[0].y = y; + vertices[0].z = 0; + + const gltexture_t& glt = gltextures[gl->index]; + vertices[1].u = glt.original_width; + vertices[1].v = glt.original_height; + vertices[1].x = x + pic->width; + vertices[1].y = y + pic->height; + vertices[1].z = 0; + + sceGuColor(GU_RGBA(0xff, 0xff, 0xff, static_cast(alpha * 255.0f))); + sceGuDrawArray( + GU_SPRITES, + GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, + 2, 0, vertices); + + if (alpha != 1.0f) + { + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + } +} +void Draw_Crosshair(void) +{ + extern cvar_t crosshair; + extern cvar_t cl_crossx; + extern cvar_t cl_crossy; + + extern cvar_t scr_fov; + + extern cvar_t in_x_axis_adjust; + extern cvar_t in_y_axis_adjust; + extern cvar_t in_freelook_analog; + extern cvar_t in_disable_analog; + extern cvar_t in_analog_strafe; + + qpic_t *pic; + + pic = 0; + + if (kurok) + { + // Read the pad state. + SceCtrlData pad; + sceCtrlPeekBufferPositive(&pad, 1); + + if (crosshair.value >= 2) + { + if (cl.stats[STAT_ACTIVEWEAPON] == IT_AXE) // Energy Sword + pic = Draw_CachePic ("gfx/ch/ch_sword.lmp"); + + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_SHOTGUN) // Pistol + pic = Draw_CachePic ("gfx/ch/ch_pistol.lmp"); + + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_SUPER_SHOTGUN) // Shotgun + pic = Draw_CachePic ("gfx/ch/ch_shottie.lmp"); + + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_NAILGUN) // Assualt rifle + pic = Draw_CachePic ("gfx/ch/ch_ar.lmp"); + + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_SUPER_NAILGUN) // Minigun + pic = Draw_CachePic ("gfx/ch/ch_smg.lmp"); + + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_GRENADE_LAUNCHER) // Grenade launcher + pic = Draw_CachePic ("gfx/ch/ch_ppist.lmp"); + + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_ROCKET_LAUNCHER) // Rocket launcher + pic = Draw_CachePic ("gfx/ch/ch_rl.lmp"); + + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_LIGHTNING) + pic = Draw_CachePic ("gfx/ch/ch_sniper.lmp"); + + else + pic = Draw_CachePic ("gfx/ch_sgun.lmp"); + + double crosshair_x = (vid.width - pic->width)/2 + cl_crossx.value + ((pad.Lx - 128) * in_x_axis_adjust.value * 0.05 ); + double crosshair_y = (vid.height - pic->height)/2 + cl_crossy.value + ((pad.Ly - 128) * in_y_axis_adjust.value * 0.05 ); + double crosshair_y_i = (vid.height - pic->height)/2 + cl_crossy.value - ((pad.Ly - 128) * in_y_axis_adjust.value * 0.05 ); + double crosshair_static_x = (vid.width - pic->width)/2 + cl_crossx.value; + double crosshair_static_y = (vid.height - pic->height)/2 + cl_crossy.value; + + if (scr_fov.value != 90) + { + if (!in_disable_analog.value) + { + if (in_freelook_analog.value) + { + if (m_pitch.value < 0) + Draw_Pic (int(crosshair_x), int(crosshair_y_i), pic); + else + Draw_Pic (int(crosshair_x), int(crosshair_y), pic); + } + else + { + if (!in_analog_strafe.value) + Draw_Pic (int(crosshair_x), int(crosshair_static_y), pic); + else + Draw_Pic (int(crosshair_static_x), int(crosshair_static_y), pic); + } + } + else + Draw_Pic (int(crosshair_static_x), int(crosshair_static_y), pic); + } + else + Draw_Pic (int(crosshair_static_x), int(crosshair_static_y), pic); + } + else if (crosshair.value) + Draw_Character ((vid.width - 8)/2, (vid.height - 8)/2, '.'); + } + else + { + if (crosshair.value == 1) +// Draw_Character (scr_vrect.x + scr_vrect.width/2 - 2, scr_vrect.y + scr_vrect.height/2 - 4, '+'); + Draw_Character ((vid.width - 8)/2, (vid.height - 8)/2, '+'); + else if (crosshair.value == 2) + Draw_Character ((vid.width - 8)/2, (vid.height - 8)/2, '.'); + } +} + +/* +============= +Draw_Pic +============= +*/ +void Draw_Pic (int x, int y, qpic_t *pic) +{ + Draw_AlphaPic(x, y, pic, 1.0f); +} + + +/* +============= +Draw_TransPic +============= +*/ +void Draw_TransPic (int x, int y, qpic_t *pic) +{ + if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 || + (unsigned)(y + pic->height) > vid.height) + { + Sys_Error ("Draw_TransPic: bad coordinates"); + } + + Draw_Pic (x, y, pic); +} + + +/* +============= +Draw_TransPicTranslate + +Only used for the player color selection menu +============= +*/ +void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation) +{ +/* + int v, u, c; + unsigned trans[64*64], *dest; + byte *src; + int p; + + GL_Bind (translate_texture); + + c = pic->width * pic->height; + + dest = trans; + for (v=0 ; v<64 ; v++, dest += 64) + { + src = &menuplyr_pixels[ ((v*pic->height)>>6) *pic->width]; + for (u=0 ; u<64 ; u++) + { + p = src[(u*pic->width)>>6]; + if (p == 255) + dest[u] = p; + else + dest[u] = d_8to24table[translation[p]]; + } + } + glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glColor3f (1,1,1); + glBegin (GL_QUADS); + glTexCoord2f (0, 0); + glVertex2f (x, y); + glTexCoord2f (1, 0); + glVertex2f (x+pic->width, y); + glTexCoord2f (1, 1); + glVertex2f (x+pic->width, y+pic->height); + glTexCoord2f (0, 1); + glVertex2f (x, y+pic->height); + glEnd ();*/ + + struct vertex + { + short u, v; + short x, y, z; + }; + + vertex* const vertices = static_cast(sceGuGetMemory(sizeof(vertex) * 2)); + + vertices[0].u = 0; + vertices[0].v = 0; + vertices[0].x = x; + vertices[0].y = y; + vertices[0].z = 0; + + vertices[1].u = 1; + vertices[1].v = 1; + vertices[1].x = x + pic->width; + vertices[1].y = y + pic->height; + vertices[1].z = 0; + + sceGuDisable(GU_TEXTURE_2D); + sceGuColor(GU_RGBA(0xff, 0, 0, 0xff)); + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, 0, vertices); + sceGuColor(0xffffffff); + sceGuEnable(GU_TEXTURE_2D); +} + + +/* +================ +Draw_ConsoleBackground + +================ +*/ +void Draw_ConsoleBackground (int lines) +{ + int y = (vid.height * 3) >> 2; + + if (lines > y) + Draw_Pic(0, lines - vid.height, conback); + else + Draw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y); +} + + +/* +============= +Draw_TileClear + +This repeats a 64*64 tile graphic to fill the screen around a sized down +refresh window. +============= +*/ +void Draw_TileClear (int x, int y, int w, int h) +{ + GL_Bind (*(int *)draw_backtile->data); + + struct vertex + { + short u, v; + short x, y, z; + }; + + vertex* const vertices = static_cast(sceGuGetMemory(sizeof(vertex) * 2)); + + vertices[0].u = x; + vertices[0].v = y; + vertices[0].x = x; + vertices[0].y = y; + vertices[0].z = 0; + + vertices[1].u = x + w; + vertices[1].v = y + h; + vertices[1].x = x + w; + vertices[1].y = y + h; + vertices[1].z = 0; + + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, 0, vertices); +} + + +/* +============= +Draw_Fill + +Fills a box of pixels with a single color +============= +*/ +void Draw_Fill (int x, int y, int w, int h, int c) +{ + struct vertex + { + short x, y, z; + }; + + vertex* const vertices = static_cast(sceGuGetMemory(sizeof(vertex) * 2)); + + vertices[0].x = x; + vertices[0].y = y; + vertices[0].z = 0; + + vertices[1].x = x + w; + vertices[1].y = y + h; + vertices[1].z = 0; + + sceGuDisable(GU_TEXTURE_2D); + sceGuColor(GU_RGBA(host_basepal[c*3], host_basepal[c*3+1], host_basepal[c*3+2], 0xff)); + sceGuDrawArray(GU_SPRITES, GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, 0, vertices); + sceGuColor(0xffffffff); + sceGuEnable(GU_TEXTURE_2D); +} +//============================================================================= + +/* +================ +Draw_FadeScreen + +================ +*/ +void Draw_FadeScreen (void) +{ + struct vertex + { + short x, y, z; + }; + + vertex* const vertices = static_cast(sceGuGetMemory(sizeof(vertex) * 2)); + + vertices[0].x = 0; + vertices[0].y = 0; + vertices[0].z = 0; + vertices[1].x = vid.width; + vertices[1].y = vid.height; + vertices[1].z = 0; + + sceGuDisable(GU_TEXTURE_2D); + + sceGuColor(GU_RGBA(0, 0, 0, 0x40)); + sceGuDrawArray( + GU_SPRITES, + GU_VERTEX_16BIT | GU_TRANSFORM_2D, + 2, 0, vertices); + + sceGuEnable(GU_TEXTURE_2D); + + Sbar_Changed(); +} + +/* +================ +Draw_FadeScreen2 + +================ +*/ +void Draw_FadeScreen2 (void) +{ + extern cvar_t r_menufade; + + Draw_AlphaPic (0, 0, conback, r_menufade.value); +} + +//============================================================================= + +/* +================ +Draw_FadeScreen + +================ +*/ +void Draw_FadeScreenColor (float r, float g, float b, float a) +{ + struct vertex + { + short x, y, z; + }; + + vertex* const vertices = static_cast(sceGuGetMemory(sizeof(vertex) * 2)); + + vertices[0].x = 0; + vertices[0].y = 0; + vertices[0].z = 0; + vertices[1].x = vid.width; + vertices[1].y = vid.height; + vertices[1].z = 0; + + sceGuDisable(GU_TEXTURE_2D); + + if (r > 1) + r = 1; + if (g > 1) + g = 1; + if (b > 1) + b = 1; + if (a > 1) + a = 1; + + sceGuColor(GU_COLOR(r, g, b, a * 1.0f)); + sceGuDrawArray( + GU_SPRITES, + GU_VERTEX_16BIT | GU_TRANSFORM_2D, + 2, 0, vertices); + + sceGuColor(0xffffffff); + + sceGuEnable(GU_TEXTURE_2D); + + Sbar_Changed(); +} + +//============================================================================= + +/* +================ +Draw_BeginDisc + +Draws the little blue disc in the corner of the screen. +Call before beginning any disc IO. +================ +*/ +void Draw_BeginDisc (void) +{ + if (!draw_disc) + return; + + //glDrawBuffer (GL_FRONT); + Draw_Pic (vid.width - 24, 0, draw_disc); + //glDrawBuffer (GL_BACK); +} + + +/* +================ +Draw_EndDisc + +Erases the disc icon. +Call after completing any disc IO +================ +*/ +void Draw_EndDisc (void) +{ +} + +/* +================ +GL_Set2D + +Setup as if the screen was 320*200 +================ +*/ +void GL_Set2D (void) +{ + sceGuViewport (glx, gly, glwidth, glheight); + sceGuScissor(0, 0, glwidth, glheight); + + sceGuEnable(GU_BLEND); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); +} + +static void GL_ResampleTexture(const byte *in, int inwidth, int inheight, unsigned char *out, int outwidth, int outheight) +{ + const unsigned int fracstep = inwidth * 0x10000 / outwidth; + for (int i = 0; i < outheight ; ++i, out += outwidth) + { + const byte* inrow = in + inwidth * (i * inheight / outheight); + unsigned int frac = fracstep >> 1; + for (int j = 0; j < outwidth; ++j, frac += fracstep) + { + out[j] = inrow[frac >> 16]; + } + } +} + +static void swizzle_fast(u8* out, const u8* in, unsigned int width, unsigned int height) +{ + unsigned int blockx, blocky; + unsigned int j; + + unsigned int width_blocks = (width / 16); + unsigned int height_blocks = (height / 8); + + unsigned int src_pitch = (width-16)/4; + unsigned int src_row = width * 8; + + const u8* ysrc = in; + u32* dst = (u32*)out; + + for (blocky = 0; blocky < height_blocks; ++blocky) + { + const u8* xsrc = ysrc; + for (blockx = 0; blockx < width_blocks; ++blockx) + { + const u32* src = (u32*)xsrc; + for (j = 0; j < 8; ++j) + { + *(dst++) = *(src++); + *(dst++) = *(src++); + *(dst++) = *(src++); + *(dst++) = *(src++); + src += src_pitch; + } + xsrc += 16; + } + ysrc += src_row; + } +} + +void GL_Upload8(int texture_index, const byte *data, int width, int height) +{ + if ((texture_index < 0) || (texture_index >= MAX_GLTEXTURES) || gltextures_used[texture_index] == false) + { + Sys_Error("Invalid texture index %d", texture_index); + } + + const gltexture_t& texture = gltextures[texture_index]; + + // Check that the texture matches. + if ((width != texture.original_width) != (height != texture.original_height)) + { + Sys_Error("Attempting to upload a texture which doesn't match the destination"); + } + + // Create a temporary buffer to use as a source for swizzling. + std::size_t buffer_size = texture.width * texture.height; + std::vector unswizzled(buffer_size); + + if (texture.mipmaps > 0) { + int size_incr = buffer_size/4; + for (int i= 1;i <= texture.mipmaps;i++) { + buffer_size += size_incr; + size_incr = size_incr/4; + } + } + + // Do we need to resize? + if (texture.stretch_to_power_of_two) + { + // Resize. + GL_ResampleTexture(data, width, height, &unswizzled[0], texture.width, texture.height); + } + else + { + // Straight copy. + for (int y = 0; y < height; ++y) + { + const byte* const src = data + (y * width); + byte* const dst = &unswizzled[y * texture.width]; + memcpy(dst, src, width); + } + } + + // Swizzle to system RAM. + swizzle_fast(texture.ram, &unswizzled[0], texture.width, texture.height); + + if (texture.mipmaps > 0) { + int size = (texture.width * texture.height); + int offset = size; + int div = 2; + + for (int i = 1; i <= texture.mipmaps;i++) { + GL_ResampleTexture(data, width, height, &unswizzled[0], texture.width/div, texture.height/div); + swizzle_fast(texture.ram+offset, &unswizzled[0], texture.width/div, texture.height/div); + offset += size/(div*div); + div *=2; + } + } + + unswizzled.clear(); + + // Copy to VRAM? + if (texture.vram) + { + // Copy. + memcpy(texture.vram, texture.ram, buffer_size); + + // Flush the data cache. + sceKernelDcacheWritebackRange(texture.vram, buffer_size); + } + + // Flush the data cache. + sceKernelDcacheWritebackRange(texture.ram, buffer_size); +} + +void GL_Upload8_A(int texture_index, const byte *data, int width, int height) +{ + if ((texture_index < 0) || (texture_index >= MAX_GLTEXTURES) || gltextures_used[texture_index] == false) + { + Sys_Error("Invalid texture index %d", texture_index); + } + + const gltexture_t& texture = gltextures[texture_index]; + + // Check that the texture matches. + if ((width != texture.original_width) != (height != texture.original_height)) + { + Sys_Error("Attempting to upload a texture which doesn't match the destination"); + } + + // Create a temporary buffer to use as a source for swizzling. + const std::size_t buffer_size = texture.width * texture.height; + memcpy((void *) texture.ram, (void *) data, buffer_size); + + // Copy to VRAM? + if (texture.vram) + { + // Copy. + memcpy(texture.vram, texture.ram, buffer_size); + + // Flush the data cache. + sceKernelDcacheWritebackRange(texture.vram, buffer_size); + } + + // Flush the data cache. + sceKernelDcacheWritebackRange(texture.ram, buffer_size); +} + +void GL_Upload16(int texture_index, const byte *data, int width, int height) +{ + if ((texture_index < 0) || (texture_index >= MAX_GLTEXTURES) || gltextures_used[texture_index] == false) + { + Sys_Error("Invalid texture index %d", texture_index); + } + + const gltexture_t& texture = gltextures[texture_index]; + + // Check that the texture matches. + if ((width != texture.original_width) != (height != texture.original_height)) + { + Sys_Error("Attempting to upload a texture which doesn't match the destination"); + } + + // Create a temporary buffer to use as a source for swizzling. + const std::size_t buffer_size = texture.width * texture.height * 2; + memcpy((void *) texture.ram, (void *) data, buffer_size); + + + // Copy to VRAM? + if (texture.vram) + { + // Copy. + memcpy(texture.vram, texture.ram, buffer_size); + + // Flush the data cache. + sceKernelDcacheWritebackRange(texture.vram, buffer_size); + } + + // Flush the data cache. + sceKernelDcacheWritebackRange(texture.ram, buffer_size); +} + +void GL_Upload24(int texture_index, const byte *data, int width, int height) +{ + if ((texture_index < 0) || (texture_index >= MAX_GLTEXTURES) || gltextures_used[texture_index] == false) + { + Sys_Error("Invalid texture index %d", texture_index); + } + + const gltexture_t& texture = gltextures[texture_index]; + + // Check that the texture matches. + if ((width != texture.original_width) != (height != texture.original_height)) + { + Sys_Error("Attempting to upload a texture which doesn't match the destination"); + } + + // Create a temporary buffer to use as a source for swizzling. + const std::size_t buffer_size = texture.width * texture.height * 3; + memcpy((void *) texture.ram, (void *) data, buffer_size); + + + // Copy to VRAM? + if (texture.vram) + { + // Copy. + memcpy(texture.vram, texture.ram, buffer_size); + + // Flush the data cache. + sceKernelDcacheWritebackRange(texture.vram, buffer_size); + } + + // Flush the data cache. + sceKernelDcacheWritebackRange(texture.ram, buffer_size); +} + +void GL_Upload32(int texture_index, const byte *data, int width, int height) +{ + if ((texture_index < 0) || (texture_index >= MAX_GLTEXTURES) || gltextures_used[texture_index] == false) + { + Sys_Error("Invalid texture index %d", texture_index); + } + + const gltexture_t& texture = gltextures[texture_index]; + + // Check that the texture matches. + if ((width != texture.original_width) != (height != texture.original_height)) + { + Sys_Error("Attempting to upload a texture which doesn't match the destination"); + } + + // Create a temporary buffer to use as a source for swizzling. + const std::size_t buffer_size = texture.width * texture.height * 4; + memcpy((void *) texture.ram, (void *) data, buffer_size); + + // Copy to VRAM? + if (texture.vram) + { + // Copy. + memcpy(texture.vram, texture.ram, buffer_size); + + // Flush the data cache. + sceKernelDcacheWritebackRange(texture.vram, buffer_size); + } + + // Flush the data cache. + sceKernelDcacheWritebackRange(texture.ram, buffer_size); +} + +static std::size_t round_up(std::size_t size) +{ + static const float denom = 1.0f / logf(2.0f); + const float logged = logf(size) * denom; + const float ceiling = ceilf(logged); + return 1 << static_cast(ceiling); +} + + +static std::size_t round_down(std::size_t size) +{ + static const float denom = 1.0f / logf(2.0f); + const float logged = logf(size) * denom; + const float floor = floorf(logged); + return 1 << static_cast(floor); +} + +void GL_UnloadTexture(int texture_index) { + if (gltextures_used[texture_index] == true) + { + gltexture_t& texture = gltextures[texture_index]; + + Con_DPrintf("Unloading: %s\n",texture.identifier); + // Source. + strcpy(texture.identifier,""); + texture.original_width = 0; + texture.original_height = 0; + texture.stretch_to_power_of_two = qfalse; + + // Texture description. + texture.format = GU_PSM_T8; + texture.filter = GU_LINEAR; + texture.width = 0; + texture.height = 0; + texture.mipmaps = 0; + // Buffers. + if (texture.ram != NULL) + { + free(texture.ram); + texture.ram = NULL; + } + if (texture.vram != NULL) + { + quake::vram::free(texture.vram); + texture.vram = NULL; + } + } + + gltextures_used[texture_index] = false; + numgltextures--; +} + +int GL_LoadTexture (const char *identifier, int width, int height, const byte *data, qboolean stretch_to_power_of_two, int filter, int mipmap_level) +{ + int texture_index = -1; + + tex_scale_down = r_tex_scale_down.value == qtrue; + // See if the texture is already present. + if (identifier[0]) + { + for (int i = 0; i < MAX_GLTEXTURES; ++i) + { + if (gltextures_used[i] == true) + { + const gltexture_t& texture = gltextures[i]; + if (!strcmp (identifier, texture.identifier)) + { + return i; + } + } + } + } + + // Out of textures? + if (numgltextures == MAX_GLTEXTURES) + { + Sys_Error("Out of OpenGL textures"); + } + + // Use the next available texture. + numgltextures++; + texture_index = numgltextures; + + for (int i = 0; i < MAX_GLTEXTURES; ++i) + { + if (gltextures_used[i] == false) { + texture_index = i; + break; + } + } + gltexture_t& texture = gltextures[texture_index]; + gltextures_used[texture_index] = true; + + // Fill in the source data. + strcpy(texture.identifier, identifier); + texture.original_width = width; + texture.original_height = height; + texture.stretch_to_power_of_two = stretch_to_power_of_two != qfalse; + + // Fill in the texture description. + texture.format = GU_PSM_T8; + texture.filter = filter; + texture.mipmaps = mipmap_level; + + if (tex_scale_down == true && texture.stretch_to_power_of_two == true) { + texture.width = std::max(round_down(width), 32U); + texture.height = std::max(round_down(height),32U); + } else { + texture.width = std::max(round_up(width), 32U); + texture.height = std::max(round_up(height),32U); + } + + for (int i=0; i <= mipmap_level;i++) { + int div = (int) powf(2,i); + if ((texture.width / div) > 16 && (texture.height / div) > 16 ) { + texture.mipmaps = i; + } + } + + // Do we really need to resize the texture? + if (texture.stretch_to_power_of_two) + { + // Not if the size hasn't changed. + texture.stretch_to_power_of_two = (texture.width != width) || (texture.height != height); + } + + Con_DPrintf("Loading: %s [%dx%d](%0.2f KB)\n",texture.identifier,texture.width,texture.height, (float) (texture.width*texture.height)/1024); + + // Allocate the RAM. + std::size_t buffer_size = texture.width * texture.height; + + if (texture.mipmaps > 0) { + int size_incr = buffer_size/4; + for (int i= 1;i <= texture.mipmaps;i++) { + buffer_size += size_incr; + size_incr = size_incr/4; + } + } + + texture.ram = static_cast(memalign(16, buffer_size)); + + if (!texture.ram) + { + Sys_Error("Out of RAM for textures."); + } + + // Allocate the VRAM. + texture.vram = static_cast(quake::vram::allocate(buffer_size)); + + // Upload the texture. + GL_Upload8(texture_index, data, width, height); + + if (texture.vram && texture.ram) { + free(texture.ram); + texture.ram = NULL; + } + // Done. + return texture_index; +} + +int GL_LoadTextureLM (const char *identifier, int width, int height, const byte *data, int bpp, int filter, qboolean update) +{ + tex_scale_down = r_tex_scale_down.value == qtrue; + int texture_index = -1; + // See if the texture is already present. + if (identifier[0]) + { + for (int i = 0; i < MAX_GLTEXTURES; ++i) + { + if (gltextures_used[i] == true) + { + const gltexture_t& texture = gltextures[i]; + if (!strcmp (identifier, texture.identifier)) + { + if (update == qfalse) { + return i; + } + else { + texture_index = i; + break; + } + } + } + } + } + + if (update == qfalse || texture_index == -1) { + // Out of textures? + if (numgltextures == MAX_GLTEXTURES) + { + Sys_Error("Out of OpenGL textures"); + } + + // Use the next available texture. + numgltextures++; + texture_index = numgltextures; + + for (int i = 0; i < MAX_GLTEXTURES; ++i) + { + if (gltextures_used[i] == false) { + texture_index = i; + break; + } + } + gltexture_t& texture = gltextures[texture_index]; + gltextures_used[texture_index] = true; + + // Fill in the source data. + strcpy(texture.identifier, identifier); + texture.original_width = width; + texture.original_height = height; + texture.stretch_to_power_of_two = false; + + // Fill in the texture description. + if (bpp == 1) + texture.format = GU_PSM_T8; + else if (bpp == 2) + texture.format = GU_PSM_4444; + else if (bpp == 3) + texture.format = GU_PSM_8888; + else if (bpp == 4) + texture.format = GU_PSM_8888; + + texture.filter = filter; + texture.mipmaps = 0; + + if (tex_scale_down == true && texture.stretch_to_power_of_two == true) { + texture.width = std::max(round_down(width), 16U); + texture.height = std::max(round_down(height), 16U); + } else { + texture.width = std::max(round_up(width), 16U); + texture.height = std::max(round_up(height), 16U); + } + + // Allocate the RAM. + const std::size_t buffer_size = texture.width * texture.height * bpp; + texture.ram = static_cast(memalign(16, buffer_size)); + if (!texture.ram) + { + Sys_Error("Out of RAM for lightmap textures."); + } + + // Allocate the VRAM. + texture.vram = static_cast(quake::vram::allocate(buffer_size)); + + // Upload the texture. + if (bpp == 1) + GL_Upload8_A(texture_index, data, width, height); + else if (bpp == 2) + GL_Upload16(texture_index, data, width, height); + else if (bpp == 3) + GL_Upload24(texture_index, data, width, height); + else if (bpp == 4) + GL_Upload32(texture_index, data, width, height); + + if (texture.vram && texture.ram) { + free(texture.ram); + texture.ram = NULL; + } + } + else { + gltexture_t& texture = gltextures[texture_index]; + + if ((width == texture.original_width) && + (height == texture.original_height)) { + + if (bpp == 1) + GL_Upload8_A(texture_index, data, width, height); + else if (bpp == 2) + GL_Upload16(texture_index, data, width, height); + else if (bpp == 3) + GL_Upload24(texture_index, data, width, height); + else if (bpp == 4) + GL_Upload32(texture_index, data, width, height); + } + + if (texture.vram && texture.ram) { + free(texture.ram); + texture.ram = NULL; + } + } + // Done. + return texture_index; +} diff --git a/r17/Revamped src/revamped_src/psp/video_hardware_entity_fragment.cpp b/r17/Revamped src/revamped_src/psp/video_hardware_entity_fragment.cpp new file mode 100755 index 00000000..22640755 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_hardware_entity_fragment.cpp @@ -0,0 +1,238 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ +// r_efrag.c + +extern "C" +{ +#include "../quakedef.h" +} + +mnode_t *r_pefragtopnode; + + +//=========================================================================== + +/* +=============================================================================== + + ENTITY FRAGMENT FUNCTIONS + +=============================================================================== +*/ + +efrag_t **lastlink; + +vec3_t r_emins, r_emaxs; + +entity_t *r_addent; + + +/* +================ +R_RemoveEfrags + +Call when removing an object from the world or moving it to another position +================ +*/ +void R_RemoveEfrags (entity_t *ent) +{ + efrag_t *ef, *old, *walk, **prev; + + ef = ent->efrag; + + while (ef) + { + prev = &ef->leaf->efrags; + while (1) + { + walk = *prev; + if (!walk) + break; + if (walk == ef) + { // remove this fragment + *prev = ef->leafnext; + break; + } + else + prev = &walk->leafnext; + } + + old = ef; + ef = ef->entnext; + + // put it on the free list + old->entnext = cl.free_efrags; + cl.free_efrags = old; + } + + ent->efrag = NULL; +} + +/* +=================== +R_SplitEntityOnNode +=================== +*/ +void R_SplitEntityOnNode (mnode_t *node) +{ + efrag_t *ef; + mplane_t *splitplane; + mleaf_t *leaf; + int sides; + + if (node->contents == CONTENTS_SOLID) + { + return; + } + +// add an efrag if the node is a leaf + + if ( node->contents < 0) + { + if (!r_pefragtopnode) + r_pefragtopnode = node; + + leaf = (mleaf_t *)node; + +// grab an efrag off the free list + ef = cl.free_efrags; + if (!ef) + { + Con_Printf ("Too many efrags!\n"); + return; // no free fragments... + } + cl.free_efrags = cl.free_efrags->entnext; + + ef->entity = r_addent; + +// add the entity link + *lastlink = ef; + lastlink = &ef->entnext; + ef->entnext = NULL; + +// set the leaf links + ef->leaf = leaf; + ef->leafnext = leaf->efrags; + leaf->efrags = ef; + + return; + } + +// NODE_MIXED + + splitplane = node->plane; + sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane); + + if (sides == 3) + { + // split on this plane + // if this is the first splitter of this bmodel, remember it + if (!r_pefragtopnode) + r_pefragtopnode = node; + } + +// recurse down the contacted sides + if (sides & 1) + R_SplitEntityOnNode (node->children[0]); + + if (sides & 2) + R_SplitEntityOnNode (node->children[1]); +} + + + +/* +=========== +R_AddEfrags +=========== +*/ +void R_AddEfrags (entity_t *ent) +{ + model_t *entmodel; + int i; + + if (!ent->model) + return; + + r_addent = ent; + + lastlink = &ent->efrag; + r_pefragtopnode = NULL; + + entmodel = ent->model; + + for (i=0 ; i<3 ; i++) + { + r_emins[i] = ent->origin[i] + entmodel->mins[i]; + r_emaxs[i] = ent->origin[i] + entmodel->maxs[i]; + } + + R_SplitEntityOnNode (cl.worldmodel->nodes); + + ent->topnode = r_pefragtopnode; +} + + +/* +================ +R_StoreEfrags + +// FIXME: a lot of this goes away with edge-based +================ +*/ +void R_StoreEfrags (efrag_t **ppefrag) +{ + entity_t *pent; + model_t *clmodel; + efrag_t *pefrag; + + + while ((pefrag = *ppefrag) != NULL) + { + pent = pefrag->entity; + clmodel = pent->model; + + switch (clmodel->type) + { + case mod_alias: + case mod_brush: + case mod_sprite: + pent = pefrag->entity; + + if ((pent->visframe != r_framecount) && + (cl_numvisedicts < MAX_VISEDICTS)) + { + cl_visedicts[cl_numvisedicts++] = pent; + + // mark that we've recorded this entity for this frame + pent->visframe = r_framecount; + } + + ppefrag = &pefrag->leafnext; + break; + + default: + Sys_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel->type); + } + } +} + + diff --git a/r17/Revamped src/revamped_src/psp/video_hardware_fog.cpp b/r17/Revamped src/revamped_src/psp/video_hardware_fog.cpp new file mode 100755 index 00000000..8cd7621d --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_hardware_fog.cpp @@ -0,0 +1,434 @@ +/* + +Kurok fogging system based on FitzQuake's implementation + +*/ + +extern "C" +{ +#include "../quakedef.h" +} + +#include + +//============================================================================== +// +// GLOBAL FOG +// +//============================================================================== + +extern refdef_t r_refdef; + +float old_start; +float old_end; +float old_red; +float old_green; +float old_blue; + +float fade_time; //duration of fade +float fade_done; //time when fade will be done + +/* +============= +Fog_Update + +update internal variables +============= +*/ +void Fog_Update (float start, float end, float red, float green, float blue, float time) +{ + //save previous settings for fade + if (time > 0) + { + //check for a fade in progress + if (fade_done > cl.time) + { + float f; + + f = (fade_done - cl.time) / fade_time; + old_start = f * old_start + (1.0 - f) * r_refdef.fog_start; + old_end = f * old_end + (1.0 - f) * r_refdef.fog_end; + old_red = f * old_red + (1.0 - f) * r_refdef.fog_red; + old_green = f * old_green + (1.0 - f) * r_refdef.fog_green; + old_blue = f * old_blue + (1.0 - f) * r_refdef.fog_blue; + } + else + { + old_start = r_refdef.fog_start; + old_end = r_refdef.fog_end; + old_red = r_refdef.fog_red; + old_green = r_refdef.fog_green; + old_blue = r_refdef.fog_blue; + } + } + + r_refdef.fog_start = start; + r_refdef.fog_end = end; + r_refdef.fog_red = red; + r_refdef.fog_green = green; + r_refdef.fog_blue = blue; + fade_time = time; + fade_done = cl.time + time; +} + +/* +============= +Fog_ParseServerMessage + +handle an SVC_FOG message from server +============= +*/ +void Fog_ParseServerMessage (void) +{ + float start, end, red, green, blue, time; + + start = MSG_ReadByte() / 255.0; + end = MSG_ReadByte() / 255.0; + red = MSG_ReadByte() / 255.0; + green = MSG_ReadByte() / 255.0; + blue = MSG_ReadByte() / 255.0; + time = MSG_ReadShort() / 100.0; + + Fog_Update (start, end, red, green, blue, time); +} + +/* +============= +Fog_FogCommand_f + +handle the 'fog' console command +============= +*/ +void Fog_FogCommand_f (void) +{ + switch (Cmd_Argc()) + { + default: + case 1: + Con_Printf("usage:\n"); + Con_Printf(" fog \n"); + Con_Printf(" fog \n"); + Con_Printf(" fog \n"); + Con_Printf(" fog \n"); + Con_Printf(" fog \n"); + Con_Printf(" fog \n"); + Con_Printf("current values:\n"); + Con_Printf(" \"start\" is \"%f\"\n", r_refdef.fog_start); + Con_Printf(" \"end\" is \"%f\"\n", r_refdef.fog_end); + Con_Printf(" \"red\" is \"%f\"\n", r_refdef.fog_red); + Con_Printf(" \"green\" is \"%f\"\n", r_refdef.fog_green); + Con_Printf(" \"blue\" is \"%f\"\n", r_refdef.fog_blue); + Con_Printf(" \"fade\" is \"%f\"\n", fade_time); + break; + case 2: //TEST + Fog_Update(r_refdef.fog_start, + r_refdef.fog_end, + r_refdef.fog_red, + r_refdef.fog_green, + r_refdef.fog_blue, + atof(Cmd_Argv(1))); + break; + case 3: + Fog_Update(atof(Cmd_Argv(1)), + atof(Cmd_Argv(2)), + r_refdef.fog_red, + r_refdef.fog_green, + r_refdef.fog_blue, + 0.0); + break; + case 4: + Fog_Update(r_refdef.fog_start, + r_refdef.fog_end, + CLAMP(0.0, atof(Cmd_Argv(1)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(2)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(3)), 100.0), + 0.0); + break; + case 5: //TEST + Fog_Update(r_refdef.fog_start, + r_refdef.fog_end, + CLAMP(0.0, atof(Cmd_Argv(1)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(2)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(3)), 100.0), + atof(Cmd_Argv(4))); + break; + case 6: + Fog_Update(atof(Cmd_Argv(1)), + atof(Cmd_Argv(2)), + CLAMP(0.0, atof(Cmd_Argv(3)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(4)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(5)), 100.0), + 0.0); + break; + case 7: + Fog_Update(atof(Cmd_Argv(1)), + atof(Cmd_Argv(2)), + CLAMP(0.0, atof(Cmd_Argv(3)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(4)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(5)), 100.0), + atof(Cmd_Argv(6))); + break; + } +} + +/* +============= +Fog_ParseWorldspawn + +called at map load +============= +*/ +void Fog_ParseWorldspawn (void) +{ + char key[128], value[4096]; + char *data; + + //initially no fog + r_refdef.fog_start = 0; + old_start = 0; + + r_refdef.fog_end = -1; + old_end = -1; + + r_refdef.fog_red = 0.0; + old_red = 0.0; + + r_refdef.fog_green = 0.0; + old_green = 0.0; + + r_refdef.fog_blue = 0.0; + old_blue = 0.0; + + fade_time = 0.0; + fade_done = 0.0; + + data = COM_Parse(cl.worldmodel->entities); + if (!data) + return; // error + if (com_token[0] != '{') + return; // error + while (1) + { + data = COM_Parse(data); + if (!data) + return; // error + if (com_token[0] == '}') + break; // end of worldspawn + if (com_token[0] == '_') + strcpy(key, com_token + 1); + else + strcpy(key, com_token); + while (key[strlen(key)-1] == ' ') // remove trailing spaces + key[strlen(key)-1] = 0; + data = COM_Parse(data); + if (!data) + return; // error + strcpy(value, com_token); + + if (!strcmp("fog", key)) + { + sscanf(value, "%f %f %f %f %f", &r_refdef.fog_start, &r_refdef.fog_end, &r_refdef.fog_red, &r_refdef.fog_green, &r_refdef.fog_blue); + } + } +} + +/* +============= +Fog_SetupFrame + +called at the beginning of each frame +============= +*/ +void Fog_SetupFrame (void) +{ + float c[4]; + float f, s, e; + + if (fade_done > cl.time) + { + f = (fade_done - cl.time) / fade_time; + s = f * old_start + (1.0 - f) * r_refdef.fog_start; + e = f * old_end + (1.0 - f) * r_refdef.fog_end; + c[0] = f * old_red + (1.0 - f) * r_refdef.fog_red; + c[1] = f * old_green + (1.0 - f) * r_refdef.fog_green; + c[2] = f * old_blue + (1.0 - f) * r_refdef.fog_blue; + c[3] = 1.0; + } + else + { + s = r_refdef.fog_start; + e = r_refdef.fog_end; + c[0] = r_refdef.fog_red; + c[1] = r_refdef.fog_green; + c[2] = r_refdef.fog_blue; + c[3] = 1.0; + } + + if(e == 0) + e = -1; + + sceGuFog ( s, e, GU_COLOR( c[0]* 0.01f, c[1]* 0.01f, c[2]* 0.01f, c[3] ) ); + + if(s == 0 || e < 0) + sceGuDisable(GU_FOG); +} + +/* +============= +Fog_GetStart + +returns current start of fog +============= +*/ +float Fog_GetStart (void) +{ + float f; + + if (fade_done > cl.time) + { + f = (fade_done - cl.time) / fade_time; + return f * old_start + (1.0 - f) * r_refdef.fog_start; + } + else + return r_refdef.fog_start; +} + +/* +============= +Fog_GetEnd + +returns current end of fog +============= +*/ +float Fog_GetEnd (void) +{ + float f; + + if (fade_done > cl.time) + { + f = (fade_done - cl.time) / fade_time; + return f * old_start + (1.0 - f) * r_refdef.fog_end; + } + else + return r_refdef.fog_end; +} + +/* +============= +Fog_EnableGFog + +called before drawing stuff that should be fogged +============= +*/ +void Fog_EnableGFog (void) +{ + if (!Fog_GetStart() == 0 || !Fog_GetEnd() <= 0) + sceGuEnable(GU_FOG); +} + +/* +============= +Fog_DisableGFog + +called after drawing stuff that should be fogged +============= +*/ +void Fog_DisableGFog (void) +{ + if (!Fog_GetStart() == 0 || !Fog_GetEnd() <= 0) + sceGuDisable(GU_FOG); +} + +/* +============= +Fog_SetColorForSky + +called before drawing flat-colored sky +============= +*/ +/* +void Fog_SetColorForSky (void) +{ + float c[3]; + float f, d; + + if (fade_done > cl.time) + { + f = (fade_done - cl.time) / fade_time; + d = f * old_density + (1.0 - f) * fog_density; + c[0] = f * old_red + (1.0 - f) * fog_red; + c[1] = f * old_green + (1.0 - f) * fog_green; + c[2] = f * old_blue + (1.0 - f) * fog_blue; + } + else + { + d = fog_density; + c[0] = fog_red; + c[1] = fog_green; + c[2] = fog_blue; + } + + if (d > 0) + glColor3fv (c); +} +*/ +//============================================================================== +// +// VOLUMETRIC FOG +// +//============================================================================== +/* +cvar_t r_vfog = {"r_vfog", "1"}; + +void Fog_DrawVFog (void){} +void Fog_MarkModels (void){} +*/ +//============================================================================== +// +// INIT +// +//============================================================================== + +/* +============= +Fog_NewMap + +called whenever a map is loaded +============= +*/ + +void Fog_NewMap (void) +{ + Fog_ParseWorldspawn (); //for global fog +// Fog_MarkModels (); //for volumetric fog +} + +/* +============= +Fog_Init + +called when quake initializes +============= +*/ +void Fog_Init (void) +{ + Cmd_AddCommand ("fog",Fog_FogCommand_f); + + //Cvar_RegisterVariable (&r_vfog, NULL); + + //set up global fog + r_refdef.fog_start = 0; + r_refdef.fog_end = -1; + r_refdef.fog_red = 0.5; + r_refdef.fog_green = 0.5; + r_refdef.fog_blue = 0.5; + fade_time = 1; +/* +#ifdef FOGEXP2 + glFogi(GL_FOG_MODE, GL_EXP2); +#else + glFogi(GL_FOG_START, 0); + glFogi(GL_FOG_MODE, GL_LINEAR); +#endif +*/ +} diff --git a/r17/Revamped src/revamped_src/psp/video_hardware_light.cpp b/r17/Revamped src/revamped_src/psp/video_hardware_light.cpp new file mode 100755 index 00000000..c6ff9451 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_hardware_light.cpp @@ -0,0 +1,554 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ +// r_light.c + +extern "C" +{ +#include "../quakedef.h" +} + +int r_dlightframecount; + + +/* +================== +R_AnimateLight +================== +*/ +void R_AnimateLight (void) +{ + int i,j,k; + +// +// light animations +// 'm' is normal light, 'a' is no light, 'z' is double bright + i = (int)(cl.time*10); + for (j=0 ; jradius * 0.35; + + VectorSubtract (light->origin, r_origin, v); + if (Length (v) < rad) + { // view is inside the dlight + AddLightBlend (1, 0.5, 0, light->radius * 0.0003); + return; + } +*/ + /* + glBegin (GL_TRIANGLE_FAN); + glColor3f (0.2,0.1,0.0); + for (i=0 ; i<3 ; i++) + v[i] = light->origin[i] - vpn[i]*rad; + glVertex3fv (v); + glColor3f (0,0,0); + for (i=16 ; i>=0 ; i--) + { + a = i/16.0 * M_PI*2; + for (j=0 ; j<3 ; j++) + v[j] = light->origin[j] + vright[j]*cosf(a)*rad + + vup[j]*sinf(a)*rad; + glVertex3fv (v); + } + glEnd (); + */ +} + +/* +============= +R_RenderDlights +============= +*/ +void R_RenderDlights (void) +{ +// int i; +// dlight_t *l; + + r_dlightframecount = r_framecount + 1; // because the count hasn't + // advanced yet for this frame + /*glDepthMask (0); + glDisable (GL_TEXTURE_2D); + glShadeModel (GL_SMOOTH); + glEnable (GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE); + + l = cl_dlights; + for (i=0 ; idie < cl.time || !l->radius) + continue; + R_RenderDlight (l); + } + + glColor3f (1,1,1); + glDisable (GL_BLEND); + glEnable (GL_TEXTURE_2D); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask (1);*/ +} + + +/* +============================================================================= + +DYNAMIC LIGHTS + +============================================================================= +*/ + +/* +============= +R_MarkLights +============= +*/ +/* +void R_MarkLights (dlight_t *light, int bit, mnode_t *node) +{ + mplane_t *splitplane; + float dist; + msurface_t *surf; + int i; + + if (node->contents < 0) + return; + + splitplane = node->plane; + dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; + + if (dist > light->radius) + { + R_MarkLights (light, bit, node->children[0]); + return; + } + if (dist < -light->radius) + { + R_MarkLights (light, bit, node->children[1]); + return; + } + +// mark the polygons + surf = cl.worldmodel->surfaces + node->firstsurface; + for (i=0 ; inumsurfaces ; i++, surf++) + { + if (surf->dlightframe != r_dlightframecount) + { + surf->dlightbits = 0; + surf->dlightframe = r_dlightframecount; + } + surf->dlightbits |= bit; + } + + R_MarkLights (light, bit, node->children[0]); + R_MarkLights (light, bit, node->children[1]); +} +*/ + +void R_MarkLights (dlight_t *light, int bit, mnode_t *node) +{ + mplane_t *splitplane; + float dist, l, maxdist; + msurface_t *surf; + int i, j, s, t, sidebit; + vec3_t impact; + +loc0: + if (node->contents < 0) + return; + + splitplane = node->plane; +// dist = PlaneDiff(light->origin, splitplane); + + if (splitplane->type < 3) + dist = light->origin[splitplane->type] - splitplane->dist; + else + dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; + + if (dist > light->radius) + { + node = node->children[0]; + goto loc0; + } + if (dist < -light->radius) + { + node = node->children[1]; + goto loc0; + } + + maxdist = light->radius * light->radius; +// mark the polygons + surf = cl.worldmodel->surfaces + node->firstsurface; + for (i=0 ; inumsurfaces ; i++, surf++) + { + dist = DotProduct (light->origin, surf->plane->normal) - surf->plane->dist; // JT030305 - fix light bleed through + if (dist >= 0) + sidebit = 0; + else + sidebit = SURF_PLANEBACK; + + if ( (surf->flags & SURF_PLANEBACK) != sidebit ) //Discoloda + continue; //Discoloda + + for (j=0 ; j<3 ; j++) + impact[j] = light->origin[j] - surf->plane->normal[j]*dist; + + // clamp center of light to corner and check brightness + l = DotProduct(impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; + s = l + 0.5; + s = bound(0, s, surf->extents[0]); + s = l - s; + l = DotProduct(impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1]; + t = l + 0.5; + t = bound(0, t, surf->extents[1]); + t = l - t; + + // compare to minimum light + if ((s*s + t*t + dist*dist) < maxdist) + { + if (surf->dlightframe != r_dlightframecount) // not dynamic until now + { + surf->dlightbits = bit; + surf->dlightframe = r_dlightframecount; + } + else // already dynamic + { + surf->dlightbits |= bit; + } + } + } + if (node->children[0]->contents >= 0) + R_MarkLights (light, bit, node->children[0]); + if (node->children[1]->contents >= 0) + R_MarkLights (light, bit, node->children[1]); +} + + +/* +============= +R_PushDlights +============= +*/ +void R_PushDlights (void) +{ + int i; + dlight_t *l; + + r_dlightframecount = r_framecount + 1; // because the count hasn't + // advanced yet for this frame + l = cl_dlights; + + for (i=0 ; idie < cl.time || !l->radius) + continue; + R_MarkLights ( l, 1<nodes ); + } +} + + +/* +============================================================================= + +LIGHT SAMPLING + +============================================================================= +*/ + +mplane_t *lightplane; +vec3_t lightspot; + +/* +int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) +{ + int r; + float front, back, frac; + int side; + mplane_t *plane; + vec3_t mid; + msurface_t *surf; + int s, t, ds, dt; + int i; + mtexinfo_t *tex; + byte *lightmap; + unsigned scale; + int maps; + + if (node->contents < 0) + return -1; // didn't hit anything + +// calculate mid point + +// FIXME: optimize for axial + plane = node->plane; + front = DotProduct (start, plane->normal) - plane->dist; + back = DotProduct (end, plane->normal) - plane->dist; + side = front < 0; + + if ( (back < 0) == side) + return RecursiveLightPoint (node->children[side], start, end); + + frac = front / (front-back); + mid[0] = start[0] + (end[0] - start[0])*frac; + mid[1] = start[1] + (end[1] - start[1])*frac; + mid[2] = start[2] + (end[2] - start[2])*frac; + +// go down front side + r = RecursiveLightPoint (node->children[side], start, mid); + if (r >= 0) + return r; // hit something + + if ( (back < 0) == side ) + return -1; // didn't hit anuthing + +// check for impact on this node + VectorCopy (mid, lightspot); + lightplane = plane; + + surf = cl.worldmodel->surfaces + node->firstsurface; + for (i=0 ; inumsurfaces ; i++, surf++) + { + if (surf->flags & SURF_DRAWTILED) + continue; // no lightmaps + + tex = surf->texinfo; + + s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3]; + t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];; + + if (s < surf->texturemins[0] || + t < surf->texturemins[1]) + continue; + + ds = s - surf->texturemins[0]; + dt = t - surf->texturemins[1]; + + if ( ds > surf->extents[0] || dt > surf->extents[1] ) + continue; + + if (!surf->samples) + return 0; + + ds >>= 4; + dt >>= 4; + + lightmap = surf->samples; + r = 0; + if (lightmap) + { + + lightmap += dt * ((surf->extents[0]>>4)+1) + ds; + + for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + r += *lightmap * scale; + lightmap += ((surf->extents[0]>>4)+1) * + ((surf->extents[1]>>4)+1); + } + + r >>= 8; + } + + return r; + } + +// go down back side + return RecursiveLightPoint (node->children[!side], mid, end); +} + +int R_LightPoint (vec3_t p) +{ + vec3_t end; + int r; + + if (!cl.worldmodel->lightdata) + return 255; + + end[0] = p[0]; + end[1] = p[1]; + end[2] = p[2] - 2048; + + r = RecursiveLightPoint (cl.worldmodel->nodes, p, end); + + if (r == -1) + r = 0; + + return r; +} +*/ + +// LordHavoc: .lit support begin +// LordHavoc: original code replaced entirely +int RecursiveLightPoint (vec3_t color, mnode_t *node, vec3_t start, vec3_t end) +{ + float front, back, frac; + vec3_t mid; + +loc0: + if (node->contents < 0) + return false; // didn't hit anything + +// calculate mid point + if (node->plane->type < 3) + { + front = start[node->plane->type] - node->plane->dist; + back = end[node->plane->type] - node->plane->dist; + } + else + { + front = DotProduct(start, node->plane->normal) - node->plane->dist; + back = DotProduct(end, node->plane->normal) - node->plane->dist; + } + + // LordHavoc: optimized recursion + if ((back < 0) == (front < 0)) +// return RecursiveLightPoint (color, node->children[front < 0], start, end); + { + node = node->children[front < 0]; + goto loc0; + } + + frac = front / (front-back); + mid[0] = start[0] + (end[0] - start[0])*frac; + mid[1] = start[1] + (end[1] - start[1])*frac; + mid[2] = start[2] + (end[2] - start[2])*frac; + +// go down front side + if (RecursiveLightPoint (color, node->children[front < 0], start, mid)) + return true; // hit something + else + { + int i, ds, dt; + msurface_t *surf; + // check for impact on this node + VectorCopy (mid, lightspot); + lightplane = node->plane; + + surf = cl.worldmodel->surfaces + node->firstsurface; + for (i = 0;i < node->numsurfaces;i++, surf++) + { + if (surf->flags & SURF_DRAWTILED) + continue; // no lightmaps + + ds = (int) ((float) DotProduct (mid, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]); + dt = (int) ((float) DotProduct (mid, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]); + + if (ds < surf->texturemins[0] || dt < surf->texturemins[1]) + continue; + + ds -= surf->texturemins[0]; + dt -= surf->texturemins[1]; + + if (ds > surf->extents[0] || dt > surf->extents[1]) + continue; + + if (surf->samples) + { + // LordHavoc: enhanced to interpolate lighting + byte *lightmap; + int maps, line3, dsfrac = ds & 15, dtfrac = dt & 15, r00 = 0, g00 = 0, b00 = 0, r01 = 0, g01 = 0, b01 = 0, r10 = 0, g10 = 0, b10 = 0, r11 = 0, g11 = 0, b11 = 0; + float scale; + line3 = ((surf->extents[0]>>4)+1)*3; + + lightmap = surf->samples + ((dt>>4) * ((surf->extents[0]>>4)+1) + (ds>>4))*3; // LordHavoc: *3 for color + + for (maps = 0;maps < MAXLIGHTMAPS && surf->styles[maps] != 255;maps++) + { + scale = (float) d_lightstylevalue[surf->styles[maps]] * 1.0 / 256.0; + r00 += (float) lightmap[ 0] * scale;g00 += (float) lightmap[ 1] * scale;b00 += (float) lightmap[2] * scale; + r01 += (float) lightmap[ 3] * scale;g01 += (float) lightmap[ 4] * scale;b01 += (float) lightmap[5] * scale; + r10 += (float) lightmap[line3+0] * scale;g10 += (float) lightmap[line3+1] * scale;b10 += (float) lightmap[line3+2] * scale; + r11 += (float) lightmap[line3+3] * scale;g11 += (float) lightmap[line3+4] * scale;b11 += (float) lightmap[line3+5] * scale; + lightmap += ((surf->extents[0]>>4)+1) * ((surf->extents[1]>>4)+1)*3; // LordHavoc: *3 for colored lighting + } + + color[0] += (float) ((int) ((((((((r11-r10) * dsfrac) >> 4) + r10)-((((r01-r00) * dsfrac) >> 4) + r00)) * dtfrac) >> 4) + ((((r01-r00) * dsfrac) >> 4) + r00))); + color[1] += (float) ((int) ((((((((g11-g10) * dsfrac) >> 4) + g10)-((((g01-g00) * dsfrac) >> 4) + g00)) * dtfrac) >> 4) + ((((g01-g00) * dsfrac) >> 4) + g00))); + color[2] += (float) ((int) ((((((((b11-b10) * dsfrac) >> 4) + b10)-((((b01-b00) * dsfrac) >> 4) + b00)) * dtfrac) >> 4) + ((((b01-b00) * dsfrac) >> 4) + b00))); + } + return true; // success + } + + // go down back side + return RecursiveLightPoint (color, node->children[front >= 0], mid, end); + } +} + +vec3_t lightcolor; // LordHavoc: used by model rendering +int R_LightPoint (vec3_t p) +{ + vec3_t end; + + if (r_fullbright.value || !cl.worldmodel->lightdata) + { + lightcolor[0] = lightcolor[1] = lightcolor[2] = 255; + return 255; + } + + end[0] = p[0]; + end[1] = p[1]; + end[2] = p[2] - 2048; + + lightcolor[0] = lightcolor[1] = lightcolor[2] = 0; + RecursiveLightPoint (lightcolor, cl.worldmodel->nodes, p, end); + return ((lightcolor[0] + lightcolor[1] + lightcolor[2]) * (1.0f / 3.0f)); +} +// LordHavoc: .lit support end diff --git a/r17/Revamped src/revamped_src/psp/video_hardware_main.cpp b/r17/Revamped src/revamped_src/psp/video_hardware_main.cpp new file mode 100755 index 00000000..ae7e8a08 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_hardware_main.cpp @@ -0,0 +1,2103 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ +// r_main.c + +extern "C" +{ +#include "../quakedef.h" +#include "video_vertex_lighting.h" +} + +#include +#include + +#include "clipping.hpp" + +using namespace quake; + +entity_t r_worldentity; + +qboolean r_cache_thrash; // compatability + +vec3_t modelorg, r_entorigin; +entity_t *currententity; + +int r_visframecount; // bumped when going to a new PVS +int r_framecount; // used for dlight push checking + +mplane_t frustum[4]; + +int c_brush_polys, c_alias_polys; + +qboolean envmap; // qtrue during envmap command capture + +int currenttexture = -1; // to avoid unnecessary texture sets + +int cnttextures[2] = {-1, -1}; // cached + +int particletexture; // little dot for particles +int playertextures; // up to 16 color translated skins + +int mirrortexturenum; // quake texturenum, not gltexturenum +qboolean mirror; +mplane_t *mirror_plane; + +bool force_fullbright; +bool additive; +bool filter; +bool alphafunc; +bool alphafunc2; +bool fixlight; + +// +// view origin +// +vec3_t vup; +vec3_t vpn; +vec3_t vright; +vec3_t r_origin; + +ScePspFMatrix4 r_world_matrix; +ScePspFMatrix4 r_base_world_matrix; + +// +// screen size info +// +refdef_t r_refdef; + +mleaf_t *r_viewleaf, *r_oldviewleaf; + +texture_t *r_notexture_mip; + +int d_lightstylevalue[256]; // 8.8 fraction of base light value + +void R_MarkLeaves (void); + +cvar_t r_skyclip = {"r_skyclip", "2560", qtrue}; // Adjust skybox clipping distance +cvar_t r_norefresh = {"r_norefresh","0"}; // Unknown +cvar_t r_drawentities = {"r_drawentities","1"}; // Toggle entity drawing +cvar_t r_drawviewmodel = {"r_drawviewmodel","1"}; // Toggle view model drawing +cvar_t r_speeds = {"r_speeds","0"}; // Toggle speed statistical display +cvar_t r_fullbright = {"r_fullbright","0"}; // Toggle fullbright world and entities +cvar_t r_lightmap = {"r_lightmap","0"}; // Toggle drawing of lightmaps only +cvar_t r_shadows = {"r_shadows","0"}; // Toggle fake stencil shadows for entities +cvar_t r_mirroralpha = {"r_mirroralpha","1"}; // Adjust alpha value of mirror textures (not functional) +cvar_t r_glassalpha = {"r_glassalpha","0.25"}; // Adjust alpha value of glass textures +cvar_t r_wateralpha = {"r_wateralpha","0.6"}; // Adjust alpha value of liquid textures +cvar_t r_mipmaps = {"r_mipmaps","0",qtrue}; // Toggle mip map optimising +cvar_t r_mipmaps_func = {"r_mipmaps_func","2",qtrue}; // Adjust mip map calculations +cvar_t r_mipmaps_bias = {"r_mipmaps_bias","-7",qtrue}; // Adjust mip map bias level +cvar_t r_dynamic = {"r_dynamic","1", qtrue}; // Toggle lightmap dynamic lighting +cvar_t r_novis = {"r_novis","0"}; // Toggle visibility calculations +cvar_t r_tex_scale_down = {"r_tex_scale_down","0", qtrue}; // Toggle odd texture size resolution down scaling +cvar_t r_particles_simple = {"r_particles_simple","0", qtrue}; // Toggle classic particle effect +cvar_t gl_keeptjunctions = {"gl_keeptjunctions","1", qtrue}; // Keeps edge t-junctions in world aligned. +cvar_t r_vsync = {"r_vsync","0", qtrue}; // Toggle V-Sync +cvar_t r_dithering = {"r_dithering","0", qtrue}; // Toggle hardware color dithering +cvar_t r_antialias = {"r_antialias","0", qtrue}; // Toggle fake anti alias effect +cvar_t r_menufade = {"r_menufade","0.5", qtrue}; // Adjust menu background alpha +cvar_t r_showtris = {"r_showtris","0", qfalse}; // Display wireframes +cvar_t r_test = {"r_test","0", qfalse}; // developer temp test cvar + +cvar_t r_i_model_animation = { "r_i_model_animation", "1", qtrue}; // Toggle smooth model animation +cvar_t r_i_model_transform = { "r_i_model_transform", "1", qtrue}; // Toggle smooth model movement +cvar_t r_model_contrast = { "r_model_contrast", "0", qtrue}; // Toggle high contrast model lighting +cvar_t r_model_brightness = { "r_model_brightness", "1", qtrue}; // Toggle high brightness model lighting +cvar_t r_skyfog = {"r_skyfog", "1", qtrue}; // Toggle sky fog + +cvar_t vlight = {"vl_light", "0", qtrue}; +cvar_t vlight_pitch = {"vl_pitch", "45", qtrue}; +cvar_t vlight_yaw = {"vl_yaw", "45", qtrue}; +cvar_t vlight_highcut = {"vl_highcut", "128", qtrue}; +cvar_t vlight_lowcut = {"vl_lowcut", "60", qtrue}; + +/* +cvar_t gl_finish = {"gl_finish","0"}; +cvar_t gl_clear = {"gl_clear","0"}; +cvar_t gl_cull = {"gl_cull","1"}; +cvar_t gl_texsort = {"gl_texsort","1"}; +cvar_t gl_smoothmodels = {"gl_smoothmodels","1"}; +cvar_t gl_affinemodels = {"gl_affinemodels","0"}; +cvar_t gl_polyblend = {"gl_polyblend","1"}; +cvar_t gl_flashblend = {"gl_flashblend","1"}; +cvar_t gl_playermip = {"gl_playermip","0"}; +cvar_t gl_nocolors = {"gl_nocolors","0"}; +cvar_t gl_reporttjunctions = {"gl_reporttjunctions","0"}; +cvar_t gl_doubleeyes = {"gl_doubleeys", "1"}; + +extern cvar_t gl_ztrick;*/ + +/* +================= +R_CullBox + +Returns qtrue if the box is completely outside the frustom +================= +*/ +qboolean R_CullBox (vec3_t mins, vec3_t maxs) +{ + int i; + + for (i=0 ; i<4 ; i++) + if (BoxOnPlaneSide (mins, maxs, &frustum[i]) == 2) + return qtrue; + return qfalse; +} + + +void R_RotateForEntity (entity_t *e) +{ + // Translate. + const ScePspFVector3 translation = { + e->origin[0], e->origin[1], e->origin[2] + }; + sceGumTranslate(&translation); +/* + // Scale. + const ScePspFVector3 scale = { + e->scale[0],e->scale[1],e->scale[2] + }; + sceGumScale(&scale); +*/ + // Rotate. + const ScePspFVector3 rotation = { + e->angles[ROLL] * (GU_PI / 180.0f), + -e->angles[PITCH] * (GU_PI / 180.0f), + e->angles[YAW] * (GU_PI / 180.0f) + }; + sceGumRotateZYX(&rotation); + + sceGumUpdateMatrix(); +} + +/* +============= +R_BlendedRotateForEntity + +fenix@io.com: model transform interpolation +============= +*/ +void R_BlendedRotateForEntity (entity_t *e) +{ + float timepassed; + float blend; + vec3_t d; + int i; + + // positional interpolation + + timepassed = realtime - e->translate_start_time; + + if (e->translate_start_time == 0 || timepassed > 1) + { + e->translate_start_time = realtime; + VectorCopy (e->origin, e->origin1); + VectorCopy (e->origin, e->origin2); + } + + if (!VectorCompare (e->origin, e->origin2)) + { + e->translate_start_time = realtime; + VectorCopy (e->origin2, e->origin1); + VectorCopy (e->origin, e->origin2); + blend = 0; + } + else + { + blend = timepassed / 0.1; + if (cl.paused || blend > 1) + blend = 0; + } + + VectorSubtract (e->origin2, e->origin1, d); + + // Translate. + const ScePspFVector3 translation = { + e->origin[0] + (blend * d[0]), + e->origin[1] + (blend * d[1]), + e->origin[2] + (blend * d[2]) + }; + sceGumTranslate(&translation); +/* + // Scale. + const ScePspFVector3 scale = { + e->scale[0] + (blend * d[0]), + e->scale[1] + (blend * d[1]), + e->scale[2] + (blend * d[2] + }; + sceGumScale(&scale); +*/ + // orientation interpolation (Euler angles, yuck!) + + timepassed = realtime - e->rotate_start_time; + + if (e->rotate_start_time == 0 || timepassed > 1) + { + e->rotate_start_time = realtime; + VectorCopy (e->angles, e->angles1); + VectorCopy (e->angles, e->angles2); + } + + if (!VectorCompare (e->angles, e->angles2)) + { + e->rotate_start_time = realtime; + VectorCopy (e->angles2, e->angles1); + VectorCopy (e->angles, e->angles2); + blend = 0; + } + else + { + blend = timepassed / 0.1; + if (cl.paused || blend > 1) + blend = 1; + } + + VectorSubtract (e->angles2, e->angles1, d); + + // always interpolate along the shortest path + for (i = 0; i < 3; i++) + { + if (d[i] > 180) + { + d[i] -= 360; + } + else if (d[i] < -180) + { + d[i] += 360; + } + } + + // Rotate. + const ScePspFVector3 rotation = { + (e->angles1[ROLL] + ( blend * d[ROLL])) * (GU_PI / 180.0f), + (-e->angles1[PITCH] + (-blend * d[PITCH])) * (GU_PI / 180.0f), + (e->angles1[YAW] + ( blend * d[YAW])) * (GU_PI / 180.0f) + }; + sceGumRotateZYX(&rotation); + + sceGumUpdateMatrix(); +} + +/* +============================================================= + + SPRITE MODELS + +============================================================= +*/ + +/* +================ +R_GetSpriteFrame +================ +*/ +mspriteframe_t *R_GetSpriteFrame (entity_t *currententity) +{ + msprite_t *psprite; + mspritegroup_t *pspritegroup; + mspriteframe_t *pspriteframe; + int i, numframes, frame; + float *pintervals, fullinterval, targettime, time; + + psprite = static_cast(currententity->model->cache.data); + frame = currententity->frame; + + if ((frame >= psprite->numframes) || (frame < 0)) + { + Con_Printf ("R_DrawSprite: no such frame %d\n", frame); + frame = 0; + } + + if (psprite->frames[frame].type == SPR_SINGLE) + { + pspriteframe = psprite->frames[frame].frameptr; + } + else + { + pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; + pintervals = pspritegroup->intervals; + numframes = pspritegroup->numframes; + fullinterval = pintervals[numframes-1]; + + time = cl.time + currententity->syncbase; + + // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values + // are positive, so we don't have to worry about division by 0 + targettime = time - ((int)(time / fullinterval)) * fullinterval; + + for (i=0 ; i<(numframes-1) ; i++) + { + if (pintervals[i] > targettime) + break; + } + + pspriteframe = pspritegroup->frames[i]; + } + + return pspriteframe; +} + + +/* +================= +R_DrawSpriteModel + +================= +*/ +void R_DrawSpriteModel (entity_t *e) +{ + vec3_t point, v_forward, v_right, v_up; + msprite_t *psprite; + mspriteframe_t *frame; + float *s_up, *s_right; + float angle, sr, cr; + + // don't even bother culling, because it's just a single polygon without a surface cache + frame = R_GetSpriteFrame (e); + psprite = static_cast(currententity->model->cache.data); + + switch(psprite->type) + { + case SPR_VP_PARALLEL_UPRIGHT: //faces view plane, up is towards the heavens + v_up[0] = 0; + v_up[1] = 0; + v_up[2] = 1; + s_up = v_up; + s_right = vright; + break; + case SPR_FACING_UPRIGHT: //faces camera origin, up is towards the heavens + VectorSubtract(currententity->origin, r_origin, v_forward); + v_forward[2] = 0; + VectorNormalizeFast(v_forward); + v_right[0] = v_forward[1]; + v_right[1] = -v_forward[0]; + v_right[2] = 0; + v_up[0] = 0; + v_up[1] = 0; + v_up[2] = 1; + s_up = v_up; + s_right = v_right; + break; + case SPR_VP_PARALLEL: //faces view plane, up is towards the top of the screen + s_up = vup; + s_right = vright; + break; + case SPR_ORIENTED: //pitch yaw roll are independent of camera + AngleVectors (currententity->angles, v_forward, v_right, v_up); + s_up = v_up; + s_right = v_right; + break; + case SPR_VP_PARALLEL_ORIENTED: //faces view plane, but obeys roll value + angle = currententity->angles[ROLL] * M_PI_DIV_180; + sr = sin(angle); + cr = cos(angle); + v_right[0] = vright[0] * cr + vup[0] * sr; + v_up[0] = vright[0] * -sr + vup[0] * cr; + v_right[1] = vright[1] * cr + vup[1] * sr; + v_up[1] = vright[1] * -sr + vup[1] * cr; + v_right[2] = vright[2] * cr + vup[2] * sr; + v_up[2] = vright[2] * -sr + vup[2] * cr; + s_up = v_up; + s_right = v_right; + break; + default: + return; + } + + additive = false; + filter = false; + + if (psprite->beamlength == 10) // we use the beam length of sprites, since they are unused by quake anyway. + additive = true; + + if (psprite->beamlength == 20) + filter = true; + + // Bind the texture. + GL_Bind(frame->gl_texturenum); + + sceGuEnable(GU_BLEND); + sceGuDisable(GU_FOG); + + if (additive) + { + sceGuDepthMask(GU_TRUE); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0xFFFFFFFF); + sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGB); + } + else if (filter) + { + sceGuDepthMask(GU_TRUE); + sceGuBlendFunc(GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0); + sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGB); + } + else + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + + // Allocate memory for this polygon. + glvert_t* const vertices = + static_cast(sceGuGetMemory(sizeof(glvert_t) * 4)); + + VectorMA (e->origin, frame->down, s_up, point); + VectorMA (point, frame->left, s_right, point); + + vertices[0].st[0] = 0.0f; + vertices[0].st[1] = 1.0f; + vertices[0].xyz[0] = point[0]; + vertices[0].xyz[1] = point[1]; + vertices[0].xyz[2] = point[2]; + + VectorMA (e->origin, frame->up, s_up, point); + VectorMA (point, frame->left, s_right, point); + + vertices[1].st[0] = 0.0f; + vertices[1].st[1] = 0.0f; + vertices[1].xyz[0] = point[0]; + vertices[1].xyz[1] = point[1]; + vertices[1].xyz[2] = point[2]; + + VectorMA (e->origin, frame->up, s_up, point); + VectorMA (point, frame->right, s_right, point); + + vertices[2].st[0] = 1.0f; + vertices[2].st[1] = 0.0f; + vertices[2].xyz[0] = point[0]; + vertices[2].xyz[1] = point[1]; + vertices[2].xyz[2] = point[2]; + + VectorMA (e->origin, frame->down, s_up, point); + VectorMA (point, frame->right, s_right, point); + + vertices[3].st[0] = 1.0f; + vertices[3].st[1] = 1.0f; + vertices[3].xyz[0] = point[0]; + vertices[3].xyz[1] = point[1]; + vertices[3].xyz[2] = point[2]; + + // Draw the clipped vertices. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF, + 4, 0, vertices); + + sceGuDepthMask(GU_FALSE); + sceGuDisable(GU_BLEND); + sceGuEnable(GU_FOG); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); +} + +/* +============================================================= + + ALIAS MODELS + +============================================================= +*/ + + +#define NUMVERTEXNORMALS 162 + +extern "C" float r_avertexnormals[NUMVERTEXNORMALS][3]; +float r_avertexnormals[NUMVERTEXNORMALS][3] = { +#include "../anorms.h" +}; + +vec3_t shadevector; +//float shadelight, ambientlight; // LordHavoc: .lit support, removed shadelight and ambientlight + +// precalculated dot products for quantized angles +#define SHADEDOT_QUANT 16 +float r_avertexnormal_dots[SHADEDOT_QUANT][256] = +#include "../anorm_dots.h" +; + +float *shadedots = r_avertexnormal_dots[0]; + +// light lerping - pox@planetquake.com + +float *shadedots2 = r_avertexnormal_dots[0]; + +float lightlerpoffset; + +// fenix@io.com: model animation interpolation +int lastposenum0; +int lastposenum; + +// fenix@io.com: model transform interpolation +float old_i_model_transform; + +// vertex lighting +float apitch, ayaw; +vec3_t vertexlight; + +/* +============= +GL_DrawAliasFrame +============= +*/ +extern vec3_t lightcolor; // LordHavoc: .lit support +void GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum, float apitch, float ayaw) +{ + float l; + trivertx_t *verts; + int *order; + int count; + float r,g,b; +// vec3_t l_v; + + lastposenum = posenum; + + verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata); + verts += posenum * paliashdr->poseverts; + order = (int *)((byte *)paliashdr + paliashdr->commands); + + while (1) + { + // get the vertex count and primitive type + count = *order++; + if (!count) + break; // done + int prim; + if (count < 0) + { + count = -count; + + if (r_showtris.value) + prim = GU_LINE_STRIP; + else + prim = GU_TRIANGLE_FAN; + } + else + { + if (r_showtris.value) + prim = GU_LINE_STRIP; + else + prim = GU_TRIANGLE_STRIP;; + } + + // Allocate the vertices. + struct vertex + { + float u, v; + unsigned int color; + float x, y, z; + }; + + vertex* const out = static_cast(sceGuGetMemory(sizeof(vertex) * count)); + + for (int vertex_index = 0; vertex_index < count; ++vertex_index) + { + // texture coordinates come from the draw list + out[vertex_index].u = ((float *)order)[0]; + out[vertex_index].v = ((float *)order)[1]; + order += 2; + + // normals and vertexes come from the frame list + + // LordHavoc: .lit support begin + //l = shadedots[verts->lightnormalindex] * shadelight; // LordHavoc: original code + //l = shadedots[verts->lightnormalindex]; + // LordHavoc: .lit support end + + // normals and vertexes come from the frame list + // blend the light intensity from the two frames together + + if(vlight.value) + // RIOT - Vertex lighting + l = VLight_LerpLight(verts->lightnormalindex, verts->lightnormalindex, 1, apitch, ayaw); + else + { + float l1, l2, diff; + + l1 = shadedots[verts->lightnormalindex]; // Colored Lighting support + l2 = shadedots2[verts->lightnormalindex]; + + if (l1 != l2) + { + if (l1 > l2) + { + diff = l1 - l2; + diff *= lightlerpoffset; + l = l1 - diff; + } + else + { + diff = l2 - l1; + diff *= lightlerpoffset; + l = l1 + diff; + } + } + else + l = l1; + } + + if (r_model_contrast.value) + l *= l; + +// if (l > 1.5) +// l = 1.5; + + r = l * lightcolor[0]; + g = l * lightcolor[1]; + b = l * lightcolor[2]; + + // PSP handles colors in bytes, so can't go anything higher then 1.0f) + // TODO: Use hardware lights to overbright the models, instead of using another pass. + if (r > 1.0f) + r = 1.0f; + if (g > 1.0f) + g = 1.0f; + if (b > 1.0f) + b = 1.0f; + + out[vertex_index].x = verts->v[0]; + out[vertex_index].y = verts->v[1]; + out[vertex_index].z = verts->v[2]; + + if (!r_showtris.value) + out[vertex_index].color = GU_COLOR(r, g, b, currententity->alpha); + else + out[vertex_index].color = 0xffffffff; + + ++verts; + } + + if (r_showtris.value) + { + sceGuDisable(GU_TEXTURE_2D); + sceGumDrawArray(prim, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_COLOR_8888, count, 0, out); + sceGuEnable(GU_TEXTURE_2D); + } + else + sceGuDrawArray(prim, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_COLOR_8888, count, 0, out); + } +} + +/* +============= +GL_DrawAliasBlendedFrame + +fenix@io.com: model animation interpolation +============= +*/ +void GL_DrawAliasBlendedFrame (aliashdr_t *paliashdr, int pose1, int pose2, float blend, float apitch, float ayaw) +{ + float l; + float r,g,b; + trivertx_t* verts1; + trivertx_t* verts2; + int* order; + int count, brightness; + vec3_t d; + + lastposenum0 = pose1; + lastposenum = pose2; + + verts1 = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata); + verts2 = verts1; + + verts1 += pose1 * paliashdr->poseverts; + verts2 += pose2 * paliashdr->poseverts; + + order = (int *)((byte *)paliashdr + paliashdr->commands); + + while (1) + { + // get the vertex count and primitive type + int prim; + count = *order++; + + if (!count) break; + + if (count < 0) + { + count = -count; + + if (r_showtris.value) + prim = GU_LINE_STRIP; + else + prim = GU_TRIANGLE_FAN; + } + else + { + if (r_showtris.value) + prim = GU_LINE_STRIP; + else + prim = GU_TRIANGLE_STRIP;; + } + + // Allocate the vertices. + struct vertex + { + float u, v; + unsigned int color; + float x, y, z; + }; + + vertex* const out = static_cast(sceGuGetMemory(sizeof(vertex) * count)); + + for (int vertex_index = 0; vertex_index < count; ++vertex_index) + { + // texture coordinates come from the draw list + out[vertex_index].u = ((float *)order)[0]; + out[vertex_index].v = ((float *)order)[1]; + order += 2; + + // normals and vertexes come from the frame list + // blend the light intensity from the two frames together + + if(vlight.value) + // RIOT - Vertex lighting + l = VLight_LerpLight(verts1->lightnormalindex, verts2->lightnormalindex, blend, apitch, ayaw); + else + { + float l1, l2, diff; + + l1 = shadedots[verts1->lightnormalindex]; // Colored Lighting support + l2 = shadedots2[verts1->lightnormalindex]; + + if (l1 != l2) + { + if (l1 > l2) + { + diff = l1 - l2; + diff *= lightlerpoffset; + l = l1 - diff; + } + else + { + diff = l2 - l1; + diff *= lightlerpoffset; + l = l1 + diff; + } + } + else + l = l1; + } + // light contrast - pox@planetquake.com + if (r_model_contrast.value) + l *= l; + + r = l * lightcolor[0]; + g = l * lightcolor[1]; + b = l * lightcolor[2]; + + if (r > 1.0f) + r = 1.0f; + if (g > 1.0f) + g = 1.0f; + if (b > 1.0f) + b = 1.0f; + + VectorSubtract(verts2->v, verts1->v, d); + // blend the vertex positions from each frame together + out[vertex_index].x = verts1->v[0] + (blend * d[0]); + out[vertex_index].y = verts1->v[1] + (blend * d[1]); + out[vertex_index].z = verts1->v[2] + (blend * d[2]); + + if (!r_showtris.value) + out[vertex_index].color = GU_COLOR(r, g, b, currententity->alpha); + else + out[vertex_index].color = 0xffffffff; + +// byte colorval = ((int) (l*brightness)) & 0xFF; +// out[vertex_index].color = (colorval << 24) | (colorval << 16) | (colorval << 8) | colorval; + + verts1++; + verts2++; + } + + if (r_showtris.value) + { + sceGuDisable(GU_TEXTURE_2D); + sceGumDrawArray(prim, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_COLOR_8888, count, 0, out); + sceGuEnable(GU_TEXTURE_2D); + } + else + sceGuDrawArray(prim, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_COLOR_8888, count, 0, out); + } +} + +/* +============= +GL_DrawAliasShadow +============= +*/ +extern vec3_t lightspot; + +void GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum) +{/* + float s, t, l; + int i, j; + int index; + trivertx_t *v, *verts; + int list; + int *order; + vec3_t point; + float *normal; + float height, lheight; + int count; + + lheight = currententity->origin[2] - lightspot[2]; + + height = 0; + verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata); + verts += posenum * paliashdr->poseverts; + order = (int *)((byte *)paliashdr + paliashdr->commands); + + height = -lheight + 1.0; + + while (1) + { + // get the vertex count and primitive type + count = *order++; + if (!count) + break; // done + if (count < 0) + { + count = -count; + glBegin (GL_TRIANGLE_FAN); + } + else + glBegin (GL_TRIANGLE_STRIP); + + do + { + // texture coordinates come from the draw list + // (skipped for shadows) glTexCoord2fv ((float *)order); + order += 2; + + // normals and vertexes come from the frame list + point[0] = verts->v[0] * paliashdr->scale[0] + paliashdr->scale_origin[0]; + point[1] = verts->v[1] * paliashdr->scale[1] + paliashdr->scale_origin[1]; + point[2] = verts->v[2] * paliashdr->scale[2] + paliashdr->scale_origin[2]; + + point[0] -= shadevector[0]*(point[2]+lheight); + point[1] -= shadevector[1]*(point[2]+lheight); + point[2] = height; + glVertex3fv (point); + + verts++; + } while (--count); + + glEnd (); + } */ +} + + + +/* +================= +R_SetupAliasFrame + +================= +*/ +void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr, float apitch, float ayaw) +{ + int pose, numposes; + float interval; + + if ((frame >= paliashdr->numframes) || (frame < 0)) + { + Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame); + frame = 0; + } + + pose = paliashdr->frames[frame].firstpose; + numposes = paliashdr->frames[frame].numposes; + + if (numposes > 1) + { + interval = paliashdr->frames[frame].interval; + pose += (int)(cl.time / interval) % numposes; + } + + GL_DrawAliasFrame (paliashdr, pose, apitch, ayaw); +} + +/* +================= +R_SetupAliasBlendedFrame + +fenix@io.com: model animation interpolation +================= +*/ +void R_SetupAliasBlendedFrame (int frame, aliashdr_t *paliashdr, entity_t* e, float apitch, float ayaw) +{ + int pose; + int numposes; + float blend; + + if ((frame >= paliashdr->numframes) || (frame < 0)) + { + Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame); + frame = 0; + } + + pose = paliashdr->frames[frame].firstpose; + numposes = paliashdr->frames[frame].numposes; + + if (numposes > 1) + { + e->frame_interval = paliashdr->frames[frame].interval; + pose += (int)(cl.time / e->frame_interval) % numposes; + } + else + { + /* One tenth of a second is a good for most Quake animations. + If the nextthink is longer then the animation is usually meant to pause + (e.g. check out the shambler magic animation in shambler.qc). If its + shorter then things will still be smoothed partly, and the jumps will be + less noticable because of the shorter time. So, this is probably a good + assumption. */ + e->frame_interval = 0.1; + } + + if (e->pose2 != pose) + { + e->frame_start_time = realtime; + e->pose1 = e->pose2; + e->pose2 = pose; + blend = 0; + } + else + { + blend = (realtime - e->frame_start_time) / e->frame_interval; + } + + // wierd things start happening if blend passes 1 + if (cl.paused || blend > 1) blend = 1; + + if (blend == 1) + GL_DrawAliasFrame (paliashdr, pose, apitch, ayaw); + else + GL_DrawAliasBlendedFrame (paliashdr, e->pose1, e->pose2, blend, apitch, ayaw); +} + +/* +================= +R_DrawAliasModel +================= +*/ +void R_DrawAliasModel (entity_t *e) +{ + int i, j; + int lnum; + vec3_t dist; + float add; + model_t *clmodel; + vec3_t mins, maxs; + aliashdr_t *paliashdr; + trivertx_t *verts, *v; + int index; + float an, s, t; + int anim; + +// float radiusmax = 0.0; + +// Tomaz - QC Alpha Begin +/* + glDisable(GL_ALPHA_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +*/ +// Tomaz - QC Alpha End + + force_fullbright = false; + additive = false; + filter = false; + alphafunc = false; + alphafunc2 = false; + fixlight = false; + + clmodel = currententity->model; + + VectorAdd (currententity->origin, clmodel->mins, mins); + VectorAdd (currententity->origin, clmodel->maxs, maxs); + + if (R_CullBox (mins, maxs)) + return; + + VectorCopy (currententity->origin, r_entorigin); + VectorSubtract (r_origin, r_entorigin, modelorg); + + // + // get lighting information + // + + // LordHavoc: .lit support begin + //ambientlight = shadelight = R_LightPoint (currententity->origin); // LordHavoc: original code, removed shadelight and ambientlight + R_LightPoint(currententity->origin); // LordHavoc: lightcolor is all that matters from this + // LordHavoc: .lit support end + + // always give the gun some light + // LordHavoc: .lit support begin + //if (e == &cl.viewent && ambientlight < 24) // LordHavoc: original code + // ambientlight = shadelight = 24; // LordHavoc: original code +/* + if (e == &cl.viewent) + { + if (lightcolor[0] < 24) + lightcolor[0] = 24; + if (lightcolor[1] < 24) + lightcolor[1] = 24; + if (lightcolor[2] < 24) + lightcolor[2] = 24; + } +*/ + // LordHavoc: .lit support end + + for (lnum=0 ; lnum= cl.time) + { + VectorSubtract (currententity->origin, + cl_dlights[lnum].origin, + dist); + add = cl_dlights[lnum].radius - Length(dist); + + // LordHavoc: .lit support begin + /* LordHavoc: original code + if (add > 0) { + ambientlight += add; + //ZOID models should be affected by dlights as well + shadelight += add; + } + */ + if (add > 0) + { + lightcolor[0] += add * cl_dlights[lnum].color[0]; + lightcolor[1] += add * cl_dlights[lnum].color[1]; + lightcolor[2] += add * cl_dlights[lnum].color[2]; + } + // LordHavoc: .lit support end + } + } + + // clamp lighting so it doesn't overbright as much +/* + if (shadelight > 65) + shadelight = 65; + if (ambientlight > 196) + { + ambientlight = 196; + force_fullbright = true; + } + else + force_fullbright = false; +*/ + // ZOID: never allow players to go totally black +// i = currententity - cl_entities; +// if (i >= 1 && i<=cl.maxclients /*&& !strcmp (currententity->model->name, "progs/player.mdl") */) + // LordHavoc: .lit support begin + // if (ambientlight < 8) // LordHavoc: original code + // ambientlight = shadelight = 8; // LordHavoc: original code + + if (!strcmp (clmodel->name, "progs/eyes.mdl") || + !strcmp (clmodel->name, "progs/flame.mdl") || + !strcmp (clmodel->name, "progs/palmleav.mdl") || + !strcmp (clmodel->name, "progs/k_spike.mdl") || + !strcmp (clmodel->name, "progs/s_spike.mdl") || + !strcmp (clmodel->name, "progs/scope.mdl") || + !strcmp (clmodel->name, "progs/spike.mdl")) + { + // LordHavoc: .lit support begin + // ambientlight = shadelight = 256; // LordHavoc: original code + lightcolor[0] = lightcolor[1] = lightcolor[2] = 256; + // LordHavoc: .lit support end + force_fullbright = true; + } + + if (!strcmp (clmodel->name, "progs/flame2.mdl") || + !strcmp (clmodel->name, "progs/lavaball.mdl") || + !strcmp (clmodel->name, "progs/bolt.mdl") || + !strcmp (clmodel->name, "progs/bolt2.mdl") || + !strcmp (clmodel->name, "progs/bolt3.mdl") || + !strcmp (clmodel->name, "progs/s_light.mdl") || + !strcmp (clmodel->name, "progs/bullet.mdl") || + !strcmp (clmodel->name, "progs/explode.mdl") || + !strcmp (clmodel->name, "progs/laser.mdl")) + { + lightcolor[0] = lightcolor[1] = lightcolor[2] = 256; + additive = true; + } + + if (!strcmp (clmodel->name, "progs/smoke.mdl") || + !strcmp (clmodel->name, "progs/glass1.mdl") || + !strcmp (clmodel->name, "progs/glass2.mdl") || + !strcmp (clmodel->name, "progs/glass3.mdl") || + !strcmp (clmodel->name, "progs/debris.mdl")) + { + filter = true; + } + + if (!strcmp (clmodel->name, "progs/raptor.mdl") || + !strcmp (clmodel->name, "progs/5_box_s.mdl") || + !strcmp (clmodel->name, "progs/trex.mdl")) + { + alphafunc = true; + } + + if (!strcmp (clmodel->name, "progs/v_axe.mdl") || + !strcmp (clmodel->name, "progs/v_axea.mdl") || + !strcmp (clmodel->name, "progs/v_bow.mdl") || + !strcmp (clmodel->name, "progs/v_tekbow.mdl") || + !strcmp (clmodel->name, "progs/v_shot.mdl") || + !strcmp (clmodel->name, "progs/v_shot2.mdl") || + !strcmp (clmodel->name, "progs/v_nail.mdl") || + !strcmp (clmodel->name, "progs/v_nail2.mdl") || + !strcmp (clmodel->name, "progs/v_rock.mdl") || + !strcmp (clmodel->name, "progs/v_rock2.mdl") || + !strcmp (clmodel->name, "progs/v_light.mdl") || + !strcmp (clmodel->name, "progs/v_uzi.mdl") || + !strcmp (clmodel->name, "progs/v_sniper.mdl") || + !strcmp (clmodel->name, "progs/crate.mdl") || + !strcmp (clmodel->name, "progs/pc.mdl")) + { + if (r_model_brightness.value) + fixlight = true; + alphafunc2 = true; + } + + if (lightcolor[0] < 16) + lightcolor[0] = 16; + if (lightcolor[1] < 16) + lightcolor[1] = 16; + if (lightcolor[2] < 16) + lightcolor[2] = 16; + + if (lightcolor[0] > 125 && lightcolor[1] > 125 && lightcolor[2] > 125) + { + lightcolor[0] = 125; + lightcolor[1] = 125; + lightcolor[2] = 125; + if (!fixlight) + force_fullbright = true; + } + + // LordHavoc: .lit support end + + // light lerping - pox@planetquake.com + //shadedots = r_avertexnormal_dots[((int)(e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)]; + + { + float ang_ceil, ang_floor; + + // add pitch angle so lighting changes when looking up/down (mainly for viewmodel) + lightlerpoffset = (e->angles[1]+e->angles[0]) * (SHADEDOT_QUANT / 360.0); + + ang_ceil = ceil(lightlerpoffset); + ang_floor = floor(lightlerpoffset); + + lightlerpoffset = ang_ceil - lightlerpoffset; + + shadedots = r_avertexnormal_dots[(int)ang_ceil & (SHADEDOT_QUANT - 1)]; + shadedots2 = r_avertexnormal_dots[(int)ang_floor & (SHADEDOT_QUANT - 1)]; + } + + // LordHavoc: .lit support begin + //shadelight = shadelight / 200.0; // LordHavoc: original code + VectorScale(lightcolor, 1.0f / 200.0f, lightcolor); + // LordHavoc: .lit support end + + // light lerping - pox@planetquake.com + +// shadelight = (shadelight + currententity->last_shadelight)/2; +// currententity->last_shadelight = shadelight; + + an = e->angles[1]/180*M_PI; + shadevector[0] = cosf(-an); + shadevector[1] = sinf(-an); + shadevector[2] = 1; + VectorNormalize (shadevector); + + // + // locate the proper data + // + + paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model); + c_alias_polys += paliashdr->numtris; + + // + // draw all the triangles + // + + sceGumPushMatrix(); + + // fenix@io.com: model transform interpolation + + if (r_i_model_transform.value) + R_BlendedRotateForEntity (e); + else + R_RotateForEntity (e); + + const ScePspFVector3 translation = { paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2] }; + sceGumTranslate(&translation); + + const ScePspFVector3 scaling = { paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2] }; + sceGumScale(&scaling); + + anim = (int)(cl.time*10) & 3; + GL_Bind(paliashdr->gl_texturenum[currententity->skinnum][anim]); + + // we can't dynamically colormap textures, so they are cached + // seperately for the players. Heads are just uncolored. + if (currententity->colormap != vid.colormap && 0) + { + i = currententity - cl_entities; + if (i >= 1 && i<=cl.maxclients) + GL_Bind(playertextures - 1 + i); + } + + if (force_fullbright) + { +// sceGuDepthMask(GU_TRUE); + sceGuEnable(GU_BLEND); + sceGuEnable(GU_ALPHA_TEST); + sceGuAlphaFunc(GU_GREATER, 0x88, 0xff); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + } + else if (additive) + { + sceGuEnable(GU_BLEND); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0xFFFFFFFF); + } + else if (filter) + { + sceGuEnable(GU_BLEND); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + sceGuBlendFunc(GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0); + } + else if (alphafunc) + { + sceGuEnable(GU_ALPHA_TEST); + sceGuAlphaFunc(GU_GREATER, 0, 0xff); + sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + } + else if (alphafunc2) + { + sceGuEnable(GU_ALPHA_TEST); + sceGuAlphaFunc(GU_GREATER, 0xaa, 0xff); + sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + } + else + sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + + sceGuShadeModel(GU_SMOOTH); + sceGumUpdateMatrix(); + + if (r_i_model_animation.value) + R_SetupAliasBlendedFrame (currententity->frame, paliashdr, currententity, e->angles[0], e->angles[1]); + else + R_SetupAliasFrame (currententity->frame, paliashdr, e->angles[0], e->angles[1]); + + if (!force_fullbright && fixlight) //Draws another pass, ouch! + { + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0xFFFFFFFF); + sceGuEnable(GU_BLEND); + + if (r_i_model_animation.value) + R_SetupAliasBlendedFrame (currententity->frame, paliashdr, currententity, e->angles[0], e->angles[1]); + else + R_SetupAliasFrame (currententity->frame, paliashdr, e->angles[0], e->angles[1]); + + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuDisable(GU_BLEND); + } + + if (force_fullbright) + { +// sceGuDepthMask(GU_FALSE); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuDisable(GU_BLEND); + } + + if (additive || filter || alphafunc) + { + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuDisable(GU_BLEND); + } + + sceGuAlphaFunc(GU_GREATER, 0, 0xff); + sceGuDisable(GU_ALPHA_TEST); + sceGuTexFunc(GU_TFX_REPLACE , GU_TCC_RGBA); + sceGuShadeModel(GU_FLAT); + +// sceGuDisable(GU_LIGHTING); + + sceGumPopMatrix(); + sceGumUpdateMatrix(); + + if (r_shadows.value) + { + sceGumPushMatrix(); + R_RotateForEntity (e); + + /* + glDisable (GL_TEXTURE_2D); + glEnable (GL_BLEND); + glColor4f (0,0,0,0.5);*/ + GL_DrawAliasShadow (paliashdr, lastposenum); + /*glEnable (GL_TEXTURE_2D); + glDisable (GL_BLEND); + glColor4f (1,1,1,1); + glPopMatrix ();*/ + + sceGumPopMatrix(); + sceGumUpdateMatrix(); + } +/* + // Tomaz - QC Alpha Begin + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + + // Tomaz - QC Alpha End +*/ +} + +//================================================================================== + +/* +============= +R_DrawEntitiesOnList +============= +*/ +void R_DrawEntitiesOnList (void) +{ + int i; + + if (!r_drawentities.value) + return; + + // Tomaz - QC Alpha Scale Begin + + if ((!strncmp (currententity->model->name, "progs/bolt", 10)) || + (!strncmp (currententity->model->name, "progs/bush", 10)) || + (!strncmp (currententity->model->name, "progs/bush1", 11)) || + (!strncmp (currententity->model->name, "progs/bush2", 11)) || + (!strncmp (currententity->model->name, "progs/bush3", 11)) || + (!strncmp (currententity->model->name, "progs/flame", 11))) + { + currententity->alpha = 1; + currententity->scale = 1; + } + + // Tomaz - QC Alpha Scale End + + // draw sprites seperately, because of alpha blending + for (i=0 ; imodel->type) + { + case mod_alias: + R_DrawAliasModel (currententity); + break; + } + + switch (currententity->model->type) + { + case mod_brush: + R_DrawBrushModel (currententity); + break; + + default: + break; + } + } + + for (i=0 ; imodel->type) + { + case mod_sprite: + R_DrawSpriteModel (currententity); + break; + } + } +} + +// Nehahra - Model_Alpha (Function by FrikaC) +/* +============= +R_DrawTransEntities +============= +*/ +/* +void R_DrawTransEntities (void) +{ + // need to draw back to front + // fixme: this isn't my favorite option + int i; + float bestdist, dist; + entity_t *bestent; + vec3_t start, test; + + VectorCopy(r_refdef.vieworg, start); + + if (!r_drawentities.value) + return; + +transgetent: + bestdist = 0; + for (i=0 ; itransignore) + continue; + if (currententity->transparency == 1 || currententity->transparency ==0) + continue; + + VectorCopy(currententity->origin, test); + if (currententity->model->type == mod_brush) + { + test[0] += currententity->model->mins[0]; + test[1] += currententity->model->mins[1]; + test[2] += currententity->model->mins[2]; + } + dist = (((test[0] - start[0]) * (test[0] - start[0])) + + ((test[1] - start[1]) * (test[1] - start[1])) + + ((test[2] - start[2]) * (test[2] - start[2]))); + + if (dist > bestdist) + { + bestdist = dist; + bestent = currententity; + + } + } + if (bestdist == 0) + return; + bestent->transignore = true; + + currententity = bestent; + switch (currententity->model->type) + { + case mod_alias: + R_DrawAliasModel (currententity); + break; + case mod_brush: + R_DrawBrushModel (currententity); + break; + default: + break; + } + + goto transgetent; + +} +*/ +/* +============= +R_DrawViewModel +============= +*/ +void R_DrawViewModel (void) +{ + /* LordHavoc: .lit support, this code was completely useless + float ambient[4], diffuse[4]; + int j; + int lnum; + vec3_t dist; + float add; + dlight_t *dl; + int ambientlight, shadelight; + */ + + if (!r_drawviewmodel.value || chase_active.value || envmap || !r_drawentities.value || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.model) + return; + + currententity = &cl.viewent; + + // Tomaz - QC Alpha Scale Begin + + currententity->alpha = cl_entities[cl.viewentity].alpha; + currententity->scale = cl_entities[cl.viewentity].scale; + + // Tomaz - QC Alpha Scale End + + /* LordHavoc: .lit support, this code was completely useless + j = R_LightPoint (currententity->origin); + + if (j < 16) + j = 16; // allways give some light on gun + ambientlight = j; + shadelight = j; + +// add dynamic lights + for (lnum=0 ; lnumradius) + continue; + if (!dl->radius) + continue; + if (dl->die < cl.time) + continue; + + VectorSubtract (currententity->origin, dl->origin, dist); + add = dl->radius - Length(dist); + if (add > 0) + ambientlight += int(add); + } + + ambient[0] = ambient[1] = ambient[2] = ambient[3] = (float)ambientlight;// / 128; + diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = (float)shadelight;// / 128; + */ + + // hack the depth range to prevent view model from poking into walls + sceGuDepthRange(0, 19660); + + // fenix@io.com: model transform interpolation + old_i_model_transform = r_i_model_transform.value; + r_i_model_transform.value = false; + R_DrawAliasModel (currententity); + r_i_model_transform.value = old_i_model_transform; + + sceGuDepthRange(0, 65535); + +// sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); +// sceGuDisable(GU_BLEND); +} + + +/* +============ +R_PolyBlend +============ +*/ +void R_PolyBlend (void) +{ +/* if (!gl_polyblend.value) + return;*/ + if (!v_blend[3]) + return; +/* + GL_DisableMultitexture(); + + glDisable (GL_ALPHA_TEST); + glEnable (GL_BLEND); + glDisable (GL_DEPTH_TEST); + glDisable (GL_TEXTURE_2D); + + glLoadIdentity (); + + glRotatef (-90, 1, 0, 0); // put Z going up + glRotatef (90, 0, 0, 1); // put Z going up + + glColor4fv (v_blend); + + glBegin (GL_QUADS); + + glVertex3f (10, 100, 100); + glVertex3f (10, -100, 100); + glVertex3f (10, -100, -100); + glVertex3f (10, 100, -100); + glEnd (); + + glDisable (GL_BLEND); + glEnable (GL_TEXTURE_2D); + glEnable (GL_ALPHA_TEST);*/ +} + + +static int SignbitsForPlane (mplane_t *out) +{ + int bits, j; + + // for fast box on planeside test + + bits = 0; + for (j=0 ; j<3 ; j++) + { + if (out->normal[j] < 0) + bits |= 1< 1) + { + Cvar_Set ("r_fullbright", "0"); + Cvar_Set ("r_lightmap", "0"); + Cvar_Set ("r_showtris", "0"); + } + + R_AnimateLight (); + + r_framecount++; + +// build the transformation matrix for the given view angles + VectorCopy (r_refdef.vieworg, r_origin); + + AngleVectors (r_refdef.viewangles, vpn, vright, vup); + +// current viewleaf + r_oldviewleaf = r_viewleaf; + r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel); + + V_SetContentsColor (r_viewleaf->contents); + /* + V_CalcBlend (); + */ + + r_cache_thrash = qfalse; + + c_brush_polys = 0; + c_alias_polys = 0; + +} + + +/* +============= +R_SetupGL +============= +*/ +void R_SetupGL (void) +{ + float screenaspect; + extern int glwidth, glheight; + int x, x2, y2, y, w, h; + float fovx, fovy; //johnfitz + int contents; //johnfitz + + // + // set up viewpoint + // + /* + glMatrixMode(GL_PROJECTION); + glLoadIdentity (); + */ + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadIdentity(); + + x = r_refdef.vrect.x * glwidth/vid.width; + x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/vid.width; + y = (vid.height-r_refdef.vrect.y) * glheight/vid.height; + y2 = (vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/vid.height; + + // fudge around because of frac screen scale + if (x > 0) + x--; + if (x2 < glwidth) + x2++; + if (y2 < 0) + y2--; + if (y < glheight) + y++; + + w = x2 - x; + h = y - y2; + + if (envmap) + { + x = y2 = 0; + w = h = 256; + } + + sceGuViewport( + glx, + gly + (glheight / 2) - y2 - (h / 2), + w, + h); + sceGuScissor(x, glheight - y2 - h, x + w, glheight - y2); + + screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height; + + //johnfitz -- warp view for underwater + fovx = screenaspect; + fovy = r_refdef.fov_y; +// if (r_waterwarp.value) +// { + contents = Mod_PointInLeaf (r_origin, cl.worldmodel)->contents; + if (contents == CONTENTS_WATER || + contents == CONTENTS_SLIME || + contents == CONTENTS_LAVA) + { + //variance should be a percentage of width, where width = 2 * tan(fov / 2) + //otherwise the effect is too dramatic at high FOV and too subtle at low FOV + //what a mess! + fovx = atan(tan(DEG2RAD(r_refdef.fov_x) / 2) * (0.97 + sin(cl.time * 1) * 0.04)) * 2 / M_PI_DIV_180; + fovy = atan(tan(DEG2RAD(r_refdef.fov_y) / 2) * (1.03 - sin(cl.time * 2) * 0.04)) * 2 / M_PI_DIV_180; + + //old method where variance was a percentage of fov + //fovx = r_refdef.fov_x * (0.98 + sin(cl.time * 1.5) * 0.02); + //fovy = r_refdef.fov_y * (1.02 - sin(cl.time * 1.5) * 0.02); + } +// } + + sceGumPerspective(fovy, screenaspect, 4, 4096); + + if (mirror) + { + if (mirror_plane->normal[2]) + { + /*glScalef (1, -1, 1);*/ + } + else + { + /*glScalef (-1, 1, 1);*/ + } + /*glCullFace(GL_BACK);*/ + } + else + { + /*glCullFace(GL_FRONT);*/ + } + sceGumUpdateMatrix(); + + /*glMatrixMode(GL_MODELVIEW); + glLoadIdentity ();*/ + sceGumMatrixMode(GU_VIEW); + sceGumLoadIdentity(); + + /*glRotatef (-90, 1, 0, 0); // put Z going up*/ + sceGumRotateX(-90 * (GU_PI / 180.0f)); + + /*glRotatef (90, 0, 0, 1); // put Z going up*/ + sceGumRotateZ(90 * (GU_PI / 180.0f)); + + /*glRotatef (-r_refdef.viewangles[2], 1, 0, 0);*/ + sceGumRotateX(-r_refdef.viewangles[2] * (GU_PI / 180.0f)); + + /*glRotatef (-r_refdef.viewangles[0], 0, 1, 0);*/ + sceGumRotateY(-r_refdef.viewangles[0] * (GU_PI / 180.0f)); + + /*glRotatef (-r_refdef.viewangles[1], 0, 0, 1);*/ + sceGumRotateZ(-r_refdef.viewangles[1] * (GU_PI / 180.0f)); + + /*glTranslatef (-r_refdef.vieworg[0], -r_refdef.vieworg[1], -r_refdef.vieworg[2]);*/ + const ScePspFVector3 translation = { + -r_refdef.vieworg[0], + -r_refdef.vieworg[1], + -r_refdef.vieworg[2] + }; + sceGumTranslate(&translation); + + /*glGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);*/ + sceGumStoreMatrix(&r_world_matrix); + sceGumUpdateMatrix(); + + sceGumMatrixMode(GU_MODEL); + + clipping::begin_frame(); + + // + // set drawing parms + // + /* + if (gl_cull.value) + { + glEnable(GL_CULL_FACE); + } + else + { + glDisable(GL_CULL_FACE); + } + + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glEnable(GL_DEPTH_TEST);*/ + sceGuDisable(GU_BLEND); + sceGuDisable(GU_ALPHA_TEST); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); +} + +/* +================ +R_RenderScene + +r_refdef must be set before the first call +================ +*/ +void R_RenderScene (void) +{ + R_SetupFrame (); + + R_SetFrustum (); + + R_SetupGL (); + + R_MarkLeaves (); // done here so we know if we're in water +/* + // Set up fogging. + + if (r_refdef.fog_end == 0) + r_refdef.fog_end = -1; + else + { + sceGuEnable ( GU_FOG ); + sceGuFog ( r_refdef.fog_start, r_refdef.fog_end, GU_COLOR( r_refdef.fog_red * 0.01f, r_refdef.fog_green * 0.01f, r_refdef.fog_blue * 0.01f, 1.0f ) ); + } +*/ + Fog_EnableGFog (); //johnfitz + + R_DrawWorld (); // adds static entities to the list + + S_ExtraUpdate (); // don't let sound get messed up if going slow + + R_DrawEntitiesOnList (); + + /*GL_DisableMultitexture();*/ + + R_RenderDlights (); + + R_DrawWaterSurfaces (); + + R_DrawParticles (); + + R_DrawViewModel (); + + Fog_DisableGFog (); //johnfitz +#ifdef GLTEST + Test_Draw (); +#endif + +} + +/* +============= +R_Clear +============= +*/ +void R_Clear (void) +{ + if(r_refdef.fog_end > 0 && r_skyfog.value) + { + sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT); + sceGuClearColor(GU_COLOR(r_refdef.fog_red * 0.01f,r_refdef.fog_green * 0.01f,r_refdef.fog_blue * 0.01f,1.0f)); + } + else + { + sceGuClear(GU_DEPTH_BUFFER_BIT); +// sceGuClearColor(GU_COLOR(0.25f,0.25f,0.25f,0.5f)); + } + + if (r_mirroralpha.value != 1.0) + { + /* + gldepthmin = 0; + gldepthmax = 0.5; + glDepthFunc (GL_LEQUAL); + */ + } + else + { + /* + gldepthmin = 0; + gldepthmax = 1; + glDepthFunc (GL_LEQUAL);*/ + } + + /*glDepthRange (gldepthmin, gldepthmax);*/ +} + +/* +============= +R_Mirror +============= + +void R_Mirror (void) +{ + + msurface_t *s; + +if(!kurok) +{ + + float d; + entity_t *ent; + + if (!mirror) + return; + + r_base_world_matrix = r_world_matrix; + + d = DotProduct (r_refdef.vieworg, mirror_plane->normal) - mirror_plane->dist; + VectorMA (r_refdef.vieworg, -2*d, mirror_plane->normal, r_refdef.vieworg); + + d = DotProduct (vpn, mirror_plane->normal); + VectorMA (vpn, -2*d, mirror_plane->normal, vpn); + + r_refdef.viewangles[0] = -asinf(vpn[2])/M_PI*180; + r_refdef.viewangles[1] = atan2f(vpn[1], vpn[0])/M_PI*180; + r_refdef.viewangles[2] = -r_refdef.viewangles[2]; + + ent = &cl_entities[cl.viewentity]; + if (cl_numvisedicts < MAX_VISEDICTS) + { + cl_visedicts[cl_numvisedicts] = ent; + cl_numvisedicts++; + } + + R_RenderScene (); + R_DrawWaterSurfaces (); + + if (mirror_plane->normal[2]) + { + + } + else + { + + } + + s = cl.worldmodel->textures[mirrortexturenum]->texturechain; + for ( ; s ; s=s->texturechain) + R_RenderBrushPoly (s); + cl.worldmodel->textures[mirrortexturenum]->texturechain = NULL; +} +else +{ + s = cl.worldmodel->textures[mirrortexturenum]->texturechain; + for ( ; s ; s=s->texturechain) + R_RenderBrushPoly (s); + cl.worldmodel->textures[mirrortexturenum]->texturechain = NULL; +} + +} +*/ + +/* +====================== +R_Fog_f +====================== +*/ +/* +void R_Fog_f (void) +{ + if (Cmd_Argc () == 1) + { + Con_Printf("\"fog\" is \"%f %f %f %f %f\"\n", r_refdef.fog_start, r_refdef.fog_end, r_refdef.fog_red, r_refdef.fog_green, r_refdef.fog_blue); + return; + } + r_refdef.fog_start = atof(Cmd_Argv(1)); + r_refdef.fog_end = atof(Cmd_Argv(2)); + r_refdef.fog_red = atof(Cmd_Argv(3)); + r_refdef.fog_green = atof(Cmd_Argv(4)); + r_refdef.fog_blue = atof(Cmd_Argv(5)); +} +*/ +/* +================ +R_RenderView + +r_refdef must be set before the first call +================ +*/ +void R_RenderView (void) +{ + double time1, time2; + int i; + + if (r_norefresh.value) + return; + + if (!r_worldentity.model || !cl.worldmodel) + Sys_Error ("R_RenderView: NULL worldmodel"); + + time1 = 0; + + if (r_speeds.value) + { + /*glFinish ();*/ + time1 = Sys_FloatTime (); + c_brush_polys = 0; + c_alias_polys = 0; + } + + mirror = qfalse; + + R_Clear (); + + // render normal view + + R_RenderScene (); + +// R_DrawTransEntities(); + + // render mirror view +// R_Mirror (); + +// R_PolyBlend (); + + if (r_speeds.value) + { + time2 = Sys_FloatTime (); + Con_Printf ("%3i ms %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys); + } +} diff --git a/r17/Revamped src/revamped_src/psp/video_hardware_mesh.cpp b/r17/Revamped src/revamped_src/psp/video_hardware_mesh.cpp new file mode 100755 index 00000000..12e2181c --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_hardware_mesh.cpp @@ -0,0 +1,311 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ +// gl_mesh.c: triangle model functions + +#include + +extern "C" +{ +#include "../quakedef.h" +} + +/* +================================================================= + +ALIAS MODEL DISPLAY LIST GENERATION + +================================================================= +*/ + +model_t *aliasmodel; +aliashdr_t *paliashdr; + +int used[8192]; + +// the command list holds counts and s/t values that are valid for +// every frame +int commands[8192]; +int numcommands; + +// all frames will have their vertexes rearranged and expanded +// so they are in the order expected by the command list +int vertexorder[8192]; +int numorder; + +int allverts, alltris; + +int stripverts[128]; +int striptris[128]; +int stripcount; + +/* +================ +StripLength +================ +*/ +static int StripLength (int starttri, int startv) +{ + int m1, m2; + int j; + mtriangle_t *last, *check; + int k; + + used[starttri] = 2; + + last = &triangles[starttri]; + + stripverts[0] = last->vertindex[(startv)%3]; + stripverts[1] = last->vertindex[(startv+1)%3]; + stripverts[2] = last->vertindex[(startv+2)%3]; + + striptris[0] = starttri; + stripcount = 1; + + m1 = last->vertindex[(startv+2)%3]; + m2 = last->vertindex[(startv+1)%3]; + + // look for a matching triangle +nexttri: + for (j=starttri+1, check=&triangles[starttri+1] ; jnumtris ; j++, check++) + { + if (check->facesfront != last->facesfront) + continue; + for (k=0 ; k<3 ; k++) + { + if (check->vertindex[k] != m1) + continue; + if (check->vertindex[ (k+1)%3 ] != m2) + continue; + + // this is the next part of the fan + + // if we can't use this triangle, this tristrip is done + if (used[j]) + goto done; + + // the new edge + if (stripcount & 1) + m2 = check->vertindex[ (k+2)%3 ]; + else + m1 = check->vertindex[ (k+2)%3 ]; + + stripverts[stripcount+2] = check->vertindex[ (k+2)%3 ]; + striptris[stripcount] = j; + stripcount++; + + used[j] = 2; + goto nexttri; + } + } +done: + + // clear the temp used flags + for (j=starttri+1 ; jnumtris ; j++) + if (used[j] == 2) + used[j] = 0; + + return stripcount; +} + +/* +=========== +FanLength +=========== +*/ +static int FanLength (int starttri, int startv) +{ + int m1, m2; + int j; + mtriangle_t *last, *check; + int k; + + used[starttri] = 2; + + last = &triangles[starttri]; + + stripverts[0] = last->vertindex[(startv)%3]; + stripverts[1] = last->vertindex[(startv+1)%3]; + stripverts[2] = last->vertindex[(startv+2)%3]; + + striptris[0] = starttri; + stripcount = 1; + + m1 = last->vertindex[(startv+0)%3]; + m2 = last->vertindex[(startv+2)%3]; + + + // look for a matching triangle +nexttri: + for (j=starttri+1, check=&triangles[starttri+1] ; jnumtris ; j++, check++) + { + if (check->facesfront != last->facesfront) + continue; + for (k=0 ; k<3 ; k++) + { + if (check->vertindex[k] != m1) + continue; + if (check->vertindex[ (k+1)%3 ] != m2) + continue; + + // this is the next part of the fan + + // if we can't use this triangle, this tristrip is done + if (used[j]) + goto done; + + // the new edge + m2 = check->vertindex[ (k+2)%3 ]; + + stripverts[stripcount+2] = m2; + striptris[stripcount] = j; + stripcount++; + + used[j] = 2; + goto nexttri; + } + } +done: + + // clear the temp used flags + for (j=starttri+1 ; jnumtris ; j++) + if (used[j] == 2) + used[j] = 0; + + return stripcount; +} + + +/* +================ +BuildTris + +Generate a list of trifans or strips +for the model, which holds for all frames +================ +*/ +static void BuildTris (void) +{ + int i, j, k; + int startv; + float s, t; + int len, bestlen, besttype; + int bestverts[1024]; + int besttris[1024]; + int type; + + // + // build tristrips + // + besttype = 0; + numorder = 0; + numcommands = 0; + memset (used, 0, sizeof(used)); + for (i=0 ; inumtris ; i++) + { + // pick an unused triangle and start the trifan + if (used[i]) + continue; + + bestlen = 0; + for (type = 0 ; type < 2 ; type++) +// type = 1; + { + for (startv =0 ; startv < 3 ; startv++) + { + if (type == 1) + len = StripLength (i, startv); + else + len = FanLength (i, startv); + if (len > bestlen) + { + besttype = type; + bestlen = len; + for (j=0 ; jskinwidth / 2; // on back side + s = (s + 0.5) / pheader->skinwidth; + t = (t + 0.5) / pheader->skinheight; + + *(float *)&commands[numcommands++] = s; + *(float *)&commands[numcommands++] = t; + } + } + + commands[numcommands++] = 0; // end of list marker + + Con_DPrintf ("%3i tri %3i vert %3i cmd\n", pheader->numtris, numorder, numcommands); + + allverts += numorder; + alltris += pheader->numtris; +} + +/* +================ +GL_MakeAliasModelDisplayLists +================ +*/ +void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr) +{ + aliasmodel = m; + paliashdr = hdr; // (aliashdr_t *)Mod_Extradata (m); + + BuildTris (); // trifans or lists + + // save the data out + + paliashdr->poseverts = numorder; + + int* cmds = static_cast(Hunk_Alloc (numcommands * 4)); + paliashdr->commands = (byte *)cmds - (byte *)paliashdr; + memcpy (cmds, commands, numcommands * 4); + + trivertx_t* verts = static_cast(Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts + * sizeof(trivertx_t) )); + paliashdr->posedata = (byte *)verts - (byte *)paliashdr; + for (int i=0 ; inumposes ; i++) + for (int j=0 ; j +#include + +extern "C" +{ +#include "../quakedef.h" +void VLight_ResetAnormTable(); +} + +void GL_InitTextureUsage (); + +/* +================== +R_InitTextures +================== +*/ +void R_InitTextures (void) +{ + int x,y, m; + byte *dest; + + GL_InitTextureUsage (); + +// create a simple checkerboard texture for the default + r_notexture_mip = static_cast(Hunk_AllocName (sizeof(texture_t) + 16*16+8*8+4*4+2*2, "notexture")); + + r_notexture_mip->width = r_notexture_mip->height = 16; + r_notexture_mip->offsets[0] = sizeof(texture_t); + r_notexture_mip->offsets[1] = r_notexture_mip->offsets[0] + 16*16; + r_notexture_mip->offsets[2] = r_notexture_mip->offsets[1] + 8*8; + r_notexture_mip->offsets[3] = r_notexture_mip->offsets[2] + 4*4; + + for (m=0 ; m<4 ; m++) + { + dest = (byte *)r_notexture_mip + r_notexture_mip->offsets[m]; + for (y=0 ; y< (16>>m) ; y++) + for (x=0 ; x< (16>>m) ; x++) + { + if ( (y< (8>>m) ) ^ (x< (8>>m) ) ) + *dest++ = 0; + else + *dest++ = 0xff; + } + } +} +/* +byte dottexture[8][8] = +{ + {0,1,1,0,0,0,0,0}, + {1,1,1,1,0,0,0,0}, + {1,1,1,1,0,0,0,0}, + {0,1,1,0,0,0,0,0}, + {0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0}, +}; + +void R_InitParticleTexture (void) +{ + int x,y; + byte data[8][8][2]; + + // + // particle texture + // + + for (x=0 ; x<8 ; x++) + { + for (y=0 ; y<8 ; y++) + { + data[y][x][0] = (dottexture[x][y])*0xF0 | (dottexture[x][y])*0x0F; + data[y][x][1] = (dottexture[x][y])*0xF0 | (dottexture[x][y])*0x0F; + } + } + particletexture = GL_LoadTextureLM ("_particle_", 8, 8, &data[0][0][0], 2, GU_LINEAR, qtrue); +} +*/ +byte dottexture2[16][16] = +{ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0}, + {0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0}, + {0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0}, + {0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0}, + {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, + {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, + {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, + {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, + {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, + {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, + {0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0}, + {0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0}, + {0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0}, + {0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +}; + +void R_InitParticleTexture (void) +{ + int x,y; + byte data[16][16][2]; + + // + // particle texture + // + + for (x=0 ; x<16 ; x++) + { + for (y=0 ; y<16 ; y++) + { + data[y][x][0] = (dottexture2[x][y])*0xF0 | (dottexture2[x][y])*0x0F; + data[y][x][1] = (dottexture2[x][y])*0xF0 | (dottexture2[x][y])*0x0F; + } + } + particletexture = GL_LoadTextureLM ("_particle_", 16, 16, &data[0][0][0], 2, GU_LINEAR, qtrue); +} + +/* +=============== +R_Envmap_f + +Grab six views for environment mapping tests +=============== +*/ +void R_Envmap_f (void) +{ + byte buffer[256*256*4]; +// char name[1024]; + + /*glDrawBuffer (GL_FRONT); + glReadBuffer (GL_FRONT);*/ + envmap = qtrue; + + r_refdef.vrect.x = 0; + r_refdef.vrect.y = 0; + r_refdef.vrect.width = 256; + r_refdef.vrect.height = 256; + + r_refdef.viewangles[0] = 0; + r_refdef.viewangles[1] = 0; + r_refdef.viewangles[2] = 0; + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + R_RenderView (); + /*glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);*/ + COM_WriteFile ("env0.rgb", buffer, sizeof(buffer)); + + r_refdef.viewangles[1] = 90; + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + R_RenderView (); + /*glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);*/ + COM_WriteFile ("env1.rgb", buffer, sizeof(buffer)); + + r_refdef.viewangles[1] = 180; + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + R_RenderView (); + /*glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);*/ + COM_WriteFile ("env2.rgb", buffer, sizeof(buffer)); + + r_refdef.viewangles[1] = 270; + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + R_RenderView (); + /*glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);*/ + COM_WriteFile ("env3.rgb", buffer, sizeof(buffer)); + + r_refdef.viewangles[0] = -90; + r_refdef.viewangles[1] = 0; + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + R_RenderView (); + /*glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);*/ + COM_WriteFile ("env4.rgb", buffer, sizeof(buffer)); + + r_refdef.viewangles[0] = 90; + r_refdef.viewangles[1] = 0; + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + R_RenderView (); + /*glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);*/ + COM_WriteFile ("env5.rgb", buffer, sizeof(buffer)); + + envmap = qfalse; + /*glDrawBuffer (GL_BACK); + glReadBuffer (GL_BACK);*/ + GL_EndRendering (); +} + +/* +=============== +R_Init +=============== +*/ +void R_Init (void) +{ +// extern byte *hunk_base; + /*extern cvar_t gl_finish;*/ + + Cmd_AddCommand ("timerefresh", R_TimeRefresh_f); + Cmd_AddCommand ("envmap", R_Envmap_f); + Cmd_AddCommand ("pointfile", R_ReadPointFile_f); + +// Cmd_AddCommand ("fog", R_Fog_f); + + Cvar_RegisterVariable (&r_showtris); + Cvar_RegisterVariable (&r_skyfog); + Cvar_RegisterVariable (&r_skyclip); + Cvar_RegisterVariable (&r_menufade); + Cvar_RegisterVariable (&r_norefresh); + Cvar_RegisterVariable (&r_lightmap); + Cvar_RegisterVariable (&r_fullbright); + Cvar_RegisterVariable (&r_drawentities); + Cvar_RegisterVariable (&r_drawviewmodel); + Cvar_RegisterVariable (&r_shadows); + Cvar_RegisterVariable (&r_mirroralpha); + Cvar_RegisterVariable (&r_glassalpha); + Cvar_RegisterVariable (&r_wateralpha); + Cvar_RegisterVariable (&r_dynamic); + Cvar_RegisterVariable (&r_novis); + Cvar_RegisterVariable (&r_speeds); + Cvar_RegisterVariable (&r_tex_scale_down); + Cvar_RegisterVariable (&r_particles_simple); + Cvar_RegisterVariable (&r_vsync); + Cvar_RegisterVariable (&r_dithering); + Cvar_RegisterVariable (&r_test); + Cvar_RegisterVariable (&r_mipmaps); + Cvar_RegisterVariable (&r_mipmaps_func); + Cvar_RegisterVariable (&r_mipmaps_bias); + Cvar_RegisterVariable (&r_antialias); + Cvar_RegisterVariable (&r_i_model_animation); + Cvar_RegisterVariable (&r_i_model_transform); + Cvar_RegisterVariable (&r_model_contrast); + Cvar_RegisterVariable (&r_model_brightness); + + Cvar_RegisterVariable (&gl_keeptjunctions); + + // RIOT - Vertex lighting + + Cvar_RegisterVariable(&vlight); + Cvar_RegisterVariable(&vlight_pitch); + Cvar_RegisterVariable(&vlight_yaw); + Cvar_RegisterVariable(&vlight_highcut); + Cvar_RegisterVariable(&vlight_lowcut); + +/* + Cvar_RegisterVariable (&gl_finish); + Cvar_RegisterVariable (&gl_clear); + Cvar_RegisterVariable (&gl_texsort); + + if (gl_mtexable) + Cvar_SetValue ("gl_texsort", 0.0); + + Cvar_RegisterVariable (&gl_cull); + Cvar_RegisterVariable (&gl_smoothmodels); + Cvar_RegisterVariable (&gl_affinemodels); + Cvar_RegisterVariable (&gl_polyblend); + Cvar_RegisterVariable (&gl_flashblend); + Cvar_RegisterVariable (&gl_playermip); + Cvar_RegisterVariable (&gl_nocolors); + + Cvar_RegisterVariable (&gl_reporttjunctions); + + Cvar_RegisterVariable (&gl_doubleeyes); +*/ + if(vlight.value) + VLight_ResetAnormTable(); + + R_InitParticles (); + R_InitParticleTexture (); + + Sky_Init (); //johnfitz + Fog_Init (); //johnfitz + +#ifdef GLTEST + Test_Init (); +#endif + + /* + playertextures = texture_extension_number; + texture_extension_number += 16; + */ +} + +/* +=============== +R_TranslatePlayerSkin + +Translates a skin texture by the per-player color lookup +=============== +*/ +void R_TranslatePlayerSkin (int playernum) +{ + int top, bottom; + byte translate[256]; + unsigned translate32[256]; + int i, j, s; + model_t *model; + aliashdr_t *paliashdr; + byte *original; + unsigned pixels[512*256];//, *out; + unsigned scaled_width, scaled_height; + int inwidth, inheight; + byte *inrow; + unsigned frac, fracstep; +// extern byte **player_8bit_texels_tbl; + + /*GL_DisableMultitexture();*/ + + top = cl.scores[playernum].colors & 0xf0; + bottom = (cl.scores[playernum].colors &15)<<4; + + for (i=0 ; i<256 ; i++) + translate[i] = i; + + for (i=0 ; i<16 ; i++) + { + if (top < 128) // the artists made some backwards ranges. sigh. + translate[TOP_RANGE+i] = top+i; + else + translate[TOP_RANGE+i] = top+15-i; + + if (bottom < 128) + translate[BOTTOM_RANGE+i] = bottom+i; + else + translate[BOTTOM_RANGE+i] = bottom+15-i; + } + + // + // locate the original skin pixels + // + currententity = &cl_entities[1+playernum]; + model = currententity->model; + if (!model) + return; // player doesn't have a model yet + if (model->type != mod_alias) + return; // only translate skins on alias models + + paliashdr = (aliashdr_t *)Mod_Extradata (model); + s = paliashdr->skinwidth * paliashdr->skinheight; + if (currententity->skinnum < 0 || currententity->skinnum >= paliashdr->numskins) { + Con_Printf("(%d): Invalid player skin #%d\n", playernum, currententity->skinnum); + original = (byte *)paliashdr + paliashdr->texels[0]; + } else + original = (byte *)paliashdr + paliashdr->texels[currententity->skinnum]; + if (s & 3) + Sys_Error ("R_TranslateSkin: s&3"); + + inwidth = paliashdr->skinwidth; + inheight = paliashdr->skinheight; + + // because this happens during gameplay, do it fast + // instead of sending it through gl_upload 8 + /*GL_Bind(playertextures + playernum);*/ + +#if 0 + byte translated[320*200]; + + for (i=0 ; iskinwidth, paliashdr->skinheight, qfalse, qfalse, qtrue); +#else + scaled_width = 512; + scaled_height = 256; + + /*if (VID_Is8bit())*/ + { // 8bit texture upload + byte *out2; + + out2 = (byte *)pixels; + memset(pixels, 0, sizeof(pixels)); + fracstep = inwidth*0x10000/scaled_width; + for (i=0 ; i<(signed)scaled_height ; i++, out2 += scaled_width) + { + inrow = original + inwidth*(i*inheight/scaled_height); + frac = fracstep >> 1; + for (j=0 ; j<(signed)scaled_width ; j+=4) + { + out2[j] = translate[inrow[frac>>16]]; + frac += fracstep; + out2[j+1] = translate[inrow[frac>>16]]; + frac += fracstep; + out2[j+2] = translate[inrow[frac>>16]]; + frac += fracstep; + out2[j+3] = translate[inrow[frac>>16]]; + frac += fracstep; + } + } + + /*GL_Upload8((byte *)pixels, scaled_width, scaled_height, qfalse, qfalse);*/ + return; + } + + + for (i=0 ; i<256 ; i++) + translate32[i] = d_8to24table[translate[i]]; +/* + out = pixels; + fracstep = inwidth*0x10000/scaled_width; + for (i=0 ; i> 1; + for (j=0 ; j>16]]; + frac += fracstep; + out[j+1] = translate32[inrow[frac>>16]]; + frac += fracstep; + out[j+2] = translate32[inrow[frac>>16]]; + frac += fracstep; + out[j+3] = translate32[inrow[frac>>16]]; + frac += fracstep; + } + } + glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + */ +#endif + +} + + +/* +=============== +R_NewMap +=============== +*/ +void R_NewMap (void) +{ + int i; + + for (i=0 ; i<256 ; i++) + d_lightstylevalue[i] = 264; // normal light value + + memset (&r_worldentity, 0, sizeof(r_worldentity)); + r_worldentity.model = cl.worldmodel; + +// clear out efrags in case the level hasn't been reloaded +// FIXME: is this one short? + for (i=0 ; inumleafs ; i++) + cl.worldmodel->leafs[i].efrags = NULL; + + r_viewleaf = NULL; + R_ClearParticles (); + + GL_BuildLightmaps (); + + Sky_NewMap (); //johnfitz -- skybox in worldspawn + Fog_NewMap (); //johnfitz -- global fog in worldspawn + + // Reset these back to normal. + if(kurok) + Cbuf_AddText ("viewsize 120\n chase_active 0\n"); + + // identify sky texture + skytexturenum = -1; + mirrortexturenum = -1; + + for (i=0 ; inumtextures ; i++) + { + if (!cl.worldmodel->textures[i]) + continue; + if (!Q_strncmp(cl.worldmodel->textures[i]->name,"sky",3) ) + skytexturenum = i; + if(!kurok) + { + if (!Q_strncmp(cl.worldmodel->textures[i]->name,"window02_1",10) ) + mirrortexturenum = i; + } + else + { + if (!Q_strncmp(cl.worldmodel->textures[i]->name,"glass",5) ) + mirrortexturenum = i; + } + cl.worldmodel->textures[i]->texturechain = NULL; + } +} + + +/* +==================== +R_TimeRefresh_f + +For program optimization +==================== +*/ +void R_TimeRefresh_f (void) +{ + int i; + double start, stop, time; +// int startangle; +// vrect_t vr; + + + start = Sys_FloatTime (); + for (i=0 ; i<128 ; i++) + { + r_refdef.viewangles[1] = i/128.0*360.0; + R_RenderView (); + } + + stop = Sys_FloatTime (); + time = stop-start; + if (time > 0) + Con_Printf ("%f seconds (%f fps)\n", time, 128/time); + + GL_EndRendering (); +} + +void D_FlushCaches (void) +{ +} + + diff --git a/r17/Revamped src/revamped_src/psp/video_hardware_model.cpp b/r17/Revamped src/revamped_src/psp/video_hardware_model.cpp new file mode 100755 index 00000000..66cb9660 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_hardware_model.cpp @@ -0,0 +1,2036 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ +// models.c -- model loading and caching + +// models are the only shared resource between a client and server running +// on the same machine. + +extern "C" +{ +#include "../quakedef.h" +} +#include +#include + +#include "lightmaps.h" +#include + +int LIGHTMAP_BYTES; +int MAX_LIGHTMAPS; + +using namespace std; + +list mapTextureNameList; + +model_t *loadmodel; +char loadname[32]; // for hunk tags + +void Mod_LoadSpriteModel (model_t *mod, void *buffer); +void Mod_LoadBrushModel (model_t *mod, void *buffer); +void Mod_LoadAliasModel (model_t *mod, void *buffer); +model_t *Mod_LoadModel (model_t *mod, qboolean crash); + +byte mod_novis[MAX_MAP_LEAFS/8]; + +#define MAX_MOD_KNOWN 512 +model_t mod_known[MAX_MOD_KNOWN]; +int mod_numknown; + +cvar_t gl_subdivide_size = {"gl_subdivide_size", "256", qtrue}; + +extern int solidskytexture; +extern int alphaskytexture; +/* +extern int sky_rt; +extern int sky_bk; +extern int sky_lf; +extern int sky_ft; +extern int sky_up; +extern int sky_dn; +*/ +/* +=============== +Mod_Init +=============== +*/ +void Mod_Init (void) +{ + Cvar_RegisterVariable (&gl_subdivide_size); + memset (mod_novis, 0xff, sizeof(mod_novis)); +} + +/* +=============== +Mod_Init + +Caches the data if needed +=============== +*/ +void *Mod_Extradata (model_t *mod) +{ + void *r; + + r = Cache_Check (&mod->cache); + if (r) + return r; + + Mod_LoadModel (mod, qtrue); + + if (!mod->cache.data) + Sys_Error ("Mod_Extradata: caching failed"); + return mod->cache.data; +} + +/* +=============== +Mod_PointInLeaf +=============== +*/ +mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) +{ + mnode_t *node; + float d; + mplane_t *plane; + + if (!model || !model->nodes) + Sys_Error ("Mod_PointInLeaf: bad model"); + + node = model->nodes; + while (1) + { + if (node->contents < 0) + return (mleaf_t *)node; + plane = node->plane; + d = DotProduct (p,plane->normal) - plane->dist; + if (d > 0) + node = node->children[0]; + else + node = node->children[1]; + } + + return NULL; // never reached +} + + +/* +=================== +Mod_DecompressVis +=================== +*/ +byte *Mod_DecompressVis (byte *in, model_t *model) +{ + static byte decompressed[MAX_MAP_LEAFS/8]; + int c; + byte *out; + int row; + + row = (model->numleafs+7)>>3; + out = decompressed; + +#if 0 + memcpy (out, in, row); +#else + if (!in) + { // no vis info, so make all visible + while (row) + { + *out++ = 0xff; + row--; + } + return decompressed; + } + + do + { + if (*in) + { + *out++ = *in++; + continue; + } + + c = in[1]; + in += 2; + while (c) + { + *out++ = 0; + c--; + } + } while (out - decompressed < row); +#endif + + return decompressed; +} + +byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model) +{ + if (leaf == model->leafs) + return mod_novis; + return Mod_DecompressVis (leaf->compressed_vis, model); +} + +/* +=================== +Mod_ClearAll +=================== +*/ +void Mod_ClearAll (void) +{ + int i,texture_index; + model_t *mod; + + for (i=0 , mod=mod_known ; itype != mod_alias) { + mod->needload = qtrue; + } + } + // maybe we should check if it is new map or not + // (so we dont unload textures unnecessary) + while (mapTextureNameList.size() > 0) { + texture_index = mapTextureNameList.front(); + mapTextureNameList.pop_front(); + GL_UnloadTexture(texture_index); + } + + solidskytexture = -1; + alphaskytexture = -1; + + //purge old sky textures + for (i=0; i<6; i++) + { + if (skyimage[i] && skyimage[i] != solidskytexture) + GL_UnloadTexture(skyimage[i]); + skyimage[i] = NULL; + } + + //purge old lightmaps + for (i=0; iname, name) ) + break; + + if (i == mod_numknown) + { + if (mod_numknown == MAX_MOD_KNOWN) + Sys_Error ("mod_numknown == MAX_MOD_KNOWN"); + strcpy (mod->name, name); + mod->needload = qtrue; + mod_numknown++; + } + + return mod; +} + +/* +================== +Mod_TouchModel + +================== +*/ +void Mod_TouchModel (char *name) +{ + model_t *mod; + + mod = Mod_FindName (name); + + if (!mod->needload) + { + if (mod->type == mod_alias) + Cache_Check (&mod->cache); + } +} + +/* +================== +Mod_LoadModel + +Loads a model into the cache +================== +*/ +model_t *Mod_LoadModel (model_t *mod, qboolean crash) +{ + void *d; + unsigned *buf; + byte stackbuf[1024]; // avoid dirtying the cache heap + + if (!mod->needload) + { + if (mod->type == mod_alias) + { + d = Cache_Check (&mod->cache); + if (d) + return mod; + } + else + return mod; // not cached at all + } + +// +// because the world is so huge, load it one piece at a time +// + if (!crash) + { + + } + +// +// load the file +// + buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf)); + if (!buf) + { + if (crash) + Sys_Error ("Mod_NumForName: %s not found", mod->name); + return NULL; + } + +// +// allocate a new model +// + COM_FileBase (mod->name, loadname); + + loadmodel = mod; + +// +// fill it in +// + +// call the apropriate loader + mod->needload = qfalse; + + switch (LittleLong(*(unsigned *)buf)) + { + case IDPOLYHEADER: + Mod_LoadAliasModel (mod, buf); + break; + + case IDSPRITEHEADER: + Mod_LoadSpriteModel (mod, buf); + break; + + default: + Mod_LoadBrushModel (mod, buf); + break; + } + + return mod; +} + +/* +================== +Mod_ForName + +Loads in a model for the given name +================== +*/ +model_t *Mod_ForName (char *name, qboolean crash) +{ + model_t *mod; + + mod = Mod_FindName (name); + + return Mod_LoadModel (mod, crash); +} + + +/* +=============================================================================== + + BRUSHMODEL LOADING + +=============================================================================== +*/ + +byte *mod_base; + +/* +================= +Mod_LoadTextures +================= +*/ +void Mod_LoadTextures (lump_t *l) +{ + int i, j, pixels, num, max, altmax; + miptex_t *mt; + texture_t *tx, *tx2; + texture_t *anims[10]; + texture_t *altanims[10]; + dmiptexlump_t *m; + + if (!l->filelen) + { + loadmodel->textures = NULL; + return; + } + m = (dmiptexlump_t *)(mod_base + l->fileofs); + + m->nummiptex = LittleLong (m->nummiptex); + + loadmodel->numtextures = m->nummiptex; + loadmodel->textures = static_cast(Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname)); + + for (i=0 ; inummiptex ; i++) + { + m->dataofs[i] = LittleLong(m->dataofs[i]); + if (m->dataofs[i] == -1) + continue; + mt = (miptex_t *)((byte *)m + m->dataofs[i]); + mt->width = LittleLong (mt->width); + mt->height = LittleLong (mt->height); + for (j=0 ; joffsets[j] = LittleLong (mt->offsets[j]); + + if ( (mt->width & 15) || (mt->height & 15) ) + Sys_Error ("Texture %s is not 16 aligned", mt->name); + pixels = mt->width*mt->height/64*85; + tx = static_cast(Hunk_AllocName (sizeof(texture_t) , loadname )); + + const std::size_t buffer_size = pixels; + byte* tx_pixels = static_cast(memalign(16, buffer_size)); + if (!tx_pixels) { + Sys_Error("Out of RAM for loading textures"); + } + + loadmodel->textures[i] = tx; + + memcpy (tx->name, mt->name, sizeof(tx->name)); + tx->width = mt->width; + tx->height = mt->height; + for (j=0 ; joffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); + // the pixels immediately follow the structures + memcpy ( tx_pixels, mt+1, pixels); + + if (!Q_strncmp(mt->name,"sky",3)) { + R_InitSky (tx_pixels); + mapTextureNameList.push_back(solidskytexture); + mapTextureNameList.push_back(alphaskytexture); + } +/* + else if (!Q_strncmp(mt->name,"sbox_rt",7)) { + R_InitSkyBox_RT (tx_pixels); + mapTextureNameList.push_back(sky_rt); + } + else if (!Q_strncmp(mt->name,"sbox_bk",7)) { + R_InitSkyBox_BK (tx_pixels); + mapTextureNameList.push_back(sky_bk); + } + else if (!Q_strncmp(mt->name,"sbox_lf",7)) { + R_InitSkyBox_LF (tx_pixels); + mapTextureNameList.push_back(sky_lf); + } + else if (!Q_strncmp(mt->name,"sbox_ft",7)) { + R_InitSkyBox_FT (tx_pixels); + mapTextureNameList.push_back(sky_ft); + } + else if (!Q_strncmp(mt->name,"sbox_up",7)) { + R_InitSkyBox_UP (tx_pixels); + mapTextureNameList.push_back(sky_up); + } + else if (!Q_strncmp(mt->name,"sbox_dn",7)) { + R_InitSkyBox_DN (tx_pixels); + mapTextureNameList.push_back(sky_dn); + } +*/ + else + { + int level = 0; + if (r_mipmaps.value > 0) + level = 3; + tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx_pixels), qtrue, GU_LINEAR, level); + mapTextureNameList.push_back(tx->gl_texturenum); + } + free (tx_pixels); + } + +// +// sequence the animations +// + for (i=0 ; inummiptex ; i++) + { + tx = loadmodel->textures[i]; + if (!tx || tx->name[0] != '+') + continue; + if (tx->anim_next) + continue; // allready sequenced + + // find the number of frames in the animation + memset (anims, 0, sizeof(anims)); + memset (altanims, 0, sizeof(altanims)); + + max = tx->name[1]; + altmax = 0; + if (max >= 'a' && max <= 'z') + max -= 'a' - 'A'; + if (max >= '0' && max <= '9') + { + max -= '0'; + altmax = 0; + anims[max] = tx; + max++; + } + else if (max >= 'A' && max <= 'J') + { + altmax = max - 'A'; + max = 0; + altanims[altmax] = tx; + altmax++; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + + for (j=i+1 ; jnummiptex ; j++) + { + tx2 = loadmodel->textures[j]; + if (!tx2 || tx2->name[0] != '+') + continue; + if (strcmp (tx2->name+2, tx->name+2)) + continue; + + num = tx2->name[1]; + if (num >= 'a' && num <= 'z') + num -= 'a' - 'A'; + if (num >= '0' && num <= '9') + { + num -= '0'; + anims[num] = tx2; + if (num+1 > max) + max = num + 1; + } + else if (num >= 'A' && num <= 'J') + { + num = num - 'A'; + altanims[num] = tx2; + if (num+1 > altmax) + altmax = num+1; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + } + +#define ANIM_CYCLE 2 + // link them all together + for (j=0 ; jname); + tx2->anim_total = max * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = anims[ (j+1)%max ]; + if (altmax) + tx2->alternate_anims = altanims[0]; + } + for (j=0 ; jname); + tx2->anim_total = altmax * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = altanims[ (j+1)%altmax ]; + if (max) + tx2->alternate_anims = anims[0]; + } + } +} + +/* +================= +Mod_LoadLighting +================= +*/ +void Mod_LoadLighting (lump_t *l) +{ + // LordHavoc: .lit support begin + /* LordHavoc: original code + if (!l->filelen) + { + loadmodel->lightdata = NULL; + return; + } + loadmodel->lightdata = static_cast(Hunk_AllocName ( l->filelen, loadname)); + memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); + */ + + int i; + byte *in, *out, *data; + byte d; + char litfilename[1024]; + loadmodel->lightdata = NULL; + // LordHavoc: check for a .lit file + strcpy(litfilename, loadmodel->name); + COM_StripExtension(litfilename, litfilename); + strcat(litfilename, ".lit"); + data = (byte*) COM_LoadHunkFile (litfilename); + + if(kurok) + { + LIGHTMAP_BYTES = 4; + MAX_LIGHTMAPS = 16; + } + else + { + LIGHTMAP_BYTES = 1; + MAX_LIGHTMAPS = 64; + } + + if (data) + { + if (data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T') + { + i = LittleLong(((int *)data)[1]); + if (i == 1) + { + Con_DPrintf("%s loaded", litfilename); + loadmodel->lightdata = data + 8; + return; + } + else + Con_Printf("Unknown .lit file version (%d)\n", i); + } + else + Con_Printf("Corrupt .lit file (old version?), ignoring\n"); + } + // LordHavoc: no .lit found, expand the white lighting data to color + if (!l->filelen) + { + return; + } + + loadmodel->lightdata = static_cast(Hunk_AllocName ( l->filelen*3, litfilename)); + in = loadmodel->lightdata + l->filelen*2; // place the file at the end, so it will not be overwritten until the very last write + out = loadmodel->lightdata; + memcpy (in, mod_base + l->fileofs, l->filelen); + for (i = 0;i < l->filelen;i++) + { + d = *in++; + *out++ = d; + *out++ = d; + *out++ = d; + } + // LordHavoc: .lit support end + +} + + +/* +================= +Mod_LoadVisibility +================= +*/ +void Mod_LoadVisibility (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->visdata = NULL; + return; + } + loadmodel->visdata = static_cast(Hunk_AllocName ( l->filelen, loadname)); + memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadEntities +================= +*/ +void Mod_LoadEntities (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->entities = NULL; + return; + } + loadmodel->entities = static_cast(Hunk_AllocName ( l->filelen, loadname)); + memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadVertexes +================= +*/ +void Mod_LoadVertexes (lump_t *l) +{ + dvertex_t *in; + mvertex_t *out; + int i, count; + + in = reinterpret_cast(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = static_cast(Hunk_AllocName ( count*sizeof(*out), loadname)); + + loadmodel->vertexes = out; + loadmodel->numvertexes = count; + + for ( i=0 ; iposition[0] = LittleFloat (in->point[0]); + out->position[1] = LittleFloat (in->point[1]); + out->position[2] = LittleFloat (in->point[2]); + } +} + +/* +================= +Mod_LoadSubmodels +================= +*/ +void Mod_LoadSubmodels (lump_t *l) +{ + dmodel_t *in; + dmodel_t *out; + int i, j, count; + + in = reinterpret_cast(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = static_cast(Hunk_AllocName ( count*sizeof(*out), loadname)); + + loadmodel->submodels = out; + loadmodel->numsubmodels = count; + + for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; + out->maxs[j] = LittleFloat (in->maxs[j]) + 1; + out->origin[j] = LittleFloat (in->origin[j]); + } + for (j=0 ; jheadnode[j] = LittleLong (in->headnode[j]); + out->visleafs = LittleLong (in->visleafs); + out->firstface = LittleLong (in->firstface); + out->numfaces = LittleLong (in->numfaces); + } +} + +/* +================= +Mod_LoadEdges +================= +*/ +void Mod_LoadEdges (lump_t *l) +{ + dedge_t *in; + medge_t *out; + int i, count; + + in = reinterpret_cast(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = static_cast(Hunk_AllocName ( (count + 1) * sizeof(*out), loadname)); + + loadmodel->edges = out; + loadmodel->numedges = count; + + for ( i=0 ; iv[0] = (unsigned short)LittleShort(in->v[0]); + out->v[1] = (unsigned short)LittleShort(in->v[1]); + } +} + +/* +================= +Mod_LoadTexinfo +================= +*/ +void Mod_LoadTexinfo (lump_t *l) +{ + texinfo_t *in; + mtexinfo_t *out; + int i, j, count; + int miptex; + float len1, len2; + + in = reinterpret_cast(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = static_cast(Hunk_AllocName ( count*sizeof(*out), loadname)); + + loadmodel->texinfo = out; + loadmodel->numtexinfo = count; + + for ( i=0 ; ivecs[0][j] = LittleFloat (in->vecs[0][j]); + len1 = Length (out->vecs[0]); + len2 = Length (out->vecs[1]); + len1 = (len1 + len2)/2; + if (len1 < 0.32) + out->mipadjust = 4; + else if (len1 < 0.49) + out->mipadjust = 3; + else if (len1 < 0.99) + out->mipadjust = 2; + else + out->mipadjust = 1; +#if 0 + if (len1 + len2 < 0.001) + out->mipadjust = 1; // don't crash + else + out->mipadjust = 1 / floorf( (len1+len2)/2 + 0.1 ); +#endif + + miptex = LittleLong (in->miptex); + out->flags = LittleLong (in->flags); + + if (!loadmodel->textures) + { + out->texture = r_notexture_mip; // checkerboard texture + out->flags = 0; + } + else + { + if (miptex >= loadmodel->numtextures) + Sys_Error ("miptex >= loadmodel->numtextures"); + out->texture = loadmodel->textures[miptex]; + if (!out->texture) + { + out->texture = r_notexture_mip; // texture not found + out->flags = 0; + } + } + } +} + +/* +================ +CalcSurfaceExtents + +Fills in s->texturemins[] and s->extents[] +================ +*/ +void CalcSurfaceExtents (msurface_t *s) +{ + float mins[2], maxs[2], val; + int i,j, e; + mvertex_t *v; + mtexinfo_t *tex; + int bmins[2], bmaxs[2]; + + mins[0] = mins[1] = 999999; + maxs[0] = maxs[1] = -99999; + + tex = s->texinfo; + + for (i=0 ; inumedges ; i++) + { + e = loadmodel->surfedges[s->firstedge+i]; + if (e >= 0) + v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; + else + v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; + + for (j=0 ; j<2 ; j++) + { + val = v->position[0] * tex->vecs[j][0] + + v->position[1] * tex->vecs[j][1] + + v->position[2] * tex->vecs[j][2] + + tex->vecs[j][3]; + if (val < mins[j]) + mins[j] = val; + if (val > maxs[j]) + maxs[j] = val; + } + } + + if (kurok) + { + for (i=0 ; i<2 ; i++) + { + bmins[i] = floorf(mins[i]/16); // + bmaxs[i] = ceilf(maxs[i]/16); // + + s->texturemins[i] = bmins[i] * 16; // + s->extents[i] = (bmaxs[i] - bmins[i]) * 16; // + if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 2000 /* 512 */ /* 256 */) + Sys_Error ("Bad surface extents"); + } + } + else + { + for (i=0 ; i<2 ; i++) + { + bmins[i] = floorf(mins[i]/16); + bmaxs[i] = ceilf(maxs[i]/16); + + s->texturemins[i] = bmins[i] * 16; + s->extents[i] = (bmaxs[i] - bmins[i]) * 16; + if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 2000 /* 512 */ /* 256 */) + Sys_Error ("Bad surface extents"); + } + } +} + + +/* +================= +Mod_LoadFaces +================= +*/ +void Mod_LoadFaces (lump_t *l) +{ + dface_t *in; + msurface_t *out; + int i, count, surfnum; + int planenum, side; + + in = reinterpret_cast(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = static_cast(Hunk_AllocName ( count*sizeof(*out), loadname)); + + loadmodel->surfaces = out; + loadmodel->numsurfaces = count; + + for ( surfnum=0 ; surfnumfirstedge = LittleLong(in->firstedge); + out->numedges = LittleShort(in->numedges); + out->flags = 0; + + planenum = LittleShort(in->planenum); + side = LittleShort(in->side); + if (side) + out->flags |= SURF_PLANEBACK; + + out->plane = loadmodel->planes + planenum; + + out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); + + CalcSurfaceExtents (out); + + // lighting info + + for (i=0 ; istyles[i] = in->styles[i]; + i = LittleLong(in->lightofs); + if (i == -1) + out->samples = NULL; + else + // LordHavoc: .lit support begin + // out->samples = loadmodel->lightdata + i; // LordHavoc: original code + out->samples = loadmodel->lightdata + (i * 3); // LordHavoc: expand white lighting + // LordHavoc: .lit support end + + // set the drawing flags flag + + if (!Q_strncmp(out->texinfo->texture->name,"sky",3)) // sky + { + out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED); + + if(kurok) + GL_Surface (out); // Don't cut up polygon for warps + else + GL_SubdivideSurface (out); // cut up polygon for warps + continue; + } + + if (!Q_strncmp(out->texinfo->texture->name,"*",1)) // turbulent + { + out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED); + for (i=0 ; i<2 ; i++) + { + out->extents[i] = 16384; + out->texturemins[i] = -8192; + } + + GL_Surface (out); // Don't cut up polygon for warps +// GL_SubdivideSurface (out); // cut up polygon for warps + continue; + } + + } +} + + +/* +================= +Mod_SetParent +================= +*/ +void Mod_SetParent (mnode_t *node, mnode_t *parent) +{ + node->parent = parent; + if (node->contents < 0) + return; + Mod_SetParent (node->children[0], node); + Mod_SetParent (node->children[1], node); +} + +/* +================= +Mod_LoadNodes +================= +*/ +void Mod_LoadNodes (lump_t *l) +{ + int i, j, count, p; + dnode_t *in; + mnode_t *out; + + in = reinterpret_cast(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = static_cast(Hunk_AllocName ( count*sizeof(*out), loadname)); + + loadmodel->nodes = out; + loadmodel->numnodes = count; + + for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->planenum); + out->plane = loadmodel->planes + p; + + out->firstsurface = LittleShort (in->firstface); + out->numsurfaces = LittleShort (in->numfaces); + + for (j=0 ; j<2 ; j++) + { + p = LittleShort (in->children[j]); + if (p >= 0) + out->children[j] = loadmodel->nodes + p; + else + out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); + } + } + + Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs +} + +/* +================= +Mod_LoadLeafs +================= +*/ +void Mod_LoadLeafs (lump_t *l) +{ + dleaf_t *in; + mleaf_t *out; + int i, j, count, p; + + in = reinterpret_cast(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = static_cast(Hunk_AllocName ( count*sizeof(*out), loadname)); + + loadmodel->leafs = out; + loadmodel->numleafs = count; + + for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->contents); + out->contents = p; + + out->firstmarksurface = loadmodel->marksurfaces + + LittleShort(in->firstmarksurface); + out->nummarksurfaces = LittleShort(in->nummarksurfaces); + + p = LittleLong(in->visofs); + if (p == -1) + out->compressed_vis = NULL; + else + out->compressed_vis = loadmodel->visdata + p; + out->efrags = NULL; + + for (j=0 ; j<4 ; j++) + out->ambient_sound_level[j] = in->ambient_level[j]; + + // gl underwater warp + if (out->contents != CONTENTS_EMPTY) + { + for (j=0 ; jnummarksurfaces ; j++) + out->firstmarksurface[j]->flags |= SURF_UNDERWATER; + } + } +} + +/* +================= +Mod_LoadClipnodes +================= +*/ +void Mod_LoadClipnodes (lump_t *l) +{ + dclipnode_t *in, *out; + int i, count; + hull_t *hull; + + in = reinterpret_cast(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = static_cast(Hunk_AllocName ( count*sizeof(*out), loadname)); + + loadmodel->clipnodes = out; + loadmodel->numclipnodes = count; + +if(kurok) +{ + hull = &loadmodel->hulls[1]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -12; + hull->clip_mins[1] = -12; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 12; + hull->clip_maxs[1] = 12; + hull->clip_maxs[2] = 32; +} +else +{ + hull = &loadmodel->hulls[1]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -16; + hull->clip_mins[1] = -16; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 16; + hull->clip_maxs[1] = 16; + hull->clip_maxs[2] = 32; +} + + hull = &loadmodel->hulls[2]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -32; + hull->clip_mins[1] = -32; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 32; + hull->clip_maxs[1] = 32; + hull->clip_maxs[2] = 64; + + for (i=0 ; iplanenum = LittleLong(in->planenum); + out->children[0] = LittleShort(in->children[0]); + out->children[1] = LittleShort(in->children[1]); + } +} + +/* +================= +Mod_MakeHull0 + +Deplicate the drawing hull structure as a clipping hull +================= +*/ +void Mod_MakeHull0 (void) +{ + mnode_t *in, *child; + dclipnode_t *out; + int i, j, count; + hull_t *hull; + + hull = &loadmodel->hulls[0]; + + in = loadmodel->nodes; + count = loadmodel->numnodes; + out = static_cast(Hunk_AllocName ( count*sizeof(*out), loadname)); + + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + + for (i=0 ; iplanenum = in->plane - loadmodel->planes; + for (j=0 ; j<2 ; j++) + { + child = in->children[j]; + if (child->contents < 0) + out->children[j] = child->contents; + else + out->children[j] = child - loadmodel->nodes; + } + } +} + +/* +================= +Mod_LoadMarksurfaces +================= +*/ +void Mod_LoadMarksurfaces (lump_t *l) +{ + int i, j, count; + short *in; + msurface_t **out; + + in = reinterpret_cast(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = static_cast(Hunk_AllocName ( count*sizeof(*out), loadname)); + + loadmodel->marksurfaces = out; + loadmodel->nummarksurfaces = count; + + for ( i=0 ; i= loadmodel->numsurfaces) + Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); + out[i] = loadmodel->surfaces + j; + } +} + +/* +================= +Mod_LoadSurfedges +================= +*/ +void Mod_LoadSurfedges (lump_t *l) +{ + int i, count; + int *in, *out; + + in = reinterpret_cast(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = static_cast(Hunk_AllocName ( count*sizeof(*out), loadname)); + + loadmodel->surfedges = out; + loadmodel->numsurfedges = count; + + for ( i=0 ; i(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = static_cast(Hunk_AllocName ( count*2*sizeof(*out), loadname)); + + loadmodel->planes = out; + loadmodel->numplanes = count; + + for ( i=0 ; inormal[j] = LittleFloat (in->normal[j]); + if (out->normal[j] < 0) + bits |= 1<dist = LittleFloat (in->dist); + out->type = LittleLong (in->type); + out->signbits = bits; + } +} + +/* +================= +RadiusFromBounds +================= +*/ +float RadiusFromBounds (vec3_t mins, vec3_t maxs) +{ + int i; + vec3_t corner; + + for (i=0 ; i<3 ; i++) + { + corner[i] = fabsf(mins[i]) > fabsf(maxs[i]) ? fabsf(mins[i]) : fabsf(maxs[i]); + } + + return Length (corner); +} + +/* +================= +Mod_LoadBrushModel +================= +*/ +void Mod_LoadBrushModel (model_t *mod, void *buffer) +{ + int i, j; + dheader_t *header; + dmodel_t *bm; + + loadmodel->type = mod_brush; + + header = (dheader_t *)buffer; + + i = LittleLong (header->version); + if (i != BSPVERSION) + Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); + +// swap all the lumps + mod_base = (byte *)header; + + for (i=0 ; ilumps[LUMP_VERTEXES]); + Mod_LoadEdges (&header->lumps[LUMP_EDGES]); + Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); + Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); + Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); + Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); + Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); + Mod_LoadFaces (&header->lumps[LUMP_FACES]); + Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); + Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); + Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); + Mod_LoadNodes (&header->lumps[LUMP_NODES]); + Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); + Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); + Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); + + Mod_MakeHull0 (); + + mod->numframes = 2; // regular and alternate animation + +// +// set up the submodels (FIXME: this is confusing) +// + for (i=0 ; inumsubmodels ; i++) + { + bm = &mod->submodels[i]; + + mod->hulls[0].firstclipnode = bm->headnode[0]; + for (j=1 ; jhulls[j].firstclipnode = bm->headnode[j]; + mod->hulls[j].lastclipnode = mod->numclipnodes-1; + } + + mod->firstmodelsurface = bm->firstface; + mod->nummodelsurfaces = bm->numfaces; + + VectorCopy (bm->maxs, mod->maxs); + VectorCopy (bm->mins, mod->mins); + + mod->radius = RadiusFromBounds (mod->mins, mod->maxs); + + mod->numleafs = bm->visleafs; + + if (i < mod->numsubmodels-1) + { // duplicate the basic information + char name[10]; + + sprintf (name, "*%i", i+1); + loadmodel = Mod_FindName (name); + *loadmodel = *mod; + strcpy (loadmodel->name, name); + mod = loadmodel; + } + } +} + +/* +============================================================================== + +ALIAS MODELS + +============================================================================== +*/ + +aliashdr_t *pheader; + +stvert_t stverts[MAXALIASVERTS]; +mtriangle_t triangles[MAXALIASTRIS]; + +// a pose is a single set of vertexes. a frame may be +// an animating sequence of poses +trivertx_t *poseverts[MAXALIASFRAMES]; +int posenum; + +byte **player_8bit_texels_tbl; +byte *player_8bit_texels; + +//byte aliasbboxmins[3], aliasbboxmaxs[3]; + +/* +================= +Mod_LoadAliasFrame +================= +*/ +void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame) +{ + trivertx_t *pinframe; + int i; + daliasframe_t *pdaliasframe; + + pdaliasframe = (daliasframe_t *)pin; + + strcpy (frame->name, pdaliasframe->name); + frame->firstpose = posenum; + frame->numposes = 1; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about endianness + frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i]; + frame->bboxmax.v[i] = pdaliasframe->bboxmax.v[i]; + +// aliasbboxmins[i] = min_b (aliasbboxmins[i], frame->bboxmin.v[i]); +// aliasbboxmaxs[i] = max_b (aliasbboxmaxs[i], frame->bboxmax.v[i]); + } + + pinframe = (trivertx_t *)(pdaliasframe + 1); + + poseverts[posenum] = pinframe; + posenum++; + + pinframe += pheader->numverts; + + return (void *)pinframe; +} + + +/* +================= +Mod_LoadAliasGroup +================= +*/ +void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame) +{ + daliasgroup_t *pingroup; + int i, numframes; + daliasinterval_t *pin_intervals; + void *ptemp; + + pingroup = (daliasgroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + frame->firstpose = posenum; + frame->numposes = numframes; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about endianness + frame->bboxmin.v[i] = pingroup->bboxmin.v[i]; + frame->bboxmax.v[i] = pingroup->bboxmax.v[i]; + +// aliasbboxmins[i] = min_b (aliasbboxmins[i], frame->bboxmin.v[i]); +// aliasbboxmaxs[i] = max_b (aliasbboxmaxs[i], frame->bboxmax.v[i]); + } + + pin_intervals = (daliasinterval_t *)(pingroup + 1); + + frame->interval = LittleFloat (pin_intervals->interval); + + pin_intervals += numframes; + + ptemp = (void *)pin_intervals; + + for (i=0 ; inumverts; + } + + return ptemp; +} + +//========================================================= + +/* +================= +Mod_FloodFillSkin + +Fill background pixels so mipmapping doesn't have haloes - Ed +================= +*/ + +typedef struct +{ + short x, y; +} floodfill_t; +/* +extern unsigned d_8to24table[]; +*/ +// must be a power of 2 +#define FLOODFILL_FIFO_SIZE 0x1000 +#define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1) + +#define FLOODFILL_STEP( off, dx, dy ) \ +{ \ + if (pos[off] == fillcolor) \ + { \ + pos[off] = 255; \ + fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \ + inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \ + } \ + else if (pos[off] != 255) fdc = pos[off]; \ +} + +void Mod_FloodFillSkin( byte *skin, int skinwidth, int skinheight ) +{ + byte fillcolor = *skin; // assume this is the pixel to fill + floodfill_t fifo[FLOODFILL_FIFO_SIZE]; + int inpt = 0, outpt = 0; + int filledcolor = -1; + int i; + + if (filledcolor == -1) + { + filledcolor = 0; + // attempt to find opaque black + for (i = 0; i < 256; ++i) + { + if (d_8to24table[i] == (255 << 0)) // alpha 1.0 + { + filledcolor = i; + break; + } + } + } + + // can't fill to filled color or to transparent color (used as visited marker) + if ((fillcolor == filledcolor) || (fillcolor == 255)) + { + //printf( "not filling skin from %d to %d\n", fillcolor, filledcolor ); + return; + } + + fifo[inpt].x = 0, fifo[inpt].y = 0; + inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; + + while (outpt != inpt) + { + int x = fifo[outpt].x, y = fifo[outpt].y; + int fdc = filledcolor; + byte *pos = &skin[x + skinwidth * y]; + + outpt = (outpt + 1) & FLOODFILL_FIFO_MASK; + + if (x > 0) FLOODFILL_STEP( -1, -1, 0 ); + if (x < skinwidth - 1) FLOODFILL_STEP( 1, 1, 0 ); + if (y > 0) FLOODFILL_STEP( -skinwidth, 0, -1 ); + if (y < skinheight - 1) FLOODFILL_STEP( skinwidth, 0, 1 ); + skin[x + skinwidth * y] = fdc; + } +} + +/* +=============== +Mod_LoadAllSkins +=============== +*/ +void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) +{ + int i, j, k; + char name[32]; + int s; +// byte *copy; + byte *skin; +// byte *texels; + daliasskingroup_t *pinskingroup; + int groupskins; + daliasskininterval_t *pinskinintervals; + + skin = (byte *)(pskintype + 1); + + if (numskins < 1 || numskins > MAX_SKINS) + Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); + + s = pheader->skinwidth * pheader->skinheight; + + for (i=0 ; itype == ALIAS_SKIN_SINGLE) { + Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight ); + + sprintf (name, "%s_%i", loadmodel->name, i); + + int gl_ident = GL_LoadTexture (name, pheader->skinwidth, pheader->skinheight, (byte *)(pskintype + 1) , qtrue, GU_LINEAR, 0); + + pheader->gl_texturenum[i][0] = pheader->gl_texturenum[i][1] = + pheader->gl_texturenum[i][2] = pheader->gl_texturenum[i][3] = gl_ident; + pskintype = (daliasskintype_t *)((byte *)(pskintype+1) + s); + } else { + // animating skin group. yuck. + pskintype++; + pinskingroup = (daliasskingroup_t *)pskintype; + groupskins = LittleLong (pinskingroup->numskins); + pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); + + pskintype = reinterpret_cast(pinskinintervals + groupskins); + + for (j=0 ; jskinwidth, pheader->skinheight ); + sprintf (name, "%s_%i_%i", loadmodel->name, i,j); + pheader->gl_texturenum[i][j&3] = + GL_LoadTexture (name, pheader->skinwidth, + pheader->skinheight, (byte *)(pskintype), qtrue, GU_LINEAR, 0); + pskintype = (daliasskintype_t *)((byte *)(pskintype) + s); + } + k = j; + for (/* */; j < 4; j++) + pheader->gl_texturenum[i][j&3] = pheader->gl_texturenum[i][j - k]; + } + } + + return (void *)pskintype; +} + +//========================================================================= + +/* +================= +Mod_LoadAliasModel +================= +*/ +void Mod_LoadAliasModel (model_t *mod, void *buffer) +{ + int i, j; + mdl_t *pinmodel; + stvert_t *pinstverts; + dtriangle_t *pintriangles; + int version, numframes;//, numskins; + int size; + daliasframetype_t *pframetype; + daliasskintype_t *pskintype; + int start, end, total; + + start = Hunk_LowMark (); + + pinmodel = (mdl_t *)buffer; + + version = LittleLong (pinmodel->version); + if (version != ALIAS_VERSION) + Sys_Error ("%s has wrong version number (%i should be %i)", + mod->name, version, ALIAS_VERSION); + +// +// allocate space for a working header, plus all the data except the frames, +// skin and group info +// + size = sizeof (aliashdr_t) + + (LittleLong (pinmodel->numframes) - 1) * + sizeof (pheader->frames[0]); + pheader = static_cast(Hunk_AllocName (size, loadname)); + + mod->flags = LittleLong (pinmodel->flags); + +// +// endian-adjust and copy the data, starting with the alias model header +// + pheader->boundingradius = LittleFloat (pinmodel->boundingradius); + pheader->numskins = LittleLong (pinmodel->numskins); + pheader->skinwidth = LittleLong (pinmodel->skinwidth); + pheader->skinheight = LittleLong (pinmodel->skinheight); + + if (pheader->skinheight > MAX_LBM_HEIGHT) + Sys_Error ("model %s has a skin taller than %d", mod->name, + MAX_LBM_HEIGHT); + + pheader->numverts = LittleLong (pinmodel->numverts); + + if (pheader->numverts <= 0) + Sys_Error ("model %s has no vertices", mod->name); + + if (pheader->numverts > MAXALIASVERTS) + Sys_Error ("model %s has too many vertices", mod->name); + + pheader->numtris = LittleLong (pinmodel->numtris); + + if (pheader->numtris <= 0) + Sys_Error ("model %s has no triangles", mod->name); + + pheader->numframes = LittleLong (pinmodel->numframes); + numframes = pheader->numframes; + if (numframes < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); + + pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; + mod->synctype = static_cast(LittleLong (pinmodel->synctype)); + mod->numframes = pheader->numframes; + + for (i=0 ; i<3 ; i++) + { + pheader->scale[i] = LittleFloat (pinmodel->scale[i]); + pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); + pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); + } + + +// +// load the skins +// + pskintype = (daliasskintype_t *)&pinmodel[1]; + pskintype = static_cast(Mod_LoadAllSkins (pheader->numskins, pskintype)); + +// +// load base s and t vertices +// + pinstverts = (stvert_t *)pskintype; + + for (i=0 ; inumverts ; i++) + { + stverts[i].onseam = LittleLong (pinstverts[i].onseam); + stverts[i].s = LittleLong (pinstverts[i].s); + stverts[i].t = LittleLong (pinstverts[i].t); + } + +// +// load triangle lists +// + pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts]; + + for (i=0 ; inumtris ; i++) + { + triangles[i].facesfront = LittleLong (pintriangles[i].facesfront); + + for (j=0 ; j<3 ; j++) + { + triangles[i].vertindex[j] = + LittleLong (pintriangles[i].vertindex[j]); + } + } + +// +// load the frames +// + posenum = 0; + pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; + +// aliasbboxmins[0] = aliasbboxmins[1] = aliasbboxmins[2] = 255; +// aliasbboxmaxs[0] = aliasbboxmaxs[1] = aliasbboxmaxs[2] = 0; + + for (i=0 ; i(LittleLong (pframetype->type)); + + if (frametype == ALIAS_SINGLE) + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]); + } + else + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]); + } + } + + pheader->numposes = posenum; + + mod->type = mod_alias; + +// FIXME: do this right + mod->mins[0] = mod->mins[1] = mod->mins[2] = -64; + mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 64; + + +// for (i = 0; i < 3; i++) +// { +// mod->mins[i] = aliasbboxmins[i] * pheader->scale[i] + pheader->scale_origin[i]; +// mod->maxs[i] = aliasbboxmaxs[i] * pheader->scale[i] + pheader->scale_origin[i]; +// } + + // + // build the draw lists + // + GL_MakeAliasModelDisplayLists (mod, pheader); + +// +// move the complete, relocatable alias model to the cache +// + end = Hunk_LowMark (); + total = end - start; + + Cache_Alloc (&mod->cache, total, loadname); + if (!mod->cache.data) + return; + memcpy (mod->cache.data, pheader, total); + + Hunk_FreeToLowMark (start); +} + +//============================================================================= + +/* +================= +Mod_LoadSpriteFrame +================= +*/ +void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum) +{ + dspriteframe_t *pinframe; + mspriteframe_t *pspriteframe; + int width, height, size, origin[2]; + char name[64]; + + pinframe = (dspriteframe_t *)pin; + + width = LittleLong (pinframe->width); + height = LittleLong (pinframe->height); + size = width * height; + + pspriteframe = static_cast(Hunk_AllocName (sizeof (mspriteframe_t),loadname)); + + Q_memset (pspriteframe, 0, sizeof (mspriteframe_t)); + + *ppframe = pspriteframe; + + pspriteframe->width = width; + pspriteframe->height = height; + origin[0] = LittleLong (pinframe->origin[0]); + origin[1] = LittleLong (pinframe->origin[1]); + + pspriteframe->up = origin[1]; + pspriteframe->down = origin[1] - height; + pspriteframe->left = origin[0]; + pspriteframe->right = width + origin[0]; + + sprintf (name, "%s_%i", loadmodel->name, framenum); + pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (byte *)(pinframe + 1), qtrue, GU_LINEAR, 0); + + return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size); +} + + +/* +================= +Mod_LoadSpriteGroup +================= +*/ +void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum) +{ + dspritegroup_t *pingroup; + mspritegroup_t *pspritegroup; + int i, numframes; + dspriteinterval_t *pin_intervals; + float *poutintervals; + void *ptemp; + + pingroup = (dspritegroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + pspritegroup = static_cast(Hunk_AllocName (sizeof (mspritegroup_t) + + (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname)); + pspritegroup->numframes = numframes; + + *ppframe = (mspriteframe_t *)pspritegroup; + + pin_intervals = (dspriteinterval_t *)(pingroup + 1); + + poutintervals = static_cast(Hunk_AllocName (numframes * sizeof (float), loadname)); + + pspritegroup->intervals = poutintervals; + + for (i=0 ; iinterval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; iframes[i], framenum * 100 + i); + } + + return ptemp; +} + + +/* +================= +Mod_LoadSpriteModel +================= +*/ +void Mod_LoadSpriteModel (model_t *mod, void *buffer) +{ + int i; + int version; + dsprite_t *pin; + msprite_t *psprite; + int numframes; + int size; + dspriteframetype_t *pframetype; + + pin = (dsprite_t *)buffer; + + version = LittleLong (pin->version); + if (version != SPRITE_VERSION) + Sys_Error ("%s has wrong version number " + "(%i should be %i)", mod->name, version, SPRITE_VERSION); + + numframes = LittleLong (pin->numframes); + + size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); + + psprite = static_cast(Hunk_AllocName (size, loadname)); + + mod->cache.data = psprite; + + psprite->type = LittleLong (pin->type); + psprite->maxwidth = LittleLong (pin->width); + psprite->maxheight = LittleLong (pin->height); + psprite->beamlength = LittleFloat (pin->beamlength); + mod->synctype = static_cast(LittleLong (pin->synctype)); + psprite->numframes = numframes; + + mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; + mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; + mod->mins[2] = -psprite->maxheight/2; + mod->maxs[2] = psprite->maxheight/2; + +// +// load the frames +// + if (numframes < 1) + Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); + + mod->numframes = numframes; + + pframetype = (dspriteframetype_t *)(pin + 1); + + for (i=0 ; i(LittleLong (pframetype->type)); + psprite->frames[i].type = frametype; + + if (frametype == SPR_SINGLE) + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteFrame (pframetype + 1, + &psprite->frames[i].frameptr, i); + } + else + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteGroup (pframetype + 1, + &psprite->frames[i].frameptr, i); + } + } + + mod->type = mod_sprite; +} + +//============================================================================= + +/* +================ +Mod_Print +================ +*/ +extern "C" void Mod_Print (void) +{ + int i; + model_t *mod; + + Con_Printf ("Cached models:\n"); + for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++) + { + Con_Printf ("%8p : %s\n",mod->cache.data, mod->name); + } +} + + diff --git a/r17/Revamped src/revamped_src/psp/video_hardware_model.h b/r17/Revamped src/revamped_src/psp/video_hardware_model.h new file mode 100755 index 00000000..d7481607 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_hardware_model.h @@ -0,0 +1,449 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#ifndef __MODEL__ +#define __MODEL__ + +#include "../modelgen.h" +#include "../spritegn.h" + +/* + +d*_t structures are on-disk representations +m*_t structures are in-memory + +*/ + +// entity effects + +#define EF_BRIGHTFIELD 1 +#define EF_MUZZLEFLASH 2 +#define EF_BRIGHTLIGHT 4 +#define EF_DIMLIGHT 8 +#define EF_REDLIGHT 16 +#define EF_BLUELIGHT 32 +#define EF_PINKLIGHT 64 +#define EF_GREENLIGHT 128 + +/* +============================================================================== + +BRUSH MODELS + +============================================================================== +*/ + +// +// in memory representation +// +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + vec3_t position; +} mvertex_t; + +#define SIDE_FRONT 0 +#define SIDE_BACK 1 +#define SIDE_ON 2 + + +// plane_t structure +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct mplane_s +{ + vec3_t normal; + float dist; + byte type; // for texture axis selection and fast side tests + byte signbits; // signx + signy<<1 + signz<<1 + byte pad[2]; +} mplane_t; + +typedef struct texture_s +{ + char name[16]; + unsigned width, height; + int gl_texturenum; + struct msurface_s *texturechain; // for gl_texsort drawing + int anim_total; // total tenths in sequence ( 0 = no) + int anim_min, anim_max; // time for this frame min <=time< max + struct texture_s *anim_next; // in the animation sequence + struct texture_s *alternate_anims; // bmodels in frmae 1 use these + unsigned offsets[MIPLEVELS]; // four mip maps stored +} texture_t; + + +#define SURF_PLANEBACK 2 +#define SURF_DRAWSKY 4 +#define SURF_DRAWSPRITE 8 +#define SURF_DRAWTURB 0x10 +#define SURF_DRAWTILED 0x20 +#define SURF_DRAWBACKGROUND 0x40 +#define SURF_UNDERWATER 0x80 + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + unsigned short v[2]; + unsigned int cachededgeoffset; +} medge_t; + +typedef struct +{ + float vecs[2][4]; + float mipadjust; + texture_t *texture; + int flags; +} mtexinfo_t; + +typedef vec_t vec2_t[2]; + +typedef struct glvert_s +{ + vec2_t st; + vec3_t xyz; +} glvert_t; + +typedef struct glpoly_s +{ + struct glpoly_s *next; + struct glpoly_s *chain; + int numverts; + int flags; // for SURF_UNDERWATER + + // This is a variable sized array, and hence must be the last element in + // this structure. + // + // The array is (numverts * 2) in size. The first half are regular + // vertices, and the second half have copies of the first half's XYZs but + // keep the light map texture coordinates. This makes the vertices easier + // to render on the PSP. + glvert_t verts[1]; +} glpoly_t; + +typedef struct msurface_s +{ + int visframe; // should be drawn when node is crossed + + mplane_t *plane; + int flags; + + int firstedge; // look up in model->surfedges[], negative numbers + int numedges; // are backwards edges + + short texturemins[2]; + short extents[2]; + + int light_s, light_t; // gl lightmap coordinates + + glpoly_t *polys; // multiple if warped + struct msurface_s *texturechain; + + mtexinfo_t *texinfo; + +// lighting info + int dlightframe; + int dlightbits; + + int lightmaptexturenum; + byte styles[MAXLIGHTMAPS]; + int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap + qboolean cached_dlight; // true if dynamic light in cache + byte *samples; // [numstyles*surfsize] +} msurface_t; + +typedef struct mnode_s +{ +// common with leaf + int contents; // 0, to differentiate from leafs + int visframe; // node needs to be traversed if current + + float minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// node specific + mplane_t *plane; + struct mnode_s *children[2]; + + unsigned short firstsurface; + unsigned short numsurfaces; +} mnode_t; + + + +typedef struct mleaf_s +{ +// common with node + int contents; // wil be a negative contents number + int visframe; // node needs to be traversed if current + + float minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// leaf specific + byte *compressed_vis; + efrag_t *efrags; + + msurface_t **firstmarksurface; + int nummarksurfaces; + int key; // BSP sequence number for leaf's contents + byte ambient_sound_level[NUM_AMBIENTS]; +} mleaf_t; + +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct +{ + dclipnode_t *clipnodes; + mplane_t *planes; + int firstclipnode; + int lastclipnode; + vec3_t clip_mins; + vec3_t clip_maxs; +} hull_t; + +/* +============================================================================== + +SPRITE MODELS + +============================================================================== +*/ + + +// FIXME: shorten these? +typedef struct mspriteframe_s +{ + int width; + int height; + float up, down, left, right; + int gl_texturenum; +} mspriteframe_t; + +typedef struct +{ + int numframes; + float *intervals; + mspriteframe_t *frames[1]; +} mspritegroup_t; + +typedef struct +{ + spriteframetype_t type; + mspriteframe_t *frameptr; +} mspriteframedesc_t; + +typedef struct +{ + int type; + int maxwidth; + int maxheight; + int numframes; + float beamlength; // remove? + void *cachespot; // remove? + mspriteframedesc_t frames[1]; +} msprite_t; + + +/* +============================================================================== + +ALIAS MODELS + +Alias models are position independent, so the cache manager can move them. +============================================================================== +*/ + +typedef struct +{ + int firstpose; + int numposes; + float interval; + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; + char name[16]; +} maliasframedesc_t; + +typedef struct +{ + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; +} maliasgroupframedesc_t; + +typedef struct +{ + int numframes; + int intervals; + maliasgroupframedesc_t frames[1]; +} maliasgroup_t; + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct mtriangle_s { + int facesfront; + int vertindex[3]; +} mtriangle_t; + + +#define MAX_SKINS 32 +typedef struct { + int ident; + int version; + vec3_t scale; + vec3_t scale_origin; + float boundingradius; + vec3_t eyeposition; + int numskins; + int skinwidth; + int skinheight; + int numverts; + int numtris; + int numframes; + synctype_t synctype; + int flags; + float size; + + int numposes; + int poseverts; + int posedata; // numposes*poseverts trivert_t + int baseposedata; //original verts for triangles to reference + int triangles; //we need tri data for collision + int commands; // gl command list with embedded s/t + int gl_texturenum[MAX_SKINS][4]; + int texels[MAX_SKINS]; // only for player skins + maliasframedesc_t frames[1]; // variable sized +} aliashdr_t; + +#define MAXALIASVERTS 5120 +#define MAXALIASFRAMES 256 +#define MAXALIASTRIS 2048 +extern aliashdr_t *pheader; +extern stvert_t stverts[MAXALIASVERTS]; +extern mtriangle_t triangles[MAXALIASTRIS]; +extern trivertx_t *poseverts[MAXALIASFRAMES]; + +//=================================================================== + +// +// Whole model +// + +typedef enum {mod_brush, mod_sprite, mod_alias} modtype_t; + +#define EF_ROCKET 1 // leave a trail +#define EF_GRENADE 2 // leave a trail +#define EF_GIB 4 // leave a trail +#define EF_ROTATE 8 // rotate (bonus items) +#define EF_TRACER 16 // green split trail +#define EF_ZOMGIB 32 // small blood trail +#define EF_TRACER2 64 // orange split trail + rotate +#define EF_TRACER3 128 // purple trail + +typedef struct model_s +{ + char name[MAX_QPATH]; + qboolean needload; // bmodels and sprites don't cache normally + + modtype_t type; + int numframes; + synctype_t synctype; + + int flags; + +// +// volume occupied by the model graphics +// + vec3_t mins, maxs; + float radius; + +// +// solid volume for clipping +// + qboolean clipbox; + vec3_t clipmins, clipmaxs; + +// +// brush model +// + int firstmodelsurface, nummodelsurfaces; + + int numsubmodels; + dmodel_t *submodels; + + int numplanes; + mplane_t *planes; + + int numleafs; // number of visible leafs, not counting 0 + mleaf_t *leafs; + + int numvertexes; + mvertex_t *vertexes; + + int numedges; + medge_t *edges; + + int numnodes; + mnode_t *nodes; + + int numtexinfo; + mtexinfo_t *texinfo; + + int numsurfaces; + msurface_t *surfaces; + + int numsurfedges; + int *surfedges; + + int numclipnodes; + dclipnode_t *clipnodes; + + int nummarksurfaces; + msurface_t **marksurfaces; + + hull_t hulls[MAX_MAP_HULLS]; + + int numtextures; + texture_t **textures; + + byte *visdata; + byte *lightdata; + char *entities; + +// +// additional model data +// + cache_user_t cache; // only access through Mod_Extradata + +} model_t; + +//============================================================================ + +void Mod_Init (void); +void Mod_ClearAll (void); +model_t *Mod_ForName (char *name, qboolean crash); +void *Mod_Extradata (model_t *mod); // handles caching +void Mod_TouchModel (char *name); + +mleaf_t *Mod_PointInLeaf (float *p, model_t *model); +byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model); + +#endif // __MODEL__ diff --git a/r17/Revamped src/revamped_src/psp/video_hardware_screen.cpp b/r17/Revamped src/revamped_src/psp/video_hardware_screen.cpp new file mode 100755 index 00000000..e1b13a97 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_hardware_screen.cpp @@ -0,0 +1,939 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +// screen.c -- master for refresh, status bar, console, chat, notify, etc + +extern "C" +{ +#include "../quakedef.h" +} + +/* + +background clear +rendering +turtle/net/ram icons +sbar +centerprint / slow centerprint +notify lines +intermission / finale overlay +loading plaque +console +menu + +required background clears +required update regions + + +syncronous draw mode or async +One off screen buffer, with updates either copied or xblited +Need to double buffer? + + +async draw will require the refresh area to be cleared, because it will be +xblited, but sync draw can just ignore it. + +sync +draw + +CenterPrint () +SlowPrint () +Screen_Update (); +Con_Printf (); + +net +turn off messages option + +the refresh is allways rendered, unless the console is full screen + + +console is: + notify lines + half + full + + +*/ + + +int glx, gly, glwidth, glheight; + +// only the refresh window will be updated unless these variables are flagged +int scr_copytop; +int scr_copyeverything; + +float scr_con_current; +float scr_conlines; // lines of console to display + +float oldscreensize, oldfov; +cvar_t scr_viewsize = {"viewsize","110", qtrue}; +cvar_t scr_fov = {"fov","90"}; // 10 - 170 +cvar_t scr_conspeed = {"scr_conspeed","9999"}; +cvar_t scr_centertime = {"scr_centertime","2"}; +cvar_t scr_showram = {"showram","1"}; +cvar_t scr_showturtle = {"showturtle","0"}; +cvar_t scr_showpause = {"showpause","1"}; +cvar_t scr_printspeed = {"scr_printspeed","8"}; +cvar_t scr_loadscreen = {"scr_loadscreen","1", qtrue}; + +extern "C" cvar_t crosshair; +extern "C" cvar_t v_idlescale; + +qboolean scr_initialized; // ready to draw + +qpic_t *scr_ram; +qpic_t *scr_net; +qpic_t *scr_turtle; + +int scr_fullupdate; + +int clearconsole; +int clearnotify; + +int sb_lines; + +viddef_t vid; // global video state + +extern "C" vrect_t scr_vrect; +vrect_t scr_vrect = {0}; + +qboolean scr_disabled_for_loading; +qboolean scr_drawloading; +float scr_disabled_time; + +qboolean block_drawing; + +void SCR_ScreenShot_f (void); + +/* +=============================================================================== + +CENTER PRINTING + +=============================================================================== +*/ + +char scr_centerstring[1024]; +float scr_centertime_start; // for slow victory printing +extern "C" float scr_centertime_off; +float scr_centertime_off = 0.0f; +int scr_center_lines; +int scr_erase_lines; +int scr_erase_center; + +/* +============== +SCR_CenterPrint + +Called for important messages that should stay in the center of the screen +for a few moments +============== +*/ +void SCR_CenterPrint (char *str) +{ + strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1); + scr_centertime_off = scr_centertime.value; + scr_centertime_start = cl.time; + +// count the number of lines for centering + scr_center_lines = 1; + while (*str) + { + if (*str == '\n') + scr_center_lines++; + str++; + } +} + + +void SCR_DrawCenterString (void) +{ + char *start; + int l; + int j; + int x, y; + int remaining; + +// the finale prints the characters one at a time + if (cl.intermission) + remaining = int(scr_printspeed.value * (cl.time - scr_centertime_start)); + else + remaining = 9999; + + scr_erase_center = 0; + start = scr_centerstring; + + if (scr_center_lines <= 4) + y = int(vid.height*0.35); + else + y = 48; + + do + { + // scan the width of the line + for (l=0 ; l<40 ; l++) + if (start[l] == '\n' || !start[l]) + break; + x = (vid.width - l*8)/2; + for (j=0 ; j scr_erase_lines) + scr_erase_lines = scr_center_lines; + + scr_centertime_off -= host_frametime; + + if (scr_centertime_off <= 0 && !cl.intermission) + return; + if (key_dest != key_game) + return; + + SCR_DrawCenterString (); +} + +//============================================================================= + + +/* +==================== +CalcFov +==================== +*/ +float CalcFov (float fov_x, float width, float height) +{ + float a; + float x; + + if (fov_x < 1 || fov_x > 179) + Sys_Error ("Bad fov: %f", fov_x); + + x = width/tanf(fov_x/360*M_PI); + + a = atanf(height/x); + + a = a*360/M_PI; + + return a; +} + +/* +================= +SCR_CalcRefdef + +Must be called whenever vid changes +Internal use only +================= +*/ +static void SCR_CalcRefdef (void) +{ + float size; + int h; + qboolean full = qfalse; + + + scr_fullupdate = 0; // force a background redraw + vid.recalc_refdef = 0; + +// force the status bar to redraw + Sbar_Changed (); + +//======================================== + +// bound viewsize + if (scr_viewsize.value < 30) + Cvar_Set ("viewsize","30"); + if (scr_viewsize.value > 130) + Cvar_Set ("viewsize","130"); + +// bound field of view + if (scr_fov.value < 10) + Cvar_Set ("fov","10"); + if (scr_fov.value > 170) + Cvar_Set ("fov","170"); + +// intermission is always full screen + if (cl.intermission) + { + size = 130; + } + else + { + size = scr_viewsize.value; + } + + if (size >= 120) + sb_lines = 0; // no status bar at all + else if (size >= 110) + sb_lines = 24; // no inventory + else + sb_lines = 24+16+8; + + if (scr_viewsize.value >= 100.0) { + full = qtrue; + size = 100.0; + } else + size = scr_viewsize.value; + if (cl.intermission) + { + full = qtrue; + size = 100; + sb_lines = 0; + } + size /= 100.0; + + h = vid.height - sb_lines; + + r_refdef.vrect.width = int(vid.width * size); + if (r_refdef.vrect.width < 96) + { + size = 96.0 / r_refdef.vrect.width; + r_refdef.vrect.width = 96; // min for icons + } + + r_refdef.vrect.height = int(vid.height * size); + if (r_refdef.vrect.height > vid.height - sb_lines) + r_refdef.vrect.height = vid.height - sb_lines; + if (r_refdef.vrect.height > vid.height) + r_refdef.vrect.height = vid.height; + r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2; + if (full) + r_refdef.vrect.y = 0; + else + r_refdef.vrect.y = (h - r_refdef.vrect.height)/2; + + r_refdef.fov_x = scr_fov.value; + r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); + + scr_vrect = r_refdef.vrect; +} + + +/* +================= +SCR_SizeUp_f + +Keybinding command +================= +*/ +void SCR_SizeUp_f (void) +{ + Cvar_SetValue ("viewsize",scr_viewsize.value+10); + vid.recalc_refdef = 1; +} + + +/* +================= +SCR_SizeDown_f + +Keybinding command +================= +*/ +void SCR_SizeDown_f (void) +{ + Cvar_SetValue ("viewsize",scr_viewsize.value-10); + vid.recalc_refdef = 1; +} + +//============================================================================ + +/* +================== +SCR_Init +================== +*/ +void SCR_Init (void) +{ + + Cvar_RegisterVariable (&scr_fov); + Cvar_RegisterVariable (&scr_viewsize); + Cvar_RegisterVariable (&scr_conspeed); + Cvar_RegisterVariable (&scr_showram); + Cvar_RegisterVariable (&scr_showturtle); + Cvar_RegisterVariable (&scr_showpause); + Cvar_RegisterVariable (&scr_centertime); + Cvar_RegisterVariable (&scr_printspeed); + Cvar_RegisterVariable (&scr_loadscreen); +// +// register our commands +// + Cmd_AddCommand ("screenshot",SCR_ScreenShot_f); + Cmd_AddCommand ("sizeup",SCR_SizeUp_f); + Cmd_AddCommand ("sizedown",SCR_SizeDown_f); + + scr_ram = Draw_PicFromWad ("ram"); + scr_net = Draw_PicFromWad ("net"); + scr_turtle = Draw_PicFromWad ("turtle"); + + scr_initialized = qtrue; +} + + + +/* +============== +SCR_DrawRam +============== +*/ +void SCR_DrawRam (void) +{ + if (!scr_showram.value) + return; + + if (!r_cache_thrash) + return; + + Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram); +} + +/* +============== +SCR_DrawTurtle +============== +*/ +void SCR_DrawTurtle (void) +{ + static int count; + + if (!scr_showturtle.value) + return; + + if (host_frametime < 0.1) + { + count = 0; + return; + } + + count++; + if (count < 3) + return; + + Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle); +} + +/* +============== +SCR_DrawNet +============== +*/ +void SCR_DrawNet (void) +{ + if (realtime - cl.last_received_message < 0.3) + return; + if (cls.demoplayback) + return; + + Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net); +} + +/* +//muff - hacked out of SourceForge implementation + modified +============== +SCR_DrawFPS +============== +*/ +void SCR_DrawFPS (void) +{ + extern cvar_t show_fps; + static double lastframetime; + double t; + extern int fps_count; + static int lastfps; + int x, y; + char st[80]; + + if (!show_fps.value) + return; + + t = Sys_FloatTime (); + + if ((t - lastframetime) >= 1.0) { + lastfps = fps_count; + fps_count = 0; + lastframetime = t; + } + + sprintf(st, "%3d FPS", lastfps); + + x = vid.width - strlen(st) * 16 + 32; + y = 0 ; //vid.height - (sb_lines * (vid.height/240) )- 16; + +// Draw_TileClear(x, y, strlen(st)*16, 16); + Draw_String(x, y, st); +} + +/* +============== +DrawPause +============== +*/ +void SCR_DrawPause (void) +{ + qpic_t *pic; + + if (!scr_showpause.value) // turn off for screenshots + return; + + if (!cl.paused) + return; + + pic = Draw_CachePic ("gfx/pause.lmp"); + Draw_Pic ( (vid.width - pic->width)/2, + (vid.height - 48 - pic->height)/2, pic); +} + +/* +============== +SCR_DrawLoading +============== +*/ +void SCR_DrawLoading (void) +{ + qpic_t *pic; + + if (!scr_drawloading) + return; + + pic = Draw_CachePic ("gfx/loading.lmp"); + Draw_Pic ( (vid.width - pic->width)/2, + (vid.height - 48 - pic->height)/2, pic); +} + +/* +============== +SCR_DrawLoadScreen +============== +*/ +void SCR_DrawLoadScreen (void) +{ + qpic_t *pic; + + if (!con_forcedup) + return; +/* + static int count; + + if (host_frametime < 0.01) + { + count = 0; + return; + } + + count++; + if (count < 3) + return; +*/ + + if(cl.worldmodel) + return; + + pic = Draw_CachePic ("gfx/menu/loadback.lmp"); + Draw_Pic (scr_vrect.x, scr_vrect.y, pic); +} + +//============================================================================= + + +/* +================== +SCR_SetUpToDrawConsole +================== +*/ +void SCR_SetUpToDrawConsole (void) +{ + Con_CheckResize (); + + if (scr_drawloading) + return; // never a console with loading plaque + +// decide on the height of the console + if (!cl.worldmodel || cls.signon != SIGNONS) + { + con_forcedup = qtrue; + } + else + { + con_forcedup = qfalse; + } + + if (con_forcedup) + { + scr_conlines = vid.height; // full screen + scr_con_current = scr_conlines; + } + else if (key_dest == key_console) + scr_conlines = vid.height/2; // half screen + else + scr_conlines = 0; // none visible + + if (scr_conlines < scr_con_current) + { + scr_con_current -= scr_conspeed.value*host_frametime; + if (scr_conlines > scr_con_current) + scr_con_current = scr_conlines; + + } + else if (scr_conlines > scr_con_current) + { + scr_con_current += scr_conspeed.value*host_frametime; + if (scr_conlines < scr_con_current) + scr_con_current = scr_conlines; + } + + if (clearconsole++ < vid.numpages) + { + Sbar_Changed (); + } + else if (clearnotify++ < vid.numpages) + { + } + else + con_notifylines = 0; +} + +/* +================== +SCR_DrawConsole +================== +*/ +void SCR_DrawConsole (void) +{ + if (scr_con_current) + { + scr_copyeverything = 1; + Con_DrawConsole (int(scr_con_current), qtrue); + clearconsole = 0; + } + else + { + if (key_dest == key_game || key_dest == key_message) + Con_DrawNotify (); // only draw notify in game + } +} + +//============================================================================= + + +/* +=============== +SCR_BeginLoadingPlaque + +================ +*/ +void SCR_BeginLoadingPlaque (void) +{ + CDAudio_Pause(); + S_StopAllSounds (qtrue); + + if (cls.state != ca_connected) + return; + if (cls.signon != SIGNONS) + return; + +// redraw with no console and the loading plaque + Con_ClearNotify (); + scr_centertime_off = 0; + scr_con_current = 0; + + scr_drawloading = qtrue; + scr_fullupdate = 0; + Sbar_Changed (); + SCR_UpdateScreen (); + scr_drawloading = qfalse; + + scr_disabled_for_loading = qtrue; + scr_disabled_time = realtime; + scr_fullupdate = 0; +} + +/* +=============== +SCR_EndLoadingPlaque + +================ +*/ +void SCR_EndLoadingPlaque (void) +{ + scr_disabled_for_loading = qfalse; + scr_fullupdate = 0; + Con_ClearNotify (); + CDAudio_Resume(); +} + +//============================================================================= + +char *scr_notifystring; +qboolean scr_drawdialog; + +void SCR_DrawNotifyString (void) +{ + char *start; + int l; + int j; + int x, y; + + start = scr_notifystring; + + y = int(vid.height*0.35f); + + do + { + // scan the width of the line + for (l=0 ; l<40 ; l++) + if (start[l] == '\n' || !start[l]) + break; + x = (vid.width - l*8)/2; + for (j=0 ; j 0) { + // left + Draw_TileClear (0, 0, r_refdef.vrect.x, vid.height - sb_lines); + // right + Draw_TileClear (r_refdef.vrect.x + r_refdef.vrect.width, 0, + vid.width - r_refdef.vrect.x + r_refdef.vrect.width, + vid.height - sb_lines); + } + if (r_refdef.vrect.y > 0) { + // top + Draw_TileClear (r_refdef.vrect.x, 0, + r_refdef.vrect.x + r_refdef.vrect.width, + r_refdef.vrect.y); + // bottom + Draw_TileClear (r_refdef.vrect.x, + r_refdef.vrect.y + r_refdef.vrect.height, + r_refdef.vrect.width, + vid.height - sb_lines - + (r_refdef.vrect.height + r_refdef.vrect.y)); + } +} + +/* +================== +SCR_UpdateScreen + +This is called every frame, and can also be called explicitly to flush +text to the screen. + +WARNING: be very careful calling this from elsewhere, because the refresh +needs almost the entire 256k of stack space! +================== +*/ +void SCR_UpdateScreen (void) +{ + if (block_drawing) + return; + + scr_copytop = 0; + scr_copyeverything = 0; + + if (scr_disabled_for_loading) + { + if (realtime - scr_disabled_time > 60) + { + scr_disabled_for_loading = qfalse; + Con_Printf ("load failed.\n"); + } + else + return; + } + + if (!scr_initialized || !con_initialized) + return; // not initialized yet + + + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + + // + // determine size of refresh window + // + if (oldfov != scr_fov.value) + { + oldfov = scr_fov.value; + vid.recalc_refdef = qtrue; + } + + if (oldscreensize != scr_viewsize.value) + { + oldscreensize = scr_viewsize.value; + vid.recalc_refdef = qtrue; + } + + if (vid.recalc_refdef) + SCR_CalcRefdef (); + +// +// do 3D refresh drawing, and then update the screen +// + SCR_SetUpToDrawConsole (); + + V_RenderView (); + + GL_Set2D (); + + // + // draw any areas not covered by the refresh + // + SCR_TileClear (); + + V_UpdatePalette (); + + if (scr_drawdialog) + { + Sbar_Draw (); + Draw_FadeScreen (); + SCR_DrawNotifyString (); + scr_copyeverything = qtrue; + } + else if (scr_drawloading) + { + SCR_DrawLoading (); + Sbar_Draw (); + } + else if (cl.intermission == 1 && key_dest == key_game) + { + Sbar_IntermissionOverlay (); + } + else if (cl.intermission == 2 && key_dest == key_game) + { + Sbar_FinaleOverlay (); + SCR_CheckDrawCenterString (); + } + else + { + // Gamma adjust before screen elements. + if (v_gamma.value < 1) + Draw_FadeScreenColor (1, 1, 1, 1 - v_gamma.value); + + if (crosshair.value) + Draw_Crosshair(); + + SCR_DrawRam (); + SCR_DrawNet (); + SCR_DrawTurtle (); + //muff - to show FPS on screen + SCR_DrawFPS (); + SCR_DrawPause (); + SCR_CheckDrawCenterString (); + + Sbar_Draw (); + + SCR_DrawConsole (); + + if (kurok) + if(scr_loadscreen.value) + SCR_DrawLoadScreen(); + + M_Draw (); + } + + GL_EndRendering (); +} + diff --git a/r17/Revamped src/revamped_src/psp/video_hardware_surface.cpp b/r17/Revamped src/revamped_src/psp/video_hardware_surface.cpp new file mode 100755 index 00000000..56ebeed2 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_hardware_surface.cpp @@ -0,0 +1,1646 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ +// r_surf.c: surface-related refresh code + +#include +#include + +extern "C" +{ +#include "../quakedef.h" +} +#include "lightmaps.h" +#include "clipping.hpp" + +using namespace quake; + +int skytexturenum; +/* +#ifdef NORMAL_MODEL +#define LIGHTMAP_BYTES 4 // 1 or 4, used to be 1 +#define MAX_LIGHTMAPS 16 // used to be 64, reduced to fit under 2MB or else crashes psp if lightmap bytes is 4 +#endif +#ifdef SLIM_MODEL +#define LIGHTMAP_BYTES 4 // 1 or 4, used to be 1 +#define MAX_LIGHTMAPS 28 // used to be 64, reduced to fit under 2MB or else crashes psp if lightmap bytes is 4 +//#define LIGHTMAP_BYTES 3 // 1 or 4, used to be 1 +//#define MAX_LIGHTMAPS 37 // used to be 64, reduced to fit under 2MB or else crashes psp if lightmap bytes is 4 +#endif +*/ + +#define BLOCK_WIDTH 128 +#define BLOCK_HEIGHT 128 + +int lightmap_textures; + +//unsigned blocklights[18*18]; +unsigned blocklights[BLOCK_WIDTH*BLOCK_HEIGHT*3]; // LordHavoc: .lit support (*3 for RGB) + +int active_lightmaps; + +typedef struct glRect_s { + unsigned char l,t,w,h; +} glRect_t; + +////////////////////////////////////////////////////////////////////////////// +// For none .lit maps. +////////////////////////////////////////////////////////////////////////////// +glpoly_t *lightmap_polys[64]; +qboolean lightmap_modified[64]; +glRect_t lightmap_rectchange[64]; + +int allocated[64][BLOCK_WIDTH]; + +// the lightmap texture data needs to be kept in +// main memory so texsubimage can update properly +byte lightmaps[1*64*BLOCK_WIDTH*BLOCK_HEIGHT]; + +int lightmap_index[64]; + +// For gl_texsort 0 +msurface_t *skychain = NULL; +msurface_t *waterchain = NULL; + +void R_RenderDynamicLightmaps (msurface_t *fa); + +void VID_SetPaletteLM(); +// switch palette for lightmaps + +void VID_SetPaletteTX(); +// switch palette for textures + +/* +=============== +R_AddDynamicLights +=============== +*/ +void R_AddDynamicLights (msurface_t *surf) +{ + int lnum; + int sd, td; + float dist, rad, minlight; + vec3_t impact, local; + int s, t; + int i; + int smax, tmax; + mtexinfo_t *tex; + + // LordHavoc: .lit support begin + float cred, cgreen, cblue, brightness; + unsigned *bl; + // LordHavoc: .lit support end + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + tex = surf->texinfo; + + for (lnum=0 ; lnumdlightbits & (1<plane->normal) - + surf->plane->dist; + rad -= fabsf(dist); + minlight = cl_dlights[lnum].minlight; + if (rad < minlight) + continue; + minlight = rad - minlight; + + for (i=0 ; i<3 ; i++) + { + impact[i] = cl_dlights[lnum].origin[i] - + surf->plane->normal[i]*dist; + } + + local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; + local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; + + local[0] -= surf->texturemins[0]; + local[1] -= surf->texturemins[1]; + + // LordHavoc: .lit support begin + bl = blocklights; + cred = cl_dlights[lnum].color[0] * 256.0f; + cgreen = cl_dlights[lnum].color[1] * 256.0f; + cblue = cl_dlights[lnum].color[2] * 256.0f; + // LordHavoc: .lit support end + for (t = 0 ; t td) + dist = sd + (td>>1); + else + dist = td + (sd>>1); + if (dist < minlight) + // LordHavoc: .lit support begin + // blocklights[t*smax + s] += (rad - dist)*256; // LordHavoc: original code + { + brightness = rad - dist; + bl[0] += (int) (brightness * cred); + bl[1] += (int) (brightness * cgreen); + bl[2] += (int) (brightness * cblue); + } + bl += 3; + // LordHavoc: .lit support end + } + } + } +} + + +/* +=============== +R_BuildLightMap + +Combine and scale multiple lightmaps into the 8.8 format in blocklights +=============== +*/ +void R_BuildLightMap (msurface_t *surf, byte *dest, int stride) +{ + int smax, tmax; + int t, r, s, q; + int i, j, size; + byte *lightmap; + unsigned scale; + int maps; + unsigned *bl; + + unsigned *blcr, *blcg, *blcb; + + surf->cached_dlight = (surf->dlightframe == r_framecount) ? qtrue : qfalse; + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + size = smax*tmax; + lightmap = surf->samples; + +// set to full bright if no light data + if (r_fullbright.value || !cl.worldmodel->lightdata) + { + // LordHavoc: .lit support begin + bl = blocklights; + for (i=0 ; istyles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + surf->cached_light[maps] = scale; // 8.8 fraction + // LordHavoc: .lit support begin + bl = blocklights; + for (i=0 ; idlightframe == r_framecount) + R_AddDynamicLights (surf); + +// bound, invert, and shift +store: + switch (LIGHTMAP_BYTES) + { + case 4: + stride -= (smax<<2); + bl = blocklights; + for (i=0 ; i>= 7; + if (t > 255) + t = 255; + dest[3] = 255-t; + dest += 4; + */ + // LordHavoc: positive lighting (would be 255-t if it were inverse like glquake was) + t = *bl++ >> 7;if (t > 255) t = 255;*dest++ = t; + t = *bl++ >> 7;if (t > 255) t = 255;*dest++ = t; + t = *bl++ >> 7;if (t > 255) t = 255;*dest++ = t; + *dest++ = 255; + // LordHavoc: .lit support end + } + } + break; + case 3: + stride -= (smax<<2); + bl = blocklights; + for (i=0 ; i>= 7; + if (t > 255) + t = 255; + dest[3] = 255-t; + dest += 4; + */ + // LordHavoc: positive lighting (would be 255-t if it were inverse like glquake was) + t = *bl++ >> 7;if (t > 255) t = 255;*dest++ = t; + t = *bl++ >> 7;if (t > 255) t = 255;*dest++ = t; + t = *bl++ >> 7;if (t > 255) t = 255;*dest++ = t; + *dest++ = 255; + // LordHavoc: .lit support end + } + } + break; + /* + stride -= smax * 3; + bl = blocklights; + for (i=0 ; i> 7;if (t > 255) t = 255;*dest++ = t; + t = *bl++ >> 7;if (t > 255) t = 255;*dest++ = t; + t = *bl++ >> 7;if (t > 255) t = 255;*dest++ = t; + } + } + break; + */ + case 2: + bl = blocklights; + for (i=0 ; i>= 7; // LordHavoc: original code + t = ((bl[0] + bl[1] + bl[2]) * 85) >> 15; // LordHavoc: basically / 3, but faster and combined with >> 7 shift down, note: actual number would be 85.3333... + bl += 3; + // LordHavoc: .lit support end + if (t > 255) + t = 255; + dest[j] = t; + } + } + break; + /* + //stride -= (smax<<1); + bl = blocklights; + for (i=0 ; i>= 7; + if (t > 255) + t = 255; + byte x = (t & 0x00f0) >> 4; + + dest[2*j] = x | (x << 4); + dest[2*j+1] = x | (x << 4); + //dest += 2; + } + } + break; + */ + case 1: + bl = blocklights; + for (i=0 ; i>= 7; // LordHavoc: original code + t = ((bl[0] + bl[1] + bl[2]) * 85) >> 15; // LordHavoc: basically / 3, but faster and combined with >> 7 shift down, note: actual number would be 85.3333... + bl += 3; + // LordHavoc: .lit support end + if (t > 255) + t = 255; + dest[j] = t; + } + } + break; + default: + Sys_Error ("Bad lightmap format"); + } +} + + +/* +=============== +R_TextureAnimation + +Returns the proper texture for a given time and base texture +=============== +*/ +texture_t *R_TextureAnimation (texture_t *base) +{ + int reletive; + int count; + + if (currententity->frame) + { + if (base->alternate_anims) + base = base->alternate_anims; + } + + if (!base->anim_total) + return base; + + reletive = (int)(cl.time*10) % base->anim_total; + + count = 0; + while (base->anim_min > reletive || base->anim_max <= reletive) + { + base = base->anim_next; + if (!base) + Sys_Error ("R_TextureAnimation: broken cycle"); + if (++count > 100) + Sys_Error ("R_TextureAnimation: infinite cycle"); + } + + return base; +} + + +/* +============================================================= + + BRUSH MODELS + +============================================================= +*/ + + +extern int solidskytexture; +extern int alphaskytexture; + +extern float speedscale; // for top sky and bottom sky + + +static inline void DrawGLPolyLM (glpoly_t *p) +{ + // Does this poly need clipped? + + + const int unclipped_vertex_count = p->numverts; + const glvert_t* const unclipped_vertices = &(p->verts[p->numverts]); + + if (clipping::is_clipping_required( + unclipped_vertices, + unclipped_vertex_count)) + { + // Clip the polygon. + const glvert_t* clipped_vertices; + std::size_t clipped_vertex_count; + clipping::clip( + unclipped_vertices, + unclipped_vertex_count, + &clipped_vertices, + &clipped_vertex_count); + + // Did we have any vertices left? + if (clipped_vertex_count) + { + // Copy the vertices to the display list. + const std::size_t buffer_size = clipped_vertex_count * sizeof(glvert_t); + glvert_t* const display_list_vertices = static_cast(sceGuGetMemory(buffer_size)); + memcpy(display_list_vertices, clipped_vertices, buffer_size); + + if (r_showtris.value) + { + sceGuDisable(GU_TEXTURE_2D); + sceGuDisable(GU_BLEND); + + // Draw the clipped vertices. + sceGumDrawArray( + GU_LINE_STRIP, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF , + clipped_vertex_count, 0, display_list_vertices); + + sceGuEnable(GU_TEXTURE_2D); + sceGuEnable(GU_BLEND); + } + else + { + // Draw the clipped vertices. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF , + clipped_vertex_count, 0, display_list_vertices); + } + } + } + else + { + + if (r_showtris.value) + { + sceGuDisable(GU_TEXTURE_2D); + sceGuDisable(GU_BLEND); + + // Draw the lines directly. + sceGumDrawArray( + GU_LINE_STRIP, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF , + unclipped_vertex_count, 0, unclipped_vertices); + + sceGuEnable(GU_TEXTURE_2D); + sceGuEnable(GU_BLEND); + + } + else + { + // Draw the poly directly. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF , + unclipped_vertex_count, 0, unclipped_vertices); + } + } +} + +static inline void DrawGLPoly (glpoly_t *p) +{ + // Does this poly need clipped? + const int unclipped_vertex_count = p->numverts; + const glvert_t* const unclipped_vertices = p->verts; + + if (clipping::is_clipping_required( + unclipped_vertices, + unclipped_vertex_count)) + { + // Clip the polygon. + const glvert_t* clipped_vertices; + std::size_t clipped_vertex_count; + clipping::clip( + unclipped_vertices, + unclipped_vertex_count, + &clipped_vertices, + &clipped_vertex_count); + + // Did we have any vertices left? + if (clipped_vertex_count) + { + // Copy the vertices to the display list. + const std::size_t buffer_size = clipped_vertex_count * sizeof(glvert_t); + glvert_t* const display_list_vertices = static_cast(sceGuGetMemory(buffer_size)); + memcpy(display_list_vertices, clipped_vertices, buffer_size); + + // Draw the clipped vertices. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF, + clipped_vertex_count, 0, display_list_vertices); + } + } + else + { + // Draw the poly directly. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF, + unclipped_vertex_count, 0, unclipped_vertices); + } +} + + +static void DrawGLWaterPoly (glpoly_t *p) +{ +#if 0 + int i; + const glvert_t *v; + float s, t, os, ot; + vec3_t nv; + + /*GL_DisableMultitexture(); + + glBegin (GL_TRIANGLE_FAN);*/ + v = p->verts; + for (i=0 ; inumverts ; i++, ++v) + { + /*glTexCoord2f (v[3], v[4]);*/ + + nv[0] = v->xyz[0] + 8*sinf(v->xyz[1]*0.05+realtime)*sinf(v->xyz[2]*0.05+realtime); + nv[1] = v->xyz[1] + 8*sinf(v->xyz[0]*0.05+realtime)*sinf(v->xyz[2]*0.05+realtime); + nv[2] = v->xyz[2]; + + /*glVertex3fv (nv);*/ + } + /*glEnd ();*/ +#else + DrawGLPoly(p); +#endif +} + +//static void DrawGLWaterPolyLightmap (glpoly_t *p) +//{ +// int i; +// const glvert_t *v; +// float s, t, os, ot; +// vec3_t nv; + + /*GL_DisableMultitexture(); + + glBegin (GL_TRIANGLE_FAN);*/ +// v = p->verts; +// for (i=0 ; inumverts ; i++, ++v) +// { + /*glTexCoord2f (v[5], v[6]);*/ + +// nv[0] = v->xyz[0] + 8*sinf(v->xyz[1]*0.05+realtime)*sinf(v->xyz[2]*0.05+realtime); +// nv[1] = v->xyz[1] + 8*sinf(v->xyz[0]*0.05+realtime)*sinf(v->xyz[2]*0.05+realtime); +// nv[2] = v->xyz[2]; + + /*glVertex3fv (nv);*/ +// } + /*glEnd ();*/ +//} + + +/* +================ +R_BlendLightmaps +================ +*/ +static void R_BlendLightmaps (void) +{ + int i; + glpoly_t *p; + + if (r_fullbright.value) + return; + + sceGuDepthMask(GU_TRUE); + sceGuEnable(GU_BLEND); + sceGuBlendFunc(GU_ADD, GU_DST_COLOR, GU_SRC_COLOR, 0, 0); + + VID_SetPaletteLM(); + + if (r_lightmap.value) + sceGuDisable(GU_BLEND); + + for (i=0 ; ichain) + { + if (p->flags & SURF_UNDERWATER) + DrawGLPolyLM(p); + else + DrawGLPolyLM(p); + } + + } + + VID_SetPaletteTX(); + + sceGuDisable(GU_BLEND); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuDepthMask (GU_FALSE); +} + +/* +================ +R_RenderBrushPoly +================ +*/ +void R_RenderBrushPoly (msurface_t *fa) +{ + texture_t *t; + byte *base; + int maps; + glRect_t *theRect; + int smax, tmax; + unsigned *bl; + + c_brush_polys++; + + if (fa->flags & SURF_DRAWSKY) + { // warp texture, no lightmaps + EmitBothSkyLayers (fa); + return; + } + + t = R_TextureAnimation (fa->texinfo->texture); + GL_Bind (t->gl_texturenum); + + if (fa->flags & SURF_DRAWTURB) + { // warp texture, no lightmaps + EmitWaterPolys (fa); + return; + } + + sceGuEnable(GU_ALPHA_TEST); + sceGuAlphaFunc(GU_GREATER, 0x88, 0xff); + + if (fa->flags & SURF_UNDERWATER) + DrawGLWaterPoly (fa->polys); + + // Don't draw texture and lightmaps. + else if (!Q_strncmp(fa->texinfo->texture->name,"nodraw",6)) + return; + + // Alpha blended textures, no lightmaps. + else if ((!Q_strncmp(fa->texinfo->texture->name,"z",1)) || + (!Q_strncmp(fa->texinfo->texture->name,"{",1))) + { + + if (kurok) + { + sceGuDepthMask(GU_TRUE); + sceGuDisable(GU_ALPHA_TEST); + sceGuEnable(GU_BLEND); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + + DrawGLPoly (fa->polys); + + sceGuDepthMask(GU_FALSE); + sceGuEnable(GU_ALPHA_TEST); + sceGuDisable(GU_BLEND); + sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + + return; + } + else + DrawGLPoly (fa->polys); + } + + // No lightmaps. + else if (!Q_strncmp(fa->texinfo->texture->name,"light",5)) + { + if (kurok) + { + DrawGLPoly (fa->polys); + return; + } + else + DrawGLPoly (fa->polys); + } + + // Surface uvmaps warp, like metal or glass effects. + else if (!Q_strncmp(fa->texinfo->texture->name,"env",3)) + { + if (kurok) + EmitReflectivePolys (fa); + else + DrawGLPoly (fa->polys); + } + + // Surface uvmaps warp, like metal or glass effects + transparency. + else if (!Q_strncmp(fa->texinfo->texture->name,"glass",5)) + { + if (r_glassalpha.value < 1) + { + if (kurok) + { + float alpha1 = r_glassalpha.value; + float alpha2 = 1 - r_glassalpha.value; + + sceGuEnable (GU_BLEND); + sceGuDepthMask(GU_TRUE); + sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, GU_COLOR(alpha1,alpha1,alpha1,alpha1), GU_COLOR(alpha2,alpha2,alpha2,alpha2)); + + EmitReflectivePolys (fa); + + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuDepthMask(GU_FALSE); + sceGuDisable (GU_BLEND); + } + else + DrawGLPoly (fa->polys); + } + else + { + if (kurok) + EmitReflectivePolys (fa); + else + DrawGLPoly (fa->polys); + } + } + else + DrawGLPoly (fa->polys); + + // add the poly to the proper lightmap chain + + fa->polys->chain = lightmap_polys[fa->lightmaptexturenum]; + lightmap_polys[fa->lightmaptexturenum] = fa->polys; + + // check for lightmap modification + for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ; + maps++) + if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]) + goto dynamic; + + if (fa->dlightframe == r_framecount // dynamic this frame + || fa->cached_dlight) // dynamic previously + { +dynamic: + if (r_dynamic.value) + { + lightmap_modified[fa->lightmaptexturenum] = qtrue; + theRect = &lightmap_rectchange[fa->lightmaptexturenum]; + + if (fa->light_t < theRect->t) { + if (theRect->h) + theRect->h += theRect->t - fa->light_t; + theRect->t = fa->light_t; + } + if (fa->light_s < theRect->l) { + if (theRect->w) + theRect->w += theRect->l - fa->light_s; + theRect->l = fa->light_s; + } + smax = (fa->extents[0]>>4)+1; + tmax = (fa->extents[1]>>4)+1; + if ((theRect->w + theRect->l) < (fa->light_s + smax)) + theRect->w = (fa->light_s-theRect->l)+smax; + if ((theRect->h + theRect->t) < (fa->light_t + tmax)) + theRect->h = (fa->light_t-theRect->t)+tmax; + + base = lightmaps + fa->lightmaptexturenum*LIGHTMAP_BYTES*BLOCK_WIDTH*BLOCK_HEIGHT; + base += fa->light_t * BLOCK_WIDTH * LIGHTMAP_BYTES + fa->light_s * LIGHTMAP_BYTES; + R_BuildLightMap (fa, base, BLOCK_WIDTH*LIGHTMAP_BYTES); + } + } + + sceGuAlphaFunc(GU_GREATER, 0, 0xff); + sceGuDisable(GU_ALPHA_TEST); +} + +/* +================ +R_RenderDynamicLightmaps +Multitexture +================ +*/ +void R_RenderDynamicLightmaps (msurface_t *fa) +{ +// texture_t *t; + byte *base; + int maps; + glRect_t *theRect; + int smax, tmax; + + c_brush_polys++; + + if (fa->flags & ( SURF_DRAWSKY | SURF_DRAWTURB) ) + return; + + fa->polys->chain = lightmap_polys[fa->lightmaptexturenum]; + lightmap_polys[fa->lightmaptexturenum] = fa->polys; + + // check for lightmap modification + for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ; + maps++) + if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]) + goto dynamic; + + if (fa->dlightframe == r_framecount // dynamic this frame + || fa->cached_dlight) // dynamic previously + { +dynamic: + if (r_dynamic.value) + { + lightmap_modified[fa->lightmaptexturenum] = qtrue; + theRect = &lightmap_rectchange[fa->lightmaptexturenum]; + + if (fa->light_t < theRect->t) { + if (theRect->h) + theRect->h += theRect->t - fa->light_t; + theRect->t = fa->light_t; + } + if (fa->light_s < theRect->l) { + if (theRect->w) + theRect->w += theRect->l - fa->light_s; + theRect->l = fa->light_s; + } + smax = (fa->extents[0]>>4)+1; + tmax = (fa->extents[1]>>4)+1; + if ((theRect->w + theRect->l) < (fa->light_s + smax)) + theRect->w = (fa->light_s-theRect->l)+smax; + if ((theRect->h + theRect->t) < (fa->light_t + tmax)) + theRect->h = (fa->light_t-theRect->t)+tmax; + + base = lightmaps + fa->lightmaptexturenum*LIGHTMAP_BYTES*BLOCK_WIDTH*BLOCK_HEIGHT; + base += fa->light_t * BLOCK_WIDTH * LIGHTMAP_BYTES + fa->light_s * LIGHTMAP_BYTES; + R_BuildLightMap (fa, base, BLOCK_WIDTH*LIGHTMAP_BYTES); + } + } +} + +/* +================ +R_MirrorChain +================ +*/ +void R_MirrorChain (msurface_t *s) +{ + if (mirror) + return; + mirror = qtrue; + mirror_plane = s->plane; +} + + +/* +================ +R_DrawWaterSurfaces +================ +*/ +void R_DrawWaterSurfaces (void) +{ + int i; + msurface_t *s; + texture_t *t; + + if (r_wateralpha.value == 1.0) + return; + + float alpha1 = r_wateralpha.value; + float alpha2 = 1 - r_wateralpha.value; + + // + // go back to the world matrix + // + + sceGumMatrixMode(GU_VIEW); + sceGumLoadMatrix(&r_world_matrix); + sceGumUpdateMatrix(); + sceGumMatrixMode(GU_MODEL); + + if (r_wateralpha.value < 1.0) + { + sceGuEnable (GU_BLEND); + sceGuTexFunc(GU_TFX_REPLACE , GU_TCC_RGBA); + sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, GU_COLOR(alpha1,alpha1,alpha1,alpha1), GU_COLOR(alpha2,alpha2,alpha2,alpha2)); + } + { + + for (i=0 ; inumtextures ; i++) + { + t = cl.worldmodel->textures[i]; + if (!t) + continue; + s = t->texturechain; + if (!s) + continue; + if ( !(s->flags & SURF_DRAWTURB ) ) + continue; + + // set modulate mode explicitly + GL_Bind (t->gl_texturenum); + + for ( ; s ; s=s->texturechain) + EmitWaterPolys (s); + + t->texturechain = NULL; + } + + } + + if (r_wateralpha.value < 1.0) { + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuDisable (GU_BLEND); + } +} + +/* +================ +DrawTextureChains +================ +*/ +static void DrawTextureChains (void) +{ + int i; + msurface_t *s; + texture_t *t; +/* + if (!gl_texsort.value) { + GL_DisableMultitexture(); + + if (skychain) { + R_DrawSkyChain(skychain); + skychain = NULL; + } + + return; + } +*/ + for (i=0 ; inumtextures ; i++) + { + t = cl.worldmodel->textures[i]; + if (!t) + continue; + s = t->texturechain; + if (!s) + continue; + if (i == skytexturenum) + R_DrawSkyChain (s); + else if (i == mirrortexturenum && r_mirroralpha.value != 1.0) + { + R_MirrorChain (s); + continue; + } + else + { + if ((s->flags & SURF_DRAWTURB) && r_wateralpha.value != 1.0) + continue; // draw translucent water later + for ( ; s ; s=s->texturechain) + R_RenderBrushPoly (s); + } + + t->texturechain = NULL; + } +} + +/* +================= +R_DrawBrushModel +================= +*/ +void R_DrawBrushModel (entity_t *e) +{ + int k;//j, k; + vec3_t mins, maxs; + int i;//, numsurfaces; + msurface_t *psurf; + float dot; + mplane_t *pplane; + model_t *clmodel; + qboolean rotated; + + currententity = e; + currenttexture = -1; + + clmodel = e->model; + + if (e->angles[0] || e->angles[1] || e->angles[2]) + { + rotated = qtrue; + for (i=0 ; i<3 ; i++) + { + mins[i] = (e->origin[i] - clmodel->radius); + maxs[i] = (e->origin[i] + clmodel->radius); + } + } + else + { + rotated = qfalse; + VectorAdd (e->origin, clmodel->mins, mins); + VectorAdd (e->origin, clmodel->maxs, maxs); + } + + if (R_CullBox (mins, maxs)) + return; + + memset (lightmap_polys, 0, sizeof(lightmap_polys)); + + VectorSubtract (r_refdef.vieworg, e->origin, modelorg); + if (rotated) + { + vec3_t temp; + vec3_t forward, right, up; + + VectorCopy (modelorg, temp); + AngleVectors (e->angles, forward, right, up); + modelorg[0] = DotProduct (temp, forward); + modelorg[1] = -DotProduct (temp, right); + modelorg[2] = DotProduct (temp, up); + } + + psurf = &clmodel->surfaces[clmodel->firstmodelsurface]; + +// calculate dynamic lighting for bmodel if it's not an +// instanced model + if (clmodel->firstmodelsurface != 0/* && !gl_flashblend.value*/) + { + for (k=0 ; knodes + clmodel->hulls[0].firstclipnode); + } + } + + sceGumPushMatrix(); + + e->angles[0] = -e->angles[0]; // stupid quake bug + R_RotateForEntity (e); + clipping::begin_brush_model(); + e->angles[0] = -e->angles[0]; // stupid quake bug + + // + // draw texture + // + for (i=0 ; inummodelsurfaces ; i++, psurf++) + { + // find which side of the node we are on + pplane = psurf->plane; + + dot = DotProduct (modelorg, pplane->normal) - pplane->dist; + + // draw the polygon + if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || + (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) + { + R_RenderBrushPoly (psurf); + } + } + + + R_BlendLightmaps (); + + clipping::end_brush_model(); + + sceGumPopMatrix(); + sceGumUpdateMatrix(); +} + +/* +============================================================= + + WORLD MODEL + +============================================================= +*/ + +/* +================ +R_RecursiveWorldNode +================ +*/ +void R_RecursiveWorldNode (mnode_t *node) +{ + int c, side;//, i, *pindex; +// vec3_t acceptpt, rejectpt; + mplane_t *plane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + float dot;//, d; +// vec3_t mins, maxs; + + if (node->contents == CONTENTS_SOLID) + return; // solid + + if (node->visframe != r_visframecount) + return; + if (R_CullBox (node->minmaxs, node->minmaxs+3)) + return; + +// if a leaf node, draw stuff + if (node->contents < 0) + { + pleaf = (mleaf_t *)node; + + mark = pleaf->firstmarksurface; + c = pleaf->nummarksurfaces; + + if (c) + { + do + { + (*mark)->visframe = r_framecount; + mark++; + } while (--c); + } + + // deal with model fragments in this leaf + if (pleaf->efrags) + R_StoreEfrags (&pleaf->efrags); + + return; + } + +// node is just a decision point, so go down the apropriate sides + +// find which side of the node we are on + plane = node->plane; + + switch (plane->type) + { + case PLANE_X: + dot = modelorg[0] - plane->dist; + break; + case PLANE_Y: + dot = modelorg[1] - plane->dist; + break; + case PLANE_Z: + dot = modelorg[2] - plane->dist; + break; + default: + dot = DotProduct (modelorg, plane->normal) - plane->dist; + break; + } + + if (dot >= 0) + side = 0; + else + side = 1; + +// recurse down the children, front side first + R_RecursiveWorldNode (node->children[side]); + +// draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + if (dot < 0 -BACKFACE_EPSILON) + side = SURF_PLANEBACK; + else if (dot > BACKFACE_EPSILON) + side = 0; + { + for ( ; c ; c--, surf++) + { + if (surf->visframe != r_framecount) + continue; + + // don't backface underwater surfaces, because they warp + if ( !(surf->flags & SURF_UNDERWATER) && ( (dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) ) + continue; // wrong side + + // if sorting by texture, just store it out + /*if (gl_texsort.value)*/ + { + if (!mirror + || surf->texinfo->texture != cl.worldmodel->textures[mirrortexturenum]) + { + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; + } + }/* else if (surf->flags & SURF_DRAWSKY) { + surf->texturechain = skychain; + skychain = surf; + } else if (surf->flags & SURF_DRAWTURB) { + surf->texturechain = waterchain; + waterchain = surf; + } else + R_DrawSequentialPoly (surf);*/ + + } + } + + } + +// recurse down the back side + R_RecursiveWorldNode (node->children[!side]); +} + +extern char skybox_name[32]; + +/* +============= +R_DrawWorld +============= +*/ +void R_DrawWorld (void) +{ + entity_t ent; +// int i; + + memset (&ent, 0, sizeof(ent)); + ent.model = cl.worldmodel; + + VectorCopy (r_refdef.vieworg, modelorg); + + currententity = &ent; + currenttexture = -1; + + /*glColor3f (1,1,1);*/ + memset (lightmap_polys, 0, sizeof(lightmap_polys)); + +//#ifdef QUAKE2 + R_ClearSkyBox (); +//#endif + + R_RecursiveWorldNode (cl.worldmodel->nodes); + + DrawTextureChains (); + + R_BlendLightmaps (); + +//#ifdef QUAKE2 + if (skybox_name[0]) + R_DrawSkyBox (); +// if (r_refdef.fog_end > 0) +// R_DrawSkyBoxFog (); +//#endif +} + + +/* +=============== +R_MarkLeaves +=============== +*/ +void R_MarkLeaves (void) +{ + byte *vis; + mnode_t *node; + int i; + byte solid[4096]; + + if (r_oldviewleaf == r_viewleaf && !r_novis.value) + return; + + if (mirror) + return; + + r_visframecount++; + r_oldviewleaf = r_viewleaf; + + if (r_novis.value) + { + vis = solid; + memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3); + } + else + vis = Mod_LeafPVS (r_viewleaf, cl.worldmodel); + + for (i=0 ; inumleafs ; i++) + { + if (vis[i>>3] & (1<<(i&7))) + { + node = (mnode_t *)&cl.worldmodel->leafs[i+1]; + do + { + if (node->visframe == r_visframecount) + break; + node->visframe = r_visframecount; + node = node->parent; + } while (node); + } + } +} + + + +/* +============================================================================= + + LIGHTMAP ALLOCATION + +============================================================================= +*/ + +// returns a texture number and the position inside it +static int AllocBlock (int w, int h, int *x, int *y) +{ + int i, j; + int best, best2; +// int bestx; + int texnum; + + for (texnum=0 ; texnum= best) + break; + if (allocated[texnum][i+j] > best2) + best2 = allocated[texnum][i+j]; + } + if (j == w) + { // this is a valid spot + *x = i; + *y = best = best2; + } + } + + if (best + h > BLOCK_HEIGHT) + continue; + + for (i=0 ; iedges; + lnumverts = fa->numedges; + vertpage = 0; + + // + // draw texture + // + poly = static_cast(Hunk_Alloc (sizeof(glpoly_t) + (lnumverts * 2 - 1) * sizeof(glvert_t))); + poly->next = fa->polys; + poly->flags = fa->flags; + fa->polys = poly; + poly->numverts = lnumverts; + + for (i=0 ; isurfedges[fa->firstedge + i]; + + if (lindex > 0) + { + r_pedge = &pedges[lindex]; + vec = r_pcurrentvertbase[r_pedge->v[0]].position; + } + else + { + r_pedge = &pedges[-lindex]; + vec = r_pcurrentvertbase[r_pedge->v[1]].position; + } + s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; + s /= fa->texinfo->texture->width; + + t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; + t /= fa->texinfo->texture->height; + + VectorCopy(vec, poly->verts[i].xyz); + poly->verts[i].st[0] = s; + poly->verts[i].st[1] = t; + + // + // lightmap texture coordinates + // + s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; + s -= fa->texturemins[0]; + s += fa->light_s*16; + s += 8; + s /= BLOCK_WIDTH*16; //fa->texinfo->texture->width; + + t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; + t -= fa->texturemins[1]; + t += fa->light_t*16; + t += 8; + t /= BLOCK_HEIGHT*16; //fa->texinfo->texture->height; + + VectorCopy(vec, poly->verts[i + lnumverts].xyz); + poly->verts[i + lnumverts].st[0] = s; + poly->verts[i + lnumverts].st[1] = t; + } + + // + // remove co-linear points - Ed + // + + // Colinear point removal-start + + int lm_vert_offset = lnumverts; + + if (!gl_keeptjunctions.value && !(fa->flags & SURF_UNDERWATER) ) + { + int numRemoved = 0; + int j; + + for (i = 0 ; i < lnumverts ; ++i) + { + vec3_t v1, v2; + const glvert_t *prev, *this_, *next; +// float f; + + prev = &poly->verts[(i + lnumverts - 1) % lnumverts]; + this_ = &poly->verts[i]; + next = &poly->verts[(i + 1) % lnumverts]; + + VectorSubtract( this_->xyz, prev->xyz, v1 ); + VectorNormalize( v1 ); + VectorSubtract( next->xyz, prev->xyz, v2 ); + VectorNormalize( v2 ); + + // skip co-linear points + #define COLINEAR_EPSILON 0.001 + if ((fabsf( v1[0] - v2[0] ) <= COLINEAR_EPSILON) && + (fabsf( v1[1] - v2[1] ) <= COLINEAR_EPSILON) && + (fabsf( v1[2] - v2[2] ) <= COLINEAR_EPSILON)) + { + for (j = i + 1; j < lnumverts; ++j) + { + poly->verts[j - 1] = poly->verts[j]; + poly->verts[lm_vert_offset + j - 1] = poly->verts[lm_vert_offset+j]; + } + + --lnumverts; + ++nColinElim; + numRemoved++; + // retry next vertex next time, which is now current vertex + --i; + } + } + + if (numRemoved > 0) { + for (j = lm_vert_offset; j < lm_vert_offset + lnumverts; j++) { + poly->verts[j - numRemoved] = poly->verts[j]; + } + } + + } + + // Colinear point removal-end + poly->numverts = lnumverts; + +} + +/* +======================== +GL_CreateSurfaceLightmap +======================== +*/ +static void GL_CreateSurfaceLightmap (msurface_t *surf) +{ + int smax, tmax;//, s, t, l, i; + byte *base; + + if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB)) + return; + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + + surf->lightmaptexturenum = AllocBlock (smax, tmax, &surf->light_s, &surf->light_t); + + base = lightmaps + surf->lightmaptexturenum*LIGHTMAP_BYTES*BLOCK_WIDTH*BLOCK_HEIGHT; + base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * LIGHTMAP_BYTES; + R_BuildLightMap (surf, base, BLOCK_WIDTH*LIGHTMAP_BYTES); +} + + +/* +================== +GL_BuildLightmaps + +Builds the lightmap texture +with all the surfaces from all brush models +================== +*/ +void GL_BuildLightmaps (void) +{ + int i, j; + model_t *m; + +// Con_Printf ("Lightmap surfaces = %i\n", MAX_LIGHTMAPS); +// Con_Printf ("Lightmap bytes = %i\n", LIGHTMAP_BYTES); + + memset (allocated, 0, sizeof(allocated)); + + r_framecount = 1; // no dlightcache + + if (!lightmap_textures) + { + lightmap_textures = 0; + } + + for (j=1 ; jname[0] == '*') + continue; + + r_pcurrentvertbase = m->vertexes; + currentmodel = m; + for (i=0 ; inumsurfaces ; i++) + { + GL_CreateSurfaceLightmap (m->surfaces + i); + if ( m->surfaces[i].flags & SURF_DRAWTURB ) + continue; +#ifndef QUAKE2 + if ( m->surfaces[i].flags & SURF_DRAWSKY ) + continue; +#endif + BuildSurfaceDisplayList (m->surfaces + i); + } + } + + // + // upload all lightmaps that were filled + // + char lm_name[16]; + for (i=0 ; i +#include +//#include + +extern "C" +{ +#include "../quakedef.h" +} + +#include "clipping.hpp" + +using namespace quake; + +extern model_t *loadmodel; + +//int skytexturenum; + +int solidskytexture = -1; +int alphaskytexture = -1; + +int sky_rt = -1; +int sky_bk = -1; +int sky_lf = -1; +int sky_ft = -1; +int sky_up = -1; +int sky_dn = -1; + +int skytexorder[6] = {0,2,1,3,4,5}; +//int skytexorder[6] = {3,1,2,0,4,5}; // The order skybox images are drawn. +int skyimage[6]; // Where sky images are stored +char skybox_name[32] = ""; //name of current skybox, or "" if no skybox +char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"}; + +// skybox pallete + +byte *host_skybasepal; + +void VID_InitPaleteSKY(unsigned char* palette); + +void VID_SetPaletteSKY(); +// switch palette for sky + +void VID_SetPaletteTX(); +// switch palette for textures + +float speedscale; // for top sky and bottom sky + +msurface_t *warpface; + +extern cvar_t gl_subdivide_size; + +static void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs) +{ + int i, j; + float *v; + + mins[0] = mins[1] = mins[2] = 9999; + maxs[0] = maxs[1] = maxs[2] = -9999; + v = verts; + for (i=0 ; i maxs[j]) + maxs[j] = *v; + } +} + +static void SubdividePolygon (int numverts, float *verts) +{ + int i, j, k; + vec3_t mins, maxs; + float m; + float *v; + vec3_t front[64], back[64]; + int f, b; + float dist[64]; + float frac; + glpoly_t *poly; + float s, t; + + if (numverts > 60) + Sys_Error ("numverts = %i", numverts); + + BoundPoly (numverts, verts, mins, maxs); + + for (i=0 ; i<3 ; i++) + { + m = (mins[i] + maxs[i]) * 0.5; + m = gl_subdivide_size.value * floorf (m/gl_subdivide_size.value + 0.5); + + if (maxs[i] - m < 8) + continue; + if (m - mins[i] < 8) + continue; + + // cut it + v = verts + i; + for (j=0 ; j= 0) + { + VectorCopy (v, front[f]); + f++; + } + if (dist[j] <= 0) + { + VectorCopy (v, back[b]); + b++; + } + if (dist[j] == 0 || dist[j+1] == 0) + continue; + if ( (dist[j] > 0) != (dist[j+1] > 0) ) + { + // clip point + frac = dist[j] / (dist[j] - dist[j+1]); + for (k=0 ; k<3 ; k++) + front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]); + f++; + b++; + } + } + + SubdividePolygon (f, front[0]); + SubdividePolygon (b, back[0]); + return; + } + + poly = static_cast(Hunk_Alloc (sizeof(glpoly_t) + (numverts - 1) * sizeof(glvert_t))); + poly->next = warpface->polys; + warpface->polys = poly; + poly->numverts = numverts; + for (i=0 ; iverts[i].xyz); + s = DotProduct (verts, warpface->texinfo->vecs[0]); + t = DotProduct (verts, warpface->texinfo->vecs[1]); + poly->verts[i].st[0] = s; + poly->verts[i].st[1] = t; + } +} + +/* +================ +GL_SubdivideSurface + +Breaks a polygon up along axial 64 unit +boundaries so that turbulent and sky warps +can be done reasonably. +================ +*/ +void GL_SubdivideSurface (msurface_t *fa) +{ + vec3_t verts[64]; + int numverts; + int i; + int lindex; + float *vec; + + warpface = fa; + + // + // convert edges back to a normal polygon + // + numverts = 0; + for (i=0 ; inumedges ; i++) + { + lindex = loadmodel->surfedges[fa->firstedge + i]; + + if (lindex > 0) + vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position; + else + vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position; + VectorCopy (vec, verts[numverts]); + numverts++; + } + + SubdividePolygon (numverts, verts[0]); +} + +/* +================ +GL_Surface +================ +*/ +void GL_Surface (msurface_t *fa) +{ + vec3_t verts[64]; + int numverts; + int i; + int lindex; + float *vec; + glpoly_t *poly; +// float texscale; + float s, t; + +// texscale = (1.0/32.0); + + // + // convert edges back to a normal polygon + // + numverts = 0; + for (i=0 ; inumedges ; i++) + { + lindex = loadmodel->surfedges[fa->firstedge + i]; + + if (lindex > 0) + vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position; + else + vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position; + VectorCopy (vec, verts[numverts]); + numverts++; + } + + //create the poly + poly = static_cast(Hunk_Alloc (sizeof(glpoly_t) + (numverts - 1) * sizeof(glvert_t))); + poly->next = NULL; + fa->polys = poly; + poly->numverts = numverts; + for (i=0, vec=(float *)verts; iverts[i].xyz); + s = DotProduct(vec, fa->texinfo->vecs[0]);// * texscale; + t = DotProduct(vec, fa->texinfo->vecs[1]);// * texscale; + poly->verts[i].st[0] = s; + poly->verts[i].st[1] = t; + } +} + +//========================================================= + + + +// speed up sin calculations - Ed +float turbsin[] = +{ + #include "../gl_warp_sin.h" +}; + +/* +============= +EmitWaterPolys + +Does a water warp on the pre-fragmented glpoly_t chain +============= +*/ +void EmitWaterPolys (msurface_t *fa) +{ + const float real_time = static_cast(realtime); + const float scale = (1.0f / 64); + const float turbscale = (256.0f / (2.0f * static_cast(M_PI))); + + // For each polygon... + for (const glpoly_t* p = fa->polys; p; p = p->next) + { + // Allocate memory for this polygon. + const int unclipped_vertex_count = p->numverts; + glvert_t* const unclipped_vertices = + static_cast(sceGuGetMemory(sizeof(glvert_t) * unclipped_vertex_count)); + + // Generate each vertex. + const glvert_t* src = p->verts; + const glvert_t* last_vertex = src + unclipped_vertex_count; + glvert_t* dst = unclipped_vertices; + + while (src != last_vertex) + { + // Get the input UVs. + const float os = src->st[0]; + const float ot = src->st[1]; + + // Fill in the vertex data. + dst->st[0] = (os + turbsin[(int) ((ot * 0.025f + real_time) * turbscale) & 255]) * scale; + dst->st[1] = (ot + turbsin[(int) ((os * 0.025f + real_time) * turbscale) & 255]) * scale; + dst->xyz[0] = src->xyz[0]; + dst->xyz[1] = src->xyz[1]; + dst->xyz[2] = src->xyz[2]; + + // Next vertex. + ++src; + ++dst; + } + + // Do these vertices need clipped? + if (clipping::is_clipping_required(unclipped_vertices, unclipped_vertex_count)) + { + // Clip the polygon. + const glvert_t* clipped_vertices; + std::size_t clipped_vertex_count; + clipping::clip( + unclipped_vertices, + unclipped_vertex_count, + &clipped_vertices, + &clipped_vertex_count); + + // Any vertices left? + if (clipped_vertex_count) + { + // Copy the vertices to the display list. + const std::size_t buffer_size = clipped_vertex_count * sizeof(glvert_t); + glvert_t* const display_list_vertices = static_cast(sceGuGetMemory(buffer_size)); + memcpy(display_list_vertices, clipped_vertices, buffer_size); + + // Draw the clipped vertices. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF, + clipped_vertex_count, 0, display_list_vertices); + } + } + else + { + // Draw the vertices. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF, + unclipped_vertex_count, 0, unclipped_vertices); + } + } +} + + +/* +============= +EmitReflectivePolys + +Does a reflective warp on the pre-fragmented glpoly_t chain +============= +*/ +void EmitReflectivePolys (msurface_t *fa) +{ + // For each polygon... + for (const glpoly_t* p = fa->polys; p; p = p->next) + { + // Allocate memory for this polygon. + const int unclipped_vertex_count = p->numverts; + glvert_t* const unclipped_vertices = + static_cast(sceGuGetMemory(sizeof(glvert_t) * unclipped_vertex_count)); + + // Generate each vertex. + const glvert_t* src = p->verts; + const glvert_t* last_vertex = src + unclipped_vertex_count; + glvert_t* dst = unclipped_vertices; + + while (src != last_vertex) + { + vec3_t dir; + VectorSubtract(src->xyz, r_origin, dir); + dir[2] *= 3; // flatten the sphere + + const float length = 6 * 63 / sqrtf(DotProduct(dir, dir)); + + dir[0] *= length; + dir[1] *= length; + + dst->st[0] = (dir[0]) * (1.0f / 256.0f); + dst->st[1] = (dir[1]) * (1.0f / 256.0f); + dst->xyz[0] = src->xyz[0]; + dst->xyz[1] = src->xyz[1]; + dst->xyz[2] = src->xyz[2]; + + // Next vertex. + ++src; + ++dst; + } + + // Do these vertices need clipped? + if (clipping::is_clipping_required(unclipped_vertices, unclipped_vertex_count)) + { + // Clip the polygon. + const glvert_t* clipped_vertices; + std::size_t clipped_vertex_count; + clipping::clip( + unclipped_vertices, + unclipped_vertex_count, + &clipped_vertices, + &clipped_vertex_count); + + // Any vertices left? + if (clipped_vertex_count) + { + // Copy the vertices to the display list. + const std::size_t buffer_size = clipped_vertex_count * sizeof(glvert_t); + glvert_t* const display_list_vertices = static_cast(sceGuGetMemory(buffer_size)); + memcpy(display_list_vertices, clipped_vertices, buffer_size); + + // Draw the clipped vertices. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF, + clipped_vertex_count, 0, display_list_vertices); + } + } + else + { + // Draw the vertices. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF, + unclipped_vertex_count, 0, unclipped_vertices); + } + } +} + +/* +============= +EmitSkyPolys +============= +*/ +void EmitSkyPolys (msurface_t *fa) +{ + + if (!kurok) + { + + for (const glpoly_t* p = fa->polys; p; p = p->next) + { + + glvert_t* const vertices = static_cast(sceGuGetMemory(sizeof(glvert_t) * p->numverts)); + + const glvert_t* src = p->verts; + const glvert_t* last_vertex = src + p->numverts; + glvert_t* dst = vertices; + + while (src != last_vertex) + { + vec3_t dir; + VectorSubtract(src->xyz, r_origin, dir); + dir[2] *= 3; // flatten the sphere + + const float length = 6 * 63 / sqrtf(DotProduct(dir, dir)); + + dir[0] *= length; + dir[1] *= length; + + dst->st[0] = (speedscale + dir[0]) * (1.0f / 128.0f); + dst->st[1] = (speedscale + dir[1]) * (1.0f / 128.0f); + dst->xyz[0] = src->xyz[0]; + dst->xyz[1] = src->xyz[1]; + dst->xyz[2] = src->xyz[2]; + + // Next vertex. + ++src; + ++dst; + } + + sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF | GU_VERTEX_32BITF, p->numverts, 0, vertices); + } + } + else + { + + for (const glpoly_t* p = fa->polys; p; p = p->next) + { + + // Allocate memory for this polygon. + const int unclipped_vertex_count = p->numverts; + glvert_t* const unclipped_vertices = + static_cast(sceGuGetMemory(sizeof(glvert_t) * unclipped_vertex_count)); + + // Generate each vertex. + const glvert_t* src = p->verts; + const glvert_t* last_vertex = src + unclipped_vertex_count; + glvert_t* dst = unclipped_vertices; + + while (src != last_vertex) + { + vec3_t dir; + VectorSubtract(src->xyz, r_origin, dir); + dir[2] *= 3; // flatten the sphere + + const float length = 6 * 63 / sqrtf(DotProduct(dir, dir)); + + dir[0] *= length; + dir[1] *= length; + + dst->st[0] = (speedscale + dir[0]) * (1.0f / 128.0f); + dst->st[1] = (speedscale + dir[1]) * (1.0f / 128.0f); + dst->xyz[0] = src->xyz[0]; + dst->xyz[1] = src->xyz[1]; + dst->xyz[2] = src->xyz[2]; + + // Next vertex. + ++src; + ++dst; + } + + // Do these vertices need clipped? + if (clipping::is_clipping_required(unclipped_vertices, unclipped_vertex_count)) + { + // Clip the polygon. + const glvert_t* clipped_vertices; + std::size_t clipped_vertex_count; + clipping::clip( + unclipped_vertices, + unclipped_vertex_count, + &clipped_vertices, + &clipped_vertex_count); + + // Any vertices left? + if (clipped_vertex_count) + { + // Copy the vertices to the display list. + const std::size_t buffer_size = clipped_vertex_count * sizeof(glvert_t); + glvert_t* const display_list_vertices = static_cast(sceGuGetMemory(buffer_size)); + memcpy(display_list_vertices, clipped_vertices, buffer_size); + + // Draw the clipped vertices. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF, + clipped_vertex_count, 0, display_list_vertices); + } + } + + else + { + // Draw the vertices. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF, + unclipped_vertex_count, 0, unclipped_vertices); + } + } + } +} + +/* +=============== +EmitBothSkyLayers + +Does a sky warp on the pre-fragmented glpoly_t chain +This will be called for brushmodels, the world +will have them chained together. +=============== +*/ +void EmitBothSkyLayers (msurface_t *fa) +{ + GL_Bind (solidskytexture); + + if (kurok) + speedscale = realtime*2; + else + speedscale = realtime*8; + + speedscale -= (int)speedscale & ~127 ; + + EmitSkyPolys (fa); + + sceGuEnable(GU_BLEND); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + + GL_Bind (alphaskytexture); + + if (kurok) + speedscale = realtime*4; + else + speedscale = realtime*16; + + speedscale -= (int)speedscale & ~127 ; + + EmitSkyPolys (fa); + + sceGuDisable(GU_BLEND); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); +} + +/* +================================================================= + + Quake 2 environment sky + +================================================================= +*/ + +/* +================================================================= + + PCX Loading + +================================================================= +*/ + +typedef struct +{ + char manufacturer; + char version; + char encoding; + char bits_per_pixel; + unsigned short xmin,ymin,xmax,ymax; + unsigned short hres,vres; + unsigned char palette[48]; + char reserved; + char color_planes; + unsigned short bytes_per_line; + unsigned short palette_type; + char filler[58]; + unsigned data; // unbounded +} pcx_t; + +byte *pcx_rgb; + +/* +============ +LoadPCX +============ +*/ + +void LoadPCX (FILE *f) +{ + pcx_t *pcx, pcxbuf; + byte palette[768]; + byte *pix; + int x, y; + int dataByte, runLength; + int count; + +// +// parse the PCX file +// + fread (&pcxbuf, 1, sizeof(pcxbuf), f); + + pcx = &pcxbuf; + + if (pcx->manufacturer != 0x0a + || pcx->version != 5 + || pcx->encoding != 1 + || pcx->bits_per_pixel != 8 + || pcx->xmax >= 320 + || pcx->ymax >= 256) + { + Con_Printf ("Bad pcx file\n"); + return; + } + + // seek to palette + fseek (f, -768, SEEK_END); + fread (palette, 1, 768, f); + + fseek (f, sizeof(pcxbuf) - 4, SEEK_SET); + + count = (pcx->xmax+1) * (pcx->ymax+1); +// pcx_rgb = malloc( count * 4); + pcx_rgb = static_cast(malloc(count*4)); + + for (y=0 ; y<=pcx->ymax ; y++) + { + pix = pcx_rgb + 4*y*(pcx->xmax+1); + for (x=0 ; x<=pcx->ymax ; ) + { + dataByte = fgetc(f); + + if((dataByte & 0xC0) == 0xC0) + { + runLength = dataByte & 0x3F; + dataByte = fgetc(f); + } + else + runLength = 1; + + while(runLength-- > 0) + { + pix[0] = palette[dataByte*3]; + pix[1] = palette[dataByte*3+1]; + pix[2] = palette[dataByte*3+2]; + pix[3] = 255; + pix += 4; + x++; + } + } + } +} + + +/* +========================================================= + +TARGA LOADING + +========================================================= +*/ + +typedef struct _TargaHeader { + unsigned char id_length, colormap_type, image_type; + unsigned short colormap_index, colormap_length; + unsigned char colormap_size; + unsigned short x_origin, y_origin, width, height; + unsigned char pixel_size, attributes; +} TargaHeader; + + +TargaHeader targa_header; +byte *targa_rgba; + +int fgetLittleShort (FILE *f) +{ + byte b1, b2; + + b1 = fgetc(f); + b2 = fgetc(f); + + return (short)(b1 + b2*256); +} + +int fgetLittleLong (FILE *f) +{ + byte b1, b2, b3, b4; + + b1 = fgetc(f); + b2 = fgetc(f); + b3 = fgetc(f); + b4 = fgetc(f); + + return b1 + (b2<<8) + (b3<<16) + (b4<<24); +} + + +/* +============= +LoadTGA +============= +*/ + +void LoadTGA (FILE *fin) +{ + int columns, rows, numPixels; + byte *pixbuf; + int row, column; + + targa_header.id_length = fgetc(fin); + targa_header.colormap_type = fgetc(fin); + targa_header.image_type = fgetc(fin); + + targa_header.colormap_index = fgetLittleShort(fin); + targa_header.colormap_length = fgetLittleShort(fin); + targa_header.colormap_size = fgetc(fin); + targa_header.x_origin = fgetLittleShort(fin); + targa_header.y_origin = fgetLittleShort(fin); + targa_header.width = fgetLittleShort(fin); + targa_header.height = fgetLittleShort(fin); + targa_header.pixel_size = fgetc(fin); + targa_header.attributes = fgetc(fin); + + if (targa_header.image_type!=2 + && targa_header.image_type!=10) + Sys_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n"); + + if (targa_header.colormap_type !=0 + || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24)) + Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n"); + + columns = targa_header.width; + rows = targa_header.height; + numPixels = columns * rows; + +// targa_rgba = malloc (numPixels*4); + targa_rgba = static_cast(malloc(numPixels*4)); + + if (targa_header.id_length != 0) + fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment + + if (targa_header.image_type==2) { // Uncompressed, RGB images + for(row=rows-1; row>=0; row--) { + pixbuf = targa_rgba + row*columns*4; + for(column=0; column=0; row--) { + pixbuf = targa_rgba + row*columns*4; + for(column=0; column0) + row--; + else + goto breakOut; + pixbuf = targa_rgba + row*columns*4; + } + } + } + else { // non run-length packet + for(j=0;j0) + row--; + else + goto breakOut; + pixbuf = targa_rgba + row*columns*4; + } + } + } + } + breakOut:; + } + } + + fclose(fin); +} + +/* +================== +R_LoadSkys +Based on fitzquake implementation, modified by MDave. +================== +*/ +void Sky_LoadSkyBox (char *name) +{ + int i, mark; + byte *f; + char filename[64],skypalette[64]; + bool nonefound = true; + +#ifdef NORMAL_MODEL + char size[64] = "_"; +#endif +#ifdef SLIM_MODEL + char size[64] = "_512_"; +#endif + + if (strcmp(skybox_name, name) == 0) + return; //no change + + //purge old textures + for (i=0; i<6; i++) + { + if (skyimage[i] && skyimage[i] != solidskytexture) + GL_UnloadTexture(skyimage[i]); + skyimage[i] = NULL; + } + + //turn off skybox if sky is set to "" + if (name[0] == 0) + { + skybox_name[0] = 0; + return; + } + + // sky palette + sprintf (skypalette, "gfx/env/%s%spalette.lmp", name, size); + host_skybasepal = static_cast(COM_LoadHunkFile (skypalette)); + if (!host_skybasepal) + { +#ifdef SLIM_MODEL + char size[64] = "_"; + sprintf (skypalette, "gfx/env/%s%spalette.lmp", name, size); + host_skybasepal = static_cast(COM_LoadHunkFile (skypalette)); + + if (!host_skybasepal) + { + Con_Printf ("Couldn't load %s%spalette.lmp, using default palette.\n", name, size); + host_skybasepal = host_basepal; + } +#endif +#ifdef NORMAL_MODEL + Con_Printf ("Couldn't load %s%spalette.lmp, using default palette.\n", name, size); + host_skybasepal = host_basepal; +#endif + } + + VID_InitPaleteSKY(host_skybasepal); + + for (i=0 ; i<6 ; i++) + { + mark = Hunk_LowMark (); + sprintf (filename, "gfx/env/%s%s%s.lmp", name, size, suf[i]); + f = static_cast(COM_LoadHunkFile (filename)); + +#ifdef SLIM_MODEL + if (f) // Load up 512 x 512 sky textures if on slim psp. + { + if (!Q_strncmp(size,"_512_",5)) + skyimage[i] = GL_LoadTexture ("", 512, 512, f+8, qfalse, GU_LINEAR, 0); + else // If no 512 x 512 textures are available, use 256 x 256. + skyimage[i] = GL_LoadTexture ("", 256, 256, f+8, qfalse, GU_LINEAR, 0); + + nonefound = false; + } +#endif +#ifdef NORMAL_MODEL + if (f) // Load up 256 x 256 sky textures if on phat psp. + { + skyimage[i] = GL_LoadTexture ("", 256, 256, f+8, qfalse, GU_LINEAR, 0); + nonefound = false; + } +#endif +#ifdef SLIM_MODEL + else // See if theres 256 x 256 sky textures available at least before giving up. + { + char size[64] = "_"; + sprintf (filename, "gfx/env/%s%s%s.lmp", name, size, suf[i]); + f = static_cast(COM_LoadHunkFile (filename)); + + if (f) // Last try + { + skyimage[i] = GL_LoadTexture ("", 256, 256, f+8, qfalse, GU_LINEAR, 0); + nonefound = false; + } + else + { + Con_Printf ("Couldn't load %s%s\n", name, size); + skyimage[i] = solidskytexture; + } + } +#endif +#ifdef NORMAL_MODEL + else + { + Con_Printf ("Couldn't load %s%s\n", name, size); + skyimage[i] = solidskytexture; + } +#endif + Hunk_FreeToLowMark (mark); + } + + if (nonefound) // go back to scrolling sky if skybox is totally missing (should never happen for kurok). + { + for (i=0; i<6; i++) + { + if (skyimage[i] && skyimage[i] != solidskytexture) + GL_UnloadTexture(skyimage[i]); + skyimage[i] = NULL; + } + skybox_name[0] = 0; + return; + } + + strcpy(skybox_name, name); +} + +/* +================= +Sky_NewMap +================= +*/ +void Sky_NewMap (void) +{ + char key[128], value[4096]; + char *data; + int i; + + //purge old textures + for (i=0; i<6; i++) + { + if (skyimage[i] && skyimage[i] != 19) + GL_UnloadTexture(skyimage[i]); + skyimage[i] = NULL; + } + + // + // initially no sky + // + + Sky_LoadSkyBox (""); + + // + // read worldspawn (this is so ugly, and shouldn't it be done on the server?) + // + data = cl.worldmodel->entities; + if (!data) + return; //FIXME: how could this possibly ever happen? -- if there's no + // worldspawn then the sever wouldn't send the loadmap message to the client + + data = COM_Parse(data); + if (!data) //should never happen + return; // error + if (com_token[0] != '{') //should never happen + return; // error + while (1) + { + data = COM_Parse(data); + if (!data) + return; // error + if (com_token[0] == '}') + break; // end of worldspawn + if (com_token[0] == '_') + strcpy(key, com_token + 1); + else + strcpy(key, com_token); + while (key[strlen(key)-1] == ' ') // remove trailing spaces + key[strlen(key)-1] = 0; + data = COM_Parse(data); + if (!data) + return; // error + strcpy(value, com_token); + + if (kurok) + { + if (!strcmp("sky", key)) + Sky_LoadSkyBox(value); + else if (!strcmp("", skybox_name)) // Kurok loads a sky by default if none is specified + Sky_LoadSkyBox ("sky"); + } + else + { + if (!strcmp("sky", key)) + Sky_LoadSkyBox(value); + +#if 1 //also accept non-standard keys + else if (!strcmp("skyname", key)) //half-life + Sky_LoadSkyBox(value); + else if (!strcmp("qlsky", key)) //quake lives + Sky_LoadSkyBox(value); +#endif + } + } +} + +/* +================= +Sky_SkyCommand_f +================= +*/ +void Sky_SkyCommand_f (void) +{ + switch (Cmd_Argc()) + { + case 1: + Con_Printf("\"sky\" is \"%s\"\n", skybox_name); + break; + case 2: + Sky_LoadSkyBox(Cmd_Argv(1)); + break; + default: + Con_Printf("usage: sky \n"); + } +} + +/* +============= +Sky_Init +============= +*/ +void Sky_Init (void) +{ + int i; + + Cmd_AddCommand ("sky",Sky_SkyCommand_f); + + for (i=0; i<6; i++) + skyimage[i] = NULL; +} + +vec3_t skyclip[6] = { + {1,1,0}, + {1,-1,0}, + {0,-1,1}, + {0,1,1}, + {1,0,1}, + {-1,0,1} +}; +int c_sky; + +// 1 = s, 2 = t, 3 = 2048 +int st_to_vec[6][3] = +{ + {3,-1,2}, + {-3,1,2}, + + {1,3,2}, + {-1,-3,2}, + + {-2,-1,3}, // 0 degrees yaw, look straight up + {2,-1,-3} // look straight down + +// {-1,2,3}, +// {1,2,-3} +}; + +// s = [0]/[2], t = [1]/[2] +int vec_to_st[6][3] = +{ + {-2,3,1}, + {2,3,-1}, + + {1,3,2}, + {-1,3,-2}, + + {-2,-1,3}, + {-2,1,-3} + +// {-1,2,3}, +// {1,2,-3} +}; + +float skymins[2][6], skymaxs[2][6]; + +void DrawSkyPolygon (int nump, vec3_t vecs) +{ + int i,j; + vec3_t v, av; + float s, t, dv; + int axis; + float *vp; + + c_sky++; + + // decide which face it maps to + VectorCopy (vec3_origin, v); + for (i=0, vp=vecs ; i av[1] && av[0] > av[2]) + { + if (v[0] < 0) + axis = 1; + else + axis = 0; + } + else if (av[1] > av[2] && av[1] > av[0]) + { + if (v[1] < 0) + axis = 3; + else + axis = 2; + } + else + { + if (v[2] < 0) + axis = 5; + else + axis = 4; + } + + // project new texture coords + for (i=0 ; i 0) + dv = vecs[j - 1]; + else + dv = -vecs[-j - 1]; + + j = vec_to_st[axis][0]; + if (j < 0) + s = -vecs[-j -1] / dv; + else + s = vecs[j-1] / dv; + j = vec_to_st[axis][1]; + if (j < 0) + t = -vecs[-j -1] / dv; + else + t = vecs[j-1] / dv; + + if (s < skymins[0][axis]) + skymins[0][axis] = s; + if (t < skymins[1][axis]) + skymins[1][axis] = t; + if (s > skymaxs[0][axis]) + skymaxs[0][axis] = s; + if (t > skymaxs[1][axis]) + skymaxs[1][axis] = t; + } +} + +#define MAX_CLIP_VERTS 64 +void ClipSkyPolygon (int nump, vec3_t vecs, int stage) +{ + float *norm; + float *v; + qboolean front, back; + float d, e; + float dists[MAX_CLIP_VERTS]; + int sides[MAX_CLIP_VERTS]; + vec3_t newv[2][MAX_CLIP_VERTS]; + int newc[2]; + int i, j; + + if (nump > MAX_CLIP_VERTS-2) + Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS"); + if (stage == 6) + { // fully clipped, so draw it + DrawSkyPolygon (nump, vecs); + return; + } + + front = back = qfalse; + norm = skyclip[stage]; + for (i=0, v = vecs ; i ON_EPSILON) + { + front = qtrue; + sides[i] = SIDE_FRONT; + } + else if (d < ON_EPSILON) + { + back = qtrue; + sides[i] = SIDE_BACK; + } + else + sides[i] = SIDE_ON; + dists[i] = d; + } + + if (!front || !back) + { // not clipped + ClipSkyPolygon (nump, vecs, stage+1); + return; + } + + // clip it + sides[i] = sides[0]; + dists[i] = dists[0]; + VectorCopy (vecs, (vecs+(i*3)) ); + newc[0] = newc[1] = 0; + + for (i=0, v = vecs ; i 511.0f/512.0f) + s = 511.0f/512.0f; + + if (t < 1.0f/512.0f) + t = 1.0f/512.0f; + else if (t > 511.0f/512.0f) + t = 511.0f/512.0f; + + // Stupid Sony leaving hardware bugs in phat psp's, they don't like the t axis flipped so the images have to be pre-flipped, sigh ... +// t = 1.0f - t; + + s_axis = s; + t_axis = t; +} + +/* +============== +R_DrawSkyBox +============== +*/ +void R_DrawSkyBox (void) +{ + int i; + float r,g,b,a; + + for (i=0 ; i<6 ; i++) + { + // Allocate memory for this polygon. + const int unclipped_vertex_count = 4; + glvert_t* const unclipped_vertices = + static_cast(sceGuGetMemory(sizeof(glvert_t) * unclipped_vertex_count)); + + if (skymins[0][i] >= skymaxs[0][i] + || skymins[1][i] >= skymaxs[1][i]) + continue; + + GL_Bind (skyimage[skytexorder[i]]); + + MakeSkyVec (skymins[0][i], skymins[1][i], i); + + unclipped_vertices[0].st[0] = s_axis; + unclipped_vertices[0].st[1] = t_axis; + unclipped_vertices[0].xyz[0] = v_axis[0]; + unclipped_vertices[0].xyz[1] = v_axis[1]; + unclipped_vertices[0].xyz[2] = v_axis[2]; + + MakeSkyVec (skymins[0][i], skymaxs[1][i], i); + + unclipped_vertices[1].st[0] = s_axis; + unclipped_vertices[1].st[1] = t_axis; + unclipped_vertices[1].xyz[0] = v_axis[0]; + unclipped_vertices[1].xyz[1] = v_axis[1]; + unclipped_vertices[1].xyz[2] = v_axis[2]; + + MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i); + + unclipped_vertices[2].st[0] = s_axis; + unclipped_vertices[2].st[1] = t_axis; + unclipped_vertices[2].xyz[0] = v_axis[0]; + unclipped_vertices[2].xyz[1] = v_axis[1]; + unclipped_vertices[2].xyz[2] = v_axis[2]; + + MakeSkyVec (skymaxs[0][i], skymins[1][i], i); + + unclipped_vertices[3].st[0] = s_axis; + unclipped_vertices[3].st[1] = t_axis; + unclipped_vertices[3].xyz[0] = v_axis[0]; + unclipped_vertices[3].xyz[1] = v_axis[1]; + unclipped_vertices[3].xyz[2] = v_axis[2]; + + if (clipping::is_clipping_required( + unclipped_vertices, + unclipped_vertex_count)) + { + // Clip the polygon. + const glvert_t* clipped_vertices; + std::size_t clipped_vertex_count; + clipping::clip( + unclipped_vertices, + unclipped_vertex_count, + &clipped_vertices, + &clipped_vertex_count); + + // Did we have any vertices left? + if (clipped_vertex_count) + { + // Copy the vertices to the display list. + const std::size_t buffer_size = clipped_vertex_count * sizeof(glvert_t); + glvert_t* const display_list_vertices = static_cast(sceGuGetMemory(buffer_size)); + memcpy(display_list_vertices, clipped_vertices, buffer_size); + + // sceKernelDcacheWritebackRange(display_list_vertices,buffer_size); + + if(cl.worldmodel) + VID_SetPaletteSKY (); + + Fog_DisableGFog(); + + if (r_refdef.fog_end > 0.0f && r_skyfog.value) + { + a = r_refdef.fog_end * 0.00025f; + r = r_refdef.fog_red * 0.01f + (a * 0.25f); + g = r_refdef.fog_green * 0.01f + (a * 0.25f); + b = r_refdef.fog_blue * 0.01f + (a * 0.25f); + + if (a > 1.0f) + a = 1.0f; + if (r > 1.0f) + r = 1.0f; + if (g > 1.0f) + g = 1.0f; + if (b > 1.0f) + b = 1.0f; + + sceGuEnable(GU_BLEND); + sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, GU_COLOR(r,g,b,a), GU_COLOR(r,g,b,a)); + } + + sceGuDepthRange(32767, 65535); +// sceGuTexWrap(GU_CLAMP, GU_CLAMP); + + // Draw the clipped vertices. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF, + clipped_vertex_count, 0, display_list_vertices); + +// sceGuTexWrap(GU_REPEAT, GU_REPEAT); + sceGuDepthRange(0, 65535); + + if (r_refdef.fog_end > 0.0f && r_skyfog.value) + { + sceGuDisable(GU_BLEND); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + } + + VID_SetPaletteTX (); + Fog_EnableGFog(); + + } + } + else + { + + if(cl.worldmodel) + VID_SetPaletteSKY (); + + Fog_DisableGFog(); + + if (r_refdef.fog_end > 0.0f && r_skyfog.value) + { + a = r_refdef.fog_end * 0.00025f; + r = r_refdef.fog_red * 0.01f + (a * 0.25f); + g = r_refdef.fog_green * 0.01f + (a * 0.25f); + b = r_refdef.fog_blue * 0.01f + (a * 0.25f); + + if (a > 1) + a = 1; + if (r > 1) + r = 1; + if (g > 1) + g = 1; + if (b > 1) + b = 1; + + sceGuEnable(GU_BLEND); + sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, GU_COLOR(r,g,b,a), GU_COLOR(r,g,b,a)); + } + + sceGuDepthRange(32767, 65535); + // sceGuTexWrap(GU_CLAMP, GU_CLAMP); + + // Draw the poly directly. + sceGuDrawArray( + GU_TRIANGLE_FAN, + GU_TEXTURE_32BITF | GU_VERTEX_32BITF, + unclipped_vertex_count, 0, unclipped_vertices); + +// sceGuTexWrap(GU_REPEAT, GU_REPEAT); + sceGuDepthRange(0, 65535); + + if (r_refdef.fog_end > 0.0f && r_skyfog.value) + { + sceGuDisable(GU_BLEND); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + } + + VID_SetPaletteTX (); + Fog_EnableGFog(); + } + } +} + +//=============================================================== + +/* +================= +R_DrawSkyChain +================= +*/ +void R_DrawSkyChain (msurface_t *s) +{ + msurface_t *fa; + int i; + vec3_t verts[MAX_CLIP_VERTS]; + glpoly_t *p; + + if (skybox_name[0]) // if the skybox has a name, draw the skybox + { + c_sky = 0; + // GL_Bind(solidskytexture); + + // calculate vertex values for sky box + + for (fa=s ; fa ; fa=fa->texturechain) + { + for (p=fa->polys ; p ; p=p->next) + { + for (i=0 ; inumverts ; i++) + { + VectorSubtract (p->verts[i].xyz, r_origin, verts[i]); + } + ClipSkyPolygon (p->numverts, verts[0], 0); + } + + } + } + else // otherwise, draw the normal quake sky + { + // used when gl_texsort is on + GL_Bind(solidskytexture); + + if (kurok) + speedscale = realtime*2; + else + speedscale = realtime*8; + + speedscale -= (int)speedscale & ~127 ; + + for (fa=s ; fa ; fa=fa->texturechain) + EmitSkyPolys (fa); + + sceGuEnable(GU_BLEND); +// sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + + GL_Bind (alphaskytexture); + + if (kurok) + speedscale = realtime*4; + else + speedscale = realtime*16; + + speedscale -= (int)speedscale & ~127 ; + + for (fa=s ; fa ; fa=fa->texturechain) + EmitSkyPolys (fa); + + sceGuDisable(GU_BLEND); +// sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + } +} + + +//=============================================================== + +/* +============= +R_InitSky + +A sky texture is 256*128, with the right side being a masked overlay +============== +*/ +//void R_InitSky (texture_t *mt) +void R_InitSky (byte *mt) +{ + byte trans[128*128]; + + const byte* const src = (byte *)mt; // + mt->offsets[0]; + + for (int i=0 ; i<128 ; i++) + { + for (int j=0 ; j<128 ; j++) + { + const byte p = src[i*256 + j + 128]; + trans[(i*128) + j] = p; + } + } + + if (solidskytexture == -1) + solidskytexture = GL_LoadTexture("", 128, 128, trans, qfalse, GU_LINEAR, 0); + + for (int i=0 ; i<128 ; i++) + { + for (int j=0 ; j<128 ; j++) + { + const byte p = src[i*256 + j]; + if (p == 0) + trans[(i*128) + j] = 255; + else + trans[(i*128) + j] = p; + } + } + + if (alphaskytexture == -1) + alphaskytexture = GL_LoadTexture("", 128, 128, trans, qfalse, GU_LINEAR, 0); +} diff --git a/r17/Revamped src/revamped_src/psp/video_software.cpp b/r17/Revamped src/revamped_src/psp/video_software.cpp new file mode 100755 index 00000000..1acb175c --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_software.cpp @@ -0,0 +1,346 @@ +/* +Quake PSP port. +Copyright (C) 2005-2006 Peter Mackay + +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include +#include +#include + +extern "C" +{ +#include "../quakedef.h" +#include "../d_local.h" +} + + +#define DEF_SCREEN_WIDTH 480 +#define DEF_SCREEN_HEIGHT 272 +#define MIN_SCREEN_WIDTH 320 +#define MIN_SCREEN_HEIGHT 200 +#define MAX_SCREEN_WIDTH 480 +#define MAX_SCREEN_HEIGHT 272 + +#define DEF_RENDER_WIDTH 320 +#define DEF_RENDER_HEIGHT 200 +#define MIN_RENDER_WIDTH 320 +#define MIN_RENDER_HEIGHT 200 +#define MAX_RENDER_WIDTH 480 +#define MAX_RENDER_HEIGHT 272 + + + +namespace quake +{ + namespace video + { + // Types. + typedef ScePspRGBA8888 Pixel; + typedef u8 Texel; + + // Constants. + static size_t screenWidth = DEF_SCREEN_WIDTH; + static size_t screenHeight = DEF_SCREEN_HEIGHT; + static size_t renderWidth = DEF_RENDER_WIDTH; + static size_t renderHeight = DEF_RENDER_HEIGHT; + static const size_t textureWidth = 512; + static const size_t textureHeight = 512; + static const size_t paletteSize = 256; + static void* const vramBase = sceGeEdramGetAddr(); + static Pixel* displayBuffer = static_cast(vramBase); + static Pixel* backBuffer = static_cast(displayBuffer + (512 * screenHeight)); + static Texel* texture0 = reinterpret_cast(displayBuffer + 2 * (512 * screenHeight)); + static Texel* texture1 = texture0 + (textureWidth * textureHeight); + + // Regular globals. + static Pixel __attribute__((aligned(16))) texturePalette[paletteSize]; + static short *zbuffer; + static unsigned char *surfaceCache; + + //! The GU display list. + //! @note Aligned to 64 bytes so it doesn't share a cache line with anything. + unsigned int *displayList; + } +} + +using namespace quake; +using namespace quake::video; + +// Globals required by Quake. +unsigned short d_8to16table[paletteSize]; + +void VID_SetPalette(unsigned char* palette) +{ + // Convert the palette to PSP format. + for(Pixel* color = &texturePalette[0]; color < &texturePalette[paletteSize]; ++color) + { + const unsigned int r = *palette++; + const unsigned int g = *palette++; + const unsigned int b = *palette++; + *color = r | (g << 8) | (b << 16); + } + + // Upload the palette. + sceGuClutMode(GU_PSM_8888, 0, paletteSize - 1, 0); + sceKernelDcacheWritebackRange(texturePalette, sizeof(texturePalette)); + sceGuClutLoad(paletteSize / 8, texturePalette); +} + +void VID_ShiftPalette(unsigned char* palette) +{ + VID_SetPalette(palette); +} + +void VID_Init(unsigned char* palette) +{ + if (COM_CheckParm("-rwidth")) { + renderWidth = atoi(com_argv[COM_CheckParm("-rwidth")+1]); + + if (renderWidth < MIN_RENDER_WIDTH) + renderWidth = MIN_RENDER_WIDTH; + if (renderWidth > MAX_RENDER_WIDTH) + renderWidth = MAX_RENDER_WIDTH; + if ((renderWidth % 8) != 0) + renderWidth = DEF_RENDER_WIDTH; + } + else + { + renderWidth = DEF_RENDER_WIDTH; + } + + if (COM_CheckParm("-rheight")) { + renderHeight = atoi(com_argv[COM_CheckParm("-rheight")+1]); + + if (renderHeight < MIN_RENDER_HEIGHT) + renderHeight = MIN_RENDER_HEIGHT; + if (renderHeight > MAX_RENDER_HEIGHT) + renderHeight = MAX_RENDER_HEIGHT; + if ((renderHeight % 8) != 0) + renderHeight = DEF_RENDER_HEIGHT; + } + else + { + renderHeight = DEF_RENDER_HEIGHT; + } + + if (COM_CheckParm("-swidth")) { + screenWidth = atoi(com_argv[COM_CheckParm("-swidth")+1]); + + if (screenWidth < MIN_SCREEN_WIDTH) + screenWidth = MIN_SCREEN_WIDTH; + if (screenWidth > MAX_SCREEN_WIDTH) + screenWidth = MAX_SCREEN_WIDTH; + if ((screenWidth % 8) != 0) + screenWidth = DEF_SCREEN_WIDTH; + } + else + { + screenWidth = DEF_SCREEN_WIDTH; + } + + if (COM_CheckParm("-sheight")) { + screenHeight = atoi(com_argv[COM_CheckParm("-sheight")+1]); + + if (screenHeight < MIN_SCREEN_HEIGHT) + screenHeight = MIN_SCREEN_HEIGHT; + if (screenHeight > MAX_SCREEN_HEIGHT) + screenHeight = MAX_SCREEN_HEIGHT; + if ((screenHeight % 8) != 0) + screenHeight = DEF_SCREEN_HEIGHT; + } + else + { + screenHeight = DEF_SCREEN_HEIGHT; + } + + int surfaceCacheSize = SURFCACHE_SIZE_AT_320X200 + ((renderWidth * renderHeight) - (320 * 200)) * 3; + + zbuffer = (short *)malloc(sizeof(short) * renderWidth * renderHeight); + surfaceCache = (unsigned char *)malloc(surfaceCacheSize); + displayList = (unsigned int *)memalign(64, sizeof(int) * 128 * 1024); + + if(!zbuffer) + Sys_Error("No memory for zbuffer\n"); + + if(!surfaceCache) + Sys_Error("No memory for surfaceCache\n"); + + if(!displayList) + Sys_Error("No memory for displayList\n"); + + // Initialise the GU. + sceGuInit(); + + // Set up the GU. + sceGuStart(GU_DIRECT, displayList); + { + // Set the draw and display buffers. + void* const displayBufferInVRAM = reinterpret_cast(displayBuffer) - reinterpret_cast(vramBase); + void* const backBufferInVRAM = reinterpret_cast(backBuffer) - reinterpret_cast(vramBase); + + sceGuDrawBuffer(GU_PSM_8888, backBufferInVRAM, 512); + sceGuDispBuffer(MAX_SCREEN_WIDTH, MAX_SCREEN_HEIGHT, displayBufferInVRAM, 512); + + // Set the rendering offset and viewport. + sceGuOffset(2048 - (MAX_SCREEN_WIDTH / 2), 2048 - (MAX_SCREEN_HEIGHT / 2)); + sceGuViewport(2048, 2048, MAX_SCREEN_WIDTH, MAX_SCREEN_HEIGHT); + + // Set up scissoring. + sceGuEnable(GU_SCISSOR_TEST); + sceGuScissor(0, 0, MAX_SCREEN_WIDTH, MAX_SCREEN_HEIGHT); + + // Set up texturing. + sceGuEnable(GU_TEXTURE_2D); + sceGuTexMode(GU_PSM_T8, 0, 0, GU_FALSE); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); + sceGuTexFilter(GU_LINEAR, GU_LINEAR); + } + sceGuFinish(); + sceGuSync(0,0); + + // Turn on the display. + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + // What is the aspect ratio? + const float screenAspectRatio = static_cast(screenWidth) / screenHeight; + const float renderAspectRatio = static_cast(renderWidth) / renderHeight; + + // Set up Quake's video parameters. + vid.aspect = screenAspectRatio / renderAspectRatio; + vid.buffer = texture0; + vid.colormap = host_colormap; + vid.colormap16 = 0; + vid.conbuffer = texture0; + vid.conheight = renderHeight; + vid.conrowbytes = textureWidth; + vid.conwidth = renderWidth; + vid.direct = texture0; + vid.fullbright = paletteSize - LittleLong(*((int *) vid.colormap + 2048)); + vid.height = renderHeight; + vid.maxwarpheight = WARP_HEIGHT; + vid.maxwarpwidth = WARP_WIDTH; + vid.numpages = 2; + vid.recalc_refdef = 0; + vid.rowbytes = textureWidth; + vid.width = renderWidth; + + // Set the z buffer address. + d_pzbuffer = zbuffer; + + // Initialise the surface cache. + D_InitCaches(surfaceCache, surfaceCacheSize); + + Con_Printf ("Rendered at ( %d x %d ) \n",vid.width, vid.height); + Con_Printf ("Displayed at ( %d x %d ) \n",screenWidth, screenHeight); + + // This is an awful hack to get around a division by zero later on... + r_refdef.vrect.width = renderWidth; + r_refdef.vrect.height = renderHeight; + + // Start a render. + sceGuStart(GU_DIRECT, displayList); + + // Set the palette. + VID_SetPalette(palette); +} + +void VID_Shutdown(void) +{ + // Finish rendering. + sceGuFinish(); + sceGuSync(0,0); + + // Shut down the display. + sceGuTerm(); + + if(zbuffer) + free(zbuffer); + + if(surfaceCache) + free(surfaceCache); + + if(displayList) + free(displayList); +} + +void VID_Update(vrect_t* rects) +{ + // Finish rendering. + sceGuFinish(); + sceGuSync(0, 0); + + // Switch the buffers. + sceGuSwapBuffers(); + + // Start a new render. + sceGuStart(GU_DIRECT, displayList); + + // Allocate memory in the display list for some vertices. + struct Vertex + { + SceUShort16 u, v; + SceShort16 x, y, z; + } * const vertices = static_cast(sceGuGetMemory(sizeof(Vertex) * 2)); + + int dif_x = (MAX_SCREEN_WIDTH/2) - (screenWidth/2); + int dif_y = (MAX_SCREEN_HEIGHT/2) - (screenHeight/2); + + + // Set up the vertices. + vertices[0].u = 0; + vertices[0].v = 0; + vertices[0].x = dif_x; + vertices[0].y = dif_y; + vertices[0].z = 0; + vertices[1].u = renderWidth; + vertices[1].v = renderHeight; + vertices[1].x = screenWidth+dif_x; + vertices[1].y = screenHeight+dif_y; + vertices[1].z = 0; + + // Flush the data cache. + sceKernelDcacheWritebackRange(vid.buffer, textureWidth * textureHeight); + + // Set the texture. + sceGuTexImage(0, textureWidth, textureHeight, textureWidth, vid.buffer); + + // Draw the sprite. + sceGuDrawArray( + GU_SPRITES, + GU_VERTEX_16BIT | GU_TEXTURE_16BIT | GU_TRANSFORM_2D, + 2, + 0, + vertices); + + // Swap Quake's buffers. + Texel* const newTexture = (vid.buffer == texture0) ? texture1 : texture0; + vid.buffer = newTexture; + vid.conbuffer = newTexture; + vid.direct = newTexture; +} + +void D_BeginDirectRect(int x, int y, byte* pbitmap, int width, int height) +{ +} + +void D_EndDirectRect(int x, int y, int width, int height) +{ +} diff --git a/r17/Revamped src/revamped_src/psp/video_vertex_lighting.c b/r17/Revamped src/revamped_src/psp/video_vertex_lighting.c new file mode 100755 index 00000000..ae51d221 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_vertex_lighting.c @@ -0,0 +1,157 @@ +// Following code is from the Quake Standards Group +// tutorial "Vertex Lighting" by (c)2001 Orbiter Productions, +// and is protected by the terms and conditions described +// in the GNU General Public License, downloadable at +// http://www.gnu.org/copyleft/gpl.html. + +// RIOT - Vertex lighting for models + +#include "../quakedef.h" +#include "video_vertex_lighting.h" + +byte anorm_pitch[162]; +byte anorm_yaw[162]; +byte vlighttable[256][256]; + +float VLight_GetLightValue(int index, float apitch, float ayaw) +{ + int pitchofs, yawofs; + float retval; + + pitchofs = anorm_pitch[index] + (apitch * 256 / 360); + yawofs = anorm_yaw[index] + (ayaw * 256 / 360); + + while(pitchofs > 255) + pitchofs -= 256; + while(yawofs > 255) + yawofs -= 256; + while(pitchofs < 0) + pitchofs += 256; + while(yawofs < 0) + yawofs += 256; + + retval = vlighttable[pitchofs][yawofs]; + + return retval / 256; +} + +float VLight_LerpLight(int index1, int index2, float ilerp, float apitch, float ayaw) +{ + float lightval1; + float lightval2; + + lightval1 = VLight_GetLightValue(index1, apitch, ayaw); + lightval2 = VLight_GetLightValue(index2, apitch, ayaw); + + return (lightval2*ilerp) + (lightval1*(1-ilerp)); +} + +void VLight_ResetAnormTable() +{ + int i,j; + vec3_t tempanorms[162] = { +#include "../anorms.h" + }; + + float forward; + float yaw, pitch; + float angle; + float sp, sy, cp, cy; + float precut; + vec3_t normal; + vec3_t lightvec; + + // Define the light vector here + angle = DEG2RAD(vlight_pitch.value); + sy = sin(angle); + cy = cos(angle); + angle = DEG2RAD(-vlight_yaw.value); + sp = sin(angle); + cp = cos(angle); + + lightvec[0] = cp*cy; + lightvec[1] = cp*sy; + lightvec[2] = -sp; + + // First thing that needs to be done is the conversion of the + // anorm table into a pitch/yaw table + + for(i=0;i<162;i++) + { + if (tempanorms[i][1] == 0 && tempanorms[i][0] == 0) + { + yaw = 0; + if (tempanorms[i][2] > 0) + pitch = 90; + else + pitch = 270; + } + else + { + yaw = (int) (atan2(tempanorms[i][1], tempanorms[i][0]) * 57.295779513082320); + if (yaw < 0) + yaw += 360; + + forward = sqrt (tempanorms[i][0]*tempanorms[i][0] + tempanorms[i][1]*tempanorms[i][1]); + pitch = (int) (atan2(tempanorms[i][2], forward) * 57.295779513082320); + + if (pitch < 0) + pitch += 360; + } + anorm_pitch[i] = pitch * 256 / 360; + anorm_yaw[i] = yaw * 256 / 360; + } + + // Next, a light value table must be constructed for pitch/yaw offsets + // DotProduct values + + // DotProduct values never go higher than 2, so store bytes as + // (product * 127.5) + + if(vlight_highcut.value <= vlight_lowcut.value || vlight_highcut.value > 256 || vlight_highcut.value < 10) + Cvar_SetValue("vl_highcut", 256); + + if(vlight_lowcut.value >= vlight_highcut.value || vlight_lowcut.value < 0 || vlight_lowcut.value > 250) + Cvar_SetValue("vl_lowcut", 0); + + for(i=0;i<256;i++) + { + + angle = DEG2RAD(i * 360 / 256); + sy = sin(angle); + cy = cos(angle); + + for(j=0;j<256;j++) + { + angle = DEG2RAD(j * 360 / 256); + sp = sin(angle); + cp = cos(angle); + + normal[0] = cp*cy; + normal[1] = cp*sy; + normal[2] = -sp; + + precut = ((DotProduct(normal, lightvec) + 2) * 63.5); + precut = (precut - (vlight_lowcut.value)) * 256 / (vlight_highcut.value - vlight_lowcut.value); + + if(precut > 255) + precut = 255; + + if(precut < 0) + precut = 0; + + vlighttable[i][j] = precut; + } + } +} + +void VLight_ChangeLightAngle_f(void) +{ + VLight_ResetAnormTable(); + +} + +void VLight_DumpLightTable_f(void) +{ + COM_WriteFile ("lighttable.raw", vlighttable, 256*256); +} diff --git a/r17/Revamped src/revamped_src/psp/video_vertex_lighting.h b/r17/Revamped src/revamped_src/psp/video_vertex_lighting.h new file mode 100755 index 00000000..39aafa74 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/video_vertex_lighting.h @@ -0,0 +1,13 @@ +// Following code is from the Quake Standards Group +// tutorial "Vertex Lighting" by (c)2001 Orbiter Productions, +// and is protected by the terms and conditions described +// in the GNU General Public License, downloadable at +// http://www.gnu.org/copyleft/gpl.html. + +// RIOT - Vertex lighting for models + +extern byte anorm_pitch[162]; +extern byte anorm_yaw[162]; +extern byte vlighttable[256][256]; + +float VLight_LerpLight(int index1, int index2, float ilerp, float apitch, float ayaw); diff --git a/r17/Revamped src/revamped_src/psp/vram.cpp b/r17/Revamped src/revamped_src/psp/vram.cpp new file mode 100755 index 00000000..1560a3ea --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/vram.cpp @@ -0,0 +1,162 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#define VRAM_DEBUGGING 0 + +#include "vram.hpp" + +#include +#include + +extern "C" +{ +#include "../quakedef.h" +} + +namespace quake +{ + namespace vram + { + typedef std::vector allocated_list; + + static char* const base = static_cast(sceGeEdramGetAddr()); + static const std::size_t block_size = 32 * 32; + static const std::size_t block_count = sceGeEdramGetSize() / block_size; + static allocated_list allocated(block_count, 0); + static std::size_t bytes_required = 0; + static std::size_t bytes_allocated = 0; + + void* allocate(std::size_t size) + { + // How many blocks to allocate? + bytes_required += size; + std::size_t blocks_required = (size + block_size - 1) / block_size; + +#if VRAM_DEBUGGING + Con_Printf("vram::allocate %u bytes (%u blocks)\n", size, blocks_required); + Con_Printf("\tblock_size = %u\n", block_size); + Con_Printf("\tblock_count = %u\n", block_count); +#endif + + // Find a sequential area this big. + for (std::size_t start = 0; start < (block_count - blocks_required);) + { + // Is this block allocated? + const std::size_t allocated_blocks = allocated.at(start); + if (allocated_blocks) + { + // Skip the allocated block. + start += allocated_blocks; + +#if VRAM_DEBUGGING + //Con_Printf("\tskipping from block %u to %u\n", start - allocated_blocks, start); +#endif + } + else + { + // Where would the allocated block end? + const std::size_t end = start + blocks_required; + +#if VRAM_DEBUGGING + //Con_Printf("\ttrying blocks %u to %u\n", start, end - 1); +#endif + + // Check for allocated blocks in the area we want. + std::size_t free_blocks_here = 1; + for (std::size_t b = start + 1; b < end; ++b) + { + if (allocated.at(b)) + { + break; + } + else + { + ++free_blocks_here; + } + } + + // Is the block big enough? + if (free_blocks_here >= blocks_required) + { + // Mark it as allocated. +#if VRAM_DEBUGGING + Con_Printf("\tmarking blocks %u to %u as allocated\n", start, end - 1); +#endif + bytes_allocated += (blocks_required * block_size); + for (std::size_t b = start; b < end; ++b) + { + allocated.at(b) = blocks_required--; + } + + // Done. +#if VRAM_DEBUGGING + Con_Printf("\tdone (%u allocated, %u required)\n", bytes_allocated, bytes_required); +#endif + return base + (block_size * start); + } + else + { + // Move on. + start += free_blocks_here; +#if VRAM_DEBUGGING + Con_Printf("\tskipping from block %u to %u, because there wasn't a big enough run of free blocks\n", + start - free_blocks_here, start); +#endif + } + } + } + + // Failed. +#if VRAM_DEBUGGING + Con_Printf("\tfailed, no free blocks big enough (%u allocated, %u required)\n", + bytes_allocated, bytes_required); +#endif + return 0; + } + + void free(void* memory) + { + // Which block is this? + const std::size_t relative_address = static_cast(memory) - base; + const std::size_t block_index = relative_address / block_size; + +#if VRAM_DEBUGGING + Con_Printf("vram::free freeing blocks starting with %u\n", block_index); +#endif + + // Mark the blocks as deallocated. + const std::size_t blocks_to_free = allocated.at(block_index); +#if VRAM_DEBUGGING + Con_Printf("\tfreeing to %u\n", block_index + blocks_to_free - 1); +#endif + for (std::size_t block = 0; block < blocks_to_free; ++block) + { + allocated.at(block_index + block) = 0; + } + + const std::size_t bytes_to_free = blocks_to_free * block_size; + bytes_allocated -= bytes_to_free; + bytes_required -= bytes_to_free; +#if VRAM_DEBUGGING + Con_Printf("\tnow %u allocated, %u required\n", bytes_allocated, bytes_required); +#endif + } + } +} diff --git a/r17/Revamped src/revamped_src/psp/vram.hpp b/r17/Revamped src/revamped_src/psp/vram.hpp new file mode 100755 index 00000000..202b75e2 --- /dev/null +++ b/r17/Revamped src/revamped_src/psp/vram.hpp @@ -0,0 +1,38 @@ +/* +Copyright (C) 2007 Peter Mackay and Chris Swindle. + +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. + +*/ + +#ifndef QUAKE_VRAM_HPP +#define QUAKE_VRAM_HPP + +#include + +namespace quake +{ + namespace vram + { + // Allocates a block of VRAM. + void* allocate(std::size_t size); + + // Frees a block of VRAM. + void free(void* const memory); + } +} + +#endif diff --git a/r17/Revamped src/revamped_src/quakedef.h b/r17/Revamped src/revamped_src/quakedef.h new file mode 100755 index 00000000..9fb73f18 --- /dev/null +++ b/r17/Revamped src/revamped_src/quakedef.h @@ -0,0 +1,371 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// quakedef.h -- primary header for client + +//#define GLTEST // experimental stuff + +#define QUAKE_GAME // as opposed to utilities + +#define KUR_VERSION 1 + +#define VERSION 1.09 +#define GLQUAKE_VERSION 1.00 +#define D3DQUAKE_VERSION 0.01 +#define WINQUAKE_VERSION 0.996 +#define LINUX_VERSION 1.30 +#define X11_VERSION 1.10 + +//define PARANOID // speed sapping error checking + +#ifdef QUAKE2 +#define GAMENAME "revamped" // directory to look in by default +#else +#define GAMENAME "revamped" +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(WIN32) && !defined(WINDED) + +#if defined(_M_IX86) +#define __i386__ 1 +#endif + +void VID_LockBuffer (void); +void VID_UnlockBuffer (void); + +#else + +#define VID_LockBuffer() +#define VID_UnlockBuffer() + +#endif + +#if defined __i386__ // && !defined __sun__ +#define id386 1 +#else +#define id386 0 +#endif + +#if id386 +#define UNALIGNED_OK 1 // set to 0 if unaligned accesses are not supported +#else +#define UNALIGNED_OK 0 +#endif + +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +#define CACHE_SIZE 32 // used to align key data structures + +#define UNUSED(x) (x = x) // for pesky compiler / lint warnings + +#define MINIMUM_MEMORY 0x550000 +#define MINIMUM_MEMORY_LEVELPAK (MINIMUM_MEMORY + 0x100000) + +#define MAX_NUM_ARGVS 50 + +// up / down +#define PITCH 0 + +// left / right +#define YAW 1 + +// fall over +#define ROLL 2 + + +#define MAX_QPATH 64 // max length of a quake game pathname +#define MAX_OSPATH 128 // max length of a filesystem pathname + +#define ON_EPSILON 0.1 // point on plane side epsilon + +#define MAX_MSGLEN 8000 // max length of a reliable message +#define MAX_DATAGRAM 1024 // max length of unreliable message + +// +// per-level limits +// +#define MAX_EDICTS 1024 // FIXME: ouch! ouch! ouch! +#define MAX_LIGHTSTYLES 64 +#define MAX_MODELS 256 // these are sent over the net as bytes +#define MAX_SOUNDS 256 // so they cannot be blindly increased + +#define SAVEGAME_COMMENT_LENGTH 39 + +#define MAX_STYLESTRING 64 + +// +// stats are integers communicated to the client by the server +// +#define MAX_CL_STATS 32 +#define STAT_HEALTH 0 +#define STAT_FRAGS 1 +#define STAT_WEAPON 2 +#define STAT_AMMO 3 +#define STAT_ARMOR 4 +#define STAT_WEAPONFRAME 5 +#define STAT_SHELLS 6 +#define STAT_NAILS 7 +#define STAT_ROCKETS 8 +#define STAT_CELLS 9 +#define STAT_ACTIVEWEAPON 10 +#define STAT_TOTALSECRETS 11 +#define STAT_TOTALMONSTERS 12 +#define STAT_SECRETS 13 // bumped on client side by svc_foundsecret +#define STAT_MONSTERS 14 // bumped by svc_killedmonster + +// stock defines + +#define IT_SHOTGUN 1 +#define IT_SUPER_SHOTGUN 2 +#define IT_NAILGUN 4 +#define IT_SUPER_NAILGUN 8 +#define IT_GRENADE_LAUNCHER 16 +#define IT_ROCKET_LAUNCHER 32 +#define IT_LIGHTNING 64 +#define IT_EXTRA_WEAPON 128 + +#define IT_SHELLS 256 +#define IT_NAILS 512 +#define IT_ROCKETS 1024 +#define IT_CELLS 2048 + +#define IT_AXE 4096 +#define IT_ARMOR1 8192 +#define IT_ARMOR2 16384 +#define IT_ARMOR3 32768 +#define IT_SUPERHEALTH 65536 +#define IT_KEY1 131072 +#define IT_KEY2 262144 +#define IT_INVISIBILITY 524288 +#define IT_INVULNERABILITY 1048576 +#define IT_SUIT 2097152 +#define IT_QUAD 4194304 +#define IT_SIGIL1 (1<<28) +#define IT_SIGIL2 (1<<29) +#define IT_SIGIL3 (1<<30) +#define IT_SIGIL4 (1<<31) + +//=========================================== +//kurok changed and added defines + +#define KIT_SHELLS 128 +#define KIT_NAILS 256 +#define KIT_ROCKETS 512 +#define KIT_CELLS 1024 +#define KIT_AXE 2048 +#define KIT_TEKBOW 4096 +#define KIT_UZI 8192 +#define KIT_M99 16384 +#define KIT_EXTRAW1 32768 +#define KIT_EXTRAW2 65536 +#define KIT_ARMOR1 8388608 +#define KIT_ARMOR2 16777216 +#define KIT_ARMOR3 33554432 +#define KIT_50CAL 67108864 +#define KIT_60CAL 134217728 +#define KIT_EXTRA1 268435456 +#define KIT_EXTRA2 536870912 +#define KIT_EXTRA3 1073741824 +#define KIT_SUPERHEALTH 2147483648 + +//=========================================== +//rogue changed and added defines + +#define RIT_SHELLS 128 +#define RIT_NAILS 256 +#define RIT_ROCKETS 512 +#define RIT_CELLS 1024 +#define RIT_AXE 2048 +#define RIT_LAVA_NAILGUN 4096 +#define RIT_LAVA_SUPER_NAILGUN 8192 +#define RIT_MULTI_GRENADE 16384 +#define RIT_MULTI_ROCKET 32768 +#define RIT_PLASMA_GUN 65536 +#define RIT_ARMOR1 8388608 +#define RIT_ARMOR2 16777216 +#define RIT_ARMOR3 33554432 +#define RIT_LAVA_NAILS 67108864 +#define RIT_PLASMA_AMMO 134217728 +#define RIT_MULTI_ROCKETS 268435456 +#define RIT_SHIELD 536870912 +#define RIT_ANTIGRAV 1073741824 +#define RIT_SUPERHEALTH 2147483648 + +//MED 01/04/97 added hipnotic defines +//=========================================== +//hipnotic added defines +#define HIT_PROXIMITY_GUN_BIT 16 +#define HIT_MJOLNIR_BIT 7 +#define HIT_LASER_CANNON_BIT 23 +#define HIT_PROXIMITY_GUN (1<v[1] >= pfv1->v[1]) + { + scale = (ALIAS_Z_CLIP_PLANE - pav0->fv[2]) / + (pav1->fv[2] - pav0->fv[2]); + + avout.fv[0] = pav0->fv[0] + (pav1->fv[0] - pav0->fv[0]) * scale; + avout.fv[1] = pav0->fv[1] + (pav1->fv[1] - pav0->fv[1]) * scale; + avout.fv[2] = ALIAS_Z_CLIP_PLANE; + + out->v[2] = pfv0->v[2] + (pfv1->v[2] - pfv0->v[2]) * scale; + out->v[3] = pfv0->v[3] + (pfv1->v[3] - pfv0->v[3]) * scale; + out->v[4] = pfv0->v[4] + (pfv1->v[4] - pfv0->v[4]) * scale; + } + else + { + scale = (ALIAS_Z_CLIP_PLANE - pav1->fv[2]) / + (pav0->fv[2] - pav1->fv[2]); + + avout.fv[0] = pav1->fv[0] + (pav0->fv[0] - pav1->fv[0]) * scale; + avout.fv[1] = pav1->fv[1] + (pav0->fv[1] - pav1->fv[1]) * scale; + avout.fv[2] = ALIAS_Z_CLIP_PLANE; + + out->v[2] = pfv1->v[2] + (pfv0->v[2] - pfv1->v[2]) * scale; + out->v[3] = pfv1->v[3] + (pfv0->v[3] - pfv1->v[3]) * scale; + out->v[4] = pfv1->v[4] + (pfv0->v[4] - pfv1->v[4]) * scale; + } + + R_AliasProjectFinalVert (out, &avout); + + if (out->v[0] < r_refdef.aliasvrect.x) + out->flags |= ALIAS_LEFT_CLIP; + if (out->v[1] < r_refdef.aliasvrect.y) + out->flags |= ALIAS_TOP_CLIP; + if (out->v[0] > r_refdef.aliasvrectright) + out->flags |= ALIAS_RIGHT_CLIP; + if (out->v[1] > r_refdef.aliasvrectbottom) + out->flags |= ALIAS_BOTTOM_CLIP; +} + + +#if !id386 + +void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) +{ + float scale; + int i; + + if (pfv0->v[1] >= pfv1->v[1]) + { + scale = (float)(r_refdef.aliasvrect.x - pfv0->v[0]) / + (pfv1->v[0] - pfv0->v[0]); + for (i=0 ; i<6 ; i++) + out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5; + } + else + { + scale = (float)(r_refdef.aliasvrect.x - pfv1->v[0]) / + (pfv0->v[0] - pfv1->v[0]); + for (i=0 ; i<6 ; i++) + out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5; + } +} + + +void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1, + finalvert_t *out) +{ + float scale; + int i; + + if (pfv0->v[1] >= pfv1->v[1]) + { + scale = (float)(r_refdef.aliasvrectright - pfv0->v[0]) / + (pfv1->v[0] - pfv0->v[0]); + for (i=0 ; i<6 ; i++) + out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5; + } + else + { + scale = (float)(r_refdef.aliasvrectright - pfv1->v[0]) / + (pfv0->v[0] - pfv1->v[0]); + for (i=0 ; i<6 ; i++) + out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5; + } +} + + +void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) +{ + float scale; + int i; + + if (pfv0->v[1] >= pfv1->v[1]) + { + scale = (float)(r_refdef.aliasvrect.y - pfv0->v[1]) / + (pfv1->v[1] - pfv0->v[1]); + for (i=0 ; i<6 ; i++) + out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5; + } + else + { + scale = (float)(r_refdef.aliasvrect.y - pfv1->v[1]) / + (pfv0->v[1] - pfv1->v[1]); + for (i=0 ; i<6 ; i++) + out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5; + } +} + + +void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1, + finalvert_t *out) +{ + float scale; + int i; + + if (pfv0->v[1] >= pfv1->v[1]) + { + scale = (float)(r_refdef.aliasvrectbottom - pfv0->v[1]) / + (pfv1->v[1] - pfv0->v[1]); + + for (i=0 ; i<6 ; i++) + out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5; + } + else + { + scale = (float)(r_refdef.aliasvrectbottom - pfv1->v[1]) / + (pfv0->v[1] - pfv1->v[1]); + + for (i=0 ; i<6 ; i++) + out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5; + } +} + +#endif + + +int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count, + void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) ) +{ + int i,j,k; + int flags, oldflags; + + j = count-1; + k = 0; + for (i=0 ; i r_refdef.aliasvrectright) + out[k].flags |= ALIAS_RIGHT_CLIP; + if (out[k].v[1] > r_refdef.aliasvrectbottom) + out[k].flags |= ALIAS_BOTTOM_CLIP; + k++; + } + if (!flags) + { + out[k] = in[i]; + k++; + } + } + + return k; +} + + +/* +================ +R_AliasClipTriangle +================ +*/ +void R_AliasClipTriangle (mtriangle_t *ptri) +{ + int i, k, pingpong; + mtriangle_t mtri; + unsigned clipflags; + +// copy vertexes and fix seam texture coordinates + if (ptri->facesfront) + { + fv[0][0] = pfinalverts[ptri->vertindex[0]]; + fv[0][1] = pfinalverts[ptri->vertindex[1]]; + fv[0][2] = pfinalverts[ptri->vertindex[2]]; + } + else + { + for (i=0 ; i<3 ; i++) + { + fv[0][i] = pfinalverts[ptri->vertindex[i]]; + + if (!ptri->facesfront && (fv[0][i].flags & ALIAS_ONSEAM) ) + fv[0][i].v[2] += r_affinetridesc.seamfixupX16; + } + } + +// clip + clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags; + + if (clipflags & ALIAS_Z_CLIP) + { + for (i=0 ; i<3 ; i++) + av[i] = pauxverts[ptri->vertindex[i]]; + + k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z); + if (k == 0) + return; + + pingpong = 1; + clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags; + } + else + { + pingpong = 0; + k = 3; + } + + if (clipflags & ALIAS_LEFT_CLIP) + { + k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], + ALIAS_LEFT_CLIP, k, R_Alias_clip_left); + if (k == 0) + return; + + pingpong ^= 1; + } + + if (clipflags & ALIAS_RIGHT_CLIP) + { + k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], + ALIAS_RIGHT_CLIP, k, R_Alias_clip_right); + if (k == 0) + return; + + pingpong ^= 1; + } + + if (clipflags & ALIAS_BOTTOM_CLIP) + { + k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], + ALIAS_BOTTOM_CLIP, k, R_Alias_clip_bottom); + if (k == 0) + return; + + pingpong ^= 1; + } + + if (clipflags & ALIAS_TOP_CLIP) + { + k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], + ALIAS_TOP_CLIP, k, R_Alias_clip_top); + if (k == 0) + return; + + pingpong ^= 1; + } + + for (i=0 ; i r_refdef.aliasvrectright) + fv[pingpong][i].v[0] = r_refdef.aliasvrectright; + + if (fv[pingpong][i].v[1] < r_refdef.aliasvrect.y) + fv[pingpong][i].v[1] = r_refdef.aliasvrect.y; + else if (fv[pingpong][i].v[1] > r_refdef.aliasvrectbottom) + fv[pingpong][i].v[1] = r_refdef.aliasvrectbottom; + + fv[pingpong][i].flags = 0; + } + +// draw triangles + mtri.facesfront = ptri->facesfront; + r_affinetridesc.ptriangles = &mtri; + r_affinetridesc.pfinalverts = fv[pingpong]; + +// FIXME: do all at once as trifan? + mtri.vertindex[0] = 0; + for (i=1 ; itrivial_accept = 0; + pmodel = currententity->model; + pahdr = Mod_Extradata (pmodel); + pmdl = (mdl_t *)((byte *)pahdr + pahdr->model); + + R_AliasSetUpTransform (0); + +// construct the base bounding box for this frame + frame = currententity->frame; +// TODO: don't repeat this check when drawing? + if ((frame >= pmdl->numframes) || (frame < 0)) + { + Con_DPrintf ("No such frame %d %s\n", frame, + pmodel->name); + frame = 0; + } + + pframedesc = &pahdr->frames[frame]; + +// x worldspace coordinates + basepts[0][0] = basepts[1][0] = basepts[2][0] = basepts[3][0] = + (float)pframedesc->bboxmin.v[0]; + basepts[4][0] = basepts[5][0] = basepts[6][0] = basepts[7][0] = + (float)pframedesc->bboxmax.v[0]; + +// y worldspace coordinates + basepts[0][1] = basepts[3][1] = basepts[5][1] = basepts[6][1] = + (float)pframedesc->bboxmin.v[1]; + basepts[1][1] = basepts[2][1] = basepts[4][1] = basepts[7][1] = + (float)pframedesc->bboxmax.v[1]; + +// z worldspace coordinates + basepts[0][2] = basepts[1][2] = basepts[4][2] = basepts[5][2] = + (float)pframedesc->bboxmin.v[2]; + basepts[2][2] = basepts[3][2] = basepts[6][2] = basepts[7][2] = + (float)pframedesc->bboxmax.v[2]; + + zclipped = false; + zfullyclipped = true; + + minz = 9999; + for (i=0; i<8 ; i++) + { + R_AliasTransformVector (&basepts[i][0], &viewaux[i].fv[0]); + + if (viewaux[i].fv[2] < ALIAS_Z_CLIP_PLANE) + { + // we must clip points that are closer than the near clip plane + viewpts[i].flags = ALIAS_Z_CLIP; + zclipped = true; + } + else + { + if (viewaux[i].fv[2] < minz) + minz = viewaux[i].fv[2]; + viewpts[i].flags = 0; + zfullyclipped = false; + } + } + + + if (zfullyclipped) + { + return false; // everything was near-z-clipped + } + + numv = 8; + + if (zclipped) + { + // organize points by edges, use edges to get new points (possible trivial + // reject) + for (i=0 ; i<12 ; i++) + { + // edge endpoints + pv0 = &viewpts[aedges[i].index0]; + pv1 = &viewpts[aedges[i].index1]; + pa0 = &viewaux[aedges[i].index0]; + pa1 = &viewaux[aedges[i].index1]; + + // if one end is clipped and the other isn't, make a new point + if (pv0->flags ^ pv1->flags) + { + frac = (ALIAS_Z_CLIP_PLANE - pa0->fv[2]) / + (pa1->fv[2] - pa0->fv[2]); + viewaux[numv].fv[0] = pa0->fv[0] + + (pa1->fv[0] - pa0->fv[0]) * frac; + viewaux[numv].fv[1] = pa0->fv[1] + + (pa1->fv[1] - pa0->fv[1]) * frac; + viewaux[numv].fv[2] = ALIAS_Z_CLIP_PLANE; + viewpts[numv].flags = 0; + numv++; + } + } + } + +// project the vertices that remain after clipping + anyclip = 0; + allclip = ALIAS_XY_CLIP_MASK; + +// TODO: probably should do this loop in ASM, especially if we use floats + for (i=0 ; i r_refdef.fvrectright) + flags |= ALIAS_RIGHT_CLIP; + if (v1 > r_refdef.fvrectbottom) + flags |= ALIAS_BOTTOM_CLIP; + + anyclip |= flags; + allclip &= flags; + } + + if (allclip) + return false; // trivial reject off one side + + currententity->trivial_accept = !anyclip & !zclipped; + + if (currententity->trivial_accept) + { + if (minz > (r_aliastransition + (pmdl->size * r_resfudge))) + { + currententity->trivial_accept |= 2; + } + } + + return true; +} + + +/* +================ +R_AliasTransformVector +================ +*/ +void R_AliasTransformVector (vec3_t in, vec3_t out) +{ + out[0] = DotProduct(in, aliastransform[0]) + aliastransform[0][3]; + out[1] = DotProduct(in, aliastransform[1]) + aliastransform[1][3]; + out[2] = DotProduct(in, aliastransform[2]) + aliastransform[2][3]; +} + + +/* +================ +R_AliasPreparePoints + +General clipped case +================ +*/ +void R_AliasPreparePoints (void) +{ + int i; + stvert_t *pstverts; + finalvert_t *fv; + auxvert_t *av; + mtriangle_t *ptri; + finalvert_t *pfv[3]; + + pstverts = (stvert_t *)((byte *)paliashdr + paliashdr->stverts); + r_anumverts = pmdl->numverts; + fv = pfinalverts; + av = pauxverts; + + for (i=0 ; ifv[2] < ALIAS_Z_CLIP_PLANE) + fv->flags |= ALIAS_Z_CLIP; + else + { + R_AliasProjectFinalVert (fv, av); + + if (fv->v[0] < r_refdef.aliasvrect.x) + fv->flags |= ALIAS_LEFT_CLIP; + if (fv->v[1] < r_refdef.aliasvrect.y) + fv->flags |= ALIAS_TOP_CLIP; + if (fv->v[0] > r_refdef.aliasvrectright) + fv->flags |= ALIAS_RIGHT_CLIP; + if (fv->v[1] > r_refdef.aliasvrectbottom) + fv->flags |= ALIAS_BOTTOM_CLIP; + } + } + +// +// clip and draw all triangles +// + r_affinetridesc.numtriangles = 1; + + ptri = (mtriangle_t *)((byte *)paliashdr + paliashdr->triangles); + for (i=0 ; inumtris ; i++, ptri++) + { + pfv[0] = &pfinalverts[ptri->vertindex[0]]; + pfv[1] = &pfinalverts[ptri->vertindex[1]]; + pfv[2] = &pfinalverts[ptri->vertindex[2]]; + + if ( pfv[0]->flags & pfv[1]->flags & pfv[2]->flags & (ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP) ) + continue; // completely clipped + + if ( ! ( (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) & + (ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP) ) ) + { // totally unclipped + r_affinetridesc.pfinalverts = pfinalverts; + r_affinetridesc.ptriangles = ptri; + D_PolysetDraw (); + } + else + { // partially clipped + R_AliasClipTriangle (ptri); + } + } +} + + +/* +================ +R_AliasSetUpTransform +================ +*/ +void R_AliasSetUpTransform (int trivial_accept) +{ + int i; + float rotationmatrix[3][4], t2matrix[3][4]; + static float tmatrix[3][4]; + static float viewmatrix[3][4]; + vec3_t angles; + +// TODO: should really be stored with the entity instead of being reconstructed +// TODO: should use a look-up table +// TODO: could cache lazily, stored in the entity + + angles[ROLL] = currententity->angles[ROLL]; + angles[PITCH] = -currententity->angles[PITCH]; + angles[YAW] = currententity->angles[YAW]; + AngleVectors (angles, alias_forward, alias_right, alias_up); + + tmatrix[0][0] = pmdl->scale[0]; + tmatrix[1][1] = pmdl->scale[1]; + tmatrix[2][2] = pmdl->scale[2]; + + tmatrix[0][3] = pmdl->scale_origin[0]; + tmatrix[1][3] = pmdl->scale_origin[1]; + tmatrix[2][3] = pmdl->scale_origin[2]; + +// TODO: can do this with simple matrix rearrangement + + for (i=0 ; i<3 ; i++) + { + t2matrix[i][0] = alias_forward[i]; + t2matrix[i][1] = -alias_right[i]; + t2matrix[i][2] = alias_up[i]; + } + + t2matrix[0][3] = -modelorg[0]; + t2matrix[1][3] = -modelorg[1]; + t2matrix[2][3] = -modelorg[2]; + +// FIXME: can do more efficiently than full concatenation + R_ConcatTransforms (t2matrix, tmatrix, rotationmatrix); + +// TODO: should be global, set when vright, etc., set + VectorCopy (vright, viewmatrix[0]); + VectorCopy (vup, viewmatrix[1]); + VectorInverse (viewmatrix[1]); + VectorCopy (vpn, viewmatrix[2]); + +// viewmatrix[0][3] = 0; +// viewmatrix[1][3] = 0; +// viewmatrix[2][3] = 0; + + R_ConcatTransforms (viewmatrix, rotationmatrix, aliastransform); + +// do the scaling up of x and y to screen coordinates as part of the transform +// for the unclipped case (it would mess up clipping in the clipped case). +// Also scale down z, so 1/z is scaled 31 bits for free, and scale down x and y +// correspondingly so the projected x and y come out right +// FIXME: make this work for clipped case too? + if (trivial_accept) + { + for (i=0 ; i<4 ; i++) + { + aliastransform[0][i] *= aliasxscale * + (1.0 / ((float)0x8000 * 0x10000)); + aliastransform[1][i] *= aliasyscale * + (1.0 / ((float)0x8000 * 0x10000)); + aliastransform[2][i] *= 1.0 / ((float)0x8000 * 0x10000); + + } + } +} + + +/* +================ +R_AliasTransformFinalVert +================ +*/ +void R_AliasTransformFinalVert (finalvert_t *fv, auxvert_t *av, + trivertx_t *pverts, stvert_t *pstverts) +{ + int temp; + float lightcos, *plightnormal; + + av->fv[0] = DotProduct(pverts->v, aliastransform[0]) + + aliastransform[0][3]; + av->fv[1] = DotProduct(pverts->v, aliastransform[1]) + + aliastransform[1][3]; + av->fv[2] = DotProduct(pverts->v, aliastransform[2]) + + aliastransform[2][3]; + + fv->v[2] = pstverts->s; + fv->v[3] = pstverts->t; + + fv->flags = pstverts->onseam; + +// lighting + plightnormal = r_avertexnormals[pverts->lightnormalindex]; + lightcos = DotProduct (plightnormal, r_plightvec); + temp = r_ambientlight; + + if (lightcos < 0) + { + temp += (int)(r_shadelight * lightcos); + + // clamp; because we limited the minimum ambient and shading light, we + // don't have to clamp low light, just bright + if (temp < 0) + temp = 0; + } + + fv->v[4] = temp; +} + + +#if !id386 + +/* +================ +R_AliasTransformAndProjectFinalVerts +================ +*/ +void R_AliasTransformAndProjectFinalVerts (finalvert_t *fv, stvert_t *pstverts) +{ + int i, temp; + float lightcos, *plightnormal, zi; + trivertx_t *pverts; + + pverts = r_apverts; + + for (i=0 ; iv, aliastransform[2]) + + aliastransform[2][3]); + + // x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is + // scaled up by 1/2**31, and the scaling cancels out for x and y in the + // projection + fv->v[5] = zi; + + fv->v[0] = ((DotProduct(pverts->v, aliastransform[0]) + + aliastransform[0][3]) * zi) + aliasxcenter; + fv->v[1] = ((DotProduct(pverts->v, aliastransform[1]) + + aliastransform[1][3]) * zi) + aliasycenter; + + fv->v[2] = pstverts->s; + fv->v[3] = pstverts->t; + fv->flags = pstverts->onseam; + + // lighting + plightnormal = r_avertexnormals[pverts->lightnormalindex]; + lightcos = DotProduct (plightnormal, r_plightvec); + temp = r_ambientlight; + + if (lightcos < 0) + { + temp += (int)(r_shadelight * lightcos); + + // clamp; because we limited the minimum ambient and shading light, we + // don't have to clamp low light, just bright + if (temp < 0) + temp = 0; + } + + fv->v[4] = temp; + } +} + +#endif + + +/* +================ +R_AliasProjectFinalVert +================ +*/ +void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av) +{ + float zi; + +// project points + zi = 1.0 / av->fv[2]; + + fv->v[5] = zi * ziscale; + + fv->v[0] = (av->fv[0] * aliasxscale * zi) + aliasxcenter; + fv->v[1] = (av->fv[1] * aliasyscale * zi) + aliasycenter; +} + + +/* +================ +R_AliasPrepareUnclippedPoints +================ +*/ +void R_AliasPrepareUnclippedPoints (void) +{ + stvert_t *pstverts; + finalvert_t *fv; + + pstverts = (stvert_t *)((byte *)paliashdr + paliashdr->stverts); + r_anumverts = pmdl->numverts; +// FIXME: just use pfinalverts directly? + fv = pfinalverts; + + R_AliasTransformAndProjectFinalVerts (fv, pstverts); + + if (r_affinetridesc.drawtype) + D_PolysetDrawFinalVerts (fv, r_anumverts); + + r_affinetridesc.pfinalverts = pfinalverts; + r_affinetridesc.ptriangles = (mtriangle_t *) + ((byte *)paliashdr + paliashdr->triangles); + r_affinetridesc.numtriangles = pmdl->numtris; + + D_PolysetDraw (); +} + +/* +=============== +R_AliasSetupSkin +=============== +*/ +void R_AliasSetupSkin (void) +{ + int skinnum; + int i, numskins; + maliasskingroup_t *paliasskingroup; + float *pskinintervals, fullskininterval; + float skintargettime, skintime; + + skinnum = currententity->skinnum; + if ((skinnum >= pmdl->numskins) || (skinnum < 0)) + { + Con_DPrintf ("R_AliasSetupSkin: no such skin # %d\n", skinnum); + skinnum = 0; + } + + pskindesc = ((maliasskindesc_t *) + ((byte *)paliashdr + paliashdr->skindesc)) + skinnum; + a_skinwidth = pmdl->skinwidth; + + if (pskindesc->type == ALIAS_SKIN_GROUP) + { + paliasskingroup = (maliasskingroup_t *)((byte *)paliashdr + + pskindesc->skin); + pskinintervals = (float *) + ((byte *)paliashdr + paliasskingroup->intervals); + numskins = paliasskingroup->numskins; + fullskininterval = pskinintervals[numskins-1]; + + skintime = cl.time + currententity->syncbase; + + // when loading in Mod_LoadAliasSkinGroup, we guaranteed all interval + // values are positive, so we don't have to worry about division by 0 + skintargettime = skintime - + ((int)(skintime / fullskininterval)) * fullskininterval; + + for (i=0 ; i<(numskins-1) ; i++) + { + if (pskinintervals[i] > skintargettime) + break; + } + + pskindesc = &paliasskingroup->skindescs[i]; + } + + r_affinetridesc.pskindesc = pskindesc; + r_affinetridesc.pskin = (void *)((byte *)paliashdr + pskindesc->skin); + r_affinetridesc.skinwidth = a_skinwidth; + r_affinetridesc.seamfixupX16 = (a_skinwidth >> 1) << 16; + r_affinetridesc.skinheight = pmdl->skinheight; +} + +/* +================ +R_AliasSetupLighting +================ +*/ +void R_AliasSetupLighting (alight_t *plighting) +{ + +// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have +// to clamp off the bottom + r_ambientlight = plighting->ambientlight; + + if (r_ambientlight < LIGHT_MIN) + r_ambientlight = LIGHT_MIN; + + r_ambientlight = (255 - r_ambientlight) << VID_CBITS; + + if (r_ambientlight < LIGHT_MIN) + r_ambientlight = LIGHT_MIN; + + r_shadelight = plighting->shadelight; + + if (r_shadelight < 0) + r_shadelight = 0; + + r_shadelight *= VID_GRADES; + +// rotate the lighting vector into the model's frame of reference + r_plightvec[0] = DotProduct (plighting->plightvec, alias_forward); + r_plightvec[1] = -DotProduct (plighting->plightvec, alias_right); + r_plightvec[2] = DotProduct (plighting->plightvec, alias_up); +} + +/* +================= +R_AliasSetupFrame + +set r_apverts +================= +*/ +void R_AliasSetupFrame (void) +{ + int frame; + int i, numframes; + maliasgroup_t *paliasgroup; + float *pintervals, fullinterval, targettime, time; + + frame = currententity->frame; + if ((frame >= pmdl->numframes) || (frame < 0)) + { + Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame); + frame = 0; + } + + if (paliashdr->frames[frame].type == ALIAS_SINGLE) + { + r_apverts = (trivertx_t *) + ((byte *)paliashdr + paliashdr->frames[frame].frame); + return; + } + + paliasgroup = (maliasgroup_t *) + ((byte *)paliashdr + paliashdr->frames[frame].frame); + pintervals = (float *)((byte *)paliashdr + paliasgroup->intervals); + numframes = paliasgroup->numframes; + fullinterval = pintervals[numframes-1]; + + time = cl.time + currententity->syncbase; + +// +// when loading in Mod_LoadAliasGroup, we guaranteed all interval values +// are positive, so we don't have to worry about division by 0 +// + targettime = time - ((int)(time / fullinterval)) * fullinterval; + + for (i=0 ; i<(numframes-1) ; i++) + { + if (pintervals[i] > targettime) + break; + } + + r_apverts = (trivertx_t *) + ((byte *)paliashdr + paliasgroup->frames[i].frame); +} + + +/* +================ +R_AliasDrawModel +================ +*/ +void R_AliasDrawModel (alight_t *plighting) +{ + finalvert_t finalverts[MAXALIASVERTS + + ((CACHE_SIZE - 1) / sizeof(finalvert_t)) + 1]; + auxvert_t auxverts[MAXALIASVERTS]; + + r_amodels_drawn++; + +// cache align + pfinalverts = (finalvert_t *) + (((long)&finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + pauxverts = &auxverts[0]; + + paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model); + pmdl = (mdl_t *)((byte *)paliashdr + paliashdr->model); + + R_AliasSetupSkin (); + R_AliasSetUpTransform (currententity->trivial_accept); + R_AliasSetupLighting (plighting); + R_AliasSetupFrame (); + + if (!currententity->colormap) + Sys_Error ("R_AliasDrawModel: !currententity->colormap"); + + r_affinetridesc.drawtype = (currententity->trivial_accept == 3) && + r_recursiveaffinetriangles; + + if (r_affinetridesc.drawtype) + { + D_PolysetUpdateTables (); // FIXME: precalc... + } + else + { +#if id386 + D_Aff8Patch (currententity->colormap); +#endif + } + + acolormap = currententity->colormap; + + if (currententity != &cl.viewent) + ziscale = (float)0x8000 * (float)0x10000; + else + ziscale = (float)0x8000 * (float)0x10000 * 3.0; + + if (currententity->trivial_accept) + R_AliasPrepareUnclippedPoints (); + else + R_AliasPreparePoints (); +} + diff --git a/r17/Revamped src/revamped_src/r_bsp.c b/r17/Revamped src/revamped_src/r_bsp.c new file mode 100755 index 00000000..667efb1a --- /dev/null +++ b/r17/Revamped src/revamped_src/r_bsp.c @@ -0,0 +1,674 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// r_bsp.c + +#include "quakedef.h" +#include "r_local.h" + +// +// current entity info +// +qboolean insubmodel; +entity_t *currententity; +vec3_t modelorg, base_modelorg; + // modelorg is the viewpoint reletive to + // the currently rendering entity +vec3_t r_entorigin; // the currently rendering entity in world + // coordinates + +float entity_rotation[3][3]; + +vec3_t r_worldmodelorg; + +int r_currentbkey; + +typedef enum {touchessolid, drawnode, nodrawnode} solidstate_t; + +#define MAX_BMODEL_VERTS 500 // 6K +#define MAX_BMODEL_EDGES 1000 // 12K + +static mvertex_t *pbverts; +static bedge_t *pbedges; +static int numbverts, numbedges; + +static mvertex_t *pfrontenter, *pfrontexit; + +static qboolean makeclippededge; + + +//=========================================================================== + +/* +================ +R_EntityRotate +================ +*/ +void R_EntityRotate (vec3_t vec) +{ + vec3_t tvec; + + VectorCopy (vec, tvec); + vec[0] = DotProduct (entity_rotation[0], tvec); + vec[1] = DotProduct (entity_rotation[1], tvec); + vec[2] = DotProduct (entity_rotation[2], tvec); +} + + +/* +================ +R_RotateBmodel +================ +*/ +void R_RotateBmodel (void) +{ + float angle, s, c, temp1[3][3], temp2[3][3], temp3[3][3]; + +// TODO: should use a look-up table +// TODO: should really be stored with the entity instead of being reconstructed +// TODO: could cache lazily, stored in the entity +// TODO: share work with R_SetUpAliasTransform + +// yaw + angle = currententity->angles[YAW]; + angle = angle * M_PI*2 / 360; + s = sinf(angle); + c = cosf(angle); + + temp1[0][0] = c; + temp1[0][1] = s; + temp1[0][2] = 0; + temp1[1][0] = -s; + temp1[1][1] = c; + temp1[1][2] = 0; + temp1[2][0] = 0; + temp1[2][1] = 0; + temp1[2][2] = 1; + + +// pitch + angle = currententity->angles[PITCH]; + angle = angle * M_PI*2 / 360; + s = sinf(angle); + c = cosf(angle); + + temp2[0][0] = c; + temp2[0][1] = 0; + temp2[0][2] = -s; + temp2[1][0] = 0; + temp2[1][1] = 1; + temp2[1][2] = 0; + temp2[2][0] = s; + temp2[2][1] = 0; + temp2[2][2] = c; + + R_ConcatRotations (temp2, temp1, temp3); + +// roll + angle = currententity->angles[ROLL]; + angle = angle * M_PI*2 / 360; + s = sinf(angle); + c = cosf(angle); + + temp1[0][0] = 1; + temp1[0][1] = 0; + temp1[0][2] = 0; + temp1[1][0] = 0; + temp1[1][1] = c; + temp1[1][2] = s; + temp1[2][0] = 0; + temp1[2][1] = -s; + temp1[2][2] = c; + + R_ConcatRotations (temp1, temp3, entity_rotation); + +// +// rotate modelorg and the transformation matrix +// + R_EntityRotate (modelorg); + R_EntityRotate (vpn); + R_EntityRotate (vright); + R_EntityRotate (vup); + + R_TransformFrustum (); +} + + +/* +================ +R_RecursiveClipBPoly +================ +*/ +void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf) +{ + bedge_t *psideedges[2], *pnextedge, *ptedge; + int i, side, lastside; + float dist, frac, lastdist; + mplane_t *splitplane, tplane; + mvertex_t *pvert, *plastvert, *ptvert; + mnode_t *pn; + + psideedges[0] = psideedges[1] = NULL; + + makeclippededge = false; + +// transform the BSP plane into model space +// FIXME: cache these? + splitplane = pnode->plane; + tplane.dist = splitplane->dist - + DotProduct(r_entorigin, splitplane->normal); + tplane.normal[0] = DotProduct (entity_rotation[0], splitplane->normal); + tplane.normal[1] = DotProduct (entity_rotation[1], splitplane->normal); + tplane.normal[2] = DotProduct (entity_rotation[2], splitplane->normal); + +// clip edges to BSP plane + for ( ; pedges ; pedges = pnextedge) + { + pnextedge = pedges->pnext; + + // set the status for the last point as the previous point + // FIXME: cache this stuff somehow? + plastvert = pedges->v[0]; + lastdist = DotProduct (plastvert->position, tplane.normal) - + tplane.dist; + + if (lastdist > 0) + lastside = 0; + else + lastside = 1; + + pvert = pedges->v[1]; + + dist = DotProduct (pvert->position, tplane.normal) - tplane.dist; + + if (dist > 0) + side = 0; + else + side = 1; + + if (side != lastside) + { + // clipped + if (numbverts >= MAX_BMODEL_VERTS) + return; + + // generate the clipped vertex + frac = lastdist / (lastdist - dist); + ptvert = &pbverts[numbverts++]; + ptvert->position[0] = plastvert->position[0] + + frac * (pvert->position[0] - + plastvert->position[0]); + ptvert->position[1] = plastvert->position[1] + + frac * (pvert->position[1] - + plastvert->position[1]); + ptvert->position[2] = plastvert->position[2] + + frac * (pvert->position[2] - + plastvert->position[2]); + + // split into two edges, one on each side, and remember entering + // and exiting points + // FIXME: share the clip edge by having a winding direction flag? + if (numbedges >= (MAX_BMODEL_EDGES - 1)) + { + Con_Printf ("Out of edges for bmodel\n"); + return; + } + + ptedge = &pbedges[numbedges]; + ptedge->pnext = psideedges[lastside]; + psideedges[lastside] = ptedge; + ptedge->v[0] = plastvert; + ptedge->v[1] = ptvert; + + ptedge = &pbedges[numbedges + 1]; + ptedge->pnext = psideedges[side]; + psideedges[side] = ptedge; + ptedge->v[0] = ptvert; + ptedge->v[1] = pvert; + + numbedges += 2; + + if (side == 0) + { + // entering for front, exiting for back + pfrontenter = ptvert; + makeclippededge = true; + } + else + { + pfrontexit = ptvert; + makeclippededge = true; + } + } + else + { + // add the edge to the appropriate side + pedges->pnext = psideedges[side]; + psideedges[side] = pedges; + } + } + +// if anything was clipped, reconstitute and add the edges along the clip +// plane to both sides (but in opposite directions) + if (makeclippededge) + { + if (numbedges >= (MAX_BMODEL_EDGES - 2)) + { + Con_Printf ("Out of edges for bmodel\n"); + return; + } + + ptedge = &pbedges[numbedges]; + ptedge->pnext = psideedges[0]; + psideedges[0] = ptedge; + ptedge->v[0] = pfrontexit; + ptedge->v[1] = pfrontenter; + + ptedge = &pbedges[numbedges + 1]; + ptedge->pnext = psideedges[1]; + psideedges[1] = ptedge; + ptedge->v[0] = pfrontenter; + ptedge->v[1] = pfrontexit; + + numbedges += 2; + } + +// draw or recurse further + for (i=0 ; i<2 ; i++) + { + if (psideedges[i]) + { + // draw if we've reached a non-solid leaf, done if all that's left is a + // solid leaf, and continue down the tree if it's not a leaf + pn = pnode->children[i]; + + // we're done with this branch if the node or leaf isn't in the PVS + if (pn->visframe == r_visframecount) + { + if (pn->contents < 0) + { + if (pn->contents != CONTENTS_SOLID) + { + r_currentbkey = ((mleaf_t *)pn)->key; + R_RenderBmodelFace (psideedges[i], psurf); + } + } + else + { + R_RecursiveClipBPoly (psideedges[i], pnode->children[i], + psurf); + } + } + } + } +} + + +/* +================ +R_DrawSolidClippedSubmodelPolygons +================ +*/ +void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel) +{ + int i, j, lindex; + vec_t dot; + msurface_t *psurf; + int numsurfaces; + mplane_t *pplane; + mvertex_t bverts[MAX_BMODEL_VERTS]; + bedge_t bedges[MAX_BMODEL_EDGES], *pbedge; + medge_t *pedge, *pedges; + +// FIXME: use bounding-box-based frustum clipping info? + + psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; + numsurfaces = pmodel->nummodelsurfaces; + pedges = pmodel->edges; + + for (i=0 ; iplane; + + dot = DotProduct (modelorg, pplane->normal) - pplane->dist; + + // draw the polygon + if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || + (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) + { + // FIXME: use bounding-box-based frustum clipping info? + + // copy the edges to bedges, flipping if necessary so always + // clockwise winding + // FIXME: if edges and vertices get caches, these assignments must move + // outside the loop, and overflow checking must be done here + pbverts = bverts; + pbedges = bedges; + numbverts = numbedges = 0; + + if (psurf->numedges > 0) + { + pbedge = &bedges[numbedges]; + numbedges += psurf->numedges; + + for (j=0 ; jnumedges ; j++) + { + lindex = pmodel->surfedges[psurf->firstedge+j]; + + if (lindex > 0) + { + pedge = &pedges[lindex]; + pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[0]]; + pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[1]]; + } + else + { + lindex = -lindex; + pedge = &pedges[lindex]; + pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[1]]; + pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[0]]; + } + + pbedge[j].pnext = &pbedge[j+1]; + } + + pbedge[j-1].pnext = NULL; // mark end of edges + + R_RecursiveClipBPoly (pbedge, currententity->topnode, psurf); + } + else + { + Sys_Error ("no edges in bmodel"); + } + } + } +} + + +/* +================ +R_DrawSubmodelPolygons +================ +*/ +void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags) +{ + int i; + vec_t dot; + msurface_t *psurf; + int numsurfaces; + mplane_t *pplane; + +// FIXME: use bounding-box-based frustum clipping info? + + psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; + numsurfaces = pmodel->nummodelsurfaces; + + for (i=0 ; iplane; + + dot = DotProduct (modelorg, pplane->normal) - pplane->dist; + + // draw the polygon + if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || + (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) + { + r_currentkey = ((mleaf_t *)currententity->topnode)->key; + + // FIXME: use bounding-box-based frustum clipping info? + R_RenderFace (psurf, clipflags); + } + } +} + + +/* +================ +R_RecursiveWorldNode +================ +*/ +void R_RecursiveWorldNode (mnode_t *node, int clipflags) +{ + int i, c, side, *pindex; + vec3_t acceptpt, rejectpt; + mplane_t *plane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + float d, dot; + + if (node->contents == CONTENTS_SOLID) + return; // solid + + if (node->visframe != r_visframecount) + return; + +// cull the clipping planes if not trivial accept +// FIXME: the compiler is doing a lousy job of optimizing here; it could be +// twice as fast in ASM + if (clipflags) + { + for (i=0 ; i<4 ; i++) + { + if (! (clipflags & (1<minmaxs[pindex[0]]; + rejectpt[1] = (float)node->minmaxs[pindex[1]]; + rejectpt[2] = (float)node->minmaxs[pindex[2]]; + + d = DotProduct (rejectpt, view_clipplanes[i].normal); + d -= view_clipplanes[i].dist; + + if (d <= 0) + return; + + acceptpt[0] = (float)node->minmaxs[pindex[3+0]]; + acceptpt[1] = (float)node->minmaxs[pindex[3+1]]; + acceptpt[2] = (float)node->minmaxs[pindex[3+2]]; + + d = DotProduct (acceptpt, view_clipplanes[i].normal); + d -= view_clipplanes[i].dist; + + if (d >= 0) + clipflags &= ~(1<contents < 0) + { + pleaf = (mleaf_t *)node; + + mark = pleaf->firstmarksurface; + c = pleaf->nummarksurfaces; + + if (c) + { + do + { + (*mark)->visframe = r_framecount; + mark++; + } while (--c); + } + + // deal with model fragments in this leaf + if (pleaf->efrags) + { + R_StoreEfrags (&pleaf->efrags); + } + + pleaf->key = r_currentkey; + r_currentkey++; // all bmodels in a leaf share the same key + } + else + { + // node is just a decision point, so go down the apropriate sides + + // find which side of the node we are on + plane = node->plane; + + switch (plane->type) + { + case PLANE_X: + dot = modelorg[0] - plane->dist; + break; + case PLANE_Y: + dot = modelorg[1] - plane->dist; + break; + case PLANE_Z: + dot = modelorg[2] - plane->dist; + break; + default: + dot = DotProduct (modelorg, plane->normal) - plane->dist; + break; + } + + if (dot >= 0) + side = 0; + else + side = 1; + + // recurse down the children, front side first + R_RecursiveWorldNode (node->children[side], clipflags); + + // draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + if (dot < -BACKFACE_EPSILON) + { + do + { + if ((surf->flags & SURF_PLANEBACK) && + (surf->visframe == r_framecount)) + { + if (r_drawpolys) + { + if (r_worldpolysbacktofront) + { + if (numbtofpolys < MAX_BTOFPOLYS) + { + pbtofpolys[numbtofpolys].clipflags = + clipflags; + pbtofpolys[numbtofpolys].psurf = surf; + numbtofpolys++; + } + } + else + { + R_RenderPoly (surf, clipflags); + } + } + else + { + R_RenderFace (surf, clipflags); + } + } + + surf++; + } while (--c); + } + else if (dot > BACKFACE_EPSILON) + { + do + { + if (!(surf->flags & SURF_PLANEBACK) && + (surf->visframe == r_framecount)) + { + if (r_drawpolys) + { + if (r_worldpolysbacktofront) + { + if (numbtofpolys < MAX_BTOFPOLYS) + { + pbtofpolys[numbtofpolys].clipflags = + clipflags; + pbtofpolys[numbtofpolys].psurf = surf; + numbtofpolys++; + } + } + else + { + R_RenderPoly (surf, clipflags); + } + } + else + { + R_RenderFace (surf, clipflags); + } + } + + surf++; + } while (--c); + } + + // all surfaces on the same node share the same sequence number + r_currentkey++; + } + + // recurse down the back side + R_RecursiveWorldNode (node->children[!side], clipflags); + } +} + + + +/* +================ +R_RenderWorld +================ +*/ +void R_RenderWorld (void) +{ + int i; + model_t *clmodel; + btofpoly_t btofpolys[MAX_BTOFPOLYS]; + + pbtofpolys = btofpolys; + + currententity = &cl_entities[0]; + VectorCopy (r_origin, modelorg); + clmodel = currententity->model; + r_pcurrentvertbase = clmodel->vertexes; + + R_RecursiveWorldNode (clmodel->nodes, 15); + +// if the driver wants the polygons back to front, play the visible ones back +// in that order + if (r_worldpolysbacktofront) + { + for (i=numbtofpolys-1 ; i>=0 ; i--) + { + R_RenderPoly (btofpolys[i].psurf, btofpolys[i].clipflags); + } + } +} + + diff --git a/r17/Revamped src/revamped_src/r_draw.c b/r17/Revamped src/revamped_src/r_draw.c new file mode 100755 index 00000000..52a4fc99 --- /dev/null +++ b/r17/Revamped src/revamped_src/r_draw.c @@ -0,0 +1,908 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +// r_draw.c + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" // FIXME: shouldn't need to include this + +#define MAXLEFTCLIPEDGES 100 + +// !!! if these are changed, they must be changed in asm_draw.h too !!! +#define FULLY_CLIPPED_CACHED 0x80000000 +#define FRAMECOUNT_MASK 0x7FFFFFFF + +unsigned int cacheoffset; + +int c_faceclip; // number of faces clipped + +zpointdesc_t r_zpointdesc; + +polydesc_t r_polydesc; + + + +clipplane_t *entity_clipplanes; +clipplane_t view_clipplanes[4]; +clipplane_t world_clipplanes[16]; + +medge_t *r_pedge; + +qboolean r_leftclipped, r_rightclipped; +static qboolean makeleftedge, makerightedge; +qboolean r_nearzionly; + +int sintable[SIN_BUFFER_SIZE]; +int intsintable[SIN_BUFFER_SIZE]; + +mvertex_t r_leftenter, r_leftexit; +mvertex_t r_rightenter, r_rightexit; + +typedef struct +{ + float u,v; + int ceilv; +} evert_t; + +int r_emitted; +float r_nearzi; +float r_u1, r_v1, r_lzi1; +int r_ceilv1; + +qboolean r_lastvertvalid; + + +#if !id386 + +/* +================ +R_EmitEdge +================ +*/ +void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1) +{ + edge_t *edge, *pcheck; + int u_check; + float u, u_step; + vec3_t local, transformed; + float *world; + int v, v2, ceilv0; + float scale, lzi0, u0, v0; + int side; + + if (r_lastvertvalid) + { + u0 = r_u1; + v0 = r_v1; + lzi0 = r_lzi1; + ceilv0 = r_ceilv1; + } + else + { + world = &pv0->position[0]; + + // transform and project + VectorSubtract (world, modelorg, local); + TransformVector (local, transformed); + + if (transformed[2] < NEAR_CLIP) + transformed[2] = NEAR_CLIP; + + lzi0 = 1.0 / transformed[2]; + + // FIXME: build x/yscale into transform? + scale = xscale * lzi0; + u0 = (xcenter + scale*transformed[0]); + if (u0 < r_refdef.fvrectx_adj) + u0 = r_refdef.fvrectx_adj; + if (u0 > r_refdef.fvrectright_adj) + u0 = r_refdef.fvrectright_adj; + + scale = yscale * lzi0; + v0 = (ycenter - scale*transformed[1]); + if (v0 < r_refdef.fvrecty_adj) + v0 = r_refdef.fvrecty_adj; + if (v0 > r_refdef.fvrectbottom_adj) + v0 = r_refdef.fvrectbottom_adj; + + ceilv0 = (int) ceilf(v0); + } + + world = &pv1->position[0]; + +// transform and project + VectorSubtract (world, modelorg, local); + TransformVector (local, transformed); + + if (transformed[2] < NEAR_CLIP) + transformed[2] = NEAR_CLIP; + + r_lzi1 = 1.0 / transformed[2]; + + scale = xscale * r_lzi1; + r_u1 = (xcenter + scale*transformed[0]); + if (r_u1 < r_refdef.fvrectx_adj) + r_u1 = r_refdef.fvrectx_adj; + if (r_u1 > r_refdef.fvrectright_adj) + r_u1 = r_refdef.fvrectright_adj; + + scale = yscale * r_lzi1; + r_v1 = (ycenter - scale*transformed[1]); + if (r_v1 < r_refdef.fvrecty_adj) + r_v1 = r_refdef.fvrecty_adj; + if (r_v1 > r_refdef.fvrectbottom_adj) + r_v1 = r_refdef.fvrectbottom_adj; + + if (r_lzi1 > lzi0) + lzi0 = r_lzi1; + + if (lzi0 > r_nearzi) // for mipmap finding + r_nearzi = lzi0; + +// for right edges, all we want is the effect on 1/z + if (r_nearzionly) + return; + + r_emitted = 1; + + r_ceilv1 = (int) ceilf(r_v1); + + +// create the edge + if (ceilv0 == r_ceilv1) + { + // we cache unclipped horizontal edges as fully clipped + if (cacheoffset != 0x7FFFFFFF) + { + cacheoffset = FULLY_CLIPPED_CACHED | + (r_framecount & FRAMECOUNT_MASK); + } + + return; // horizontal edge + } + + side = ceilv0 > r_ceilv1; + + edge = edge_p++; + + edge->owner = r_pedge; + + edge->nearzi = lzi0; + + if (side == 0) + { + // trailing edge (go from p1 to p2) + v = ceilv0; + v2 = r_ceilv1 - 1; + + edge->surfs[0] = surface_p - surfaces; + edge->surfs[1] = 0; + + u_step = ((r_u1 - u0) / (r_v1 - v0)); + u = u0 + ((float)v - v0) * u_step; + } + else + { + // leading edge (go from p2 to p1) + v2 = ceilv0 - 1; + v = r_ceilv1; + + edge->surfs[0] = 0; + edge->surfs[1] = surface_p - surfaces; + + u_step = ((u0 - r_u1) / (v0 - r_v1)); + u = r_u1 + ((float)v - r_v1) * u_step; + } + + edge->u_step = u_step*0x100000; + edge->u = u*0x100000 + 0xFFFFF; + +// we need to do this to avoid stepping off the edges if a very nearly +// horizontal edge is less than epsilon above a scan, and numeric error causes +// it to incorrectly extend to the scan, and the extension of the line goes off +// the edge of the screen +// FIXME: is this actually needed? + if (edge->u < r_refdef.vrect_x_adj_shift20) + edge->u = r_refdef.vrect_x_adj_shift20; + if (edge->u > r_refdef.vrectright_adj_shift20) + edge->u = r_refdef.vrectright_adj_shift20; + +// +// sort the edge in normally +// + u_check = edge->u; + if (edge->surfs[0]) + u_check++; // sort trailers after leaders + + if (!newedges[v] || newedges[v]->u >= u_check) + { + edge->next = newedges[v]; + newedges[v] = edge; + } + else + { + pcheck = newedges[v]; + while (pcheck->next && pcheck->next->u < u_check) + pcheck = pcheck->next; + edge->next = pcheck->next; + pcheck->next = edge; + } + + edge->nextremove = removeedges[v2]; + removeedges[v2] = edge; +} + + +/* +================ +R_ClipEdge +================ +*/ +void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip) +{ + float d0, d1, f; + mvertex_t clipvert; + + if (clip) + { + do + { + d0 = DotProduct (pv0->position, clip->normal) - clip->dist; + d1 = DotProduct (pv1->position, clip->normal) - clip->dist; + + if (d0 >= 0) + { + // point 0 is unclipped + if (d1 >= 0) + { + // both points are unclipped + continue; + } + + // only point 1 is clipped + + // we don't cache clipped edges + cacheoffset = 0x7FFFFFFF; + + f = d0 / (d0 - d1); + clipvert.position[0] = pv0->position[0] + + f * (pv1->position[0] - pv0->position[0]); + clipvert.position[1] = pv0->position[1] + + f * (pv1->position[1] - pv0->position[1]); + clipvert.position[2] = pv0->position[2] + + f * (pv1->position[2] - pv0->position[2]); + + if (clip->leftedge) + { + r_leftclipped = true; + r_leftexit = clipvert; + } + else if (clip->rightedge) + { + r_rightclipped = true; + r_rightexit = clipvert; + } + + R_ClipEdge (pv0, &clipvert, clip->next); + return; + } + else + { + // point 0 is clipped + if (d1 < 0) + { + // both points are clipped + // we do cache fully clipped edges + if (!r_leftclipped) + cacheoffset = FULLY_CLIPPED_CACHED | + (r_framecount & FRAMECOUNT_MASK); + return; + } + + // only point 0 is clipped + r_lastvertvalid = false; + + // we don't cache partially clipped edges + cacheoffset = 0x7FFFFFFF; + + f = d0 / (d0 - d1); + clipvert.position[0] = pv0->position[0] + + f * (pv1->position[0] - pv0->position[0]); + clipvert.position[1] = pv0->position[1] + + f * (pv1->position[1] - pv0->position[1]); + clipvert.position[2] = pv0->position[2] + + f * (pv1->position[2] - pv0->position[2]); + + if (clip->leftedge) + { + r_leftclipped = true; + r_leftenter = clipvert; + } + else if (clip->rightedge) + { + r_rightclipped = true; + r_rightenter = clipvert; + } + + R_ClipEdge (&clipvert, pv1, clip->next); + return; + } + } while ((clip = clip->next) != NULL); + } + +// add the edge + R_EmitEdge (pv0, pv1); +} + +#endif // !id386 + + +/* +================ +R_EmitCachedEdge +================ +*/ +void R_EmitCachedEdge (void) +{ + edge_t *pedge_t; + + pedge_t = (edge_t *)((unsigned long)r_edges + r_pedge->cachededgeoffset); + + if (!pedge_t->surfs[0]) + pedge_t->surfs[0] = surface_p - surfaces; + else + pedge_t->surfs[1] = surface_p - surfaces; + + if (pedge_t->nearzi > r_nearzi) // for mipmap finding + r_nearzi = pedge_t->nearzi; + + r_emitted = 1; +} + + +/* +================ +R_RenderFace +================ +*/ +void R_RenderFace (msurface_t *fa, int clipflags) +{ + int i, lindex; + unsigned mask; + mplane_t *pplane; + float distinv; + vec3_t p_normal; + medge_t *pedges, tedge; + clipplane_t *pclip; + +// skip out if no more surfs + if ((surface_p) >= surf_max) + { + r_outofsurfaces++; + return; + } + +// ditto if not enough edges left, or switch to auxedges if possible + if ((edge_p + fa->numedges + 4) >= edge_max) + { + r_outofedges += fa->numedges; + return; + } + + c_faceclip++; + +// set up clip planes + pclip = NULL; + + for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1) + { + if (clipflags & mask) + { + view_clipplanes[i].next = pclip; + pclip = &view_clipplanes[i]; + } + } + +// push the edges through + r_emitted = 0; + r_nearzi = 0; + r_nearzionly = false; + makeleftedge = makerightedge = false; + pedges = currententity->model->edges; + r_lastvertvalid = false; + + for (i=0 ; inumedges ; i++) + { + lindex = currententity->model->surfedges[fa->firstedge + i]; + + if (lindex > 0) + { + r_pedge = &pedges[lindex]; + + // if the edge is cached, we can just reuse the edge + if (!insubmodel) + { + if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) + { + if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) == + r_framecount) + { + r_lastvertvalid = false; + continue; + } + } + else + { + if ((((unsigned long)edge_p - (unsigned long)r_edges) > + r_pedge->cachededgeoffset) && + (((edge_t *)((unsigned long)r_edges + + r_pedge->cachededgeoffset))->owner == r_pedge)) + { + R_EmitCachedEdge (); + r_lastvertvalid = false; + continue; + } + } + } + + // assume it's cacheable + cacheoffset = (byte *)edge_p - (byte *)r_edges; + r_leftclipped = r_rightclipped = false; + R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]], + &r_pcurrentvertbase[r_pedge->v[1]], + pclip); + r_pedge->cachededgeoffset = cacheoffset; + + if (r_leftclipped) + makeleftedge = true; + if (r_rightclipped) + makerightedge = true; + r_lastvertvalid = true; + } + else + { + lindex = -lindex; + r_pedge = &pedges[lindex]; + // if the edge is cached, we can just reuse the edge + if (!insubmodel) + { + if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) + { + if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) == + r_framecount) + { + r_lastvertvalid = false; + continue; + } + } + else + { + // it's cached if the cached edge is valid and is owned + // by this medge_t + if ((((unsigned long)edge_p - (unsigned long)r_edges) > + r_pedge->cachededgeoffset) && + (((edge_t *)((unsigned long)r_edges + + r_pedge->cachededgeoffset))->owner == r_pedge)) + { + R_EmitCachedEdge (); + r_lastvertvalid = false; + continue; + } + } + } + + // assume it's cacheable + cacheoffset = (byte *)edge_p - (byte *)r_edges; + r_leftclipped = r_rightclipped = false; + R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]], + &r_pcurrentvertbase[r_pedge->v[0]], + pclip); + r_pedge->cachededgeoffset = cacheoffset; + + if (r_leftclipped) + makeleftedge = true; + if (r_rightclipped) + makerightedge = true; + r_lastvertvalid = true; + } + } + +// if there was a clip off the left edge, add that edge too +// FIXME: faster to do in screen space? +// FIXME: share clipped edges? + if (makeleftedge) + { + r_pedge = &tedge; + r_lastvertvalid = false; + R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next); + } + +// if there was a clip off the right edge, get the right r_nearzi + if (makerightedge) + { + r_pedge = &tedge; + r_lastvertvalid = false; + r_nearzionly = true; + R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next); + } + +// if no edges made it out, return without posting the surface + if (!r_emitted) + return; + + r_polycount++; + + surface_p->data = (void *)fa; + surface_p->nearzi = r_nearzi; + surface_p->flags = fa->flags; + surface_p->insubmodel = insubmodel; + surface_p->spanstate = 0; + surface_p->entity = currententity; + surface_p->key = r_currentkey++; + surface_p->spans = NULL; + + pplane = fa->plane; +// FIXME: cache this? + TransformVector (pplane->normal, p_normal); +// FIXME: cache this? + distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal)); + + surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv; + surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv; + surface_p->d_ziorigin = p_normal[2] * distinv - + xcenter * surface_p->d_zistepu - + ycenter * surface_p->d_zistepv; + +//JDC VectorCopy (r_worldmodelorg, surface_p->modelorg); + surface_p++; +} + + +/* +================ +R_RenderBmodelFace +================ +*/ +void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf) +{ + int i; + unsigned mask; + mplane_t *pplane; + float distinv; + vec3_t p_normal; + medge_t tedge; + clipplane_t *pclip; + +// skip out if no more surfs + if (surface_p >= surf_max) + { + r_outofsurfaces++; + return; + } + +// ditto if not enough edges left, or switch to auxedges if possible + if ((edge_p + psurf->numedges + 4) >= edge_max) + { + r_outofedges += psurf->numedges; + return; + } + + c_faceclip++; + +// this is a dummy to give the caching mechanism someplace to write to + r_pedge = &tedge; + +// set up clip planes + pclip = NULL; + + for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1) + { + if (r_clipflags & mask) + { + view_clipplanes[i].next = pclip; + pclip = &view_clipplanes[i]; + } + } + +// push the edges through + r_emitted = 0; + r_nearzi = 0; + r_nearzionly = false; + makeleftedge = makerightedge = false; +// FIXME: keep clipped bmodel edges in clockwise order so last vertex caching +// can be used? + r_lastvertvalid = false; + + for ( ; pedges ; pedges = pedges->pnext) + { + r_leftclipped = r_rightclipped = false; + R_ClipEdge (pedges->v[0], pedges->v[1], pclip); + + if (r_leftclipped) + makeleftedge = true; + if (r_rightclipped) + makerightedge = true; + } + +// if there was a clip off the left edge, add that edge too +// FIXME: faster to do in screen space? +// FIXME: share clipped edges? + if (makeleftedge) + { + r_pedge = &tedge; + R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next); + } + +// if there was a clip off the right edge, get the right r_nearzi + if (makerightedge) + { + r_pedge = &tedge; + r_nearzionly = true; + R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next); + } + +// if no edges made it out, return without posting the surface + if (!r_emitted) + return; + + r_polycount++; + + surface_p->data = (void *)psurf; + surface_p->nearzi = r_nearzi; + surface_p->flags = psurf->flags; + surface_p->insubmodel = true; + surface_p->spanstate = 0; + surface_p->entity = currententity; + surface_p->key = r_currentbkey; + surface_p->spans = NULL; + + pplane = psurf->plane; +// FIXME: cache this? + TransformVector (pplane->normal, p_normal); +// FIXME: cache this? + distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal)); + + surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv; + surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv; + surface_p->d_ziorigin = p_normal[2] * distinv - + xcenter * surface_p->d_zistepu - + ycenter * surface_p->d_zistepv; + +//JDC VectorCopy (r_worldmodelorg, surface_p->modelorg); + surface_p++; +} + + +/* +================ +R_RenderPoly +================ +*/ +void R_RenderPoly (msurface_t *fa, int clipflags) +{ + int i, lindex, lnumverts, s_axis, t_axis; + float dist, lastdist, lzi, scale, u, v, frac; + unsigned mask; + vec3_t local, transformed; + clipplane_t *pclip; + medge_t *pedges; + mplane_t *pplane; + mvertex_t verts[2][100]; //FIXME: do real number + polyvert_t pverts[100]; //FIXME: do real number, safely + int vertpage, newverts, newpage, lastvert; + qboolean visible; + +// FIXME: clean this up and make it faster +// FIXME: guard against running out of vertices + + s_axis = t_axis = 0; // keep compiler happy + +// set up clip planes + pclip = NULL; + + for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1) + { + if (clipflags & mask) + { + view_clipplanes[i].next = pclip; + pclip = &view_clipplanes[i]; + } + } + +// reconstruct the polygon +// FIXME: these should be precalculated and loaded off disk + pedges = currententity->model->edges; + lnumverts = fa->numedges; + vertpage = 0; + + for (i=0 ; imodel->surfedges[fa->firstedge + i]; + + if (lindex > 0) + { + r_pedge = &pedges[lindex]; + verts[0][i] = r_pcurrentvertbase[r_pedge->v[0]]; + } + else + { + r_pedge = &pedges[-lindex]; + verts[0][i] = r_pcurrentvertbase[r_pedge->v[1]]; + } + } + +// clip the polygon, done if not visible + while (pclip) + { + lastvert = lnumverts - 1; + lastdist = DotProduct (verts[vertpage][lastvert].position, + pclip->normal) - pclip->dist; + + visible = false; + newverts = 0; + newpage = vertpage ^ 1; + + for (i=0 ; inormal) - + pclip->dist; + + if ((lastdist > 0) != (dist > 0)) + { + frac = dist / (dist - lastdist); + verts[newpage][newverts].position[0] = + verts[vertpage][i].position[0] + + ((verts[vertpage][lastvert].position[0] - + verts[vertpage][i].position[0]) * frac); + verts[newpage][newverts].position[1] = + verts[vertpage][i].position[1] + + ((verts[vertpage][lastvert].position[1] - + verts[vertpage][i].position[1]) * frac); + verts[newpage][newverts].position[2] = + verts[vertpage][i].position[2] + + ((verts[vertpage][lastvert].position[2] - + verts[vertpage][i].position[2]) * frac); + newverts++; + } + + if (dist >= 0) + { + verts[newpage][newverts] = verts[vertpage][i]; + newverts++; + visible = true; + } + + lastvert = i; + lastdist = dist; + } + + if (!visible || (newverts < 3)) + return; + + lnumverts = newverts; + vertpage ^= 1; + pclip = pclip->next; + } + +// transform and project, remembering the z values at the vertices and +// r_nearzi, and extract the s and t coordinates at the vertices + pplane = fa->plane; + switch (pplane->type) + { + case PLANE_X: + case PLANE_ANYX: + s_axis = 1; + t_axis = 2; + break; + case PLANE_Y: + case PLANE_ANYY: + s_axis = 0; + t_axis = 2; + break; + case PLANE_Z: + case PLANE_ANYZ: + s_axis = 0; + t_axis = 1; + break; + } + + r_nearzi = 0; + + for (i=0 ; i r_nearzi) // for mipmap finding + r_nearzi = lzi; + + // FIXME: build x/yscale into transform? + scale = xscale * lzi; + u = (xcenter + scale*transformed[0]); + if (u < r_refdef.fvrectx_adj) + u = r_refdef.fvrectx_adj; + if (u > r_refdef.fvrectright_adj) + u = r_refdef.fvrectright_adj; + + scale = yscale * lzi; + v = (ycenter - scale*transformed[1]); + if (v < r_refdef.fvrecty_adj) + v = r_refdef.fvrecty_adj; + if (v > r_refdef.fvrectbottom_adj) + v = r_refdef.fvrectbottom_adj; + + pverts[i].u = u; + pverts[i].v = v; + pverts[i].zi = lzi; + pverts[i].s = verts[vertpage][i].position[s_axis]; + pverts[i].t = verts[vertpage][i].position[t_axis]; + } + +// build the polygon descriptor, including fa, r_nearzi, and u, v, s, t, and z +// for each vertex + r_polydesc.numverts = lnumverts; + r_polydesc.nearzi = r_nearzi; + r_polydesc.pcurrentface = fa; + r_polydesc.pverts = pverts; + +// draw the polygon + D_DrawPoly (); +} + + +/* +================ +R_ZDrawSubmodelPolys +================ +*/ +void R_ZDrawSubmodelPolys (model_t *pmodel) +{ + int i, numsurfaces; + msurface_t *psurf; + float dot; + mplane_t *pplane; + + psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; + numsurfaces = pmodel->nummodelsurfaces; + + for (i=0 ; iplane; + + dot = DotProduct (modelorg, pplane->normal) - pplane->dist; + + // draw the polygon + if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || + (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) + { + // FIXME: use bounding-box-based frustum clipping info? + R_RenderPoly (psurf, 15); + } + } +} + diff --git a/r17/Revamped src/revamped_src/r_edge.c b/r17/Revamped src/revamped_src/r_edge.c new file mode 100755 index 00000000..700ccaa4 --- /dev/null +++ b/r17/Revamped src/revamped_src/r_edge.c @@ -0,0 +1,774 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// r_edge.c + +#include "quakedef.h" +#include "r_local.h" + +#if 0 +// FIXME +the complex cases add new polys on most lines, so dont optimize for keeping them the same +have multiple free span lists to try to get better coherence? +low depth complexity -- 1 to 3 or so + +this breaks spans at every edge, even hidden ones (bad) + +have a sentinal at both ends? +#endif + + +edge_t *auxedges; +edge_t *r_edges, *edge_p, *edge_max; + +surf_t *surfaces, *surface_p, *surf_max; + +// surfaces are generated in back to front order by the bsp, so if a surf +// pointer is greater than another one, it should be drawn in front +// surfaces[1] is the background, and is used as the active surface stack + +edge_t *newedges[MAXHEIGHT]; +edge_t *removeedges[MAXHEIGHT]; + +espan_t *span_p, *max_span_p; + +int r_currentkey; + +extern int screenwidth; + +int current_iv; + +int edge_head_u_shift20, edge_tail_u_shift20; + +static void (*pdrawfunc)(void); + +edge_t edge_head; +edge_t edge_tail; +edge_t edge_aftertail; +edge_t edge_sentinel; + +float fv; + +void R_GenerateSpans (void); +void R_GenerateSpansBackward (void); + +void R_LeadingEdge (edge_t *edge); +void R_LeadingEdgeBackwards (edge_t *edge); +void R_TrailingEdge (surf_t *surf, edge_t *edge); + + +//============================================================================= + + +/* +============== +R_DrawCulledPolys +============== +*/ +void R_DrawCulledPolys (void) +{ + surf_t *s; + msurface_t *pface; + + currententity = &cl_entities[0]; + + if (r_worldpolysbacktofront) + { + for (s=surface_p-1 ; s>&surfaces[1] ; s--) + { + if (!s->spans) + continue; + + if (!(s->flags & SURF_DRAWBACKGROUND)) + { + pface = (msurface_t *)s->data; + R_RenderPoly (pface, 15); + } + } + } + else + { + for (s = &surfaces[1] ; sspans) + continue; + + if (!(s->flags & SURF_DRAWBACKGROUND)) + { + pface = (msurface_t *)s->data; + R_RenderPoly (pface, 15); + } + } + } +} + + +/* +============== +R_BeginEdgeFrame +============== +*/ +void R_BeginEdgeFrame (void) +{ + int v; + + edge_p = r_edges; + edge_max = &r_edges[r_numallocatededges]; + + surface_p = &surfaces[2]; // background is surface 1, + // surface 0 is a dummy + surfaces[1].spans = NULL; // no background spans yet + surfaces[1].flags = SURF_DRAWBACKGROUND; + +// put the background behind everything in the world + if (r_draworder.value) + { + pdrawfunc = R_GenerateSpansBackward; + surfaces[1].key = 0; + r_currentkey = 1; + } + else + { + pdrawfunc = R_GenerateSpans; + surfaces[1].key = 0x7FFFFFFF; + r_currentkey = 0; + } + +// FIXME: set with memset + for (v=r_refdef.vrect.y ; vnext; +edgesearch: + if (edgelist->u >= edgestoadd->u) + goto addedge; + edgelist=edgelist->next; + if (edgelist->u >= edgestoadd->u) + goto addedge; + edgelist=edgelist->next; + if (edgelist->u >= edgestoadd->u) + goto addedge; + edgelist=edgelist->next; + if (edgelist->u >= edgestoadd->u) + goto addedge; + edgelist=edgelist->next; + goto edgesearch; + + // insert edgestoadd before edgelist +addedge: + edgestoadd->next = edgelist; + edgestoadd->prev = edgelist->prev; + edgelist->prev->next = edgestoadd; + edgelist->prev = edgestoadd; + } while ((edgestoadd = next_edge) != NULL); +} + +#endif // !id386 + + +#if !id386 + +/* +============== +R_RemoveEdges +============== +*/ +void R_RemoveEdges (edge_t *pedge) +{ + + do + { + pedge->next->prev = pedge->prev; + pedge->prev->next = pedge->next; + } while ((pedge = pedge->nextremove) != NULL); +} + +#endif // !id386 + + +#if !id386 + +/* +============== +R_StepActiveU +============== +*/ +void R_StepActiveU (edge_t *pedge) +{ + edge_t *pnext_edge, *pwedge; + + while (1) + { +nextedge: + pedge->u += pedge->u_step; + if (pedge->u < pedge->prev->u) + goto pushback; + pedge = pedge->next; + + pedge->u += pedge->u_step; + if (pedge->u < pedge->prev->u) + goto pushback; + pedge = pedge->next; + + pedge->u += pedge->u_step; + if (pedge->u < pedge->prev->u) + goto pushback; + pedge = pedge->next; + + pedge->u += pedge->u_step; + if (pedge->u < pedge->prev->u) + goto pushback; + pedge = pedge->next; + + goto nextedge; + +pushback: + if (pedge == &edge_aftertail) + return; + + // push it back to keep it sorted + pnext_edge = pedge->next; + + // pull the edge out of the edge list + pedge->next->prev = pedge->prev; + pedge->prev->next = pedge->next; + + // find out where the edge goes in the edge list + pwedge = pedge->prev->prev; + + while (pwedge->u > pedge->u) + { + pwedge = pwedge->prev; + } + + // put the edge back into the edge list + pedge->next = pwedge->next; + pedge->prev = pwedge; + pedge->next->prev = pedge; + pwedge->next = pedge; + + pedge = pnext_edge; + if (pedge == &edge_tail) + return; + } +} + +#endif // !id386 + + +/* +============== +R_CleanupSpan +============== +*/ +void R_CleanupSpan () +{ + surf_t *surf; + int iu; + espan_t *span; + +// now that we've reached the right edge of the screen, we're done with any +// unfinished surfaces, so emit a span for whatever's on top + surf = surfaces[1].next; + iu = edge_tail_u_shift20; + if (iu > surf->last_u) + { + span = span_p++; + span->u = surf->last_u; + span->count = iu - span->u; + span->v = current_iv; + span->pnext = surf->spans; + surf->spans = span; + } + +// reset spanstate for all surfaces in the surface stack + do + { + surf->spanstate = 0; + surf = surf->next; + } while (surf != &surfaces[1]); +} + + +/* +============== +R_LeadingEdgeBackwards +============== +*/ +void R_LeadingEdgeBackwards (edge_t *edge) +{ + espan_t *span; + surf_t *surf, *surf2; + int iu; + +// it's adding a new surface in, so find the correct place + surf = &surfaces[edge->surfs[1]]; + +// don't start a span if this is an inverted span, with the end +// edge preceding the start edge (that is, we've already seen the +// end edge) + if (++surf->spanstate == 1) + { + surf2 = surfaces[1].next; + + if (surf->key > surf2->key) + goto newtop; + + // if it's two surfaces on the same plane, the one that's already + // active is in front, so keep going unless it's a bmodel + if (surf->insubmodel && (surf->key == surf2->key)) + { + // must be two bmodels in the same leaf; don't care, because they'll + // never be farthest anyway + goto newtop; + } + +continue_search: + + do + { + surf2 = surf2->next; + } while (surf->key < surf2->key); + + if (surf->key == surf2->key) + { + // if it's two surfaces on the same plane, the one that's already + // active is in front, so keep going unless it's a bmodel + if (!surf->insubmodel) + goto continue_search; + + // must be two bmodels in the same leaf; don't care which is really + // in front, because they'll never be farthest anyway + } + + goto gotposition; + +newtop: + // emit a span (obscures current top) + iu = edge->u >> 20; + + if (iu > surf2->last_u) + { + span = span_p++; + span->u = surf2->last_u; + span->count = iu - span->u; + span->v = current_iv; + span->pnext = surf2->spans; + surf2->spans = span; + } + + // set last_u on the new span + surf->last_u = iu; + +gotposition: + // insert before surf2 + surf->next = surf2; + surf->prev = surf2->prev; + surf2->prev->next = surf; + surf2->prev = surf; + } +} + + +/* +============== +R_TrailingEdge +============== +*/ +void R_TrailingEdge (surf_t *surf, edge_t *edge) +{ + espan_t *span; + int iu; + +// don't generate a span if this is an inverted span, with the end +// edge preceding the start edge (that is, we haven't seen the +// start edge yet) + if (--surf->spanstate == 0) + { + if (surf->insubmodel) + r_bmodelactive--; + + if (surf == surfaces[1].next) + { + // emit a span (current top going away) + iu = edge->u >> 20; + if (iu > surf->last_u) + { + span = span_p++; + span->u = surf->last_u; + span->count = iu - span->u; + span->v = current_iv; + span->pnext = surf->spans; + surf->spans = span; + } + + // set last_u on the surface below + surf->next->last_u = iu; + } + + surf->prev->next = surf->next; + surf->next->prev = surf->prev; + } +} + + +#if !id386 + +/* +============== +R_LeadingEdge +============== +*/ +void R_LeadingEdge (edge_t *edge) +{ + espan_t *span; + surf_t *surf, *surf2; + int iu; + float fu, newzi, testzi, newzitop, newzibottom; + + if (edge->surfs[1]) + { + // it's adding a new surface in, so find the correct place + surf = &surfaces[edge->surfs[1]]; + + // don't start a span if this is an inverted span, with the end + // edge preceding the start edge (that is, we've already seen the + // end edge) + if (++surf->spanstate == 1) + { + if (surf->insubmodel) + r_bmodelactive++; + + surf2 = surfaces[1].next; + + if (surf->key < surf2->key) + goto newtop; + + // if it's two surfaces on the same plane, the one that's already + // active is in front, so keep going unless it's a bmodel + if (surf->insubmodel && (surf->key == surf2->key)) + { + // must be two bmodels in the same leaf; sort on 1/z + fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000); + newzi = surf->d_ziorigin + fv*surf->d_zistepv + + fu*surf->d_zistepu; + newzibottom = newzi * 0.99; + + testzi = surf2->d_ziorigin + fv*surf2->d_zistepv + + fu*surf2->d_zistepu; + + if (newzibottom >= testzi) + { + goto newtop; + } + + newzitop = newzi * 1.01; + if (newzitop >= testzi) + { + if (surf->d_zistepu >= surf2->d_zistepu) + { + goto newtop; + } + } + } + +continue_search: + + do + { + surf2 = surf2->next; + } while (surf->key > surf2->key); + + if (surf->key == surf2->key) + { + // if it's two surfaces on the same plane, the one that's already + // active is in front, so keep going unless it's a bmodel + if (!surf->insubmodel) + goto continue_search; + + // must be two bmodels in the same leaf; sort on 1/z + fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000); + newzi = surf->d_ziorigin + fv*surf->d_zistepv + + fu*surf->d_zistepu; + newzibottom = newzi * 0.99; + + testzi = surf2->d_ziorigin + fv*surf2->d_zistepv + + fu*surf2->d_zistepu; + + if (newzibottom >= testzi) + { + goto gotposition; + } + + newzitop = newzi * 1.01; + if (newzitop >= testzi) + { + if (surf->d_zistepu >= surf2->d_zistepu) + { + goto gotposition; + } + } + + goto continue_search; + } + + goto gotposition; + +newtop: + // emit a span (obscures current top) + iu = edge->u >> 20; + + if (iu > surf2->last_u) + { + span = span_p++; + span->u = surf2->last_u; + span->count = iu - span->u; + span->v = current_iv; + span->pnext = surf2->spans; + surf2->spans = span; + } + + // set last_u on the new span + surf->last_u = iu; + +gotposition: + // insert before surf2 + surf->next = surf2; + surf->prev = surf2->prev; + surf2->prev->next = surf; + surf2->prev = surf; + } + } +} + + +/* +============== +R_GenerateSpans +============== +*/ +void R_GenerateSpans (void) +{ + edge_t *edge; + surf_t *surf; + + r_bmodelactive = 0; + +// clear active surfaces to just the background surface + surfaces[1].next = surfaces[1].prev = &surfaces[1]; + surfaces[1].last_u = edge_head_u_shift20; + +// generate spans + for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next) + { + if (edge->surfs[0]) + { + // it has a left surface, so a surface is going away for this span + surf = &surfaces[edge->surfs[0]]; + + R_TrailingEdge (surf, edge); + + if (!edge->surfs[1]) + continue; + } + + R_LeadingEdge (edge); + } + + R_CleanupSpan (); +} + +#endif // !id386 + + +/* +============== +R_GenerateSpansBackward +============== +*/ +void R_GenerateSpansBackward (void) +{ + edge_t *edge; + + r_bmodelactive = 0; + +// clear active surfaces to just the background surface + surfaces[1].next = surfaces[1].prev = &surfaces[1]; + surfaces[1].last_u = edge_head_u_shift20; + +// generate spans + for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next) + { + if (edge->surfs[0]) + R_TrailingEdge (&surfaces[edge->surfs[0]], edge); + + if (edge->surfs[1]) + R_LeadingEdgeBackwards (edge); + } + + R_CleanupSpan (); +} + + +/* +============== +R_ScanEdges + +Input: +newedges[] array + this has links to edges, which have links to surfaces + +Output: +Each surface has a linked list of its visible spans +============== +*/ +void R_ScanEdges (void) +{ + int iv, bottom; + byte basespans[MAXSPANS*sizeof(espan_t)+CACHE_SIZE]; + espan_t *basespan_p; + surf_t *s; + + basespan_p = (espan_t *) + ((long)(basespans + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + max_span_p = &basespan_p[MAXSPANS - r_refdef.vrect.width]; + + span_p = basespan_p; + +// clear active edges to just the background edges around the whole screen +// FIXME: most of this only needs to be set up once + edge_head.u = r_refdef.vrect.x << 20; + edge_head_u_shift20 = edge_head.u >> 20; + edge_head.u_step = 0; + edge_head.prev = NULL; + edge_head.next = &edge_tail; + edge_head.surfs[0] = 0; + edge_head.surfs[1] = 1; + + edge_tail.u = (r_refdef.vrectright << 20) + 0xFFFFF; + edge_tail_u_shift20 = edge_tail.u >> 20; + edge_tail.u_step = 0; + edge_tail.prev = &edge_head; + edge_tail.next = &edge_aftertail; + edge_tail.surfs[0] = 1; + edge_tail.surfs[1] = 0; + + edge_aftertail.u = -1; // force a move + edge_aftertail.u_step = 0; + edge_aftertail.next = &edge_sentinel; + edge_aftertail.prev = &edge_tail; + +// FIXME: do we need this now that we clamp x in r_draw.c? + edge_sentinel.u = 2000 << 24; // make sure nothing sorts past this + edge_sentinel.prev = &edge_aftertail; + +// +// process all scan lines +// + bottom = r_refdef.vrectbottom - 1; + + for (iv=r_refdef.vrect.y ; iv= max_span_p) + { + VID_UnlockBuffer (); + S_ExtraUpdate (); // don't let sound get messed up if going slow + VID_LockBuffer (); + + if (r_drawculledpolys) + { + R_DrawCulledPolys (); + } + else + { + D_DrawSurfaces (); + } + + // clear the surface span pointers + for (s = &surfaces[1] ; sspans = NULL; + + span_p = basespan_p; + } + + if (removeedges[iv]) + R_RemoveEdges (removeedges[iv]); + + if (edge_head.next != &edge_tail) + R_StepActiveU (edge_head.next); + } + +// do the last scan (no need to step or sort or remove on the last scan) + + current_iv = iv; + fv = (float)iv; + +// mark that the head (background start) span is pre-included + surfaces[1].spanstate = 1; + + if (newedges[iv]) + R_InsertNewEdges (newedges[iv], edge_head.next); + + (*pdrawfunc) (); + +// draw whatever's left in the span list + if (r_drawculledpolys) + R_DrawCulledPolys (); + else + D_DrawSurfaces (); +} + + diff --git a/r17/Revamped src/revamped_src/r_efrag.c b/r17/Revamped src/revamped_src/r_efrag.c new file mode 100755 index 00000000..f502d860 --- /dev/null +++ b/r17/Revamped src/revamped_src/r_efrag.c @@ -0,0 +1,276 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// r_efrag.c + +#include "quakedef.h" +#include "r_local.h" + +mnode_t *r_pefragtopnode; + + +//=========================================================================== + +/* +=============================================================================== + + ENTITY FRAGMENT FUNCTIONS + +=============================================================================== +*/ + +efrag_t **lastlink; + +vec3_t r_emins, r_emaxs; + +entity_t *r_addent; + + +/* +================ +R_RemoveEfrags + +Call when removing an object from the world or moving it to another position +================ +*/ +void R_RemoveEfrags (entity_t *ent) +{ + efrag_t *ef, *old, *walk, **prev; + + ef = ent->efrag; + + while (ef) + { + prev = &ef->leaf->efrags; + while (1) + { + walk = *prev; + if (!walk) + break; + if (walk == ef) + { // remove this fragment + *prev = ef->leafnext; + break; + } + else + prev = &walk->leafnext; + } + + old = ef; + ef = ef->entnext; + + // put it on the free list + old->entnext = cl.free_efrags; + cl.free_efrags = old; + } + + ent->efrag = NULL; +} + +/* +=================== +R_SplitEntityOnNode +=================== +*/ +void R_SplitEntityOnNode (mnode_t *node) +{ + efrag_t *ef; + mplane_t *splitplane; + mleaf_t *leaf; + int sides; + + if (node->contents == CONTENTS_SOLID) + { + return; + } + +// add an efrag if the node is a leaf + + if ( node->contents < 0) + { + if (!r_pefragtopnode) + r_pefragtopnode = node; + + leaf = (mleaf_t *)node; + +// grab an efrag off the free list + ef = cl.free_efrags; + if (!ef) + { + Con_Printf ("Too many efrags!\n"); + return; // no free fragments... + } + cl.free_efrags = cl.free_efrags->entnext; + + ef->entity = r_addent; + +// add the entity link + *lastlink = ef; + lastlink = &ef->entnext; + ef->entnext = NULL; + +// set the leaf links + ef->leaf = leaf; + ef->leafnext = leaf->efrags; + leaf->efrags = ef; + + return; + } + +// NODE_MIXED + + splitplane = node->plane; + sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane); + + if (sides == 3) + { + // split on this plane + // if this is the first splitter of this bmodel, remember it + if (!r_pefragtopnode) + r_pefragtopnode = node; + } + +// recurse down the contacted sides + if (sides & 1) + R_SplitEntityOnNode (node->children[0]); + + if (sides & 2) + R_SplitEntityOnNode (node->children[1]); +} + + +/* +=================== +R_SplitEntityOnNode2 +=================== +*/ +void R_SplitEntityOnNode2 (mnode_t *node) +{ + mplane_t *splitplane; + int sides; + + if (node->visframe != r_visframecount) + return; + + if (node->contents < 0) + { + if (node->contents != CONTENTS_SOLID) + r_pefragtopnode = node; // we've reached a non-solid leaf, so it's + // visible and not BSP clipped + return; + } + + splitplane = node->plane; + sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane); + + if (sides == 3) + { + // remember first splitter + r_pefragtopnode = node; + return; + } + +// not split yet; recurse down the contacted side + if (sides & 1) + R_SplitEntityOnNode2 (node->children[0]); + else + R_SplitEntityOnNode2 (node->children[1]); +} + + +/* +=========== +R_AddEfrags +=========== +*/ +void R_AddEfrags (entity_t *ent) +{ + model_t *entmodel; + int i; + + if (!ent->model) + return; + + if (ent == cl_entities) + return; // never add the world + + r_addent = ent; + + lastlink = &ent->efrag; + r_pefragtopnode = NULL; + + entmodel = ent->model; + + for (i=0 ; i<3 ; i++) + { + r_emins[i] = ent->origin[i] + entmodel->mins[i]; + r_emaxs[i] = ent->origin[i] + entmodel->maxs[i]; + } + + R_SplitEntityOnNode (cl.worldmodel->nodes); + + ent->topnode = r_pefragtopnode; +} + + +/* +================ +R_StoreEfrags + +// FIXME: a lot of this goes away with edge-based +================ +*/ +void R_StoreEfrags (efrag_t **ppefrag) +{ + entity_t *pent; + model_t *clmodel; + efrag_t *pefrag; + + + while ((pefrag = *ppefrag) != NULL) + { + pent = pefrag->entity; + clmodel = pent->model; + + switch (clmodel->type) + { + case mod_alias: + case mod_brush: + case mod_sprite: + pent = pefrag->entity; + + if ((pent->visframe != r_framecount) && + (cl_numvisedicts < MAX_VISEDICTS)) + { + cl_visedicts[cl_numvisedicts++] = pent; + + // mark that we've recorded this entity for this frame + pent->visframe = r_framecount; + } + + ppefrag = &pefrag->leafnext; + break; + + default: + Sys_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel->type); + } + } +} + + diff --git a/r17/Revamped src/revamped_src/r_light.c b/r17/Revamped src/revamped_src/r_light.c new file mode 100755 index 00000000..14350e81 --- /dev/null +++ b/r17/Revamped src/revamped_src/r_light.c @@ -0,0 +1,260 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// r_light.c + +#include "quakedef.h" +#include "r_local.h" + +int r_dlightframecount; + + +/* +================== +R_AnimateLight +================== +*/ +void R_AnimateLight (void) +{ + int i,j,k; + +// +// light animations +// 'm' is normal light, 'a' is no light, 'z' is double bright + i = (int)(cl.time*10); + for (j=0 ; jcontents < 0) + return; + + splitplane = node->plane; + dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; + + if (dist > light->radius) + { + R_MarkLights (light, bit, node->children[0]); + return; + } + if (dist < -light->radius) + { + R_MarkLights (light, bit, node->children[1]); + return; + } + +// mark the polygons + surf = cl.worldmodel->surfaces + node->firstsurface; + for (i=0 ; inumsurfaces ; i++, surf++) + { + if (surf->dlightframe != r_dlightframecount) + { + surf->dlightbits = 0; + surf->dlightframe = r_dlightframecount; + } + surf->dlightbits |= bit; + } + + R_MarkLights (light, bit, node->children[0]); + R_MarkLights (light, bit, node->children[1]); +} + + +/* +============= +R_PushDlights +============= +*/ +void R_PushDlights (void) +{ + int i; + dlight_t *l; + + r_dlightframecount = r_framecount + 1; // because the count hasn't + // advanced yet for this frame + l = cl_dlights; + + for (i=0 ; idie < cl.time || !l->radius) + continue; + R_MarkLights ( l, 1<nodes ); + } +} + + +/* +============================================================================= + +LIGHT SAMPLING + +============================================================================= +*/ + +int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) +{ + int r; + float front, back, frac; + int side; + mplane_t *plane; + vec3_t mid; + msurface_t *surf; + int s, t, ds, dt; + int i; + mtexinfo_t *tex; + byte *lightmap; + unsigned scale; + int maps; + + if (node->contents < 0) + return -1; // didn't hit anything + +// calculate mid point + +// FIXME: optimize for axial + plane = node->plane; + front = DotProduct (start, plane->normal) - plane->dist; + back = DotProduct (end, plane->normal) - plane->dist; + side = front < 0; + + if ( (back < 0) == side) + return RecursiveLightPoint (node->children[side], start, end); + + frac = front / (front-back); + mid[0] = start[0] + (end[0] - start[0])*frac; + mid[1] = start[1] + (end[1] - start[1])*frac; + mid[2] = start[2] + (end[2] - start[2])*frac; + +// go down front side + r = RecursiveLightPoint (node->children[side], start, mid); + if (r >= 0) + return r; // hit something + + if ( (back < 0) == side ) + return -1; // didn't hit anuthing + +// check for impact on this node + + surf = cl.worldmodel->surfaces + node->firstsurface; + for (i=0 ; inumsurfaces ; i++, surf++) + { + if (surf->flags & SURF_DRAWTILED) + continue; // no lightmaps + + tex = surf->texinfo; + + s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3]; + t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];; + + if (s < surf->texturemins[0] || + t < surf->texturemins[1]) + continue; + + ds = s - surf->texturemins[0]; + dt = t - surf->texturemins[1]; + + if ( ds > surf->extents[0] || dt > surf->extents[1] ) + continue; + + if (!surf->samples) + return 0; + + ds >>= 4; + dt >>= 4; + + lightmap = surf->samples; + r = 0; + if (lightmap) + { + + lightmap += dt * ((surf->extents[0]>>4)+1) + ds; + + for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + r += *lightmap * scale; + lightmap += ((surf->extents[0]>>4)+1) * + ((surf->extents[1]>>4)+1); + } + + r >>= 8; + } + + return r; + } + +// go down back side + return RecursiveLightPoint (node->children[!side], mid, end); +} + +int R_LightPoint (vec3_t p) +{ + vec3_t end; + int r; + + if (!cl.worldmodel->lightdata) + return 255; + + end[0] = p[0]; + end[1] = p[1]; + end[2] = p[2] - 2048; + + r = RecursiveLightPoint (cl.worldmodel->nodes, p, end); + + if (r == -1) + r = 0; + + if (r < r_refdef.ambientlight) + r = r_refdef.ambientlight; + + return r; +} + diff --git a/r17/Revamped src/revamped_src/r_local.h b/r17/Revamped src/revamped_src/r_local.h new file mode 100755 index 00000000..a67de802 --- /dev/null +++ b/r17/Revamped src/revamped_src/r_local.h @@ -0,0 +1,317 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// r_local.h -- private refresh defs + +#if !defined(GLQUAKE) && !defined(PSP_HARDWARE_VIDEO) +#include "r_shared.h" + +#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0) + // normalizing factor so player model works out to about + // 1 pixel per triangle + +#define BMODEL_FULLY_CLIPPED 0x10 // value returned by R_BmodelCheckBBox () + // if bbox is trivially rejected + +//=========================================================================== +// viewmodel lighting + +typedef struct { + int ambientlight; + int shadelight; + float *plightvec; +} alight_t; + +//=========================================================================== +// clipped bmodel edges + +typedef struct bedge_s +{ + mvertex_t *v[2]; + struct bedge_s *pnext; +} bedge_t; + +typedef struct { + float fv[3]; // viewspace x, y +} auxvert_t; + +//=========================================================================== + +extern cvar_t r_draworder; +extern cvar_t r_speeds; +extern cvar_t r_timegraph; +extern cvar_t r_graphheight; +extern cvar_t r_clearcolor; +extern cvar_t r_waterwarp; +extern cvar_t r_wateralpha; +extern cvar_t r_fullbright; +extern cvar_t r_drawentities; +extern cvar_t r_aliasstats; +extern cvar_t r_dspeeds; +extern cvar_t r_drawflat; +extern cvar_t r_ambient; +extern cvar_t r_reportsurfout; +extern cvar_t r_maxsurfs; +extern cvar_t r_numsurfs; +extern cvar_t r_reportedgeout; +extern cvar_t r_maxedges; +extern cvar_t r_numedges; + +#define XCENTERING (1.0 / 2.0) +#define YCENTERING (1.0 / 2.0) + +#define CLIP_EPSILON 0.001 + +#define BACKFACE_EPSILON 0.01 + +//=========================================================================== + +#define DIST_NOT_SET 98765 + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct clipplane_s +{ + vec3_t normal; + float dist; + struct clipplane_s *next; + byte leftedge; + byte rightedge; + byte reserved[2]; +} clipplane_t; + +extern clipplane_t view_clipplanes[4]; + +//============================================================================= + +void R_RenderWorld (void); + +//============================================================================= + +extern mplane_t screenedge[4]; + +extern vec3_t r_origin; + +extern vec3_t r_entorigin; + +extern float screenAspect; +extern float verticalFieldOfView; +extern float xOrigin, yOrigin; + +extern int r_visframecount; + +//============================================================================= + +extern int vstartscan; + + +void R_ClearPolyList (void); +void R_DrawPolyList (void); + +// +// current entity info +// +extern qboolean insubmodel; +extern vec3_t r_worldmodelorg; + + +void R_DrawSprite (void); +void R_RenderFace (msurface_t *fa, int clipflags); +void R_RenderPoly (msurface_t *fa, int clipflags); +void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf); +void R_TransformPlane (mplane_t *p, float *normal, float *dist); +void R_TransformFrustum (void); +void R_SetSkyFrame (void); +void R_DrawSurfaceBlock16 (void); +void R_DrawSurfaceBlock8 (void); +texture_t *R_TextureAnimation (texture_t *base); + +#if id386 + +void R_DrawSurfaceBlock8_mip0 (void); +void R_DrawSurfaceBlock8_mip1 (void); +void R_DrawSurfaceBlock8_mip2 (void); +void R_DrawSurfaceBlock8_mip3 (void); + +#endif + +void R_GenSkyTile (void *pdest); +void R_GenSkyTile16 (void *pdest); +void R_Surf8Patch (void); +void R_Surf16Patch (void); +void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags); +void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel); + +void R_AddPolygonEdges (emitpoint_t *pverts, int numverts, int miplevel); +surf_t *R_GetSurf (void); +void R_AliasDrawModel (alight_t *plighting); +void R_BeginEdgeFrame (void); +void R_ScanEdges (void); +void D_DrawSurfaces (void); +void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist); +void R_StepActiveU (edge_t *pedge); +void R_RemoveEdges (edge_t *pedge); + +extern void R_Surf8Start (void); +extern void R_Surf8End (void); +extern void R_Surf16Start (void); +extern void R_Surf16End (void); +extern void R_EdgeCodeStart (void); +extern void R_EdgeCodeEnd (void); + +extern void R_RotateBmodel (void); + +extern int c_faceclip; +extern int r_polycount; +extern int r_wholepolycount; + +extern model_t *cl_worldmodel; + +extern int *pfrustum_indexes[4]; + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +#define NEAR_CLIP 0.01 + +extern int ubasestep, errorterm, erroradjustup, erroradjustdown; +extern int vstartscan; + +extern fixed16_t sadjust, tadjust; +extern fixed16_t bbextents, bbextentt; + +#define MAXBVERTINDEXES 1000 // new clipped vertices when clipping bmodels + // to the world BSP +extern mvertex_t *r_ptverts, *r_ptvertsmax; + +extern vec3_t sbaseaxis[3], tbaseaxis[3]; +extern float entity_rotation[3][3]; + +extern int reinit_surfcache; + +extern int r_currentkey; +extern int r_currentbkey; + +typedef struct btofpoly_s { + int clipflags; + msurface_t *psurf; +} btofpoly_t; + +#define MAX_BTOFPOLYS 5000 // FIXME: tune this + +extern int numbtofpolys; +extern btofpoly_t *pbtofpolys; + +void R_InitTurb (void); +void R_ZDrawSubmodelPolys (model_t *clmodel); + +//========================================================= +// Alias models +//========================================================= + +#define MAXALIASVERTS 2000 // TODO: tune this +#define ALIAS_Z_CLIP_PLANE 5 + +extern int numverts; +extern int a_skinwidth; +extern mtriangle_t *ptriangles; +extern int numtriangles; +extern aliashdr_t *paliashdr; +extern mdl_t *pmdl; +extern float leftclip, topclip, rightclip, bottomclip; +extern int r_acliptype; +extern finalvert_t *pfinalverts; +extern auxvert_t *pauxverts; + +qboolean R_AliasCheckBBox (void); + +//========================================================= +// turbulence stuff + +#define AMP 8*0x10000 +#define AMP2 3 +#define SPEED 20 + +//========================================================= +// particle stuff + +void R_DrawParticles (void); +void R_InitParticles (void); +void R_ClearParticles (void); +void R_ReadPointFile_f (void); +void R_SurfacePatch (void); + +extern int r_amodels_drawn; +extern edge_t *auxedges; +extern int r_numallocatededges; +extern edge_t *r_edges, *edge_p, *edge_max; + +extern edge_t *newedges[MAXHEIGHT]; +extern edge_t *removeedges[MAXHEIGHT]; + +extern int screenwidth; + +// FIXME: make stack vars when debugging done +extern edge_t edge_head; +extern edge_t edge_tail; +extern edge_t edge_aftertail; +extern int r_bmodelactive; +extern vrect_t *pconupdate; + +extern float aliasxscale, aliasyscale, aliasxcenter, aliasycenter; +extern float r_aliastransition, r_resfudge; + +extern int r_outofsurfaces; +extern int r_outofedges; + +extern mvertex_t *r_pcurrentvertbase; +extern int r_maxvalidedgeoffset; + +void R_AliasClipTriangle (mtriangle_t *ptri); + +extern float r_time1; +extern float dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2; +extern float se_time1, se_time2, de_time1, de_time2, dv_time1, dv_time2; +extern int r_frustum_indexes[4*6]; +extern int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs; +extern qboolean r_surfsonstack; +extern cshift_t cshift_water; +extern qboolean r_dowarpold, r_viewchanged; + +extern mleaf_t *r_viewleaf, *r_oldviewleaf; + +extern vec3_t r_emins, r_emaxs; +extern mnode_t *r_pefragtopnode; +extern int r_clipflags; +extern int r_dlightframecount; +extern qboolean r_fov_greater_than_90; + +void R_StoreEfrags (efrag_t **ppefrag); +void R_TimeRefresh_f (void); +void R_TimeGraph (void); +void R_PrintAliasStats (void); +void R_PrintTimes (void); +void R_PrintDSpeeds (void); +void R_AnimateLight (void); +int R_LightPoint (vec3_t p); +void R_SetupFrame (void); +void R_cshift_f (void); +void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1); +void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip); +void R_SplitEntityOnNode2 (mnode_t *node); +void R_MarkLights (dlight_t *light, int bit, mnode_t *node); + +#endif diff --git a/r17/Revamped src/revamped_src/r_main.c b/r17/Revamped src/revamped_src/r_main.c new file mode 100755 index 00000000..10014a9e --- /dev/null +++ b/r17/Revamped src/revamped_src/r_main.c @@ -0,0 +1,1085 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// r_main.c + +#include "quakedef.h" +#include "r_local.h" + +//define PASSAGES + +void *colormap; +vec3_t viewlightvec; +alight_t r_viewlighting = {128, 192, viewlightvec}; +float r_time1; +int r_numallocatededges; +qboolean r_drawpolys; +qboolean r_drawculledpolys; +qboolean r_worldpolysbacktofront; +qboolean r_recursiveaffinetriangles = true; +int r_pixbytes = 1; +float r_aliasuvscale = 1.0; +int r_outofsurfaces; +int r_outofedges; + +qboolean r_dowarp, r_dowarpold, r_viewchanged; + +int numbtofpolys; +btofpoly_t *pbtofpolys; +mvertex_t *r_pcurrentvertbase; + +int c_surf; +int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs; +qboolean r_surfsonstack; +int r_clipflags; + +byte *r_warpbuffer; + +byte *r_stack_start; + +qboolean r_fov_greater_than_90; + +// +// view origin +// +vec3_t vup, base_vup; +vec3_t vpn, base_vpn; +vec3_t vright, base_vright; +vec3_t r_origin; + +// +// screen size info +// +refdef_t r_refdef; +float xcenter, ycenter; +float xscale, yscale; +float xscaleinv, yscaleinv; +float xscaleshrink, yscaleshrink; +float aliasxscale, aliasyscale, aliasxcenter, aliasycenter; + +int screenwidth; + +float pixelAspect; +float screenAspect; +float verticalFieldOfView; +float xOrigin, yOrigin; + +mplane_t screenedge[4]; + +// +// refresh flags +// +int r_framecount = 1; // so frame counts initialized to 0 don't match +int r_visframecount; +int d_spanpixcount; +int r_polycount; +int r_drawnpolycount; +int r_wholepolycount; + +#define VIEWMODNAME_LENGTH 256 +char viewmodname[VIEWMODNAME_LENGTH+1]; +int modcount; + +int *pfrustum_indexes[4]; +int r_frustum_indexes[4*6]; + +int reinit_surfcache = 1; // if 1, surface cache is currently empty and + // must be reinitialized for current cache size + +mleaf_t *r_viewleaf, *r_oldviewleaf; + +texture_t *r_notexture_mip; + +float r_aliastransition, r_resfudge; + +int d_lightstylevalue[256]; // 8.8 fraction of base light value + +float dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2; +float se_time1, se_time2, de_time1, de_time2, dv_time1, dv_time2; + +void R_MarkLeaves (void); + +cvar_t r_draworder = {"r_draworder","0"}; +cvar_t r_speeds = {"r_speeds","0"}; +cvar_t r_timegraph = {"r_timegraph","0"}; +cvar_t r_graphheight = {"r_graphheight","10"}; +cvar_t r_clearcolor = {"r_clearcolor","2"}; +cvar_t r_waterwarp = {"r_waterwarp","1"}; +cvar_t r_fullbright = {"r_fullbright","0"}; +cvar_t r_drawentities = {"r_drawentities","1"}; +cvar_t r_drawviewmodel = {"r_drawviewmodel","1"}; +cvar_t r_aliasstats = {"r_polymodelstats","0"}; +cvar_t r_dspeeds = {"r_dspeeds","0"}; +cvar_t r_drawflat = {"r_drawflat", "0"}; +cvar_t r_ambient = {"r_ambient", "0"}; +cvar_t r_reportsurfout = {"r_reportsurfout", "0"}; +cvar_t r_maxsurfs = {"r_maxsurfs", "0"}; +cvar_t r_numsurfs = {"r_numsurfs", "0"}; +cvar_t r_reportedgeout = {"r_reportedgeout", "0"}; +cvar_t r_maxedges = {"r_maxedges", "0"}; +cvar_t r_numedges = {"r_numedges", "0"}; +cvar_t r_aliastransbase = {"r_aliastransbase", "200"}; +cvar_t r_aliastransadj = {"r_aliastransadj", "100"}; + +extern cvar_t scr_fov; + +void CreatePassages (void); +void SetVisibilityByPassages (void); + +/* +================== +R_InitTextures +================== +*/ +void R_InitTextures (void) +{ + int x,y, m; + byte *dest; + +// create a simple checkerboard texture for the default + r_notexture_mip = Hunk_AllocName (sizeof(texture_t) + 16*16+8*8+4*4+2*2, "notexture"); + + r_notexture_mip->width = r_notexture_mip->height = 16; + r_notexture_mip->offsets[0] = sizeof(texture_t); + r_notexture_mip->offsets[1] = r_notexture_mip->offsets[0] + 16*16; + r_notexture_mip->offsets[2] = r_notexture_mip->offsets[1] + 8*8; + r_notexture_mip->offsets[3] = r_notexture_mip->offsets[2] + 4*4; + + for (m=0 ; m<4 ; m++) + { + dest = (byte *)r_notexture_mip + r_notexture_mip->offsets[m]; + for (y=0 ; y< (16>>m) ; y++) + for (x=0 ; x< (16>>m) ; x++) + { + if ( (y< (8>>m) ) ^ (x< (8>>m) ) ) + *dest++ = 0; + else + *dest++ = 0xff; + } + } +} + +/* +=============== +R_Init +=============== +*/ +void R_Init (void) +{ + int dummy; + +// get stack position so we can guess if we are going to overflow + r_stack_start = (byte *)&dummy; + + R_InitTurb (); + + Cmd_AddCommand ("timerefresh", R_TimeRefresh_f); + Cmd_AddCommand ("pointfile", R_ReadPointFile_f); + + Cvar_RegisterVariable (&r_draworder); + Cvar_RegisterVariable (&r_speeds); + Cvar_RegisterVariable (&r_timegraph); + Cvar_RegisterVariable (&r_graphheight); + Cvar_RegisterVariable (&r_drawflat); + Cvar_RegisterVariable (&r_ambient); + Cvar_RegisterVariable (&r_clearcolor); + Cvar_RegisterVariable (&r_waterwarp); + Cvar_RegisterVariable (&r_fullbright); + Cvar_RegisterVariable (&r_drawentities); + Cvar_RegisterVariable (&r_drawviewmodel); + Cvar_RegisterVariable (&r_aliasstats); + Cvar_RegisterVariable (&r_dspeeds); + Cvar_RegisterVariable (&r_reportsurfout); + Cvar_RegisterVariable (&r_maxsurfs); + Cvar_RegisterVariable (&r_numsurfs); + Cvar_RegisterVariable (&r_reportedgeout); + Cvar_RegisterVariable (&r_maxedges); + Cvar_RegisterVariable (&r_numedges); + Cvar_RegisterVariable (&r_aliastransbase); + Cvar_RegisterVariable (&r_aliastransadj); + + Cvar_SetValue ("r_maxedges", (float)NUMSTACKEDGES); + Cvar_SetValue ("r_maxsurfs", (float)NUMSTACKSURFACES); + + view_clipplanes[0].leftedge = true; + view_clipplanes[1].rightedge = true; + view_clipplanes[1].leftedge = view_clipplanes[2].leftedge = + view_clipplanes[3].leftedge = false; + view_clipplanes[0].rightedge = view_clipplanes[2].rightedge = + view_clipplanes[3].rightedge = false; + + r_refdef.xOrigin = XCENTERING; + r_refdef.yOrigin = YCENTERING; + + R_InitParticles (); + +// TODO: collect 386-specific code in one place +#if id386 + Sys_MakeCodeWriteable ((long)R_EdgeCodeStart, + (long)R_EdgeCodeEnd - (long)R_EdgeCodeStart); +#endif // id386 + + D_Init (); +} + +/* +=============== +R_NewMap +=============== +*/ +void R_NewMap (void) +{ + int i; + +// clear out efrags in case the level hasn't been reloaded +// FIXME: is this one short? + for (i=0 ; inumleafs ; i++) + cl.worldmodel->leafs[i].efrags = NULL; + + r_viewleaf = NULL; + R_ClearParticles (); + + r_cnumsurfs = r_maxsurfs.value; + + if (r_cnumsurfs <= MINSURFACES) + r_cnumsurfs = MINSURFACES; + + if (r_cnumsurfs > NUMSTACKSURFACES) + { + surfaces = Hunk_AllocName (r_cnumsurfs * sizeof(surf_t), "surfaces"); + surface_p = surfaces; + surf_max = &surfaces[r_cnumsurfs]; + r_surfsonstack = false; + // surface 0 doesn't really exist; it's just a dummy because index 0 + // is used to indicate no edge attached to surface + surfaces--; + R_SurfacePatch (); + } + else + { + r_surfsonstack = true; + } + + r_maxedgesseen = 0; + r_maxsurfsseen = 0; + + r_numallocatededges = r_maxedges.value; + + if (r_numallocatededges < MINEDGES) + r_numallocatededges = MINEDGES; + + if (r_numallocatededges <= NUMSTACKEDGES) + { + auxedges = NULL; + } + else + { + auxedges = Hunk_AllocName (r_numallocatededges * sizeof(edge_t), + "edges"); + } + + r_dowarpold = false; + r_viewchanged = false; +#ifdef PASSAGES +CreatePassages (); +#endif +} + + +/* +=============== +R_SetVrect +=============== +*/ +void R_SetVrect (vrect_t *pvrectin, vrect_t *pvrect, int lineadj) +{ + int h; + float size; + + size = scr_viewsize.value > 100 ? 100 : scr_viewsize.value; + if (cl.intermission) + { + size = 100; + lineadj = 0; + } + size /= 100; + + h = pvrectin->height - lineadj; + pvrect->width = pvrectin->width * size; + if (pvrect->width < 96) + { + size = 96.0 / pvrectin->width; + pvrect->width = 96; // min for icons + } + pvrect->width &= ~7; + pvrect->height = pvrectin->height * size; + if (pvrect->height > pvrectin->height - lineadj) + pvrect->height = pvrectin->height - lineadj; + + pvrect->height &= ~1; + + pvrect->x = (pvrectin->width - pvrect->width)/2; + pvrect->y = (h - pvrect->height)/2; + + { + if (lcd_x.value) + { + pvrect->y >>= 1; + pvrect->height >>= 1; + } + } +} + + +/* +=============== +R_ViewChanged + +Called every time the vid structure or r_refdef changes. +Guaranteed to be called before the first refresh +=============== +*/ +void R_ViewChanged (vrect_t *pvrect, int lineadj, float aspect) +{ + int i; + float res_scale; + + r_viewchanged = true; + + R_SetVrect (pvrect, &r_refdef.vrect, lineadj); + + r_refdef.horizontalFieldOfView = 2.0 * tanf (r_refdef.fov_x/360*M_PI); + r_refdef.fvrectx = (float)r_refdef.vrect.x; + r_refdef.fvrectx_adj = (float)r_refdef.vrect.x - 0.5; + r_refdef.vrect_x_adj_shift20 = (r_refdef.vrect.x<<20) + (1<<19) - 1; + r_refdef.fvrecty = (float)r_refdef.vrect.y; + r_refdef.fvrecty_adj = (float)r_refdef.vrect.y - 0.5; + r_refdef.vrectright = r_refdef.vrect.x + r_refdef.vrect.width; + r_refdef.vrectright_adj_shift20 = (r_refdef.vrectright<<20) + (1<<19) - 1; + r_refdef.fvrectright = (float)r_refdef.vrectright; + r_refdef.fvrectright_adj = (float)r_refdef.vrectright - 0.5; + r_refdef.vrectrightedge = (float)r_refdef.vrectright - 0.99; + r_refdef.vrectbottom = r_refdef.vrect.y + r_refdef.vrect.height; + r_refdef.fvrectbottom = (float)r_refdef.vrectbottom; + r_refdef.fvrectbottom_adj = (float)r_refdef.vrectbottom - 0.5; + + r_refdef.aliasvrect.x = (int)(r_refdef.vrect.x * r_aliasuvscale); + r_refdef.aliasvrect.y = (int)(r_refdef.vrect.y * r_aliasuvscale); + r_refdef.aliasvrect.width = (int)(r_refdef.vrect.width * r_aliasuvscale); + r_refdef.aliasvrect.height = (int)(r_refdef.vrect.height * r_aliasuvscale); + r_refdef.aliasvrectright = r_refdef.aliasvrect.x + + r_refdef.aliasvrect.width; + r_refdef.aliasvrectbottom = r_refdef.aliasvrect.y + + r_refdef.aliasvrect.height; + + pixelAspect = aspect; + xOrigin = r_refdef.xOrigin; + yOrigin = r_refdef.yOrigin; + + screenAspect = r_refdef.vrect.width*pixelAspect / + r_refdef.vrect.height; +// 320*200 1.0 pixelAspect = 1.6 screenAspect +// 320*240 1.0 pixelAspect = 1.3333 screenAspect +// proper 320*200 pixelAspect = 0.8333333 + + verticalFieldOfView = r_refdef.horizontalFieldOfView / screenAspect; + +// values for perspective projection +// if math were exact, the values would range from 0.5 to to range+0.5 +// hopefully they wll be in the 0.000001 to range+.999999 and truncate +// the polygon rasterization will never render in the first row or column +// but will definately render in the [range] row and column, so adjust the +// buffer origin to get an exact edge to edge fill + xcenter = ((float)r_refdef.vrect.width * XCENTERING) + + r_refdef.vrect.x - 0.5; + aliasxcenter = xcenter * r_aliasuvscale; + ycenter = ((float)r_refdef.vrect.height * YCENTERING) + + r_refdef.vrect.y - 0.5; + aliasycenter = ycenter * r_aliasuvscale; + + xscale = r_refdef.vrect.width / r_refdef.horizontalFieldOfView; + aliasxscale = xscale * r_aliasuvscale; + xscaleinv = 1.0 / xscale; + yscale = xscale * pixelAspect; + aliasyscale = yscale * r_aliasuvscale; + yscaleinv = 1.0 / yscale; + xscaleshrink = (r_refdef.vrect.width-6)/r_refdef.horizontalFieldOfView; + yscaleshrink = xscaleshrink*pixelAspect; + +// left side clip + screenedge[0].normal[0] = -1.0 / (xOrigin*r_refdef.horizontalFieldOfView); + screenedge[0].normal[1] = 0; + screenedge[0].normal[2] = 1; + screenedge[0].type = PLANE_ANYZ; + +// right side clip + screenedge[1].normal[0] = + 1.0 / ((1.0-xOrigin)*r_refdef.horizontalFieldOfView); + screenedge[1].normal[1] = 0; + screenedge[1].normal[2] = 1; + screenedge[1].type = PLANE_ANYZ; + +// top side clip + screenedge[2].normal[0] = 0; + screenedge[2].normal[1] = -1.0 / (yOrigin*verticalFieldOfView); + screenedge[2].normal[2] = 1; + screenedge[2].type = PLANE_ANYZ; + +// bottom side clip + screenedge[3].normal[0] = 0; + screenedge[3].normal[1] = 1.0 / ((1.0-yOrigin)*verticalFieldOfView); + screenedge[3].normal[2] = 1; + screenedge[3].type = PLANE_ANYZ; + + for (i=0 ; i<4 ; i++) + VectorNormalize (screenedge[i].normal); + + res_scale = sqrtf ((float)(r_refdef.vrect.width * r_refdef.vrect.height) / + (320.0 * 152.0)) * + (2.0 / r_refdef.horizontalFieldOfView); + r_aliastransition = r_aliastransbase.value * res_scale; + r_resfudge = r_aliastransadj.value * res_scale; + + if (scr_fov.value <= 90.0) + r_fov_greater_than_90 = false; + else + r_fov_greater_than_90 = true; + +// TODO: collect 386-specific code in one place +#if id386 + if (r_pixbytes == 1) + { + Sys_MakeCodeWriteable ((long)R_Surf8Start, + (long)R_Surf8End - (long)R_Surf8Start); + colormap = vid.colormap; + R_Surf8Patch (); + } + else + { + Sys_MakeCodeWriteable ((long)R_Surf16Start, + (long)R_Surf16End - (long)R_Surf16Start); + colormap = vid.colormap16; + R_Surf16Patch (); + } +#endif // id386 + + D_ViewChanged (); +} + + +/* +=============== +R_MarkLeaves +=============== +*/ +void R_MarkLeaves (void) +{ + byte *vis; + mnode_t *node; + int i; + + if (r_oldviewleaf == r_viewleaf) + return; + + r_visframecount++; + r_oldviewleaf = r_viewleaf; + + vis = Mod_LeafPVS (r_viewleaf, cl.worldmodel); + + for (i=0 ; inumleafs ; i++) + { + if (vis[i>>3] & (1<<(i&7))) + { + node = (mnode_t *)&cl.worldmodel->leafs[i+1]; + do + { + if (node->visframe == r_visframecount) + break; + node->visframe = r_visframecount; + node = node->parent; + } while (node); + } + } +} + + +/* +============= +R_DrawEntitiesOnList +============= +*/ +void R_DrawEntitiesOnList (void) +{ + int i, j; + int lnum; + alight_t lighting; +// FIXME: remove and do real lighting + float lightvec[3] = {-1, 0, 0}; + vec3_t dist; + float add; + + if (!r_drawentities.value) + return; + + for (i=0 ; imodel->type) + { + case mod_sprite: + VectorCopy (currententity->origin, r_entorigin); + VectorSubtract (r_origin, r_entorigin, modelorg); + R_DrawSprite (); + break; + + case mod_alias: + VectorCopy (currententity->origin, r_entorigin); + VectorSubtract (r_origin, r_entorigin, modelorg); + + // see if the bounding box lets us trivially reject, also sets + // trivial accept status + if (R_AliasCheckBBox ()) + { + j = R_LightPoint (currententity->origin); + + lighting.ambientlight = j; + lighting.shadelight = j; + + lighting.plightvec = lightvec; + + for (lnum=0 ; lnum= cl.time) + { + VectorSubtract (currententity->origin, + cl_dlights[lnum].origin, + dist); + add = cl_dlights[lnum].radius - Length(dist); + + if (add > 0) + lighting.ambientlight += add; + } + } + + // clamp lighting so it doesn't overbright as much + if (lighting.ambientlight > 128) + lighting.ambientlight = 128; + if (lighting.ambientlight + lighting.shadelight > 192) + lighting.shadelight = 192 - lighting.ambientlight; + + R_AliasDrawModel (&lighting); + } + + break; + + default: + break; + } + } +} + +/* +============= +R_DrawViewModel +============= +*/ +void R_DrawViewModel (void) +{ +// FIXME: remove and do real lighting + float lightvec[3] = {-1, 0, 0}; + int j; + int lnum; + vec3_t dist; + float add; + dlight_t *dl; + + if (!r_drawviewmodel.value || r_fov_greater_than_90) + return; + + if (cl.items & IT_INVISIBILITY) + return; + + if (cl.stats[STAT_HEALTH] <= 0) + return; + + currententity = &cl.viewent; + if (!currententity->model) + return; + + VectorCopy (currententity->origin, r_entorigin); + VectorSubtract (r_origin, r_entorigin, modelorg); + + VectorCopy (vup, viewlightvec); + VectorInverse (viewlightvec); + + j = R_LightPoint (currententity->origin); + + if (j < 24) + j = 24; // allways give some light on gun + r_viewlighting.ambientlight = j; + r_viewlighting.shadelight = j; + +// add dynamic lights + for (lnum=0 ; lnumradius) + continue; + if (!dl->radius) + continue; + if (dl->die < cl.time) + continue; + + VectorSubtract (currententity->origin, dl->origin, dist); + add = dl->radius - Length(dist); + if (add > 0) + r_viewlighting.ambientlight += add; + } + +// clamp lighting so it doesn't overbright as much + if (r_viewlighting.ambientlight > 128) + r_viewlighting.ambientlight = 128; + if (r_viewlighting.ambientlight + r_viewlighting.shadelight > 192) + r_viewlighting.shadelight = 192 - r_viewlighting.ambientlight; + + r_viewlighting.plightvec = lightvec; + +#ifdef QUAKE2 + cl.light_level = r_viewlighting.ambientlight; +#endif + + R_AliasDrawModel (&r_viewlighting); +} + + +/* +============= +R_BmodelCheckBBox +============= +*/ +int R_BmodelCheckBBox (model_t *clmodel, float *minmaxs) +{ + int i, *pindex, clipflags; + vec3_t acceptpt, rejectpt; + float d; + + clipflags = 0; + + if (currententity->angles[0] || currententity->angles[1] + || currententity->angles[2]) + { + for (i=0 ; i<4 ; i++) + { + d = DotProduct (currententity->origin, view_clipplanes[i].normal); + d -= view_clipplanes[i].dist; + + if (d <= -clmodel->radius) + return BMODEL_FULLY_CLIPPED; + + if (d <= clmodel->radius) + clipflags |= (1<model->type) + { + case mod_brush: + + clmodel = currententity->model; + + // see if the bounding box lets us trivially reject, also sets + // trivial accept status + for (j=0 ; j<3 ; j++) + { + minmaxs[j] = currententity->origin[j] + + clmodel->mins[j]; + minmaxs[3+j] = currententity->origin[j] + + clmodel->maxs[j]; + } + + clipflags = R_BmodelCheckBBox (clmodel, minmaxs); + + if (clipflags != BMODEL_FULLY_CLIPPED) + { + VectorCopy (currententity->origin, r_entorigin); + VectorSubtract (r_origin, r_entorigin, modelorg); + // FIXME: is this needed? + VectorCopy (modelorg, r_worldmodelorg); + + r_pcurrentvertbase = clmodel->vertexes; + + // FIXME: stop transforming twice + R_RotateBmodel (); + + // calculate dynamic lighting for bmodel if it's not an + // instanced model + if (clmodel->firstmodelsurface != 0) + { + for (k=0 ; knodes + clmodel->hulls[0].firstclipnode); + } + } + + // if the driver wants polygons, deliver those. Z-buffering is on + // at this point, so no clipping to the world tree is needed, just + // frustum clipping + if (r_drawpolys | r_drawculledpolys) + { + R_ZDrawSubmodelPolys (clmodel); + } + else + { + r_pefragtopnode = NULL; + + for (j=0 ; j<3 ; j++) + { + r_emins[j] = minmaxs[j]; + r_emaxs[j] = minmaxs[3+j]; + } + + R_SplitEntityOnNode2 (cl.worldmodel->nodes); + + if (r_pefragtopnode) + { + currententity->topnode = r_pefragtopnode; + + if (r_pefragtopnode->contents >= 0) + { + // not a leaf; has to be clipped to the world BSP + r_clipflags = clipflags; + R_DrawSolidClippedSubmodelPolygons (clmodel); + } + else + { + // falls entirely in one leaf, so we just put all the + // edges in the edge list and let 1/z sorting handle + // drawing order + R_DrawSubmodelPolygons (clmodel, clipflags); + } + + currententity->topnode = NULL; + } + } + + // put back world rotation and frustum clipping + // FIXME: R_RotateBmodel should just work off base_vxx + VectorCopy (base_vpn, vpn); + VectorCopy (base_vup, vup); + VectorCopy (base_vright, vright); + VectorCopy (base_modelorg, modelorg); + VectorCopy (oldorigin, modelorg); + R_TransformFrustum (); + } + + break; + + default: + break; + } + } + + insubmodel = false; +} + + +/* +================ +R_EdgeDrawing +================ +*/ +void R_EdgeDrawing (void) +{ + edge_t ledges[NUMSTACKEDGES + + ((CACHE_SIZE - 1) / sizeof(edge_t)) + 1]; + surf_t lsurfs[NUMSTACKSURFACES + + ((CACHE_SIZE - 1) / sizeof(surf_t)) + 1]; + + if (auxedges) + { + r_edges = auxedges; + } + else + { + r_edges = (edge_t *) + (((long)&ledges[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + } + + if (r_surfsonstack) + { + surfaces = (surf_t *) + (((long)&lsurfs[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + surf_max = &surfaces[r_cnumsurfs]; + // surface 0 doesn't really exist; it's just a dummy because index 0 + // is used to indicate no edge attached to surface + surfaces--; + R_SurfacePatch (); + } + + R_BeginEdgeFrame (); + + if (r_dspeeds.value) + { + rw_time1 = Sys_FloatTime (); + } + + R_RenderWorld (); + + if (r_drawculledpolys) + R_ScanEdges (); + +// only the world can be drawn back to front with no z reads or compares, just +// z writes, so have the driver turn z compares on now + D_TurnZOn (); + + if (r_dspeeds.value) + { + rw_time2 = Sys_FloatTime (); + db_time1 = rw_time2; + } + + R_DrawBEntitiesOnList (); + + if (r_dspeeds.value) + { + db_time2 = Sys_FloatTime (); + se_time1 = db_time2; + } + + if (!r_dspeeds.value) + { + VID_UnlockBuffer (); + S_ExtraUpdate (); // don't let sound get messed up if going slow + VID_LockBuffer (); + } + + if (!(r_drawpolys | r_drawculledpolys)) + R_ScanEdges (); +} + + +/* +================ +R_RenderView + +r_refdef must be set before the first call +================ +*/ +void R_RenderView_ (void) +{ + byte warpbuffer[WARP_WIDTH * WARP_HEIGHT]; + + r_warpbuffer = warpbuffer; + + if (r_timegraph.value || r_speeds.value || r_dspeeds.value) + r_time1 = Sys_FloatTime (); + + R_SetupFrame (); + +#ifdef PASSAGES +SetVisibilityByPassages (); +#else + R_MarkLeaves (); // done here so we know if we're in water +#endif + +// make FDIV fast. This reduces timing precision after we've been running for a +// while, so we don't do it globally. This also sets chop mode, and we do it +// here so that setup stuff like the refresh area calculations match what's +// done in screen.c + Sys_LowFPPrecision (); + + if (!cl_entities[0].model || !cl.worldmodel) + Sys_Error ("R_RenderView: NULL worldmodel"); + + if (!r_dspeeds.value) + { + VID_UnlockBuffer (); + S_ExtraUpdate (); // don't let sound get messed up if going slow + VID_LockBuffer (); + } + + R_EdgeDrawing (); + + if (!r_dspeeds.value) + { + VID_UnlockBuffer (); + S_ExtraUpdate (); // don't let sound get messed up if going slow + VID_LockBuffer (); + } + + if (r_dspeeds.value) + { + se_time2 = Sys_FloatTime (); + de_time1 = se_time2; + } + + R_DrawEntitiesOnList (); + + if (r_dspeeds.value) + { + de_time2 = Sys_FloatTime (); + dv_time1 = de_time2; + } + + R_DrawViewModel (); + + if (r_dspeeds.value) + { + dv_time2 = Sys_FloatTime (); + dp_time1 = Sys_FloatTime (); + } + + R_DrawParticles (); + + if (r_dspeeds.value) + dp_time2 = Sys_FloatTime (); + + if (r_dowarp) + D_WarpScreen (); + + V_SetContentsColor (r_viewleaf->contents); + + if (r_timegraph.value) + R_TimeGraph (); + + if (r_aliasstats.value) + R_PrintAliasStats (); + + if (r_speeds.value) + R_PrintTimes (); + + if (r_dspeeds.value) + R_PrintDSpeeds (); + + if (r_reportsurfout.value && r_outofsurfaces) + Con_Printf ("Short %d surfaces\n", r_outofsurfaces); + + if (r_reportedgeout.value && r_outofedges) + Con_Printf ("Short roughly %d edges\n", r_outofedges * 2 / 3); + +// back to high floating-point precision + Sys_HighFPPrecision (); +} + +void R_RenderView (void) +{ + int dummy; + int delta; + + delta = (byte *)&dummy - r_stack_start; + if (delta < -10000 || delta > 10000) + Sys_Error ("R_RenderView: called without enough stack"); + + if ( Hunk_LowMark() & 3 ) + Sys_Error ("Hunk is missaligned"); + + if ( (long)(&dummy) & 3 ) + Sys_Error ("Stack is missaligned"); + + if ( (long)(&r_warpbuffer) & 3 ) + Sys_Error ("Globals are missaligned"); + + R_RenderView_ (); +} + +/* +================ +R_InitTurb +================ +*/ +void R_InitTurb (void) +{ + int i; + + for (i=0 ; i<(SIN_BUFFER_SIZE) ; i++) + { + sintable[i] = AMP + sinf(i*3.14159*2/CYCLE)*AMP; + intsintable[i] = AMP2 + sinf(i*3.14159*2/CYCLE)*AMP2; // AMP2, not 20 + } +} + diff --git a/r17/Revamped src/revamped_src/r_misc.c b/r17/Revamped src/revamped_src/r_misc.c new file mode 100755 index 00000000..12a136c5 --- /dev/null +++ b/r17/Revamped src/revamped_src/r_misc.c @@ -0,0 +1,527 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// r_misc.c + +#include "quakedef.h" +#include "r_local.h" + + +/* +=============== +R_CheckVariables +=============== +*/ +void R_CheckVariables (void) +{ + static float oldbright; + + if (r_fullbright.value != oldbright) + { + oldbright = r_fullbright.value; + D_FlushCaches (); // so all lighting changes + } +} + + +/* +============ +Show + +Debugging use +============ +*/ +void Show (void) +{ + vrect_t vr; + + vr.x = vr.y = 0; + vr.width = vid.width; + vr.height = vid.height; + vr.pnext = NULL; + VID_Update (&vr); +} + + +/* +==================== +R_TimeRefresh_f + +For program optimization +==================== +*/ +void R_TimeRefresh_f (void) +{ + int i; + double start, stop, time; + int startangle; + vrect_t vr; + +#ifdef PSP_SOFTWARE_VIDEO + startangle = r_refdef.viewangles[1]; + + start = Sys_FloatTime (); + for (i=0 ; i<128 ; i++) + { + r_refdef.viewangles[1] = i/128.0*360.0; + + VID_LockBuffer (); + + R_RenderView (); + + VID_UnlockBuffer (); + + vr.x = r_refdef.vrect.x; + vr.y = r_refdef.vrect.y; + vr.width = r_refdef.vrect.width; + vr.height = r_refdef.vrect.height; + vr.pnext = NULL; + VID_Update (&vr); + } + stop = Sys_FloatTime (); + time = stop-start; + Con_Printf ("%f seconds (%f fps)\n", time, 128/time); + + r_refdef.viewangles[1] = startangle; +#else + Con_Printf ("Sorry: 'timerefresh' command disabled\n"); +#endif +} + + +/* +================ +R_LineGraph + +Only called by R_DisplayTime +================ +*/ +void R_LineGraph (int x, int y, int h) +{ + int i; + byte *dest; + int s; + +// FIXME: should be disabled on no-buffer adapters, or should be in the driver + + x += r_refdef.vrect.x; + y += r_refdef.vrect.y; + + dest = vid.buffer + vid.rowbytes*y + x; + + s = r_graphheight.value; + + if (h>s) + h = s; + + for (i=0 ; inormal); + *dist = p->dist - d; +// TODO: when we have rotating entities, this will need to use the view matrix + TransformVector (p->normal, normal); +} + + +/* +=============== +R_SetUpFrustumIndexes +=============== +*/ +void R_SetUpFrustumIndexes (void) +{ + int i, j, *pindex; + + pindex = r_frustum_indexes; + + for (i=0 ; i<4 ; i++) + { + for (j=0 ; j<3 ; j++) + { + if (view_clipplanes[i].normal[j] < 0) + { + pindex[j] = j; + pindex[j+3] = j+3; + } + else + { + pindex[j] = j+3; + pindex[j+3] = j; + } + } + + // FIXME: do just once at start + pfrustum_indexes[i] = pindex; + pindex += 6; + } +} + + +/* +=============== +R_SetupFrame +=============== +*/ +void R_SetupFrame (void) +{ + int edgecount; + vrect_t vrect; + float w, h; + +// don't allow cheats in multiplayer + if (cl.maxclients > 1) + { + Cvar_Set ("r_draworder", "0"); + Cvar_Set ("r_fullbright", "0"); + Cvar_Set ("r_ambient", "0"); + Cvar_Set ("r_drawflat", "0"); + } + + if (r_numsurfs.value) + { + if ((surface_p - surfaces) > r_maxsurfsseen) + r_maxsurfsseen = surface_p - surfaces; + + Con_Printf ("Used %d of %d surfs; %d max\n", surface_p - surfaces, + surf_max - surfaces, r_maxsurfsseen); + } + + if (r_numedges.value) + { + edgecount = edge_p - r_edges; + + if (edgecount > r_maxedgesseen) + r_maxedgesseen = edgecount; + + Con_Printf ("Used %d of %d edges; %d max\n", edgecount, + r_numallocatededges, r_maxedgesseen); + } + + r_refdef.ambientlight = r_ambient.value; + + if (r_refdef.ambientlight < 0) + r_refdef.ambientlight = 0; + + if (!sv.active) + r_draworder.value = 0; // don't let cheaters look behind walls + + R_CheckVariables (); + + R_AnimateLight (); + + r_framecount++; + + numbtofpolys = 0; + +// debugging +#if 0 +r_refdef.vieworg[0]= 80; +r_refdef.vieworg[1]= 64; +r_refdef.vieworg[2]= 40; +r_refdef.viewangles[0]= 0; +r_refdef.viewangles[1]= 46.763641357; +r_refdef.viewangles[2]= 0; +#endif + +// build the transformation matrix for the given view angles + VectorCopy (r_refdef.vieworg, modelorg); + VectorCopy (r_refdef.vieworg, r_origin); + + AngleVectors (r_refdef.viewangles, vpn, vright, vup); + +// current viewleaf + r_oldviewleaf = r_viewleaf; + r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel); + + r_dowarpold = r_dowarp; + r_dowarp = r_waterwarp.value && (r_viewleaf->contents <= CONTENTS_WATER); + + if ((r_dowarp != r_dowarpold) || r_viewchanged || lcd_x.value) + { + if (r_dowarp) + { + if ((vid.width <= vid.maxwarpwidth) && + (vid.height <= vid.maxwarpheight)) + { + vrect.x = 0; + vrect.y = 0; + vrect.width = vid.width; + vrect.height = vid.height; + + R_ViewChanged (&vrect, sb_lines, vid.aspect); + } + else + { + w = vid.width; + h = vid.height; + + if (w > vid.maxwarpwidth) + { + h *= (float)vid.maxwarpwidth / w; + w = vid.maxwarpwidth; + } + + if (h > vid.maxwarpheight) + { + h = vid.maxwarpheight; + w *= (float)vid.maxwarpheight / h; + } + + vrect.x = 0; + vrect.y = 0; + vrect.width = (int)w; + vrect.height = (int)h; + + R_ViewChanged (&vrect, + (int)((float)sb_lines * (h/(float)vid.height)), + vid.aspect * (h / w) * + ((float)vid.width / (float)vid.height)); + } + } + else + { + vrect.x = 0; + vrect.y = 0; + vrect.width = vid.width; + vrect.height = vid.height; + + R_ViewChanged (&vrect, sb_lines, vid.aspect); + } + + r_viewchanged = false; + } + +// start off with just the four screen edge clip planes + R_TransformFrustum (); + +// save base values + VectorCopy (vpn, base_vpn); + VectorCopy (vright, base_vright); + VectorCopy (vup, base_vup); + VectorCopy (modelorg, base_modelorg); + + R_SetSkyFrame (); + + R_SetUpFrustumIndexes (); + + r_cache_thrash = false; + +// clear frame counts + c_faceclip = 0; + d_spanpixcount = 0; + r_polycount = 0; + r_drawnpolycount = 0; + r_wholepolycount = 0; + r_amodels_drawn = 0; + r_outofsurfaces = 0; + r_outofedges = 0; + + D_SetupFrame (); +} + diff --git a/r17/Revamped src/revamped_src/r_part.c b/r17/Revamped src/revamped_src/r_part.c new file mode 100755 index 00000000..c57d9c97 --- /dev/null +++ b/r17/Revamped src/revamped_src/r_part.c @@ -0,0 +1,821 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +#include "quakedef.h" +#include "r_local.h" + +#define MAX_PARTICLES 1024 // default max # of particles at one + // time +#define ABSOLUTE_MIN_PARTICLES 512 // no fewer than this no matter what's + // on the command line + +int ramp1[8] = {0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61}; +int ramp2[8] = {0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66}; +int ramp3[8] = {0x6d, 0x6b, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01}; + +particle_t *active_particles, *free_particles; + +particle_t *particles; +int r_numparticles; + +vec3_t r_pright, r_pup, r_ppn; + + +/* +=============== +R_InitParticles +=============== +*/ +void R_InitParticles (void) +{ + int i; + + i = COM_CheckParm ("-particles"); + + if (i) + { + r_numparticles = (int)(Q_atoi(com_argv[i+1])); + if (r_numparticles < ABSOLUTE_MIN_PARTICLES) + r_numparticles = ABSOLUTE_MIN_PARTICLES; + } + else + { + r_numparticles = MAX_PARTICLES; + } + + particles = (particle_t *) + Hunk_AllocName (r_numparticles * sizeof(particle_t), "particles"); +} + +#ifdef QUAKE2 +void R_DarkFieldParticles (entity_t *ent) +{ + int i, j, k; + particle_t *p; + float vel; + vec3_t dir; + vec3_t org; + + org[0] = ent->origin[0]; + org[1] = ent->origin[1]; + org[2] = ent->origin[2]; + for (i=-16 ; i<16 ; i+=8) + for (j=-16 ; j<16 ; j+=8) + for (k=0 ; k<32 ; k+=8) + { + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + + p->die = cl.time + 0.2 + (rand()&7) * 0.02; + p->color = 150 + rand()%6; + p->type = pt_slowgrav; + + dir[0] = j*8; + dir[1] = i*8; + dir[2] = k*8; + + p->org[0] = org[0] + i + (rand()&3); + p->org[1] = org[1] + j + (rand()&3); + p->org[2] = org[2] + k + (rand()&3); + + VectorNormalize (dir); + vel = 50 + (rand()&63); + VectorScale (dir, vel, p->vel); + } +} +#endif + + +/* +=============== +R_EntityParticles +=============== +*/ + +#define NUMVERTEXNORMALS 162 +extern float r_avertexnormals[NUMVERTEXNORMALS][3]; +vec3_t avelocities[NUMVERTEXNORMALS]; +float beamlength = 16; +vec3_t avelocity = {23, 7, 3}; +float partstep = 0.01; +float timescale = 0.01; + +void R_EntityParticles (entity_t *ent) +{ + int count; + int i; + particle_t *p; + float angle; + float sr, sp, sy, cr, cp, cy; + vec3_t forward; + float dist; + + dist = 64; + count = 25; //50; + +if (!avelocities[0][0]) +{ +for (i=0 ; inext; + p->next = active_particles; + active_particles = p; + + p->die = cl.time + 0.01; + p->color = 0x6f; + p->type = pt_explode; + + p->org[0] = ent->origin[0] + r_avertexnormals[i][0]*dist + forward[0]*beamlength; + p->org[1] = ent->origin[1] + r_avertexnormals[i][1]*dist + forward[1]*beamlength; + p->org[2] = ent->origin[2] + r_avertexnormals[i][2]*dist + forward[2]*beamlength; + } +} + + +/* +=============== +R_ClearParticles +=============== +*/ +void R_ClearParticles (void) +{ + int i; + + free_particles = &particles[0]; + active_particles = NULL; + + for (i=0 ;i= (sizeof(line) - 2)) + { + Sys_Error("Line buffer overflow when reading point file"); + } + + if (!Sys_FileRead(f, &line[chars++], 1) != 1) + { + break; + } + } + while (line[chars - 1] != '\n'); + line[chars] = '\0'; + + r = sscanf (line, "%f %f %f\n", &org[0], &org[1], &org[2]); + if (r != 3) + break; + c++; + + if (!free_particles) + { + Con_Printf ("Not enough free particles\n"); + break; + } + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + + p->die = 99999; + p->color = (-c)&15; + p->type = pt_static; + VectorCopy (vec3_origin, p->vel); + VectorCopy (org, p->org); + } + + Sys_FileClose(f); + Con_Printf ("%i points read\n", c); +} + +/* +=============== +R_ParseParticleEffect + +Parse an effect out of the server message +=============== +*/ +void R_ParseParticleEffect (void) +{ + vec3_t org, dir; + int i, count, msgcount, color; + + for (i=0 ; i<3 ; i++) + org[i] = MSG_ReadCoord (); + for (i=0 ; i<3 ; i++) + dir[i] = MSG_ReadChar () * (1.0/16); + msgcount = MSG_ReadByte (); + color = MSG_ReadByte (); + +if (msgcount == 255) + count = 1024; +else + count = msgcount; + + R_RunParticleEffect (org, dir, color, count); +} + +/* +=============== +R_ParticleExplosion + +=============== +*/ +void R_ParticleExplosion (vec3_t org) +{ + int i, j; + particle_t *p; + + for (i=0 ; i<1024 ; i++) + { + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + + p->die = cl.time + 5; + p->color = ramp1[0]; + p->ramp = rand()&3; + if (i & 1) + { + p->type = pt_explode; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } + else + { + p->type = pt_explode2; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } + } +} + +/* +=============== +R_ParticleExplosion2 + +=============== +*/ +void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength) +{ + int i, j; + particle_t *p; + int colorMod = 0; + + for (i=0; i<512; i++) + { + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + + p->die = cl.time + 0.3; + p->color = colorStart + (colorMod % colorLength); + colorMod++; + + p->type = pt_blob; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } +} + +/* +=============== +R_BlobExplosion + +=============== +*/ +void R_BlobExplosion (vec3_t org) +{ + int i, j; + particle_t *p; + + for (i=0 ; i<1024 ; i++) + { + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + + p->die = cl.time + 1 + (rand()&8)*0.05; + + if (i & 1) + { + p->type = pt_blob; + p->color = 66 + rand()%6; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } + else + { + p->type = pt_blob2; + p->color = 150 + rand()%6; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } + } +} + +/* +=============== +R_RunParticleEffect + +=============== +*/ +void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count) +{ + int i, j; + particle_t *p; + + for (i=0 ; inext; + p->next = active_particles; + active_particles = p; + + if (count == 1024) + { // rocket explosion + p->die = cl.time + 5; + p->color = ramp1[0]; + p->ramp = rand()&3; + if (i & 1) + { + p->type = pt_explode; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } + else + { + p->type = pt_explode2; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } + } + else + { + p->die = cl.time + 0.1*(rand()%5); + p->color = (color&~7) + (rand()&7); + p->type = pt_slowgrav; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()&15)-8); + p->vel[j] = dir[j]*15;// + (rand()%300)-150; + } + } + } +} + + +/* +=============== +R_LavaSplash + +=============== +*/ +void R_LavaSplash (vec3_t org) +{ + int i, j, k; + particle_t *p; + float vel; + vec3_t dir; + + for (i=-16 ; i<16 ; i++) + for (j=-16 ; j<16 ; j++) + for (k=0 ; k<1 ; k++) + { + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + + p->die = cl.time + 2 + (rand()&31) * 0.02; + p->color = 224 + (rand()&7); + p->type = pt_slowgrav; + + dir[0] = j*8 + (rand()&7); + dir[1] = i*8 + (rand()&7); + dir[2] = 256; + + p->org[0] = org[0] + dir[0]; + p->org[1] = org[1] + dir[1]; + p->org[2] = org[2] + (rand()&63); + + VectorNormalize (dir); + vel = 50 + (rand()&63); + VectorScale (dir, vel, p->vel); + } +} + +/* +=============== +R_TeleportSplash + +=============== +*/ +void R_TeleportSplash (vec3_t org) +{ + int i, j, k; + particle_t *p; + float vel; + vec3_t dir; + + for (i=-16 ; i<16 ; i+=4) + for (j=-16 ; j<16 ; j+=4) + for (k=-24 ; k<32 ; k+=4) + { + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + + p->die = cl.time + 0.2 + (rand()&7) * 0.02; + p->color = 7 + (rand()&7); + p->type = pt_slowgrav; + + dir[0] = j*8; + dir[1] = i*8; + dir[2] = k*8; + + p->org[0] = org[0] + i + (rand()&3); + p->org[1] = org[1] + j + (rand()&3); + p->org[2] = org[2] + k + (rand()&3); + + VectorNormalize (dir); + vel = 50 + (rand()&63); + VectorScale (dir, vel, p->vel); + } +} + +void R_RocketTrail (vec3_t start, vec3_t end, int type) +{ + vec3_t vec; + float len; + int j; + particle_t *p; + int dec; + static int tracercount; + + VectorSubtract (end, start, vec); + len = VectorNormalize (vec); + if (type < 128) + dec = 3; + else + { + dec = 1; + type -= 128; + } + + while (len > 0) + { + len -= dec; + + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + + VectorCopy (vec3_origin, p->vel); + p->die = cl.time + 2; + + switch (type) + { + case 0: // rocket trail + p->ramp = (rand()&3); + p->color = ramp3[(int)p->ramp]; + p->type = pt_fire; + for (j=0 ; j<3 ; j++) + p->org[j] = start[j] + ((rand()%6)-3); + break; + + case 1: // smoke smoke + p->ramp = (rand()&3) + 2; + p->color = ramp3[(int)p->ramp]; + p->type = pt_fire; + for (j=0 ; j<3 ; j++) + p->org[j] = start[j] + ((rand()%6)-3); + break; + + case 2: // blood + p->type = pt_grav; + p->color = 67 + (rand()&3); + for (j=0 ; j<3 ; j++) + p->org[j] = start[j] + ((rand()%6)-3); + break; + + case 3: + case 5: // tracer + p->die = cl.time + 0.5; + p->type = pt_static; + if (type == 3) + p->color = 52 + ((tracercount&4)<<1); + else + p->color = 230 + ((tracercount&4)<<1); + + tracercount++; + + VectorCopy (start, p->org); + if (tracercount & 1) + { + p->vel[0] = 30*vec[1]; + p->vel[1] = 30*-vec[0]; + } + else + { + p->vel[0] = 30*-vec[1]; + p->vel[1] = 30*vec[0]; + } + break; + + case 4: // slight blood + p->type = pt_grav; + p->color = 67 + (rand()&3); + for (j=0 ; j<3 ; j++) + p->org[j] = start[j] + ((rand()%6)-3); + len -= 3; + break; + + case 6: // voor trail + p->color = 9*16 + 8 + (rand()&3); + p->type = pt_static; + p->die = cl.time + 0.3; + for (j=0 ; j<3 ; j++) + p->org[j] = start[j] + ((rand()&15)-8); + break; + } + + + VectorAdd (start, vec, start); + } +} + + +/* +=============== +R_DrawParticles +=============== +*/ +extern cvar_t sv_gravity; + +#define PART_BUFFER_SIZE 1024 + +void R_DrawParticles (void) +{ + particle_t *p, *kill; + float grav; + int i; + float time2, time3; + float time1; + float dvel; + float frametime; + vec3_t up, right; + float scale; + +#ifdef PSP_HARDWARE_VIDEO + + int part_buffer_size = PART_BUFFER_SIZE; + psp_particle* part_buffer = NULL; + part_buffer = D_CreateBuffer(part_buffer_size); + + VectorScale (vup, 1.25, up); + VectorScale (vright, 1.25, right); +#endif + D_StartParticles (); + + #ifdef PSP_HARDWARE_VIDEO + //VectorScale (vright, xscaleshrink, r_pright); + //VectorScale (vup, yscaleshrink, r_pup); + //VectorCopy (vright, r_pright); + //VectorCopy (vup, r_pup); + #else + VectorScale (vright, xscaleshrink, r_pright); + VectorScale (vup, yscaleshrink, r_pup); + #endif + VectorCopy (vpn, r_ppn); + + frametime = cl.time - cl.oldtime; + time3 = frametime * 15; + time2 = frametime * 10; // 15; + time1 = frametime * 5; + grav = frametime * sv_gravity.value * 0.05; + dvel = 4*frametime; + + for ( ;; ) + { + kill = active_particles; + if (kill && kill->die < cl.time) + { + active_particles = kill->next; + kill->next = free_particles; + free_particles = kill; + continue; + } + break; + } + + for (p=active_particles ; p ; p=p->next) + { + for ( ;; ) + { + kill = p->next; + if (kill && kill->die < cl.time) + { + p->next = kill->next; + kill->next = free_particles; + free_particles = kill; + continue; + } + break; + } + +#ifdef PSP_HARDWARE_VIDEO + // hack a scale up to keep particles from disapearing + scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] + + (p->org[2] - r_origin[2])*vpn[2]; + if (scale < 20) + scale = 1; + else + scale = 1 + scale * 0.004; + + // D_DrawParticle (p, up, right, scale); + int rv = D_DrawParticleBuffered(part_buffer,p, up, right, scale); + if (rv == -1) + part_buffer = D_CreateBuffer(part_buffer_size); + +#else + D_DrawParticle (p); +#endif + p->org[0] += p->vel[0]*frametime; + p->org[1] += p->vel[1]*frametime; + p->org[2] += p->vel[2]*frametime; + + switch (p->type) + { + case pt_static: + break; + case pt_fire: + p->ramp += time1; + if (p->ramp >= 6) + p->die = -1; + else + p->color = ramp3[(int)p->ramp]; + p->vel[2] += grav; + break; + + case pt_explode: + p->ramp += time2; + if (p->ramp >=8) + p->die = -1; + else + p->color = ramp1[(int)p->ramp]; + for (i=0 ; i<3 ; i++) + p->vel[i] += p->vel[i]*dvel; + p->vel[2] -= grav; + break; + + case pt_explode2: + p->ramp += time3; + if (p->ramp >=8) + p->die = -1; + else + p->color = ramp2[(int)p->ramp]; + for (i=0 ; i<3 ; i++) + p->vel[i] -= p->vel[i]*frametime; + p->vel[2] -= grav; + break; + + case pt_blob: + for (i=0 ; i<3 ; i++) + p->vel[i] += p->vel[i]*dvel; + p->vel[2] -= grav; + break; + + case pt_blob2: + for (i=0 ; i<2 ; i++) + p->vel[i] -= p->vel[i]*dvel; + p->vel[2] -= grav; + break; + + case pt_grav: +#ifdef QUAKE2 + p->vel[2] -= grav * 20; + break; +#endif + case pt_slowgrav: + p->vel[2] -= grav; + break; + } + } +#ifdef PSP_HARDWARE_VIDEO + D_DeleteBuffer(part_buffer); +#endif + D_EndParticles (); +} + diff --git a/r17/Revamped src/revamped_src/r_shared.h b/r17/Revamped src/revamped_src/r_shared.h new file mode 100755 index 00000000..4d146274 --- /dev/null +++ b/r17/Revamped src/revamped_src/r_shared.h @@ -0,0 +1,157 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +#if !defined(GLQUAKE) && !defined(PSP_HARDWARE_VIDEO) +// r_shared.h: general refresh-related stuff shared between the refresh and the +// driver + +// FIXME: clean up and move into d_iface.h + +#ifndef _R_SHARED_H_ +#define _R_SHARED_H_ + +#define MAXVERTS 16 // max points in a surface polygon +#define MAXWORKINGVERTS (MAXVERTS+4) // max points in an intermediate + // polygon (while processing) +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +#define MAXHEIGHT 1024 +#define MAXWIDTH 1280 +#define MAXDIMENSION ((MAXHEIGHT > MAXWIDTH) ? MAXHEIGHT : MAXWIDTH) + +#define SIN_BUFFER_SIZE (MAXDIMENSION+CYCLE) + +#define INFINITE_DISTANCE 0x10000 // distance that's always guaranteed to + // be farther away than anything in + // the scene + +//=================================================================== + +extern void R_DrawLine (polyvert_t *polyvert0, polyvert_t *polyvert1); + +extern int cachewidth; +extern pixel_t *cacheblock; +extern int screenwidth; + +extern float pixelAspect; + +extern int r_drawnpolycount; + +extern cvar_t r_clearcolor; + +extern int sintable[SIN_BUFFER_SIZE]; +extern int intsintable[SIN_BUFFER_SIZE]; + +extern vec3_t vup, base_vup; +extern vec3_t vpn, base_vpn; +extern vec3_t vright, base_vright; +extern entity_t *currententity; + +#define NUMSTACKEDGES 2400 +#define MINEDGES NUMSTACKEDGES +#define NUMSTACKSURFACES 800 +#define MINSURFACES NUMSTACKSURFACES +#define MAXSPANS 3000 + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct espan_s +{ + int u, v, count; + struct espan_s *pnext; +} espan_t; + +// FIXME: compress, make a union if that will help +// insubmodel is only 1, flags is fewer than 32, spanstate could be a byte +typedef struct surf_s +{ + struct surf_s *next; // active surface stack in r_edge.c + struct surf_s *prev; // used in r_edge.c for active surf stack + struct espan_s *spans; // pointer to linked list of spans to draw + int key; // sorting key (BSP order) + int last_u; // set during tracing + int spanstate; // 0 = not in span + // 1 = in span + // -1 = in inverted span (end before + // start) + int flags; // currentface flags + void *data; // associated data like msurface_t + entity_t *entity; + float nearzi; // nearest 1/z on surface, for mipmapping + qboolean insubmodel; + float d_ziorigin, d_zistepu, d_zistepv; + + int pad[2]; // to 64 bytes +} surf_t; + +extern surf_t *surfaces, *surface_p, *surf_max; + +// surfaces are generated in back to front order by the bsp, so if a surf +// pointer is greater than another one, it should be drawn in front +// surfaces[1] is the background, and is used as the active surface stack. +// surfaces[0] is a dummy, because index 0 is used to indicate no surface +// attached to an edge_t + +//=================================================================== + +extern vec3_t sxformaxis[4]; // s axis transformed into viewspace +extern vec3_t txformaxis[4]; // t axis transformed into viewspac + +extern vec3_t modelorg, base_modelorg; + +extern float xcenter, ycenter; +extern float xscale, yscale; +extern float xscaleinv, yscaleinv; +extern float xscaleshrink, yscaleshrink; + +extern int d_lightstylevalue[256]; // 8.8 frac of base light value + +extern void TransformVector (vec3_t in, vec3_t out); +extern void SetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv, + fixed8_t endvertu, fixed8_t endvertv); + +extern int r_skymade; +extern void R_MakeSky (void); + +extern int ubasestep, errorterm, erroradjustup, erroradjustdown; + +// flags in finalvert_t.flags +#define ALIAS_LEFT_CLIP 0x0001 +#define ALIAS_TOP_CLIP 0x0002 +#define ALIAS_RIGHT_CLIP 0x0004 +#define ALIAS_BOTTOM_CLIP 0x0008 +#define ALIAS_Z_CLIP 0x0010 +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +#define ALIAS_ONSEAM 0x0020 // also defined in modelgen.h; + // must be kept in sync +#define ALIAS_XY_CLIP_MASK 0x000F + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct edge_s +{ + fixed16_t u; + fixed16_t u_step; + struct edge_s *prev, *next; + unsigned short surfs[2]; + struct edge_s *nextremove; + float nearzi; + medge_t *owner; +} edge_t; + +#endif // _R_SHARED_H_ + +#endif // GLQUAKE, PSP_HARDWARE_VIDEO diff --git a/r17/Revamped src/revamped_src/r_sky.c b/r17/Revamped src/revamped_src/r_sky.c new file mode 100755 index 00000000..83c93e15 --- /dev/null +++ b/r17/Revamped src/revamped_src/r_sky.c @@ -0,0 +1,273 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// r_sky.c + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" + + +int iskyspeed = 8; +int iskyspeed2 = 2; +float skyspeed, skyspeed2; + +float skytime; + +byte *r_skysource; + +int r_skymade; +int r_skydirect; // not used? + + +// TODO: clean up these routines + +byte bottomsky[128*131]; +byte bottommask[128*131]; +byte newsky[128*256]; // newsky and topsky both pack in here, 128 bytes + // of newsky on the left of each scan, 128 bytes + // of topsky on the right, because the low-level + // drawers need 256-byte scan widths + + +/* +============= +R_InitSky + +A sky texture is 256*128, with the right side being a masked overlay +============== +*/ +void R_InitSky (texture_t *mt) +{ + int i, j; + byte *src; + + src = (byte *)mt + mt->offsets[0]; + + for (i=0 ; i<128 ; i++) + { + for (j=0 ; j<128 ; j++) + { + newsky[(i*256) + j + 128] = src[i*256 + j + 128]; + } + } + + for (i=0 ; i<128 ; i++) + { + for (j=0 ; j<131 ; j++) + { + if (src[i*256 + (j & 0x7F)]) + { + bottomsky[(i*131) + j] = src[i*256 + (j & 0x7F)]; + bottommask[(i*131) + j] = 0; + } + else + { + bottomsky[(i*131) + j] = 0; + bottommask[(i*131) + j] = 0xff; + } + } + } + + r_skysource = newsky; +} + + +/* +================= +R_MakeSky +================= +*/ +void R_MakeSky (void) +{ + int x, y; + int ofs, baseofs; + int xshift, yshift; + unsigned *pnewsky; + static int xlast = -1, ylast = -1; + + xshift = skytime*skyspeed; + yshift = skytime*skyspeed; + + if ((xshift == xlast) && (yshift == ylast)) + return; + + xlast = xshift; + ylast = yshift; + + pnewsky = (unsigned *)&newsky[0]; + + for (y=0 ; ydist; + pclipnormal = pclipplane->normal; + +// calc dists + if (clip_current) + { + in = clip_verts[1][0]; + outstep = clip_verts[0][0]; + clip_current = 0; + } + else + { + in = clip_verts[0][0]; + outstep = clip_verts[1][0]; + clip_current = 1; + } + + instep = in; + for (i=0 ; i= 0) + { + Q_memcpy (outstep, instep, sizeof (vec5_t)); + outstep += sizeof (vec5_t) / sizeof (float); + outcount++; + } + + if (dists[i] == 0 || dists[i+1] == 0) + continue; + + if ( (dists[i] > 0) == (dists[i+1] > 0) ) + continue; + + // split it into a new vertex + frac = dists[i] / (dists[i] - dists[i+1]); + + vert2 = instep + sizeof (vec5_t) / sizeof (float); + + outstep[0] = instep[0] + frac*(vert2[0] - instep[0]); + outstep[1] = instep[1] + frac*(vert2[1] - instep[1]); + outstep[2] = instep[2] + frac*(vert2[2] - instep[2]); + outstep[3] = instep[3] + frac*(vert2[3] - instep[3]); + outstep[4] = instep[4] + frac*(vert2[4] - instep[4]); + + outstep += sizeof (vec5_t) / sizeof (float); + outcount++; + } + + return outcount; +} + + +/* +================ +R_SetupAndDrawSprite +================ +*/ +void R_SetupAndDrawSprite () +{ + int i, nump; + float dot, scale, *pv; + vec5_t *pverts; + vec3_t left, up, right, down, transformed, local; + emitpoint_t outverts[MAXWORKINGVERTS+1], *pout; + + dot = DotProduct (r_spritedesc.vpn, modelorg); + +// backface cull + if (dot >= 0) + return; + +// build the sprite poster in worldspace + VectorScale (r_spritedesc.vright, r_spritedesc.pspriteframe->right, right); + VectorScale (r_spritedesc.vup, r_spritedesc.pspriteframe->up, up); + VectorScale (r_spritedesc.vright, r_spritedesc.pspriteframe->left, left); + VectorScale (r_spritedesc.vup, r_spritedesc.pspriteframe->down, down); + + pverts = clip_verts[0]; + + pverts[0][0] = r_entorigin[0] + up[0] + left[0]; + pverts[0][1] = r_entorigin[1] + up[1] + left[1]; + pverts[0][2] = r_entorigin[2] + up[2] + left[2]; + pverts[0][3] = 0; + pverts[0][4] = 0; + + pverts[1][0] = r_entorigin[0] + up[0] + right[0]; + pverts[1][1] = r_entorigin[1] + up[1] + right[1]; + pverts[1][2] = r_entorigin[2] + up[2] + right[2]; + pverts[1][3] = sprite_width; + pverts[1][4] = 0; + + pverts[2][0] = r_entorigin[0] + down[0] + right[0]; + pverts[2][1] = r_entorigin[1] + down[1] + right[1]; + pverts[2][2] = r_entorigin[2] + down[2] + right[2]; + pverts[2][3] = sprite_width; + pverts[2][4] = sprite_height; + + pverts[3][0] = r_entorigin[0] + down[0] + left[0]; + pverts[3][1] = r_entorigin[1] + down[1] + left[1]; + pverts[3][2] = r_entorigin[2] + down[2] + left[2]; + pverts[3][3] = 0; + pverts[3][4] = sprite_height; + +// clip to the frustum in worldspace + nump = 4; + clip_current = 0; + + for (i=0 ; i<4 ; i++) + { + nump = R_ClipSpriteFace (nump, &view_clipplanes[i]); + if (nump < 3) + return; + if (nump >= MAXWORKINGVERTS) + Sys_Error("R_SetupAndDrawSprite: too many points"); + } + +// transform vertices into viewspace and project + pv = &clip_verts[clip_current][0][0]; + r_spritedesc.nearzi = -999999; + + for (i=0 ; izi = 1.0 / transformed[2]; + if (pout->zi > r_spritedesc.nearzi) + r_spritedesc.nearzi = pout->zi; + + pout->s = pv[3]; + pout->t = pv[4]; + + scale = xscale * pout->zi; + pout->u = (xcenter + scale * transformed[0]); + + scale = yscale * pout->zi; + pout->v = (ycenter - scale * transformed[1]); + + pv += sizeof (vec5_t) / sizeof (*pv); + } + +// draw it + r_spritedesc.nump = nump; + r_spritedesc.pverts = outverts; + D_DrawSprite (); +} + + +/* +================ +R_GetSpriteframe +================ +*/ +mspriteframe_t *R_GetSpriteframe (msprite_t *psprite) +{ + mspritegroup_t *pspritegroup; + mspriteframe_t *pspriteframe; + int i, numframes, frame; + float *pintervals, fullinterval, targettime, time; + + frame = currententity->frame; + + if ((frame >= psprite->numframes) || (frame < 0)) + { + Con_Printf ("R_DrawSprite: no such frame %d\n", frame); + frame = 0; + } + + if (psprite->frames[frame].type == SPR_SINGLE) + { + pspriteframe = psprite->frames[frame].frameptr; + } + else + { + pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; + pintervals = pspritegroup->intervals; + numframes = pspritegroup->numframes; + fullinterval = pintervals[numframes-1]; + + time = cl.time + currententity->syncbase; + + // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values + // are positive, so we don't have to worry about division by 0 + targettime = time - ((int)(time / fullinterval)) * fullinterval; + + for (i=0 ; i<(numframes-1) ; i++) + { + if (pintervals[i] > targettime) + break; + } + + pspriteframe = pspritegroup->frames[i]; + } + + return pspriteframe; +} + + +/* +================ +R_DrawSprite +================ +*/ +void R_DrawSprite (void) +{ + int i; + msprite_t *psprite; + vec3_t tvec; + float dot, angle, sr, cr; + + psprite = currententity->model->cache.data; + + r_spritedesc.pspriteframe = R_GetSpriteframe (psprite); + + sprite_width = r_spritedesc.pspriteframe->width; + sprite_height = r_spritedesc.pspriteframe->height; + +// TODO: make this caller-selectable + if (psprite->type == SPR_FACING_UPRIGHT) + { + // generate the sprite's axes, with vup straight up in worldspace, and + // r_spritedesc.vright perpendicular to modelorg. + // This will not work if the view direction is very close to straight up or + // down, because the cross product will be between two nearly parallel + // vectors and starts to approach an undefined state, so we don't draw if + // the two vectors are less than 1 degree apart + tvec[0] = -modelorg[0]; + tvec[1] = -modelorg[1]; + tvec[2] = -modelorg[2]; + VectorNormalize (tvec); + dot = tvec[2]; // same as DotProduct (tvec, r_spritedesc.vup) because + // r_spritedesc.vup is 0, 0, 1 + if ((dot > 0.999848) || (dot < -0.999848)) // cos(1 degree) = 0.999848 + return; + r_spritedesc.vup[0] = 0; + r_spritedesc.vup[1] = 0; + r_spritedesc.vup[2] = 1; + r_spritedesc.vright[0] = tvec[1]; + // CrossProduct(r_spritedesc.vup, -modelorg, + r_spritedesc.vright[1] = -tvec[0]; + // r_spritedesc.vright) + r_spritedesc.vright[2] = 0; + VectorNormalize (r_spritedesc.vright); + r_spritedesc.vpn[0] = -r_spritedesc.vright[1]; + r_spritedesc.vpn[1] = r_spritedesc.vright[0]; + r_spritedesc.vpn[2] = 0; + // CrossProduct (r_spritedesc.vright, r_spritedesc.vup, + // r_spritedesc.vpn) + } + else if (psprite->type == SPR_VP_PARALLEL) + { + // generate the sprite's axes, completely parallel to the viewplane. There + // are no problem situations, because the sprite is always in the same + // position relative to the viewer + for (i=0 ; i<3 ; i++) + { + r_spritedesc.vup[i] = vup[i]; + r_spritedesc.vright[i] = vright[i]; + r_spritedesc.vpn[i] = vpn[i]; + } + } + else if (psprite->type == SPR_VP_PARALLEL_UPRIGHT) + { + // generate the sprite's axes, with vup straight up in worldspace, and + // r_spritedesc.vright parallel to the viewplane. + // This will not work if the view direction is very close to straight up or + // down, because the cross product will be between two nearly parallel + // vectors and starts to approach an undefined state, so we don't draw if + // the two vectors are less than 1 degree apart + dot = vpn[2]; // same as DotProduct (vpn, r_spritedesc.vup) because + // r_spritedesc.vup is 0, 0, 1 + if ((dot > 0.999848) || (dot < -0.999848)) // cos(1 degree) = 0.999848 + return; + r_spritedesc.vup[0] = 0; + r_spritedesc.vup[1] = 0; + r_spritedesc.vup[2] = 1; + r_spritedesc.vright[0] = vpn[1]; + // CrossProduct (r_spritedesc.vup, vpn, + r_spritedesc.vright[1] = -vpn[0]; // r_spritedesc.vright) + r_spritedesc.vright[2] = 0; + VectorNormalize (r_spritedesc.vright); + r_spritedesc.vpn[0] = -r_spritedesc.vright[1]; + r_spritedesc.vpn[1] = r_spritedesc.vright[0]; + r_spritedesc.vpn[2] = 0; + // CrossProduct (r_spritedesc.vright, r_spritedesc.vup, + // r_spritedesc.vpn) + } + else if (psprite->type == SPR_ORIENTED) + { + // generate the sprite's axes, according to the sprite's world orientation + AngleVectors (currententity->angles, r_spritedesc.vpn, + r_spritedesc.vright, r_spritedesc.vup); + } + else if (psprite->type == SPR_VP_PARALLEL_ORIENTED) + { + // generate the sprite's axes, parallel to the viewplane, but rotated in + // that plane around the center according to the sprite entity's roll + // angle. So vpn stays the same, but vright and vup rotate + angle = currententity->angles[ROLL] * (M_PI*2 / 360); + sr = sinf(angle); + cr = cosf(angle); + + for (i=0 ; i<3 ; i++) + { + r_spritedesc.vpn[i] = vpn[i]; + r_spritedesc.vright[i] = vright[i] * cr + vup[i] * sr; + r_spritedesc.vup[i] = vright[i] * -sr + vup[i] * cr; + } + } + else + { + Sys_Error ("R_DrawSprite: Bad sprite type %d", psprite->type); + } + + R_RotateSprite (psprite->beamlength); + + R_SetupAndDrawSprite (); +} + diff --git a/r17/Revamped src/revamped_src/r_surf.c b/r17/Revamped src/revamped_src/r_surf.c new file mode 100755 index 00000000..abd03d4b --- /dev/null +++ b/r17/Revamped src/revamped_src/r_surf.c @@ -0,0 +1,678 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// r_surf.c: surface-related refresh code + +#include "quakedef.h" +#include "r_local.h" + +drawsurf_t r_drawsurf; + +int lightleft, sourcesstep, blocksize, sourcetstep; +int lightdelta, lightdeltastep; +int lightright, lightleftstep, lightrightstep, blockdivshift; +unsigned blockdivmask; +void *prowdestbase; +unsigned char *pbasesource; +int surfrowbytes; // used by ASM files +unsigned *r_lightptr; +int r_stepback; +int r_lightwidth; +int r_numhblocks, r_numvblocks; +unsigned char *r_source, *r_sourcemax; + +void R_DrawSurfaceBlock8_mip0 (void); +void R_DrawSurfaceBlock8_mip1 (void); +void R_DrawSurfaceBlock8_mip2 (void); +void R_DrawSurfaceBlock8_mip3 (void); + +static void (*surfmiptable[4])(void) = { + R_DrawSurfaceBlock8_mip0, + R_DrawSurfaceBlock8_mip1, + R_DrawSurfaceBlock8_mip2, + R_DrawSurfaceBlock8_mip3 +}; + + + +unsigned blocklights[18*18]; + +/* +=============== +R_AddDynamicLights +=============== +*/ +void R_AddDynamicLights (void) +{ + msurface_t *surf; + int lnum; + int sd, td; + float dist, rad, minlight; + vec3_t impact, local; + int s, t; + int i; + int smax, tmax; + mtexinfo_t *tex; + + surf = r_drawsurf.surf; + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + tex = surf->texinfo; + + for (lnum=0 ; lnumdlightbits & (1<plane->normal) - + surf->plane->dist; + rad -= fabsf(dist); + minlight = cl_dlights[lnum].minlight; + if (rad < minlight) + continue; + minlight = rad - minlight; + + for (i=0 ; i<3 ; i++) + { + impact[i] = cl_dlights[lnum].origin[i] - + surf->plane->normal[i]*dist; + } + + local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; + local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; + + local[0] -= surf->texturemins[0]; + local[1] -= surf->texturemins[1]; + + for (t = 0 ; t td) + dist = sd + (td>>1); + else + dist = td + (sd>>1); + if (dist < minlight) +#ifdef QUAKE2 + { + unsigned temp; + temp = (rad - dist)*256; + i = t*smax + s; + if (!cl_dlights[lnum].dark) + blocklights[i] += temp; + else + { + if (blocklights[i] > temp) + blocklights[i] -= temp; + else + blocklights[i] = 0; + } + } +#else + blocklights[t*smax + s] += (rad - dist)*256; +#endif + } + } + } +} + +/* +=============== +R_BuildLightMap + +Combine and scale multiple lightmaps into the 8.8 format in blocklights +=============== +*/ +void R_BuildLightMap (void) +{ + int smax, tmax; + int t; + int i, size; + byte *lightmap; + unsigned scale; + int maps; + msurface_t *surf; + + surf = r_drawsurf.surf; + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + size = smax*tmax; + lightmap = surf->samples; + + if (r_fullbright.value || !cl.worldmodel->lightdata) + { + for (i=0 ; istyles[maps] != 255 ; + maps++) + { + scale = r_drawsurf.lightadj[maps]; // 8.8 fraction + for (i=0 ; idlightframe == r_framecount) + R_AddDynamicLights (); + +// bound, invert, and shift + for (i=0 ; i> (8 - VID_CBITS); + + if (t < (1 << 6)) + t = (1 << 6); + + blocklights[i] = t; + } +} + + +/* +=============== +R_TextureAnimation + +Returns the proper texture for a given time and base texture +=============== +*/ +texture_t *R_TextureAnimation (texture_t *base) +{ + int reletive; + int count; + + if (currententity->frame) + { + if (base->alternate_anims) + base = base->alternate_anims; + } + + if (!base->anim_total) + return base; + + reletive = (int)(cl.time*10) % base->anim_total; + + count = 0; + while (base->anim_min > reletive || base->anim_max <= reletive) + { + base = base->anim_next; + if (!base) + Sys_Error ("R_TextureAnimation: broken cycle"); + if (++count > 100) + Sys_Error ("R_TextureAnimation: infinite cycle"); + } + + return base; +} + + +/* +=============== +R_DrawSurface +=============== +*/ +void R_DrawSurface (void) +{ + unsigned char *basetptr; + int smax, tmax, twidth; + int u; + int soffset, basetoffset, texwidth; + int horzblockstep; + unsigned char *pcolumndest; + void (*pblockdrawer)(void); + texture_t *mt; + +// calculate the lightings + R_BuildLightMap (); + + surfrowbytes = r_drawsurf.rowbytes; + + mt = r_drawsurf.texture; + + r_source = (byte *)mt + mt->offsets[r_drawsurf.surfmip]; + +// the fractional light values should range from 0 to (VID_GRADES - 1) << 16 +// from a source range of 0 - 255 + + texwidth = mt->width >> r_drawsurf.surfmip; + + blocksize = 16 >> r_drawsurf.surfmip; + blockdivshift = 4 - r_drawsurf.surfmip; + blockdivmask = (1 << blockdivshift) - 1; + + r_lightwidth = (r_drawsurf.surf->extents[0]>>4)+1; + + r_numhblocks = r_drawsurf.surfwidth >> blockdivshift; + r_numvblocks = r_drawsurf.surfheight >> blockdivshift; + +//============================== + + if (r_pixbytes == 1) + { + pblockdrawer = surfmiptable[r_drawsurf.surfmip]; + // TODO: only needs to be set when there is a display settings change + horzblockstep = blocksize; + } + else + { + pblockdrawer = R_DrawSurfaceBlock16; + // TODO: only needs to be set when there is a display settings change + horzblockstep = blocksize << 1; + } + + smax = mt->width >> r_drawsurf.surfmip; + twidth = texwidth; + tmax = mt->height >> r_drawsurf.surfmip; + sourcetstep = texwidth; + r_stepback = tmax * twidth; + + r_sourcemax = r_source + (tmax * smax); + + soffset = r_drawsurf.surf->texturemins[0]; + basetoffset = r_drawsurf.surf->texturemins[1]; + +// << 16 components are to guarantee positive values for % + soffset = ((soffset >> r_drawsurf.surfmip) + (smax << 16)) % smax; + basetptr = &r_source[((((basetoffset >> r_drawsurf.surfmip) + + (tmax << 16)) % tmax) * twidth)]; + + pcolumndest = r_drawsurf.surfdat; + + for (u=0 ; u= smax) + soffset = 0; + + pcolumndest += horzblockstep; + } +} + + +//============================================================================= + +#if !id386 + +/* +================ +R_DrawSurfaceBlock8_mip0 +================ +*/ +void R_DrawSurfaceBlock8_mip0 (void) +{ + int v, i, b, lightstep, lighttemp, light; + unsigned char pix, *psource, *prowdest; + + psource = pbasesource; + prowdest = prowdestbase; + + for (v=0 ; v> 4; + lightrightstep = (r_lightptr[1] - lightright) >> 4; + + for (i=0 ; i<16 ; i++) + { + lighttemp = lightleft - lightright; + lightstep = lighttemp >> 4; + + light = lightright; + + for (b=15; b>=0; b--) + { + pix = psource[b]; + prowdest[b] = ((unsigned char *)vid.colormap) + [(light & 0xFF00) + pix]; + light += lightstep; + } + + psource += sourcetstep; + lightright += lightrightstep; + lightleft += lightleftstep; + prowdest += surfrowbytes; + } + + if (psource >= r_sourcemax) + psource -= r_stepback; + } +} + + +/* +================ +R_DrawSurfaceBlock8_mip1 +================ +*/ +void R_DrawSurfaceBlock8_mip1 (void) +{ + int v, i, b, lightstep, lighttemp, light; + unsigned char pix, *psource, *prowdest; + + psource = pbasesource; + prowdest = prowdestbase; + + for (v=0 ; v> 3; + lightrightstep = (r_lightptr[1] - lightright) >> 3; + + for (i=0 ; i<8 ; i++) + { + lighttemp = lightleft - lightright; + lightstep = lighttemp >> 3; + + light = lightright; + + for (b=7; b>=0; b--) + { + pix = psource[b]; + prowdest[b] = ((unsigned char *)vid.colormap) + [(light & 0xFF00) + pix]; + light += lightstep; + } + + psource += sourcetstep; + lightright += lightrightstep; + lightleft += lightleftstep; + prowdest += surfrowbytes; + } + + if (psource >= r_sourcemax) + psource -= r_stepback; + } +} + + +/* +================ +R_DrawSurfaceBlock8_mip2 +================ +*/ +void R_DrawSurfaceBlock8_mip2 (void) +{ + int v, i, b, lightstep, lighttemp, light; + unsigned char pix, *psource, *prowdest; + + psource = pbasesource; + prowdest = prowdestbase; + + for (v=0 ; v> 2; + lightrightstep = (r_lightptr[1] - lightright) >> 2; + + for (i=0 ; i<4 ; i++) + { + lighttemp = lightleft - lightright; + lightstep = lighttemp >> 2; + + light = lightright; + + for (b=3; b>=0; b--) + { + pix = psource[b]; + prowdest[b] = ((unsigned char *)vid.colormap) + [(light & 0xFF00) + pix]; + light += lightstep; + } + + psource += sourcetstep; + lightright += lightrightstep; + lightleft += lightleftstep; + prowdest += surfrowbytes; + } + + if (psource >= r_sourcemax) + psource -= r_stepback; + } +} + + +/* +================ +R_DrawSurfaceBlock8_mip3 +================ +*/ +void R_DrawSurfaceBlock8_mip3 (void) +{ + int v, i, b, lightstep, lighttemp, light; + unsigned char pix, *psource, *prowdest; + + psource = pbasesource; + prowdest = prowdestbase; + + for (v=0 ; v> 1; + lightrightstep = (r_lightptr[1] - lightright) >> 1; + + for (i=0 ; i<2 ; i++) + { + lighttemp = lightleft - lightright; + lightstep = lighttemp >> 1; + + light = lightright; + + for (b=1; b>=0; b--) + { + pix = psource[b]; + prowdest[b] = ((unsigned char *)vid.colormap) + [(light & 0xFF00) + pix]; + light += lightstep; + } + + psource += sourcetstep; + lightright += lightrightstep; + lightleft += lightleftstep; + prowdest += surfrowbytes; + } + + if (psource >= r_sourcemax) + psource -= r_stepback; + } +} + + +/* +================ +R_DrawSurfaceBlock16 + +FIXME: make this work +================ +*/ +void R_DrawSurfaceBlock16 (void) +{ + int k; + unsigned char *psource; + int lighttemp, lightstep, light; + unsigned short *prowdest; + + prowdest = (unsigned short *)prowdestbase; + + for (k=0 ; k> blockdivshift; + + light = lightleft; + pdest = prowdest; + + for (b=0; b> 16) & 63; + t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63; + *pd++ = *(pbasetex + (t<<6) + s); + } + } +} + + +/* +================ +R_GenTurbTile16 +================ +*/ +void R_GenTurbTile16 (pixel_t *pbasetex, void *pdest) +{ + int *turb; + int i, j, s, t; + unsigned short *pd; + + turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1)); + pd = (unsigned short *)pdest; + + for (i=0 ; i> 16) & 63; + t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63; + *pd++ = d_8to16table[*(pbasetex + (t<<6) + s)]; + } + } +} + + +/* +================ +R_GenTile +================ +*/ +void R_GenTile (msurface_t *psurf, void *pdest) +{ + if (psurf->flags & SURF_DRAWTURB) + { + if (r_pixbytes == 1) + { + R_GenTurbTile ((pixel_t *) + ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest); + } + else + { + R_GenTurbTile16 ((pixel_t *) + ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest); + } + } + else if (psurf->flags & SURF_DRAWSKY) + { + if (r_pixbytes == 1) + { + R_GenSkyTile (pdest); + } + else + { + R_GenSkyTile16 (pdest); + } + } + else + { + Sys_Error ("Unknown tile type"); + } +} + diff --git a/r17/Revamped src/revamped_src/r_vars.c b/r17/Revamped src/revamped_src/r_vars.c new file mode 100755 index 00000000..90fe7f55 --- /dev/null +++ b/r17/Revamped src/revamped_src/r_vars.c @@ -0,0 +1,39 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// r_vars.c: global refresh variables + +#include "quakedef.h" + +#if !id386 + +// all global and static refresh variables are collected in a contiguous block +// to avoid cache conflicts. + +//------------------------------------------------------- +// global refresh variables +//------------------------------------------------------- + +// FIXME: make into one big structure, like cl or sv +// FIXME: do separately for refresh engine and driver + +int r_bmodelactive; + +#endif // !id386 + diff --git a/r17/Revamped src/revamped_src/render.h b/r17/Revamped src/revamped_src/render.h new file mode 100755 index 00000000..76072824 --- /dev/null +++ b/r17/Revamped src/revamped_src/render.h @@ -0,0 +1,198 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +// refresh.h -- public interface to refresh functions + +#define MAXCLIPPLANES 11 + +#define TOP_RANGE 16 // soldier uniform colors +#define BOTTOM_RANGE 96 + +//============================================================================= + +typedef struct efrag_s +{ + struct mleaf_s *leaf; + struct efrag_s *leafnext; + struct entity_s *entity; + struct efrag_s *entnext; +} efrag_t; + + +typedef struct entity_s +{ + qboolean forcelink; // model changed + + int update_type; + + entity_state_t baseline; // to fill in defaults in updates + + double msgtime; // time of last update + vec3_t msg_origins[2]; // last two updates (0 is newest) + vec3_t origin; + vec3_t msg_angles[2]; // last two updates (0 is newest) + vec3_t angles; + struct model_s *model; // NULL = no model + struct efrag_s *efrag; // linked list of efrags + int frame; + float syncbase; // for client-side animations + byte *colormap; + int effects; // light, particals, etc + int skinnum; // for Alias models + int visframe; // last frame this entity was + // found in an active leaf + + int dlightframe; // dynamic lighting + int dlightbits; + +// FIXME: could turn these into a union + int trivial_accept; + struct mnode_s *topnode; // for bmodels, first world node + // that splits bmodel, or NULL if + // not split + + float frame_start_time; + float frame_interval; + int pose1; + int pose2; + + // fenix@io.com: model transform interpolation + float translate_start_time; + vec3_t origin1; + vec3_t origin2; + + float rotate_start_time; + vec3_t angles1; + vec3_t angles2; + + // light lerping - pox@planetquake.com + + float last_shadelight; + + // Tomaz - QC Alpha Scale Glow Begin + + float alpha; + float scale; + float glow_size; + float glow_red; + float glow_green; + float glow_blue; + + // Tomaz - QC Alpha Scale Glow End + +} entity_t; + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + vrect_t vrect; // subwindow in video for refresh + // FIXME: not need vrect next field here? + vrect_t aliasvrect; // scaled Alias version + int vrectright, vrectbottom; // right & bottom screen coords + int aliasvrectright, aliasvrectbottom; // scaled Alias versions + float vrectrightedge; // rightmost right edge we care about, + // for use in edge list + float fvrectx, fvrecty; // for floating-point compares + float fvrectx_adj, fvrecty_adj; // left and top edges, for clamping + int vrect_x_adj_shift20; // (vrect.x + 0.5 - epsilon) << 20 + int vrectright_adj_shift20; // (vrectright + 0.5 - epsilon) << 20 + float fvrectright_adj, fvrectbottom_adj; + // right and bottom edges, for clamping + float fvrectright; // rightmost edge, for Alias clamping + float fvrectbottom; // bottommost edge, for Alias clamping + float horizontalFieldOfView; // at Z = 1.0, this many X is visible + // 2.0 = 90 degrees + float xOrigin; // should probably allways be 0.5 + float yOrigin; // between be around 0.3 to 0.5 + + vec3_t vieworg; + vec3_t viewangles; + + float fov_x, fov_y; + + int ambientlight; + + float fog_start; + float fog_end; + float fog_red; + float fog_green; + float fog_blue; + +} refdef_t; + + +// +// refresh +// +extern int reinit_surfcache; + + +extern refdef_t r_refdef; +extern vec3_t r_origin, vpn, vright, vup; + +extern struct texture_s *r_notexture_mip; + + +void R_Init (void); +void R_InitTextures (void); +void R_InitEfrags (void); +void R_RenderView (void); // must set r_refdef first +void R_ViewChanged (vrect_t *pvrect, int lineadj, float aspect); +#ifdef PSP_HARDWARE_VIDEO // called whenever r_refdef or vid change +void R_InitSky (byte *mt); // called at level load +#else +void R_InitSky (struct texture_s *mt); // called at level load +#endif + +void R_AddEfrags (entity_t *ent); +void R_RemoveEfrags (entity_t *ent); + +void R_NewMap (void); + + +void R_ParseParticleEffect (void); +void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count); +void R_RocketTrail (vec3_t start, vec3_t end, int type); + +#ifdef QUAKE2 +void R_DarkFieldParticles (entity_t *ent); +#endif +void R_EntityParticles (entity_t *ent); +void R_BlobExplosion (vec3_t org); +void R_ParticleExplosion (vec3_t org); +void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength); +void R_LavaSplash (vec3_t org); +void R_TeleportSplash (vec3_t org); + +void R_PushDlights (void); + + +// +// surface cache related +// +extern int reinit_surfcache; // if 1, surface cache is currently empty and +extern qboolean r_cache_thrash; // set if thrashing the surface cache + +int D_SurfaceCacheForRes (int width, int height); +void D_FlushCaches (void); +void D_DeleteSurfaceCache (void); +void D_InitCaches (void *buffer, int size); +void R_SetVrect (vrect_t *pvrect, vrect_t *pvrectin, int lineadj); + diff --git a/r17/Revamped src/revamped_src/resource.h b/r17/Revamped src/revamped_src/resource.h new file mode 100755 index 00000000..a72295f3 --- /dev/null +++ b/r17/Revamped src/revamped_src/resource.h @@ -0,0 +1,20 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by winquake.rc +// +#define IDS_STRING1 1 +#define IDI_ICON2 1 +#define IDD_DIALOG1 108 +#define IDD_PROGRESS 109 +#define IDC_PROGRESS 1000 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 111 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1004 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/r17/Revamped src/revamped_src/sbar.c b/r17/Revamped src/revamped_src/sbar.c new file mode 100755 index 00000000..2e9aa13c --- /dev/null +++ b/r17/Revamped src/revamped_src/sbar.c @@ -0,0 +1,2932 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// sbar.c -- status bar code + +#include "quakedef.h" +#include + +int sb_updates; // if >= vid.numpages, no update needed + +cvar_t cl_killmedals = {"cl_killmedals", "0"}; +cvar_t cl_plasmanade = {"cl_plasmanade", "2"}; +cvar_t cl_nadenum = {"cl_nadenum", "5"}; +cvar_t cl_ww = {"cl_ww", "0"}; //World weapon print message + + + +#define STAT_MINUS 10 // num frame for '-' stats digit +qpic_t *sb_nums[2][11]; +qpic_t *sb_colon, *sb_slash; +qpic_t *sb_ibar; +qpic_t *sb_sbar; +qpic_t *sb_scorebar; + +qpic_t *sb_weapons[7][8]; // 0 is active, 1 is owned, 2-5 are flashes +qpic_t *sb_ammo[4]; +qpic_t *sb_sigil[4]; +qpic_t *sb_armor[3]; +qpic_t *sb_items[32]; + +qpic_t *sb_faces[7][2]; // 0 is gibbed, 1 is dead, 2-6 are alive + // 0 is static, 1 is temporary animation +qpic_t *sb_face_invis; +qpic_t *sb_face_quad; +qpic_t *sb_face_invuln; +qpic_t *sb_face_invis_invuln; + +qboolean sb_showscores; + +int sb_lines; // scan lines to draw + +qpic_t *ksb_ammo[1]; + +qpic_t *rsb_invbar[2]; +qpic_t *rsb_weapons[5]; +qpic_t *rsb_items[2]; +qpic_t *rsb_ammo[3]; +qpic_t *rsb_teambord; // PGM 01/19/97 - team color border +//Weapon Icons +qpic_t *AR; +qpic_t *SMG; +qpic_t *Sniper; +qpic_t *RL; +qpic_t *Needler; +qpic_t *ppist; +qpic_t *Pistol; +qpic_t *Shottie; +//World weapons +qpic_t *ARW; +qpic_t *SMGW; +qpic_t *SniperW; +qpic_t *RLW; +qpic_t *NeedlerW; +qpic_t *ppistW; +qpic_t *PistolW; +qpic_t *ShottieW; + +//Kill medals +qpic_t *doublek; +qpic_t *triple; +qpic_t *killtrocity; +qpic_t *killtacular; + +//Grenade types +qpic_t *plasma; +qpic_t *frag; + + +//Health +qpic_t *life90; +qpic_t *health_bar; +qpic_t *health_bar_red; + +//Ammo counter +qpic_t *pistolb; +qpic_t *shotgunb; +qpic_t *arb; +qpic_t *needleb; +qpic_t *rocketb; +//Grenade Numbers +qpic_t *numbers[5]; + + +//MED 01/04/97 added two more weapons + 3 alternates for grenade launcher +qpic_t *hsb_weapons[7][5]; // 0 is active, 1 is owned, 2-5 are flashes +//MED 01/04/97 added array to simplify weapon parsing +int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BIT}; +//MED 01/04/97 added hipnotic items array +qpic_t *hsb_items[2]; + +void Sbar_MiniDeathmatchOverlay (void); +void Sbar_TimeOverlay (void); +void Sbar_DeathmatchOverlay (void); +void Sbar_DeathmatchOverlay2 (void); +void M_DrawPic (int x, int y, qpic_t *pic); + +/* +=============== +Sbar_ShowScores + +Tab key down +=============== +*/ +void Sbar_ShowScores (void) +{ + if (sb_showscores) + return; + sb_showscores = true; + sb_updates = 0; +} + +/* +=============== +Sbar_DontShowScores + +Tab key up +=============== +*/ +void Sbar_DontShowScores (void) +{ + sb_showscores = false; + sb_updates = 0; +} + +/* +=============== +Sbar_Changed +=============== +*/ +void Sbar_Changed (void) +{ + sb_updates = 0; // update next frame +} + +/* +=============== +Sbar_Init +=============== +*/ +void Sbar_Init (void) +{ + int i; + + for (i=0 ; i<10 ; i++) + { + sb_nums[0][i] = Draw_PicFromWad (va("num_%i",i)); + sb_nums[1][i] = Draw_PicFromWad (va("anum_%i",i)); + } + + sb_nums[0][10] = Draw_PicFromWad ("num_minus"); + sb_nums[1][10] = Draw_PicFromWad ("anum_minus"); + + sb_colon = Draw_PicFromWad ("num_colon"); + sb_slash = Draw_PicFromWad ("num_slash"); + +/* +================================================= +Weapon Icons for weapons. +================================================= +*/ + + //Ammo counter + pistolb = Draw_CachePic ("gfx/ammo/pistolb.lmp"); //Pistolb + shotgunb = Draw_CachePic ("gfx/ammo/shotgunb.lmp"); //shotgunb + arb = Draw_CachePic ("gfx/ammo/arb.lmp"); //arb + needleb = Draw_CachePic ("gfx/ammo/needleb.lmp"); //needleb + rocketb = Draw_CachePic ("gfx/ammo/rocketb.lmp"); //rocketb + + //World Weapons + ARW = Draw_CachePic ("gfx/worldweapons/ar.lmp"); //Assault rifle + SMGW = Draw_CachePic ("gfx/worldweapons/smg.lmp"); //SMG + SniperW = Draw_CachePic ("gfx/worldweapons/sniper.lmp"); //Sniper Rifle + RLW = Draw_CachePic ("gfx/worldweapons/RL.lmp"); //Rocket Launcher + NeedlerW = Draw_CachePic ("gfx/worldweapons/Needler.lmp"); //Needler + PistolW = Draw_CachePic ("gfx/worldweapons/Pistol.lmp"); //Pistol + ShottieW = Draw_CachePic ("gfx/worldweapons/Shottie.lmp"); //Shottie + ppistW = Draw_CachePic ("gfx/worldweapons/ppist.lmp"); //Plasma Pistol + + //Weapons + AR = Draw_CachePic ("gfx/weapons/ar.lmp"); //Assault rifle + SMG = Draw_CachePic ("gfx/weapons/smg.lmp"); //SMG + Sniper = Draw_CachePic ("gfx/weapons/sniper.lmp"); //Sniper Rifle + RL = Draw_CachePic ("gfx/weapons/RL.lmp"); //Rocket Launcher + Needler = Draw_CachePic ("gfx/weapons/Needler.lmp"); //Needler + Pistol = Draw_CachePic ("gfx/weapons/Pistol.lmp"); //Pistol + Shottie = Draw_CachePic ("gfx/weapons/Shottie.lmp"); //Shottie + ppist = Draw_CachePic ("gfx/weapons/ppist.lmp"); //Plasma Pistol + + + //Health + life90 = Draw_CachePic ("gfx/healthb.lmp"); + health_bar = Draw_CachePic ("gfx/healthback.lmp"); + health_bar_red = Draw_CachePic ("gfx/healthbackr.lmp"); + + //Kill medals + doublek = Draw_CachePic ("gfx/medals/double.lmp"); + triple = Draw_CachePic ("gfx/medals/triple.lmp"); + killtacular = Draw_CachePic ("gfx/medals/killtacular.lmp"); + killtrocity = Draw_CachePic ("gfx/medals/killtrocity.lmp"); + + //Nade types + plasma = Draw_CachePic ("gfx/plasmanade.lmp"); + frag = Draw_CachePic ("gfx/fraggrenade.lmp"); + + //Nade number counter + numbers[0] = Draw_CachePic ("gfx/numbers/num_0.lmp"); + numbers[1] = Draw_CachePic ("gfx/numbers/num_1.lmp"); + numbers[2] = Draw_CachePic ("gfx/numbers/num_2.lmp"); + numbers[3] = Draw_CachePic ("gfx/numbers/num_3.lmp"); + numbers[4] = Draw_CachePic ("gfx/numbers/num_4.lmp"); + + //Client variables + Cvar_RegisterVariable (&cl_killmedals); //Kill medals + Cvar_RegisterVariable (&cl_plasmanade); //Grenade types + Cvar_RegisterVariable (&cl_nadenum); //A counter for your grenades. + Cvar_RegisterVariable (&cl_ww); //World weapons + + sb_weapons[0][0] = Draw_PicFromWad ("inv_shotgun"); + sb_weapons[0][1] = Draw_PicFromWad ("inv_sshotgun"); + sb_weapons[0][2] = Draw_PicFromWad ("inv_nailgun"); + sb_weapons[0][3] = Draw_PicFromWad ("inv_snailgun"); + sb_weapons[0][4] = Draw_PicFromWad ("inv_rlaunch"); + sb_weapons[0][5] = Draw_PicFromWad ("inv_srlaunch"); + sb_weapons[0][6] = Draw_PicFromWad ("inv_lightng"); + + sb_weapons[1][0] = Draw_PicFromWad ("inv2_shotgun"); + sb_weapons[1][1] = Draw_PicFromWad ("inv2_sshotgun"); + sb_weapons[1][2] = Draw_PicFromWad ("inv2_nailgun"); + sb_weapons[1][3] = Draw_PicFromWad ("inv2_snailgun"); + sb_weapons[1][4] = Draw_PicFromWad ("inv2_rlaunch"); + sb_weapons[1][5] = Draw_PicFromWad ("inv2_srlaunch"); + sb_weapons[1][6] = Draw_PicFromWad ("inv2_lightng"); + + for (i=0 ; i<5 ; i++) + { + sb_weapons[2+i][0] = Draw_PicFromWad (va("inva%i_shotgun",i+1)); + sb_weapons[2+i][1] = Draw_PicFromWad (va("inva%i_sshotgun",i+1)); + sb_weapons[2+i][2] = Draw_PicFromWad (va("inva%i_nailgun",i+1)); + sb_weapons[2+i][3] = Draw_PicFromWad (va("inva%i_snailgun",i+1)); + sb_weapons[2+i][4] = Draw_PicFromWad (va("inva%i_rlaunch",i+1)); + sb_weapons[2+i][5] = Draw_PicFromWad (va("inva%i_srlaunch",i+1)); + sb_weapons[2+i][6] = Draw_PicFromWad (va("inva%i_lightng",i+1)); + } + + sb_ammo[0] = Draw_PicFromWad ("sb_shells"); + sb_ammo[1] = Draw_PicFromWad ("sb_nails"); + sb_ammo[2] = Draw_PicFromWad ("sb_rocket"); + sb_ammo[3] = Draw_PicFromWad ("sb_cells"); + + + sb_armor[0] = Draw_PicFromWad ("sb_armor1"); + sb_armor[1] = Draw_PicFromWad ("sb_armor2"); + sb_armor[2] = Draw_PicFromWad ("sb_armor3"); + + sb_items[0] = Draw_PicFromWad ("sb_key1"); + sb_items[1] = Draw_PicFromWad ("sb_key2"); + sb_items[2] = Draw_PicFromWad ("sb_invis"); + sb_items[3] = Draw_PicFromWad ("sb_invuln"); + sb_items[4] = Draw_PicFromWad ("sb_suit"); + sb_items[5] = Draw_PicFromWad ("sb_quad"); + + sb_sigil[0] = Draw_PicFromWad ("sb_sigil1"); + sb_sigil[1] = Draw_PicFromWad ("sb_sigil2"); + sb_sigil[2] = Draw_PicFromWad ("sb_sigil3"); + sb_sigil[3] = Draw_PicFromWad ("sb_sigil4"); + + sb_faces[4][0] = Draw_PicFromWad ("face1"); + sb_faces[4][1] = Draw_PicFromWad ("face_p1"); + sb_faces[3][0] = Draw_PicFromWad ("face2"); + sb_faces[3][1] = Draw_PicFromWad ("face_p2"); + sb_faces[2][0] = Draw_PicFromWad ("face3"); + sb_faces[2][1] = Draw_PicFromWad ("face_p3"); + sb_faces[1][0] = Draw_PicFromWad ("face4"); + sb_faces[1][1] = Draw_PicFromWad ("face_p4"); + sb_faces[0][0] = Draw_PicFromWad ("face5"); + sb_faces[0][1] = Draw_PicFromWad ("face_p5"); + + sb_face_invis = Draw_PicFromWad ("face_invis"); + sb_face_invuln = Draw_PicFromWad ("face_invul2"); + sb_face_invis_invuln = Draw_PicFromWad ("face_inv2"); + sb_face_quad = Draw_PicFromWad ("face_quad"); + + Cmd_AddCommand ("+showscores", Sbar_ShowScores); + Cmd_AddCommand ("-showscores", Sbar_DontShowScores); + + sb_sbar = Draw_PicFromWad ("sbar"); + sb_ibar = Draw_PicFromWad ("ibar"); + sb_scorebar = Draw_PicFromWad ("scorebar"); + +//MED 01/04/97 added new hipnotic weapons + if (hipnotic) + { + hsb_weapons[0][0] = Draw_PicFromWad ("inv_laser"); + hsb_weapons[0][1] = Draw_PicFromWad ("inv_mjolnir"); + hsb_weapons[0][2] = Draw_PicFromWad ("inv_gren_prox"); + hsb_weapons[0][3] = Draw_PicFromWad ("inv_prox_gren"); + hsb_weapons[0][4] = Draw_PicFromWad ("inv_prox"); + + hsb_weapons[1][0] = Draw_PicFromWad ("inv2_laser"); + hsb_weapons[1][1] = Draw_PicFromWad ("inv2_mjolnir"); + hsb_weapons[1][2] = Draw_PicFromWad ("inv2_gren_prox"); + hsb_weapons[1][3] = Draw_PicFromWad ("inv2_prox_gren"); + hsb_weapons[1][4] = Draw_PicFromWad ("inv2_prox"); + for (i=0 ; i<5 ; i++) + { + hsb_weapons[2+i][0] = Draw_PicFromWad (va("inva%i_laser",i+1)); + hsb_weapons[2+i][1] = Draw_PicFromWad (va("inva%i_mjolnir",i+1)); + hsb_weapons[2+i][2] = Draw_PicFromWad (va("inva%i_gren_prox",i+1)); + hsb_weapons[2+i][3] = Draw_PicFromWad (va("inva%i_prox_gren",i+1)); + hsb_weapons[2+i][4] = Draw_PicFromWad (va("inva%i_prox",i+1)); + } + + hsb_items[0] = Draw_PicFromWad ("sb_wsuit"); + hsb_items[1] = Draw_PicFromWad ("sb_eshld"); + } + + if (rogue) + { + rsb_invbar[0] = Draw_PicFromWad ("r_invbar1"); + rsb_invbar[1] = Draw_PicFromWad ("r_invbar2"); + + rsb_weapons[0] = Draw_PicFromWad ("r_lava"); + rsb_weapons[1] = Draw_PicFromWad ("r_superlava"); + rsb_weapons[2] = Draw_PicFromWad ("r_gren"); + rsb_weapons[3] = Draw_PicFromWad ("r_multirock"); + rsb_weapons[4] = Draw_PicFromWad ("r_plasma"); + + rsb_items[0] = Draw_PicFromWad ("r_shield1"); + rsb_items[1] = Draw_PicFromWad ("r_agrav1"); + +// PGM 01/19/97 - team color border + rsb_teambord = Draw_PicFromWad ("r_teambord"); +// PGM 01/19/97 - team color border + + rsb_ammo[0] = Draw_PicFromWad ("r_ammolava"); + rsb_ammo[1] = Draw_PicFromWad ("r_ammomulti"); + rsb_ammo[2] = Draw_PicFromWad ("r_ammoplasma"); + } +} + + +//============================================================================= + +// drawing routines are relative to the status bar location + +/* +============= +Sbar_DrawAlphaPic +Alpha = 1 : full alpha which is fully solid +Alpha = 0.5 ... 50% transparency +Alpha = 0.25 ... 75% transparency +Alpha = 0 ... invisible .. not drawn essentially +This function calls Draw_AlphaPic in video_hardware_draw.cpp (PSP)/gl_draw.c (GLQuake) +instead of Draw_Pic (Draw_Pic draws fully solid images). Draw_AlphaPic offers an extra field "alpha" +which can draw fully solid or with transparency/translucency or whatever you like to call it. +============= +*/ +void Sbar_DrawAlphaPic (int x, int y, qpic_t *pic, float alpha) +{ + if(kurok) + Draw_AlphaPic (x /* + ((vid.width - 320)>>1)*/, y + (vid.height-SBAR_HEIGHT), pic, alpha); + else + { + if (cl.gametype == GAME_DEATHMATCH) + Draw_AlphaPic (x /* + ((vid.width - 320)>>1)*/, y + + +(vid.height-SBAR_HEIGHT), pic, alpha); + else + Draw_AlphaPic (x + ((vid.width - 320)>>1), y + (vid.height-SBAR_HEIGHT), pic, alpha); + } +} +/* +============= +Sbar_DrawPic +============= +*/ +void Sbar_DrawPic (int x, int y, qpic_t *pic) +{ + if(kurok) + Draw_Pic (x /* + ((vid.width - 320)>>1)*/, y + (vid.height-SBAR_HEIGHT), pic); + else + { + if (cl.gametype == GAME_DEATHMATCH) + Draw_Pic (x /* + ((vid.width - 320)>>1)*/, y + (vid.height-SBAR_HEIGHT), pic); + else + Draw_Pic (x + ((vid.width - 320)>>1), y + (vid.height-SBAR_HEIGHT), pic); + } +} +/* +============= +Sbar_DrawTransPic +============= +*/ +void Sbar_DrawTransPic (int x, int y, qpic_t *pic) +{ + if(kurok) + Draw_TransPic (x /*+ ((vid.width - 320)>>1)*/, y + (vid.height-SBAR_HEIGHT), pic); + else + { + if (cl.gametype == GAME_DEATHMATCH) + Draw_TransPic (x /*+ ((vid.width - 320)>>1)*/, y + (vid.height-SBAR_HEIGHT), pic); + else + Draw_TransPic (x + ((vid.width - 320)>>1), y + (vid.height-SBAR_HEIGHT), pic); + } +} + +/* +================ +Sbar_DrawCharacter + +Draws one solid graphics character +================ +*/ +void Sbar_DrawCharacter (int x, int y, int num) +{ + if(kurok) + Draw_Character ( x /*+ ((vid.width - 320)>>1) */ + 4 , y + vid.height-SBAR_HEIGHT, num); + else + { + if (cl.gametype == GAME_DEATHMATCH) + Draw_Character ( x /*+ ((vid.width - 320)>>1) */ + 4 , y + vid.height-SBAR_HEIGHT, num); + else + Draw_Character ( x + ((vid.width - 320)>>1) + 4 , y + vid.height-SBAR_HEIGHT, num); + } +} + +/* +================ +Sbar_DrawString +================ +*/ +void Sbar_DrawString (int x, int y, char *str) +{ + if(kurok) + Draw_String (x /*+ ((vid.width - 320)>>1)*/, y + vid.height-SBAR_HEIGHT, str); + else + { + if (cl.gametype == GAME_DEATHMATCH) + Draw_String (x /*+ ((vid.width - 320)>>1)*/, y+ vid.height-SBAR_HEIGHT, str); + else + Draw_String (x + ((vid.width - 320)>>1), y+ vid.height-SBAR_HEIGHT, str); + } +} + +/* +=============== +Sbar_DrawScrollString -- johnfitz + +scroll the string inside a glscissor region +=============== +*/ +void Sbar_DrawScrollString (int x, int y, int width, char* str) +{ + int len, ofs; + + y += vid.height-SBAR_HEIGHT; +// if (cl.gametype != GAME_DEATHMATCH) x += ((vid.width - 320)>>1); + + len = strlen(str)*8 + 40; + ofs = ((int)(realtime*30))%len; + +// sceGuEnable(GU_SCISSOR_TEST); +// sceGuViewport (x, y, glwidth, glheight); +// sceGuScissor (x, vid.height - y - 8, 160, 8); + + Draw_String (x - ofs, y, str); + Draw_String (x - ofs + len - 32, y, "///"); + Draw_String (x - ofs + len, y, str); + +// sceGuDisable(GU_SCISSOR_TEST); +} + +/* +============= +Sbar_itoa +============= +*/ +int Sbar_itoa (int num, char *buf) +{ + char *str; + int pow10; + int dig; + + str = buf; + + if (num < 0) + { + *str++ = '-'; + num = -num; + } + + for (pow10 = 10 ; num >= pow10 ; pow10 *= 10) + ; + + do + { + pow10 /= 10; + dig = num/pow10; + *str++ = '0'+dig; + num -= dig*pow10; + } while (pow10 != 1); + + *str = 0; + + return str-buf; +} + + +/* +============= +Sbar_DrawNum +============= +*/ +void Sbar_DrawNum (int x, int y, int num, int digits, int color) +{ + char str[12]; + char *ptr; + int l, frame; + + l = Sbar_itoa (num, str); + ptr = str; + if (l > digits) + ptr += (l-digits); + + if (l < digits) + { + if (kurok) + x += (digits-l)*16; + else + x += (digits-l)*24; + } + + while (*ptr) + { + if (*ptr == '-') + frame = STAT_MINUS; + else + frame = *ptr -'0'; + + Sbar_DrawTransPic (x,y,sb_nums[color][frame]); + + if (kurok) + x += 16; + else + x += 24; + ptr++; + } +} + +/* +============= +Sbar_DrawNum2 +============= +*/ +void Sbar_DrawNum2 (int x, int y, int num, int digits, int color) +{ + char str[12]; + char *ptr; + int l, frame; + + l = Sbar_itoa (num, str); + ptr = str; + if (l > digits) + ptr += (l-digits); + + if (l < digits) + x += (digits-l)*0; + + while (*ptr) + { + if (*ptr == '-') + frame = STAT_MINUS; + else + frame = *ptr -'0'; + + M_DrawPic (x,y,sb_nums[color][frame]); + + x += 10; + ptr++; + } +} + +//============================================================================= + +int fragsort[MAX_SCOREBOARD]; + +char scoreboardtext[MAX_SCOREBOARD][20]; +int scoreboardtop[MAX_SCOREBOARD]; +int scoreboardbottom[MAX_SCOREBOARD]; +int scoreboardcount[MAX_SCOREBOARD]; +int scoreboardlines; + +/* +=============== +Sbar_SortFrags +=============== +*/ +void Sbar_SortFrags (void) +{ + int i, j, k; + +// sort by frags + scoreboardlines = 0; + for (i=0 ; ifrags, s->name); + + top = s->colors & 0xf0; + bottom = (s->colors & 15) <<4; + scoreboardtop[i] = Sbar_ColorForMap (top); + scoreboardbottom[i] = Sbar_ColorForMap (bottom); + } +} + + + +/* +=============== +Sbar_SoloScoreboard +=============== +*/ +void Sbar_SoloScoreboard (void) +{ + char str[80]; + int minutes, seconds, tens, units; + int len; + + if(kurok) + sprintf (str,"Enemies :%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]); + else + sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]); + Sbar_DrawString (8, 4, str); + + if(kurok) + sprintf (str,"Objectives :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]); + else + sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]); + Sbar_DrawString (8, 12, str); + +// time + minutes = cl.time / 60; + seconds = cl.time - 60*minutes; + tens = seconds / 10; + units = seconds - 10*tens; + sprintf (str,"Time :%3i:%i%i", minutes, tens, units); + Sbar_DrawString (184, 4, str); + + //johnfitz -- scroll long levelnames + len = strlen (cl.levelname); +#ifdef PSP_HARDWARE_VIDEO + if (len > 22) + Sbar_DrawScrollString (184, 12, 160, cl.levelname); + else +#endif +// Sbar_DrawString (232 - len*4, 12, cl.levelname); + Sbar_DrawString (184, 12, cl.levelname); + //johnfitz + +// draw level name +// l = strlen (cl.levelname); +// Sbar_DrawString (232 - l*4, 12, cl.levelname); +} + +/* +=============== +Sbar_DrawScoreboard +=============== +*/ +void Sbar_DrawScoreboard (void) +{ + Sbar_SoloScoreboard (); + if (cl.gametype == GAME_DEATHMATCH) + Sbar_DeathmatchOverlay (); +#if 0 + int i, j, c; + int x, y; + int l; + int top, bottom; + scoreboard_t *s; + + if (cl.gametype != GAME_DEATHMATCH) + { + Sbar_SoloScoreboard (); + return; + } + + Sbar_UpdateScoreboard (); + + l = scoreboardlines <= 6 ? scoreboardlines : 6; + + for (i=0 ; iname[0]) + continue; + + // draw background + top = s->colors & 0xf0; + bottom = (s->colors & 15)<<4; + top = Sbar_ColorForMap (top); + bottom = Sbar_ColorForMap (bottom); + + Draw_Fill ( x*8+10 + ((vid.width - 320)>>1), y + vid.height - SBAR_HEIGHT, 28, 4, top); + Draw_Fill ( x*8+10 + ((vid.width - 320)>>1), y+4 + vid.height - SBAR_HEIGHT, 28, 4, bottom); + + // draw text + for (j=0 ; j<20 ; j++) + { + c = scoreboardtext[i][j]; + if (c == 0 || c == ' ') + continue; + Sbar_DrawCharacter ( (x+j)*8, y, c); + } + } +#endif +} + +//============================================================================= + +/* +=============== +Sbar_DrawInventory +=============== +*/ +void Sbar_DrawInventory (void) +{ + int i; + char num[6]; + float time; + int flashon; + + if (rogue) + { + if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN ) + Sbar_DrawPic (0, -24, rsb_invbar[0]); + else + Sbar_DrawPic (0, -24, rsb_invbar[1]); + } + else if (!kurok) + Sbar_DrawPic (0, -24, sb_ibar); + +// weapons + if (!kurok) + { + for (i=0 ; i<7 ; i++) + { + if (cl.items & (IT_SHOTGUN<= 10) + { + if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN< 1) + sb_updates = 0; // force update to remove flash + } + } + } +// MED 01/04/97 +// hipnotic weapons + if (hipnotic) + { + int grenadeflashing=0; + for (i=0 ; i<4 ; i++) + { + if (cl.items & (1<= 10) + { + if ( cl.stats[STAT_ACTIVEWEAPON] == (1< 1) + sb_updates = 0; // force update to remove flash + } + } + } + + if (rogue) + { + // check for powered up weapon. + if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN ) + { + for (i=0;i<5;i++) + { + if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i)) + { + Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]); + } + } + } + } + + if (!kurok) + { + +// ammo counts + for (i=0 ; i<4 ; i++) + { + sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] ); + if (num[0] != ' ') + Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0'); + if (num[1] != ' ') + Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0'); + if (num[2] != ' ') + Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0'); + } + } + flashon = 0; + + // items + for (i=0 ; i<6 ; i++) + if (cl.items & (1<<(17+i))) + { + time = cl.item_gettime[17+i]; + if (time && time > cl.time - 2 && flashon ) + { // flash frame + sb_updates = 0; + } + else + { + //MED 01/04/97 changed keys + if (!hipnotic || (i>1)) + { + if(kurok) + Sbar_DrawPic (80 + i*16, 0, sb_items[i]); + else + Sbar_DrawPic (192 + i*16, -16, sb_items[i]); + } + } + if (time && time > cl.time - 2) + sb_updates = 0; + } + + //MED 01/04/97 added hipnotic items + // hipnotic items + if (hipnotic) + { + for (i=0 ; i<2 ; i++) + if (cl.items & (1<<(24+i))) + { + time = cl.item_gettime[24+i]; + if (time && time > cl.time - 2 && flashon ) + { // flash frame + sb_updates = 0; + } + else + { + Sbar_DrawPic (288 + i*16, -16, hsb_items[i]); + } + if (time && time > cl.time - 2) + sb_updates = 0; + } + } + + if (rogue) + { + // new rogue items + for (i=0 ; i<2 ; i++) + { + if (cl.items & (1<<(29+i))) + { + time = cl.item_gettime[29+i]; + + if (time && time > cl.time - 2 && flashon ) + { // flash frame + sb_updates = 0; + } + else + { + Sbar_DrawPic (288 + i*16, -16, rsb_items[i]); + } + + if (time && time > cl.time - 2) + sb_updates = 0; + } + } + } + + if (kurok) + { +/* + // new kurok items + for (i=0 ; i<2 ; i++) + { + if (cl.items & (1<<(29+i))) + { + time = cl.item_gettime[29+i]; + + if (time && time > cl.time - 2 && flashon ) + { // flash frame + sb_updates = 0; + } + else + { + Sbar_DrawPic (288 + i*16, -16, rsb_items[i]); + } + + if (time && time > cl.time - 2) + sb_updates = 0; + } + } +*/ + } + + else + { + // sigils + for (i=0 ; i<4 ; i++) + { + if (cl.items & (1<<(28+i))) + { + time = cl.item_gettime[28+i]; + if (time && time > cl.time - 2 && flashon ) + { // flash frame + sb_updates = 0; + } + else + Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]); + if (time && time > cl.time - 2) + sb_updates = 0; + } + } + } +} + +//============================================================================= + +/* +=============== +Sbar_DrawFrags +=============== +*/ +void Sbar_DrawFrags (void) +{ + int i, k, l; + int top, bottom; + int x, y, f; + int xofs; + char num[12]; + scoreboard_t *s; + + Sbar_SortFrags (); + +// draw the text + l = scoreboardlines <= 4 ? scoreboardlines : 4; + + x = 23; + + if (kurok) + { + xofs = 0; + } + else + { + if (cl.gametype == GAME_DEATHMATCH) + xofs = 0; + else + xofs = (vid.width - 320)>>1; + } + + y = vid.height - SBAR_HEIGHT - 23; + + for (i=0 ; iname[0]) + continue; + + // draw background + top = s->colors & 0xf0; + bottom = (s->colors & 15)<<4; + top = Sbar_ColorForMap (top); + bottom = Sbar_ColorForMap (bottom); + + Draw_Fill (xofs + x*8 + 10, y, 28, 4, top); + Draw_Fill (xofs + x*8 + 10, y+4, 28, 3, bottom); + + // draw number + f = s->frags; + sprintf (num, "%3i",f); + + Sbar_DrawCharacter ( (x+1)*8 , -24, num[0]); + Sbar_DrawCharacter ( (x+2)*8 , -24, num[1]); + Sbar_DrawCharacter ( (x+3)*8 , -24, num[2]); + + if (k == cl.viewentity - 1) + { + Sbar_DrawCharacter (x*8+2, -24, 16); + Sbar_DrawCharacter ( (x+4)*8-4, -24, 17); + } + x+=4; + } +} + +//============================================================================= + + +/* +=============== +Sbar_DrawFace +=============== +*/ +void Sbar_DrawFace (void) +{ + int f, anim; + +// PGM 01/19/97 - team color drawing +// PGM 03/02/97 - fixed so color swatch only appears in CTF modes + if (rogue && + (cl.maxclients != 1) && + (teamplay.value>3) && + (teamplay.value<7)) + { + int top, bottom; + int xofs; + char num[12]; + scoreboard_t *s; + + s = &cl.scores[cl.viewentity - 1]; + // draw background + top = s->colors & 0xf0; + bottom = (s->colors & 15)<<4; + top = Sbar_ColorForMap (top); + bottom = Sbar_ColorForMap (bottom); + + if (kurok) + { + xofs = 113; + } + else + { + if (cl.gametype == GAME_DEATHMATCH) + xofs = 113; + else + xofs = ((vid.width - 320)>>1) + 113; + } + + Sbar_DrawPic (112, 0, rsb_teambord); + Draw_Fill (xofs, vid.height-SBAR_HEIGHT+3, 22, 9, top); + Draw_Fill (xofs, vid.height-SBAR_HEIGHT+12, 22, 9, bottom); + + // draw number + f = s->frags; + sprintf (num, "%3i",f); + + if (top==8) + { + if (num[0] != ' ') + Sbar_DrawCharacter(109, 3, 18 + num[0] - '0'); + if (num[1] != ' ') + Sbar_DrawCharacter(116, 3, 18 + num[1] - '0'); + if (num[2] != ' ') + Sbar_DrawCharacter(123, 3, 18 + num[2] - '0'); + } + else + { + Sbar_DrawCharacter ( 109, 3, num[0]); + Sbar_DrawCharacter ( 116, 3, num[1]); + Sbar_DrawCharacter ( 123, 3, num[2]); + } + + return; + } +// PGM 01/19/97 - team color drawing + + if (!kurok) + { + + if ( (cl.items & (IT_INVISIBILITY | IT_INVULNERABILITY) ) + == (IT_INVISIBILITY | IT_INVULNERABILITY) ) + { + if (kurok) + Sbar_DrawPic (8, 0, sb_face_invis_invuln); + else + Sbar_DrawPic (112, 0, sb_face_invis_invuln); + return; + } + if (cl.items & IT_QUAD) + { + if (kurok) + Sbar_DrawPic (8, 0, sb_face_quad ); + else + Sbar_DrawPic (112, 0, sb_face_quad ); + return; + } + if (cl.items & IT_INVISIBILITY) + { + if (kurok) + Sbar_DrawPic (8, 0, sb_face_invis ); + else + Sbar_DrawPic (112, 0, sb_face_invis ); + return; + } + if (cl.items & IT_INVULNERABILITY) + { + if (kurok) + Sbar_DrawPic (8, 0, sb_face_invuln); + else + Sbar_DrawPic (112, 0, sb_face_invuln); + return; + } + + } + +/* +======================================== +Health bar edges +======================================== +*/ + if (cl.stats[STAT_HEALTH] <= 30) + { + M_DrawPic ( (324-health_bar_red->width)/2, 16, health_bar_red); + } + else + { + M_DrawPic ( (324-health_bar->width)/2, 16, health_bar); + } + + + +/* +=================================== +Health bar 2 (322 = middle) +=================================== +*/ +if (cl.stats[STAT_HEALTH] >= 130) + { + M_DrawPic ( (422-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 129) + { + M_DrawPic ( (420-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 128) + { + M_DrawPic ( (418-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 127) + { + M_DrawPic ( (416-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 126) + { + M_DrawPic ( (414-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 125) + { + M_DrawPic ( (412-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 124) + { + M_DrawPic ( (410-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 123) + { + M_DrawPic ( (408-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 122) + { + M_DrawPic ( (406-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 121) + { + M_DrawPic ( (404-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 120) + { + M_DrawPic ( (402-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 119) + { + M_DrawPic ( (400-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 118) + { + M_DrawPic ( (398-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 117) + { + + M_DrawPic ( (396-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 116) + { + + M_DrawPic ( (394-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 115) + { + + M_DrawPic ( (392-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 114) + { + + M_DrawPic ( (390-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 113) + { + + M_DrawPic ( (388-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 112) + { + + M_DrawPic ( (386-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 111) + { + + M_DrawPic ( (384-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 110) + { + + M_DrawPic ( (382-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 109) + { + + M_DrawPic ( (380-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 108) + { + + M_DrawPic ( (378-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 107) + { + + M_DrawPic ( (376-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 106) + { + + M_DrawPic ( (374-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 105) + { + + M_DrawPic ( (372-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 104) + { + + M_DrawPic ( (370-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 103) + { + + M_DrawPic ( (368-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 102) + { + + M_DrawPic ( (366-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 101) + { + + M_DrawPic ( (364-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 100) + { + + M_DrawPic ( (362-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 99) + { + + M_DrawPic ( (360-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 98) + { + + M_DrawPic ( (358-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 97) + { + + M_DrawPic ( (356-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 96) + { + + M_DrawPic ( (354-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 95) + { + + M_DrawPic ( (352-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 94) + { + + M_DrawPic ( (350-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 93) + { + + M_DrawPic ( (348-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 92) + { + + M_DrawPic ( (346-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 91) + { + + M_DrawPic ( (344-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 90) + { + + M_DrawPic ( (342-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 89) + { + + M_DrawPic ( (340-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 88) + { + + M_DrawPic ( (338-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 87) + { + + M_DrawPic ( (336-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 86) + { + + M_DrawPic ( (334-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 85) + { + + M_DrawPic ( (332-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 84) + { + + M_DrawPic ( (330-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 83) + { + + M_DrawPic ( (328-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 82) + { + + M_DrawPic ( (326-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 81) + { + + M_DrawPic ( (324-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 80) + { + + M_DrawPic ( (322-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 79) + { + + M_DrawPic ( (320-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 78) + { + + M_DrawPic ( (318-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 77) + { + + M_DrawPic ( (316-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 76) + { + + M_DrawPic ( (314-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 75) + { + + M_DrawPic ( (312-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 74) + { + + M_DrawPic ( (310-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 73) + { + + M_DrawPic ( (308-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 72) //Checkpoint + { + + M_DrawPic ( (306-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 71) + { + + M_DrawPic ( (304-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 70) + { + + M_DrawPic ( (302-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 69) + { + + M_DrawPic ( (300-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 68) + { + + M_DrawPic ( (298-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 67) + { + + M_DrawPic ( (296-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 66) + { + + M_DrawPic ( (294-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 65) + { + + M_DrawPic ( (292-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 64) + { + + M_DrawPic ( (290-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 63) + { + + M_DrawPic ( (288-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 62) + { + + M_DrawPic ( (286-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 61) + { + + M_DrawPic ( (284-life90->width)/2, 20, life90 ); + } + + if (cl.stats[STAT_HEALTH] > 60) + { + + M_DrawPic ( (282-life90->width)/2, 20, life90 ); + } + + if (cl.stats[STAT_HEALTH] >= 59) + { + + M_DrawPic ( (280-life90->width)/2, 20, life90 ); + } + + if (cl.stats[STAT_HEALTH] >= 58) + { + + M_DrawPic ( (278-life90->width)/2, 20, life90 ); + } + + if (cl.stats[STAT_HEALTH] >= 57) + { + + M_DrawPic ( (276-life90->width)/2, 20, life90 ); + } + + if (cl.stats[STAT_HEALTH] >= 56) + { + + M_DrawPic ( (274-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 55) + { + + M_DrawPic ( (272-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 54) + { + + M_DrawPic ( (270-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 53) + { + + M_DrawPic ( (268-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 52) + { + + M_DrawPic ( (266-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 51) //Checkpoint 2 + { + + M_DrawPic ( (264-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 50) + { + + M_DrawPic ( (262-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 49) + { + + M_DrawPic ( (260-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 48) + { + + M_DrawPic ( (258-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 47) + { + + M_DrawPic ( (256-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 46) + { + + M_DrawPic ( (254-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 45) + { + + M_DrawPic ( (252-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 44) + { + + M_DrawPic ( (250-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 43) + { + + M_DrawPic ( (248-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 42) + { + + M_DrawPic ( (246-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 41) + { + + M_DrawPic ( (244-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 40) + { + + M_DrawPic ( (242-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 39) + { + + M_DrawPic ( (240-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 38) + { + + M_DrawPic ( (238-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 37) + { + + M_DrawPic ( (236-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 36) + { + + M_DrawPic ( (234-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 35) + { + + M_DrawPic ( (232-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 34) + { + + M_DrawPic ( (230-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 33) + { + + M_DrawPic ( (228-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 32) + { + + M_DrawPic ( (226-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 31) + { + + M_DrawPic ( (224-life90->width)/2, 20, life90 ); + } + if (cl.stats[STAT_HEALTH] >= 30) + { + } + + + + +/* +=================================== +Displays weapons that are on the ground. +=================================== +*/ + //Assault rifle + if (cl_ww.value == 1) + { + + M_DrawPic ( (680-ARW->width)/2, 55, ARW); + } + //plasma Pistol + if (cl_ww.value == 2) + { + M_DrawPic ( (680-ppistW->width)/2, 55, ppistW ); + } + //Shottie + if (cl_ww.value == 3) + { + M_DrawPic ( (680-ShottieW->width)/2, 55, ShottieW ); + } + //Needler + if (cl_ww.value == 4) + { + M_DrawPic ( (680-NeedlerW->width)/2, 55, NeedlerW ); + } + //Rocket Launcher + if (cl_ww.value == 5) + { + M_DrawPic ( (680-RLW->width)/2, 55, RLW ); + } + //Pistol + if (cl_ww.value == 6) + { + M_DrawPic ( (680-PistolW->width)/2, 55, PistolW ); + } + //SMG + if (cl_ww.value == 7) + { + M_DrawPic ( (680-SMGW->width)/2, 55, SMGW ); + } + //Sniper + if (cl_ww.value == 8) + { + M_DrawPic ( (680-SniperW->width)/2, 55, SniperW ); + } +/* +=================================== +Weapon HUD. Displays current weapon +=================================== +*/ + //Assault rifle + if (cl.stats[STAT_ACTIVEWEAPON] == IT_NAILGUN) + { + M_DrawPic ( (680-AR->width)/2, 15, AR); + } + //plasma Pistol + if (cl.stats[STAT_ACTIVEWEAPON] == IT_LIGHTNING) + { + M_DrawPic ( (680-ppist->width)/2, 15, ppist ); + } + //Shottie + if (cl.stats[STAT_ACTIVEWEAPON] == IT_SUPER_SHOTGUN) + { + M_DrawPic ( (680-Shottie->width)/2, 15, Shottie ); + } + //Needler + if (cl.stats[STAT_ACTIVEWEAPON] == IT_EXTRA_WEAPON) + { + M_DrawPic ( (680-Needler->width)/2, 15, Needler ); + } + //Rocket Launcher + if (cl.stats[STAT_ACTIVEWEAPON] == IT_ROCKET_LAUNCHER) + { + M_DrawPic ( (680-RL->width)/2, 15, RL ); + } + //Pistol + if (cl.stats[STAT_ACTIVEWEAPON] == IT_SHOTGUN) + { + M_DrawPic ( (680-Pistol->width)/2, 15, Pistol ); + } + //SMG + if (cl.stats[STAT_ACTIVEWEAPON] == IT_SUPER_NAILGUN) + { + M_DrawPic ( (680-SMG->width)/2, 15, SMG ); + } + //Sniper + if (cl.stats[STAT_ACTIVEWEAPON] == IT_GRENADE_LAUNCHER) + { + M_DrawPic ( (680-Sniper->width)/2, 15, Sniper ); + } + +/* +=================================== +Needle ammo counter +=================================== +*/ + + if (cl.stats[STAT_ACTIVEWEAPON] == IT_EXTRA_WEAPON) + { + if (cl.stats[STAT_AMMO] >= 20) + { + M_DrawPic ( (620-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 19) + { + M_DrawPic ( (626-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 18) + { + M_DrawPic ( (632-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 17) + { + M_DrawPic ( (638-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 16) + { + M_DrawPic ( (644-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 15) + { + M_DrawPic ( (650-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 14) + { + + M_DrawPic ( (656-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 13) + { + + M_DrawPic ( (662-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 12) + { + + M_DrawPic ( (668-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 11) + { + + M_DrawPic ( (674-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 10) + { + + M_DrawPic ( (680-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 9) + { + + M_DrawPic ( (686-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 8) + { + + M_DrawPic ( (692-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 7) + { + + M_DrawPic ( (698-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 6) + { + + M_DrawPic ( (704-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 5) + { + + M_DrawPic ( (710-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 4) + { + + M_DrawPic ( (716-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 3) + { + + M_DrawPic ( (722-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 2) + { + + M_DrawPic ( (728-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 1) + { + + M_DrawPic ( (734-needleb->width)/2, 43, needleb); + } + if (cl.stats[STAT_AMMO] >= 0) + { + } + + } +/* +=================================== +Assault rifle counter +=================================== +*/ + if (cl.stats[STAT_ACTIVEWEAPON] == IT_NAILGUN) + { + if (cl.stats[STAT_AMMO] >= 32) + { + + M_DrawPic ( (650-arb->width)/2, 36, arb); + } + + if (cl.stats[STAT_AMMO] >= 31) + { + + M_DrawPic ( (656-arb->width)/2, 36, arb); + } + + if (cl.stats[STAT_AMMO] >= 30) + { + + M_DrawPic ( (662-arb->width)/2, 36, arb); + } + + if (cl.stats[STAT_AMMO] >= 29) + { + + M_DrawPic ( (668-arb->width)/2, 36, arb); + } + + if (cl.stats[STAT_AMMO] >= 28) + { + + M_DrawPic ( (674-arb->width)/2, 36, arb); + } + + if (cl.stats[STAT_AMMO] >= 27) + { + + M_DrawPic ( (680-arb->width)/2, 36, arb); + } + + if (cl.stats[STAT_AMMO] >= 26) + { + + M_DrawPic ( (686-arb->width)/2, 36, arb); + } + if (cl.stats[STAT_AMMO] >= 25) + { + + M_DrawPic ( (692-arb->width)/2, 36, arb); + } + if (cl.stats[STAT_AMMO] >= 24) + { + + M_DrawPic ( (698-arb->width)/2, 36, arb); + } + if (cl.stats[STAT_AMMO] >= 23) + { + + M_DrawPic ( (704-arb->width)/2, 36, arb); + } + if (cl.stats[STAT_AMMO] >= 22) + { + + M_DrawPic ( (710-arb->width)/2, 36, arb); + } + if (cl.stats[STAT_AMMO] >= 21) + { + + M_DrawPic ( (716-arb->width)/2, 36, arb); + } + if (cl.stats[STAT_AMMO] >= 20) + { + + M_DrawPic ( (722-arb->width)/2, 36, arb); + } + if (cl.stats[STAT_AMMO] >= 19) + { + + M_DrawPic ( (728-arb->width)/2, 36, arb); + } + if (cl.stats[STAT_AMMO] >= 18) + { + + M_DrawPic ( (734-arb->width)/2, 36, arb); + } + if (cl.stats[STAT_AMMO] >= 17) + { + + M_DrawPic ( (740-arb->width)/2, 36, arb); + } + if (cl.stats[STAT_AMMO] >= 16) + { + + M_DrawPic ( (650-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 15) + { + + M_DrawPic ( (656-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 14) + { + + M_DrawPic ( (662-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 13) + { + + M_DrawPic ( (668-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 12) + { + + M_DrawPic ( (674-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 11) + { + + M_DrawPic ( (680-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 10) + { + + M_DrawPic ( (686-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 9) + { + + M_DrawPic ( (692-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 8) + { + + M_DrawPic ( (698-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 7) + { + + M_DrawPic ( (704-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 6) + { + + M_DrawPic ( (710-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 5) + { + + M_DrawPic ( (716-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 4) + { + + M_DrawPic ( (722-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 3) + { + + M_DrawPic ( (728-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 2) + { + + M_DrawPic ( (734-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 1) + { + + M_DrawPic ( (740-arb->width)/2, 43, arb); + } + if (cl.stats[STAT_AMMO] >= 0) + { + } + + } +/* +=================================== +Rocket Ammo counter +=================================== +*/ + if (cl.stats[STAT_ACTIVEWEAPON] == IT_ROCKET_LAUNCHER) + { + if (cl.stats[STAT_AMMO] >= 2) + { + + M_DrawPic ( (665-rocketb->width)/2, 47, rocketb); + } + + if (cl.stats[STAT_AMMO] >= 1) + { + + M_DrawPic ( (735-rocketb->width)/2, 47, rocketb); + } + + if (cl.stats[STAT_AMMO] >= 0) + { + } + + } +/* +=================================== +Shotgun Ammo counter +=================================== +*/ + if (cl.stats[STAT_ACTIVEWEAPON] == IT_SUPER_SHOTGUN) + { + if (cl.stats[STAT_AMMO] >= 6) + { + + M_DrawPic ( (690-shotgunb->width)/2, 36, shotgunb); + } + + if (cl.stats[STAT_AMMO] >= 5) + { + + M_DrawPic ( (700-shotgunb->width)/2, 36, shotgunb); + } + + if (cl.stats[STAT_AMMO] >= 4) + { + + M_DrawPic ( (710-shotgunb->width)/2, 36, shotgunb); + } + + if (cl.stats[STAT_AMMO] >= 3) + { + + M_DrawPic ( (720-shotgunb->width)/2, 36, shotgunb); + } + + if (cl.stats[STAT_AMMO] >= 2) + { + + M_DrawPic ( (730-shotgunb->width)/2, 36, shotgunb); + } + + if (cl.stats[STAT_AMMO] >= 1) + { + + M_DrawPic ( (740-shotgunb->width)/2, 36, shotgunb); + } + + if (cl.stats[STAT_AMMO] >= 0) + { + } + + } + +/* +=================================== +Pistol ammo counter +=================================== +*/ + if (cl.stats[STAT_ACTIVEWEAPON] == IT_SHOTGUN) + { + //Pistol + if (cl.stats[STAT_AMMO] >= 12) + { + + M_DrawPic ( (690-pistolb->width)/2, 35, pistolb); + } + + if (cl.stats[STAT_AMMO] >= 11) + { + + M_DrawPic ( (696-pistolb->width)/2, 35, pistolb); + } + + if (cl.stats[STAT_AMMO] >= 10) + { + + M_DrawPic ( (702-pistolb->width)/2, 35, pistolb); + } + + if (cl.stats[STAT_AMMO] >= 9) + { + + M_DrawPic ( (708-pistolb->width)/2, 35, pistolb); + } + + if (cl.stats[STAT_AMMO] >= 8) + { + + M_DrawPic ( (714-pistolb->width)/2, 35, pistolb); + } + + if (cl.stats[STAT_AMMO] >= 7) + { + + M_DrawPic ( (720-pistolb->width)/2, 35, pistolb); + } + + if (cl.stats[STAT_AMMO] >= 6) + { + + M_DrawPic ( (726-pistolb->width)/2, 35, pistolb); + } + + if (cl.stats[STAT_AMMO] >= 5) + { + + M_DrawPic ( (732-pistolb->width)/2, 35, pistolb); + } + + if (cl.stats[STAT_AMMO] >= 4) + { + + M_DrawPic ( (738-pistolb->width)/2, 35, pistolb); + } + + if (cl.stats[STAT_AMMO] >= 3) + { + + M_DrawPic ( (744-pistolb->width)/2, 35, pistolb); + } + + if (cl.stats[STAT_AMMO] >= 2) + { + + M_DrawPic ( (750-pistolb->width)/2, 35, pistolb); + } + + if (cl.stats[STAT_AMMO] >= 1) + { + + M_DrawPic ( (756-pistolb->width)/2, 35, pistolb); + } + + if (cl.stats[STAT_AMMO] >= 0) + { + } + + } + +/* +=================================== +Grenade counter numbers +=================================== +*/ + if (cl_nadenum.value == 1) + { + M_DrawPic ((-40 - numbers[0]->width)/2, 15, numbers[0]); + } + if (cl_nadenum.value == 2) + { + M_DrawPic ( (-40-numbers[1]->width)/2, 15, numbers[1] ); + } + if (cl_nadenum.value == 3) + { + M_DrawPic ( (-40-numbers[2]->width)/2, 15, numbers[2] ); + } + if (cl_nadenum.value == 4) + { + M_DrawPic ( (-40-numbers[3]->width)/2, 15, numbers[3] ); + } + if (cl_nadenum.value == 5) + { + M_DrawPic ( (-40-numbers[4]->width)/2, 15, numbers[4] ); + } + +/* +=================================== +Displays what Grenade you currently have. +=================================== +*/ + //For Plasma Nades. + if (cl_plasmanade.value == 1) + { + M_DrawPic ( (-70-plasma->width)/2, 15, plasma); + } + + //These are Actually Frag Grenades. + if (cl_plasmanade.value == 2) + { + M_DrawPic ( (-70-frag->width)/2, 15, frag); + } +/* +=================================== +Kill medals +=================================== +*/ + if (cl_killmedals.value == 1) + { + M_DrawPic ( (-70-doublek->width)/2, 165, doublek ); + } + if (cl_killmedals.value == 2) + { + M_DrawPic ( (-70-triple->width)/2, 165, triple ); + } + if (cl_killmedals.value == 3) + { + M_DrawPic ( (-70-killtacular->width)/2, 165, killtacular ); + } + if (cl_killmedals.value == 4) + { + M_DrawPic ( (-70-killtrocity->width)/2, 165, killtrocity ); + } + + +} +/* +=============== +Sbar_Draw +=============== +*/ +void Sbar_Draw (void) +{ + extern cvar_t cl_gunpitch; + + if (scr_con_current == vid.height) + return; // console is full screen + + if (scr_viewsize.value == 130) + return; + + if (!kurok) + { + if (sb_updates >= vid.numpages) + return; + } + scr_copyeverything = 1; + + sb_updates++; + + if (sb_lines && vid.width > 320) + Draw_TileClear (0, vid.height - sb_lines, vid.width, sb_lines); + + if (kurok) + { + if (scr_viewsize.value < 130) + { + Sbar_DrawInventory (); + if (cl.maxclients != 1) + { + if (cl.stats[STAT_HEALTH] > 0) + { + Sbar_DeathmatchOverlay2 (); + Sbar_TimeOverlay(); + } + } + } + else// if (sb_lines < 24) + { + if (cl.maxclients != 1) + { + if (cl.stats[STAT_HEALTH] > 0) + { + Sbar_DeathmatchOverlay2 (); + Sbar_TimeOverlay(); + } + } + } + } + else + { + if (sb_lines > 24) + { + Sbar_DrawInventory (); + if (cl.maxclients != 1) + Sbar_DrawFrags (); + } + else if (sb_lines < 48) + { + if (cl.maxclients != 1) + { + if (cl.stats[STAT_HEALTH] > 0) + Sbar_DeathmatchOverlay2 (); + } + } + } + + if (sb_showscores || cl.stats[STAT_HEALTH] <= 0) + { + if(!kurok) + Sbar_DrawPic (0, 0, sb_scorebar); + Sbar_DrawScoreboard (); + sb_updates = 0; + } +// else if (sb_lines) + else if (sb_lines >= 0) + { + + if (!kurok) + { + if (sb_lines >= 24) + Sbar_DrawPic (0, 0, sb_sbar); + } + + // keys (hipnotic only) + //MED 01/04/97 moved keys here so they would not be overwritten + if (hipnotic) + { + if (cl.items & IT_KEY1) + Sbar_DrawPic (209, 3, sb_items[0]); + if (cl.items & IT_KEY2) + Sbar_DrawPic (209, 12, sb_items[1]); + } + // armor + if (cl.items & IT_INVULNERABILITY) + { + Sbar_DrawNum (24, 0, 666, 3, 1); + Sbar_DrawPic (0, 0, draw_disc); + } + else + { + if (rogue) + { + Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, + cl.stats[STAT_ARMOR] <= 25); + if (cl.items & RIT_ARMOR3) + Sbar_DrawPic (0, 0, sb_armor[2]); + else if (cl.items & RIT_ARMOR2) + Sbar_DrawPic (0, 0, sb_armor[1]); + else if (cl.items & RIT_ARMOR1) + Sbar_DrawPic (0, 0, sb_armor[0]); + } + } + + // face + Sbar_DrawFace (); + + // ammo icon + if (rogue) + { + if (cl.items & RIT_SHELLS) + Sbar_DrawPic (224, 0, sb_ammo[0]); + else if (cl.items & RIT_NAILS) + Sbar_DrawPic (224, 0, sb_ammo[1]); + else if (cl.items & RIT_ROCKETS) + Sbar_DrawPic (224, 0, sb_ammo[2]); + else if (cl.items & RIT_CELLS) + Sbar_DrawPic (224, 0, sb_ammo[3]); + else if (cl.items & RIT_LAVA_NAILS) + Sbar_DrawPic (224, 0, rsb_ammo[0]); + else if (cl.items & RIT_PLASMA_AMMO) + Sbar_DrawPic (224, 0, rsb_ammo[1]); + else if (cl.items & RIT_MULTI_ROCKETS) + Sbar_DrawPic (224, 0, rsb_ammo[2]); + } + + if (cl.stats[STAT_ARMOR] <= 0) + {} + else + { + if (kurok) + Sbar_DrawNum2 (620/2, 10, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25); + else + Sbar_DrawNum (620/2, 10, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25); + } + //if (cl.stats[STAT_HEALTH] <= 0) + //{} + //else + //{ + //if (kurok) + //{ + //if (cl.stats[STAT_ARMOR] >= 1) + //{} + //else + // Sbar_DrawNum2 (24, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25); + // } + //else + //Sbar_DrawNum (136, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25); + //} + +if (kurok) + { + if (!cl_gunpitch.value) + { + if (cl.stats[STAT_ACTIVEWEAPON] == IT_SHOTGUN) // Pistol + { + {}// Sbar_DrawNum (352, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 1); + {}// Sbar_DrawNum2 (418, 0, cl.stats[STAT_NAILS], 3, cl.stats[STAT_NAILS] <= 10); + } + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_NAILGUN) // Assualt rifle + { + {}// Sbar_DrawNum (352, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 1); + {}// Sbar_DrawNum2 (418, 0, cl.stats[STAT_NAILS], 3, cl.stats[STAT_NAILS] <= 10); + } + else if (cl.stats[STAT_ACTIVEWEAPON] == KIT_UZI) // Uzi + { + {}// Sbar_DrawNum (352, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 1); + {}// Sbar_DrawNum2 (418, 0, cl.stats[STAT_NAILS], 3, cl.stats[STAT_NAILS] <= 10); + } + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_SUPER_SHOTGUN) // Shotgun + {}// Sbar_DrawNum2 (418, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10); + + else if (cl.stats[STAT_ACTIVEWEAPON] == KIT_M99) // Sniper + {}// Sbar_DrawNum2 (418, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10); + + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_SUPER_NAILGUN) // Minigun + {}// Sbar_DrawNum2 (418, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10); + + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_GRENADE_LAUNCHER) // Grenade launcher + {}// Sbar_DrawNum2 (418, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10); + + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_ROCKET_LAUNCHER) // Rocket launcher + {}// Sbar_DrawNum2 (418, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10); + + else if (cl.stats[STAT_ACTIVEWEAPON] == IT_LIGHTNING) // Remote Mines + {}// Sbar_DrawNum2 (418, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10); + + else if (cl.stats[STAT_AMMO] <= 0) // Axe / Bow + { + + } + else + {}// Sbar_DrawNum2 ((740-shotgunb->width)/2, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] < 0); + } + } + else + {}//Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10); + } + +// Con_Printf ("I am an %i! woohoo!\n", cl.stats[STAT_ACTIVEWEAPON]); + +// if (vid.width > 320) { + if (cl.gametype == GAME_DEATHMATCH) + Sbar_MiniDeathmatchOverlay (); +// } +} + + +//============================================================================= + +/* +================== +Sbar_IntermissionNumber + +================== +*/ +void Sbar_IntermissionNumber (int x, int y, int num, int digits, int color) +{ + char str[12]; + char *ptr; + int l, frame; + + l = Sbar_itoa (num, str); + ptr = str; + if (l > digits) + ptr += (l-digits); + if (l < digits) + x += (digits-l)*24; + + while (*ptr) + { + if (*ptr == '-') + frame = STAT_MINUS; + else + frame = *ptr -'0'; + + Draw_TransPic (x,y,sb_nums[color][frame]); + x += 24; + ptr++; + } +} + + +/* +================== +Sbar_DeathmatchOverlay + +================== +*/ +void Sbar_DeathmatchOverlay (void) +{ + qpic_t *pic; + int i, k, l; + int top, bottom; + int x, y, f; + char num[12]; + scoreboard_t *s; + + scr_copyeverything = 1; + scr_fullupdate = 0; + + pic = Draw_CachePic ("gfx/ranking.lmp"); + M_DrawPic ((320-pic->width)/2, 8, pic); + +// scores + Sbar_SortFrags (); + +// draw the text + l = scoreboardlines; + + x = 80 + ((vid.width - 320)>>1); + y = 40; + for (i=0 ; iname[0]) + continue; + + // draw background + top = s->colors & 0xf0; + bottom = (s->colors & 15)<<4; + top = Sbar_ColorForMap (top); + bottom = Sbar_ColorForMap (bottom); + + Draw_Fill ( x, y, 40, 4, top); + Draw_Fill ( x, y+4, 40, 4, bottom); + + // draw number + f = s->frags; + sprintf (num, "%3i",f); + + Draw_Character ( x+8 , y, num[0]); + Draw_Character ( x+16 , y, num[1]); + Draw_Character ( x+24 , y, num[2]); + +// if (k == cl.viewentity - 1) +// Draw_Character ( x - 8, y, 12); + + if (k == cl.viewentity - 1) { + Draw_Character ( x, y, 16); + Draw_Character ( x + 32, y, 17); + } + +#if 0 +{ + int total; + int n, minutes, tens, units; + + // draw time + total = cl.completed_time - s->entertime; + minutes = (int)total/60; + n = total - minutes*60; + tens = n/10; + units = n%10; + + sprintf (num, "%3i:%i%i", minutes, tens, units); + + Draw_String ( x+48 , y, num); +} +#endif + + // draw name + Draw_String (x+64, y, s->name); + + y += 10; + } +} + +/* +================== +Sbar_DeathmatchOverlay + +================== +*/ +void Sbar_MiniDeathmatchOverlay (void) +{ + int i, k, l; + int top, bottom; + int x, y, f; + char num[12]; + scoreboard_t *s; + int numlines; + + if (vid.width < 512 || !sb_lines) + return; + + scr_copyeverything = 1; + scr_fullupdate = 0; + +// scores + Sbar_SortFrags (); + +// draw the text + l = scoreboardlines; + y = vid.height - sb_lines; + numlines = sb_lines/8; + if (numlines < 3) + return; + + //find us + for (i = 0; i < scoreboardlines; i++) + if (fragsort[i] == cl.viewentity - 1) + break; + + if (i == scoreboardlines) // we're not there + i = 0; + else // figure out start + i = i - numlines/2; + + if (i > scoreboardlines - numlines) + i = scoreboardlines - numlines; + if (i < 0) + i = 0; + + x = 324; + for (/* */; i < scoreboardlines && y < vid.height - 8 ; i++) + { + k = fragsort[i]; + s = &cl.scores[k]; + if (!s->name[0]) + continue; + + // draw background + top = s->colors & 0xf0; + bottom = (s->colors & 15)<<4; + top = Sbar_ColorForMap (top); + bottom = Sbar_ColorForMap (bottom); + + Draw_Fill ( x, y+1, 40, 3, top); + Draw_Fill ( x, y+4, 40, 4, bottom); + + // draw number + f = s->frags; + sprintf (num, "%3i",f); + + Draw_Character ( x+8 , y, num[0]); + Draw_Character ( x+16 , y, num[1]); + Draw_Character ( x+24 , y, num[2]); + + if (k == cl.viewentity - 1) { + Draw_Character ( x, y, 16); + Draw_Character ( x + 32, y, 17); + } + +#if 0 +{ + int total; + int n, minutes, tens, units; + + // draw time + total = cl.completed_time - s->entertime; + minutes = (int)total/60; + n = total - minutes*60; + tens = n/10; + units = n%10; + + sprintf (num, "%3i:%i%i", minutes, tens, units); + + Draw_String ( x+48 , y, num); +} +#endif + + // draw name + Draw_String (x+48, y, s->name); + + y += 8; + } +} + +/* +================== +Sbar_DeathmatchOverlay2 + +================== +*/ +void Sbar_DeathmatchOverlay2 (void) +{ +// qpic_t *pic; + int i, k, l; + int top, bottom; + int x, y, f; + char num[12]; + scoreboard_t *s; + + scr_copyeverything = 1; + scr_fullupdate = 0; + +// scores + Sbar_SortFrags (); + +// draw the text + l = scoreboardlines; + + x = 16; + y = 56; + for (i=0 ; iname[0]) + continue; + + // draw background + top = s->colors & 0xf0; + bottom = (s->colors & 15)<<4; + top = Sbar_ColorForMap (top); + bottom = Sbar_ColorForMap (bottom); + + Draw_Fill ( x, y, 24, 4, top); + Draw_Fill ( x, y+4, 24, 4, bottom); + + // draw number + f = s->frags; + sprintf (num, "%3i",f); + + Draw_Character ( x, y, num[0]); + Draw_Character ( x+8 , y, num[1]); + Draw_Character ( x+16 , y, num[2]); + + if (k == cl.viewentity - 1) + Draw_Character ( x - 8, y, 13); + + Draw_String (x+32, y, s->name); + + y += 10; + } +} + +/* +================== +Sbar_TimeOverlay + +================== +*/ + +void Sbar_TimeOverlay (void) +{ + char str[80]; + int minutes, seconds, tens, units; + int x, y; + + x = 8; + y = 56; + + minutes = cl.time / 60; + seconds = cl.time - 60*minutes; + tens = seconds / 10; + units = seconds - 10*tens; + sprintf (str,"Time %i:%i%i", minutes, tens, units); + Draw_String ( x, y - 16, str); +} +/* +================== +Sbar_IntermissionOverlay + +================== +*/ +void Sbar_IntermissionOverlay (void) +{ + qpic_t *pic; + int dig; + int num; + + scr_copyeverything = 1; + scr_fullupdate = 0; + + if (cl.gametype == GAME_DEATHMATCH) + { + Sbar_DeathmatchOverlay (); + return; + } + + pic = Draw_CachePic ("gfx/complete.lmp"); + Draw_Pic (64, 24, pic); + + pic = Draw_CachePic ("gfx/inter.lmp"); + Draw_TransPic (0, 56, pic); + +// time + dig = cl.completed_time/60; + Sbar_IntermissionNumber (160, 64, dig, 3, 0); + num = cl.completed_time - dig*60; + Draw_TransPic (234,64,sb_colon); + Draw_TransPic (246,64,sb_nums[0][num/10]); + Draw_TransPic (266,64,sb_nums[0][num%10]); + + Sbar_IntermissionNumber (160, 104, cl.stats[STAT_SECRETS], 3, 0); + Draw_TransPic (232,104,sb_slash); + Sbar_IntermissionNumber (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0); + + Sbar_IntermissionNumber (160, 144, cl.stats[STAT_MONSTERS], 3, 0); + Draw_TransPic (232,144,sb_slash); + Sbar_IntermissionNumber (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0); + +} + + +/* +================== +Sbar_FinaleOverlay + +================== +*/ +void Sbar_FinaleOverlay (void) +{ + qpic_t *pic; + + scr_copyeverything = 1; + + pic = Draw_CachePic ("gfx/finale.lmp"); + Draw_TransPic ( (vid.width-pic->width)/2, 16, pic); +} diff --git a/r17/Revamped src/revamped_src/sbar.h b/r17/Revamped src/revamped_src/sbar.h new file mode 100755 index 00000000..3dc5ad1c --- /dev/null +++ b/r17/Revamped src/revamped_src/sbar.h @@ -0,0 +1,40 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ + +// the status bar is only redrawn if something has changed, but if anything +// does, the entire thing will be redrawn for the next vid.numpages frames. + +#define SBAR_HEIGHT 24 + +extern int sb_lines; // scan lines to draw + +void Sbar_Init (void); + +void Sbar_Changed (void); +// call whenever any of the client stats represented on the sbar changes + +void Sbar_Draw (void); +// called every frame by screen +void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha); + +void Sbar_IntermissionOverlay (void); +// called each frame after the level has been completed + +void Sbar_FinaleOverlay (void); diff --git a/r17/Revamped src/revamped_src/screen.c b/r17/Revamped src/revamped_src/screen.c new file mode 100755 index 00000000..8251e0ea --- /dev/null +++ b/r17/Revamped src/revamped_src/screen.c @@ -0,0 +1,991 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// screen.c -- master for refresh, status bar, console, chat, notify, etc + +#include "quakedef.h" +#include "r_local.h" + +// only the refresh window will be updated unless these variables are flagged +int scr_copytop; +int scr_copyeverything; + +float scr_con_current; +float scr_conlines; // lines of console to display + +float oldscreensize, oldfov; +cvar_t scr_viewsize = {"viewsize","100", true}; +cvar_t scr_fov = {"fov","90"}; // 10 - 170 +cvar_t scr_conspeed = {"scr_conspeed","300"}; +cvar_t scr_centertime = {"scr_centertime","2"}; +cvar_t scr_showram = {"showram","1"}; +cvar_t scr_showturtle = {"showturtle","0"}; +cvar_t scr_showpause = {"showpause","1"}; +cvar_t scr_printspeed = {"scr_printspeed","8"}; + +qboolean scr_initialized; // ready to draw + +qpic_t *scr_ram; +qpic_t *scr_net; +qpic_t *scr_turtle; + +int scr_fullupdate; + +int clearconsole; +int clearnotify; + +viddef_t vid; // global video state + +vrect_t *pconupdate; +vrect_t scr_vrect; + +qboolean scr_disabled_for_loading; +qboolean scr_drawloading; +float scr_disabled_time; +qboolean scr_skipupdate; + +qboolean block_drawing; + +void SCR_ScreenShot_f (void); + +/* +=============================================================================== + +CENTER PRINTING + +=============================================================================== +*/ + +char scr_centerstring[1024]; +float scr_centertime_start; // for slow victory printing +float scr_centertime_off; +int scr_center_lines; +int scr_erase_lines; +int scr_erase_center; + +/* +============== +SCR_CenterPrint + +Called for important messages that should stay in the center of the screen +for a few moments +============== +*/ +void SCR_CenterPrint (char *str) +{ + strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1); + scr_centertime_off = scr_centertime.value; + scr_centertime_start = cl.time; + +// count the number of lines for centering + scr_center_lines = 1; + while (*str) + { + if (*str == '\n') + scr_center_lines++; + str++; + } +} + +void SCR_EraseCenterString (void) +{ + int y; + + if (scr_erase_center++ > vid.numpages) + { + scr_erase_lines = 0; + return; + } + + if (scr_center_lines <= 4) + y = vid.height*0.35; + else + y = 48; + + scr_copytop = 1; + Draw_TileClear (0, y,vid.width, 8*scr_erase_lines); +} + +void SCR_DrawCenterString (void) +{ + char *start; + int l; + int j; + int x, y; + int remaining; + +// the finale prints the characters one at a time + if (cl.intermission) + remaining = scr_printspeed.value * (cl.time - scr_centertime_start); + else + remaining = 9999; + + scr_erase_center = 0; + start = scr_centerstring; + + if (scr_center_lines <= 4) + y = vid.height*0.35; + else + y = 48; + + do + { + // scan the width of the line + for (l=0 ; l<40 ; l++) + if (start[l] == '\n' || !start[l]) + break; + x = (vid.width - l*8)/2; + for (j=0 ; j scr_erase_lines) + scr_erase_lines = scr_center_lines; + + scr_centertime_off -= host_frametime; + + if (scr_centertime_off <= 0 && !cl.intermission) + return; + if (key_dest != key_game) + return; + + SCR_DrawCenterString (); +} + +//============================================================================= + +/* +==================== +CalcFov +==================== +*/ +float CalcFov (float fov_x, float width, float height) +{ + float a; + float x; + + if (fov_x < 1 || fov_x > 179) + Sys_Error ("Bad fov: %f", fov_x); + + x = width/tanf(fov_x/360*M_PI); + + a = atanf(height/x); + + a = a*360/M_PI; + + return a; +} + +/* +================= +SCR_CalcRefdef + +Must be called whenever vid changes +Internal use only +================= +*/ +static void SCR_CalcRefdef (void) +{ + vrect_t vrect; + float size; + + scr_fullupdate = 0; // force a background redraw + vid.recalc_refdef = 0; + +// force the status bar to redraw + Sbar_Changed (); + +//======================================== + +// bound viewsize + if (scr_viewsize.value < 30) + Cvar_Set ("viewsize","30"); + if (scr_viewsize.value > 130) + Cvar_Set ("viewsize","130"); + +// bound field of view + if (scr_fov.value < 10) + Cvar_Set ("fov","10"); + if (scr_fov.value > 170) + Cvar_Set ("fov","170"); + + r_refdef.fov_x = scr_fov.value; + r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); + +// intermission is always full screen + if (cl.intermission) + size = 130; + else + size = scr_viewsize.value; + + if (size >= 130) + sb_lines = 0; // no status bar at all + else if (size >= 120) + sb_lines = 24; // no inventory + else + sb_lines = 24+16+8; + +// these calculations mirror those in R_Init() for r_refdef, but take no +// account of water warping + vrect.x = 0; + vrect.y = 0; + vrect.width = vid.width; + vrect.height = vid.height; + + R_SetVrect (&vrect, &scr_vrect, sb_lines); + +// guard against going from one mode to another that's less than half the +// vertical resolution + if (scr_con_current > vid.height) + scr_con_current = vid.height; + +// notify the refresh of the change + R_ViewChanged (&vrect, sb_lines, vid.aspect); +} + + +/* +================= +SCR_SizeUp_f + +Keybinding command +================= +*/ +void SCR_SizeUp_f (void) +{ + Cvar_SetValue ("viewsize",scr_viewsize.value+10); + vid.recalc_refdef = 1; +} + + +/* +================= +SCR_SizeDown_f + +Keybinding command +================= +*/ +void SCR_SizeDown_f (void) +{ + Cvar_SetValue ("viewsize",scr_viewsize.value-10); + vid.recalc_refdef = 1; +} + +//============================================================================ + +/* +================== +SCR_Init +================== +*/ +void SCR_Init (void) +{ + Cvar_RegisterVariable (&scr_fov); + Cvar_RegisterVariable (&scr_viewsize); + Cvar_RegisterVariable (&scr_conspeed); + Cvar_RegisterVariable (&scr_showram); + Cvar_RegisterVariable (&scr_showturtle); + Cvar_RegisterVariable (&scr_showpause); + Cvar_RegisterVariable (&scr_centertime); + Cvar_RegisterVariable (&scr_printspeed); + +// +// register our commands +// + Cmd_AddCommand ("screenshot",SCR_ScreenShot_f); + Cmd_AddCommand ("sizeup",SCR_SizeUp_f); + Cmd_AddCommand ("sizedown",SCR_SizeDown_f); + + scr_ram = Draw_PicFromWad ("ram"); + scr_net = Draw_PicFromWad ("net"); + scr_turtle = Draw_PicFromWad ("turtle"); + + scr_initialized = true; +} + + + +/* +============== +SCR_DrawRam +============== +*/ +void SCR_DrawRam (void) +{ + if (!scr_showram.value) + return; + + if (!r_cache_thrash) + return; + + Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram); +} + +/* +============== +SCR_DrawTurtle +============== +*/ +void SCR_DrawTurtle (void) +{ + static int count; + + if (!scr_showturtle.value) + return; + + if (host_frametime < 0.1) + { + count = 0; + return; + } + + count++; + if (count < 3) + return; + + Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle); +} + +/* +============== +SCR_DrawNet +============== +*/ +void SCR_DrawNet (void) +{ + if (realtime - cl.last_received_message < 0.3) + return; + if (cls.demoplayback) + return; + + Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net); +} + +/* +============== +DrawPause +============== +*/ +void SCR_DrawPause (void) +{ + qpic_t *pic; + + if (!scr_showpause.value) // turn off for screenshots + return; + + if (!cl.paused) + return; + + pic = Draw_CachePic ("gfx/pause.lmp"); + Draw_Pic ( (vid.width - pic->width)/2, + (vid.height - 48 - pic->height)/2, pic); +} + + + +/* +============== +SCR_DrawLoading +============== +*/ +void SCR_DrawLoading (void) +{ + qpic_t *pic; + + if (!scr_drawloading) + return; + + pic = Draw_CachePic ("gfx/loading.lmp"); + Draw_Pic ( (vid.width - pic->width)/2, + (vid.height - 48 - pic->height)/2, pic); +} + + + +//============================================================================= + + +/* +================== +SCR_SetUpToDrawConsole +================== +*/ +void SCR_SetUpToDrawConsole (void) +{ + Con_CheckResize (); + + if (scr_drawloading) + return; // never a console with loading plaque + +// decide on the height of the console + con_forcedup = !cl.worldmodel || cls.signon != SIGNONS; + + if (con_forcedup) + { + scr_conlines = vid.height; // full screen + scr_con_current = scr_conlines; + } + else if (key_dest == key_console) + scr_conlines = vid.height/2; // half screen + else + scr_conlines = 0; // none visible + + if (scr_conlines < scr_con_current) + { + scr_con_current -= scr_conspeed.value*host_frametime; + if (scr_conlines > scr_con_current) + scr_con_current = scr_conlines; + + } + else if (scr_conlines > scr_con_current) + { + scr_con_current += scr_conspeed.value*host_frametime; + if (scr_conlines < scr_con_current) + scr_con_current = scr_conlines; + } + + if (clearconsole++ < vid.numpages) + { + scr_copytop = 1; + Draw_TileClear (0,(int)scr_con_current,vid.width, vid.height - (int)scr_con_current); + Sbar_Changed (); + } + else if (clearnotify++ < vid.numpages) + { + scr_copytop = 1; + Draw_TileClear (0,0,vid.width, con_notifylines); + } + else + con_notifylines = 0; +} + +/* +================== +SCR_DrawConsole +================== +*/ +void SCR_DrawConsole (void) +{ + if (scr_con_current) + { + scr_copyeverything = 1; + Con_DrawConsole (scr_con_current, true); + clearconsole = 0; + } + else + { + if (key_dest == key_game || key_dest == key_message) + Con_DrawNotify (); // only draw notify in game + } +} + + +/* +============================================================================== + + SCREEN SHOTS + +============================================================================== +*/ + + +typedef struct +{ + char manufacturer; + char version; + char encoding; + char bits_per_pixel; + unsigned short xmin,ymin,xmax,ymax; + unsigned short hres,vres; + unsigned char palette[48]; + char reserved; + char color_planes; + unsigned short bytes_per_line; + unsigned short palette_type; + char filler[58]; + unsigned char data; // unbounded +} pcx_t; + +/* +============== +WritePCXfile +============== +*/ +void WritePCXfile (char *filename, byte *data, int width, int height, + int rowbytes, byte *palette) +{ + int i, j, length; + pcx_t *pcx; + byte *pack; + + pcx = Hunk_TempAlloc (width*height*2+1000); + if (pcx == NULL) + { + Con_Printf("SCR_ScreenShot_f: not enough memory\n"); + return; + } + + pcx->manufacturer = 0x0a; // PCX id + pcx->version = 5; // 256 color + pcx->encoding = 1; // uncompressed + pcx->bits_per_pixel = 8; // 256 color + pcx->xmin = 0; + pcx->ymin = 0; + pcx->xmax = LittleShort((short)(width-1)); + pcx->ymax = LittleShort((short)(height-1)); + pcx->hres = LittleShort((short)width); + pcx->vres = LittleShort((short)height); + Q_memset (pcx->palette,0,sizeof(pcx->palette)); + pcx->color_planes = 1; // chunky image + pcx->bytes_per_line = LittleShort((short)width); + pcx->palette_type = LittleShort(2); // not a grey scale + Q_memset (pcx->filler,0,sizeof(pcx->filler)); + +// pack the image + pack = &pcx->data; + + for (i=0 ; i 60) + { + scr_disabled_for_loading = false; + Con_Printf ("load failed.\n"); + } + else + return; + } + + if (cls.state == ca_dedicated) + return; // stdout only + + if (!scr_initialized || !con_initialized) + return; // not initialized yet + + if (scr_viewsize.value != oldscr_viewsize) + { + oldscr_viewsize = scr_viewsize.value; + vid.recalc_refdef = 1; + } + +// +// check for vid changes +// + if (oldfov != scr_fov.value) + { + oldfov = scr_fov.value; + vid.recalc_refdef = true; + } + + if (oldlcd_x != lcd_x.value) + { + oldlcd_x = lcd_x.value; + vid.recalc_refdef = true; + } + + if (oldscreensize != scr_viewsize.value) + { + oldscreensize = scr_viewsize.value; + vid.recalc_refdef = true; + } + + if (vid.recalc_refdef) + { + // something changed, so reorder the screen + SCR_CalcRefdef (); + } + +// +// do 3D refresh drawing, and then update the screen +// + D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly + + if (scr_fullupdate++ < vid.numpages) + { // clear the entire screen + scr_copyeverything = 1; + Draw_TileClear (0,0,vid.width,vid.height); + Sbar_Changed (); + } + + pconupdate = NULL; + + + SCR_SetUpToDrawConsole (); + SCR_EraseCenterString (); + + D_DisableBackBufferAccess (); // for adapters that can't stay mapped in + // for linear writes all the time + + VID_LockBuffer (); + + V_RenderView (); + + VID_UnlockBuffer (); + + D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly + + if (scr_drawdialog) + { + Sbar_Draw (); + Draw_FadeScreen (); + SCR_DrawNotifyString (); + scr_copyeverything = true; + } + else if (scr_drawloading) + { + SCR_DrawLoading (); + Sbar_Draw (); + } + else if (cl.intermission == 1 && key_dest == key_game) + { + Sbar_IntermissionOverlay (); + } + else if (cl.intermission == 2 && key_dest == key_game) + { + Sbar_FinaleOverlay (); + SCR_CheckDrawCenterString (); + } + else if (cl.intermission == 3 && key_dest == key_game) + { + SCR_CheckDrawCenterString (); + } + else + { + SCR_DrawRam (); + SCR_DrawNet (); + SCR_DrawTurtle (); + SCR_DrawPause (); + SCR_CheckDrawCenterString (); + Sbar_Draw (); + SCR_DrawConsole (); + M_Draw (); + } + + D_DisableBackBufferAccess (); // for adapters that can't stay mapped in + // for linear writes all the time + if (pconupdate) + { + D_UpdateRects (pconupdate); + } + + V_UpdatePalette (); + +// +// update one of three areas +// + + if (scr_copyeverything) + { + vrect.x = 0; + vrect.y = 0; + vrect.width = vid.width; + vrect.height = vid.height; + vrect.pnext = 0; + + VID_Update (&vrect); + } + else if (scr_copytop) + { + vrect.x = 0; + vrect.y = 0; + vrect.width = vid.width; + vrect.height = vid.height - sb_lines; + vrect.pnext = 0; + + VID_Update (&vrect); + } + else + { + vrect.x = scr_vrect.x; + vrect.y = scr_vrect.y; + vrect.width = scr_vrect.width; + vrect.height = scr_vrect.height; + vrect.pnext = 0; + + VID_Update (&vrect); + } +} + + +/* +================== +SCR_UpdateWholeScreen +================== +*/ +void SCR_UpdateWholeScreen (void) +{ + scr_fullupdate = 0; + SCR_UpdateScreen (); +} diff --git a/r17/Revamped src/revamped_src/screen.h b/r17/Revamped src/revamped_src/screen.h new file mode 100755 index 00000000..154f3e00 --- /dev/null +++ b/r17/Revamped src/revamped_src/screen.h @@ -0,0 +1,57 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// screen.h + +void SCR_Init (void); + +void SCR_UpdateScreen (void); + + +void SCR_SizeUp (void); +void SCR_SizeDown (void); +void SCR_BringDownConsole (void); +void SCR_CenterPrint (char *str); + +void SCR_BeginLoadingPlaque (void); +void SCR_EndLoadingPlaque (void); + +int SCR_ModalMessage (char *text); + +extern float scr_con_current; +extern float scr_conlines; // lines of console to display + +extern int scr_fullupdate; // set to 0 to force full redraw +extern int sb_lines; + +extern int clearnotify; // set to 0 whenever notify text is drawn +extern qboolean scr_disabled_for_loading; +extern qboolean scr_skipupdate; + +extern cvar_t scr_viewsize; + +extern cvar_t scr_viewsize; + +// only the refresh window will be updated unless these variables are flagged +extern int scr_copytop; +extern int scr_copyeverything; + +extern qboolean block_drawing; + +void SCR_UpdateWholeScreen (void); diff --git a/r17/Revamped src/revamped_src/server.h b/r17/Revamped src/revamped_src/server.h new file mode 100755 index 00000000..e277db79 --- /dev/null +++ b/r17/Revamped src/revamped_src/server.h @@ -0,0 +1,278 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// server.h + +typedef struct +{ + int maxclients; + int maxclientslimit; + struct client_s *clients; // [maxclients] + int serverflags; // episode completion information + qboolean changelevel_issued; // cleared when at SV_SpawnServer +} server_static_t; + +//============================================================================= + +typedef enum {ss_loading, ss_active} server_state_t; + +typedef struct +{ + qboolean active; // false if only a net client + + qboolean paused; + qboolean loadgame; // handle connections specially + + double time; + + int lastcheck; // used by PF_checkclient + double lastchecktime; + + char name[64]; // map name + char modelname[64]; // maps/.bsp, for model_precache[0] + struct model_s *worldmodel; + char *model_precache[MAX_MODELS]; // NULL terminated + struct model_s *models[MAX_MODELS]; + char *sound_precache[MAX_SOUNDS]; // NULL terminated + char *lightstyles[MAX_LIGHTSTYLES]; + int num_edicts; + int max_edicts; + edict_t *edicts; // can NOT be array indexed, because + // edict_t is variable sized, but can + // be used to reference the world ent + server_state_t state; // some actions are only valid during load + + sizebuf_t datagram; + byte datagram_buf[MAX_DATAGRAM]; + + sizebuf_t reliable_datagram; // copied to all clients at end of frame + byte reliable_datagram_buf[MAX_DATAGRAM]; + + sizebuf_t signon; + byte signon_buf[8192]; +#ifdef PROQUAKE_EXTENSION + // JPG - DON'T MODIFY ANYTHING ABOVE THIS POINT (CRMOD 6.X COMPATIBIILITY) + + unsigned long model_crc[MAX_MODELS]; // JPG - model checking +#endif +} server_t; + + +#define NUM_PING_TIMES 16 +#define NUM_SPAWN_PARMS 16 + +typedef struct client_s +{ + qboolean active; // false = client is free + qboolean spawned; // false = don't send datagrams + qboolean dropasap; // has been told to go to another level + qboolean privileged; // can execute any host command + qboolean sendsignon; // only valid before spawned + + double last_message; // reliable messages must be sent + // periodically + + struct qsocket_s *netconnection; // communications handle + + usercmd_t cmd; // movement + vec3_t wishdir; // intended motion calced from cmd + + sizebuf_t message; // can be added to at any time, + // copied and clear once per frame + byte msgbuf[MAX_MSGLEN]; + edict_t *edict; // EDICT_NUM(clientnum+1) + char name[32]; // for printing to other people + int colors; + + float ping_times[NUM_PING_TIMES]; + int num_pings; // ping_times[num_pings%NUM_PING_TIMES] + +// spawn parms are carried from level to level + float spawn_parms[NUM_SPAWN_PARMS]; + +// client known data for deltas + int old_frags; +#ifdef PROQUAKE_EXTENSION + // JPG - DON'T MODIFY ANYTHING ABOVE THIS POINT (CRMOD 6.X COMPATIBIILITY) + + // JPG - added spam_time to prevent spamming. If time < spam_time then + // the client is spamming and is silenced. + double spam_time; + + // JPG 3.00 - prevent clients from rapidly changing their name/colour + // and doing a say or say_team + double change_time; + + // JPG 3.30 - allow clients to connect if they don't have the map + qboolean nomap; +#endif +} client_t; + + +//============================================================================= + +// edict->movetype values +#define MOVETYPE_NONE 0 // never moves +#define MOVETYPE_ANGLENOCLIP 1 +#define MOVETYPE_ANGLECLIP 2 +#define MOVETYPE_WALK 3 // gravity +#define MOVETYPE_STEP 4 // gravity, special edge handling +#define MOVETYPE_FLY 5 +#define MOVETYPE_TOSS 6 // gravity +#define MOVETYPE_PUSH 7 // no clip to world, push and crush +#define MOVETYPE_NOCLIP 8 +#define MOVETYPE_FLYMISSILE 9 // extra size to monsters +#define MOVETYPE_BOUNCE 10 + +// edict->solid values +#define SOLID_NOT 0 // no interaction with other objects +#define SOLID_TRIGGER 1 // touch on edge, but not blocking +#define SOLID_BBOX 2 // touch on edge, block +#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground +#define SOLID_BSP 4 // bsp clip, touch on edge, block + +// edict->deadflag values +#define DEAD_NO 0 +#define DEAD_DYING 1 +#define DEAD_DEAD 2 + +#define DAMAGE_NO 0 +#define DAMAGE_YES 1 +#define DAMAGE_AIM 2 + +// edict->flags +#define FL_FLY 1 +#define FL_SWIM 2 +#define FL_CONVEYOR 4 +#define FL_CLIENT 8 +#define FL_INWATER 16 +#define FL_MONSTER 32 +#define FL_GODMODE 64 +#define FL_NOTARGET 128 +#define FL_ITEM 256 +#define FL_ONGROUND 512 +#define FL_PARTIALGROUND 1024 // not all corners are valid +#define FL_WATERJUMP 2048 // player jumping out of water +#define FL_JUMPRELEASED 4096 // for jump debouncing +#define FL_LOW_BANDWIDTH_CLIENT 8192 // Baker 3.99b: Slot Zero's anti-lag server/mod option for dialup users + +// entity effects + +#define EF_BRIGHTFIELD 1 +#define EF_MUZZLEFLASH 2 +#define EF_BRIGHTLIGHT 4 +#define EF_DIMLIGHT 8 +#ifdef SUPPORTS_KUROK_PROTOCOL +#define EF_REDLIGHT 16 +#define EF_BLUELIGHT 32 +#define EF_BLUELIGHT 64 +#define EF_BLUELIGHT 128 +#ifdef QUAKE2 +#define EF_DARKLIGHT 16 +#define EF_DARKFIELD 32 +#define EF_LIGHT 64 +#define EF_NODRAW 128 +#endif +#else +#define EF_NODRAW 16 +#define EF_BLUE 64 +#define EF_RED 128 +#define EF_MAYBE_DRAW 32768 // Baker 3.99b: Slot Zero's anti-lag server/mod option for dialup users + +#endif + +#define SPAWNFLAG_NOT_EASY 256 +#define SPAWNFLAG_NOT_MEDIUM 512 +#define SPAWNFLAG_NOT_HARD 1024 +#define SPAWNFLAG_NOT_DEATHMATCH 2048 + +//============================================================================ + +extern cvar_t teamplay; +extern cvar_t skill; +extern cvar_t deathmatch; +extern cvar_t coop; +extern cvar_t fraglimit; +extern cvar_t timelimit; +extern cvar_t sv_ipmasking; + +#ifdef PROQUAKE_EXTENSION +extern cvar_t pq_fullpitch; // JPG 2.01 +#endif + +extern cvar_t sv_maxvelocity; +extern cvar_t sv_gravity; +extern cvar_t sv_nostep; +extern cvar_t sv_friction; +extern cvar_t sv_edgefriction; +extern cvar_t sv_stopspeed; +extern cvar_t sv_maxspeed; +extern cvar_t sv_accelerate; +extern cvar_t sv_idealpitchscale; +extern cvar_t sv_aim; + +extern server_static_t svs; // persistant server info +extern server_t sv; // local server + +extern client_t *host_client; + +extern jmp_buf host_abortserver; + +extern double host_time; + +extern edict_t *sv_player; + + +//=========================================================== + +void SV_Init (void); + +void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count); +void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,float attenuation); + +void SV_DropClient (qboolean crash); + +void SV_SendClientMessages (void); +void SV_ClearDatagram (void); + +int SV_ModelIndex (char *name); + +void SV_SetIdealPitch (void); + +void SV_AddUpdates (void); + +void SV_ClientThink (void); +void SV_AddClientToServer (struct qsocket_s *ret); + +void SV_ClientPrintf (char *fmt, ...); +void SV_BroadcastPrintf (char *fmt, ...); + +void SV_Physics (void); + +qboolean SV_CheckBottom (edict_t *ent); +qboolean SV_MoveStep (edict_t *ent, vec3_t move, qboolean relink); + +void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg); + +void SV_MoveToGoal (void); + +void SV_CheckForNewClients (void); +void SV_RunClients (void); +void SV_SaveSpawnparms (); +void SV_SpawnServer (char *server); diff --git a/r17/Revamped src/revamped_src/snd_dma.c b/r17/Revamped src/revamped_src/snd_dma.c new file mode 100755 index 00000000..c9a5d9f6 --- /dev/null +++ b/r17/Revamped src/revamped_src/snd_dma.c @@ -0,0 +1,1020 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// snd_dma.c -- main control for any streaming sound output device + +#include "quakedef.h" + +#ifdef WIN32 +#include "winquake.h" +#endif + +void S_Play(void); +void S_PlayVol(void); +void S_SoundList(void); +void S_Update_(); +void S_StopAllSounds(qboolean clear); +void S_StopAllSoundsC(void); + +// ======================================================================= +// Internal sound data & structures +// ======================================================================= + +channel_t channels[MAX_CHANNELS]; +int total_channels; + +int snd_blocked = 0; +static qboolean snd_ambient = 1; +qboolean snd_initialized = false; + +// pointer should go away +volatile dma_t *shm = 0; +volatile dma_t sn; + +vec3_t listener_origin; +vec3_t listener_forward; +vec3_t listener_right; +vec3_t listener_up; +vec_t sound_nominal_clip_dist=1000.0; + +int soundtime; // sample PAIRS +int paintedtime; // sample PAIRS + + +#define MAX_SFX 512 +sfx_t *known_sfx; // hunk allocated [MAX_SFX] +int num_sfx; + +sfx_t *ambient_sfx[NUM_AMBIENTS]; + +int desired_speed = 11025; +int desired_bits = 16; + +int sound_started=0; + +cvar_t bgmvolume = {"bgmvolume", "1", true}; +cvar_t bgmtype = {"bgmtype", "cd", true}; // cd or none + +cvar_t volume = {"volume", "0.7", true}; + +cvar_t nosound = {"nosound", "0"}; +cvar_t precache = {"precache", "1"}; +cvar_t loadas8bit = {"loadas8bit", "0"}; +cvar_t bgmbuffer = {"bgmbuffer", "4096"}; +cvar_t ambient_level = {"ambient_level", "0.3"}; +cvar_t ambient_fade = {"ambient_fade", "100"}; +cvar_t snd_noextraupdate = {"snd_noextraupdate", "0"}; +cvar_t snd_show = {"snd_show", "0"}; +cvar_t _snd_mixahead = {"_snd_mixahead", "0.1", true}; + + +// ==================================================================== +// User-setable variables +// ==================================================================== + + +// +// Fake dma is a synchronous faking of the DMA progress used for +// isolating performance in the renderer. The fakedma_updates is +// number of times S_Update() is called per second. +// + +qboolean fakedma = false; +int fakedma_updates = 15; + + +void S_AmbientOff (void) +{ + snd_ambient = false; +} + + +void S_AmbientOn (void) +{ + snd_ambient = true; +} + + +void S_SoundInfo_f(void) +{ + if (!sound_started || !shm) + { + Con_Printf ("sound system not started\n"); + return; + } + + Con_Printf("%5d stereo\n", shm->channels - 1); + Con_Printf("%5d samples\n", shm->samples); + Con_Printf("%5d samplepos\n", shm->samplepos); + Con_Printf("%5d samplebits\n", shm->samplebits); + Con_Printf("%5d submission_chunk\n", shm->submission_chunk); + Con_Printf("%5d speed\n", shm->speed); + Con_Printf("0x%x dma buffer\n", shm->buffer); + Con_Printf("%5d total_channels\n", total_channels); +} + + +/* +================ +S_Startup +================ +*/ + +void S_Startup (void) +{ + int rc; + + if (!snd_initialized) + return; + + if (!fakedma) + { + rc = SNDDMA_Init(); + + if (!rc) + { +#ifndef WIN32 + Con_Printf("S_Startup: SNDDMA_Init failed.\n"); +#endif + sound_started = 0; + return; + } + } + + sound_started = 1; +} + + +/* +================ +S_Init +================ +*/ +void S_Init (void) +{ + + Con_Printf("\nSound Initialization\n"); + + if (COM_CheckParm("-nosound")) + return; + + if (COM_CheckParm("-simsound")) + fakedma = true; + + Cmd_AddCommand("play", S_Play); + Cmd_AddCommand("playvol", S_PlayVol); + Cmd_AddCommand("stopsound", S_StopAllSoundsC); + Cmd_AddCommand("soundlist", S_SoundList); + Cmd_AddCommand("soundinfo", S_SoundInfo_f); + + Cvar_RegisterVariable(&nosound); + Cvar_RegisterVariable(&volume); + Cvar_RegisterVariable(&precache); + Cvar_RegisterVariable(&loadas8bit); + Cvar_RegisterVariable(&bgmvolume); + Cvar_RegisterVariable(&bgmbuffer); + Cvar_RegisterVariable(&bgmtype); + Cvar_RegisterVariable(&ambient_level); + Cvar_RegisterVariable(&ambient_fade); + Cvar_RegisterVariable(&snd_noextraupdate); + Cvar_RegisterVariable(&snd_show); + Cvar_RegisterVariable(&_snd_mixahead); + + if (host_parms.memsize < 0x800000) + { + Cvar_Set ("loadas8bit", "1"); + Con_Printf ("loading all sounds as 8bit\n"); + } + + + + snd_initialized = true; + + S_Startup (); + + SND_InitScaletable (); + + known_sfx = Hunk_AllocName (MAX_SFX*sizeof(sfx_t), "sfx_t"); + num_sfx = 0; + +// create a piece of DMA memory + + if (fakedma) + { + shm = (void *) Hunk_AllocName(sizeof(*shm), "shm"); + shm->splitbuffer = 0; + shm->samplebits = 16; + shm->speed = 22050; + shm->channels = 2; + shm->samples = 32768; + shm->samplepos = 0; + shm->soundalive = true; + shm->gamealive = true; + shm->submission_chunk = 1; + shm->buffer = Hunk_AllocName(1<<16, "shmbuf"); + } + + Con_Printf ("Sound sampling rate: %i\n", shm->speed); + + // provides a tick sound until washed clean + +// if (shm->buffer) +// shm->buffer[4] = shm->buffer[5] = 0x7f; // force a pop for debugging + + ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav"); + ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav"); + + S_StopAllSounds (true); +} + + +// ======================================================================= +// Shutdown sound engine +// ======================================================================= + +void S_Shutdown(void) +{ + + if (!sound_started) + return; + + if (shm) + shm->gamealive = 0; + + shm = 0; + sound_started = 0; + + if (!fakedma) + { + SNDDMA_Shutdown(); + } +} + + +// ======================================================================= +// Load a sound +// ======================================================================= + +/* +================== +S_FindName + +================== +*/ +sfx_t *S_FindName (char *name) +{ + int i; + sfx_t *sfx; + + if (!name) + Sys_Error ("S_FindName: NULL\n"); + + if (Q_strlen(name) >= MAX_QPATH) + Sys_Error ("Sound name too long: %s", name); + +// see if already loaded + for (i=0 ; i < num_sfx ; i++) + if (!Q_strcmp(known_sfx[i].name, name)) + { + return &known_sfx[i]; + } + + if (num_sfx == MAX_SFX) + Sys_Error ("S_FindName: out of sfx_t"); + + sfx = &known_sfx[i]; + strcpy (sfx->name, name); + + num_sfx++; + + return sfx; +} + + +/* +================== +S_TouchSound + +================== +*/ +void S_TouchSound (char *name) +{ + sfx_t *sfx; + + if (!sound_started) + return; + + sfx = S_FindName (name); + Cache_Check (&sfx->cache); +} + +/* +================== +S_PrecacheSound + +================== +*/ +sfx_t *S_PrecacheSound (char *name) +{ + sfx_t *sfx; + + if (!sound_started || nosound.value) + return NULL; + + sfx = S_FindName (name); + +// cache it in + if (precache.value) + S_LoadSound (sfx); + + return sfx; +} + + +//============================================================================= + +/* +================= +SND_PickChannel +================= +*/ +channel_t *SND_PickChannel(int entnum, int entchannel) +{ + int ch_idx; + int first_to_die; + int life_left; + +// Check for replacement sound, or find the best one to replace + first_to_die = -1; + life_left = 0x7fffffff; + for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++) + { + if (entchannel != 0 // channel 0 never overrides + && channels[ch_idx].entnum == entnum + && (channels[ch_idx].entchannel == entchannel || entchannel == -1) ) + { // allways override sound from same entity + first_to_die = ch_idx; + break; + } + + // don't let monster sounds override player sounds + if (channels[ch_idx].entnum == cl.viewentity && entnum != cl.viewentity && channels[ch_idx].sfx) + continue; + + if (channels[ch_idx].end - paintedtime < life_left) + { + life_left = channels[ch_idx].end - paintedtime; + first_to_die = ch_idx; + } + } + + if (first_to_die == -1) + return NULL; + + if (channels[first_to_die].sfx) + channels[first_to_die].sfx = NULL; + + return &channels[first_to_die]; +} + +/* +================= +SND_Spatialize +================= +*/ +void SND_Spatialize(channel_t *ch) +{ + vec_t dot; + vec_t dist; + vec_t lscale, rscale, scale; + vec3_t source_vec; + sfx_t *snd; + +// anything coming from the view entity will allways be full volume + if (ch->entnum == cl.viewentity) + { + ch->leftvol = ch->master_vol; + ch->rightvol = ch->master_vol; + return; + } + +// calculate stereo seperation and distance attenuation + + snd = ch->sfx; + VectorSubtract(ch->origin, listener_origin, source_vec); + + dist = VectorNormalize(source_vec) * ch->dist_mult; + + dot = DotProduct(listener_right, source_vec); + + if (shm->channels == 1) + { + rscale = 1.0; + lscale = 1.0; + } + else + { + rscale = 1.0 + dot; + lscale = 1.0 - dot; + } + +// add in distance effect + scale = (1.0 - dist) * rscale; + ch->rightvol = (int) (ch->master_vol * scale); + if (ch->rightvol < 0) + ch->rightvol = 0; + + scale = (1.0 - dist) * lscale; + ch->leftvol = (int) (ch->master_vol * scale); + if (ch->leftvol < 0) + ch->leftvol = 0; +} + + +// ======================================================================= +// Start a sound effect +// ======================================================================= + +void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation) +{ + channel_t *target_chan, *check; + sfxcache_t *sc; + int vol; + int ch_idx; + int skip; + + if (!sound_started) + return; + + if (!sfx) + return; + + if (nosound.value) + return; + + vol = fvol*255; + +// pick a channel to play on + target_chan = SND_PickChannel(entnum, entchannel); + if (!target_chan) + return; + +// spatialize + memset (target_chan, 0, sizeof(*target_chan)); + VectorCopy(origin, target_chan->origin); + target_chan->dist_mult = attenuation / sound_nominal_clip_dist; + target_chan->master_vol = vol; + target_chan->entnum = entnum; + target_chan->entchannel = entchannel; + SND_Spatialize(target_chan); + + if (!target_chan->leftvol && !target_chan->rightvol) + return; // not audible at all + +// new channel + sc = S_LoadSound (sfx); + if (!sc) + { + target_chan->sfx = NULL; + return; // couldn't load the sound's data + } + + target_chan->sfx = sfx; + target_chan->pos = 0.0; + target_chan->end = paintedtime + sc->length; + +// if an identical sound has also been started this frame, offset the pos +// a bit to keep it from just making the first one louder + check = &channels[NUM_AMBIENTS]; + for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++, check++) + { + if (check == target_chan) + continue; + if (check->sfx == sfx && !check->pos) + { + skip = rand () % (int)(0.1*shm->speed); + if (skip >= target_chan->end) + skip = target_chan->end - 1; + target_chan->pos += skip; + target_chan->end -= skip; + break; + } + + } +} + +void S_StopSound(int entnum, int entchannel) +{ + int i; + + for (i=0 ; ibuffer && !pDSBuf)) +#else + if (!sound_started || !shm || !shm->buffer) +#endif + return; + + if (shm->samplebits == 8) + clear = 0x80; + else + clear = 0; + +#ifdef WIN32 + if (pDSBuf) + { + DWORD dwSize; + DWORD *pData; + int reps; + HRESULT hresult; + + reps = 0; + + while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pData, &dwSize, NULL, NULL, 0)) != DS_OK) + { + if (hresult != DSERR_BUFFERLOST) + { + Con_Printf ("S_ClearBuffer: DS::Lock Sound Buffer Failed\n"); + S_Shutdown (); + return; + } + + if (++reps > 10000) + { + Con_Printf ("S_ClearBuffer: DS: couldn't restore buffer\n"); + S_Shutdown (); + return; + } + } + + Q_memset(pData, clear, shm->samples * shm->samplebits/8); + + pDSBuf->lpVtbl->Unlock(pDSBuf, pData, dwSize, NULL, 0); + + } + else +#endif + { + Q_memset(shm->buffer, clear, shm->samples * shm->samplebits/8); + } +} + + +/* +================= +S_StaticSound +================= +*/ +void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) +{ + channel_t *ss; + sfxcache_t *sc; + + if (!sfx) + return; + + if (total_channels == MAX_CHANNELS) + { + Con_Printf ("total_channels == MAX_CHANNELS\n"); + return; + } + + ss = &channels[total_channels]; + total_channels++; + + sc = S_LoadSound (sfx); + if (!sc) + return; + + if (sc->loopstart == -1) + { + Con_Printf ("Sound %s not looped\n", sfx->name); + return; + } + + ss->sfx = sfx; + VectorCopy (origin, ss->origin); + ss->master_vol = vol; + ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist; + ss->end = paintedtime + sc->length; + + SND_Spatialize (ss); +} + + +//============================================================================= + +/* +=================== +S_UpdateAmbientSounds +=================== +*/ +void S_UpdateAmbientSounds (void) +{ + mleaf_t *l; + float vol; + int ambient_channel; + channel_t *chan; + + if (!snd_ambient) + return; + +// calc ambient sound levels + if (!cl.worldmodel) + return; + + l = Mod_PointInLeaf (listener_origin, cl.worldmodel); + if (!l || !ambient_level.value) + { + for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++) + channels[ambient_channel].sfx = NULL; + return; + } + + for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++) + { + chan = &channels[ambient_channel]; + chan->sfx = ambient_sfx[ambient_channel]; + + vol = ambient_level.value * l->ambient_sound_level[ambient_channel]; + if (vol < 8) + vol = 0; + + // don't adjust volume too fast + if (chan->master_vol < vol) + { + chan->master_vol += host_frametime * ambient_fade.value; + if (chan->master_vol > vol) + chan->master_vol = vol; + } + else if (chan->master_vol > vol) + { + chan->master_vol -= host_frametime * ambient_fade.value; + if (chan->master_vol < vol) + chan->master_vol = vol; + } + + chan->leftvol = chan->rightvol = chan->master_vol; + } +} + + +/* +============ +S_Update + +Called once each time through the main loop +============ +*/ +void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up) +{ + int i, j; + int total; + channel_t *ch; + channel_t *combine; + + if (!sound_started || (snd_blocked > 0)) + return; + + VectorCopy(origin, listener_origin); + VectorCopy(forward, listener_forward); + VectorCopy(right, listener_right); + VectorCopy(up, listener_up); + +// update general area ambient sound sources + S_UpdateAmbientSounds (); + + combine = NULL; + +// update spatialization for static and dynamic sounds + ch = channels+NUM_AMBIENTS; + for (i=NUM_AMBIENTS ; isfx) + continue; + SND_Spatialize(ch); // respatialize channel + if (!ch->leftvol && !ch->rightvol) + continue; + + // try to combine static sounds with a previous channel of the same + // sound effect so we don't mix five torches every frame + + if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS) + { + // see if it can just use the last one + if (combine && combine->sfx == ch->sfx) + { + combine->leftvol += ch->leftvol; + combine->rightvol += ch->rightvol; + ch->leftvol = ch->rightvol = 0; + continue; + } + // search for one + combine = channels+MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; + for (j=MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS ; jsfx == ch->sfx) + break; + + if (j == total_channels) + { + combine = NULL; + } + else + { + if (combine != ch) + { + combine->leftvol += ch->leftvol; + combine->rightvol += ch->rightvol; + ch->leftvol = ch->rightvol = 0; + } + continue; + } + } + + + } + +// +// debugging output +// + if (snd_show.value) + { + total = 0; + ch = channels; + for (i=0 ; isfx && (ch->leftvol || ch->rightvol) ) + { + //Con_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, ch->sfx->name); + total++; + } + + Con_Printf ("----(%i)----\n", total); + } + +// mix some sound + S_Update_(); +} + +void GetSoundtime(void) +{ + int samplepos; + static int buffers; + static int oldsamplepos; + int fullsamples; + + fullsamples = shm->samples / shm->channels; + +// it is possible to miscount buffers if it has wrapped twice between +// calls to S_Update. Oh well. +#ifdef __sun__ + soundtime = SNDDMA_GetSamples(); +#else + samplepos = SNDDMA_GetDMAPos(); + + + if (samplepos < oldsamplepos) + { + buffers++; // buffer wrapped + + if (paintedtime > 0x40000000) + { // time to chop things off to avoid 32 bit limits + buffers = 0; + paintedtime = fullsamples; + S_StopAllSounds (true); + } + } + oldsamplepos = samplepos; + + soundtime = buffers*fullsamples + samplepos/shm->channels; +#endif +} + +void S_ExtraUpdate (void) +{ + +#ifdef WIN32 + IN_Accumulate (); +#endif + + if (snd_noextraupdate.value) + return; // don't pollute timings + S_Update_(); +} + +void S_Update_(void) +{ + unsigned endtime; + int samps; + + if (!sound_started || (snd_blocked > 0)) + return; + +// Updates DMA time + GetSoundtime(); + +// check to make sure that we haven't overshot + if (paintedtime < soundtime) + { + //Con_Printf ("S_Update_ : overflow\n"); + paintedtime = soundtime; + } + +// mix ahead of current position + endtime = soundtime + _snd_mixahead.value * shm->speed; + samps = shm->samples >> (shm->channels-1); + if (endtime - soundtime > samps) + endtime = soundtime + samps; + +#ifdef WIN32 +// if the buffer was lost or stopped, restore it and/or restart it + { + DWORD dwStatus; + + if (pDSBuf) + { + if (pDSBuf->lpVtbl->GetStatus (pDSBuf, &dwStatus) != DD_OK) + Con_Printf ("Couldn't get sound buffer status\n"); + + if (dwStatus & DSBSTATUS_BUFFERLOST) + pDSBuf->lpVtbl->Restore (pDSBuf); + + if (!(dwStatus & DSBSTATUS_PLAYING)) + pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); + } + } +#endif + + S_PaintChannels (endtime); + + SNDDMA_Submit (); +} + +/* +=============================================================================== + +console functions + +=============================================================================== +*/ + +void S_Play(void) +{ + static int hash=345; + int i; + char name[256]; + sfx_t *sfx; + + i = 1; + while (icache); + if (!sc) + continue; + size = sc->length*sc->width*(sc->stereo+1); + total += size; + if (sc->loopstart >= 0) + Con_Printf ("L"); + else + Con_Printf (" "); + Con_Printf("(%2db) %6i : %s\n",sc->width*8, size, sfx->name); + } + Con_Printf ("Total resident: %i\n", total); +} + + +void S_LocalSound (char *sound) +{ + sfx_t *sfx; + + if (nosound.value) + return; + if (!sound_started) + return; + + sfx = S_PrecacheSound (sound); + if (!sfx) + { + Con_Printf ("S_LocalSound: can't cache %s\n", sound); + return; + } + S_StartSound (cl.viewentity, -1, sfx, vec3_origin, 1, 1); +} + + +void S_ClearPrecache (void) +{ +} + + +void S_BeginPrecaching (void) +{ +} + + +void S_EndPrecaching (void) +{ +} + diff --git a/r17/Revamped src/revamped_src/snd_mem.c b/r17/Revamped src/revamped_src/snd_mem.c new file mode 100755 index 00000000..494928ae --- /dev/null +++ b/r17/Revamped src/revamped_src/snd_mem.c @@ -0,0 +1,341 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// snd_mem.c: sound caching + +#include "quakedef.h" + +int cache_full_cycle; + +byte *S_Alloc (int size); + +/* +================ +ResampleSfx +================ +*/ +void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte *data) +{ + int outcount; + int srcsample; + float stepscale; + int i; + int sample, samplefrac, fracstep; + sfxcache_t *sc; + + sc = Cache_Check (&sfx->cache); + if (!sc) + return; + + stepscale = (float)inrate / shm->speed; // this is usually 0.5, 1, or 2 + + outcount = sc->length / stepscale; + sc->length = outcount; + if (sc->loopstart != -1) + sc->loopstart = sc->loopstart / stepscale; + + sc->speed = shm->speed; + if (loadas8bit.value) + sc->width = 1; + else + sc->width = inwidth; + sc->stereo = 0; + +// resample / decimate to the current source rate + + if (stepscale == 1 && inwidth == 1 && sc->width == 1) + { +// fast special case + for (i=0 ; idata)[i] + = (int)( (unsigned char)(data[i]) - 128); + } + else + { +// general case + samplefrac = 0; + fracstep = stepscale*256; + for (i=0 ; i> 8; + samplefrac += fracstep; + if (inwidth == 2) + sample = LittleShort ( ((short *)data)[srcsample] ); + else + sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8; + if (sc->width == 2) + ((short *)sc->data)[i] = sample; + else + ((signed char *)sc->data)[i] = sample >> 8; + } + } +} + +//============================================================================= + +/* +============== +S_LoadSound +============== +*/ +sfxcache_t *S_LoadSound (sfx_t *s) +{ + char namebuffer[256]; + byte *data; + wavinfo_t info; + int len; + float stepscale; + sfxcache_t *sc; + byte stackbuf[1*1024]; // avoid dirtying the cache heap + +// see if still in memory + sc = Cache_Check (&s->cache); + if (sc) + return sc; + +//Con_Printf ("S_LoadSound: %x\n", (int)stackbuf); +// load it in + Q_strcpy(namebuffer, "sound/"); + Q_strcat(namebuffer, s->name); + +// Con_Printf ("loading %s\n",namebuffer); + + data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf)); + + if (!data) + { + Con_Printf ("Couldn't load %s\n", namebuffer); + return NULL; + } + + info = GetWavinfo (s->name, data, com_filesize); + if (info.channels != 1) + { + Con_Printf ("%s is a stereo sample\n",s->name); + return NULL; + } + + stepscale = (float)info.rate / shm->speed; + len = info.samples / stepscale; + + len = len * info.width * info.channels; + + sc = Cache_Alloc ( &s->cache, len + sizeof(sfxcache_t), s->name); + if (!sc) + return NULL; + + sc->length = info.samples; + sc->loopstart = info.loopstart; + sc->speed = info.rate; + sc->width = info.width; + sc->stereo = info.channels; + + ResampleSfx (s, sc->speed, sc->width, data + info.dataofs); + + return sc; +} + + + +/* +=============================================================================== + +WAV loading + +=============================================================================== +*/ + + +byte *data_p; +byte *iff_end; +byte *last_chunk; +byte *iff_data; +int iff_chunk_len; + + +short GetLittleShort(void) +{ + short val = 0; + val = *data_p; + val = val + (*(data_p+1)<<8); + data_p += 2; + return val; +} + +int GetLittleLong(void) +{ + int val = 0; + val = *data_p; + val = val + (*(data_p+1)<<8); + val = val + (*(data_p+2)<<16); + val = val + (*(data_p+3)<<24); + data_p += 4; + return val; +} + +void FindNextChunk(char *name) +{ + while (1) + { + data_p=last_chunk; + + if (data_p >= iff_end) + { // didn't find the chunk + data_p = NULL; + return; + } + + data_p += 4; + iff_chunk_len = GetLittleLong(); + if (iff_chunk_len < 0) + { + data_p = NULL; + return; + } +// if (iff_chunk_len > 1024*1024) +// Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len); + data_p -= 8; + last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 ); + if (!Q_strncmp(data_p, name, 4)) + return; + } +} + +void FindChunk(char *name) +{ + last_chunk = iff_data; + FindNextChunk (name); +} + + +void DumpChunks(void) +{ + char str[5]; + + str[4] = 0; + data_p=iff_data; + do + { + memcpy (str, data_p, 4); + data_p += 4; + iff_chunk_len = GetLittleLong(); + Con_Printf ("0x%x : %s (%d)\n", (int)(data_p - 4), str, iff_chunk_len); + data_p += (iff_chunk_len + 1) & ~1; + } while (data_p < iff_end); +} + +/* +============ +GetWavinfo +============ +*/ +wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) +{ + wavinfo_t info; + int i; + int format; + int samples; + + memset (&info, 0, sizeof(info)); + + if (!wav) + return info; + + iff_data = wav; + iff_end = wav + wavlength; + +// find "RIFF" chunk + FindChunk("RIFF"); + if (!(data_p && !Q_strncmp(data_p+8, "WAVE", 4))) + { + Con_Printf("Missing RIFF/WAVE chunks\n"); + return info; + } + +// get "fmt " chunk + iff_data = data_p + 12; +// DumpChunks (); + + FindChunk("fmt "); + if (!data_p) + { + Con_Printf("Missing fmt chunk\n"); + return info; + } + data_p += 8; + format = GetLittleShort(); + if (format != 1) + { + Con_Printf("Microsoft PCM format only\n"); + return info; + } + + info.channels = GetLittleShort(); + info.rate = GetLittleLong(); + data_p += 4+2; + info.width = GetLittleShort() / 8; + +// get cue chunk + FindChunk("cue "); + if (data_p) + { + data_p += 32; + info.loopstart = GetLittleLong(); +// Con_Printf("loopstart=%d\n", sfx->loopstart); + + // if the next chunk is a LIST chunk, look for a cue length marker + FindNextChunk ("LIST"); + if (data_p) + { + if (!strncmp (data_p + 28, "mark", 4)) + { // this is not a proper parse, but it works with cooledit... + data_p += 24; + i = GetLittleLong (); // samples in loop + info.samples = info.loopstart + i; +// Con_Printf("looped length: %i\n", i); + } + } + } + else + info.loopstart = -1; + +// find data chunk + FindChunk("data"); + if (!data_p) + { + Con_Printf("Missing data chunk\n"); + return info; + } + + data_p += 4; + samples = GetLittleLong () / info.width; + + if (info.samples) + { + if (samples < info.samples) + Sys_Error ("Sound %s has a bad loop length", name); + } + else + info.samples = samples; + + info.dataofs = data_p - wav; + + return info; +} + diff --git a/r17/Revamped src/revamped_src/snd_mix.c b/r17/Revamped src/revamped_src/snd_mix.c new file mode 100755 index 00000000..425bccfc --- /dev/null +++ b/r17/Revamped src/revamped_src/snd_mix.c @@ -0,0 +1,398 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// snd_mix.c -- portable code to mix sounds for snd_dma.c + +#include "quakedef.h" + +#ifdef WIN32 +#include "winquake.h" +#else +#define DWORD unsigned long +#endif + +#define PAINTBUFFER_SIZE 512 +portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE]; +int snd_scaletable[32][256]; +int *snd_p, snd_linear_count, snd_vol; +short *snd_out; + +void Snd_WriteLinearBlastStereo16 (void); + +#if !id386 +void Snd_WriteLinearBlastStereo16 (void) +{ + int i; + int val; + + for (i=0 ; i>8; + if (val > 0x7fff) + snd_out[i] = 0x7fff; + else if (val < (short)0x8000) + snd_out[i] = (short)0x8000; + else + snd_out[i] = val; + + val = (snd_p[i+1]*snd_vol)>>8; + if (val > 0x7fff) + snd_out[i+1] = 0x7fff; + else if (val < (short)0x8000) + snd_out[i+1] = (short)0x8000; + else + snd_out[i+1] = val; + } +} +#endif + +void S_TransferStereo16 (int endtime) +{ + int lpos; + int lpaintedtime; + DWORD *pbuf; +#ifdef WIN32 + int reps; + DWORD dwSize,dwSize2; + DWORD *pbuf2; + HRESULT hresult; +#endif + + snd_vol = volume.value*256; + + snd_p = (int *) paintbuffer; + lpaintedtime = paintedtime; + +#ifdef WIN32 + if (pDSBuf) + { + reps = 0; + + while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pbuf, &dwSize, + &pbuf2, &dwSize2, 0)) != DS_OK) + { + if (hresult != DSERR_BUFFERLOST) + { + Con_Printf ("S_TransferStereo16: DS::Lock Sound Buffer Failed\n"); + S_Shutdown (); + S_Startup (); + return; + } + + if (++reps > 10000) + { + Con_Printf ("S_TransferStereo16: DS: couldn't restore buffer\n"); + S_Shutdown (); + S_Startup (); + return; + } + } + } + else +#endif + { + pbuf = (DWORD *)shm->buffer; + } + + while (lpaintedtime < endtime) + { + // handle recirculating buffer issues + lpos = lpaintedtime & ((shm->samples>>1)-1); + + snd_out = (short *) pbuf + (lpos<<1); + + snd_linear_count = (shm->samples>>1) - lpos; + if (lpaintedtime + snd_linear_count > endtime) + snd_linear_count = endtime - lpaintedtime; + + snd_linear_count <<= 1; + + // write a linear blast of samples + Snd_WriteLinearBlastStereo16 (); + + snd_p += snd_linear_count; + lpaintedtime += (snd_linear_count>>1); + } + +#ifdef WIN32 + if (pDSBuf) + pDSBuf->lpVtbl->Unlock(pDSBuf, pbuf, dwSize, NULL, 0); +#endif +} + +void S_TransferPaintBuffer(int endtime) +{ + int out_idx; + int count; + int out_mask; + int *p; + int step; + int val; + int snd_vol; + DWORD *pbuf; +#ifdef WIN32 + int reps; + DWORD dwSize,dwSize2; + DWORD *pbuf2; + HRESULT hresult; +#endif + + if (shm->samplebits == 16 && shm->channels == 2) + { + S_TransferStereo16 (endtime); + return; + } + + p = (int *) paintbuffer; + count = (endtime - paintedtime) * shm->channels; + out_mask = shm->samples - 1; + out_idx = paintedtime * shm->channels & out_mask; + step = 3 - shm->channels; + snd_vol = volume.value*256; + +#ifdef WIN32 + if (pDSBuf) + { + reps = 0; + + while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pbuf, &dwSize, + &pbuf2,&dwSize2, 0)) != DS_OK) + { + if (hresult != DSERR_BUFFERLOST) + { + Con_Printf ("S_TransferPaintBuffer: DS::Lock Sound Buffer Failed\n"); + S_Shutdown (); + S_Startup (); + return; + } + + if (++reps > 10000) + { + Con_Printf ("S_TransferPaintBuffer: DS: couldn't restore buffer\n"); + S_Shutdown (); + S_Startup (); + return; + } + } + } + else +#endif + { + pbuf = (DWORD *)shm->buffer; + } + + if (shm->samplebits == 16) + { + short *out = (short *) pbuf; + while (count--) + { + val = (*p * snd_vol) >> 8; + p+= step; + if (val > 0x7fff) + val = 0x7fff; + else if (val < (short)0x8000) + val = (short)0x8000; + out[out_idx] = val; + out_idx = (out_idx + 1) & out_mask; + } + } + else if (shm->samplebits == 8) + { + unsigned char *out = (unsigned char *) pbuf; + while (count--) + { + val = (*p * snd_vol) >> 8; + p+= step; + if (val > 0x7fff) + val = 0x7fff; + else if (val < (short)0x8000) + val = (short)0x8000; + out[out_idx] = (val>>8) + 128; + out_idx = (out_idx + 1) & out_mask; + } + } + +#ifdef WIN32 + if (pDSBuf) { + DWORD dwNewpos, dwWrite; + int il = paintedtime; + int ir = endtime - paintedtime; + + ir += il; + + pDSBuf->lpVtbl->Unlock(pDSBuf, pbuf, dwSize, NULL, 0); + + pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &dwNewpos, &dwWrite); + +// if ((dwNewpos >= il) && (dwNewpos <= ir)) +// Con_Printf("%d-%d p %d c\n", il, ir, dwNewpos); + } +#endif +} + + +/* +=============================================================================== + +CHANNEL MIXING + +=============================================================================== +*/ + +void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime); +void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime); + +void S_PaintChannels(int endtime) +{ + int i; + int end; + channel_t *ch; + sfxcache_t *sc; + int ltime, count; + + while (paintedtime < endtime) + { + // if paintbuffer is smaller than DMA buffer + end = endtime; + if (endtime - paintedtime > PAINTBUFFER_SIZE) + end = paintedtime + PAINTBUFFER_SIZE; + + // clear the paint buffer + Q_memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t)); + + // paint in the channels. + ch = channels; + for (i=0; isfx) + continue; + if (!ch->leftvol && !ch->rightvol) + continue; + sc = S_LoadSound (ch->sfx); + if (!sc) + continue; + + ltime = paintedtime; + + while (ltime < end) + { // paint up to end + if (ch->end < end) + count = ch->end - ltime; + else + count = end - ltime; + + if (count > 0) + { + if (sc->width == 1) + SND_PaintChannelFrom8(ch, sc, count); + else + SND_PaintChannelFrom16(ch, sc, count); + + ltime += count; + } + + // if at end of loop, restart + if (ltime >= ch->end) + { + if (sc->loopstart >= 0) + { + ch->pos = sc->loopstart; + ch->end = ltime + sc->length - ch->pos; + } + else + { // channel just stopped + ch->sfx = NULL; + break; + } + } + } + + } + + // transfer out according to DMA format + S_TransferPaintBuffer(end); + paintedtime = end; + } +} + +void SND_InitScaletable (void) +{ + int i, j; + + for (i=0 ; i<32 ; i++) + for (j=0 ; j<256 ; j++) + snd_scaletable[i][j] = ((signed char)j) * i * 8; +} + + +#if !id386 + +void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count) +{ + int data; + int *lscale, *rscale; + unsigned char *sfx; + int i; + + if (ch->leftvol > 255) + ch->leftvol = 255; + if (ch->rightvol > 255) + ch->rightvol = 255; + + lscale = snd_scaletable[ch->leftvol >> 3]; + rscale = snd_scaletable[ch->rightvol >> 3]; + sfx = (signed char *)sc->data + ch->pos; + + for (i=0 ; ipos += count; +} + +#endif // !id386 + + +void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count) +{ + int data; + int left, right; + int leftvol, rightvol; + signed short *sfx; + int i; + + leftvol = ch->leftvol; + rightvol = ch->rightvol; + sfx = (signed short *)sc->data + ch->pos; + + for (i=0 ; i> 8; + right = (data * rightvol) >> 8; + paintbuffer[i].left += left; + paintbuffer[i].right += right; + } + + ch->pos += count; +} + diff --git a/r17/Revamped src/revamped_src/snd_null.c b/r17/Revamped src/revamped_src/snd_null.c new file mode 100755 index 00000000..6dea5cf8 --- /dev/null +++ b/r17/Revamped src/revamped_src/snd_null.c @@ -0,0 +1,97 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// snd_null.c -- include this instead of all the other snd_* files to have +// no sound code whatsoever + +#include "quakedef.h" + +cvar_t bgmvolume = {"bgmvolume", "1", true}; +cvar_t volume = {"volume", "0.7", true}; + + +void S_Init (void) +{ +} + +void S_AmbientOff (void) +{ +} + +void S_AmbientOn (void) +{ +} + +void S_Shutdown (void) +{ +} + +void S_TouchSound (char *sample) +{ +} + +void S_ClearBuffer (void) +{ +} + +void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) +{ +} + +void S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation) +{ +} + +void S_StopSound (int entnum, int entchannel) +{ +} + +sfx_t *S_PrecacheSound (char *sample) +{ + return NULL; +} + +void S_ClearPrecache (void) +{ +} + +void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up) +{ +} + +void S_StopAllSounds (qboolean clear) +{ +} + +void S_BeginPrecaching (void) +{ +} + +void S_EndPrecaching (void) +{ +} + +void S_ExtraUpdate (void) +{ +} + +void S_LocalSound (char *s) +{ +} + diff --git a/r17/Revamped src/revamped_src/sound.h b/r17/Revamped src/revamped_src/sound.h new file mode 100755 index 00000000..36f5bb71 --- /dev/null +++ b/r17/Revamped src/revamped_src/sound.h @@ -0,0 +1,178 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// sound.h -- client sound i/o functions + +#ifndef __SOUND__ +#define __SOUND__ + +#define DEFAULT_SOUND_PACKET_VOLUME 255 +#define DEFAULT_SOUND_PACKET_ATTENUATION 1.0 + +// !!! if this is changed, it much be changed in asm_i386.h too !!! +typedef struct +{ + int left; + int right; +} portable_samplepair_t; + +typedef struct sfx_s +{ + char name[MAX_QPATH]; + cache_user_t cache; +} sfx_t; + +// !!! if this is changed, it much be changed in asm_i386.h too !!! +typedef struct +{ + int length; + int loopstart; + int speed; + int width; + int stereo; + byte data[1]; // variable sized +} sfxcache_t; + +typedef struct +{ + qboolean gamealive; + qboolean soundalive; + qboolean splitbuffer; + int channels; + int samples; // mono samples in buffer + int submission_chunk; // don't mix less than this # + int samplepos; // in mono samples + int samplebits; + int speed; + unsigned char *buffer; +} dma_t; + +// !!! if this is changed, it much be changed in asm_i386.h too !!! +typedef struct +{ + sfx_t *sfx; // sfx number + int leftvol; // 0-255 volume + int rightvol; // 0-255 volume + int end; // end time in global paintsamples + int pos; // sample position in sfx + int looping; // where to loop, -1 = no looping + int entnum; // to allow overriding a specific sound + int entchannel; // + vec3_t origin; // origin of sound effect + vec_t dist_mult; // distance multiplier (attenuation/clipK) + int master_vol; // 0-255 master volume +} channel_t; + +typedef struct +{ + int rate; + int width; + int channels; + int loopstart; + int samples; + int dataofs; // chunk starts this many bytes from file start +} wavinfo_t; + +void S_Init (void); +void S_Startup (void); +void S_Shutdown (void); +void S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation); +void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation); +void S_StopSound (int entnum, int entchannel); +void S_StopAllSounds(qboolean clear); +void S_ClearBuffer (void); +void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up); +void S_ExtraUpdate (void); + +sfx_t *S_PrecacheSound (char *sample); +void S_TouchSound (char *sample); +void S_ClearPrecache (void); +void S_BeginPrecaching (void); +void S_EndPrecaching (void); +void S_PaintChannels(int endtime); +void S_InitPaintChannels (void); + +// picks a channel based on priorities, empty slots, number of channels +channel_t *SND_PickChannel(int entnum, int entchannel); + +// spatializes a channel +void SND_Spatialize(channel_t *ch); + +// initializes cycling through a DMA buffer and returns information on it +qboolean SNDDMA_Init(void); + +// gets the current DMA position +int SNDDMA_GetDMAPos(void); + +// shutdown the DMA xfer. +void SNDDMA_Shutdown(void); + +// ==================================================================== +// User-setable variables +// ==================================================================== + +#define MAX_CHANNELS 128 +#define MAX_DYNAMIC_CHANNELS 8 + + +extern channel_t channels[MAX_CHANNELS]; +// 0 to MAX_DYNAMIC_CHANNELS-1 = normal entity sounds +// MAX_DYNAMIC_CHANNELS to MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS -1 = water, etc +// MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS to total_channels = static sounds + +extern int total_channels; + +// +// Fake dma is a synchronous faking of the DMA progress used for +// isolating performance in the renderer. The fakedma_updates is +// number of times S_Update() is called per second. +// + +extern qboolean fakedma; +extern int fakedma_updates; +extern int paintedtime; +extern vec3_t listener_origin; +extern vec3_t listener_forward; +extern vec3_t listener_right; +extern vec3_t listener_up; +extern volatile dma_t *shm; +extern volatile dma_t sn; +extern vec_t sound_nominal_clip_dist; + +extern cvar_t loadas8bit; +extern cvar_t bgmvolume; +extern cvar_t bgmtype; +extern cvar_t volume; + +extern qboolean snd_initialized; + +extern int snd_blocked; + +void S_LocalSound (char *s); +sfxcache_t *S_LoadSound (sfx_t *s); + +wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength); + +void SND_InitScaletable (void); +void SNDDMA_Submit(void); + +void S_AmbientOff (void); +void S_AmbientOn (void); + +#endif diff --git a/r17/Revamped src/revamped_src/spritegn.h b/r17/Revamped src/revamped_src/spritegn.h new file mode 100755 index 00000000..337c1d6b --- /dev/null +++ b/r17/Revamped src/revamped_src/spritegn.h @@ -0,0 +1,110 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// +// spritegn.h: header file for sprite generation program +// + +// ********************************************************** +// * This file must be identical in the spritegen directory * +// * and in the Quake directory, because it's used to * +// * pass data from one to the other via .spr files. * +// ********************************************************** + +//------------------------------------------------------- +// This program generates .spr sprite package files. +// The format of the files is as follows: +// +// dsprite_t file header structure +// +// +// dspriteframe_t frame header structure +// sprite bitmap +// +// dspriteframe_t frame header structure +// sprite bitmap +// +//------------------------------------------------------- + +#ifdef INCLUDELIBS + +#include +#include +#include +#include + +#include "cmdlib.h" +#include "scriplib.h" +#include "dictlib.h" +#include "trilib.h" +#include "lbmlib.h" +#include "mathlib.h" + +#endif + +#define SPRITE_VERSION 1 + +// must match definition in modelgen.h +#ifndef SYNCTYPE_T +#define SYNCTYPE_T +typedef enum {ST_SYNC=0, ST_RAND } synctype_t; +#endif + +// TODO: shorten these? +typedef struct { + int ident; + int version; + int type; + float boundingradius; + int width; + int height; + int numframes; + float beamlength; + synctype_t synctype; +} dsprite_t; + +#define SPR_VP_PARALLEL_UPRIGHT 0 +#define SPR_FACING_UPRIGHT 1 +#define SPR_VP_PARALLEL 2 +#define SPR_ORIENTED 3 +#define SPR_VP_PARALLEL_ORIENTED 4 + +typedef struct { + int origin[2]; + int width; + int height; +} dspriteframe_t; + +typedef struct { + int numframes; +} dspritegroup_t; + +typedef struct { + float interval; +} dspriteinterval_t; + +typedef enum { SPR_SINGLE=0, SPR_GROUP } spriteframetype_t; + +typedef struct { + spriteframetype_t type; +} dspriteframetype_t; + +#define IDSPRITEHEADER (('P'<<24)+('S'<<16)+('D'<<8)+'I') + // little-endian "IDSP" + diff --git a/r17/Revamped src/revamped_src/sv_main.c b/r17/Revamped src/revamped_src/sv_main.c new file mode 100755 index 00000000..5f443bd3 --- /dev/null +++ b/r17/Revamped src/revamped_src/sv_main.c @@ -0,0 +1,1286 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// sv_main.c -- server main program + +#include "quakedef.h" + +server_t sv; +server_static_t svs; + +char localmodels[MAX_MODELS][5]; // inline model names for precache + +//============================================================================ + +/* +=============== +SV_Init +=============== +*/ +void SV_Init (void) +{ + int i; + extern cvar_t sv_maxvelocity; + extern cvar_t sv_gravity; + extern cvar_t sv_nostep; + extern cvar_t sv_friction; + extern cvar_t sv_edgefriction; + extern cvar_t sv_stopspeed; + extern cvar_t sv_maxspeed; + extern cvar_t sv_accelerate; + extern cvar_t sv_idealpitchscale; + extern cvar_t sv_aim; + + Cvar_RegisterVariable (&sv_maxvelocity); + Cvar_RegisterVariable (&sv_gravity); + Cvar_RegisterVariable (&sv_friction); + Cvar_RegisterVariable (&sv_edgefriction); + Cvar_RegisterVariable (&sv_stopspeed); + Cvar_RegisterVariable (&sv_maxspeed); + Cvar_RegisterVariable (&sv_accelerate); + Cvar_RegisterVariable (&sv_idealpitchscale); + Cvar_RegisterVariable (&sv_aim); + Cvar_RegisterVariable (&sv_nostep); + + for (i=0 ; i MAX_DATAGRAM-16) + return; + MSG_WriteByte (&sv.datagram, svc_particle); + MSG_WriteCoord (&sv.datagram, org[0]); + MSG_WriteCoord (&sv.datagram, org[1]); + MSG_WriteCoord (&sv.datagram, org[2]); + for (i=0 ; i<3 ; i++) + { + v = dir[i]*16; + if (v > 127) + v = 127; + else if (v < -128) + v = -128; + MSG_WriteChar (&sv.datagram, v); + } + MSG_WriteByte (&sv.datagram, count); + MSG_WriteByte (&sv.datagram, color); +} + +/* +================== +SV_StartSound + +Each entity can have eight independant sound sources, like voice, +weapon, feet, etc. + +Channel 0 is an auto-allocate channel, the others override anything +allready running on that entity/channel pair. + +An attenuation of 0 will play full volume everywhere in the level. +Larger attenuations will drop off. (max 4 attenuation) + +================== +*/ +void SV_StartSound (edict_t *entity, int channel, char *sample, int volume, + float attenuation) +{ + int sound_num; + int field_mask; + int i; + int ent; + + if (volume < 0 || volume > 255) + Sys_Error ("SV_StartSound: volume = %i", volume); + + if (attenuation < 0 || attenuation > 4) + Sys_Error ("SV_StartSound: attenuation = %f", attenuation); + + if (channel < 0 || channel > 7) + Sys_Error ("SV_StartSound: channel = %i", channel); + + if (sv.datagram.cursize > MAX_DATAGRAM-16) + return; + +// find precache number for sound + for (sound_num=1 ; sound_numv.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i])); +} + +/* +============================================================================== + +CLIENT SPAWNING + +============================================================================== +*/ + +/* +================ +SV_SendServerinfo + +Sends the first message from the server to a connected client. +This will be sent on the initial connection and upon each server load. +================ +*/ +void SV_SendServerinfo (client_t *client) +{ + char **s; + char message[2048]; + + MSG_WriteByte (&client->message, svc_print); + sprintf (message, "%c\nVERSION %4.2f SERVER (%i CRC)", 2, VERSION, pr_crc); + MSG_WriteString (&client->message,message); + + MSG_WriteByte (&client->message, svc_serverinfo); + MSG_WriteLong (&client->message, PROTOCOL_VERSION); + MSG_WriteByte (&client->message, svs.maxclients); + + if (!coop.value && deathmatch.value) + MSG_WriteByte (&client->message, GAME_DEATHMATCH); + else + MSG_WriteByte (&client->message, GAME_COOP); + + sprintf (message, pr_strings+sv.edicts->v.message); + + MSG_WriteString (&client->message,message); + + for (s = sv.model_precache+1 ; *s ; s++) + MSG_WriteString (&client->message, *s); + MSG_WriteByte (&client->message, 0); + + for (s = sv.sound_precache+1 ; *s ; s++) + MSG_WriteString (&client->message, *s); + MSG_WriteByte (&client->message, 0); + +// send music + MSG_WriteByte (&client->message, svc_cdtrack); + MSG_WriteByte (&client->message, sv.edicts->v.sounds); + MSG_WriteByte (&client->message, sv.edicts->v.sounds); + +// set view + MSG_WriteByte (&client->message, svc_setview); + MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict)); + + MSG_WriteByte (&client->message, svc_signonnum); + MSG_WriteByte (&client->message, 1); + + client->sendsignon = true; + client->spawned = false; // need prespawn, spawn, etc +} + +/* +================ +SV_ConnectClient + +Initializes a client_t for a new net connection. This will only be called +once for a player each game, not once for each level change. +================ +*/ +void SV_ConnectClient (int clientnum) +{ + edict_t *ent; + client_t *client; + int edictnum; + struct qsocket_s *netconnection; + int i; + float spawn_parms[NUM_SPAWN_PARMS]; + + client = svs.clients + clientnum; + + Con_DPrintf ("Client %s connected\n", client->netconnection->address); + + edictnum = clientnum+1; + + ent = EDICT_NUM(edictnum); + +// set up the client_t + netconnection = client->netconnection; + + if (sv.loadgame) + memcpy (spawn_parms, client->spawn_parms, sizeof(spawn_parms)); + memset (client, 0, sizeof(*client)); + client->netconnection = netconnection; + + strcpy (client->name, "unconnected"); + client->active = true; + client->spawned = false; + client->edict = ent; + client->message.data = client->msgbuf; + client->message.maxsize = sizeof(client->msgbuf); + client->message.allowoverflow = true; // we can catch it + +#ifdef IDGODS + client->privileged = IsID(&client->netconnection->addr); +#else + client->privileged = false; +#endif + + if (sv.loadgame) + memcpy (client->spawn_parms, spawn_parms, sizeof(spawn_parms)); + else + { + // call the progs to get default spawn parms for the new client + PR_ExecuteProgram (pr_global_struct->SetNewParms); + for (i=0 ; ispawn_parms[i] = (&pr_global_struct->parm1)[i]; + } + + SV_SendServerinfo (client); +} + + +/* +=================== +SV_CheckForNewClients + +=================== +*/ +void SV_CheckForNewClients (void) +{ + struct qsocket_s *ret; + int i; + +// +// check for new connections +// + while (1) + { + ret = NET_CheckNewConnections (); + if (!ret) + break; + + // + // init a new client structure + // + for (i=0 ; icontents < 0) + { + if (node->contents != CONTENTS_SOLID) + { + pvs = Mod_LeafPVS ( (mleaf_t *)node, sv.worldmodel); + for (i=0 ; iplane; + d = DotProduct (org, plane->normal) - plane->dist; + if (d > 8) + node = node->children[0]; + else if (d < -8) + node = node->children[1]; + else + { // go down both + SV_AddToFatPVS (org, node->children[0]); + node = node->children[1]; + } + } +} + +/* +============= +SV_FatPVS + +Calculates a PVS that is the inclusive or of all leafs within 8 pixels of the +given point. +============= +*/ +byte *SV_FatPVS (vec3_t org) +{ + fatbytes = (sv.worldmodel->numleafs+31)>>3; + Q_memset (fatpvs, 0, fatbytes); + SV_AddToFatPVS (org, sv.worldmodel->nodes); + return fatpvs; +} + +//============================================================================= + + +/* +============= +SV_WriteEntitiesToClient + +============= +*/ +void SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg) +{ + int e, i; + int bits; + byte *pvs; + vec3_t org; + float miss; + edict_t *ent; + + // Tomaz - QC Alpha Scale Glow Begin + + float alpha; + float scale; + float glow_size; + float glow_red; + float glow_green; + float glow_blue; + + // Tomaz - QC Alpha Scale Glow End + +// find the client's PVS + VectorAdd (clent->v.origin, clent->v.view_ofs, org); + pvs = SV_FatPVS (org); + +// send over all entities (excpet the client) that touch the pvs + ent = NEXT_EDICT(sv.edicts); + for (e=1 ; ev.effects == EF_NODRAW) + continue; +#endif + +// ignore if not touching a PV leaf + if (ent != clent) // clent is ALLWAYS sent + { +// ignore ents without visible models + if (!ent->v.modelindex || !pr_strings[ent->v.model]) + continue; + + for (i=0 ; i < ent->num_leafs ; i++) + if (pvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i]&7) )) + break; + + if (i == ent->num_leafs) + continue; // not visible + } + + if (msg->maxsize - msg->cursize < 16) + { + Con_Printf ("packet overflow\n"); + return; + } + +// send an update + bits = 0; + + for (i=0 ; i<3 ; i++) + { + miss = ent->v.origin[i] - ent->baseline.origin[i]; + if ( miss < -0.1 || miss > 0.1 ) + bits |= U_ORIGIN1<v.angles[0] != ent->baseline.angles[0] ) + bits |= U_ANGLE1; + + if ( ent->v.angles[1] != ent->baseline.angles[1] ) + bits |= U_ANGLE2; + + if ( ent->v.angles[2] != ent->baseline.angles[2] ) + bits |= U_ANGLE3; + + if (ent->v.movetype == MOVETYPE_STEP) + bits |= U_NOLERP; // don't mess up the step animation + + if (ent->baseline.colormap != ent->v.colormap) + bits |= U_COLORMAP; + + if (ent->baseline.skin != ent->v.skin) + bits |= U_SKIN; + + if (ent->baseline.frame != ent->v.frame) + bits |= U_FRAME; + + if (ent->baseline.effects != ent->v.effects) + bits |= U_EFFECTS; + + if (ent->baseline.modelindex != ent->v.modelindex) + bits |= U_MODEL; + + if (e >= 256) + bits |= U_LONGENTITY; + + if (bits >= 256) + bits |= U_MOREBITS; + + // + // write the message + // + MSG_WriteByte (msg,bits | U_SIGNAL); + + if (bits & U_MOREBITS) + MSG_WriteByte (msg, bits>>8); + if (bits & U_LONGENTITY) + MSG_WriteShort (msg,e); + else + MSG_WriteByte (msg,e); + + if (bits & U_MODEL) + MSG_WriteByte (msg, ent->v.modelindex); + + // Tomaz - QC Alpha Scale Glow Begin + + { + eval_t *val; + + alpha=1; + scale=1; + + if (val == GetEdictFieldValue(ent, "alpha")) + { + alpha = val->_float; + } + else + alpha = 1; + + if (val == GetEdictFieldValue(ent, "scale")) + { + scale = val->_float; + } + else + scale = 1; + + if (scale > 4) + scale = 4; + + if (val == GetEdictFieldValue(ent, "glow_size")) + { + glow_size = val->_float; + } + else + glow_size = 0; + + if (glow_size > 250) + glow_size = 250; + + if (val == GetEdictFieldValue(ent, "glow_red")) + { + glow_red = val->_float; + } + else + glow_red = 0; + + if (val == GetEdictFieldValue(ent, "glow_green")) + { + glow_green = val->_float; + } + else + glow_green = 0; + + if (val == GetEdictFieldValue(ent, "glow_blue")) + { + glow_blue = val->_float; + } + else + glow_blue = 0; + + if ((alpha <= 1) && (alpha > 0)) + bits |= U_ALPHA; + + if ((scale <= 4) && (scale > 0)) + bits |= U_SCALE; + + if (glow_size >= 0) + { + bits |= U_GLOW_SIZE; + bits |= U_GLOW_RED; + bits |= U_GLOW_GREEN; + bits |= U_GLOW_BLUE; + } + } + + // Tomaz - QC Alpha Scale Glow End + + if (bits & U_FRAME) + MSG_WriteByte (msg, ent->v.frame); + if (bits & U_COLORMAP) + MSG_WriteByte (msg, ent->v.colormap); + if (bits & U_SKIN) + MSG_WriteByte (msg, ent->v.skin); + if (bits & U_EFFECTS) + MSG_WriteByte (msg, ent->v.effects); + if (bits & U_ORIGIN1) + MSG_WriteCoord (msg, ent->v.origin[0]); + if (bits & U_ANGLE1) + MSG_WriteAngle(msg, ent->v.angles[0]); + if (bits & U_ORIGIN2) + MSG_WriteCoord (msg, ent->v.origin[1]); + if (bits & U_ANGLE2) + MSG_WriteAngle(msg, ent->v.angles[1]); + if (bits & U_ORIGIN3) + MSG_WriteCoord (msg, ent->v.origin[2]); + if (bits & U_ANGLE3) + MSG_WriteAngle(msg, ent->v.angles[2]); + + } +} + +/* +============= +SV_CleanupEnts + +============= +*/ +void SV_CleanupEnts (void) +{ + int e; + edict_t *ent; + + ent = NEXT_EDICT(sv.edicts); + for (e=1 ; ev.effects = (int)ent->v.effects & ~EF_MUZZLEFLASH; + } + +} + +/* +================== +SV_WriteClientdataToMessage + +================== +*/ +void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg) +{ + int bits; + int i; + edict_t *other; + int items; +#ifndef QUAKE2 + eval_t *val; +#endif + +// +// send a damage message +// + if (ent->v.dmg_take || ent->v.dmg_save) + { + other = PROG_TO_EDICT(ent->v.dmg_inflictor); + MSG_WriteByte (msg, svc_damage); + MSG_WriteByte (msg, ent->v.dmg_save); + MSG_WriteByte (msg, ent->v.dmg_take); + for (i=0 ; i<3 ; i++) + MSG_WriteCoord (msg, other->v.origin[i] + 0.5*(other->v.mins[i] + other->v.maxs[i])); + + ent->v.dmg_take = 0; + ent->v.dmg_save = 0; + } + +// +// send the current viewpos offset from the view entity +// + SV_SetIdealPitch (); // how much to look up / down ideally + +// a fixangle might get lost in a dropped packet. Oh well. + if ( ent->v.fixangle ) + { + MSG_WriteByte (msg, svc_setangle); + for (i=0 ; i < 3 ; i++) + MSG_WriteAngle (msg, ent->v.angles[i] ); + ent->v.fixangle = 0; + } + + bits = 0; + + if (ent->v.view_ofs[2] != DEFAULT_VIEWHEIGHT) + bits |= SU_VIEWHEIGHT; + + if (ent->v.idealpitch) + bits |= SU_IDEALPITCH; + +// stuff the sigil bits into the high bits of items for sbar, or else +// mix in items2 +#ifdef QUAKE2 + items = (int)ent->v.items | ((int)ent->v.items2 << 23); +#else + val = GetEdictFieldValue(ent, "items2"); + + if (val) + items = (int)ent->v.items | ((int)val->_float << 23); + else + items = (int)ent->v.items | ((int)pr_global_struct->serverflags << 28); +#endif + + bits |= SU_ITEMS; + + if ( (int)ent->v.flags & FL_ONGROUND) + bits |= SU_ONGROUND; + + if ( ent->v.waterlevel >= 2) + bits |= SU_INWATER; + + for (i=0 ; i<3 ; i++) + { + if (ent->v.punchangle[i]) + bits |= (SU_PUNCH1<v.velocity[i]) + bits |= (SU_VELOCITY1<v.weaponframe) + bits |= SU_WEAPONFRAME; + + if (ent->v.armorvalue) + bits |= SU_ARMOR; + +// if (ent->v.weapon) + bits |= SU_WEAPON; + +// send the data + + MSG_WriteByte (msg, svc_clientdata); + MSG_WriteShort (msg, bits); + + if (bits & SU_VIEWHEIGHT) + MSG_WriteChar (msg, ent->v.view_ofs[2]); + + if (bits & SU_IDEALPITCH) + MSG_WriteChar (msg, ent->v.idealpitch); + + for (i=0 ; i<3 ; i++) + { + if (bits & (SU_PUNCH1<v.punchangle[i]); + if (bits & (SU_VELOCITY1<v.velocity[i]/16); + } + +// [always sent] if (bits & SU_ITEMS) + MSG_WriteLong (msg, items); + + if (bits & SU_WEAPONFRAME) + MSG_WriteByte (msg, ent->v.weaponframe); + if (bits & SU_ARMOR) + MSG_WriteByte (msg, ent->v.armorvalue); + if (bits & SU_WEAPON) + MSG_WriteByte (msg, SV_ModelIndex(pr_strings+ent->v.weaponmodel)); + + MSG_WriteShort (msg, ent->v.health); + MSG_WriteByte (msg, ent->v.currentammo); + MSG_WriteByte (msg, ent->v.ammo_shells); + MSG_WriteByte (msg, ent->v.ammo_nails); + MSG_WriteByte (msg, ent->v.ammo_rockets); + MSG_WriteByte (msg, ent->v.ammo_cells); + + if (standard_quake) + { + MSG_WriteByte (msg, ent->v.weapon); + } + else + { + for(i=0;i<32;i++) + { + if ( ((int)ent->v.weapon) & (1<edict, &msg); + + SV_WriteEntitiesToClient (client->edict, &msg); + +// copy the server datagram if there is space + if (msg.cursize + sv.datagram.cursize < msg.maxsize) + SZ_Write (&msg, sv.datagram.data, sv.datagram.cursize); + +// send the datagram + if (NET_SendUnreliableMessage (client->netconnection, &msg) == -1) + { + SV_DropClient (true);// if the message couldn't send, kick off + return false; + } + + return true; +} + +/* +======================= +SV_UpdateToReliableMessages +======================= +*/ +void SV_UpdateToReliableMessages (void) +{ + int i, j; + client_t *client; + +// check for changes to be sent over the reliable streams + for (i=0, host_client = svs.clients ; iold_frags != host_client->edict->v.frags) + { + for (j=0, client = svs.clients ; jactive) + continue; + MSG_WriteByte (&client->message, svc_updatefrags); + MSG_WriteByte (&client->message, i); + MSG_WriteShort (&client->message, host_client->edict->v.frags); + } + + host_client->old_frags = host_client->edict->v.frags; + } + } + + for (j=0, client = svs.clients ; jactive) + continue; + SZ_Write (&client->message, sv.reliable_datagram.data, sv.reliable_datagram.cursize); + } + + SZ_Clear (&sv.reliable_datagram); +} + + +/* +======================= +SV_SendNop + +Send a nop message without trashing or sending the accumulated client +message buffer +======================= +*/ +void SV_SendNop (client_t *client) +{ + sizebuf_t msg; + byte buf[4]; + + msg.data = buf; + msg.maxsize = sizeof(buf); + msg.cursize = 0; + + MSG_WriteChar (&msg, svc_nop); + + if (NET_SendUnreliableMessage (client->netconnection, &msg) == -1) + SV_DropClient (true); // if the message couldn't send, kick off + client->last_message = realtime; +} + +/* +======================= +SV_SendClientMessages +======================= +*/ +void SV_SendClientMessages (void) +{ + int i; + +// update frags, names, etc + SV_UpdateToReliableMessages (); + +// build individual updates + for (i=0, host_client = svs.clients ; iactive) + continue; + + if (host_client->spawned) + { + if (!SV_SendClientDatagram (host_client)) + continue; + } + else + { + // the player isn't totally in the game yet + // send small keepalive messages if too much time has passed + // send a full message when the next signon stage has been requested + // some other message data (name changes, etc) may accumulate + // between signon stages + if (!host_client->sendsignon) + { + if (realtime - host_client->last_message > 5) + SV_SendNop (host_client); + continue; // don't send out non-signon messages + } + } + + // check for an overflowed message. Should only happen + // on a very fucked up connection that backs up a lot, then + // changes level + if (host_client->message.overflowed) + { + SV_DropClient (true); + host_client->message.overflowed = false; + continue; + } + + if (host_client->message.cursize || host_client->dropasap) + { + if (!NET_CanSendMessage (host_client->netconnection)) + { +// I_Printf ("can't write\n"); + continue; + } + + if (host_client->dropasap) + SV_DropClient (false); // went to another level + else + { + if (NET_SendMessage (host_client->netconnection + , &host_client->message) == -1) + SV_DropClient (true); // if the message couldn't send, kick off + SZ_Clear (&host_client->message); + host_client->last_message = realtime; + host_client->sendsignon = false; + } + } + } + + +// clear muzzle flashes + SV_CleanupEnts (); +} + + +/* +============================================================================== + +SERVER SPAWNING + +============================================================================== +*/ + +/* +================ +SV_ModelIndex + +================ +*/ +int SV_ModelIndex (char *name) +{ + int i; + + if (!name || !name[0]) + return 0; + + for (i=0 ; ifree) + continue; + if (entnum > svs.maxclients && !svent->v.modelindex) + continue; + + // + // create entity baseline + // + VectorCopy (svent->v.origin, svent->baseline.origin); + VectorCopy (svent->v.angles, svent->baseline.angles); + svent->baseline.frame = svent->v.frame; + svent->baseline.skin = svent->v.skin; + if (entnum > 0 && entnum <= svs.maxclients) + { + svent->baseline.colormap = entnum; + svent->baseline.modelindex = SV_ModelIndex("progs/player.mdl"); + } + else + { + svent->baseline.colormap = 0; + svent->baseline.modelindex = + SV_ModelIndex(pr_strings + svent->v.model); + } + + // + // add to the message + // + MSG_WriteByte (&sv.signon,svc_spawnbaseline); + MSG_WriteShort (&sv.signon,entnum); + + MSG_WriteByte (&sv.signon, svent->baseline.modelindex); + MSG_WriteByte (&sv.signon, svent->baseline.frame); + MSG_WriteByte (&sv.signon, svent->baseline.colormap); + MSG_WriteByte (&sv.signon, svent->baseline.skin); + for (i=0 ; i<3 ; i++) + { + MSG_WriteCoord(&sv.signon, svent->baseline.origin[i]); + MSG_WriteAngle(&sv.signon, svent->baseline.angles[i]); + } + } +} + + +/* +================ +SV_SendReconnect + +Tell all the clients that the server is changing levels +================ +*/ +void SV_SendReconnect (void) +{ + char data[128]; + sizebuf_t msg; + + msg.data = data; + msg.cursize = 0; + msg.maxsize = sizeof(data); + + MSG_WriteChar (&msg, svc_stufftext); + MSG_WriteString (&msg, "reconnect\n"); + NET_SendToAll (&msg, 5); + + if (cls.state != ca_dedicated) +#ifdef QUAKE2 + Cbuf_InsertText ("reconnect\n"); +#else + Cmd_ExecuteString ("reconnect\n", src_command); +#endif +} + + +/* +================ +SV_SaveSpawnparms + +Grabs the current state of each client for saving across the +transition to another level +================ +*/ +void SV_SaveSpawnparms (void) +{ + int i, j; + + svs.serverflags = pr_global_struct->serverflags; + + for (i=0, host_client = svs.clients ; iactive) + continue; + + // call the progs to get default spawn parms for the new client + pr_global_struct->self = EDICT_TO_PROG(host_client->edict); + PR_ExecuteProgram (pr_global_struct->SetChangeParms); + for (j=0 ; jspawn_parms[j] = (&pr_global_struct->parm1)[j]; + } +} + + +/* +================ +SV_SpawnServer + +This is called at the start of each level +================ +*/ +extern float scr_centertime_off; + +#ifdef QUAKE2 +void SV_SpawnServer (char *server, char *startspot) +#else +void SV_SpawnServer (char *server) +#endif +{ + edict_t *ent; + int i; + + // let's not have any servers with no name + if (hostname.string[0] == 0) + Cvar_Set ("hostname", "UNNAMED"); + scr_centertime_off = 0; + + Con_DPrintf ("SpawnServer: %s\n",server); + svs.changelevel_issued = false; // now safe to issue another + +// +// tell all connected clients that we are going to a new level +// + if (sv.active) + { + SV_SendReconnect (); + } + +// +// make cvars consistant +// + if (coop.value) + Cvar_SetValue ("deathmatch", 0); + current_skill = (int)(skill.value + 0.5); + if (current_skill < 0) + current_skill = 0; + if (current_skill > 3) + current_skill = 3; + + Cvar_SetValue ("skill", (float)current_skill); + +// +// set up the new server +// + Host_ClearMemory (); + + memset (&sv, 0, sizeof(sv)); + + strcpy (sv.name, server); +#ifdef QUAKE2 + if (startspot) + strcpy(sv.startspot, startspot); +#endif + +// load progs to get entity field count + PR_LoadProgs (); + +// allocate server memory + sv.max_edicts = MAX_EDICTS; + + sv.edicts = Hunk_AllocName (sv.max_edicts*pr_edict_size, "edicts"); + + sv.datagram.maxsize = sizeof(sv.datagram_buf); + sv.datagram.cursize = 0; + sv.datagram.data = sv.datagram_buf; + + sv.reliable_datagram.maxsize = sizeof(sv.reliable_datagram_buf); + sv.reliable_datagram.cursize = 0; + sv.reliable_datagram.data = sv.reliable_datagram_buf; + + sv.signon.maxsize = sizeof(sv.signon_buf); + sv.signon.cursize = 0; + sv.signon.data = sv.signon_buf; + +// leave slots at start for clients only + sv.num_edicts = svs.maxclients+1; + for (i=0 ; inumsubmodels ; i++) + { + sv.model_precache[1+i] = localmodels[i]; + sv.models[i+1] = Mod_ForName (localmodels[i], false); + } + +// +// load the rest of the entities +// + ent = EDICT_NUM(0); + memset (&ent->v, 0, progs->entityfields * 4); + ent->free = false; + ent->v.model = sv.worldmodel->name - pr_strings; + ent->v.modelindex = 1; // world model + ent->v.solid = SOLID_BSP; + ent->v.movetype = MOVETYPE_PUSH; + + if (coop.value) + pr_global_struct->coop = coop.value; + else + pr_global_struct->deathmatch = deathmatch.value; + + pr_global_struct->mapname = sv.name - pr_strings; +#ifdef QUAKE2 + pr_global_struct->startspot = sv.startspot - pr_strings; +#endif + +// serverflags are for cross level information (sigils) + pr_global_struct->serverflags = svs.serverflags; + + ED_LoadFromFile (sv.worldmodel->entities); + + sv.active = true; + +// all setup is completed, any further precache statements are errors + sv.state = ss_active; + +// run two frames to allow everything to settle + host_frametime = 0.1; + SV_Physics (); + SV_Physics (); + +// create a baseline for more efficient communications + SV_CreateBaseline (); + +// send serverinfo to all connected clients + for (i=0,host_client = svs.clients ; iactive) + SV_SendServerinfo (host_client); + + Con_DPrintf ("Server spawned.\n"); +} + diff --git a/r17/Revamped src/revamped_src/sv_move.c b/r17/Revamped src/revamped_src/sv_move.c new file mode 100755 index 00000000..cc2206f0 --- /dev/null +++ b/r17/Revamped src/revamped_src/sv_move.c @@ -0,0 +1,427 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// sv_move.c -- monster movement + +#include "quakedef.h" + +#define STEPSIZE 18 + +/* +============= +SV_CheckBottom + +Returns false if any part of the bottom of the entity is off an edge that +is not a staircase. + +============= +*/ +int c_yes, c_no; + +qboolean SV_CheckBottom (edict_t *ent) +{ + vec3_t mins, maxs, start, stop; + trace_t trace; + int x, y; + float mid, bottom; + + VectorAdd (ent->v.origin, ent->v.mins, mins); + VectorAdd (ent->v.origin, ent->v.maxs, maxs); + +// if all of the points under the corners are solid world, don't bother +// with the tougher checks +// the corners must be within 16 of the midpoint + start[2] = mins[2] - 1; + for (x=0 ; x<=1 ; x++) + for (y=0 ; y<=1 ; y++) + { + start[0] = x ? maxs[0] : mins[0]; + start[1] = y ? maxs[1] : mins[1]; + if (SV_PointContents (start) != CONTENTS_SOLID) + goto realcheck; + } + + c_yes++; + return true; // we got out easy + +realcheck: + c_no++; +// +// check it for real... +// + start[2] = mins[2]; + +// the midpoint must be within 16 of the bottom + start[0] = stop[0] = (mins[0] + maxs[0])*0.5; + start[1] = stop[1] = (mins[1] + maxs[1])*0.5; + stop[2] = start[2] - 2*STEPSIZE; + trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, ent); + + if (trace.fraction == 1.0) + return false; + mid = bottom = trace.endpos[2]; + +// the corners must be within 16 of the midpoint + for (x=0 ; x<=1 ; x++) + for (y=0 ; y<=1 ; y++) + { + start[0] = stop[0] = x ? maxs[0] : mins[0]; + start[1] = stop[1] = y ? maxs[1] : mins[1]; + + trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, ent); + + if (trace.fraction != 1.0 && trace.endpos[2] > bottom) + bottom = trace.endpos[2]; + if (trace.fraction == 1.0 || mid - trace.endpos[2] > STEPSIZE) + return false; + } + + c_yes++; + return true; +} + + +/* +============= +SV_movestep + +Called by monster program code. +The move will be adjusted for slopes and stairs, but if the move isn't +possible, no move is done, false is returned, and +pr_global_struct->trace_normal is set to the normal of the blocking wall +============= +*/ +qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) +{ + float dz; + vec3_t oldorg, neworg, end; + trace_t trace; + int i; + edict_t *enemy; + +// try the move + VectorCopy (ent->v.origin, oldorg); + VectorAdd (ent->v.origin, move, neworg); + +// flying monsters don't step up + if ( (int)ent->v.flags & (FL_SWIM | FL_FLY) ) + { + // try one move with vertical motion, then one without + for (i=0 ; i<2 ; i++) + { + VectorAdd (ent->v.origin, move, neworg); + enemy = PROG_TO_EDICT(ent->v.enemy); + if (i == 0 && enemy != sv.edicts) + { + dz = ent->v.origin[2] - PROG_TO_EDICT(ent->v.enemy)->v.origin[2]; + if (dz > 40) + neworg[2] -= 8; + if (dz < 30) + neworg[2] += 8; + } + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, neworg, false, ent); + + if (trace.fraction == 1) + { + if ( ((int)ent->v.flags & FL_SWIM) && SV_PointContents(trace.endpos) == CONTENTS_EMPTY ) + return false; // swim monster left water + + VectorCopy (trace.endpos, ent->v.origin); + if (relink) + SV_LinkEdict (ent, true); + return true; + } + + if (enemy == sv.edicts) + break; + } + + return false; + } + +// push down from a step height above the wished position + neworg[2] += STEPSIZE; + VectorCopy (neworg, end); + end[2] -= STEPSIZE*2; + + trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end, false, ent); + + if (trace.allsolid) + return false; + + if (trace.startsolid) + { + neworg[2] -= STEPSIZE; + trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end, false, ent); + if (trace.allsolid || trace.startsolid) + return false; + } + if (trace.fraction == 1) + { + // if monster had the ground pulled out, go ahead and fall + if ( (int)ent->v.flags & FL_PARTIALGROUND ) + { + VectorAdd (ent->v.origin, move, ent->v.origin); + if (relink) + SV_LinkEdict (ent, true); + ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; +// Con_Printf ("fall down\n"); + return true; + } + + return false; // walked off an edge + } + +// check point traces down for dangling corners + VectorCopy (trace.endpos, ent->v.origin); + + if (!SV_CheckBottom (ent)) + { + if ( (int)ent->v.flags & FL_PARTIALGROUND ) + { // entity had floor mostly pulled out from underneath it + // and is trying to correct + if (relink) + SV_LinkEdict (ent, true); + return true; + } + VectorCopy (oldorg, ent->v.origin); + return false; + } + + if ( (int)ent->v.flags & FL_PARTIALGROUND ) + { +// Con_Printf ("back on ground\n"); + ent->v.flags = (int)ent->v.flags & ~FL_PARTIALGROUND; + } + ent->v.groundentity = EDICT_TO_PROG(trace.ent); + +// the move is ok + if (relink) + SV_LinkEdict (ent, true); + return true; +} + + +//============================================================================ + +/* +====================== +SV_StepDirection + +Turns to the movement direction, and walks the current distance if +facing it. + +====================== +*/ +void PF_changeyaw (void); +qboolean SV_StepDirection (edict_t *ent, float yaw, float dist) +{ + vec3_t move, oldorigin; + float delta; + + ent->v.ideal_yaw = yaw; + PF_changeyaw(); + + yaw = yaw*M_PI*2 / 360; + move[0] = cosf(yaw)*dist; + move[1] = sinf(yaw)*dist; + move[2] = 0; + + VectorCopy (ent->v.origin, oldorigin); + if (SV_movestep (ent, move, false)) + { + delta = ent->v.angles[YAW] - ent->v.ideal_yaw; + if (delta > 45 && delta < 315) + { // not turned far enough, so don't take the step + VectorCopy (oldorigin, ent->v.origin); + } + SV_LinkEdict (ent, true); + return true; + } + SV_LinkEdict (ent, true); + + return false; +} + +/* +====================== +SV_FixCheckBottom + +====================== +*/ +void SV_FixCheckBottom (edict_t *ent) +{ +// Con_Printf ("SV_FixCheckBottom\n"); + + ent->v.flags = (int)ent->v.flags | FL_PARTIALGROUND; +} + + + +/* +================ +SV_NewChaseDir + +================ +*/ +#define DI_NODIR -1 +void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist) +{ + float deltax,deltay; + float d[3]; + float tdir, olddir, turnaround; + + olddir = anglemod( (int)(actor->v.ideal_yaw/45)*45 ); + turnaround = anglemod(olddir - 180); + + deltax = enemy->v.origin[0] - actor->v.origin[0]; + deltay = enemy->v.origin[1] - actor->v.origin[1]; + if (deltax>10) + d[1]= 0; + else if (deltax<-10) + d[1]= 180; + else + d[1]= DI_NODIR; + if (deltay<-10) + d[2]= 270; + else if (deltay>10) + d[2]= 90; + else + d[2]= DI_NODIR; + +// try direct route + if (d[1] != DI_NODIR && d[2] != DI_NODIR) + { + if (d[1] == 0) + tdir = d[2] == 90 ? 45 : 315; + else + tdir = d[2] == 90 ? 135 : 215; + + if (tdir != turnaround && SV_StepDirection(actor, tdir, dist)) + return; + } + +// try other directions + if ( ((rand()&3) & 1) || abs(deltay)>abs(deltax)) + { + tdir=d[1]; + d[1]=d[2]; + d[2]=tdir; + } + + if (d[1]!=DI_NODIR && d[1]!=turnaround + && SV_StepDirection(actor, d[1], dist)) + return; + + if (d[2]!=DI_NODIR && d[2]!=turnaround + && SV_StepDirection(actor, d[2], dist)) + return; + +/* there is no direct path to the player, so pick another direction */ + + if (olddir!=DI_NODIR && SV_StepDirection(actor, olddir, dist)) + return; + + if (rand()&1) /*randomly determine direction of search*/ + { + for (tdir=0 ; tdir<=315 ; tdir += 45) + if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) ) + return; + } + else + { + for (tdir=315 ; tdir >=0 ; tdir -= 45) + if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) ) + return; + } + + if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist) ) + return; + + actor->v.ideal_yaw = olddir; // can't move + +// if a bridge was pulled out from underneath a monster, it may not have +// a valid standing position at all + + if (!SV_CheckBottom (actor)) + SV_FixCheckBottom (actor); + +} + +/* +====================== +SV_CloseEnough + +====================== +*/ +qboolean SV_CloseEnough (edict_t *ent, edict_t *goal, float dist) +{ + int i; + + for (i=0 ; i<3 ; i++) + { + if (goal->v.absmin[i] > ent->v.absmax[i] + dist) + return false; + if (goal->v.absmax[i] < ent->v.absmin[i] - dist) + return false; + } + return true; +} + +/* +====================== +SV_MoveToGoal + +====================== +*/ +void SV_MoveToGoal (void) +{ + edict_t *ent, *goal; + float dist; +#ifdef QUAKE2 + edict_t *enemy; +#endif + + ent = PROG_TO_EDICT(pr_global_struct->self); + goal = PROG_TO_EDICT(ent->v.goalentity); + dist = G_FLOAT(OFS_PARM0); + + if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) ) + { + G_FLOAT(OFS_RETURN) = 0; + return; + } + +// if the next step hits the enemy, return immediately +#ifdef QUAKE2 + enemy = PROG_TO_EDICT(ent->v.enemy); + if (enemy != sv.edicts && SV_CloseEnough (ent, enemy, dist) ) +#else + if ( PROG_TO_EDICT(ent->v.enemy) != sv.edicts && SV_CloseEnough (ent, goal, dist) ) +#endif + return; + +// bump around... + if ( (rand()&3)==1 || + !SV_StepDirection (ent, ent->v.ideal_yaw, dist)) + { + SV_NewChaseDir (ent, goal, dist); + } +} + diff --git a/r17/Revamped src/revamped_src/sv_phys.c b/r17/Revamped src/revamped_src/sv_phys.c new file mode 100755 index 00000000..d6aaed14 --- /dev/null +++ b/r17/Revamped src/revamped_src/sv_phys.c @@ -0,0 +1,1627 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// sv_phys.c + +#include "quakedef.h" + +/* + + +pushmove objects do not obey gravity, and do not interact with each other or trigger fields, but block normal movement and push normal objects when they move. + +onground is set for toss objects when they come to a complete rest. it is set for steping or walking objects + +doors, plats, etc are SOLID_BSP, and MOVETYPE_PUSH +bonus items are SOLID_TRIGGER touch, and MOVETYPE_TOSS +corpses are SOLID_NOT and MOVETYPE_TOSS +crates are SOLID_BBOX and MOVETYPE_TOSS +walking monsters are SOLID_SLIDEBOX and MOVETYPE_STEP +flying/floating monsters are SOLID_SLIDEBOX and MOVETYPE_FLY + +solid_edge items only clip against bsp models. + +*/ + +cvar_t sv_friction = {"sv_friction","4",false,true}; +cvar_t sv_stopspeed = {"sv_stopspeed","100"}; +cvar_t sv_gravity = {"sv_gravity","800",false,true}; +cvar_t sv_maxvelocity = {"sv_maxvelocity","2000"}; +cvar_t sv_nostep = {"sv_nostep","0"}; + +#ifdef QUAKE2 +static vec3_t vec_origin = {0.0, 0.0, 0.0}; +#endif + +#define MOVE_EPSILON 0.01 + +void SV_Physics_Toss (edict_t *ent); + +/* +================ +SV_CheckAllEnts +================ +*/ +void SV_CheckAllEnts (void) +{ + int e; + edict_t *check; + +// see if any solid entities are inside the final position + check = NEXT_EDICT(sv.edicts); + for (e=1 ; efree) + continue; + if (check->v.movetype == MOVETYPE_PUSH + || check->v.movetype == MOVETYPE_NONE +#ifdef QUAKE2 + || check->v.movetype == MOVETYPE_FOLLOW +#endif + || check->v.movetype == MOVETYPE_NOCLIP) + continue; + + if (SV_TestEntityPosition (check)) + Con_Printf ("entity in invalid position\n"); + } +} + +/* +================ +SV_CheckVelocity +================ +*/ +void SV_CheckVelocity (edict_t *ent) +{ + int i; + float wishspeed; + +// +// bound velocity +// + for (i=0 ; i<3 ; i++) + { + if (IS_NAN(ent->v.velocity[i])) + { + Con_Printf ("Got a NaN velocity on %s\n", pr_strings + ent->v.classname); + ent->v.velocity[i] = 0; + } + if (IS_NAN(ent->v.origin[i])) + { + Con_Printf ("Got a NaN origin on %s\n", pr_strings + ent->v.classname); + ent->v.origin[i] = 0; + } +/* + if (ent->v.velocity[i] > sv_maxvelocity.value) + ent->v.velocity[i] = sv_maxvelocity.value; + else if (ent->v.velocity[i] < -sv_maxvelocity.value) + ent->v.velocity[i] = -sv_maxvelocity.value; +*/ + } + + wishspeed = Length(ent->v.velocity); + if (wishspeed > sv_maxvelocity.value) + { + VectorScale (ent->v.velocity, sv_maxvelocity.value/wishspeed, ent->v.velocity); + wishspeed = sv_maxvelocity.value; + } +} + +/* +============= +SV_RunThink + +Runs thinking code if time. There is some play in the exact time the think +function will be called, because it is called before any movement is done +in a frame. Not used for pushmove objects, because they must be exact. +Returns false if the entity removed itself. +============= +*/ +qboolean SV_RunThink (edict_t *ent) +{ + float thinktime; + + thinktime = ent->v.nextthink; + if (thinktime <= 0 || thinktime > sv.time + host_frametime) + return true; + + if (thinktime < sv.time) + thinktime = sv.time; // don't let things stay in the past. + // it is possible to start that way + // by a trigger with a local time. + ent->v.nextthink = 0; + pr_global_struct->time = thinktime; + pr_global_struct->self = EDICT_TO_PROG(ent); + pr_global_struct->other = EDICT_TO_PROG(sv.edicts); + PR_ExecuteProgram (ent->v.think); + return !ent->free; +} + +/* +================== +SV_Impact + +Two entities have touched, so run their touch functions +================== +*/ +void SV_Impact (edict_t *e1, edict_t *e2) +{ + int old_self, old_other; + + old_self = pr_global_struct->self; + old_other = pr_global_struct->other; + + pr_global_struct->time = sv.time; + if (e1->v.touch && e1->v.solid != SOLID_NOT) + { + pr_global_struct->self = EDICT_TO_PROG(e1); + pr_global_struct->other = EDICT_TO_PROG(e2); + PR_ExecuteProgram (e1->v.touch); + } + + if (e2->v.touch && e2->v.solid != SOLID_NOT) + { + pr_global_struct->self = EDICT_TO_PROG(e2); + pr_global_struct->other = EDICT_TO_PROG(e1); + PR_ExecuteProgram (e2->v.touch); + } + + pr_global_struct->self = old_self; + pr_global_struct->other = old_other; +} + + +/* +================== +ClipVelocity + +Slide off of the impacting object +returns the blocked flags (1 = floor, 2 = step / wall) +================== +*/ +#define STOP_EPSILON 0.1 + +int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) +{ + float backoff; + float change; + int i, blocked; + + blocked = 0; + if (normal[2] > 0) + blocked |= 1; // floor + if (!normal[2]) + blocked |= 2; // step + + backoff = DotProduct (in, normal) * overbounce; + + for (i=0 ; i<3 ; i++) + { + change = normal[i]*backoff; + out[i] = in[i] - change; + if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON) + out[i] = 0; + } + + return blocked; +} + + +/* +============ +SV_FlyMove + +The basic solid body movement clip that slides along multiple planes +Returns the clipflags if the velocity was modified (hit something solid) +1 = floor +2 = wall / step +4 = dead stop +If steptrace is not NULL, the trace of any vertical wall hit will be stored +============ +*/ +#define MAX_CLIP_PLANES 5 +int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) +{ + int bumpcount, numbumps; + vec3_t dir; + float d; + int numplanes; + vec3_t planes[MAX_CLIP_PLANES]; + vec3_t primal_velocity, original_velocity, new_velocity; + int i, j; + trace_t trace; + vec3_t end; + float time_left; + int blocked; + + numbumps = 4; + + blocked = 0; + VectorCopy (ent->v.velocity, original_velocity); + VectorCopy (ent->v.velocity, primal_velocity); + numplanes = 0; + + time_left = time; + + for (bumpcount=0 ; bumpcountv.velocity[0] && !ent->v.velocity[1] && !ent->v.velocity[2]) + break; + + for (i=0 ; i<3 ; i++) + end[i] = ent->v.origin[i] + time_left * ent->v.velocity[i]; + + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent); + + if (trace.allsolid) + { // entity is trapped in another solid + VectorCopy (vec3_origin, ent->v.velocity); + return 3; + } + + if (trace.fraction > 0) + { // actually covered some distance + VectorCopy (trace.endpos, ent->v.origin); + VectorCopy (ent->v.velocity, original_velocity); + numplanes = 0; + } + + if (trace.fraction == 1) + break; // moved the entire distance + + if (!trace.ent) + Sys_Error ("SV_FlyMove: !trace.ent"); + + if (trace.plane.normal[2] > 0.7) + { + blocked |= 1; // floor + if (trace.ent->v.solid == SOLID_BSP) + { + ent->v.flags = (int)ent->v.flags | FL_ONGROUND; + ent->v.groundentity = EDICT_TO_PROG(trace.ent); + } + } + if (!trace.plane.normal[2]) + { + blocked |= 2; // step + if (steptrace) + *steptrace = trace; // save for player extrafriction + } + +// +// run the impact function +// + SV_Impact (ent, trace.ent); + if (ent->free) + break; // removed by the impact function + + + time_left -= time_left * trace.fraction; + + // cliped to another plane + if (numplanes >= MAX_CLIP_PLANES) + { // this shouldn't really happen + VectorCopy (vec3_origin, ent->v.velocity); + return 3; + } + + VectorCopy (trace.plane.normal, planes[numplanes]); + numplanes++; + +// +// modify original_velocity so it parallels all of the clip planes +// + for (i=0 ; iv.velocity); + } + else + { // go along the crease + if (numplanes != 2) + { +// Con_Printf ("clip velocity, numplanes == %i\n",numplanes); + VectorCopy (vec3_origin, ent->v.velocity); + return 7; + } + CrossProduct (planes[0], planes[1], dir); + d = DotProduct (dir, ent->v.velocity); + VectorScale (dir, d, ent->v.velocity); + } + +// +// if original velocity is against the original velocity, stop dead +// to avoid tiny occilations in sloping corners +// + if (DotProduct (ent->v.velocity, primal_velocity) <= 0) + { + VectorCopy (vec3_origin, ent->v.velocity); + return blocked; + } + } + + return blocked; +} + + +/* +============ +SV_AddGravity + +============ +*/ +void SV_AddGravity (edict_t *ent) +{ + float ent_gravity; + +#ifdef QUAKE2 + if (ent->v.gravity) + ent_gravity = ent->v.gravity; + else + ent_gravity = 1.0; +#else + eval_t *val; + + val = GetEdictFieldValue(ent, "gravity"); + if (val && val->_float) + ent_gravity = val->_float; + else + ent_gravity = 1.0; +#endif + ent->v.velocity[2] -= ent_gravity * sv_gravity.value * host_frametime; +} + + +/* +=============================================================================== + +PUSHMOVE + +=============================================================================== +*/ + +/* +============ +SV_PushEntity + +Does not change the entities velocity at all +============ +*/ +trace_t SV_PushEntity (edict_t *ent, vec3_t push) +{ + trace_t trace; + vec3_t end; + + VectorAdd (ent->v.origin, push, end); + + if (ent->v.movetype == MOVETYPE_FLYMISSILE) + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_MISSILE, ent); + else if (ent->v.solid == SOLID_TRIGGER || ent->v.solid == SOLID_NOT) + // only clip against bmodels + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NOMONSTERS, ent); + else + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent); + + VectorCopy (trace.endpos, ent->v.origin); + SV_LinkEdict (ent, true); + + if (trace.ent) + SV_Impact (ent, trace.ent); + + return trace; +} + + +/* +============ +SV_PushMove + +============ +*/ +void SV_PushMove (edict_t *pusher, float movetime) +{ + int i, e; + edict_t *check, *block; + vec3_t mins, maxs, move; + vec3_t entorig, pushorig; + int num_moved; + edict_t *moved_edict[MAX_EDICTS]; + vec3_t moved_from[MAX_EDICTS]; + + if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2]) + { + pusher->v.ltime += movetime; + return; + } + + for (i=0 ; i<3 ; i++) + { + move[i] = pusher->v.velocity[i] * movetime; + mins[i] = pusher->v.absmin[i] + move[i]; + maxs[i] = pusher->v.absmax[i] + move[i]; + } + + VectorCopy (pusher->v.origin, pushorig); + +// move the pusher to it's final position + + VectorAdd (pusher->v.origin, move, pusher->v.origin); + pusher->v.ltime += movetime; + SV_LinkEdict (pusher, false); + + +// see if any solid entities are inside the final position + num_moved = 0; + check = NEXT_EDICT(sv.edicts); + for (e=1 ; efree) + continue; + if (check->v.movetype == MOVETYPE_PUSH + || check->v.movetype == MOVETYPE_NONE +#ifdef QUAKE2 + || check->v.movetype == MOVETYPE_FOLLOW +#endif + || check->v.movetype == MOVETYPE_NOCLIP) + continue; + + // if the entity is standing on the pusher, it will definately be moved + if ( ! ( ((int)check->v.flags & FL_ONGROUND) + && PROG_TO_EDICT(check->v.groundentity) == pusher) ) + { + if ( check->v.absmin[0] >= maxs[0] + || check->v.absmin[1] >= maxs[1] + || check->v.absmin[2] >= maxs[2] + || check->v.absmax[0] <= mins[0] + || check->v.absmax[1] <= mins[1] + || check->v.absmax[2] <= mins[2] ) + continue; + + // see if the ent's bbox is inside the pusher's final position + if (!SV_TestEntityPosition (check)) + continue; + } + + // remove the onground flag for non-players + if (check->v.movetype != MOVETYPE_WALK) + check->v.flags = (int)check->v.flags & ~FL_ONGROUND; + + VectorCopy (check->v.origin, entorig); + VectorCopy (check->v.origin, moved_from[num_moved]); + moved_edict[num_moved] = check; + num_moved++; + + // try moving the contacted entity + pusher->v.solid = SOLID_NOT; + SV_PushEntity (check, move); + pusher->v.solid = SOLID_BSP; + + // if it is still inside the pusher, block + block = SV_TestEntityPosition (check); + if (block) + { // fail the move + if (check->v.mins[0] == check->v.maxs[0]) + continue; + if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER) + { // corpse + check->v.mins[0] = check->v.mins[1] = 0; + VectorCopy (check->v.mins, check->v.maxs); + continue; + } + + VectorCopy (entorig, check->v.origin); + SV_LinkEdict (check, true); + + VectorCopy (pushorig, pusher->v.origin); + SV_LinkEdict (pusher, false); + pusher->v.ltime -= movetime; + + // if the pusher has a "blocked" function, call it + // otherwise, just stay in place until the obstacle is gone + if (pusher->v.blocked) + { + pr_global_struct->self = EDICT_TO_PROG(pusher); + pr_global_struct->other = EDICT_TO_PROG(check); + PR_ExecuteProgram (pusher->v.blocked); + } + + // move back any entities we already moved + for (i=0 ; iv.origin); + SV_LinkEdict (moved_edict[i], false); + } + return; + } + } + + +} + +#ifdef QUAKE2 +/* +============ +SV_PushRotate + +============ +*/ +void SV_PushRotate (edict_t *pusher, float movetime) +{ + int i, e; + edict_t *check, *block; + vec3_t move, a, amove; + vec3_t entorig, pushorig; + int num_moved; + edict_t *moved_edict[MAX_EDICTS]; + vec3_t moved_from[MAX_EDICTS]; + vec3_t org, org2; + vec3_t forward, right, up; + + if (!pusher->v.avelocity[0] && !pusher->v.avelocity[1] && !pusher->v.avelocity[2]) + { + pusher->v.ltime += movetime; + return; + } + + for (i=0 ; i<3 ; i++) + amove[i] = pusher->v.avelocity[i] * movetime; + + VectorSubtract (vec3_origin, amove, a); + AngleVectors (a, forward, right, up); + + VectorCopy (pusher->v.angles, pushorig); + +// move the pusher to it's final position + + VectorAdd (pusher->v.angles, amove, pusher->v.angles); + pusher->v.ltime += movetime; + SV_LinkEdict (pusher, false); + + +// see if any solid entities are inside the final position + num_moved = 0; + check = NEXT_EDICT(sv.edicts); + for (e=1 ; efree) + continue; + if (check->v.movetype == MOVETYPE_PUSH + || check->v.movetype == MOVETYPE_NONE + || check->v.movetype == MOVETYPE_FOLLOW + || check->v.movetype == MOVETYPE_NOCLIP) + continue; + + // if the entity is standing on the pusher, it will definately be moved + if ( ! ( ((int)check->v.flags & FL_ONGROUND) + && PROG_TO_EDICT(check->v.groundentity) == pusher) ) + { + if ( check->v.absmin[0] >= pusher->v.absmax[0] + || check->v.absmin[1] >= pusher->v.absmax[1] + || check->v.absmin[2] >= pusher->v.absmax[2] + || check->v.absmax[0] <= pusher->v.absmin[0] + || check->v.absmax[1] <= pusher->v.absmin[1] + || check->v.absmax[2] <= pusher->v.absmin[2] ) + continue; + + // see if the ent's bbox is inside the pusher's final position + if (!SV_TestEntityPosition (check)) + continue; + } + + // remove the onground flag for non-players + if (check->v.movetype != MOVETYPE_WALK) + check->v.flags = (int)check->v.flags & ~FL_ONGROUND; + + VectorCopy (check->v.origin, entorig); + VectorCopy (check->v.origin, moved_from[num_moved]); + moved_edict[num_moved] = check; + num_moved++; + + // calculate destination position + VectorSubtract (check->v.origin, pusher->v.origin, org); + org2[0] = DotProduct (org, forward); + org2[1] = -DotProduct (org, right); + org2[2] = DotProduct (org, up); + VectorSubtract (org2, org, move); + + // try moving the contacted entity + pusher->v.solid = SOLID_NOT; + SV_PushEntity (check, move); + pusher->v.solid = SOLID_BSP; + + // if it is still inside the pusher, block + block = SV_TestEntityPosition (check); + if (block) + { // fail the move + if (check->v.mins[0] == check->v.maxs[0]) + continue; + if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER) + { // corpse + check->v.mins[0] = check->v.mins[1] = 0; + VectorCopy (check->v.mins, check->v.maxs); + continue; + } + + VectorCopy (entorig, check->v.origin); + SV_LinkEdict (check, true); + + VectorCopy (pushorig, pusher->v.angles); + SV_LinkEdict (pusher, false); + pusher->v.ltime -= movetime; + + // if the pusher has a "blocked" function, call it + // otherwise, just stay in place until the obstacle is gone + if (pusher->v.blocked) + { + pr_global_struct->self = EDICT_TO_PROG(pusher); + pr_global_struct->other = EDICT_TO_PROG(check); + PR_ExecuteProgram (pusher->v.blocked); + } + + // move back any entities we already moved + for (i=0 ; iv.origin); + VectorSubtract (moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles); + SV_LinkEdict (moved_edict[i], false); + } + return; + } + else + { + VectorAdd (check->v.angles, amove, check->v.angles); + } + } + + +} +#endif + +/* +================ +SV_Physics_Pusher + +================ +*/ +void SV_Physics_Pusher (edict_t *ent) +{ + float thinktime; + float oldltime; + float movetime; + + oldltime = ent->v.ltime; + + thinktime = ent->v.nextthink; + if (thinktime < ent->v.ltime + host_frametime) + { + movetime = thinktime - ent->v.ltime; + if (movetime < 0) + movetime = 0; + } + else + movetime = host_frametime; + + if (movetime) + { +#ifdef QUAKE2 + if (ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2]) + SV_PushRotate (ent, movetime); + else +#endif + SV_PushMove (ent, movetime); // advances ent->v.ltime if not blocked + } + + if (thinktime > oldltime && thinktime <= ent->v.ltime) + { + ent->v.nextthink = 0; + pr_global_struct->time = sv.time; + pr_global_struct->self = EDICT_TO_PROG(ent); + pr_global_struct->other = EDICT_TO_PROG(sv.edicts); + PR_ExecuteProgram (ent->v.think); + if (ent->free) + return; + } + +} + + +/* +=============================================================================== + +CLIENT MOVEMENT + +=============================================================================== +*/ + +/* +============= +SV_CheckStuck + +This is a big hack to try and fix the rare case of getting stuck in the world +clipping hull. +============= +*/ +void SV_CheckStuck (edict_t *ent) +{ + int i, j; + int z; + vec3_t org; + + if (!SV_TestEntityPosition(ent)) + { + VectorCopy (ent->v.origin, ent->v.oldorigin); + return; + } + + VectorCopy (ent->v.origin, org); + VectorCopy (ent->v.oldorigin, ent->v.origin); + if (!SV_TestEntityPosition(ent)) + { + Con_DPrintf ("Unstuck.\n"); + SV_LinkEdict (ent, true); + return; + } + + for (z=0 ; z< 18 ; z++) + for (i=-1 ; i <= 1 ; i++) + for (j=-1 ; j <= 1 ; j++) + { + ent->v.origin[0] = org[0] + i; + ent->v.origin[1] = org[1] + j; + ent->v.origin[2] = org[2] + z; + if (!SV_TestEntityPosition(ent)) + { + Con_DPrintf ("Unstuck.\n"); + SV_LinkEdict (ent, true); + return; + } + } + + VectorCopy (org, ent->v.origin); + Con_DPrintf ("player is stuck.\n"); +} + + +/* +============= +SV_CheckWater +============= +*/ +qboolean SV_CheckWater (edict_t *ent) +{ + vec3_t point; + int cont; +#ifdef QUAKE2 + int truecont; +#endif + + point[0] = ent->v.origin[0]; + point[1] = ent->v.origin[1]; + point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; + + ent->v.waterlevel = 0; + ent->v.watertype = CONTENTS_EMPTY; + cont = SV_PointContents (point); + if (cont <= CONTENTS_WATER) + { +#ifdef QUAKE2 + truecont = SV_TruePointContents (point); +#endif + ent->v.watertype = cont; + ent->v.waterlevel = 1; + point[2] = ent->v.origin[2] + (ent->v.mins[2] + ent->v.maxs[2])*0.5; + cont = SV_PointContents (point); + if (cont <= CONTENTS_WATER) + { + ent->v.waterlevel = 2; + point[2] = ent->v.origin[2] + ent->v.view_ofs[2]; + cont = SV_PointContents (point); + if (cont <= CONTENTS_WATER) + ent->v.waterlevel = 3; + } +#ifdef QUAKE2 + if (truecont <= CONTENTS_CURRENT_0 && truecont >= CONTENTS_CURRENT_DOWN) + { + static vec3_t current_table[] = + { + {1, 0, 0}, + {0, 1, 0}, + {-1, 0, 0}, + {0, -1, 0}, + {0, 0, 1}, + {0, 0, -1} + }; + + VectorMA (ent->v.basevelocity, 150.0*ent->v.waterlevel/3.0, current_table[CONTENTS_CURRENT_0 - truecont], ent->v.basevelocity); + } +#endif + } + + return ent->v.waterlevel > 1; +} + +/* +============ +SV_WallFriction + +============ +*/ +void SV_WallFriction (edict_t *ent, trace_t *trace) +{ + vec3_t forward, right, up; + float d, i; + vec3_t into, side; + + AngleVectors (ent->v.v_angle, forward, right, up); + d = DotProduct (trace->plane.normal, forward); + + d += 0.5; + if (d >= 0) + return; + +// cut the tangential velocity + i = DotProduct (trace->plane.normal, ent->v.velocity); + VectorScale (trace->plane.normal, i, into); + VectorSubtract (ent->v.velocity, into, side); + + ent->v.velocity[0] = side[0] * (1 + d); + ent->v.velocity[1] = side[1] * (1 + d); +} + +/* +===================== +SV_TryUnstick + +Player has come to a dead stop, possibly due to the problem with limited +float precision at some angle joins in the BSP hull. + +Try fixing by pushing one pixel in each direction. + +This is a hack, but in the interest of good gameplay... +====================== +*/ +int SV_TryUnstick (edict_t *ent, vec3_t oldvel) +{ + int i; + vec3_t oldorg; + vec3_t dir; + int clip; + trace_t steptrace; + + VectorCopy (ent->v.origin, oldorg); + VectorCopy (vec3_origin, dir); + + for (i=0 ; i<8 ; i++) + { +// try pushing a little in an axial direction + switch (i) + { + case 0: dir[0] = 2; dir[1] = 0; break; + case 1: dir[0] = 0; dir[1] = 2; break; + case 2: dir[0] = -2; dir[1] = 0; break; + case 3: dir[0] = 0; dir[1] = -2; break; + case 4: dir[0] = 2; dir[1] = 2; break; + case 5: dir[0] = -2; dir[1] = 2; break; + case 6: dir[0] = 2; dir[1] = -2; break; + case 7: dir[0] = -2; dir[1] = -2; break; + } + + SV_PushEntity (ent, dir); + +// retry the original move + ent->v.velocity[0] = oldvel[0]; + ent->v. velocity[1] = oldvel[1]; + ent->v. velocity[2] = 0; + clip = SV_FlyMove (ent, 0.1, &steptrace); + + if ( fabsf(oldorg[1] - ent->v.origin[1]) > 4 + || fabsf(oldorg[0] - ent->v.origin[0]) > 4 ) + { +//Con_DPrintf ("unstuck!\n"); + return clip; + } + +// go back to the original pos and try again + VectorCopy (oldorg, ent->v.origin); + } + + VectorCopy (vec3_origin, ent->v.velocity); + return 7; // still not moving +} + +/* +===================== +SV_WalkMove + +Only used by players +====================== +*/ +#define STEPSIZE 18 +void SV_WalkMove (edict_t *ent) +{ + vec3_t upmove, downmove; + vec3_t oldorg, oldvel; + vec3_t nosteporg, nostepvel; + int clip; + int oldonground; + trace_t steptrace, downtrace; + +// +// do a regular slide move unless it looks like you ran into a step +// + oldonground = (int)ent->v.flags & FL_ONGROUND; + ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; + + VectorCopy (ent->v.origin, oldorg); + VectorCopy (ent->v.velocity, oldvel); + + clip = SV_FlyMove (ent, host_frametime, &steptrace); + + if ( !(clip & 2) ) + return; // move didn't block on a step + + if (!oldonground && ent->v.waterlevel == 0) + return; // don't stair up while jumping + + if (ent->v.movetype != MOVETYPE_WALK) + return; // gibbed by a trigger + + if (sv_nostep.value) + return; + + if ( (int)sv_player->v.flags & FL_WATERJUMP ) + return; + + VectorCopy (ent->v.origin, nosteporg); + VectorCopy (ent->v.velocity, nostepvel); + +// +// try moving up and forward to go up a step +// + VectorCopy (oldorg, ent->v.origin); // back to start pos + + VectorCopy (vec3_origin, upmove); + VectorCopy (vec3_origin, downmove); + upmove[2] = STEPSIZE; + downmove[2] = -STEPSIZE + oldvel[2]*host_frametime; + +// move up + SV_PushEntity (ent, upmove); // FIXME: don't link? + +// move forward + ent->v.velocity[0] = oldvel[0]; + ent->v. velocity[1] = oldvel[1]; + ent->v. velocity[2] = 0; + clip = SV_FlyMove (ent, host_frametime, &steptrace); + +// check for stuckness, possibly due to the limited precision of floats +// in the clipping hulls + if (clip) + { + if ( fabsf(oldorg[1] - ent->v.origin[1]) < 0.03125 + && fabsf(oldorg[0] - ent->v.origin[0]) < 0.03125 ) + { // stepping up didn't make any progress + clip = SV_TryUnstick (ent, oldvel); + } + } + +// extra friction based on view angle + if ( clip & 2 ) + SV_WallFriction (ent, &steptrace); + +// move down + downtrace = SV_PushEntity (ent, downmove); // FIXME: don't link? + + if (downtrace.plane.normal[2] > 0.7) + { + if (ent->v.solid == SOLID_BSP) + { + ent->v.flags = (int)ent->v.flags | FL_ONGROUND; + ent->v.groundentity = EDICT_TO_PROG(downtrace.ent); + } + } + else + { +// if the push down didn't end up on good ground, use the move without +// the step up. This happens near wall / slope combinations, and can +// cause the player to hop up higher on a slope too steep to climb + VectorCopy (nosteporg, ent->v.origin); + VectorCopy (nostepvel, ent->v.velocity); + } +} + + +/* +================ +SV_Physics_Client + +Player character actions +================ +*/ +void SV_Physics_Client (edict_t *ent, int num) +{ + if ( ! svs.clients[num-1].active ) + return; // unconnected slot + +// +// call standard client pre-think +// + pr_global_struct->time = sv.time; + pr_global_struct->self = EDICT_TO_PROG(ent); + PR_ExecuteProgram (pr_global_struct->PlayerPreThink); + +// +// do a move +// + SV_CheckVelocity (ent); + +// +// decide which move function to call +// + switch ((int)ent->v.movetype) + { + case MOVETYPE_NONE: + if (!SV_RunThink (ent)) + return; + break; + + case MOVETYPE_WALK: + if (!SV_RunThink (ent)) + return; + if (!SV_CheckWater (ent) && ! ((int)ent->v.flags & FL_WATERJUMP) ) + SV_AddGravity (ent); + SV_CheckStuck (ent); +#ifdef QUAKE2 + VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); +#endif + SV_WalkMove (ent); + +#ifdef QUAKE2 + VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); +#endif + break; + + case MOVETYPE_TOSS: + case MOVETYPE_BOUNCE: + SV_Physics_Toss (ent); + break; + + case MOVETYPE_FLY: + if (!SV_RunThink (ent)) + return; + SV_FlyMove (ent, host_frametime, NULL); + break; + + case MOVETYPE_NOCLIP: + if (!SV_RunThink (ent)) + return; + VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin); + break; + + default: + Sys_Error ("SV_Physics_client: bad movetype %i", (int)ent->v.movetype); + } + +// +// call standard player post-think +// + SV_LinkEdict (ent, true); + + pr_global_struct->time = sv.time; + pr_global_struct->self = EDICT_TO_PROG(ent); + PR_ExecuteProgram (pr_global_struct->PlayerPostThink); +} + +//============================================================================ + +/* +============= +SV_Physics_None + +Non moving objects can only think +============= +*/ +void SV_Physics_None (edict_t *ent) +{ +// regular thinking + SV_RunThink (ent); +} + +#ifdef QUAKE2 +/* +============= +SV_Physics_Follow + +Entities that are "stuck" to another entity +============= +*/ +void SV_Physics_Follow (edict_t *ent) +{ +// regular thinking + SV_RunThink (ent); + VectorAdd (PROG_TO_EDICT(ent->v.aiment)->v.origin, ent->v.v_angle, ent->v.origin); + SV_LinkEdict (ent, true); +} +#endif + +/* +============= +SV_Physics_Noclip + +A moving object that doesn't obey physics +============= +*/ +void SV_Physics_Noclip (edict_t *ent) +{ +// regular thinking + if (!SV_RunThink (ent)) + return; + + VectorMA (ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles); + VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin); + + SV_LinkEdict (ent, false); +} + +/* +============================================================================== + +TOSS / BOUNCE + +============================================================================== +*/ + +/* +============= +SV_CheckWaterTransition + +============= +*/ +void SV_CheckWaterTransition (edict_t *ent) +{ + int cont; +#ifdef QUAKE2 + vec3_t point; + + point[0] = ent->v.origin[0]; + point[1] = ent->v.origin[1]; + point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; + cont = SV_PointContents (point); +#else + cont = SV_PointContents (ent->v.origin); +#endif + if (!ent->v.watertype) + { // just spawned here + ent->v.watertype = cont; + ent->v.waterlevel = 1; + return; + } + + if (cont <= CONTENTS_WATER) + { + if (ent->v.watertype == CONTENTS_EMPTY) + { // just crossed into water + SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); + } + ent->v.watertype = cont; + ent->v.waterlevel = 1; + } + else + { + if (ent->v.watertype != CONTENTS_EMPTY) + { // just crossed into water + SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); + } + ent->v.watertype = CONTENTS_EMPTY; + ent->v.waterlevel = cont; + } +} + +/* +============= +SV_Physics_Toss + +Toss, bounce, and fly movement. When onground, do nothing. +============= +*/ +void SV_Physics_Toss (edict_t *ent) +{ + trace_t trace; + vec3_t move; + float backoff; +#ifdef QUAKE2 + edict_t *groundentity; + + groundentity = PROG_TO_EDICT(ent->v.groundentity); + if ((int)groundentity->v.flags & FL_CONVEYOR) + VectorScale(groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity); + else + VectorCopy(vec_origin, ent->v.basevelocity); + SV_CheckWater (ent); +#endif + // regular thinking + if (!SV_RunThink (ent)) + return; + +#ifdef QUAKE2 + if (ent->v.velocity[2] > 0) + ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; + + if ( ((int)ent->v.flags & FL_ONGROUND) ) +//@@ + if (VectorCompare(ent->v.basevelocity, vec_origin)) + return; + + SV_CheckVelocity (ent); + +// add gravity + if (! ((int)ent->v.flags & FL_ONGROUND) + && ent->v.movetype != MOVETYPE_FLY + && ent->v.movetype != MOVETYPE_BOUNCEMISSILE + && ent->v.movetype != MOVETYPE_FLYMISSILE) + SV_AddGravity (ent); + +#else +// if onground, return without moving + if ( ((int)ent->v.flags & FL_ONGROUND) ) + return; + + SV_CheckVelocity (ent); + +// add gravity + if (ent->v.movetype != MOVETYPE_FLY + && ent->v.movetype != MOVETYPE_FLYMISSILE) + SV_AddGravity (ent); +#endif + +// move angles + VectorMA (ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles); + +// move origin +#ifdef QUAKE2 + VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); +#endif + VectorScale (ent->v.velocity, host_frametime, move); + trace = SV_PushEntity (ent, move); +#ifdef QUAKE2 + VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); +#endif + if (trace.fraction == 1) + return; + if (ent->free) + return; + + if (ent->v.movetype == MOVETYPE_BOUNCE) + backoff = 1.5; +#ifdef QUAKE2 + else if (ent->v.movetype == MOVETYPE_BOUNCEMISSILE) + backoff = 2.0; +#endif + else + backoff = 1; + + ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, backoff); + +// stop if on ground + if (trace.plane.normal[2] > 0.7) + { +#ifdef QUAKE2 + if (ent->v.velocity[2] < 60 || (ent->v.movetype != MOVETYPE_BOUNCE && ent->v.movetype != MOVETYPE_BOUNCEMISSILE)) +#else + if (ent->v.velocity[2] < 60 || ent->v.movetype != MOVETYPE_BOUNCE) +#endif + { + ent->v.flags = (int)ent->v.flags | FL_ONGROUND; + ent->v.groundentity = EDICT_TO_PROG(trace.ent); + VectorCopy (vec3_origin, ent->v.velocity); + VectorCopy (vec3_origin, ent->v.avelocity); + } + } + +// check for in water + SV_CheckWaterTransition (ent); +} + +/* +=============================================================================== + +STEPPING MOVEMENT + +=============================================================================== +*/ + +/* +============= +SV_Physics_Step + +Monsters freefall when they don't have a ground entity, otherwise +all movement is done with discrete steps. + +This is also used for objects that have become still on the ground, but +will fall if the floor is pulled out from under them. +============= +*/ +#ifdef QUAKE2 +void SV_Physics_Step (edict_t *ent) +{ + qboolean wasonground; + qboolean inwater; + qboolean hitsound = false; + float *vel; + float speed, newspeed, control; + float friction; + edict_t *groundentity; + + groundentity = PROG_TO_EDICT(ent->v.groundentity); + if ((int)groundentity->v.flags & FL_CONVEYOR) + VectorScale(groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity); + else + VectorCopy(vec_origin, ent->v.basevelocity); +//@@ + pr_global_struct->time = sv.time; + pr_global_struct->self = EDICT_TO_PROG(ent); + PF_WaterMove(); + + SV_CheckVelocity (ent); + + wasonground = (int)ent->v.flags & FL_ONGROUND; +// ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; + + // add gravity except: + // flying monsters + // swimming monsters who are in the water + inwater = SV_CheckWater(ent); + if (! wasonground) + if (!((int)ent->v.flags & FL_FLY)) + if (!(((int)ent->v.flags & FL_SWIM) && (ent->v.waterlevel > 0))) + { + if (ent->v.velocity[2] < sv_gravity.value*-0.1) + hitsound = true; + if (!inwater) + SV_AddGravity (ent); + } + + if (!VectorCompare(ent->v.velocity, vec_origin) || !VectorCompare(ent->v.basevelocity, vec_origin)) + { + ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; + // apply friction + // let dead monsters who aren't completely onground slide + if (wasonground) + if (!(ent->v.health <= 0.0 && !SV_CheckBottom(ent))) + { + vel = ent->v.velocity; + speed = sqrtf(vel[0]*vel[0] +vel[1]*vel[1]); + if (speed) + { + friction = sv_friction.value; + + control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed; + newspeed = speed - host_frametime*control*friction; + + if (newspeed < 0) + newspeed = 0; + newspeed /= speed; + + vel[0] = vel[0] * newspeed; + vel[1] = vel[1] * newspeed; + } + } + + VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); + SV_FlyMove (ent, host_frametime, NULL); + VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); + + // determine if it's on solid ground at all + { + vec3_t mins, maxs, point; + int x, y; + + VectorAdd (ent->v.origin, ent->v.mins, mins); + VectorAdd (ent->v.origin, ent->v.maxs, maxs); + + point[2] = mins[2] - 1; + for (x=0 ; x<=1 ; x++) + for (y=0 ; y<=1 ; y++) + { + point[0] = x ? maxs[0] : mins[0]; + point[1] = y ? maxs[1] : mins[1]; + if (SV_PointContents (point) == CONTENTS_SOLID) + { + ent->v.flags = (int)ent->v.flags | FL_ONGROUND; + break; + } + } + + } + + SV_LinkEdict (ent, true); + + if ((int)ent->v.flags & FL_ONGROUND) + if (!wasonground) + if (hitsound) + SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1); + } + +// regular thinking + SV_RunThink (ent); + SV_CheckWaterTransition (ent); +} +#else +void SV_Physics_Step (edict_t *ent) +{ + qboolean hitsound; + +// freefall if not onground + if ( ! ((int)ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM) ) ) + { + if (ent->v.velocity[2] < sv_gravity.value*-0.1) + hitsound = true; + else + hitsound = false; + + SV_AddGravity (ent); + SV_CheckVelocity (ent); + SV_FlyMove (ent, host_frametime, NULL); + SV_LinkEdict (ent, true); + + if ( (int)ent->v.flags & FL_ONGROUND ) // just hit ground + { + if (hitsound) + SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1); + } + } + +// regular thinking + SV_RunThink (ent); + + SV_CheckWaterTransition (ent); +} +#endif + +//============================================================================ + +/* +================ +SV_Physics + +================ +*/ +void SV_Physics (void) +{ + int i; + edict_t *ent; + +// let the progs know that a new frame has started + pr_global_struct->self = EDICT_TO_PROG(sv.edicts); + pr_global_struct->other = EDICT_TO_PROG(sv.edicts); + pr_global_struct->time = sv.time; + PR_ExecuteProgram (pr_global_struct->StartFrame); + +//SV_CheckAllEnts (); + +// +// treat each object in turn +// + ent = sv.edicts; + for (i=0 ; ifree) + continue; + + if (pr_global_struct->force_retouch) + { + SV_LinkEdict (ent, true); // force retouch even for stationary + } + + if (i > 0 && i <= svs.maxclients) + SV_Physics_Client (ent, i); + else if (ent->v.movetype == MOVETYPE_PUSH) + SV_Physics_Pusher (ent); + else if (ent->v.movetype == MOVETYPE_NONE) + SV_Physics_None (ent); +#ifdef QUAKE2 + else if (ent->v.movetype == MOVETYPE_FOLLOW) + SV_Physics_Follow (ent); +#endif + else if (ent->v.movetype == MOVETYPE_NOCLIP) + SV_Physics_Noclip (ent); + else if (ent->v.movetype == MOVETYPE_STEP) + SV_Physics_Step (ent); + else if (ent->v.movetype == MOVETYPE_TOSS + || ent->v.movetype == MOVETYPE_BOUNCE +#ifdef QUAKE2 + || ent->v.movetype == MOVETYPE_BOUNCEMISSILE +#endif + || ent->v.movetype == MOVETYPE_FLY + || ent->v.movetype == MOVETYPE_FLYMISSILE) + SV_Physics_Toss (ent); + else + Sys_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype); + } + + if (pr_global_struct->force_retouch) + pr_global_struct->force_retouch--; + + sv.time += host_frametime; +} + + +#ifdef QUAKE2 +trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore) +{ + edict_t tempent, *tent; + trace_t trace; + vec3_t move; + vec3_t end; + double save_frametime; +// extern particle_t *active_particles, *free_particles; +// particle_t *p; + + + save_frametime = host_frametime; + host_frametime = 0.05; + + memcpy(&tempent, ent, sizeof(edict_t)); + tent = &tempent; + + while (1) + { + SV_CheckVelocity (tent); + SV_AddGravity (tent); + VectorMA (tent->v.angles, host_frametime, tent->v.avelocity, tent->v.angles); + VectorScale (tent->v.velocity, host_frametime, move); + VectorAdd (tent->v.origin, move, end); + trace = SV_Move (tent->v.origin, tent->v.mins, tent->v.maxs, end, MOVE_NORMAL, tent); + VectorCopy (trace.endpos, tent->v.origin); + +// p = free_particles; +// if (p) +// { +// free_particles = p->next; +// p->next = active_particles; +// active_particles = p; +// +// p->die = 256; +// p->color = 15; +// p->type = pt_static; +// VectorCopy (vec3_origin, p->vel); +// VectorCopy (tent->v.origin, p->org); +// } + + if (trace.ent) + if (trace.ent != ignore) + break; + } +// p->color = 224; + host_frametime = save_frametime; + return trace; +} +#endif diff --git a/r17/Revamped src/revamped_src/sv_user.c b/r17/Revamped src/revamped_src/sv_user.c new file mode 100755 index 00000000..8aa1f565 --- /dev/null +++ b/r17/Revamped src/revamped_src/sv_user.c @@ -0,0 +1,656 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// sv_user.c -- server code for moving users + +#include "quakedef.h" + +edict_t *sv_player; + +extern cvar_t sv_friction; +cvar_t sv_edgefriction = {"edgefriction", "2"}; +extern cvar_t sv_stopspeed; + +static vec3_t forward, right, up; + +vec3_t wishdir; +float wishspeed; + +// world +float *angles; +float *origin; +float *velocity; + +qboolean onground; + +usercmd_t cmd; + +cvar_t sv_idealpitchscale = {"sv_idealpitchscale","0.8"}; + + +/* +=============== +SV_SetIdealPitch +=============== +*/ +#define MAX_FORWARD 6 +void SV_SetIdealPitch (void) +{ + float angleval, sinval, cosval; + trace_t tr; + vec3_t top, bottom; + float z[MAX_FORWARD]; + int i, j; + int step, dir, steps; + + if (!((int)sv_player->v.flags & FL_ONGROUND)) + return; + + angleval = sv_player->v.angles[YAW] * M_PI*2 / 360; + sinval = sinf(angleval); + cosval = cosf(angleval); + + for (i=0 ; iv.origin[0] + cosval*(i+3)*12; + top[1] = sv_player->v.origin[1] + sinval*(i+3)*12; + top[2] = sv_player->v.origin[2] + sv_player->v.view_ofs[2]; + + bottom[0] = top[0]; + bottom[1] = top[1]; + bottom[2] = top[2] - 160; + + tr = SV_Move (top, vec3_origin, vec3_origin, bottom, 1, sv_player); + if (tr.allsolid) + return; // looking at a wall, leave ideal the way is was + + if (tr.fraction == 1) + return; // near a dropoff + + z[i] = top[2] + tr.fraction*(bottom[2]-top[2]); + } + + dir = 0; + steps = 0; + for (j=1 ; j -ON_EPSILON && step < ON_EPSILON) + continue; + + if (dir && ( step-dir > ON_EPSILON || step-dir < -ON_EPSILON ) ) + return; // mixed changes + + steps++; + dir = step; + } + + if (!dir) + { + sv_player->v.idealpitch = 0; + return; + } + + if (steps < 2) + return; + sv_player->v.idealpitch = -dir * sv_idealpitchscale.value; +} + + +/* +================== +SV_UserFriction + +================== +*/ +void SV_UserFriction (void) +{ + float *vel; + float speed, newspeed, control; + vec3_t start, stop; + float friction; + trace_t trace; + + vel = velocity; + + speed = sqrtf(vel[0]*vel[0] +vel[1]*vel[1]); + if (!speed) + return; + +// if the leading edge is over a dropoff, increase friction + start[0] = stop[0] = origin[0] + vel[0]/speed*16; + start[1] = stop[1] = origin[1] + vel[1]/speed*16; + start[2] = origin[2] + sv_player->v.mins[2]; + stop[2] = start[2] - 34; + + trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, sv_player); + + if (trace.fraction == 1.0) + friction = sv_friction.value*sv_edgefriction.value; + else + friction = sv_friction.value; + +// apply friction + control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed; + newspeed = speed - host_frametime*control*friction; + + if (newspeed < 0) + newspeed = 0; + newspeed /= speed; + + vel[0] = vel[0] * newspeed; + vel[1] = vel[1] * newspeed; + vel[2] = vel[2] * newspeed; +} + +/* +============== +SV_Accelerate +============== +*/ +cvar_t sv_maxspeed = {"sv_maxspeed", "320", false, true}; +cvar_t sv_accelerate = {"sv_accelerate", "10"}; +#if 0 +void SV_Accelerate (vec3_t wishvel) +{ + int i; + float addspeed, accelspeed; + vec3_t pushvec; + + if (wishspeed == 0) + return; + + VectorSubtract (wishvel, velocity, pushvec); + addspeed = VectorNormalize (pushvec); + + accelspeed = sv_accelerate.value*host_frametime*addspeed; + if (accelspeed > addspeed) + accelspeed = addspeed; + + for (i=0 ; i<3 ; i++) + velocity[i] += accelspeed*pushvec[i]; +} +#endif +void SV_Accelerate (void) +{ + int i; + float addspeed, accelspeed, currentspeed; + + currentspeed = DotProduct (velocity, wishdir); + addspeed = wishspeed - currentspeed; + if (addspeed <= 0) + return; + accelspeed = sv_accelerate.value*host_frametime*wishspeed; + if (accelspeed > addspeed) + accelspeed = addspeed; + + for (i=0 ; i<3 ; i++) + velocity[i] += accelspeed*wishdir[i]; +} + +void SV_AirAccelerate (vec3_t wishveloc) +{ + int i; + float addspeed, wishspd, accelspeed, currentspeed; + + wishspd = VectorNormalize (wishveloc); + if (wishspd > 30) + wishspd = 30; + currentspeed = DotProduct (velocity, wishveloc); + addspeed = wishspd - currentspeed; + if (addspeed <= 0) + return; +// accelspeed = sv_accelerate.value * host_frametime; + accelspeed = sv_accelerate.value*wishspeed * host_frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + for (i=0 ; i<3 ; i++) + velocity[i] += accelspeed*wishveloc[i]; +} + + +void DropPunchAngle (void) +{ + float len; + + len = VectorNormalize (sv_player->v.punchangle); + + if(kurok) + len -= 25*host_frametime; + else + len -= 10*host_frametime; + + if (len < 0) + len = 0; + VectorScale (sv_player->v.punchangle, len, sv_player->v.punchangle); +} + +/* +=================== +SV_WaterMove + +=================== +*/ +void SV_WaterMove (void) +{ + int i; + vec3_t wishvel; + float speed, newspeed, wishspeed, addspeed, accelspeed; + +// +// user intentions +// + AngleVectors (sv_player->v.v_angle, forward, right, up); + + for (i=0 ; i<3 ; i++) + wishvel[i] = forward[i]*cmd.forwardmove + right[i]*cmd.sidemove; + + if (!cmd.forwardmove && !cmd.sidemove && !cmd.upmove) + { + if (!kurok) + wishvel[2] -= 60; // drift towards bottom + } + else + wishvel[2] += cmd.upmove; + + wishspeed = Length(wishvel); + if (wishspeed > sv_maxspeed.value) + { + VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel); + wishspeed = sv_maxspeed.value; + } + wishspeed *= 0.7; + +// +// water friction +// + speed = Length (velocity); + if (speed) + { + newspeed = speed - host_frametime * speed * sv_friction.value; + if (newspeed < 0) + newspeed = 0; + VectorScale (velocity, newspeed/speed, velocity); + } + else + newspeed = 0; + +// +// water acceleration +// + if (!wishspeed) + return; + + addspeed = wishspeed - newspeed; + if (addspeed <= 0) + return; + + VectorNormalize (wishvel); + accelspeed = sv_accelerate.value * wishspeed * host_frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + for (i=0 ; i<3 ; i++) + velocity[i] += accelspeed * wishvel[i]; +} + +void SV_WaterJump (void) +{ + if (sv.time > sv_player->v.teleport_time + || !sv_player->v.waterlevel) + { + sv_player->v.flags = (int)sv_player->v.flags & ~FL_WATERJUMP; + sv_player->v.teleport_time = 0; + } + sv_player->v.velocity[0] = sv_player->v.movedir[0]; + sv_player->v.velocity[1] = sv_player->v.movedir[1]; +} + + +/* +=================== +SV_AirMove + +=================== +*/ +void SV_AirMove (void) +{ + int i; + vec3_t wishvel; + float fmove, smove; + + AngleVectors (sv_player->v.angles, forward, right, up); + + fmove = cmd.forwardmove; + smove = cmd.sidemove; + +// hack to not let you back into teleporter + if (sv.time < sv_player->v.teleport_time && fmove < 0) + fmove = 0; + + for (i=0 ; i<3 ; i++) + wishvel[i] = forward[i]*fmove + right[i]*smove; + + if ( (int)sv_player->v.movetype != MOVETYPE_WALK) + wishvel[2] = cmd.upmove; + else + wishvel[2] = 0; + + VectorCopy (wishvel, wishdir); + wishspeed = VectorNormalize(wishdir); + if (wishspeed > sv_maxspeed.value) + { + VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel); + wishspeed = sv_maxspeed.value; + } + + if ( sv_player->v.movetype == MOVETYPE_NOCLIP) + { // noclip + VectorCopy (wishvel, velocity); + } + else if ( onground ) + { + SV_UserFriction (); + SV_Accelerate (); + } + else + { // not on ground, so little effect on velocity + SV_AirAccelerate (wishvel); + } +} + +/* +=================== +SV_ClientThink + +the move fields specify an intended velocity in pix/sec +the angle fields specify an exact angular motion in degrees +=================== +*/ +void SV_ClientThink (void) +{ + vec3_t v_angle; + + if (sv_player->v.movetype == MOVETYPE_NONE) + return; + + onground = (int)sv_player->v.flags & FL_ONGROUND; + + origin = sv_player->v.origin; + velocity = sv_player->v.velocity; + + DropPunchAngle (); + +// +// if dead, behave differently +// + if (sv_player->v.health <= 0) + return; + +// +// angles +// show 1/3 the pitch angle and all the roll angle + cmd = host_client->cmd; + angles = sv_player->v.angles; + + VectorAdd (sv_player->v.v_angle, sv_player->v.punchangle, v_angle); + angles[ROLL] = V_CalcRoll (sv_player->v.angles, sv_player->v.velocity)*4; + if (!sv_player->v.fixangle) + { + angles[PITCH] = -v_angle[PITCH]/3; + angles[YAW] = v_angle[YAW]; + } + + if ( (int)sv_player->v.flags & FL_WATERJUMP ) + { + SV_WaterJump (); + return; + } +// +// walk +// + if ( (sv_player->v.waterlevel >= 2) + && (sv_player->v.movetype != MOVETYPE_NOCLIP) ) + { + SV_WaterMove (); + return; + } + + SV_AirMove (); +} + + +/* +=================== +SV_ReadClientMove +=================== +*/ +void SV_ReadClientMove (usercmd_t *move) +{ + int i; + vec3_t angle; + int bits; + +// read ping time + host_client->ping_times[host_client->num_pings%NUM_PING_TIMES] + = sv.time - MSG_ReadFloat (); + host_client->num_pings++; + +// read current angles +// JPG - precise aim for ProQuake!! + for (i=0 ; i<3 ; i++) + angle[i] = MSG_ReadPreciseAngle (); + +// read current angles +// for (i=0 ; i<3 ; i++) +// angle[i] = MSG_ReadAngle (); + + VectorCopy (angle, host_client->edict->v.v_angle); + +// read movement + move->forwardmove = MSG_ReadShort (); + move->sidemove = MSG_ReadShort (); + move->upmove = MSG_ReadShort (); + +// read buttons + bits = MSG_ReadByte (); + host_client->edict->v.button0 = bits & 1; + host_client->edict->v.button2 = (bits & 2)>>1; + + i = MSG_ReadByte (); + if (i) + host_client->edict->v.impulse = i; + +#ifdef QUAKE2 +// read light level + host_client->edict->v.light_level = MSG_ReadByte (); +#endif +} + +/* +=================== +SV_ReadClientMessage + +Returns false if the client should be killed +=================== +*/ +qboolean SV_ReadClientMessage (void) +{ + int ret; + int cmd; + char *s; + + do + { +nextmsg: + ret = NET_GetMessage (host_client->netconnection); + if (ret == -1) + { + Sys_Printf ("SV_ReadClientMessage: NET_GetMessage failed\n"); + return false; + } + if (!ret) + return true; + + MSG_BeginReading (); + + while (1) + { + if (!host_client->active) + return false; // a command caused an error + + if (msg_badread) + { + Sys_Printf ("SV_ReadClientMessage: badread\n"); + return false; + } + + cmd = MSG_ReadChar (); + + switch (cmd) + { + case -1: + goto nextmsg; // end of message + + default: + Sys_Printf ("SV_ReadClientMessage: unknown command char\n"); + return false; + + case clc_nop: +// Sys_Printf ("clc_nop\n"); + break; + + case clc_stringcmd: + s = MSG_ReadString (); + if (host_client->privileged) + ret = 2; + else + ret = 0; + if (Q_strncasecmp(s, "status", 6) == 0) + ret = 1; + else if (Q_strncasecmp(s, "god", 3) == 0) + ret = 1; + else if (Q_strncasecmp(s, "notarget", 8) == 0) + ret = 1; + else if (Q_strncasecmp(s, "fly", 3) == 0) + ret = 1; + else if (Q_strncasecmp(s, "name", 4) == 0) + ret = 1; + else if (Q_strncasecmp(s, "noclip", 6) == 0) + ret = 1; + else if (Q_strncasecmp(s, "say", 3) == 0) + ret = 1; + else if (Q_strncasecmp(s, "say_team", 8) == 0) + ret = 1; + else if (Q_strncasecmp(s, "tell", 4) == 0) + ret = 1; + else if (Q_strncasecmp(s, "color", 5) == 0) + ret = 1; + else if (Q_strncasecmp(s, "kill", 4) == 0) + ret = 1; + else if (Q_strncasecmp(s, "pause", 5) == 0) + ret = 1; + else if (Q_strncasecmp(s, "spawn", 5) == 0) + ret = 1; + else if (Q_strncasecmp(s, "begin", 5) == 0) + ret = 1; + else if (Q_strncasecmp(s, "prespawn", 8) == 0) + ret = 1; + else if (Q_strncasecmp(s, "kick", 4) == 0) + ret = 1; + else if (Q_strncasecmp(s, "ping", 4) == 0) + ret = 1; + else if (Q_strncasecmp(s, "give", 4) == 0) + ret = 1; + else if (Q_strncasecmp(s, "ban", 3) == 0) + ret = 1; + if (ret == 2) + Cbuf_InsertText (s); + else if (ret == 1) + Cmd_ExecuteString (s, src_client); + else + Con_DPrintf("%s tried to %s\n", host_client->name, s); + break; + + case clc_disconnect: +// Sys_Printf ("SV_ReadClientMessage: client disconnected\n"); + return false; + + case clc_move: + SV_ReadClientMove (&host_client->cmd); + break; + } + } + } while (ret == 1); + + return true; +} + +extern qboolean bmg_type_changed; +/* +================== +SV_RunClients +================== +*/ +void SV_RunClients (void) +{ + int i; + + for (i=0, host_client = svs.clients ; iactive) + continue; + + sv_player = host_client->edict; + + if (!SV_ReadClientMessage ()) + { + SV_DropClient (false); // client misbehaved... + continue; + } + + if (!host_client->spawned) + { + // clear client movement until a new packet is received + memset (&host_client->cmd, 0, sizeof(host_client->cmd)); + continue; + } + +// always pause in single player if in console or menus + if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) ) + { + SV_ClientThink (); + if(kurok) + { + Cvar_Set("bgmtype","cd"); + bmg_type_changed = true; + } + } + else + { + if(kurok) + { + Cvar_Set("bgmtype","none"); + bmg_type_changed = true; + } + } + } +} + diff --git a/r17/Revamped src/revamped_src/sys.h b/r17/Revamped src/revamped_src/sys.h new file mode 100755 index 00000000..6486a114 --- /dev/null +++ b/r17/Revamped src/revamped_src/sys.h @@ -0,0 +1,71 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// sys.h -- non-portable functions + +// +// file IO +// + +// returns the file size +// return -1 if file is not present +// the file should be in BINARY mode for stupid OSs that care +int Sys_FileOpenRead (char *path, int *hndl); + +int Sys_FileOpenWrite (char *path); +void Sys_FileClose (int handle); +void Sys_FileSeek (int handle, int position); +int Sys_FileRead (int handle, void *dest, int count); +int Sys_FileWrite (int handle, void *data, int count); +int Sys_FileTime (char *path); +void Sys_mkdir (char *path); + +// +// memory protection +// +void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length); + +// +// system IO +// +void Sys_DebugLog(char *file, char *fmt, ...); + +void Sys_Error (char *error, ...); +// an error will cause the entire program to exit + +void Sys_Printf (char *fmt, ...); +// send text to the console + +void Sys_Quit (void); + +double Sys_FloatTime (void); + +char *Sys_ConsoleInput (void); + +void Sys_Sleep (void); +// called to yield for a little bit so as +// not to hog cpu when paused or debugging + +void Sys_SendKeyEvents (void); +// Perform Key_Event () callbacks until the input que is empty + +void Sys_LowFPPrecision (void); +void Sys_HighFPPrecision (void); +void Sys_SetFPCW (void); + diff --git a/r17/Revamped src/revamped_src/vid.h b/r17/Revamped src/revamped_src/vid.h new file mode 100755 index 00000000..dedf7dec --- /dev/null +++ b/r17/Revamped src/revamped_src/vid.h @@ -0,0 +1,85 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// vid.h -- video driver defs + +#define VID_CBITS 6 +#define VID_GRADES (1 << VID_CBITS) + +// a pixel can be one, two, or four bytes +typedef byte pixel_t; + +typedef struct vrect_s +{ + int x,y,width,height; + struct vrect_s *pnext; +} vrect_t; + +typedef struct +{ + pixel_t *buffer; // invisible buffer + pixel_t *colormap; // 256 * VID_GRADES size + unsigned short *colormap16; // 256 * VID_GRADES size + int fullbright; // index of first fullbright color + unsigned rowbytes; // may be > width if displayed in a window + unsigned width; + unsigned height; + float aspect; // width / height -- < 0 is taller than wide + int numpages; + int recalc_refdef; // if true, recalc vid-based stuff + pixel_t *conbuffer; + int conrowbytes; + unsigned conwidth; + unsigned conheight; + int maxwarpwidth; + int maxwarpheight; + pixel_t *direct; // direct drawing to framebuffer, if not + // NULL +} viddef_t; + +extern viddef_t vid; // global video state +extern unsigned short d_8to16table[256]; +extern unsigned d_8to24table[256]; +extern void (*vid_menudrawfn)(void); +extern void (*vid_menukeyfn)(int key); + +void VID_SetPalette (unsigned char *palette); +// called at startup and after any gamma correction + +void VID_ShiftPalette (unsigned char *palette); +// called for bonus and pain flashes, and for underwater color changes + +void VID_Init (unsigned char *palette); +// Called at startup to set up translation tables, takes 256 8 bit RGB values +// the palette data will go away after the call, so it must be copied off if +// the video driver will need it again + +void VID_Shutdown (void); +// Called at shutdown + +void VID_Update (vrect_t *rects); +// flushes the given rectangles from the view buffer to the screen + +int VID_SetMode (int modenum, unsigned char *palette); +// sets the mode; only used by the Quake engine for resetting to mode 0 (the +// base mode) on memory allocation failures + +void VID_HandlePause (qboolean pause); +// called only on Win32, when pause happens, so the mouse can be released + diff --git a/r17/Revamped src/revamped_src/view - Copy.c b/r17/Revamped src/revamped_src/view - Copy.c new file mode 100755 index 00000000..7a00a82a --- /dev/null +++ b/r17/Revamped src/revamped_src/view - Copy.c @@ -0,0 +1,1284 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// view.c -- player eye positioning + +#include "quakedef.h" +#include "r_local.h" +#include +/* + +The view is allowed to move slightly from it's true position for bobbing, +but if it exceeds 8 pixels linear distance (spherical, not box), the list of +entities sent from the server may not include everything in the pvs, especially +when crossing a water boudnary. + +*/ + +cvar_t lcd_x = {"lcd_x","0"}; +cvar_t lcd_yaw = {"lcd_yaw","0"}; + +cvar_t scr_ofsx = {"scr_ofsx","0", false}; +cvar_t scr_ofsy = {"scr_ofsy","0", false}; +cvar_t scr_ofsz = {"scr_ofsz","0", false}; + +cvar_t cl_rollspeed = {"cl_rollspeed", "200"}; +cvar_t cl_rollangle = {"cl_rollangle", "3.0"}; + +cvar_t cl_bob = {"cl_bob","0.02", true}; +cvar_t cl_bobcycle = {"cl_bobcycle","0.45", true}; +cvar_t cl_bobup = {"cl_bobup","0.5", true}; + +cvar_t cl_bobside = {"cl_bobside","0.02", true}; +cvar_t cl_bobsidecycle = {"cl_bobsidecycle","0.9", true}; +cvar_t cl_bobsideup = {"cl_bobsideup","0.5", true}; + +cvar_t v_kicktime = {"v_kicktime", "0.5", false}; +cvar_t v_kickroll = {"v_kickroll", "0.6", false}; +cvar_t v_kickpitch = {"v_kickpitch", "0.6", false}; + +cvar_t v_iyaw_cycle = {"v_iyaw_cycle", "6", true}; +cvar_t v_iroll_cycle = {"v_iroll_cycle", "6", true}; +cvar_t v_ipitch_cycle = {"v_ipitch_cycle", "12", true}; +cvar_t v_iyaw_level = {"v_iyaw_level", "0.15", true}; +cvar_t v_iroll_level = {"v_iroll_level", "0.15", true}; +cvar_t v_ipitch_level = {"v_ipitch_level", "0.15", true}; + +cvar_t v_idlescale = {"v_idlescale", "0.1", true}; + +cvar_t crosshair = {"crosshair", "2", true}; +cvar_t cl_crossx = {"cl_crossx", "0", false}; +cvar_t cl_crossy = {"cl_crossy", "0", false}; + +cvar_t cl_gunpitch = {"cl_gunpitch", "0", false}; + +cvar_t gl_cshiftpercent = {"gl_cshiftpercent", "100", false}; + +float v_dmg_time, v_dmg_roll, v_dmg_pitch; + +extern int in_forward, in_forward2, in_back; +extern cvar_t lookcenter; +/* +=============== +V_CalcRoll + +Used by view and sv_user +=============== +*/ +vec3_t forward, right, up; + +float V_CalcRoll (vec3_t angles, vec3_t velocity) +{ + float sign; + float side; + float value; + + AngleVectors (angles, forward, right, up); + side = DotProduct (velocity, right); + sign = side < 0 ? -1 : 1; + side = fabsf(side); + + value = cl_rollangle.value; + if (cl.inwater) + value *= 2; + + if (side < cl_rollspeed.value) + side = side * value / cl_rollspeed.value; + else + side = value; + + return side*sign; + +} + + +/* +=============== +V_CalcBob + +=============== +*/ +float V_CalcBob (void) +{ + float bob; + float cycle; + + cycle = cl.time - (int)(cl.time/cl_bobcycle.value)*cl_bobcycle.value; + cycle /= cl_bobcycle.value; + if (cycle < cl_bobup.value) + cycle = M_PI * cycle / cl_bobup.value; + else + cycle = M_PI + M_PI*(cycle-cl_bobup.value)/(1.0 - cl_bobup.value); + +// bob is proportional to velocity in the xy plane +// (don't count Z, or jumping messes it up) + + bob = sqrtf(cl.velocity[0]*cl.velocity[0] + cl.velocity[1]*cl.velocity[1]) * cl_bob.value; +// Con_Printf ("speed: %5.1f\n", Length(cl.velocity)); + bob = bob*0.3 + bob*0.7*sinf(cycle); + if (bob > 4) + bob = 4; + else if (bob < -7) + bob = -7; + return bob; + +} + +/* +=============== +V_CalcBobSide + +=============== +*/ +float V_CalcBobSide (void) +{ + float bobside; + float cycle; + + cycle = cl.time - (int)(cl.time/cl_bobsidecycle.value)*cl_bobsidecycle.value; + cycle /= cl_bobsidecycle.value; + if (cycle < cl_bobsideup.value) + cycle = M_PI * cycle / cl_bobsideup.value; + else + cycle = M_PI + M_PI*(cycle-cl_bobsideup.value)/(1.0 - cl_bobsideup.value); + +// bob is proportional to velocity in the xy plane +// (don't count Z, or jumping messes it up) + + bobside = sqrtf(cl.velocity[0]*cl.velocity[0] + cl.velocity[1]*cl.velocity[1]) * cl_bobside.value; +//Con_Printf ("speed: %5.1f\n", Length(cl.velocity)); + bobside = bobside*0.3 + bobside*0.7*sinf(cycle); + if (bobside > 4) + bobside = 4; + else if (bobside < -7) + bobside = -7; + return bobside; + +} + +/* +=============== +V_ZoomIN + +Kurok specific zoom code. +=============== +*/ +/* +float V_ZoomIN (void) +{ + +} +*/ + +//============================================================================= + + +cvar_t v_centermove = {"v_centermove", "1", true}; +cvar_t v_centerspeed = {"v_centerspeed","100", true}; + + +void V_StartPitchDrift (void) +{ +#if 1 + if (cl.laststop == cl.time) + { + return; // something else is keeping it from drifting + } +#endif + if (cl.nodrift || !cl.pitchvel) + { + cl.pitchvel = v_centerspeed.value; + cl.nodrift = false; + cl.driftmove = 0; + } +} + +void V_StopPitchDrift (void) +{ + cl.laststop = cl.time; + cl.nodrift = true; + cl.pitchvel = 0; +} + +/* +=============== +V_DriftPitch + +Moves the client pitch angle towards cl.idealpitch sent by the server. + +If the user is adjusting pitch manually, either with lookup/lookdown, +mlook and mouse, or klook and keyboard, pitch drifting is constantly stopped. + +Drifting is enabled when the center view key is hit, mlook is released and +lookspring is non 0, or when +=============== +*/ +void V_DriftPitch (void) +{ + float delta, move; + + if (noclip_anglehack || !cl.onground || cls.demoplayback || lookcenter.value) + { + cl.driftmove = 0; + cl.pitchvel = 0; + return; + } + +// don't count small mouse motion + if (cl.nodrift) + { + if ( fabsf(cl.cmd.forwardmove) < cl_forwardspeed.value) + cl.driftmove = 0; + else + cl.driftmove += host_frametime; + + if ( cl.driftmove > v_centermove.value) + { + V_StartPitchDrift (); + } + return; + } + + delta = cl.idealpitch - cl.viewangles[PITCH]; + + if (!delta) + { + cl.pitchvel = 0; + return; + } + + move = host_frametime * cl.pitchvel; + cl.pitchvel += host_frametime * v_centerspeed.value; + +//Con_Printf ("move: %f (%f)\n", move, host_frametime); + + if (delta > 0) + { + if (move > delta) + { + cl.pitchvel = 0; + move = delta; + } + cl.viewangles[PITCH] += move; + } + else if (delta < 0) + { + if (move > -delta) + { + cl.pitchvel = 0; + move = -delta; + } + cl.viewangles[PITCH] -= move; + } +} + + + + + +/* +============================================================================== + + PALETTE FLASHES + +============================================================================== +*/ + + +cshift_t cshift_empty = { {130,80,50}, 0 }; +cshift_t cshift_water = { {130,80,50}, 128 }; +cshift_t cshift_kwater = { {64,64,128}, 128 }; // Blue water for Kurok +cshift_t cshift_slime = { {0,25,5}, 150 }; +cshift_t cshift_lava = { {255,80,0}, 150 }; + +cvar_t v_gamma = {"gamma", "1", true}; + +byte gammatable[256]; // palette is sent through this + +#if defined(GLQUAKE) || defined(PSP_HARDWARE_VIDEO) +byte ramps[3][256]; +float v_blend[4]; // rgba 0.0 - 1.0 +#endif // GLQUAKE + +void BuildGammaTable (float g) +{ + int i, inf; + + if (g == 1.0) + { + for (i=0 ; i<256 ; i++) + gammatable[i] = i; + return; + } + + for (i=0 ; i<256 ; i++) + { + inf = 255 * powf ( (i+0.5f)/255.5f , g ) + 0.5; + if (inf < 0) + inf = 0; + if (inf > 255) + inf = 255; + gammatable[i] = inf; + } +} + +/* +================= +V_CheckGamma +================= +*/ +qboolean V_CheckGamma (void) +{ + static float oldgammavalue; + + if (v_gamma.value == oldgammavalue) + return false; + oldgammavalue = v_gamma.value; + + BuildGammaTable (v_gamma.value); + vid.recalc_refdef = 1; // force a surface cache flush + + return true; +} + + + +/* +=============== +V_ParseDamage +=============== +*/ +void V_ParseDamage (void) +{ + int armor, blood; + vec3_t from; + int i; + vec3_t forward, right, up; + entity_t *ent; + float side; + float count; + + armor = MSG_ReadByte (); + blood = MSG_ReadByte (); + for (i=0 ; i<3 ; i++) + from[i] = MSG_ReadCoord (); + + count = blood*0.5 + armor*0.5; + if (count < 10) + count = 10; + + cl.faceanimtime = cl.time + 0.2; // but sbar face into pain frame + + cl.cshifts[CSHIFT_DAMAGE].percent += 3*count; + if (cl.cshifts[CSHIFT_DAMAGE].percent < 0) + cl.cshifts[CSHIFT_DAMAGE].percent = 0; + if (cl.cshifts[CSHIFT_DAMAGE].percent > 150) + cl.cshifts[CSHIFT_DAMAGE].percent = 150; + + if (armor > blood) + { + if (kurok) // Flash blue for damage when wearing armor + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 100; //r + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100; //g + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 200; //b + } + else + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 200; //r + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100; //g + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 100; //b + } + } + else if (armor) + { + if (kurok) // Flash blue for damage when wearing armor + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 0; //r + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 0; //g + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 255; //b + } + else + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 220; //r + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 50; //g + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 50; //b + } + } + else + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 255; //r + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 0; //g + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 0; //b + } + +// +// calculate view angle kicks +// + ent = &cl_entities[cl.viewentity]; + + VectorSubtract (from, ent->origin, from); + VectorNormalize (from); + + AngleVectors (ent->angles, forward, right, up); + + side = DotProduct (from, right); + v_dmg_roll = count*side*v_kickroll.value; + + side = DotProduct (from, forward); + v_dmg_pitch = count*side*v_kickpitch.value; + + v_dmg_time = v_kicktime.value; +} + + +/* +================== +V_cshift_f +================== +*/ +void V_cshift_f (void) +{ + cshift_empty.destcolor[0] = atoi(Cmd_Argv(1)); + cshift_empty.destcolor[1] = atoi(Cmd_Argv(2)); + cshift_empty.destcolor[2] = atoi(Cmd_Argv(3)); + cshift_empty.percent = atoi(Cmd_Argv(4)); +} + + +/* +================== +V_BonusFlash_f + +When you run over an item, the server sends this command +================== +*/ +void V_BonusFlash_f (void) +{ + cl.cshifts[CSHIFT_BONUS].destcolor[0] = 128; + cl.cshifts[CSHIFT_BONUS].destcolor[1] = 128; + cl.cshifts[CSHIFT_BONUS].destcolor[2] = 128; + cl.cshifts[CSHIFT_BONUS].percent = 50; +} + +/* +============= +V_SetContentsColor + +Underwater, lava, etc each has a color shift +============= +*/ +void V_SetContentsColor (int contents) +{ + switch (contents) + { + case CONTENTS_EMPTY: + case CONTENTS_SOLID: + cl.cshifts[CSHIFT_CONTENTS] = cshift_empty; + break; + case CONTENTS_LAVA: + cl.cshifts[CSHIFT_CONTENTS] = cshift_lava; + break; + case CONTENTS_SLIME: + cl.cshifts[CSHIFT_CONTENTS] = cshift_slime; + break; + default: + if (kurok) + cl.cshifts[CSHIFT_CONTENTS] = cshift_kwater; + else + cl.cshifts[CSHIFT_CONTENTS] = cshift_water; + } +} + +/* +============= +V_CalcPowerupCshift +============= +*/ +void V_CalcPowerupCshift (void) +{ + if (cl.items & IT_QUAD) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 0; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 255; + cl.cshifts[CSHIFT_POWERUP].percent = 30; + } + else if (cl.items & IT_SUIT) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0; + cl.cshifts[CSHIFT_POWERUP].percent = 20; + } + else if (cl.items & IT_INVISIBILITY) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 100; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 100; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 100; + cl.cshifts[CSHIFT_POWERUP].percent = 50; + } + else if (cl.items & IT_INVULNERABILITY) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 255; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 255; + cl.cshifts[CSHIFT_POWERUP].percent = 30; + } + else + cl.cshifts[CSHIFT_POWERUP].percent = 0; +} + +/* +============= +V_CalcBlend +============= +*/ +#if defined(GLQUAKE) || defined(PSP_HARDWARE_VIDEO) +void V_CalcBlend (void) +{ + float r, g, b, a, a2; + int j; + + r = 0; + g = 0; + b = 0; + a = 0; + + for (j=0 ; j 1) + v_blend[3] = 1; + if (v_blend[3] < 0) + v_blend[3] = 0; + + Draw_FadeScreenColor (v_blend[0], v_blend[1], v_blend[2], v_blend[3]); +} +#endif + +/* +============= +V_UpdatePalette +============= +*/ +#if defined(GLQUAKE) || defined(PSP_HARDWARE_VIDEO) +void V_UpdatePalette (void) +{ + int i, j; + qboolean new; +// byte *basepal, *newpal; +// byte pal[768]; +// float r,g,b,a; +// int ir, ig, ib; +// qboolean force; + + V_CalcPowerupCshift (); + + new = false; + + for (i=0 ; i 255) + ir = 255; + if (ig > 255) + ig = 255; + if (ib > 255) + ib = 255; + + ramps[0][i] = gammatable[ir]; + ramps[1][i] = gammatable[ig]; + ramps[2][i] = gammatable[ib]; + } + + basepal = host_basepal; + newpal = pal; + + for (i=0 ; i<256 ; i++) + { + ir = basepal[0]; + ig = basepal[1]; + ib = basepal[2]; + basepal += 3; + + newpal[0] = ramps[0][ir]; + newpal[1] = ramps[1][ig]; + newpal[2] = ramps[2][ib]; + newpal += 3; + } + + VID_ShiftPalette (pal); + */ +} +#else // !GLQUAKE +void V_UpdatePalette (void) +{ + int i, j; + qboolean new; + byte *basepal, *newpal; + byte pal[768]; + int r,g,b; + qboolean force; + + V_CalcPowerupCshift (); + + new = false; + + for (i=0 ; i>8; + g += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[1]-g))>>8; + b += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[2]-b))>>8; + } + + newpal[0] = gammatable[r]; + newpal[1] = gammatable[g]; + newpal[2] = gammatable[b]; + newpal += 3; + } + + VID_ShiftPalette (pal); +} +#endif // !GLQUAKE + + +/* +============================================================================== + + VIEW RENDERING + +============================================================================== +*/ + +float angledelta (float a) +{ + a = anglemod(a); + if (a > 180) + a -= 360; + return a; +} + +/* +================== +CalcGunAngle +================== +*/ +void CalcGunAngle (void) +{ + float yaw, pitch, move; + static float oldyaw = 0; + static float oldpitch = 0; + + extern cvar_t in_freelook_analog; + extern cvar_t in_disable_analog; + extern cvar_t in_analog_strafe; + + extern cvar_t in_x_axis_adjust; + extern cvar_t in_y_axis_adjust; + + yaw = r_refdef.viewangles[YAW]; + pitch = -r_refdef.viewangles[PITCH]; + + yaw = angledelta(yaw - r_refdef.viewangles[YAW]) * 0.4; + if (yaw > 10) + yaw = 10; + if (yaw < -10) + yaw = -10; + pitch = angledelta(-pitch - r_refdef.viewangles[PITCH]) * 0.4; + if (pitch > 10) + pitch = 10; + if (pitch < -10) + pitch = -10; + move = host_frametime*20; + if (yaw > oldyaw) + { + if (oldyaw + move < yaw) + yaw = oldyaw + move; + } + else + { + if (oldyaw - move > yaw) + yaw = oldyaw - move; + } + + if (pitch > oldpitch) + { + if (oldpitch + move < pitch) + pitch = oldpitch + move; + } + else + { + if (oldpitch - move > pitch) + pitch = oldpitch - move; + } + + oldyaw = yaw; + oldpitch = pitch; + + cl.viewent.angles[YAW] = r_refdef.viewangles[YAW] + yaw; + cl.viewent.angles[PITCH] = - (r_refdef.viewangles[PITCH] + pitch); + + // Read the pad state. + SceCtrlData pad; + sceCtrlPeekBufferPositive(&pad, 1); + + extern cvar_t scr_fov; + + if (scr_fov.value == 90) + { + cl.viewent.angles[ROLL] -= sin(cl.time*3); + if (!in_disable_analog.value) + { + if (in_freelook_analog.value) + { + if (m_pitch.value < 0) + cl.viewent.angles[PITCH] -= sin(cl.time*1.8) - ((pad.Ly - 128) * in_y_axis_adjust.value * 0.015); + else + cl.viewent.angles[PITCH] -= sin(cl.time*1.8) + ((pad.Ly - 128) * in_y_axis_adjust.value * 0.015); + cl.viewent.angles[YAW] -= sin(cl.time*1.5) + ((pad.Lx - 128) * in_x_axis_adjust.value * 0.015); + } + else + { + if (!in_analog_strafe.value) + cl.viewent.angles[YAW] -= sin(cl.time*1.5) + ((pad.Lx - 128) * in_x_axis_adjust.value * 0.015); + } + } + + if (cl_gunpitch.value) + cl.viewent.angles[PITCH] -= cl_gunpitch.value; + + } + else + { + cl.viewent.angles[ROLL] -= v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value; + cl.viewent.angles[PITCH] -= v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value; + cl.viewent.angles[YAW] -= v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value; + } + +} + +/* +============== +V_BoundOffsets +============== +*/ +void V_BoundOffsets (void) +{ + entity_t *ent; + + ent = &cl_entities[cl.viewentity]; + +// absolutely bound refresh reletive to entity clipping hull +// so the view can never be inside a solid wall + + if (r_refdef.vieworg[0] < ent->origin[0] - 14) + r_refdef.vieworg[0] = ent->origin[0] - 14; + else if (r_refdef.vieworg[0] > ent->origin[0] + 14) + r_refdef.vieworg[0] = ent->origin[0] + 14; + if (r_refdef.vieworg[1] < ent->origin[1] - 14) + r_refdef.vieworg[1] = ent->origin[1] - 14; + else if (r_refdef.vieworg[1] > ent->origin[1] + 14) + r_refdef.vieworg[1] = ent->origin[1] + 14; + if (r_refdef.vieworg[2] < ent->origin[2] - 22) + r_refdef.vieworg[2] = ent->origin[2] - 22; + else if (r_refdef.vieworg[2] > ent->origin[2] + 30) + r_refdef.vieworg[2] = ent->origin[2] + 30; +} + +/* +============== +V_AddIdle + +Idle swaying +============== +*/ +void V_AddIdle (void) +{ + /* + if (kurok) + { + double xyspeed; + float bspeed; + + xyspeed = sqrt(cl.velocity[0]*cl.velocity[0] + cl.velocity[1]*cl.velocity[1]); + bspeed = xyspeed * 0.15f; + + r_refdef.viewangles[ROLL] += v_idlescale.value * sinf(cl.time*v_iroll_cycle.value) * (v_iroll_level.value * bspeed); + r_refdef.viewangles[PITCH] += v_idlescale.value * sinf(cl.time*v_ipitch_cycle.value) * (v_ipitch_level.value * bspeed); + r_refdef.viewangles[YAW] += v_idlescale.value * sinf(cl.time*v_iyaw_cycle.value) * (v_iyaw_level.value * bspeed); + + r_refdef.viewangles[ROLL] += (v_idlescale.value * 3 ) * sinf(cl.time*v_iroll_cycle.value * 0.25 ) * v_iroll_level.value; + r_refdef.viewangles[PITCH] += (v_idlescale.value * 3 ) * sinf(cl.time*v_ipitch_cycle.value * 0.25 ) * v_ipitch_level.value; + r_refdef.viewangles[YAW] += (v_idlescale.value * 3 ) * sinf(cl.time*v_iyaw_cycle.value * 0.25 ) * v_iyaw_level.value; + } + else + { + */ + r_refdef.viewangles[ROLL] += v_idlescale.value * sinf(cl.time*v_iroll_cycle.value) * v_iroll_level.value; + r_refdef.viewangles[PITCH] += v_idlescale.value * sinf(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value; + r_refdef.viewangles[YAW] += v_idlescale.value * sinf(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value; + //} +} + + +/* +============== +V_CalcViewRoll + +Roll is induced by movement and damage +============== +*/ +void V_CalcViewRoll (void) +{ + float side; + + side = V_CalcRoll (cl_entities[cl.viewentity].angles, cl.velocity); + r_refdef.viewangles[ROLL] += side; + + if (v_dmg_time > 0) + { + r_refdef.viewangles[ROLL] += v_dmg_time/v_kicktime.value*v_dmg_roll; + r_refdef.viewangles[PITCH] += v_dmg_time/v_kicktime.value*v_dmg_pitch; + v_dmg_time -= host_frametime; + } + + if (cl.stats[STAT_HEALTH] <= 0) + { + r_refdef.viewangles[ROLL] = 80; // dead view angle + return; + } + +} + + +/* +================== +V_CalcIntermissionRefdef + +================== +*/ +void V_CalcIntermissionRefdef (void) +{ + entity_t *ent, *view; + float old; + +// ent is the player model (visible when out of body) + ent = &cl_entities[cl.viewentity]; +// view is the weapon model (only visible from inside body) + view = &cl.viewent; + + VectorCopy (ent->origin, r_refdef.vieworg); + VectorCopy (ent->angles, r_refdef.viewangles); + view->model = NULL; + +// allways idle in intermission + if (!kurok) + { + old = v_idlescale.value; + v_idlescale.value = 1; + V_AddIdle (); + v_idlescale.value = old; + } +} + +/* +================== +V_CalcRefdef + +================== +*/ +void V_CalcRefdef (void) +{ + entity_t *ent, *view; + int i; + vec3_t forward, right, up; + vec3_t angles; + float bob, bobside; + static float oldz = 0; + + V_DriftPitch (); + +// ent is the player model (visible when out of body) + ent = &cl_entities[cl.viewentity]; +// view is the weapon model (only visible from inside body) + view = &cl.viewent; + + +// transform the view offset by the model's matrix to get the offset from +// model origin for the view + ent->angles[YAW] = cl.viewangles[YAW]; // the model should face + // the view dir + ent->angles[PITCH] = -cl.viewangles[PITCH]; // the model should face + // the view dir + if (chase_active.value) + { + bob = 0; + bobside = 0; + } + else + { + bob = V_CalcBob (); + bobside = V_CalcBobSide (); + } + +// refresh position + VectorCopy (ent->origin, r_refdef.vieworg); + r_refdef.vieworg[2] += cl.viewheight + bob; + +// never let it sit exactly on a node line, because a water plane can +// dissapear when viewed with the eye exactly on it. +// the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis + r_refdef.vieworg[0] += 1.0/32; + r_refdef.vieworg[1] += 1.0/32; + r_refdef.vieworg[2] += 1.0/32; + + VectorCopy (cl.viewangles, r_refdef.viewangles); + + if (!chase_active.value) + { + V_CalcViewRoll (); + V_AddIdle (); + } + +// offsets + angles[PITCH] = -ent->angles[PITCH]; // because entity pitches are + // actually backward + angles[YAW] = ent->angles[YAW]; + angles[ROLL] = ent->angles[ROLL]; + + AngleVectors (angles, forward, right, up); + + for (i=0 ; i<3 ; i++) + r_refdef.vieworg[i] += scr_ofsx.value*forward[i] + + scr_ofsy.value*right[i] + + scr_ofsz.value*up[i]; + + + V_BoundOffsets (); + +// set up gun position + VectorCopy (cl.viewangles, view->angles); + + CalcGunAngle (); + + VectorCopy (ent->origin, view->origin); + view->origin[2] += cl.viewheight; + + for (i=0 ; i<3 ; i++) + { +// view->origin[i] += forward[i]*bob*0.2; + view->origin[i] += right[i]*bobside*0.2; + view->origin[i] += up[i]*bob*0.2; + } + view->origin[2] += bob; + + if(!kurok) + { + +// fudge position around to keep amount of weapon visible +// roughly equal with different FOV + +#if 0 + if (cl.model_precache[cl.stats[STAT_WEAPON]] && strcmp (cl.model_precache[cl.stats[STAT_WEAPON]]->name, "progs/v_shot2.mdl")) +#endif + if (scr_viewsize.value == 130) + view->origin[2] += 2.25; + else if (scr_viewsize.value == 120) + view->origin[2] += 2.25; + else if (scr_viewsize.value == 110) + view->origin[2] += 2.5; + else if (scr_viewsize.value == 100) + view->origin[2] += 3; + else if (scr_viewsize.value == 90) + view->origin[2] += 2.5; + else if (scr_viewsize.value <= 80) + view->origin[2] += 2; + } + + view->model = cl.model_precache[cl.stats[STAT_WEAPON]]; + view->frame = cl.stats[STAT_WEAPONFRAME]; + view->colormap = vid.colormap; + +// set up the refresh position + VectorAdd (r_refdef.viewangles, cl.punchangle, r_refdef.viewangles); + +// smooth out stair step ups +if (cl.onground && ent->origin[2] - oldz > 0) +{ + float steptime; + + steptime = cl.time - cl.oldtime; + if (steptime < 0) +//FIXME I_Error ("steptime < 0"); + steptime = 0; + + oldz += steptime * 80; + if (oldz > ent->origin[2]) + oldz = ent->origin[2]; + if (ent->origin[2] - oldz > 12) + oldz = ent->origin[2] - 12; + r_refdef.vieworg[2] += oldz - ent->origin[2]; + view->origin[2] += oldz - ent->origin[2]; +} +else + oldz = ent->origin[2]; + + if (chase_active.value) + Chase_Update (); +} + +/* +================== +V_RenderView + +The player's clipping box goes from (-16 -16 -24) to (16 16 32) from +the entity origin, so any view position inside that will be valid +================== +*/ +extern vrect_t scr_vrect; + +void V_RenderView (void) +{ + if (con_forcedup) + return; + + if (!kurok) + { + // don't allow cheats in multiplayer + if (cl.maxclients > 1) + { + Cvar_Set ("scr_ofsx", "0"); + Cvar_Set ("scr_ofsy", "0"); + Cvar_Set ("scr_ofsz", "0"); + } + } + + if (cl.intermission) + { // intermission / finale rendering + V_CalcIntermissionRefdef (); + } + else + { + if (!cl.paused /* && (sv.maxclients > 1 || key_dest == key_game) */ ) + V_CalcRefdef (); + } + + R_PushDlights (); + + if (lcd_x.value) + { + // + // render two interleaved views + // + int i; + + vid.rowbytes <<= 1; + vid.aspect *= 0.5; + + r_refdef.viewangles[YAW] -= lcd_yaw.value; + for (i=0 ; i<3 ; i++) + r_refdef.vieworg[i] -= right[i]*lcd_x.value; + R_RenderView (); + + vid.buffer += vid.rowbytes>>1; + + R_PushDlights (); + + r_refdef.viewangles[YAW] += lcd_yaw.value*2; + for (i=0 ; i<3 ; i++) + r_refdef.vieworg[i] += 2*right[i]*lcd_x.value; + R_RenderView (); + + vid.buffer -= vid.rowbytes>>1; + + r_refdef.vrect.height <<= 1; + + vid.rowbytes >>= 1; + vid.aspect *= 2; + } + else + { + R_RenderView (); + } + +#if !defined(GLQUAKE) && !defined(PSP_HARDWARE_VIDEO) + if (crosshair.value) + Draw_Crosshair(); +// Draw_Character (scr_vrect.x + scr_vrect.width/2 + cl_crossx.value, scr_vrect.y + scr_vrect.height/2 + cl_crossy.value, '+'); +#endif + +} + +//============================================================================ + +/* +============= +V_Init +============= +*/ +void V_Init (void) +{ + Cmd_AddCommand ("v_cshift", V_cshift_f); + Cmd_AddCommand ("bf", V_BonusFlash_f); + Cmd_AddCommand ("centerview", V_StartPitchDrift); + + Cvar_RegisterVariable (&lcd_x); + Cvar_RegisterVariable (&lcd_yaw); + + Cvar_RegisterVariable (&v_centermove); + Cvar_RegisterVariable (&v_centerspeed); + + Cvar_RegisterVariable (&v_iyaw_cycle); + Cvar_RegisterVariable (&v_iroll_cycle); + Cvar_RegisterVariable (&v_ipitch_cycle); + Cvar_RegisterVariable (&v_iyaw_level); + Cvar_RegisterVariable (&v_iroll_level); + Cvar_RegisterVariable (&v_ipitch_level); + + Cvar_RegisterVariable (&v_idlescale); + Cvar_RegisterVariable (&crosshair); + Cvar_RegisterVariable (&cl_crossx); + Cvar_RegisterVariable (&cl_crossy); + Cvar_RegisterVariable (&gl_cshiftpercent); + + Cvar_RegisterVariable (&scr_ofsx); + Cvar_RegisterVariable (&scr_ofsy); + Cvar_RegisterVariable (&scr_ofsz); + Cvar_RegisterVariable (&cl_rollspeed); + Cvar_RegisterVariable (&cl_rollangle); + + Cvar_RegisterVariable (&cl_bob); + Cvar_RegisterVariable (&cl_bobcycle); + Cvar_RegisterVariable (&cl_bobup); + + Cvar_RegisterVariable (&cl_bobside); + Cvar_RegisterVariable (&cl_bobsidecycle); + Cvar_RegisterVariable (&cl_bobsideup); + + Cvar_RegisterVariable (&cl_gunpitch); + + Cvar_RegisterVariable (&v_kicktime); + Cvar_RegisterVariable (&v_kickroll); + Cvar_RegisterVariable (&v_kickpitch); + + BuildGammaTable (1.0); // no gamma yet + Cvar_RegisterVariable (&v_gamma); +} + + diff --git a/r17/Revamped src/revamped_src/view.c b/r17/Revamped src/revamped_src/view.c new file mode 100755 index 00000000..7a7da4c3 --- /dev/null +++ b/r17/Revamped src/revamped_src/view.c @@ -0,0 +1,1372 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// view.c -- player eye positioning + +#include "quakedef.h" +#include "r_local.h" +#include +/* + +The view is allowed to move slightly from it's true position for bobbing, +but if it exceeds 8 pixels linear distance (spherical, not box), the list of +entities sent from the server may not include everything in the pvs, especially +when crossing a water boudnary. + +*/ + +cvar_t lcd_x = {"lcd_x","0"}; +cvar_t lcd_yaw = {"lcd_yaw","0"}; + +cvar_t scr_ofsx = {"scr_ofsx","0", false}; +cvar_t scr_ofsy = {"scr_ofsy","0", false}; +cvar_t scr_ofsz = {"scr_ofsz","0", false}; + +cvar_t cl_rollspeed = {"cl_rollspeed", "200"}; +cvar_t cl_rollangle = {"cl_rollangle", "3.0"}; + +cvar_t cl_bob = {"cl_bob","0.02", true}; +cvar_t cl_bobcycle = {"cl_bobcycle","0.45", true}; +cvar_t cl_bobup = {"cl_bobup","0.5", true}; + +cvar_t cl_bobside = {"cl_bobside","0.02", true}; +cvar_t cl_bobsidecycle = {"cl_bobsidecycle","0.9", true}; +cvar_t cl_bobsideup = {"cl_bobsideup","0.5", true}; + +cvar_t v_kicktime = {"v_kicktime", "0.5", false}; +cvar_t v_kickroll = {"v_kickroll", "0.6", false}; +cvar_t v_kickpitch = {"v_kickpitch", "0.6", false}; + +cvar_t v_iyaw_cycle = {"v_iyaw_cycle", "6", true}; +cvar_t v_iroll_cycle = {"v_iroll_cycle", "6", true}; +cvar_t v_ipitch_cycle = {"v_ipitch_cycle", "12", true}; +cvar_t v_iyaw_level = {"v_iyaw_level", "0.15", true}; +cvar_t v_iroll_level = {"v_iroll_level", "0.15", true}; +cvar_t v_ipitch_level = {"v_ipitch_level", "0.15", true}; + +cvar_t v_idlescale = {"v_idlescale", "0.1", true}; + +cvar_t crosshair = {"crosshair", "2", true}; +cvar_t cl_crossx = {"cl_crossx", "0", false}; +cvar_t cl_crossy = {"cl_crossy", "0", false}; + +cvar_t cl_gunpitch = {"cl_gunpitch", "0", false}; + +cvar_t gl_cshiftpercent = {"gl_cshiftpercent", "100", false}; + +float v_dmg_time, v_dmg_roll, v_dmg_pitch; + +extern int in_forward, in_forward2, in_back; +extern cvar_t lookcenter; +/* +=============== +V_CalcRoll + +Used by view and sv_user +=============== +*/ +vec3_t forward, right, up; + +float V_CalcRoll (vec3_t angles, vec3_t velocity) +{ + float sign; + float side; + float value; + + AngleVectors (angles, forward, right, up); + side = DotProduct (velocity, right); + sign = side < 0 ? -1 : 1; + side = fabsf(side); + + value = cl_rollangle.value; + if (cl.inwater) + value *= 2; + + if (side < cl_rollspeed.value) + side = side * value / cl_rollspeed.value; + else + side = value; + + return side*sign; + +} + + +/* +=============== +V_CalcBob + +=============== +*/ +float V_CalcBob (void) +{ + float bob; + float cycle; + + cycle = cl.time - (int)(cl.time/cl_bobcycle.value)*cl_bobcycle.value; + cycle /= cl_bobcycle.value; + if (cycle < cl_bobup.value) + cycle = M_PI * cycle / cl_bobup.value; + else + cycle = M_PI + M_PI*(cycle-cl_bobup.value)/(1.0 - cl_bobup.value); + +// bob is proportional to velocity in the xy plane +// (don't count Z, or jumping messes it up) + + bob = sqrtf(cl.velocity[0]*cl.velocity[0] + cl.velocity[1]*cl.velocity[1]) * cl_bob.value; +// Con_Printf ("speed: %5.1f\n", Length(cl.velocity)); + bob = bob*0.3 + bob*0.7*sinf(cycle); + if (bob > 4) + bob = 4; + else if (bob < -7) + bob = -7; + return bob; + +} + +/* +=============== +V_CalcBobSide + +=============== +*/ +float V_CalcBobSide (void) +{ + float bobside; + float cycle; + + cycle = cl.time - (int)(cl.time/cl_bobsidecycle.value)*cl_bobsidecycle.value; + cycle /= cl_bobsidecycle.value; + if (cycle < cl_bobsideup.value) + cycle = M_PI * cycle / cl_bobsideup.value; + else + cycle = M_PI + M_PI*(cycle-cl_bobsideup.value)/(1.0 - cl_bobsideup.value); + +// bob is proportional to velocity in the xy plane +// (don't count Z, or jumping messes it up) + + bobside = sqrtf(cl.velocity[0]*cl.velocity[0] + cl.velocity[1]*cl.velocity[1]) * cl_bobside.value; +//Con_Printf ("speed: %5.1f\n", Length(cl.velocity)); + bobside = bobside*0.3 + bobside*0.7*sinf(cycle); + if (bobside > 4) + bobside = 4; + else if (bobside < -7) + bobside = -7; + return bobside; + +} + +/* +=============== +V_ZoomIN + +Kurok specific zoom code. +=============== +*/ +/* +float V_ZoomIN (void) +{ + +} +*/ + +//============================================================================= + + +cvar_t v_centermove = {"v_centermove", "1", true}; +cvar_t v_centerspeed = {"v_centerspeed","100", true}; + + +void V_StartPitchDrift (void) +{ +#if 1 + if (cl.laststop == cl.time) + { + return; // something else is keeping it from drifting + } +#endif + if (cl.nodrift || !cl.pitchvel) + { + cl.pitchvel = v_centerspeed.value; + cl.nodrift = false; + cl.driftmove = 0; + } +} + +void V_StopPitchDrift (void) +{ + cl.laststop = cl.time; + cl.nodrift = true; + cl.pitchvel = 0; +} + +/* +=============== +V_DriftPitch + +Moves the client pitch angle towards cl.idealpitch sent by the server. + +If the user is adjusting pitch manually, either with lookup/lookdown, +mlook and mouse, or klook and keyboard, pitch drifting is constantly stopped. + +Drifting is enabled when the center view key is hit, mlook is released and +lookspring is non 0, or when +=============== +*/ +void V_DriftPitch (void) +{ + float delta, move; + + if (noclip_anglehack || !cl.onground || cls.demoplayback || lookcenter.value) + { + cl.driftmove = 0; + cl.pitchvel = 0; + return; + } + +// don't count small mouse motion + if (cl.nodrift) + { + if ( fabsf(cl.cmd.forwardmove) < cl_forwardspeed.value) + cl.driftmove = 0; + else + cl.driftmove += host_frametime; + + if ( cl.driftmove > v_centermove.value) + { + V_StartPitchDrift (); + } + return; + } + + delta = cl.idealpitch - cl.viewangles[PITCH]; + + if (!delta) + { + cl.pitchvel = 0; + return; + } + + move = host_frametime * cl.pitchvel; + cl.pitchvel += host_frametime * v_centerspeed.value; + +//Con_Printf ("move: %f (%f)\n", move, host_frametime); + + if (delta > 0) + { + if (move > delta) + { + cl.pitchvel = 0; + move = delta; + } + cl.viewangles[PITCH] += move; + } + else if (delta < 0) + { + if (move > -delta) + { + cl.pitchvel = 0; + move = -delta; + } + cl.viewangles[PITCH] -= move; + } +} + + + + + +/* +============================================================================== + + PALETTE FLASHES + +============================================================================== +*/ + + +cshift_t cshift_empty = { {130,80,50}, 0 }; +cshift_t cshift_water = { {130,80,50}, 128 }; +cshift_t cshift_kwater = { {64,64,128}, 128 }; // Blue water for Kurok +cshift_t cshift_slime = { {0,25,5}, 150 }; +cshift_t cshift_lava = { {255,80,0}, 150 }; + +cvar_t v_gamma = {"gamma", "1", true}; + +byte gammatable[256]; // palette is sent through this + +#if defined(GLQUAKE) || defined(PSP_HARDWARE_VIDEO) +byte ramps[3][256]; +float v_blend[4]; // rgba 0.0 - 1.0 +#endif // GLQUAKE + +void BuildGammaTable (float g) +{ + int i, inf; + + if (g == 1.0) + { + for (i=0 ; i<256 ; i++) + gammatable[i] = i; + return; + } + + for (i=0 ; i<256 ; i++) + { + inf = 255 * powf ( (i+0.5f)/255.5f , g ) + 0.5; + if (inf < 0) + inf = 0; + if (inf > 255) + inf = 255; + gammatable[i] = inf; + } +} + +/* +================= +V_CheckGamma +================= +*/ +qboolean V_CheckGamma (void) +{ + static float oldgammavalue; + + if (v_gamma.value == oldgammavalue) + return false; + oldgammavalue = v_gamma.value; + + BuildGammaTable (v_gamma.value); + vid.recalc_refdef = 1; // force a surface cache flush + + return true; +} + + + +/* +=============== +V_ParseDamage +=============== +*/ +void V_ParseDamage (void) +{ + int armor, blood; + vec3_t from; + int i; + vec3_t forward, right, up; + entity_t *ent; + float side; + float count; + + armor = MSG_ReadByte (); + blood = MSG_ReadByte (); + for (i=0 ; i<3 ; i++) + from[i] = MSG_ReadCoord (); + + count = blood*0.5 + armor*0.5; + if (count < 10) + count = 10; + + cl.faceanimtime = cl.time + 0.2; // but sbar face into pain frame + + cl.cshifts[CSHIFT_DAMAGE].percent += 3*count; + if (cl.cshifts[CSHIFT_DAMAGE].percent < 0) + cl.cshifts[CSHIFT_DAMAGE].percent = 0; + if (cl.cshifts[CSHIFT_DAMAGE].percent > 150) + cl.cshifts[CSHIFT_DAMAGE].percent = 150; + + if (armor > blood) + { + if (kurok) // Flash blue for damage when wearing armor + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 100; //r + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100; //g + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 200; //b + } + else + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 200; //r + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100; //g + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 100; //b + } + } + else if (armor) + { + if (kurok) // Flash blue for damage when wearing armor + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 0; //r + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 0; //g + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 255; //b + } + else + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 220; //r + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 50; //g + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 50; //b + } + } + else + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 255; //r + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 0; //g + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 0; //b + } + +// +// calculate view angle kicks +// + ent = &cl_entities[cl.viewentity]; + + VectorSubtract (from, ent->origin, from); + VectorNormalize (from); + + AngleVectors (ent->angles, forward, right, up); + + side = DotProduct (from, right); + v_dmg_roll = count*side*v_kickroll.value; + + side = DotProduct (from, forward); + v_dmg_pitch = count*side*v_kickpitch.value; + + v_dmg_time = v_kicktime.value; +} + + +/* +================== +V_cshift_f +================== +*/ +void V_cshift_f (void) +{ + cshift_empty.destcolor[0] = atoi(Cmd_Argv(1)); + cshift_empty.destcolor[1] = atoi(Cmd_Argv(2)); + cshift_empty.destcolor[2] = atoi(Cmd_Argv(3)); + cshift_empty.percent = atoi(Cmd_Argv(4)); +} + + +/* +================== +V_BonusFlash_f + +When you run over an item, the server sends this command +================== +*/ +void V_BonusFlash_f (void) +{ + cl.cshifts[CSHIFT_BONUS].destcolor[0] = 128; + cl.cshifts[CSHIFT_BONUS].destcolor[1] = 128; + cl.cshifts[CSHIFT_BONUS].destcolor[2] = 128; + cl.cshifts[CSHIFT_BONUS].percent = 50; +} + +/* +============= +V_SetContentsColor + +Underwater, lava, etc each has a color shift +============= +*/ +void V_SetContentsColor (int contents) +{ + switch (contents) + { + case CONTENTS_EMPTY: + case CONTENTS_SOLID: + cl.cshifts[CSHIFT_CONTENTS] = cshift_empty; + break; + case CONTENTS_LAVA: + cl.cshifts[CSHIFT_CONTENTS] = cshift_lava; + break; + case CONTENTS_SLIME: + cl.cshifts[CSHIFT_CONTENTS] = cshift_slime; + break; + default: + if (kurok) + cl.cshifts[CSHIFT_CONTENTS] = cshift_kwater; + else + cl.cshifts[CSHIFT_CONTENTS] = cshift_water; + } +} + +/* +============= +V_CalcPowerupCshift +============= +*/ +void V_CalcPowerupCshift (void) +{ + if (cl.items & IT_QUAD) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 0; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 255; + cl.cshifts[CSHIFT_POWERUP].percent = 30; + } + else if (cl.items & IT_SUIT) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0; + cl.cshifts[CSHIFT_POWERUP].percent = 20; + } + else if (cl.items & IT_INVISIBILITY) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 100; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 100; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 100; + cl.cshifts[CSHIFT_POWERUP].percent = 50; + } + else if (cl.items & IT_INVULNERABILITY) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 255; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 255; + cl.cshifts[CSHIFT_POWERUP].percent = 30; + } + else + cl.cshifts[CSHIFT_POWERUP].percent = 0; +} + +/* +============= +V_CalcBlend +============= +*/ +#if defined(GLQUAKE) || defined(PSP_HARDWARE_VIDEO) +void V_CalcBlend (void) +{ + float r, g, b, a, a2; + int j; + + r = 0; + g = 0; + b = 0; + a = 0; + + for (j=0 ; j 1) + v_blend[3] = 1; + if (v_blend[3] < 0) + v_blend[3] = 0; + + Draw_FadeScreenColor (v_blend[0], v_blend[1], v_blend[2], v_blend[3]); +} +#endif + +/* +============= +V_UpdatePalette +============= +*/ +#if defined(GLQUAKE) || defined(PSP_HARDWARE_VIDEO) +void V_UpdatePalette (void) +{ + int i, j; + qboolean new; +// byte *basepal, *newpal; +// byte pal[768]; +// float r,g,b,a; +// int ir, ig, ib; +// qboolean force; + + V_CalcPowerupCshift (); + + new = false; + + for (i=0 ; i 255) + ir = 255; + if (ig > 255) + ig = 255; + if (ib > 255) + ib = 255; + + ramps[0][i] = gammatable[ir]; + ramps[1][i] = gammatable[ig]; + ramps[2][i] = gammatable[ib]; + } + + basepal = host_basepal; + newpal = pal; + + for (i=0 ; i<256 ; i++) + { + ir = basepal[0]; + ig = basepal[1]; + ib = basepal[2]; + basepal += 3; + + newpal[0] = ramps[0][ir]; + newpal[1] = ramps[1][ig]; + newpal[2] = ramps[2][ib]; + newpal += 3; + } + + VID_ShiftPalette (pal); + */ +} +#else // !GLQUAKE +void V_UpdatePalette (void) +{ + int i, j; + qboolean new; + byte *basepal, *newpal; + byte pal[768]; + int r,g,b; + qboolean force; + + V_CalcPowerupCshift (); + + new = false; + + for (i=0 ; i>8; + g += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[1]-g))>>8; + b += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[2]-b))>>8; + } + + newpal[0] = gammatable[r]; + newpal[1] = gammatable[g]; + newpal[2] = gammatable[b]; + newpal += 3; + } + + VID_ShiftPalette (pal); +} +#endif // !GLQUAKE + + +/* +============================================================================== + + VIEW RENDERING + +============================================================================== +*/ + +float angledelta (float a) +{ + a = anglemod(a); + if (a > 180) + a -= 360; + return a; +} + +/* +================== +CalcGunAngle +================== +*/ +/* +void CalcGunAngle (void) +{ + float yaw, pitch, move; + static float oldyaw = 0; + static float oldpitch = 0; + + extern cvar_t in_freelook_analog; + extern cvar_t in_disable_analog; + extern cvar_t in_analog_strafe; + + extern cvar_t in_x_axis_adjust; + extern cvar_t in_y_axis_adjust; + + yaw = r_refdef.viewangles[YAW]; + pitch = -r_refdef.viewangles[PITCH]; + + yaw = angledelta(yaw - r_refdef.viewangles[YAW]) * 0.4; + if (yaw > 10) + yaw = 10; + if (yaw < -10) + yaw = -10; + pitch = angledelta(-pitch - r_refdef.viewangles[PITCH]) * 0.4; + if (pitch > 10) + pitch = 10; + if (pitch < -10) + pitch = -10; + move = host_frametime*20; + if (yaw > oldyaw) + { + if (oldyaw + move < yaw) + yaw = oldyaw + move; + } + else + { + if (oldyaw - move > yaw) + yaw = oldyaw - move; + } + + if (pitch > oldpitch) + { + if (oldpitch + move < pitch) + pitch = oldpitch + move; + } + else + { + if (oldpitch - move > pitch) + pitch = oldpitch - move; + } + + oldyaw = yaw; + oldpitch = pitch; + + cl.viewent.angles[YAW] = r_refdef.viewangles[YAW] + yaw; + cl.viewent.angles[PITCH] = - (r_refdef.viewangles[PITCH] + pitch); + + // Read the pad state. + SceCtrlData pad; + sceCtrlPeekBufferPositive(&pad, 1); + + extern cvar_t scr_fov; + + if (scr_fov.value == 90) + { + cl.viewent.angles[ROLL] -= sin(cl.time*3); + if (!in_disable_analog.value) + { + if (in_freelook_analog.value) + { + if (m_pitch.value < 0) + cl.viewent.angles[PITCH] -= sin(cl.time*1.8) - ((pad.Ly - 128) * in_y_axis_adjust.value * 0.015); + else + cl.viewent.angles[PITCH] -= sin(cl.time*1.8) + ((pad.Ly - 128) * in_y_axis_adjust.value * 0.015); + cl.viewent.angles[YAW] -= sin(cl.time*1.5) + ((pad.Lx - 128) * in_x_axis_adjust.value * 0.015); + } + else + { + if (!in_analog_strafe.value) + cl.viewent.angles[YAW] -= sin(cl.time*1.5) + ((pad.Lx - 128) * in_x_axis_adjust.value * 0.015); + } + } + + if (cl_gunpitch.value) + cl.viewent.angles[PITCH] -= cl_gunpitch.value; + + } + else + { + cl.viewent.angles[ROLL] -= v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value; + cl.viewent.angles[PITCH] -= v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value; + cl.viewent.angles[YAW] -= v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value; + } + +}*/ +/////////////// Blubswillrule's new CalcGunAngle added by Naievil +////////////////////// Better look for players on emulators +////////////////////////// Better fluidity in looking using A-nub +static float OldYawTheta; +static float OldPitchTheta; + + +void CalcGunAngle (void) +{ + float yaw, pitch, move; + static float oldyaw = 0; + static float oldpitch = 0; + + + yaw = r_refdef.viewangles[YAW]; + pitch = -r_refdef.viewangles[PITCH]; + + yaw = angledelta(yaw - r_refdef.viewangles[YAW]) * 0.4; + if (yaw > 10) + yaw = 10; + if (yaw < -10) + yaw = -10; + pitch = angledelta(-pitch - r_refdef.viewangles[PITCH]) * 0.4; + if (pitch > 10) + pitch = 10; + if (pitch < -10) + pitch = -10; + move = host_frametime*20; + if (yaw > oldyaw) + { + if (oldyaw + move < yaw) + yaw = oldyaw + move; + } + else + { + if (oldyaw - move > yaw) + yaw = oldyaw - move; + } + + if (pitch > oldpitch) + { + if (oldpitch + move < pitch) + pitch = oldpitch + move; + } + else + { + if (oldpitch - move > pitch) + pitch = oldpitch - move; + } + + oldyaw = yaw; + oldpitch = pitch; + + + //=========Strafe-Roll========= + //Creating backup + CWeaponRot[PITCH] = cl.viewent.angles[PITCH] * -1; + CWeaponRot[YAW] = cl.viewent.angles[YAW] * -1; + CWeaponRot[ROLL] = cl.viewent.angles[ROLL] * -1; + + float side; + side = V_CalcRoll (cl_entities[cl.viewentity].angles, cl.velocity); + cl.viewent.angles[ROLL] = angledelta(cl.viewent.angles[ROLL] - ((cl.viewent.angles[ROLL] - (side * 5)) * 0.5)); + + //^^^ Model swaying + + cl.viewent.angles[YAW] = (r_refdef.viewangles[YAW] + yaw) - (angledelta((r_refdef.viewangles[YAW] + yaw) - OldYawTheta ) * 0.6);//0.6 + + cl.viewent.angles[PITCH] = -1 * ((r_refdef.viewangles[PITCH] + pitch) - (angledelta((r_refdef.viewangles[PITCH] + pitch) + OldPitchTheta ) * 0.2)); + + //cl.viewent.angles[PITCH] = - (r_refdef.viewangles[PITCH] + pitch); + + //BLUBS STOPS HERE + OldYawTheta = cl.viewent.angles[YAW]; + OldPitchTheta = cl.viewent.angles[PITCH]; + + //Evaluating total offset + CWeaponRot[PITCH] -= cl.viewent.angles[PITCH]; + CWeaponRot[YAW] += cl.viewent.angles[YAW]; + CWeaponRot[ROLL] += cl.viewent.angles[ROLL]; + +} + +/* +============== +V_BoundOffsets +============== +*/ +void V_BoundOffsets (void) +{ + entity_t *ent; + + ent = &cl_entities[cl.viewentity]; + +// absolutely bound refresh reletive to entity clipping hull +// so the view can never be inside a solid wall + + if (r_refdef.vieworg[0] < ent->origin[0] - 14) + r_refdef.vieworg[0] = ent->origin[0] - 14; + else if (r_refdef.vieworg[0] > ent->origin[0] + 14) + r_refdef.vieworg[0] = ent->origin[0] + 14; + if (r_refdef.vieworg[1] < ent->origin[1] - 14) + r_refdef.vieworg[1] = ent->origin[1] - 14; + else if (r_refdef.vieworg[1] > ent->origin[1] + 14) + r_refdef.vieworg[1] = ent->origin[1] + 14; + if (r_refdef.vieworg[2] < ent->origin[2] - 22) + r_refdef.vieworg[2] = ent->origin[2] - 22; + else if (r_refdef.vieworg[2] > ent->origin[2] + 30) + r_refdef.vieworg[2] = ent->origin[2] + 30; +} + +/* +============== +V_AddIdle + +Idle swaying +============== +*/ +void V_AddIdle (void) +{ + /* + if (kurok) + { + double xyspeed; + float bspeed; + + xyspeed = sqrt(cl.velocity[0]*cl.velocity[0] + cl.velocity[1]*cl.velocity[1]); + bspeed = xyspeed * 0.15f; + + r_refdef.viewangles[ROLL] += v_idlescale.value * sinf(cl.time*v_iroll_cycle.value) * (v_iroll_level.value * bspeed); + r_refdef.viewangles[PITCH] += v_idlescale.value * sinf(cl.time*v_ipitch_cycle.value) * (v_ipitch_level.value * bspeed); + r_refdef.viewangles[YAW] += v_idlescale.value * sinf(cl.time*v_iyaw_cycle.value) * (v_iyaw_level.value * bspeed); + + r_refdef.viewangles[ROLL] += (v_idlescale.value * 3 ) * sinf(cl.time*v_iroll_cycle.value * 0.25 ) * v_iroll_level.value; + r_refdef.viewangles[PITCH] += (v_idlescale.value * 3 ) * sinf(cl.time*v_ipitch_cycle.value * 0.25 ) * v_ipitch_level.value; + r_refdef.viewangles[YAW] += (v_idlescale.value * 3 ) * sinf(cl.time*v_iyaw_cycle.value * 0.25 ) * v_iyaw_level.value; + } + else + { + */ + r_refdef.viewangles[ROLL] += v_idlescale.value * sinf(cl.time*v_iroll_cycle.value) * v_iroll_level.value; + r_refdef.viewangles[PITCH] += v_idlescale.value * sinf(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value; + r_refdef.viewangles[YAW] += v_idlescale.value * sinf(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value; + //} +} + + +/* +============== +V_CalcViewRoll + +Roll is induced by movement and damage +============== +*/ +void V_CalcViewRoll (void) +{ + float side; + + side = V_CalcRoll (cl_entities[cl.viewentity].angles, cl.velocity); + r_refdef.viewangles[ROLL] += side; + + if (v_dmg_time > 0) + { + r_refdef.viewangles[ROLL] += v_dmg_time/v_kicktime.value*v_dmg_roll; + r_refdef.viewangles[PITCH] += v_dmg_time/v_kicktime.value*v_dmg_pitch; + v_dmg_time -= host_frametime; + } + + if (cl.stats[STAT_HEALTH] <= 0) + { + r_refdef.viewangles[ROLL] = 80; // dead view angle + return; + } + +} + + +/* +================== +V_CalcIntermissionRefdef + +================== +*/ +void V_CalcIntermissionRefdef (void) +{ + entity_t *ent, *view; + float old; + +// ent is the player model (visible when out of body) + ent = &cl_entities[cl.viewentity]; +// view is the weapon model (only visible from inside body) + view = &cl.viewent; + + + VectorCopy (ent->origin, r_refdef.vieworg); + VectorCopy (ent->angles, r_refdef.viewangles); + view->model = NULL; + +// allways idle in intermission + if (!kurok) + { + old = v_idlescale.value; + v_idlescale.value = 1; + V_AddIdle (); + v_idlescale.value = old; + } +} + +/* +================== +V_CalcRefdef + +================== +*/ + +vec3_t CWeaponOffset;//blubs declared this +vec3_t CWeaponRot; + +void V_CalcRefdef (void) +{ + entity_t *ent, *view; + int i; + vec3_t forward, right, up; + vec3_t angles; + float bob, bobside; + static float oldz = 0; + + V_DriftPitch (); + +// ent is the player model (visible when out of body) + ent = &cl_entities[cl.viewentity]; +// view is the weapon model (only visible from inside body) + view = &cl.viewent; + + +// transform the view offset by the model's matrix to get the offset from +// model origin for the view + ent->angles[YAW] = cl.viewangles[YAW]; // the model should face + // the view dir + ent->angles[PITCH] = -cl.viewangles[PITCH]; // the model should face + // the view dir + if (chase_active.value) + { + bob = 0; + bobside = 0; + } + else + { + bob = V_CalcBob (); + bobside = V_CalcBobSide (); + } + +// refresh position + VectorCopy (ent->origin, r_refdef.vieworg); + r_refdef.vieworg[2] += cl.viewheight + bob; + +// never let it sit exactly on a node line, because a water plane can +// dissapear when viewed with the eye exactly on it. +// the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis + r_refdef.vieworg[0] += 1.0/32; + r_refdef.vieworg[1] += 1.0/32; + r_refdef.vieworg[2] += 1.0/32; + + VectorCopy (cl.viewangles, r_refdef.viewangles); + + if (!chase_active.value) + { + V_CalcViewRoll (); + V_AddIdle (); + } + +// offsets + angles[PITCH] = -ent->angles[PITCH]; // because entity pitches are + // actually backward + angles[YAW] = ent->angles[YAW]; + angles[ROLL] = ent->angles[ROLL]; + + AngleVectors (angles, forward, right, up); + + for (i=0 ; i<3 ; i++) + r_refdef.vieworg[i] += scr_ofsx.value*forward[i] + + scr_ofsy.value*right[i] + + scr_ofsz.value*up[i]; + + + V_BoundOffsets (); + +// set up gun position + VectorCopy (cl.viewangles, view->angles); + + CalcGunAngle (); + + VectorCopy (ent->origin, view->origin); + view->origin[2] += cl.viewheight; + + for (i=0 ; i<3 ; i++) + { +// view->origin[i] += forward[i]*bob*0.2; + view->origin[i] += right[i]*bobside*0.2; + view->origin[i] += up[i]*bob*0.2; + } + view->origin[2] += bob; + + if(!kurok) + { + +// fudge position around to keep amount of weapon visible +// roughly equal with different FOV + +#if 0 + if (cl.model_precache[cl.stats[STAT_WEAPON]] && strcmp (cl.model_precache[cl.stats[STAT_WEAPON]]->name, "progs/v_shot2.mdl")) +#endif + if (scr_viewsize.value == 130) + view->origin[2] += 2.25; + else if (scr_viewsize.value == 120) + view->origin[2] += 2.25; + else if (scr_viewsize.value == 110) + view->origin[2] += 2.5; + else if (scr_viewsize.value == 100) + view->origin[2] += 3; + else if (scr_viewsize.value == 90) + view->origin[2] += 2.5; + else if (scr_viewsize.value <= 80) + view->origin[2] += 2; + } + + view->model = cl.model_precache[cl.stats[STAT_WEAPON]]; + view->frame = cl.stats[STAT_WEAPONFRAME]; + view->colormap = vid.colormap; + +// set up the refresh position + VectorAdd (r_refdef.viewangles, cl.punchangle, r_refdef.viewangles); + +// smooth out stair step ups +if (cl.onground && ent->origin[2] - oldz > 0) +{ + float steptime; + + steptime = cl.time - cl.oldtime; + if (steptime < 0) +//FIXME I_Error ("steptime < 0"); + steptime = 0; + + oldz += steptime * 80; + if (oldz > ent->origin[2]) + oldz = ent->origin[2]; + if (ent->origin[2] - oldz > 12) + oldz = ent->origin[2] - 12; + r_refdef.vieworg[2] += oldz - ent->origin[2]; + view->origin[2] += oldz - ent->origin[2]; +} +else + oldz = ent->origin[2]; + + if (chase_active.value) + Chase_Update (); +} + +/* +================== +V_RenderView + +The player's clipping box goes from (-16 -16 -24) to (16 16 32) from +the entity origin, so any view position inside that will be valid +================== +*/ +extern vrect_t scr_vrect; + +void V_RenderView (void) +{ + if (con_forcedup) + return; + + if (!kurok) + { + // don't allow cheats in multiplayer + if (cl.maxclients > 1) + { + Cvar_Set ("scr_ofsx", "0"); + Cvar_Set ("scr_ofsy", "0"); + Cvar_Set ("scr_ofsz", "0"); + } + } + + if (cl.intermission) + { // intermission / finale rendering + V_CalcIntermissionRefdef (); + } + else + { + if (!cl.paused /* && (sv.maxclients > 1 || key_dest == key_game) */ ) + V_CalcRefdef (); + } + + R_PushDlights (); + + if (lcd_x.value) + { + // + // render two interleaved views + // + int i; + + vid.rowbytes <<= 1; + vid.aspect *= 0.5; + + r_refdef.viewangles[YAW] -= lcd_yaw.value; + for (i=0 ; i<3 ; i++) + r_refdef.vieworg[i] -= right[i]*lcd_x.value; + R_RenderView (); + + vid.buffer += vid.rowbytes>>1; + + R_PushDlights (); + + r_refdef.viewangles[YAW] += lcd_yaw.value*2; + for (i=0 ; i<3 ; i++) + r_refdef.vieworg[i] += 2*right[i]*lcd_x.value; + R_RenderView (); + + vid.buffer -= vid.rowbytes>>1; + + r_refdef.vrect.height <<= 1; + + vid.rowbytes >>= 1; + vid.aspect *= 2; + } + else + { + R_RenderView (); + } + +#if !defined(GLQUAKE) && !defined(PSP_HARDWARE_VIDEO) + if (crosshair.value) + Draw_Crosshair(); +// Draw_Character (scr_vrect.x + scr_vrect.width/2 + cl_crossx.value, scr_vrect.y + scr_vrect.height/2 + cl_crossy.value, '+'); +#endif + +} + +//============================================================================ + +/* +============= +V_Init +============= +*/ +void V_Init (void) +{ + Cmd_AddCommand ("v_cshift", V_cshift_f); + Cmd_AddCommand ("bf", V_BonusFlash_f); + Cmd_AddCommand ("centerview", V_StartPitchDrift); + + Cvar_RegisterVariable (&lcd_x); + Cvar_RegisterVariable (&lcd_yaw); + + Cvar_RegisterVariable (&v_centermove); + Cvar_RegisterVariable (&v_centerspeed); + + Cvar_RegisterVariable (&v_iyaw_cycle); + Cvar_RegisterVariable (&v_iroll_cycle); + Cvar_RegisterVariable (&v_ipitch_cycle); + Cvar_RegisterVariable (&v_iyaw_level); + Cvar_RegisterVariable (&v_iroll_level); + Cvar_RegisterVariable (&v_ipitch_level); + + Cvar_RegisterVariable (&v_idlescale); + Cvar_RegisterVariable (&crosshair); + Cvar_RegisterVariable (&cl_crossx); + Cvar_RegisterVariable (&cl_crossy); + Cvar_RegisterVariable (&gl_cshiftpercent); + + Cvar_RegisterVariable (&scr_ofsx); + Cvar_RegisterVariable (&scr_ofsy); + Cvar_RegisterVariable (&scr_ofsz); + Cvar_RegisterVariable (&cl_rollspeed); + Cvar_RegisterVariable (&cl_rollangle); + + Cvar_RegisterVariable (&cl_bob); + Cvar_RegisterVariable (&cl_bobcycle); + Cvar_RegisterVariable (&cl_bobup); + + Cvar_RegisterVariable (&cl_bobside); + Cvar_RegisterVariable (&cl_bobsidecycle); + Cvar_RegisterVariable (&cl_bobsideup); + + Cvar_RegisterVariable (&cl_gunpitch); + + Cvar_RegisterVariable (&v_kicktime); + Cvar_RegisterVariable (&v_kickroll); + Cvar_RegisterVariable (&v_kickpitch); + + BuildGammaTable (1.0); // no gamma yet + Cvar_RegisterVariable (&v_gamma); +} + + diff --git a/r17/Revamped src/revamped_src/view.h b/r17/Revamped src/revamped_src/view.h new file mode 100755 index 00000000..22513b12 --- /dev/null +++ b/r17/Revamped src/revamped_src/view.h @@ -0,0 +1,37 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// view.h + +extern cvar_t v_gamma; + +extern byte gammatable[256]; // palette is sent through this +extern byte ramps[3][256]; +extern float v_blend[4]; + +extern cvar_t lcd_x; + + +void V_Init (void); +void V_RenderView (void); +float V_CalcRoll (vec3_t angles, vec3_t velocity); +void V_UpdatePalette (void); + +extern vec3_t CWeaponOffset;//blubs declared this +extern vec3_t CWeaponRot; \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/wad.c b/r17/Revamped src/revamped_src/wad.c new file mode 100755 index 00000000..1eb8b59b --- /dev/null +++ b/r17/Revamped src/revamped_src/wad.c @@ -0,0 +1,158 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// wad.c + +#include "quakedef.h" + +int wad_numlumps; +lumpinfo_t *wad_lumps; +byte *wad_base; + +void SwapPic (qpic_t *pic); + +/* +================== +W_CleanupName + +Lowercases name and pads with spaces and a terminating 0 to the length of +lumpinfo_t->name. +Used so lumpname lookups can proceed rapidly by comparing 4 chars at a time +Space padding is so names can be printed nicely in tables. +Can safely be performed in place. +================== +*/ +void W_CleanupName (char *in, char *out) +{ + int i; + int c; + + for (i=0 ; i<16 ; i++ ) + { + c = in[i]; + if (!c) + break; + + if (c >= 'A' && c <= 'Z') + c += ('a' - 'A'); + out[i] = c; + } + + for ( ; i< 16 ; i++ ) + out[i] = 0; +} + + + +/* +==================== +W_LoadWadFile +==================== +*/ +void W_LoadWadFile (char *filename) +{ + lumpinfo_t *lump_p; + wadinfo_t *header; + unsigned i; + int infotableofs; + + wad_base = COM_LoadHunkFile (filename); + if (!wad_base) + Sys_Error ("W_LoadWadFile: couldn't load %s", filename); + + header = (wadinfo_t *)wad_base; + + if (header->identification[0] != 'W' + || header->identification[1] != 'A' + || header->identification[2] != 'D' + || header->identification[3] != '2') + Sys_Error ("Wad file %s doesn't have WAD2 id\n",filename); + + wad_numlumps = LittleLong(header->numlumps); + infotableofs = LittleLong(header->infotableofs); + wad_lumps = (lumpinfo_t *)(wad_base + infotableofs); + + for (i=0, lump_p = wad_lumps ; ifilepos = LittleLong(lump_p->filepos); + lump_p->size = LittleLong(lump_p->size); + W_CleanupName (lump_p->name, lump_p->name); + if (lump_p->type == TYP_QPIC) + SwapPic ( (qpic_t *)(wad_base + lump_p->filepos)); + } +} + + +/* +============= +W_GetLumpinfo +============= +*/ +lumpinfo_t *W_GetLumpinfo (char *name) +{ + int i; + lumpinfo_t *lump_p; + char clean[16]; + + W_CleanupName (name, clean); + + for (lump_p=wad_lumps, i=0 ; iname)) + return lump_p; + } + + Sys_Error ("W_GetLumpinfo: %s not found", name); + return NULL; +} + +void *W_GetLumpName (char *name) +{ + lumpinfo_t *lump; + + lump = W_GetLumpinfo (name); + + return (void *)(wad_base + lump->filepos); +} + +void *W_GetLumpNum (int num) +{ + lumpinfo_t *lump; + + if (num < 0 || num > wad_numlumps) + Sys_Error ("W_GetLumpNum: bad number: %i", num); + + lump = wad_lumps + num; + + return (void *)(wad_base + lump->filepos); +} + +/* +============================================================================= + +automatic byte swapping + +============================================================================= +*/ + +void SwapPic (qpic_t *pic) +{ + pic->width = LittleLong(pic->width); + pic->height = LittleLong(pic->height); +} diff --git a/r17/Revamped src/revamped_src/wad.h b/r17/Revamped src/revamped_src/wad.h new file mode 100755 index 00000000..125f5d71 --- /dev/null +++ b/r17/Revamped src/revamped_src/wad.h @@ -0,0 +1,75 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// wad.h + +//=============== +// TYPES +//=============== + +#define CMP_NONE 0 +#define CMP_LZSS 1 + +#define TYP_NONE 0 +#define TYP_LABEL 1 + +#define TYP_LUMPY 64 // 64 + grab command number +#define TYP_PALETTE 64 +#define TYP_QTEX 65 +#define TYP_QPIC 66 +#define TYP_SOUND 67 +#define TYP_MIPTEX 68 + +typedef struct +{ + int width, height; + byte data[4]; // variably sized +} qpic_t; + + + +typedef struct +{ + char identification[4]; // should be WAD2 or 2DAW + int numlumps; + int infotableofs; +} wadinfo_t; + +typedef struct +{ + int filepos; + int disksize; + int size; // uncompressed + char type; + char compression; + char pad1, pad2; + char name[16]; // must be null terminated +} lumpinfo_t; + +extern int wad_numlumps; +extern lumpinfo_t *wad_lumps; +extern byte *wad_base; + +void W_LoadWadFile (char *filename); +void W_CleanupName (char *in, char *out); +lumpinfo_t *W_GetLumpinfo (char *name); +void *W_GetLumpName (char *name); +void *W_GetLumpNum (int num); + +void SwapPic (qpic_t *pic); diff --git a/r17/Revamped src/revamped_src/win32_stubs/Debug/CL.read.1.tlog b/r17/Revamped src/revamped_src/win32_stubs/Debug/CL.read.1.tlog new file mode 100755 index 00000000..ba419603 Binary files /dev/null and b/r17/Revamped src/revamped_src/win32_stubs/Debug/CL.read.1.tlog differ diff --git a/r17/Revamped src/revamped_src/win32_stubs/Debug/CL.write.1.tlog b/r17/Revamped src/revamped_src/win32_stubs/Debug/CL.write.1.tlog new file mode 100755 index 00000000..630d4d35 Binary files /dev/null and b/r17/Revamped src/revamped_src/win32_stubs/Debug/CL.write.1.tlog differ diff --git a/r17/Revamped src/revamped_src/win32_stubs/Debug/Quake_Win32Stubs.lastbuildstate b/r17/Revamped src/revamped_src/win32_stubs/Debug/Quake_Win32Stubs.lastbuildstate new file mode 100755 index 00000000..c521af7d --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/Debug/Quake_Win32Stubs.lastbuildstate @@ -0,0 +1,2 @@ +#v4.0:v100 +Debug|Win32|C:\Documents and Settings\fr\Desktop\Kurok\| diff --git a/r17/Revamped src/revamped_src/win32_stubs/Debug/Quake_Win32Stubs.unsuccessfulbuild b/r17/Revamped src/revamped_src/win32_stubs/Debug/Quake_Win32Stubs.unsuccessfulbuild new file mode 100755 index 00000000..e69de29b diff --git a/r17/Revamped src/revamped_src/win32_stubs/Debug/cl.command.1.tlog b/r17/Revamped src/revamped_src/win32_stubs/Debug/cl.command.1.tlog new file mode 100755 index 00000000..d7c00518 Binary files /dev/null and b/r17/Revamped src/revamped_src/win32_stubs/Debug/cl.command.1.tlog differ diff --git a/r17/Revamped src/revamped_src/win32_stubs/Debug/vc100.idb b/r17/Revamped src/revamped_src/win32_stubs/Debug/vc100.idb new file mode 100755 index 00000000..4928b168 Binary files /dev/null and b/r17/Revamped src/revamped_src/win32_stubs/Debug/vc100.idb differ diff --git a/r17/Revamped src/revamped_src/win32_stubs/Debug/vc100.pdb b/r17/Revamped src/revamped_src/win32_stubs/Debug/vc100.pdb new file mode 100755 index 00000000..5289099a Binary files /dev/null and b/r17/Revamped src/revamped_src/win32_stubs/Debug/vc100.pdb differ diff --git a/r17/Revamped src/revamped_src/win32_stubs/Quake_Win32Stubs.vcproj b/r17/Revamped src/revamped_src/win32_stubs/Quake_Win32Stubs.vcproj new file mode 100755 index 00000000..c2c5e75c --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/Quake_Win32Stubs.vcproj @@ -0,0 +1,643 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/r17/Revamped src/revamped_src/win32_stubs/Quake_Win32Stubs.vcxproj b/r17/Revamped src/revamped_src/win32_stubs/Quake_Win32Stubs.vcxproj new file mode 100755 index 00000000..d9575b58 --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/Quake_Win32Stubs.vcxproj @@ -0,0 +1,205 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {D94197A6-9EAA-452A-AA05-652C940D70A3} + Quake_Win32Stubs + Win32Proj + + + + Application + Unicode + true + + + Application + Unicode + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + + Disabled + $(ProjectDir);%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;PSP;PSP_HARDWARE_VIDEO;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + EditAndContinue + + + true + Console + MachineX86 + + + + + $(ProjectDir);%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;PSP;PSP_HARDWARE_VIDEO;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX86 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/win32_stubs/Quake_Win32Stubs.vcxproj.filters b/r17/Revamped src/revamped_src/win32_stubs/Quake_Win32Stubs.vcxproj.filters new file mode 100755 index 00000000..ace54c08 --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/Quake_Win32Stubs.vcxproj.filters @@ -0,0 +1,357 @@ + + + + + {c0f34578-fa2e-4119-93b8-efb2599650b0} + + + {b3179418-1a1f-4865-a04a-705a93d8eb1b} + + + {dcd7d2f2-79bb-4a66-8bc3-ccac097b9a72} + + + {148dafbf-c3e6-4e54-8828-ee1b16ab8f02} + + + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + Windows stubs + + + Windows stubs + + + Windows stubs + + + Windows stubs + + + Windows stubs + + + Windows stubs + + + Windows stubs + + + Windows stubs + + + Windows stubs + + + Windows stubs\sys + + + Windows stubs\sys + + + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + Generic source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + PSP specific source + + + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/win32_stubs/Quake_Win32Stubs.vcxproj.user b/r17/Revamped src/revamped_src/win32_stubs/Quake_Win32Stubs.vcxproj.user new file mode 100755 index 00000000..695b5c78 --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/Quake_Win32Stubs.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/r17/Revamped src/revamped_src/win32_stubs/pspaudiolib.h b/r17/Revamped src/revamped_src/win32_stubs/pspaudiolib.h new file mode 100755 index 00000000..0362df79 --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/pspaudiolib.h @@ -0,0 +1,31 @@ +#ifndef PSPAUDIOLIB_H +#define PSPAUDIOLIB_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef void (CHANNEL_CALLBACK) (void*, unsigned int, void*); + + static void pspAudioInit(void) + { + } + + static void pspAudioEndPre(void) + { + } + + static void pspAudioEnd(void) + { + } + + static void pspAudioSetChannelCallback(int, CHANNEL_CALLBACK*, int) + { + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/r17/Revamped src/revamped_src/win32_stubs/pspctrl.h b/r17/Revamped src/revamped_src/win32_stubs/pspctrl.h new file mode 100755 index 00000000..9fed1cb1 --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/pspctrl.h @@ -0,0 +1,56 @@ +#ifndef PSPCTRL_H +#define PSPCTRL_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define PSP_CTRL_MODE_ANALOG 0 + +#define PSP_CTRL_CROSS 0 +#define PSP_CTRL_CIRCLE 1 +#define PSP_CTRL_SQUARE 2 +#define PSP_CTRL_TRIANGLE 3 +#define PSP_CTRL_SELECT 0 +#define PSP_CTRL_START 1 +#define PSP_CTRL_UP 0 +#define PSP_CTRL_DOWN 1 +#define PSP_CTRL_LEFT 0 +#define PSP_CTRL_RIGHT 1 +#define PSP_CTRL_LTRIGGER 0 +#define PSP_CTRL_RTRIGGER 1 + + typedef struct SceCtrlDataS + { + int Buttons; + int Lx; + int Ly; + int TimeStamp; + } SceCtrlData; + + static void sceCtrlSetSamplingCycle(int) + { + } + + static void sceCtrlSetSamplingMode(int) + { + } + + static void sceCtrlPeekBufferPositive(SceCtrlData* pad, int) + { + memset(pad, 0, sizeof(*pad)); + } + + static void sceCtrlReadBufferPositive(SceCtrlData* pad, int i) + { + sceCtrlPeekBufferPositive(pad, i); + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/r17/Revamped src/revamped_src/win32_stubs/pspdebug.h b/r17/Revamped src/revamped_src/win32_stubs/pspdebug.h new file mode 100755 index 00000000..b139be47 --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/pspdebug.h @@ -0,0 +1,43 @@ +#ifndef PSPDEBUG_H +#define PSPDEBUG_H + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + static void pspDebugScreenInit(void) + { + } + + static void pspDebugScreenSetTextColor(int) + { + DebugBreak(); + } + + static void pspDebugScreenPrintData(const char* d, int) + { + OutputDebugStringA(d); + printf("%s", d); + } + + static void pspDebugScreenPrintf(const char* f, ...) + { + va_list args; + static char buffer[1024]; + + va_start(args, f); + vsnprintf(buffer, sizeof(buffer) - 1, f, args); + va_end(args); + + pspDebugScreenPrintData(buffer, strlen(buffer)); + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/r17/Revamped src/revamped_src/win32_stubs/pspdisplay.h b/r17/Revamped src/revamped_src/win32_stubs/pspdisplay.h new file mode 100755 index 00000000..5e8bc490 --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/pspdisplay.h @@ -0,0 +1,17 @@ +#ifndef PSPDISPLAY_H +#define PSPDISPLAY_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + static void sceDisplayWaitVblankStart(void) + { + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/r17/Revamped src/revamped_src/win32_stubs/pspgu.h b/r17/Revamped src/revamped_src/win32_stubs/pspgu.h new file mode 100755 index 00000000..e0edafe7 --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/pspgu.h @@ -0,0 +1,27 @@ +#ifndef PSPGU_H +#define PSPGU_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define PSP_GU 2 + + typedef unsigned char u8; + typedef unsigned int ScePspRGBA8888; + + static void sceGu(void) + { + } + + static void* sceGeEdramGetAddr(void) + { + return 0; + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/r17/Revamped src/revamped_src/win32_stubs/pspkernel.h b/r17/Revamped src/revamped_src/win32_stubs/pspkernel.h new file mode 100755 index 00000000..14bab01e --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/pspkernel.h @@ -0,0 +1,62 @@ +#ifndef PSPKERNEL_H +#define PSPKERNEL_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef int SceSize; + typedef int SceUID; + + typedef int K_CALLBACK(int, int, void*); + typedef int K_THREAD_CALLBACK(SceSize, void*); + + typedef int PspDebugRegBlock; + + static void sceKernelDelayThread(int) + { + } + + static SceUID sceKernelCreateCallback(const char*, K_CALLBACK, void*) + { + return 0; + } + + static void sceKernelRegisterExitCallback(SceUID) + { + } + + static void sceKernelSleepThreadCB() + { + } + + static int sceKernelCreateThread(const char*, K_THREAD_CALLBACK*, int, int, int, int) + { + return 1; + } + + static void sceKernelStartThread(int, int, int) + { + } + + static void pspDebugDumpException(PspDebugRegBlock*) + { + } + + static void pspDebugInstallErrorHandler(void (*) (PspDebugRegBlock*)) + { + } + + static void sceKernelExitGame(void) + { + DebugBreak(); + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/r17/Revamped src/revamped_src/win32_stubs/pspmoduleinfo.h b/r17/Revamped src/revamped_src/win32_stubs/pspmoduleinfo.h new file mode 100755 index 00000000..88af220b --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/pspmoduleinfo.h @@ -0,0 +1,21 @@ +#ifndef PSPMODULEINFO_H +#define PSPMODULEINFO_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define PSP_MODULE_INFO(name, flags, version1, version2) +#define PSP_MAIN_THREAD_ATTR(x) + + static int sceM(void) + { + return 50; + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/r17/Revamped src/revamped_src/win32_stubs/psppower.h b/r17/Revamped src/revamped_src/win32_stubs/psppower.h new file mode 100755 index 00000000..b9f983c4 --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/psppower.h @@ -0,0 +1,56 @@ +#ifndef PSPPOWER_H +#define PSPPOWER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define PSP_POWER_CB_POWER_SWITCH 1 +#define PSP_POWER_CB_SUSPENDING 2 +#define PSP_POWER_CB_RESUMING 1 +#define PSP_POWER_CB_RESUME_COMPLETE 2 + + static int scePowerGetBatteryLifePercent(void) + { + return 50; + } + + static int scePowerGetBatteryChargingStatus(void) + { + return 1; + } + + static int scePowerIsBatteryExist(void) + { + return 1; + } + + static int scePowerGetBatteryLifeTime(void) + { + return 60; + } + + static int scePowerGetCpuClockFrequencyInt() + { + return 333; + } + + static int scePowerGetBusClockFrequencyInt() + { + return scePowerGetCpuClockFrequencyInt() / 2; + } + + static void scePowerRegisterCallback(int, int) + { + } + + static void scePowerSetClockFrequency(int, int, int) + { + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/r17/Revamped src/revamped_src/win32_stubs/psprtc.h b/r17/Revamped src/revamped_src/win32_stubs/psprtc.h new file mode 100755 index 00000000..6f60b74e --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/psprtc.h @@ -0,0 +1,27 @@ +#ifndef PSPRTC_H +#define PSPRTC_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef UINT64 u64; + + static int sceRtcGetTickResolution(void) + { + return 1000; + } + + static void sceRtcGetCurrentTick(u64* u) + { + *u = GetTickCount(); + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/r17/Revamped src/revamped_src/win32_stubs/sys/stat.h b/r17/Revamped src/revamped_src/win32_stubs/sys/stat.h new file mode 100755 index 00000000..1cd5220b --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/sys/stat.h @@ -0,0 +1,22 @@ +#ifndef STAT_H +#define STAT_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct stat; + + static void sceIoMkdir(const char* d, int) + { + CreateDirectoryA(d, 0); + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/r17/Revamped src/revamped_src/win32_stubs/sys/unistd.h b/r17/Revamped src/revamped_src/win32_stubs/sys/unistd.h new file mode 100755 index 00000000..c235bf59 --- /dev/null +++ b/r17/Revamped src/revamped_src/win32_stubs/sys/unistd.h @@ -0,0 +1,20 @@ +#ifndef UNISTD_H +#define UNISTD_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + static void getcwd(char* dir, size_t size) + { + strncpy(dir, ".", size); + } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/r17/Revamped src/revamped_src/world.c b/r17/Revamped src/revamped_src/world.c new file mode 100755 index 00000000..06543cee --- /dev/null +++ b/r17/Revamped src/revamped_src/world.c @@ -0,0 +1,964 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// world.c -- world query functions + +#include "quakedef.h" + +/* + +entities never clip against themselves, or their owner + +line of sight checks trace->crosscontent, but bullets don't + +*/ + + +typedef struct +{ + vec3_t boxmins, boxmaxs;// enclose the test object along entire move + float *mins, *maxs; // size of the moving object + vec3_t mins2, maxs2; // size when clipping against mosnters + float *start, *end; + trace_t trace; + int type; + edict_t *passedict; +} moveclip_t; + + +int SV_HullPointContents (hull_t *hull, int num, vec3_t p); + +/* +=============================================================================== + +HULL BOXES + +=============================================================================== +*/ + + +static hull_t box_hull; +static dclipnode_t box_clipnodes[6]; +static mplane_t box_planes[6]; + +/* +=================== +SV_InitBoxHull + +Set up the planes and clipnodes so that the six floats of a bounding box +can just be stored out and get a proper hull_t structure. +=================== +*/ +void SV_InitBoxHull (void) +{ + int i; + int side; + + box_hull.clipnodes = box_clipnodes; + box_hull.planes = box_planes; + box_hull.firstclipnode = 0; + box_hull.lastclipnode = 5; + + for (i=0 ; i<6 ; i++) + { + box_clipnodes[i].planenum = i; + + side = i&1; + + box_clipnodes[i].children[side] = CONTENTS_EMPTY; + if (i != 5) + box_clipnodes[i].children[side^1] = i + 1; + else + box_clipnodes[i].children[side^1] = CONTENTS_SOLID; + + box_planes[i].type = i>>1; + box_planes[i].normal[i>>1] = 1; + } + +} + + +/* +=================== +SV_HullForBox + +To keep everything totally uniform, bounding boxes are turned into small +BSP trees instead of being compared directly. +=================== +*/ +hull_t *SV_HullForBox (vec3_t mins, vec3_t maxs) +{ + box_planes[0].dist = maxs[0]; + box_planes[1].dist = mins[0]; + box_planes[2].dist = maxs[1]; + box_planes[3].dist = mins[1]; + box_planes[4].dist = maxs[2]; + box_planes[5].dist = mins[2]; + + return &box_hull; +} + + + +/* +================ +SV_HullForEntity + +Returns a hull that can be used for testing or clipping an object of mins/maxs +size. +Offset is filled in to contain the adjustment that must be added to the +testing object's origin to get a point to use with the returned hull. +================ +*/ +hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset) +{ + model_t *model; + vec3_t size; + vec3_t hullmins, hullmaxs; + hull_t *hull; + +// decide which clipping hull to use, based on the size + if (ent->v.solid == SOLID_BSP) + { // explicit hulls in the BSP model + if (ent->v.movetype != MOVETYPE_PUSH) + Sys_Error ("SOLID_BSP without MOVETYPE_PUSH"); + + model = sv.models[ (int)ent->v.modelindex ]; + + if (!model || model->type != mod_brush) + Sys_Error ("MOVETYPE_PUSH with a non bsp model"); + + VectorSubtract (maxs, mins, size); + if (size[0] < 3) + hull = &model->hulls[0]; + else if (size[0] <= 32) + hull = &model->hulls[1]; + else if (size[0] <= 12) + hull = &model->hulls[3]; + else + hull = &model->hulls[2]; + +// calculate an offset value to center the origin + VectorSubtract (hull->clip_mins, mins, offset); + VectorAdd (offset, ent->v.origin, offset); + } + else + { // create a temp hull from bounding box sizes + + VectorSubtract (ent->v.mins, maxs, hullmins); + VectorSubtract (ent->v.maxs, mins, hullmaxs); + hull = SV_HullForBox (hullmins, hullmaxs); + + VectorCopy (ent->v.origin, offset); + } + + + return hull; +} + +/* +=============================================================================== + +ENTITY AREA CHECKING + +=============================================================================== +*/ + +typedef struct areanode_s +{ + int axis; // -1 = leaf node + float dist; + struct areanode_s *children[2]; + link_t trigger_edicts; + link_t solid_edicts; +} areanode_t; + +#define AREA_DEPTH 4 +#define AREA_NODES 32 + +static areanode_t sv_areanodes[AREA_NODES]; +static int sv_numareanodes; + +/* +=============== +SV_CreateAreaNode + +=============== +*/ +areanode_t *SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs) +{ + areanode_t *anode; + vec3_t size; + vec3_t mins1, maxs1, mins2, maxs2; + + anode = &sv_areanodes[sv_numareanodes]; + sv_numareanodes++; + + ClearLink (&anode->trigger_edicts); + ClearLink (&anode->solid_edicts); + + if (depth == AREA_DEPTH) + { + anode->axis = -1; + anode->children[0] = anode->children[1] = NULL; + return anode; + } + + VectorSubtract (maxs, mins, size); + if (size[0] > size[1]) + anode->axis = 0; + else + anode->axis = 1; + + anode->dist = 0.5 * (maxs[anode->axis] + mins[anode->axis]); + VectorCopy (mins, mins1); + VectorCopy (mins, mins2); + VectorCopy (maxs, maxs1); + VectorCopy (maxs, maxs2); + + maxs1[anode->axis] = mins2[anode->axis] = anode->dist; + + anode->children[0] = SV_CreateAreaNode (depth+1, mins2, maxs2); + anode->children[1] = SV_CreateAreaNode (depth+1, mins1, maxs1); + + return anode; +} + +/* +=============== +SV_ClearWorld + +=============== +*/ +void SV_ClearWorld (void) +{ + SV_InitBoxHull (); + + memset (sv_areanodes, 0, sizeof(sv_areanodes)); + sv_numareanodes = 0; + SV_CreateAreaNode (0, sv.worldmodel->mins, sv.worldmodel->maxs); +} + + +/* +=============== +SV_UnlinkEdict + +=============== +*/ +void SV_UnlinkEdict (edict_t *ent) +{ + if (!ent->area.prev) + return; // not linked in anywhere + RemoveLink (&ent->area); + ent->area.prev = ent->area.next = NULL; +} + + +/* +==================== +SV_TouchLinks +==================== +*/ +void SV_TouchLinks ( edict_t *ent, areanode_t *node ) +{ + link_t *l, *next; + edict_t *touch; + int old_self, old_other; + +// touch linked edicts + for (l = node->trigger_edicts.next ; l != &node->trigger_edicts ; l = next) + { + next = l->next; + touch = EDICT_FROM_AREA(l); + if (touch == ent) + continue; + if (!touch->v.touch || touch->v.solid != SOLID_TRIGGER) + continue; + if (ent->v.absmin[0] > touch->v.absmax[0] + || ent->v.absmin[1] > touch->v.absmax[1] + || ent->v.absmin[2] > touch->v.absmax[2] + || ent->v.absmax[0] < touch->v.absmin[0] + || ent->v.absmax[1] < touch->v.absmin[1] + || ent->v.absmax[2] < touch->v.absmin[2] ) + continue; + old_self = pr_global_struct->self; + old_other = pr_global_struct->other; + + pr_global_struct->self = EDICT_TO_PROG(touch); + pr_global_struct->other = EDICT_TO_PROG(ent); + pr_global_struct->time = sv.time; + PR_ExecuteProgram (touch->v.touch); + + pr_global_struct->self = old_self; + pr_global_struct->other = old_other; + } + +// recurse down both sides + if (node->axis == -1) + return; + + if ( ent->v.absmax[node->axis] > node->dist ) + SV_TouchLinks ( ent, node->children[0] ); + if ( ent->v.absmin[node->axis] < node->dist ) + SV_TouchLinks ( ent, node->children[1] ); +} + + +/* +=============== +SV_FindTouchedLeafs + +=============== +*/ +void SV_FindTouchedLeafs (edict_t *ent, mnode_t *node) +{ + mplane_t *splitplane; + mleaf_t *leaf; + int sides; + int leafnum; + + if (node->contents == CONTENTS_SOLID) + return; + +// add an efrag if the node is a leaf + + if ( node->contents < 0) + { + if (ent->num_leafs == MAX_ENT_LEAFS) + return; + + leaf = (mleaf_t *)node; + leafnum = leaf - sv.worldmodel->leafs - 1; + + ent->leafnums[ent->num_leafs] = leafnum; + ent->num_leafs++; + return; + } + +// NODE_MIXED + + splitplane = node->plane; + sides = BOX_ON_PLANE_SIDE(ent->v.absmin, ent->v.absmax, splitplane); + +// recurse down the contacted sides + if (sides & 1) + SV_FindTouchedLeafs (ent, node->children[0]); + + if (sides & 2) + SV_FindTouchedLeafs (ent, node->children[1]); +} + +/* +=============== +SV_LinkEdict + +=============== +*/ +void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) +{ + areanode_t *node; + + if (ent->area.prev) + SV_UnlinkEdict (ent); // unlink from old position + + if (ent == sv.edicts) + return; // don't add the world + + if (ent->free) + return; + +// set the abs box + +#ifdef QUAKE2 + if (ent->v.solid == SOLID_BSP && + (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) ) + { // expand for rotation + float max, v; + int i; + + max = 0; + for (i=0 ; i<3 ; i++) + { + v =fabsf( ent->v.mins[i]); + if (v > max) + max = v; + v =fabsf( ent->v.maxs[i]); + if (v > max) + max = v; + } + for (i=0 ; i<3 ; i++) + { + ent->v.absmin[i] = ent->v.origin[i] - max; + ent->v.absmax[i] = ent->v.origin[i] + max; + } + } + else +#endif + { + VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin); + VectorAdd (ent->v.origin, ent->v.maxs, ent->v.absmax); + } + +// +// to make items easier to pick up and allow them to be grabbed off +// of shelves, the abs sizes are expanded +// + if ((int)ent->v.flags & FL_ITEM) + { + ent->v.absmin[0] -= 15; + ent->v.absmin[1] -= 15; + ent->v.absmax[0] += 15; + ent->v.absmax[1] += 15; + } + else + { // because movement is clipped an epsilon away from an actual edge, + // we must fully check even when bounding boxes don't quite touch + ent->v.absmin[0] -= 1; + ent->v.absmin[1] -= 1; + ent->v.absmin[2] -= 1; + ent->v.absmax[0] += 1; + ent->v.absmax[1] += 1; + ent->v.absmax[2] += 1; + } + +// link to PVS leafs + ent->num_leafs = 0; + if (ent->v.modelindex) + SV_FindTouchedLeafs (ent, sv.worldmodel->nodes); + + if (ent->v.solid == SOLID_NOT) + return; + +// find the first node that the ent's box crosses + node = sv_areanodes; + while (1) + { + if (node->axis == -1) + break; + if (ent->v.absmin[node->axis] > node->dist) + node = node->children[0]; + else if (ent->v.absmax[node->axis] < node->dist) + node = node->children[1]; + else + break; // crosses the node + } + +// link it in + + if (ent->v.solid == SOLID_TRIGGER) + InsertLinkBefore (&ent->area, &node->trigger_edicts); + else + InsertLinkBefore (&ent->area, &node->solid_edicts); + +// if touch_triggers, touch all entities at this node and decend for more + if (touch_triggers) + SV_TouchLinks ( ent, sv_areanodes ); +} + + + +/* +=============================================================================== + +POINT TESTING IN HULLS + +=============================================================================== +*/ + +#if !id386 + +/* +================== +SV_HullPointContents + +================== +*/ +int SV_HullPointContents (hull_t *hull, int num, vec3_t p) +{ + float d; + dclipnode_t *node; + mplane_t *plane; + + while (num >= 0) + { + if (num < hull->firstclipnode || num > hull->lastclipnode) + Sys_Error ("SV_HullPointContents: bad node number"); + + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + + if (plane->type < 3) + d = p[plane->type] - plane->dist; + else + d = DotProduct (plane->normal, p) - plane->dist; + if (d < 0) + num = node->children[1]; + else + num = node->children[0]; + } + + return num; +} + +#endif // !id386 + + +/* +================== +SV_PointContents + +================== +*/ +int SV_PointContents (vec3_t p) +{ + int cont; + + cont = SV_HullPointContents (&sv.worldmodel->hulls[0], 0, p); + if (cont <= CONTENTS_CURRENT_0 && cont >= CONTENTS_CURRENT_DOWN) + cont = CONTENTS_WATER; + return cont; +} + +int SV_TruePointContents (vec3_t p) +{ + return SV_HullPointContents (&sv.worldmodel->hulls[0], 0, p); +} + +//=========================================================================== + +/* +============ +SV_TestEntityPosition + +This could be a lot more efficient... +============ +*/ +edict_t *SV_TestEntityPosition (edict_t *ent) +{ + trace_t trace; + + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, 0, ent); + + if (trace.startsolid) + return sv.edicts; + + return NULL; +} + + +/* +=============================================================================== + +LINE TESTING IN HULLS + +=============================================================================== +*/ + +// 1/32 epsilon to keep floating point happy +#define DIST_EPSILON (0.03125) + +/* +================== +SV_RecursiveHullCheck + +================== +*/ +qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace) +{ + dclipnode_t *node; + mplane_t *plane; + float t1, t2; + float frac; + int i; + vec3_t mid; + int side; + float midf; + +// check for empty + if (num < 0) + { + if (num != CONTENTS_SOLID) + { + trace->allsolid = false; + if (num == CONTENTS_EMPTY) + trace->inopen = true; + else + trace->inwater = true; + } + else + trace->startsolid = true; + return true; // empty + } + + if (num < hull->firstclipnode || num > hull->lastclipnode) + Sys_Error ("SV_RecursiveHullCheck: bad node number"); + +// +// find the point distances +// + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + + if (plane->type < 3) + { + t1 = p1[plane->type] - plane->dist; + t2 = p2[plane->type] - plane->dist; + } + else + { + t1 = DotProduct (plane->normal, p1) - plane->dist; + t2 = DotProduct (plane->normal, p2) - plane->dist; + } + +#if 1 + if (t1 >= 0 && t2 >= 0) + return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace); + if (t1 < 0 && t2 < 0) + return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace); +#else + if ( (t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0) ) + return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace); + if ( (t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0) ) + return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace); +#endif + +// put the crosspoint DIST_EPSILON pixels on the near side + if (t1 < 0) + frac = (t1 + DIST_EPSILON)/(t1-t2); + else + frac = (t1 - DIST_EPSILON)/(t1-t2); + if (frac < 0) + frac = 0; + if (frac > 1) + frac = 1; + + midf = p1f + (p2f - p1f)*frac; + for (i=0 ; i<3 ; i++) + mid[i] = p1[i] + frac*(p2[i] - p1[i]); + + side = (t1 < 0); + +// move up to the node + if (!SV_RecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) ) + return false; + +#ifdef PARANOID + if (SV_HullPointContents (sv_hullmodel, mid, node->children[side]) + == CONTENTS_SOLID) + { + Con_Printf ("mid PointInHullSolid\n"); + return false; + } +#endif + + if (SV_HullPointContents (hull, node->children[side^1], mid) + != CONTENTS_SOLID) +// go past the node + return SV_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace); + + if (trace->allsolid) + return false; // never got out of the solid area + +//================== +// the other side of the node is solid, this is the impact point +//================== + if (!side) + { + VectorCopy (plane->normal, trace->plane.normal); + trace->plane.dist = plane->dist; + } + else + { + VectorSubtract (vec3_origin, plane->normal, trace->plane.normal); + trace->plane.dist = -plane->dist; + } + + while (SV_HullPointContents (hull, hull->firstclipnode, mid) + == CONTENTS_SOLID) + { // shouldn't really happen, but does occasionally + frac -= 0.1; + if (frac < 0) + { + trace->fraction = midf; + VectorCopy (mid, trace->endpos); + Con_DPrintf ("backup past 0\n"); + return false; + } + midf = p1f + (p2f - p1f)*frac; + for (i=0 ; i<3 ; i++) + mid[i] = p1[i] + frac*(p2[i] - p1[i]); + } + + trace->fraction = midf; + VectorCopy (mid, trace->endpos); + + return false; +} + + +/* +================== +SV_ClipMoveToEntity + +Handles selection or creation of a clipping hull, and offseting (and +eventually rotation) of the end points +================== +*/ +trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end) +{ + trace_t trace; + vec3_t offset; + vec3_t start_l, end_l; + hull_t *hull; + +// fill in a default trace + memset (&trace, 0, sizeof(trace_t)); + trace.fraction = 1; + trace.allsolid = true; + VectorCopy (end, trace.endpos); + +// get the clipping hull + hull = SV_HullForEntity (ent, mins, maxs, offset); + + VectorSubtract (start, offset, start_l); + VectorSubtract (end, offset, end_l); + +#ifdef QUAKE2 + // rotate start and end into the models frame of reference + if (ent->v.solid == SOLID_BSP && + (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) ) + { + vec3_t a; + vec3_t forward, right, up; + vec3_t temp; + + AngleVectors (ent->v.angles, forward, right, up); + + VectorCopy (start_l, temp); + start_l[0] = DotProduct (temp, forward); + start_l[1] = -DotProduct (temp, right); + start_l[2] = DotProduct (temp, up); + + VectorCopy (end_l, temp); + end_l[0] = DotProduct (temp, forward); + end_l[1] = -DotProduct (temp, right); + end_l[2] = DotProduct (temp, up); + } +#endif + +// trace a line through the apropriate clipping hull + SV_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, &trace); + +#ifdef QUAKE2 + // rotate endpos back to world frame of reference + if (ent->v.solid == SOLID_BSP && + (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) ) + { + vec3_t a; + vec3_t forward, right, up; + vec3_t temp; + + if (trace.fraction != 1) + { + VectorSubtract (vec3_origin, ent->v.angles, a); + AngleVectors (a, forward, right, up); + + VectorCopy (trace.endpos, temp); + trace.endpos[0] = DotProduct (temp, forward); + trace.endpos[1] = -DotProduct (temp, right); + trace.endpos[2] = DotProduct (temp, up); + + VectorCopy (trace.plane.normal, temp); + trace.plane.normal[0] = DotProduct (temp, forward); + trace.plane.normal[1] = -DotProduct (temp, right); + trace.plane.normal[2] = DotProduct (temp, up); + } + } +#endif + +// fix trace up by the offset + if (trace.fraction != 1) + VectorAdd (trace.endpos, offset, trace.endpos); + +// did we clip the move? + if (trace.fraction < 1 || trace.startsolid ) + trace.ent = ent; + + return trace; +} + +//=========================================================================== + +/* +==================== +SV_ClipToLinks + +Mins and maxs enclose the entire area swept by the move +==================== +*/ +void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip ) +{ + link_t *l, *next; + edict_t *touch; + trace_t trace; + +// touch linked edicts + for (l = node->solid_edicts.next ; l != &node->solid_edicts ; l = next) + { + next = l->next; + touch = EDICT_FROM_AREA(l); + if (touch->v.solid == SOLID_NOT) + continue; + if (touch == clip->passedict) + continue; + if (touch->v.solid == SOLID_TRIGGER) + Sys_Error ("Trigger in clipping list"); + + if (clip->type == MOVE_NOMONSTERS && touch->v.solid != SOLID_BSP) + continue; + + if (clip->boxmins[0] > touch->v.absmax[0] + || clip->boxmins[1] > touch->v.absmax[1] + || clip->boxmins[2] > touch->v.absmax[2] + || clip->boxmaxs[0] < touch->v.absmin[0] + || clip->boxmaxs[1] < touch->v.absmin[1] + || clip->boxmaxs[2] < touch->v.absmin[2] ) + continue; + + if (clip->passedict && clip->passedict->v.size[0] && !touch->v.size[0]) + continue; // points never interact + + // might intersect, so do an exact clip + if (clip->trace.allsolid) + return; + if (clip->passedict) + { + if (PROG_TO_EDICT(touch->v.owner) == clip->passedict) + continue; // don't clip against own missiles + if (PROG_TO_EDICT(clip->passedict->v.owner) == touch) + continue; // don't clip against owner + } + + if ((int)touch->v.flags & FL_MONSTER) + trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end); + else + trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end); + if (trace.allsolid || trace.startsolid || + trace.fraction < clip->trace.fraction) + { + trace.ent = touch; + if (clip->trace.startsolid) + { + clip->trace = trace; + clip->trace.startsolid = true; + } + else + clip->trace = trace; + } + else if (trace.startsolid) + clip->trace.startsolid = true; + } + +// recurse down both sides + if (node->axis == -1) + return; + + if ( clip->boxmaxs[node->axis] > node->dist ) + SV_ClipToLinks ( node->children[0], clip ); + if ( clip->boxmins[node->axis] < node->dist ) + SV_ClipToLinks ( node->children[1], clip ); +} + + +/* +================== +SV_MoveBounds +================== +*/ +void SV_MoveBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, vec3_t boxmins, vec3_t boxmaxs) +{ +#if 0 +// debug to test against everything +boxmins[0] = boxmins[1] = boxmins[2] = -9999; +boxmaxs[0] = boxmaxs[1] = boxmaxs[2] = 9999; +#else + int i; + + for (i=0 ; i<3 ; i++) + { + if (end[i] > start[i]) + { + boxmins[i] = start[i] + mins[i] - 1; + boxmaxs[i] = end[i] + maxs[i] + 1; + } + else + { + boxmins[i] = end[i] + mins[i] - 1; + boxmaxs[i] = start[i] + maxs[i] + 1; + } + } +#endif +} + +/* +================== +SV_Move +================== +*/ +trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *passedict) +{ + moveclip_t clip; + int i; + + memset ( &clip, 0, sizeof ( moveclip_t ) ); + +// clip to world + clip.trace = SV_ClipMoveToEntity ( sv.edicts, start, mins, maxs, end ); + + clip.start = start; + clip.end = end; + clip.mins = mins; + clip.maxs = maxs; + clip.type = type; + clip.passedict = passedict; + + if (type == MOVE_MISSILE) + { + for (i=0 ; i<3 ; i++) + { + clip.mins2[i] = -15; + clip.maxs2[i] = 15; + } + } + else + { + VectorCopy (mins, clip.mins2); + VectorCopy (maxs, clip.maxs2); + } + +// create the bounding box of the entire move + SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); + +// clip to entities + SV_ClipToLinks ( sv_areanodes, &clip ); + + return clip.trace; +} + diff --git a/r17/Revamped src/revamped_src/world.h b/r17/Revamped src/revamped_src/world.h new file mode 100755 index 00000000..d7374f17 --- /dev/null +++ b/r17/Revamped src/revamped_src/world.h @@ -0,0 +1,79 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// world.h + +typedef struct +{ + vec3_t normal; + float dist; +} plane_t; + +typedef struct +{ + qboolean allsolid; // if true, plane is not valid + qboolean startsolid; // if true, the initial point was in a solid area + qboolean inopen, inwater; + float fraction; // time completed, 1.0 = didn't hit anything + vec3_t endpos; // final position + plane_t plane; // surface normal at impact + edict_t *ent; // entity the surface is on +} trace_t; + + +#define MOVE_NORMAL 0 +#define MOVE_NOMONSTERS 1 +#define MOVE_MISSILE 2 + + +void SV_ClearWorld (void); +// called after the world model has been loaded, before linking any entities + +void SV_UnlinkEdict (edict_t *ent); +// call before removing an entity, and before trying to move one, +// so it doesn't clip against itself +// flags ent->v.modified + +void SV_LinkEdict (edict_t *ent, qboolean touch_triggers); +// Needs to be called any time an entity changes origin, mins, maxs, or solid +// flags ent->v.modified +// sets ent->v.absmin and ent->v.absmax +// if touchtriggers, calls prog functions for the intersected triggers + +int SV_PointContents (vec3_t p); +int SV_TruePointContents (vec3_t p); +// returns the CONTENTS_* value from the world at the given point. +// does not check any entities at all +// the non-true version remaps the water current contents to content_water + +edict_t *SV_TestEntityPosition (edict_t *ent); +qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace); + +trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *passedict); +// mins and maxs are reletive + +// if the entire move stays in a solid volume, trace.allsolid will be set + +// if the starting point is in a solid, it will be allowed to move out +// to an open area + +// nomonsters is used for line of sight or edge testing, where mosnters +// shouldn't be considered solid objects + +// passedict is explicitly excluded from clipping checks (normally NULL) diff --git a/r17/Revamped src/revamped_src/zone.c b/r17/Revamped src/revamped_src/zone.c new file mode 100755 index 00000000..42d7c455 --- /dev/null +++ b/r17/Revamped src/revamped_src/zone.c @@ -0,0 +1,935 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +// Z_zone.c + +#include "quakedef.h" + +#define DYNAMIC_SIZE 0xc000 + +#define ZONEID 0x1d4a11 +#define MINFRAGMENT 64 + +typedef struct memblock_s +{ + int size; // including the header and possibly tiny fragments + int tag; // a tag of 0 is a free block + int id; // should be ZONEID + struct memblock_s *next, *prev; + int pad; // pad to 64 bit boundary +} memblock_t; + +typedef struct +{ + int size; // total bytes malloced, including header + memblock_t blocklist; // start / end cap for linked list + memblock_t *rover; +} memzone_t; + +void Cache_FreeLow (int new_low_hunk); +void Cache_FreeHigh (int new_high_hunk); + + +/* +============================================================================== + + ZONE MEMORY ALLOCATION + +There is never any space between memblocks, and there will never be two +contiguous free memblocks. + +The rover can be left pointing at a non-empty block + +The zone calls are pretty much only used for small strings and structures, +all big things are allocated on the hunk. +============================================================================== +*/ + +memzone_t *mainzone; + +void Z_ClearZone (memzone_t *zone, int size); + + +/* +======================== +Z_ClearZone +======================== +*/ +void Z_ClearZone (memzone_t *zone, int size) +{ + memblock_t *block; + +// set the entire zone to one free block + + zone->blocklist.next = zone->blocklist.prev = block = + (memblock_t *)( (byte *)zone + sizeof(memzone_t) ); + zone->blocklist.tag = 1; // in use block + zone->blocklist.id = 0; + zone->blocklist.size = 0; + zone->rover = block; + + block->prev = block->next = &zone->blocklist; + block->tag = 0; // free block + block->id = ZONEID; + block->size = size - sizeof(memzone_t); +} + + +/* +======================== +Z_Free +======================== +*/ +void Z_Free (void *ptr) +{ + memblock_t *block, *other; + + if (!ptr) + Sys_Error ("Z_Free: NULL pointer"); + + block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t)); + if (block->id != ZONEID) + Sys_Error ("Z_Free: freed a pointer without ZONEID"); + if (block->tag == 0) + Sys_Error ("Z_Free: freed a freed pointer"); + + block->tag = 0; // mark as free + + other = block->prev; + if (!other->tag) + { // merge with previous free block + other->size += block->size; + other->next = block->next; + other->next->prev = other; + if (block == mainzone->rover) + mainzone->rover = other; + block = other; + } + + other = block->next; + if (!other->tag) + { // merge the next free block onto the end + block->size += other->size; + block->next = other->next; + block->next->prev = block; + if (other == mainzone->rover) + mainzone->rover = block; + } +} + + +/* +======================== +Z_Malloc +======================== +*/ +void *Z_Malloc (int size) +{ + void *buf; + +Z_CheckHeap (); // DEBUG + buf = Z_TagMalloc (size, 1); + if (!buf) + Sys_Error ("Z_Malloc: failed on allocation of %i bytes",size); + Q_memset (buf, 0, size); + + return buf; +} + +void *Z_TagMalloc (int size, int tag) +{ + int extra; + memblock_t *start, *rover, *new, *base; + + if (!tag) + Sys_Error ("Z_TagMalloc: tried to use a 0 tag"); + +// +// scan through the block list looking for the first free block +// of sufficient size +// + size += sizeof(memblock_t); // account for size of block header + size += 4; // space for memory trash tester + size = (size + 7) & ~7; // align to 8-byte boundary + + base = rover = mainzone->rover; + start = base->prev; + + do + { + if (rover == start) // scaned all the way around the list + return NULL; + if (rover->tag) + base = rover = rover->next; + else + rover = rover->next; + } while (base->tag || base->size < size); + +// +// found a block big enough +// + extra = base->size - size; + if (extra > MINFRAGMENT) + { // there will be a free fragment after the allocated block + new = (memblock_t *) ((byte *)base + size ); + new->size = extra; + new->tag = 0; // free block + new->prev = base; + new->id = ZONEID; + new->next = base->next; + new->next->prev = new; + base->next = new; + base->size = size; + } + + base->tag = tag; // no longer a free block + + mainzone->rover = base->next; // next allocation will start looking here + + base->id = ZONEID; + +// marker for memory trash testing + *(int *)((byte *)base + base->size - 4) = ZONEID; + + return (void *) ((byte *)base + sizeof(memblock_t)); +} + + +/* +======================== +Z_Print +======================== +*/ +void Z_Print (memzone_t *zone) +{ + memblock_t *block; + + Con_Printf ("zone size: %i location: %p\n",mainzone->size,mainzone); + + for (block = zone->blocklist.next ; ; block = block->next) + { + Con_Printf ("block:%p size:%7i tag:%3i\n", + block, block->size, block->tag); + + if (block->next == &zone->blocklist) + break; // all blocks have been hit + if ( (byte *)block + block->size != (byte *)block->next) + Con_Printf ("ERROR: block size does not touch the next block\n"); + if ( block->next->prev != block) + Con_Printf ("ERROR: next block doesn't have proper back link\n"); + if (!block->tag && !block->next->tag) + Con_Printf ("ERROR: two consecutive free blocks\n"); + } +} + + +/* +======================== +Z_CheckHeap +======================== +*/ +void Z_CheckHeap (void) +{ + memblock_t *block; + + for (block = mainzone->blocklist.next ; ; block = block->next) + { + if (block->next == &mainzone->blocklist) + break; // all blocks have been hit + if ( (byte *)block + block->size != (byte *)block->next) + Sys_Error ("Z_CheckHeap: block size does not touch the next block\n"); + if ( block->next->prev != block) + Sys_Error ("Z_CheckHeap: next block doesn't have proper back link\n"); + if (!block->tag && !block->next->tag) + Sys_Error ("Z_CheckHeap: two consecutive free blocks\n"); + } +} + +//============================================================================ + +#define HUNK_SENTINAL 0x1df001ed + +typedef struct +{ + int sentinal; + int size; // including sizeof(hunk_t), -1 = not allocated + char name[8]; +} hunk_t; + +byte *hunk_base; +int hunk_size; + +int hunk_low_used; +int hunk_high_used; + +qboolean hunk_tempactive; +int hunk_tempmark; + +void R_FreeTextures (void); + +/* +============== +Hunk_Check + +Run consistancy and sentinal trahing checks +============== +*/ +void Hunk_Check (void) +{ + hunk_t *h; + + for (h = (hunk_t *)hunk_base ; (byte *)h != hunk_base + hunk_low_used ; ) + { + if (h->sentinal != HUNK_SENTINAL) + Sys_Error ("Hunk_Check: trahsed sentinal"); + if (h->size < 16 || h->size + (byte *)h - hunk_base > hunk_size) + Sys_Error ("Hunk_Check: bad size"); + h = (hunk_t *)((byte *)h+h->size); + } +} + +/* +============== +Hunk_Print + +If "all" is specified, every single allocation is printed. +Otherwise, allocations with the same name will be totaled up before printing. +============== +*/ +void Hunk_Print (qboolean all) +{ + hunk_t *h, *next, *endlow, *starthigh, *endhigh; + int count, sum; + int totalblocks; + char name[9]; + + name[8] = 0; + count = 0; + sum = 0; + totalblocks = 0; + + h = (hunk_t *)hunk_base; + endlow = (hunk_t *)(hunk_base + hunk_low_used); + starthigh = (hunk_t *)(hunk_base + hunk_size - hunk_high_used); + endhigh = (hunk_t *)(hunk_base + hunk_size); + + Con_Printf (" :%8i total hunk size\n", hunk_size); + Con_Printf ("-------------------------\n"); + + while (1) + { + // + // skip to the high hunk if done with low hunk + // + if ( h == endlow ) + { + Con_Printf ("-------------------------\n"); + Con_Printf (" :%8i REMAINING\n", hunk_size - hunk_low_used - hunk_high_used); + Con_Printf ("-------------------------\n"); + h = starthigh; + } + + // + // if totally done, break + // + if ( h == endhigh ) + break; + + // + // run consistancy checks + // + if (h->sentinal != HUNK_SENTINAL) + Sys_Error ("Hunk_Check: trahsed sentinal"); + if (h->size < 16 || h->size + (byte *)h - hunk_base > hunk_size) + Sys_Error ("Hunk_Check: bad size"); + + next = (hunk_t *)((byte *)h+h->size); + count++; + totalblocks++; + sum += h->size; + + // + // print the single block + // + memcpy (name, h->name, 8); + if (all) + Con_Printf ("%8p :%8i %8s\n",h, h->size, name); + + // + // print the total + // + if (next == endlow || next == endhigh || + strncmp (h->name, next->name, 8) ) + { + if (!all) + Con_Printf (" :%8i %8s (TOTAL)\n",sum, name); + count = 0; + sum = 0; + } + + h = next; + } + + Con_Printf ("-------------------------\n"); + Con_Printf ("%8i total blocks\n", totalblocks); + +} + +/* +=================== +Hunk_AllocName +=================== +*/ +void *Hunk_AllocName (int size, char *name) +{ + hunk_t *h; + +#ifdef PARANOID + Hunk_Check (); +#endif + + if (size < 0) + Sys_Error ("Hunk_Alloc: bad size: %i", size); + + size = sizeof(hunk_t) + ((size+15)&~15); + + if (hunk_size - hunk_low_used - hunk_high_used < size) + Sys_Error ("Hunk_Alloc: failed on %i bytes",size); + + h = (hunk_t *)(hunk_base + hunk_low_used); + hunk_low_used += size; + + Cache_FreeLow (hunk_low_used); + + memset (h, 0, size); + + h->size = size; + h->sentinal = HUNK_SENTINAL; + Q_strncpy (h->name, name, 8); + + return (void *)(h+1); +} + +/* +=================== +Hunk_Alloc +=================== +*/ +void *Hunk_Alloc (int size) +{ + return Hunk_AllocName (size, "unknown"); +} + +int Hunk_LowMark (void) +{ + return hunk_low_used; +} + +void Hunk_FreeToLowMark (int mark) +{ + if (mark < 0 || mark > hunk_low_used) + Sys_Error ("Hunk_FreeToLowMark: bad mark %i", mark); + memset (hunk_base + mark, 0, hunk_low_used - mark); + hunk_low_used = mark; +} + +int Hunk_HighMark (void) +{ + if (hunk_tempactive) + { + hunk_tempactive = false; + Hunk_FreeToHighMark (hunk_tempmark); + } + + return hunk_high_used; +} + +void Hunk_FreeToHighMark (int mark) +{ + if (hunk_tempactive) + { + hunk_tempactive = false; + Hunk_FreeToHighMark (hunk_tempmark); + } + if (mark < 0 || mark > hunk_high_used) + Sys_Error ("Hunk_FreeToHighMark: bad mark %i", mark); + memset (hunk_base + hunk_size - hunk_high_used, 0, hunk_high_used - mark); + hunk_high_used = mark; +} + + +/* +=================== +Hunk_HighAllocName +=================== +*/ +void *Hunk_HighAllocName (int size, char *name) +{ + hunk_t *h; + + if (size < 0) + Sys_Error ("Hunk_HighAllocName: bad size: %i", size); + + if (hunk_tempactive) + { + Hunk_FreeToHighMark (hunk_tempmark); + hunk_tempactive = false; + } + +#ifdef PARANOID + Hunk_Check (); +#endif + + size = sizeof(hunk_t) + ((size+15)&~15); + + if (hunk_size - hunk_low_used - hunk_high_used < size) + { + Con_Printf ("Hunk_HighAlloc: failed on %i bytes\n",size); + return NULL; + } + + hunk_high_used += size; + Cache_FreeHigh (hunk_high_used); + + h = (hunk_t *)(hunk_base + hunk_size - hunk_high_used); + + memset (h, 0, size); + h->size = size; + h->sentinal = HUNK_SENTINAL; + Q_strncpy (h->name, name, 8); + + return (void *)(h+1); +} + + +/* +================= +Hunk_TempAlloc + +Return space from the top of the hunk +================= +*/ +void *Hunk_TempAlloc (int size) +{ + void *buf; + + size = (size+15)&~15; + + if (hunk_tempactive) + { + Hunk_FreeToHighMark (hunk_tempmark); + hunk_tempactive = false; + } + + hunk_tempmark = Hunk_HighMark (); + + buf = Hunk_HighAllocName (size, "temp"); + + hunk_tempactive = true; + + return buf; +} + +/* +=============================================================================== + +CACHE MEMORY + +=============================================================================== +*/ + +typedef struct cache_system_s +{ + int size; // including this header + cache_user_t *user; + char name[16]; + struct cache_system_s *prev, *next; + struct cache_system_s *lru_prev, *lru_next; // for LRU flushing +} cache_system_t; + +cache_system_t *Cache_TryAlloc (int size, qboolean nobottom); + +cache_system_t cache_head; + +/* +=========== +Cache_Move +=========== +*/ +void Cache_Move ( cache_system_t *c) +{ + cache_system_t *new; + +// we are clearing up space at the bottom, so only allocate it late + new = Cache_TryAlloc (c->size, true); + if (new) + { +// Con_Printf ("cache_move ok\n"); + + Q_memcpy ( new+1, c+1, c->size - sizeof(cache_system_t) ); + new->user = c->user; + Q_memcpy (new->name, c->name, sizeof(new->name)); + Cache_Free (c->user); + new->user->data = (void *)(new+1); + } + else + { +// Con_Printf ("cache_move failed\n"); + + Cache_Free (c->user); // tough luck... + } +} + +/* +============ +Cache_FreeLow + +Throw things out until the hunk can be expanded to the given point +============ +*/ +void Cache_FreeLow (int new_low_hunk) +{ + cache_system_t *c; + + while (1) + { + c = cache_head.next; + if (c == &cache_head) + return; // nothing in cache at all + if ((byte *)c >= hunk_base + new_low_hunk) + return; // there is space to grow the hunk + Cache_Move ( c ); // reclaim the space + } +} + +/* +============ +Cache_FreeHigh + +Throw things out until the hunk can be expanded to the given point +============ +*/ +void Cache_FreeHigh (int new_high_hunk) +{ + cache_system_t *c, *prev; + + prev = NULL; + while (1) + { + c = cache_head.prev; + if (c == &cache_head) + return; // nothing in cache at all + if ( (byte *)c + c->size <= hunk_base + hunk_size - new_high_hunk) + return; // there is space to grow the hunk + if (c == prev) + Cache_Free (c->user); // didn't move out of the way + else + { + Cache_Move (c); // try to move it + prev = c; + } + } +} + +void Cache_UnlinkLRU (cache_system_t *cs) +{ + if (!cs->lru_next || !cs->lru_prev) + Sys_Error ("Cache_UnlinkLRU: NULL link"); + + cs->lru_next->lru_prev = cs->lru_prev; + cs->lru_prev->lru_next = cs->lru_next; + + cs->lru_prev = cs->lru_next = NULL; +} + +void Cache_MakeLRU (cache_system_t *cs) +{ + if (cs->lru_next || cs->lru_prev) + Sys_Error ("Cache_MakeLRU: active link"); + + cache_head.lru_next->lru_prev = cs; + cs->lru_next = cache_head.lru_next; + cs->lru_prev = &cache_head; + cache_head.lru_next = cs; +} + +/* +============ +Cache_TryAlloc + +Looks for a free block of memory between the high and low hunk marks +Size should already include the header and padding +============ +*/ +cache_system_t *Cache_TryAlloc (int size, qboolean nobottom) +{ + cache_system_t *cs, *new; + +// is the cache completely empty? + + if (!nobottom && cache_head.prev == &cache_head) + { + if (hunk_size - hunk_high_used - hunk_low_used < size) + Sys_Error ("Cache_TryAlloc: %i is greater then free hunk", size); + + new = (cache_system_t *) (hunk_base + hunk_low_used); + memset (new, 0, sizeof(*new)); + new->size = size; + + cache_head.prev = cache_head.next = new; + new->prev = new->next = &cache_head; + + Cache_MakeLRU (new); + return new; + } + +// search from the bottom up for space + + new = (cache_system_t *) (hunk_base + hunk_low_used); + cs = cache_head.next; + + do + { + if (!nobottom || cs != cache_head.next) + { + if ( (byte *)cs - (byte *)new >= size) + { // found space + memset (new, 0, sizeof(*new)); + new->size = size; + + new->next = cs; + new->prev = cs->prev; + cs->prev->next = new; + cs->prev = new; + + Cache_MakeLRU (new); + + return new; + } + } + + // continue looking + new = (cache_system_t *)((byte *)cs + cs->size); + cs = cs->next; + + } while (cs != &cache_head); + +// try to allocate one at the very end + if ( hunk_base + hunk_size - hunk_high_used - (byte *)new >= size) + { + memset (new, 0, sizeof(*new)); + new->size = size; + + new->next = &cache_head; + new->prev = cache_head.prev; + cache_head.prev->next = new; + cache_head.prev = new; + + Cache_MakeLRU (new); + + return new; + } + + return NULL; // couldn't allocate +} + +/* +============ +Cache_Flush + +Throw everything out, so new data will be demand cached +============ +*/ +void Cache_Flush (void) +{ + while (cache_head.next != &cache_head) + Cache_Free ( cache_head.next->user ); // reclaim the space +} + + +/* +============ +Cache_Print + +============ +*/ +void Cache_Print (void) +{ + cache_system_t *cd; + + for (cd = cache_head.next ; cd != &cache_head ; cd = cd->next) + { + Con_Printf ("%8i : %s\n", cd->size, cd->name); + } +} + +/* +============ +Cache_Report + +============ +*/ +void Cache_Report (void) +{ + Con_DPrintf ("%4.1f megabyte data cache\n", (hunk_size - hunk_high_used - hunk_low_used) / (float)(1024*1024) ); +} + +/* +============ +Cache_Compact + +============ +*/ +void Cache_Compact (void) +{ +} + +/* +============ +Cache_Init + +============ +*/ +void Cache_Init (void) +{ + cache_head.next = cache_head.prev = &cache_head; + cache_head.lru_next = cache_head.lru_prev = &cache_head; + + Cmd_AddCommand ("flush", Cache_Flush); +} + +/* +============== +Cache_Free + +Frees the memory and removes it from the LRU list +============== +*/ +void Cache_Free (cache_user_t *c) +{ + cache_system_t *cs; + + if (!c->data) + Sys_Error ("Cache_Free: not allocated"); + + cs = ((cache_system_t *)c->data) - 1; + + cs->prev->next = cs->next; + cs->next->prev = cs->prev; + cs->next = cs->prev = NULL; + + c->data = NULL; + + Cache_UnlinkLRU (cs); +} + + + +/* +============== +Cache_Check +============== +*/ +void *Cache_Check (cache_user_t *c) +{ + cache_system_t *cs; + + if (!c->data) + return NULL; + + cs = ((cache_system_t *)c->data) - 1; + +// move to head of LRU + Cache_UnlinkLRU (cs); + Cache_MakeLRU (cs); + + return c->data; +} + + +/* +============== +Cache_Alloc +============== +*/ +void *Cache_Alloc (cache_user_t *c, int size, char *name) +{ + cache_system_t *cs; + + if (c->data) + Sys_Error ("Cache_Alloc: allready allocated"); + + if (size <= 0) + Sys_Error ("Cache_Alloc: size %i", size); + + size = (size + sizeof(cache_system_t) + 15) & ~15; + +// find memory for it + while (1) + { + cs = Cache_TryAlloc (size, false); + if (cs) + { + strncpy (cs->name, name, sizeof(cs->name)-1); + c->data = (void *)(cs+1); + cs->user = c; + break; + } + + // free the least recently used cahedat + if (cache_head.lru_prev == &cache_head) + Sys_Error ("Cache_Alloc: out of memory"); + // not enough memory at all + Cache_Free ( cache_head.lru_prev->user ); + } + + return Cache_Check (c); +} + +//============================================================================ + + +/* +======================== +Memory_Init +======================== +*/ +void Memory_Init (void *buf, int size) +{ + int p; + int zonesize = DYNAMIC_SIZE; + + hunk_base = buf; + hunk_size = size; + hunk_low_used = 0; + hunk_high_used = 0; + + Cache_Init (); + p = COM_CheckParm ("-zone"); + if (p) + { + if (p < com_argc-1) + zonesize = Q_atoi (com_argv[p+1]) * 1024; + else + Sys_Error ("Memory_Init: you must specify a size in KB after -zone"); + } + mainzone = Hunk_AllocName (zonesize, "zone" ); + Z_ClearZone (mainzone, zonesize); +} + diff --git a/r17/Revamped src/revamped_src/zone.h b/r17/Revamped src/revamped_src/zone.h new file mode 100755 index 00000000..b63006f8 --- /dev/null +++ b/r17/Revamped src/revamped_src/zone.h @@ -0,0 +1,131 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +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. + +*/ +/* + memory allocation + + +H_??? The hunk manages the entire memory block given to quake. It must be +contiguous. Memory can be allocated from either the low or high end in a +stack fashion. The only way memory is released is by resetting one of the +pointers. + +Hunk allocations should be given a name, so the Hunk_Print () function +can display usage. + +Hunk allocations are guaranteed to be 16 byte aligned. + +The video buffers are allocated high to avoid leaving a hole underneath +server allocations when changing to a higher video mode. + + +Z_??? Zone memory functions used for small, dynamic allocations like text +strings from command input. There is only about 48K for it, allocated at +the very bottom of the hunk. + +Cache_??? Cache memory is for objects that can be dynamically loaded and +can usefully stay persistant between levels. The size of the cache +fluctuates from level to level. + +To allocate a cachable object + + +Temp_??? Temp memory is used for file loading and surface caching. The size +of the cache memory is adjusted so that there is a minimum of 512k remaining +for temp memory. + + +------ Top of Memory ------- + +high hunk allocations + +<--- high hunk reset point held by vid + +video buffer + +z buffer + +surface cache + +<--- high hunk used + +cachable memory + +<--- low hunk used + +client and server low hunk allocations + +<-- low hunk reset point held by host + +startup hunk allocations + +Zone block + +----- Bottom of Memory ----- + + + +*/ + +void Memory_Init (void *buf, int size); + +void Z_Free (void *ptr); +void *Z_Malloc (int size); // returns 0 filled memory +void *Z_TagMalloc (int size, int tag); + +void Z_DumpHeap (void); +void Z_CheckHeap (void); +int Z_FreeMemory (void); + +void *Hunk_Alloc (int size); // returns 0 filled memory +void *Hunk_AllocName (int size, char *name); + +void *Hunk_HighAllocName (int size, char *name); + +int Hunk_LowMark (void); +void Hunk_FreeToLowMark (int mark); + +int Hunk_HighMark (void); +void Hunk_FreeToHighMark (int mark); + +void *Hunk_TempAlloc (int size); + +void Hunk_Check (void); + +typedef struct cache_user_s +{ + void *data; +} cache_user_t; + +void Cache_Flush (void); + +void *Cache_Check (cache_user_t *c); +// returns the cached data, and moves to the head of the LRU list +// if present, otherwise returns NULL + +void Cache_Free (cache_user_t *c); + +void *Cache_Alloc (cache_user_t *c, int size, char *name); +// Returns NULL if all purgable data was tossed and there still +// wasn't enough room. + +void Cache_Report (void); + + +