home *** CD-ROM | disk | FTP | other *** search
-
- void () Wisp_Die;
- void (entity attacker, float damage) Wisp_Pain;
- void () WispImpulses;
- void () WispToggleView;
- void () WispToggleHalt;
- void () WispThink;
- void () WispAttack;
- void () WispApproach;
- void () WispHunt;
- entity () WispFindTarget;
- void () WispReset;
- void () WispActivate;
- void () WispDeactivate;
- void () WispToggle;
- void (entity tgt) WispFire;
- void () WispRecall;
-
- void (vector p1, vector p2, entity from, float damage) LightningDamage;
- void () BecomeExplosion;
-
- void (vector org) spawn_tfog;
-
- void () Wisp_Die =
- {
- if(self.owner.wisp_view==TRUE)
- WispToggleView();
- sprint(self.owner,"Wisp has died!\n");
- self.owner.wisp_flag=FALSE;
- // Detonate wisp when it dies
- 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();
- };
-
- void (entity attacker, float damage) Wisp_Pain =
- {
- local string stemp;
- sprint(self.owner,"Wisp: hit by ");
- if(attacker.classname=="player")
- sprint(self.owner,attacker.netname);
- else
- sprint(self.owner,attacker.classname);
- stemp=ftos(self.health);
- sprint(self.owner,", health ");
- sprint(self.owner,stemp);
- sprint(self.owner,"\n");
- };
-
- void () WispImpulses =
- {
- if(self.impulse==100) // Summon/banish wisp
- WispToggle();
- if(self.impulse==101) // Teleport wisp to self
- WispRecall();
- if(self.impulse==102) // Freeze/unfreeze wisp
- WispToggleHalt();
- if(self.impulse==103) // Hitch a ride/drop off
- WispToggleView();
- };
-
- void () WispToggleView =
- {
- if(self.wisp_flag==FALSE)
- {
- sprint(self,"Wisp hasn't been summoned.\n");
- return;
- }
- if(self.wisp_view==FALSE)
- {
- setorigin(self,self.wisp.origin);
- self.movetype=MOVETYPE_FLY;
- self.wisp_view=TRUE;
- }
- else
- {
- self.movetype=MOVETYPE_WALK;
- self.wisp_view=FALSE;
- }
- };
-
- void () WispToggleHalt =
- {
- if(self.wisp_state==WISP_HALT)
- self.wisp_state=WISP_HUNT;
- else
- {
- self.wisp_state=WISP_HALT;
- self.wisp.velocity='0 0 0';
- }
- };
-
- void () WispThink =
- {
- local float ftemp;
- if(self.owner.wisp_stuck==TRUE)
- { // if wisp was unstuck, restore bounding box
- ftemp=vlen(self.origin-self.owner.wisp_porg);
- if(ftemp>=10)
- {
- setsize(self,'-4 -4 -4','4 4 4');
- self.owner.wisp_stuck=FALSE;
- }
- }
- if(self.owner.wisp_porg==self.origin && self.owner.wisp_state!=WISP_HALT)
- { // if wisp is stuck, try to unstuck by eliminating bounding box
- setsize(self,'0 0 0','0 0 0');
- self.owner.wisp_stuck=TRUE;
- // sprint(self.owner,"UNSTUCKING WISP\n");
- }
- self.owner.wisp_porg=self.origin; // save previous origin for stuck detection
- if(self.owner.wisp_view==TRUE)
- { // update position after wisp if being carried
- setorigin(self.owner,self.origin);
- }
- if(self.owner.wisp_state==WISP_HUNT)
- WispHunt();
- else
- if(self.owner.wisp_state==WISP_APPROACH)
- WispApproach();
- else
- if(self.owner.wisp_state==WISP_ATTACK)
- WispAttack();
- self.nextthink=time+0.1;
- self.think=WispThink;
- };
-
- void () WispAttack =
- {
- if(self.enemy.health<1 || !(self.enemy))
- self.owner.wisp_state=WISP_HUNT; // no valid enemy, go hunt
- else
- {
- traceline(self.origin,self.enemy.origin,TRUE,self);
- if(trace_fraction==1.0)
- {
- self.velocity='0 0 0';
- WispFire(self.enemy);
- }
- else
- self.owner.wisp_state=WISP_HUNT; // enemy not in sight, go hunt
- }
- self.think=WispThink;
- self.nextthink=time+0.1;
- };
-
- void () WispApproach =
- {
- local float ftemp;
- local vector vtemp,dir;
- if(self.enemy != world)
- {
- traceline(self.origin,self.enemy.origin,TRUE,self);
- if(trace_fraction==1.0 && !(self.enemy.health<1 || !(self.enemy)))
- {
- ftemp=vlen(self.enemy.origin-self.origin);
- if(ftemp>300)
- { // far from enemy, approach
- vtemp=self.enemy.origin+'0 0 10';
- dir=normalize(vtemp-self.origin);
- self.velocity=dir*200;
- self.angles=vectoangles(self.velocity);
- }
- else // near to enemy, attack
- self.owner.wisp_state=WISP_ATTACK;
- }
- else // no valid enemy in sight, go hunt
- self.owner.wisp_state=WISP_HUNT;
- }
- else // won't attack the world, go hunt
- self.owner.wisp_state=WISP_HUNT;
- };
-
- void () WispHunt =
- {
- local float r,mf;
- local float dist=300;
- local float offset;
- local float spd;
- local vector ang,sel;
-
- self.enemy=WispFindTarget();
- if(self.enemy)
- { // enemy found, approach
- self.owner.wisp_state=1;
- return;
- }
- makevectors(self.angles);
- traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
- if(trace_fraction<1.0)
- { // approaching obstacle
- offset=90-trace_fraction*80;
- spd=(trace_fraction)*200; // reduce speed as we get nearer
- if(trace_fraction*dist<=50)
- { // wisp is very near obstacle, panic move (90 degrees)
- offset=90;
- sprint(self.owner,"Wisp halted!\n");
- }
- mf=0;
- ang=self.angles;
- ang_x=anglemod(ang_x+offset);
- makevectors(ang);
- traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
- if(trace_fraction>mf)
- {
- mf=trace_fraction;
- sel=ang;
- }
- ang=self.angles;
- ang_x=anglemod(ang_x-offset);
- makevectors(ang);
- traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
- if(trace_fraction>mf)
- {
- mf=trace_fraction;
- sel=ang;
- }
- ang=self.angles;
- ang_x=anglemod(ang_x+offset);
- ang_y=anglemod(ang_y+offset);
- makevectors(ang);
- traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
- if(trace_fraction>mf)
- {
- mf=trace_fraction;
- sel=ang;
- }
- ang=self.angles;
- ang_x=anglemod(ang_x+offset);
- ang_y=anglemod(ang_y-offset);
- makevectors(ang);
- traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
- if(trace_fraction>mf)
- {
- mf=trace_fraction;
- sel=ang;
- }
- ang=self.angles;
- ang_y=anglemod(ang_y+offset);
- makevectors(ang);
- traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
- if(trace_fraction>mf)
- {
- mf=trace_fraction;
- sel=ang;
- }
- ang=self.angles;
- ang_y=anglemod(ang_y-offset);
- makevectors(ang);
- traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
- if(trace_fraction>mf)
- {
- mf=trace_fraction;
- sel=ang;
- }
- ang=self.angles;
- ang_x=anglemod(ang_x-offset);
- ang_y=anglemod(ang_y+offset);
- makevectors(ang);
- traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
- if(trace_fraction>mf)
- {
- mf=trace_fraction;
- sel=ang;
- }
- ang=self.angles;
- ang_x=anglemod(ang_x-offset);
- ang_y=anglemod(ang_y+offset);
- makevectors(ang);
- traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
- if(trace_fraction>mf)
- {
- mf=trace_fraction;
- sel=ang;
- }
- ang=self.angles;
- makevectors(ang);
- traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
- if(trace_fraction>mf)
- {
- mf=trace_fraction;
- sel=ang;
- }
- self.angles=sel;
- makevectors(sel);
- self.velocity=v_forward*spd;
- }
- else
- { // no obstacle in sight, change course a little, but unpredictably
- ang=self.angles;
- r=random()*10 - 5;
- ang_x=anglemod(ang_x+r);
- r=random()*10 - 5;
- ang_y=anglemod(ang_y+r);
- self.angles=ang;
- makevectors(ang);
- self.velocity=v_forward*200;
- }
- self.think=WispThink;
- self.nextthink=time+0.1;
- };
-
- entity () WispFindTarget =
- { // Find nearest valid target
- local entity head, selected;
- local float dist;
- dist = 100000;
- selected = world;
- head = findradius(self.origin, 100000);
- while(head)
- {
- if( (head.health > 1) && (head != self) && (head != self.owner) && head.classname != "door" && head.classname != "monster_zombie")
- {
- traceline(self.origin,head.origin,TRUE,self);
- if ( (trace_fraction >= 1) && (vlen(head.origin - self.origin) < dist) )
- {
- selected = head;
- dist = vlen(head.origin - self.origin);
- }
- }
- head = head.chain;
- }
- if (selected != world)
- {
- sprint (self.owner,"Wisp: attacking ");
- if (selected.classname == "player")
- sprint (self.owner,selected.netname);
- else
- sprint (self.owner,selected.classname);
- sprint (self.owner,"\n");
- }
- return selected;
- };
-
- void () WispReset =
- {
- self.wisp_state=WISP_HUNT;
- self.wisp.enemy=world;
- self.wisp.angles=self.angles;
- };
-
- void () WispActivate =
- {
- local entity newwisp;
- newwisp=spawn();
- newwisp.solid=SOLID_BBOX;
- newwisp.movetype=MOVETYPE_FLY;
- newwisp.classname="wisp";
- newwisp.owner=self;
-
- self.wisp=newwisp;
- self.wisp_flag=TRUE;
- newwisp.th_pain=Wisp_Pain;
- newwisp.th_die=Wisp_Die;
- newwisp.takedamage=TRUE;
- self.wisp_stuck=FALSE;
- self.wisp_porg='0 0 0';
- self.wisp_view=FALSE;
- WispReset();
- newwisp.health=60;
- newwisp.takedamage=DAMAGE_AIM;
- setmodel(newwisp,"progs/lavaball.mdl");
- setsize(newwisp,'-4 -4 -4','4 4 4');
- // setsize(newwisp,'0 0 0','0 0 0');
- setorigin(newwisp,self.origin+'0 0 16');
-
- spawn_tfog(newwisp.origin);
- sprint(self,"Wisp summoned!\n");
- newwisp.nextthink=time+0.1;
- newwisp.think=WispThink;
- };
-
- void () WispDeactivate =
- {
- if(self.owner.wisp_view==TRUE)
- WispToggleView();
- spawn_tfog(self.wisp.origin);
- self.wisp.nextthink=time+0.1;
- self.wisp.think=SUB_Remove;
- self.wisp_flag=FALSE;
- sprint(self,"Wisp Banished!\n");
- };
-
- void () WispToggle =
- {
- if(self.wisp_flag)
- WispDeactivate();
- else
- WispActivate();
- };
-
- void (entity tgt) WispFire =
- { // Fire lightning at enemy
- local vector org;
- sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
- org=self.origin;
-
- 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(org,self.enemy.origin,self,5);
- };
-
- void () WispRecall =
- { // Teleport wisp to self
- if(!self.wisp_flag)
- {
- sprint(self,"Wisp hasn't been summoned.\n");
- return;
- }
- spawn_tfog(self.wisp.origin);
- setorigin(self.wisp,self.origin+'0 0 16');
- spawn_tfog(self.wisp.origin);
- self.wisp_stuck=FALSE;
- self.wisp_porg='0 0 0';
- self.wisp.think=WispThink;
- self.wisp.nextthink=time+0.1;
- WispReset();
- };
-
-