vector(vector source,vector normal) R_Vector = { local vector reflection; reflection = source + 2*normal; if (reflection_x > 1) reflection_x = 2 - reflection_x; if (reflection_x < -1) reflection_x = -2 - reflection_x; if (reflection_y > 1) reflection_y = 2 - reflection_y; if (reflection_y < -1) reflection_y = -2 - reflection_y; if (reflection_z > 1) reflection_z = 2 - reflection_z; if (reflection_z < -1) reflection_z = -2 - reflection_z; return reflection; }; void() SmartScan; void() SmartHLV = { T_RadiusDamage (self, self.owner, 50, world, "dart"); RadiusEffects(self, self.owner, 100, "poison", self, self.owner); muzzleflash(); sound(self, CHAN_WEAPON, "dart/dartimpact.wav", 1, ATTN_NORM); // don't want this to explode /* WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); WriteByte (MSG_BROADCAST, TE_EXPLOSION); WriteCoord (MSG_BROADCAST, self.origin_x); WriteCoord (MSG_BROADCAST, self.origin_y); WriteCoord (MSG_BROADCAST, self.origin_z); */ // BecomeExplosion (); remove(self); }; void() REFLECT = { local vector p1; local vector p2; local vector v; local float oldveloc; v = self.movedir; oldveloc = vlen(v); v = normalize(v); p1 = self.origin - 20*v; p2 = self.origin + 20*v; traceline (p1, p2, true, self); p1 = R_Vector(v, trace_plane_normal); self.flags = self.flags - (self.flags & FL_ONGROUND); self.velocity = p1*oldveloc; self.angles = vectoangles(self.velocity); self.movedir = self.velocity; if (self.health < time) { SmartHLV (); return; } self.think = SmartScan; self.nextthink = time + 0.1; }; void() T_SmartTouch = { local float damg; if (other.classname == "worldspawn" || other.classname == "door" || other.classname == "train" || other.classname == "plat" || other.classname == "func_button") { self.think = REFLECT; self.nextthink = time + 0.1; sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); return; } if (other == self.owner) return; if (pointcontents(self.origin) == CONTENT_SKY) { remove(self); return; } SmartHLV (); }; void() SmartGetEnemy = { local entity targ; targ = findradius(self.origin, 1000); while (targ) { if (targ.takedamage == DAMAGE_AIM) { if (targ.health > 0) { if (targ != self) { if (targ != self.owner) { if (targ.owner != self.owner) { traceline (self.origin, targ.origin + '0 0 16', false, self); if (trace_ent == targ || targ == self.owner) { self.enemy = targ; return; } } } } } } targ = targ.chain; } }; void() SmartScan = { // CQ // sounding out the dart // if(time >= dartsoundtime) // { sound(self, CHAN_AUTO, "dart/darttrav.wav", 1, ATTN_NORM); // dartsoundtime = time + 0.1; // } // CQ local vector dir; local float spd; if (self.health < time) { SmartHLV (); return; } self.nextthink = time + 0.1; if (self.enemy == world) { if (self.frags < time) { self.frags = time + 0.3; SmartGetEnemy (); } } if (self.enemy != world) { if (self.enemy.health <= 0 || self.enemy.deadflag != DEAD_NO) { self.enemy = world; self.frags = 0; return; } if (self.frags < time) { self.frags = time + 0.5; traceline (self.origin, self.enemy.origin + '0 0 16', false, self); if (trace_ent != self.enemy) { self.enemy = world; self.frags = 0; return; } } dir = self.origin - self.enemy.origin + '0 0 16'; dir = normalize(dir); dir = dir*random()*350; self.velocity = self.velocity - dir; } spd = vlen(self.velocity); if (spd > 350) { self.velocity = normalize(self.velocity); self.velocity = self.velocity * 350; } self.movedir = self.velocity; }; void() FireDart = { local entity missile, mpuff; // CQ // check for bots or players /* if(self.classname != "player") { if(self.NumberOfDarts < 1) return; } else */ if(self.DartsAndShields.NumberOfDarts < 1) { sprint(self, 1, "Only five darts per level\n"); return; } if(self.ammo_rockets < 10 || self.ammo_cells < 10) { sprint(self, 1, "Not enough ammo to launch a saberdart!\n"); return; } self.ammo_cells = self.ammo_cells - 10; // self.NumberOfDarts = self.NumberOfDarts - 1; self.DartsAndShields.NumberOfDarts = self.DartsAndShields.NumberOfDarts - 1; // CQ self.currentammo = self.ammo_rockets = self.ammo_rockets - 10; self.currentammo = floor(self.ammo_rockets / 10); sound (self, CHAN_WEAPON, "dart/dart.wav", 1, ATTN_NORM); // CQ sound (self, CHAN_AUTO, "dart/darttrav.wav", 1, ATTN_NORM); // does not work with current code version or engine // self.punchangle_x = -2; // CQ missile = spawn (); missile.owner = self; missile.movetype = MOVETYPE_FLYMISSILE; missile.solid = SOLID_BBOX; missile.classname = "dart"; // set missile speed makevectors (self.v_angle); missile.velocity = v_forward * 600; missile.angles = vectoangles(missile.velocity); missile.enemy = world; missile.frags = 0; missile.touch = T_SmartTouch; // set missile duration missile.health = time + 10; missile.nextthink = time + 0.1; missile.think = SmartScan; setmodel (missile, "progs/s_light.spr"); setsize (missile, '0 0 0', '0 0 0'); setorigin (missile, self.origin + v_forward*8 + '0 0 16'); }