/* * $Header: /HexenWorld/HCode/invntory.hc 39 5/04/98 8:49p Mgummelt $ */ void teleport_touch (void); void PlayerSpeed_Calc (void); void player_fly(void); void player_stopfly(void); void XbowBoltTurn(entity bolt); void PolyTurn(entity bolt); void DrillaTurn(entity bolt); void Use_RingFlight() { if(self.rings&RING_FLIGHT) {//Toggle off, but don't get leftovers! self.ring_flight=self.ring_flight_time=0; self.rings(-)RING_FLIGHT; self.rings_low (-) RING_FLIGHT; player_stopfly(); self.cnt_flight -= 1; } else { self.rings(+)RING_FLIGHT; self.ring_flight = 100; self.ring_flight_time = time + 1; player_fly(); self.rings_low (-) RING_FLIGHT; } } void()monster_imp_lord; void BecomeImp () { float move_cnt; if(other.solid!=SOLID_BSP) return; self.solid=SOLID_NOT; setorigin(self,self.origin+'0 0 50'); setsize(self,'-40 -40 -50','40 40 50'); self.hull=HULL_GOLEM; newmis=spawn(); setorigin(newmis,self.origin); tracearea(self.origin,self.origin+'0 0 1',self.mins,self.maxs,FALSE,newmis); while((trace_fraction<1||trace_allsolid)&&move_cnt<36) { setorigin(newmis,newmis.origin+'0 0 1'); tracearea(newmis.origin,newmis.origin+'0 0 1',self.mins,self.maxs,FALSE,newmis); move_cnt+=1; } if(trace_fraction==1&&!trace_allsolid) { self.touch=SUB_Null; newmis.flags2(+)FL_SUMMONED; newmis.controller=self.owner; newmis.team=self.owner.team; newmis.classname="monster_imp_lord"; newmis.lifetime=time+30; if(self.owner.enemy!=world&&self.owner.enemy.flags2&FL_ALIVE&&visible2ent(self.owner.enemy,self)) { newmis.enemy=newmis.goalentity=self.owner.enemy; newmis.monster_awake=TRUE; } else { newmis.enemy=newmis.goalentity=self.owner; newmis.monster_awake=TRUE; } self.owner.imp_count+=1; newmis.imp_count=self.owner.imp_count; newmis.think=monster_imp_lord; thinktime newmis : 0; sound (newmis, CHAN_AUTO, "weapons/expsmall.wav", 1, ATTN_NORM); sound (newmis, CHAN_VOICE, "imp/upbig.wav", 1, ATTN_NORM); setorigin(self,self.origin-'0 0 50'); BecomeExplosion(CE_FLOOR_EXPLOSION); newmis.hull = HULL_HYDRA; newmis.solid = SOLID_SLIDEBOX; } else { entity oself; setorigin(self,self.origin-'0 0 50'-self.movedir*8); traceline(self.origin+'0 0 10',self.origin-'0 0 100',TRUE,self); sound (newmis, CHAN_BODY, "items/itmspawn.wav", 1, ATTN_NORM); // play respawn sound newmis.classname="art_summon"; setorigin(newmis,trace_endpos+'0 0 50'); CreateWhiteFlash(newmis.origin); oself=self; oself.think=SUB_Remove; thinktime oself : 0; self=newmis; spawn_artifact(ARTIFACT_SUMMON,FALSE); } } void Use_Summoner () { self.attack_finished=time + 0.1;//So you can't have a ton of them makevectors(self.v_angle); //sound entity missile; missile=spawn(); missile.owner=self; missile.classname="summon"; missile.movetype=MOVETYPE_BOUNCE; missile.solid=SOLID_BBOX; missile.touch=BecomeImp; missile.effects=EF_DIMLIGHT; missile.drawflags=MLS_POWERMODE; missile.movedir=normalize(v_forward); missile.velocity=normalize(v_forward)*300 +v_up*100; missile.avelocity=RandomVector('300 300 300'); setmodel (missile, "models/a_summon.mdl"); setsize(missile,'0 0 0','0 0 0'); setorigin(missile,self.origin+self.proj_ofs+v_forward*16); missile.think=BecomeImp; thinktime missile : 1; self.cnt_summon-=1; } /* teleport_coin_run - The entity "teleportcoin" is created when teleport artifact is used */ void teleport_coin_run (void) { //added this for chaos device hangin-around self.touch = teleport_touch; self.think = SUB_Remove; self.nextthink = time + 3.0;//!shorter time, por favor! WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); WriteByte (MSG_BROADCAST, TE_TELEPORT_LINGER); WriteCoord (MSG_BROADCAST, self.origin_x); WriteCoord (MSG_BROADCAST, self.origin_y); WriteCoord (MSG_BROADCAST, self.origin_z); WriteCoord (MSG_BROADCAST, 3.0); //this part was here b4 other = self.enemy; teleport_touch(); } /* Use_teleportCoin - generates an entity that acts like a teleporter trigger which places the player in his startspot or in deathmatch at a random start spot */ void () Use_TeleportCoin = { entity teleport_ent; self.flags2(+)FL_TORNATO_SAFE; teleport_ent = spawn(); teleport_ent.goalentity = SelectSpawnPoint (); teleport_ent.classname = "teleportcoin"; teleport_ent.inactive = FALSE; teleport_ent.think = teleport_coin_run; teleport_ent.nextthink = time + .01; teleport_ent.spawnflags = 1;//player_only, that is. self.cnt_teleport -= 1; teleport_ent.enemy = self; //added this for chaos device hangin-around setorigin (teleport_ent, self.origin); teleport_ent.movetype = MOVETYPE_NONE; teleport_ent.solid = SOLID_TRIGGER; teleport_ent.takedamage = DAMAGE_NO; setsize(teleport_ent,'-16 -16 0','16 16 56'); // setmodel (teleport_ent, "models/sheep.mdl");//uncomment if tempent not working to see where teleport is supposed to be }; void wedge_run(void) { if ((self.owner.velocity_x == 0) && (self.owner.velocity_y == 0) && (self.owner.velocity_z == 0)) self.effects(+)EF_NODRAW; // All stop else if (self.effects & EF_NODRAW) self.effects(-)EF_NODRAW; self.angles = vectoangles(self.owner.velocity); self.origin = self.owner.origin; self.think = wedge_run; //self.nextthink = time + HX_FRAME_TIME; self.nextthink = time + .04; // This faster time is because it would lag behind every once in a while if ((self.owner.health<=0) || !(self.owner.artifact_active & ART_HASTE)) remove(self); } /* void launch_hastewedge (void) { local entity tail; tail = spawn (); tail.movetype = MOVETYPE_NOCLIP; tail.solid = SOLID_NOT; tail.classname = "haste_wedge"; setmodel (tail, "models/wedge.mdl"); setsize (tail, '0 0 0', '0 0 0'); tail.drawflags(+)DRF_TRANSLUCENT; tail.owner = self; tail.origin = tail.owner.origin; tail.velocity = tail.owner.velocity; tail.angles = tail.owner.angles; tail.think = wedge_run; tail.nextthink = time + HX_FRAME_TIME; } */ void Use_TomeofPower (void) { if(self.model=="models/sheep.mdl") self.sheep_time=0; else { if((tomeMode == 1)||(tomeMode == 2)) { // does nothing but sheep stuff... return; } self.artifact_active = self.artifact_active | ART_TOMEOFPOWER; self.tome_time = time + TOME_TIME; } self.cnt_tome -= 1; } void () Use_Haste = { self.artifact_active = self.artifact_active | ART_HASTE; self.haste_time = time + TOME_TIME; // launch_hastewedge (); self.effects(+)EF_DARKFIELD; PlayerSpeed_Calc(); self.cnt_haste -= 1; }; /* ============ Use_ProximityMine ============ */ void proximity_explode() { T_RadiusDamage (self, self.owner, self.dmg, world); WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_TIME_BOMB); WriteCoord (MSG_MULTICAST, self.origin_x); WriteCoord (MSG_MULTICAST, self.origin_y); WriteCoord (MSG_MULTICAST, self.origin_z); multicast(self.origin,MULTICAST_PHS); remove(self); } void proximity_think () { float okay; thinktime self : 0.1; if(self.lifetime120) newmis.dmg=120; newmis.health=10; newmis.takedamage=DAMAGE_YES; newmis.touch=newmis.th_die=proximity_explode; newmis.angles_x=90; newmis.avelocity_y=100; newmis.skin=1; newmis.drawflags(+)MLS_POWERMODE; setmodel (newmis, "models/glyphwir.mdl"); setsize(newmis,'-3 -3 -3','3 3 3'); newmis.hull=HULL_POINT; setorigin(newmis,self.origin+self.proj_ofs); newmis.lifetime=time+30; newmis.think=proximity_think; thinktime newmis : 0; } /* ============ UseTimebomb ============ */ void TimeBombExplode() { WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_TIME_BOMB); WriteCoord (MSG_MULTICAST, self.origin_x); WriteCoord (MSG_MULTICAST, self.origin_y); WriteCoord (MSG_MULTICAST, self.origin_z); multicast(self.origin,MULTICAST_PHS); T_RadiusDamage(self, self.owner, 140.0, self.owner); remove(self); } void TimeBombTouch() { if((other == self.owner)||(other == world)||(!(other.takedamage))) { return; } TimeBombExplode(); } void TimeBombThink() { vector destination; /* float dist; float vel; // move around and stay close to the owner. dist = vlen(self.owner.origin - self.origin); if(dist > 160) { // teleport into place self.origin = self.owner.origin + normalize(self.origin - self.owner.origin)*120 + '0 0 20'; } else if(dist > 80) { vel = vlen(self.owner.velocity); self.velocity = normalize(self.owner.origin + '0 0 20' - self.origin)*vel; } else { self.velocity_x = 0; self.velocity_y = 0; self.velocity_z = 0; } */ // self.health is a constant value that adds a good randomness for multiple bombs... destination_x = self.owner.origin_x + cos(time*200 + self.health*100) * 90; destination_y = self.owner.origin_y + sin(time*200 + self.health*100) * 90; destination_z = self.owner.origin_z + cos(time*300 + self.health*100) * 20 + 36; self.origin = destination; //self.velocity_x = (destination_x - self.origin_x)/.05; //self.velocity_y = (destination_y - self.origin_y)/.05; //self.velocity_z = (destination_z - self.origin_z)/.05; // run out if too long if(time > self.health + 10.0) { TimeBombExplode(); } thinktime self : 0.05; } void Use_TimeBomb() { newmis=spawn(); newmis.owner=self; newmis.enemy=world; newmis.classname="timebomb"; newmis.solid=SOLID_BBOX; newmis.dmg=50; newmis.touch=TimeBombTouch; newmis.angles_x=90; newmis.avelocity_y=100; newmis.skin=1; newmis.drawflags(+)MLS_ABSLIGHT; newmis.abslight=0.5; setmodel (newmis, "models/glyphwir.mdl"); setsize(newmis,'0 0 0','0 0 0'); setorigin(newmis,self.origin+self.proj_ofs); newmis.movetype=MOVETYPE_FLYMISSILE; newmis.think=TimeBombThink; thinktime newmis : 0.05; newmis.health = time; } /* ============ Anything which can change a velocity of a client effect missile must call this function ============ */ void UpdateMissileVelocity(entity missile) { if((missile.flags & EF_NODRAW)||(missile.model == "")) { //if nodraw, it is probably a client effect and needs updating if((missile.classname == "magic missile")|| (missile.classname == "bone_powered")|| (missile.classname == "bone_shrapnel")|| (missile.classname == "bone_normal")) { turneffect(missile.wrq_effect_id, missile.origin, missile.velocity); } else if ((missile.classname == "bird_missile")|| (missile.classname == "set_missile")) { turneffect(missile.raven_effect_id, missile.origin, missile.velocity); } else if ((missile.classname == "flaming arrow")|| (missile.classname == "bolt")) { XbowBoltTurn(missile); } else if (missile.classname == "polyblob") { PolyTurn(missile); } else if (missile.classname == "pincer") { DrillaTurn(missile); } } } /* ============ UseBlast ============ */ void UseBlast (void) { vector dir,holdpos; entity victim; float v_length,push,percent,points,inertia; self.cnt_blast -= 1;//moved this up here--doing damage to other things can //trigger an explosion and kill me, so if i decriment count after that, i might end up with -1 discs. victim = findradius( self.origin, BLAST_RADIUS*2); // self.safe_time=time+7; while(victim) { if(victim.classname=="cube_of_force"&&victim.controller!=self&&random()<0.2) { if(victim.artifact_flags&AFL_CUBE_RIGHT) victim.controller.artifact_flags(-)AFL_CUBE_RIGHT; if(victim.artifact_flags&AFL_CUBE_LEFT) victim.controller.artifact_flags(-)AFL_CUBE_LEFT; victim.frags=2; victim.movetype=MOVETYPE_BOUNCE; stopSound(victim,0); victim.owner = victim.controller = self; victim.velocity = normalize(victim.origin - (self.absmin+self.absmax)*0.5)*600; victim.avelocity=randomv('-300 -300 -300','300 300 300'); if(victim.movedir!='0 0 0') victim.movedir=normalize(victim.velocity); victim.dmg=75; victim.touch = GrenadeTouch2; victim.think = MultiExplode; thinktime victim : 3; holdpos = victim.origin; holdpos_z += (victim.maxs_z - victim.mins_z)/2; traceline(self.origin,holdpos,FALSE,self); CreateBlueFlash(trace_endpos); } else if (victim.classname!="hook"&&victim.owner.classname != "circfire" && victim.classname != "cube_of_force"&&victim.monsterclass 3) percent = 3; if (victim.mass>20) inertia = victim.mass/20; else inertia = 1; push = (percent + 1)/inertia; victim.velocity = dir * push; victim.flags(-)FL_ONGROUND; push = ((percent * 100) + 100)/inertia; victim.velocity_z = push; UpdateMissileVelocity(victim); } } else { victim.frags=2; //if(victim.classname=="pincer") // victim.enemy=victim.owner; victim.enemy=victim.owner; victim.owner = self; if (victim.classname!="tornato") { victim.velocity = victim.velocity * -1; victim.angles = vectoangles(victim.velocity); UpdateMissileVelocity(victim); } } holdpos = victim.origin; holdpos_z += (victim.maxs_z - victim.mins_z)/2; traceline(self.origin,holdpos,FALSE,self); CreateBlueFlash(trace_endpos); points = percent * BLASTDAMAGE; // Minimum blast damage if (points > 10) points = 10; //Bad idea- if someone uses a blast radius on a player and that player falls in //the lava 10 minutes later without being hurt by another player in the //meantime, original player gets credit- not good. // if(victim.classname=="player") // if(!victim.artifact_active&ARTFLAG_FROZEN) // victim.credit_enemy=self; T_Damage (victim, self, self, points); } } } if (victim.classname=="tornato" && victim.enemy.flags2&FL_ALIVE) victim.enemy.flags2(+)FL_TORNATO_SAFE; // if(victim.classname=="swarm") // { // victim.think=hive_die; // thinktime victim : 0; // } victim = victim.chain; } if(self.v_angle_x > 30) { if(self.artifact_active & ART_TOMEOFPOWER) { self.velocity_z += 500 * sin(self.v_angle_x); } else { self.velocity_z += 300 * sin(self.v_angle_x); } } } void UseInvincibility (void) { self.artifact_active = self.artifact_active | ART_INVINCIBILITY; if(deathmatch) self.invincible_time = time + TOME_TIME; else self.invincible_time = time + 10; if (self.artifact_low & ART_INVINCIBILITY) self.artifact_low = self.artifact_low - (self.artifact_low & ART_INVINCIBILITY); //Temp invincibility effects if(self.playerclass==CLASS_CRUSADER) self.skin = GLOBAL_SKIN_STONE; else if(self.playerclass==CLASS_PALADIN) self.effects(+)EF_BRIGHTLIGHT; else if(self.playerclass==CLASS_ASSASSIN) self.colormap=140; else if(self.playerclass==CLASS_NECROMANCER) self.effects(+)EF_DARKLIGHT; else if(self.playerclass==CLASS_SUCCUBUS) { self.drawflags(+)MLS_ABSLIGHT; self.effects(+)EF_INVINC_CIRC; self.abslight=0.75; } self.cnt_invincibility -= 1; } void UseInvisibility (void) { centerprint(self,"You are Invisible!\n"); self.artifact_active = self.artifact_active | ART_INVISIBILITY; self.invisible_time = time + 45;//was TOME_TIME (30) if (self.artifact_low & ART_INVISIBILITY) self.artifact_low = self.artifact_low - (self.artifact_low & ART_INVISIBILITY); msg_entity=self; WriteByte(MSG_ONE, SVC_SET_VIEW_FLAGS); WriteByte(MSG_ONE,DRF_TRANSLUCENT); self.effects(+)EF_NODRAW|EF_LIGHT; self.cnt_invisibility -= 1; } void()Use_Polymorph; void()Use_Tripwire; void()Use_Fireball; void poisong_die() { dprint("Poisong_die\n"); stopSound(self,0); SmallExplosion(); } void SpewPoison () { //vector updir; if(self.solid!=SOLID_PHASE) { setsize(self,'-3 -3 -3','3 3 3'); self.solid=SOLID_PHASE; } if(self.owner.tripwire_cnt>self.tripwire_cnt+4) self.lifetime=0; if(self.lifetime==-1) self.lifetime=time + 30; else if(self.lifetime=5)) { spawn_artifact(ARTIFACT_GLYPH,NO_RESPAWN); if(holdent.playerclass==CLASS_CRUSADER) holdent.cnt_glyph -=5; else holdent.cnt_glyph -=1; throwflag = 1; } else if ((holdent.inventory == INV_HASTE) && (holdent.cnt_haste)) { spawn_artifact(ARTIFACT_HASTE,NO_RESPAWN); holdent.cnt_haste -=1; throwflag = 1; } else if ((holdent.inventory == INV_BLAST) && (holdent.cnt_blast)) { spawn_artifact(ARTIFACT_BLAST,NO_RESPAWN); holdent.cnt_blast -=1; throwflag = 1; } else if ((holdent.inventory == INV_POLYMORPH) && (holdent.cnt_polymorph)) { spawn_artifact(ARTIFACT_POLYMORPH,NO_RESPAWN); holdent.cnt_polymorph -=1; throwflag = 1; } else if ((holdent.inventory == INV_FLIGHT) && ((holdent.cnt_flight > 0 && !(holdent.rings&RING_FLIGHT))||//if we have just 1 left, and it's in use, don't drop it (holdent.cnt_flight > 1))) { spawn_artifact(ARTIFACT_FLIGHT,NO_RESPAWN); holdent.cnt_flight -=1; throwflag = 1; } else if ((holdent.inventory == INV_CUBEOFFORCE) && (holdent.cnt_cubeofforce)) { spawn_artifact(ARTIFACT_CUBEOFFORCE,NO_RESPAWN); holdent.cnt_cubeofforce -=1; throwflag = 1; } else if ((holdent.inventory == INV_INVINCIBILITY) && (holdent.cnt_invincibility)) { spawn_artifact(ARTIFACT_INVINCIBILITY,NO_RESPAWN); holdent.cnt_invincibility -=1; throwflag = 1; } self = holdent; if (throwflag) // Something could be thrown { // Throw it item.velocity = normalize (v_forward); item.velocity = item.velocity * 200; item.velocity_x += random(-20,20); // So they don't land on top if each other if player is item.velocity_y += random(-20,20); // standing in one place and throwing multiple items item.velocity_z = 200; makevectors(self.v_angle); setorigin(item,self.origin + self.proj_ofs + v_up * 10 + v_forward * 40 + v_right * 8); sound(self,CHAN_BODY,"misc/whoosh.wav",1,ATTN_NORM); } else remove(item); } void Inventory_Quick(float which) { float old_inv; old_inv = self.inventory; self.inventory = which; UseInventoryItem(); self.inventory = old_inv; }