as released 1998-06-24

This commit is contained in:
archive 1998-06-24 00:00:00 +00:00
commit 9dc55483c0
181 changed files with 90357 additions and 0 deletions

1222
MG_AI.hc Normal file

File diff suppressed because it is too large Load Diff

522
acidorb.hc Normal file
View File

@ -0,0 +1,522 @@
/*
==============================================================================
Q:\art\models\weapons\spllbook\spllbook.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\weapons\spllbook
$origin 0 0 0
$base BASE skin
$skin skin
$flags 0
//
$frame idlebn01 idlebn02 idlebn03 idlebn04 idlebn05
$frame idlebn06 idlebn07 idlebn08 idlebn09 idlebn10
$frame idlebn11 idlebn12 idlebn13 idlebn14 idlebn15
$frame idlebn16 idlebn17 idlebn18 idlebn19 idlebn20
$frame idlebn21 idlebn22 idlebn23 idlebn24 idlebn25
//
$frame idlean26 idlean27 idlean28 idlean29 idlean30
$frame idlean31 idlean32 idlean33 idlean34 idlean35
$frame idlean36 idlean37 idlean38 idlean39 idlean40
$frame idlean41 idlean42 idlean43 idlean44 idlean45
$frame idlean46 idlean47 idlean48 idlean49 idlean50
//
$frame normal51 normal52 normal53 normal54 normal55
$frame normal56 normal57 normal58 normal59 normal60
$frame normal61 normal62 normal63 normal64
//
$frame topowr65 topowr66 topowr67 topowr68 topowr69
$frame topowr70 topowr71 topowr72 topowr73 topowr74
$frame topowr75 topowr76 topowr77 topowr78 topowr79
$frame topowr80 topowr81 topowr82 topowr83 topowr84
//
$frame pidleb085 pidleb086 pidleb087 pidleb088 pidleb089
$frame pidleb090 pidleb091 pidleb092 pidleb093 pidleb094
$frame pidleb095 pidleb096 pidleb097 pidleb098 pidleb099
$frame pidleb100 pidleb101 pidleb102 pidleb103 pidleb104
$frame pidleb105 pidleb106 pidleb107 pidleb108 pidleb109
//
$frame pidlea110 pidlea111 pidlea112 pidlea113 pidlea114
$frame pidlea115 pidlea116 pidlea117 pidlea118 pidlea119
$frame pidlea120 pidlea121 pidlea122 pidlea123 pidlea124
$frame pidlea125 pidlea126 pidlea127 pidlea128 pidlea129
$frame pidlea130 pidlea131 pidlea132 pidlea133 pidlea134
//
$frame powern135 powern136 powern137 powern138 powern139
$frame powern140 powern141 powern142 powern143 powern144
$frame powern145 powern146 powern147 powern148
//
$frame tonrml149 tonrml150 tonrml151 tonrml152 tonrml153
$frame tonrml154 tonrml155 tonrml156 tonrml157 tonrml158
$frame tonrml159 tonrml160 tonrml161 tonrml162 tonrml163
$frame tonrml164 tonrml165 tonrml166 tonrml167 tonrml168
//
$frame ndesel213 ndesel214 ndesel215 ndesel216 ndesel217
$frame ndesel218 ndesel219 ndesel220 ndesel221 ndesel222
$frame ndesel223
//
$frame pselon224 pselon225 pselon226 pselon227 pselon228
$frame pselon229 pselon230 pselon231 pselon232 pselon233
$frame pselon234
/*void acidblobFizzle (void)
{
CreateGreenSmoke (self.origin,'0 0 8',HX_FRAME_TIME * 2);
remove(self);
}
*/
void acidBlobDie(void)
{
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_ACIDBLOB);
WriteCoord (MSG_MULTICAST, self.origin_x - self.movedir_x * 10);
WriteCoord (MSG_MULTICAST, self.origin_y - self.movedir_y * 10);
WriteCoord (MSG_MULTICAST, self.origin_z - self.movedir_z * 10);
multicast(self.origin,MULTICAST_PHS_R);
remove(self);
}
void acidblobThink (void)
{
if(self.lifetime<time)
{
acidBlobDie();
}
thinktime self : 0.1;
}
void acidblobTouch (void)
{
if(other.controller==self.owner)
return;
if(other.takedamage&&other.health)
{
T_Damage(other,self,self.owner,self.dmg);
if((other.flags&FL_CLIENT||other.flags&FL_MONSTER)&&other.mass<200)
{
vector hitdir;
hitdir=self.o_angle*300;
hitdir_z+=150;
if(hitdir_z<0)
hitdir_z=0;
other.velocity=hitdir;
other.flags(-)FL_ONGROUND;
}
self.dmg/=2;
}
self.dmg=100;
T_RadiusDamage (self, self.owner, self.dmg, other);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_ACIDBLOB);
WriteCoord (MSG_MULTICAST, self.origin_x - self.movedir_x * 10);
WriteCoord (MSG_MULTICAST, self.origin_y - self.movedir_y * 10);
WriteCoord (MSG_MULTICAST, self.origin_z - self.movedir_z * 10);
multicast(self.origin,MULTICAST_PHS);
remove(self);
//acidblobFizzle();
}
void AcidBlobThink(void)
{
self.movedir = normalize(self.velocity);
self.angles = vectoangles(self.movedir);
traceline(self.origin, self.origin + self.movedir * 300.0, FALSE, self);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_ACID_BLOB_FLY);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
WriteByte (MSG_MULTICAST, self.angles_y*256.0/360.0);
WriteByte (MSG_MULTICAST, self.angles_x*256.0/360.0);
WriteByte (MSG_MULTICAST, trace_fraction * 100);
multicast(self.origin,MULTICAST_PVS);
thinktime self : 0.3;
if (self.lifetime < time)
SUB_Remove();
}
void FireAcidBlob (string type)
{
vector org;
entity acidblob;
acidblob=spawn();
setmodel(acidblob,"models/sucwp2p.mdl");
acidblob.thingtype=THINGTYPE_ACID;
acidblob.th_die = acidBlobDie;
self.bluemana-=8;
acidblob.classname="acidblob";
self.punchangle_x = -4;
weapon_sound(self, "succubus/acidpfir.wav");
self.attack_finished=time + 0.7;
self.effects(+)EF_MUZZLEFLASH;
makevectors(self.v_angle);
acidblob.speed=1000;
acidblob.o_angle=normalize(v_forward);
acidblob.velocity=acidblob.o_angle*acidblob.speed;
acidblob.veer=30;
acidblob.lifetime=time + 5;
acidblob.dmg=75;
acidblob.scale=2.5; // <---- slight net traffic - try to get around somehow...
acidblob.movetype=MOVETYPE_FLYMISSILE;
org=self.origin+self.proj_ofs+v_forward*8-v_right*12 - '0 0 3';
setsize(acidblob,'0 0 0', '0 0 0');
// let this default - it's unlikely the client will notice this at all...
acidblob.angles=vectoangles(acidblob.velocity);
// acidblob.effects (+) EF_ACIDBLOB;
acidblob.effects (+) EF_NODRAW;
acidblob.owner=self;
acidblob.movedir=normalize(acidblob.velocity);
acidblob.solid=SOLID_BBOX;
acidblob.touch=acidblobTouch;
setorigin(acidblob,org);
entity oldself;
oldself = self;
self = acidblob;
acidblob.think = AcidBlobThink;
acidblob.think();
self = oldself;
}
void AcidMissileTouch (void)
{
if(pointcontents(self.origin)==CONTENT_SKY)
{
remove(self);
return;
}
if(other.classname==self.classname&&other.owner==self.owner)
return;
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_ACIDBALL);
WriteCoord (MSG_MULTICAST, self.origin_x - self.movedir_x * 10);
WriteCoord (MSG_MULTICAST, self.origin_y - self.movedir_y * 10);
WriteCoord (MSG_MULTICAST, self.origin_z - self.movedir_z * 10);
multicast(self.origin,MULTICAST_PHS_R);
if(other.takedamage)
{
T_Damage(other,self,self.owner,self.dmg);
}
remove(self);
}
void AcidMissileThink(void)
{
self.movedir = normalize(self.velocity);
self.angles = vectoangles(self.movedir);
traceline(self.origin, self.origin + self.velocity*.3, FALSE, self);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_ACID_BALL_FLY);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
WriteByte (MSG_MULTICAST, self.angles_y*256.0/360.0);
WriteByte (MSG_MULTICAST, self.angles_x*256.0/360.0);
WriteByte (MSG_MULTICAST, trace_fraction * 100);
multicast(self.origin,MULTICAST_PVS);
thinktime self : 0.3;
if (self.lifetime < time)
SUB_Remove();
}
void FireAcidMissile (float offset)
{//fixme: add trail
vector spread;
makevectors(self.v_angle);
self.effects(+)EF_MUZZLEFLASH;
self.bluemana-=3;
newmis=spawn();
newmis.owner=self;
newmis.frags=FALSE;
newmis.movetype=MOVETYPE_FLYMISSILE;
newmis.solid=SOLID_BBOX;
newmis.touch=AcidMissileTouch;
newmis.dmg=random(27,33);
spread=normalize(v_right)*(offset*25);
spread=normalize(v_up)*(offset*8);
newmis.velocity=normalize(v_forward)*850 + spread;
newmis.movedir=normalize(newmis.velocity);
newmis.angles=vectoangles(newmis.velocity);
setmodel(newmis,"models/sucwp2p.mdl");
setsize(newmis,'0 0 0','0 0 0');
setorigin(newmis,self.origin+self.proj_ofs+v_forward*8-v_right*12 + v_right*(offset*3) + '0 0 2');
weapon_sound(self, "succubus/acidfire.wav");
newmis.lifetime = time + 2;
newmis.effects (+) EF_NODRAW;
entity oldself;
oldself = self;
self = newmis;
newmis.think = AcidMissileThink;
newmis.think();
self = oldself;
}
void aorb_power()
{
if(self.attack_finished>time)
return;
FireAcidBlob("acidblob");
self.attack_finished=time+0.7;
}
void aorb_normal()
{
if(self.attack_finished>time)
return;
FireAcidMissile(0);
self.attack_finished=time+0.4;
}
/*======================
ACTION
select
deselect
ready loop
relax loop
fire once
fire loop
ready to relax(after short delay)
relax to ready(Fire delay? or automatic if see someone?)
=======================*/
void()acidorb_ready_power;
void()acidorb_ready_normal;
void() Suc_Aorb_Fire;
void acidorb_fire (void)
{
if(self.button0&&self.weaponframe==$normal60 &&!self.artifact_active&ART_TOMEOFPOWER)
self.weaponframe=$normal58;
else
if(self.artifact_active&ART_TOMEOFPOWER)
{
self.wfs = advanceweaponframe($powern135,$powern148);
if(self.weaponframe<$powern141)
self.weaponframe+=1;
}
else
{
self.wfs = advanceweaponframe($normal51,$normal64);
if(self.weaponframe<$normal58)
self.weaponframe+=1;
}
self.th_weapon=acidorb_fire;
self.last_attack=time;
if(self.wfs==WF_CYCLE_WRAPPED||self.bluemana<3||(self.bluemana<8&&self.artifact_active&ART_TOMEOFPOWER))
if(self.artifact_active&ART_TOMEOFPOWER)
acidorb_ready_power();
else
acidorb_ready_normal();
else if(self.weaponframe==$normal58)// &&self.attack_finished<=time)
aorb_normal();
else if(self.weaponframe==$powern141)
aorb_power();//Fixme: hold this frame for a few
}
void Suc_Aorb_Fire()
{
acidorb_fire();
thinktime self : 0;
}
void acidorb_jellyfingers_normal ()
{
self.wfs = advanceweaponframe($idlebn01,$idlebn25);
self.th_weapon=acidorb_jellyfingers_normal;
if(self.wfs==WF_CYCLE_WRAPPED)
if(self.artifact_active&ART_TOMEOFPOWER)
acidorb_ready_power();
else
acidorb_ready_normal();
}
void acidorb_jellyfingers_power ()
{
self.wfs = advanceweaponframe($pidleb085,$pidleb109);
self.th_weapon=acidorb_jellyfingers_power;
if(self.wfs==WF_CYCLE_WRAPPED)
if(self.artifact_active&ART_TOMEOFPOWER)
acidorb_ready_power();
else
acidorb_ready_normal();
}
void acidorb_to_power (void)
{
self.wfs = advanceweaponframe($topowr65,$topowr84);
self.th_weapon=acidorb_to_power;
if(self.wfs==WF_CYCLE_WRAPPED)
acidorb_ready_power();
}
void acidorb_to_normal (void)
{
self.wfs = advanceweaponframe($tonrml149,$tonrml168);
self.th_weapon=acidorb_to_normal;
if(self.wfs==WF_CYCLE_WRAPPED)
acidorb_ready_normal();
}
void acidorb_ready_normal (void)
{
self.wfs = advanceweaponframe($idlean26,$idlean50);
if(random()<0.1&&self.weaponframe==$idlean50)
self.th_weapon=acidorb_jellyfingers_normal;
else
self.th_weapon=acidorb_ready_normal;
if(self.artifact_active&ART_TOMEOFPOWER)
{
self.weaponframe=$topowr65;
acidorb_to_power();
}
}
void acidorb_ready_power (void)
{
self.wfs = advanceweaponframe($pidlea110,$pidlea134);
if(random()<0.1&&self.weaponframe==$pidlea134)
self.th_weapon=acidorb_jellyfingers_power;
else
self.th_weapon=acidorb_ready_power;
if(!self.artifact_active&ART_TOMEOFPOWER)
{
self.weaponframe=$tonrml149;
acidorb_to_normal();
}
}
void acidorb_select_normal (void)
{
self.wfs = advanceweaponframe($ndesel223,$ndesel213);
self.weaponmodel = "models/sucwp2.mdl";
self.th_weapon=acidorb_select_normal;
self.t_width=-1;
if(self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
acidorb_ready_normal();
}
}
void acidorb_select_power (void)
{
self.wfs = advanceweaponframe($pselon224,$pselon234);
self.weaponmodel = "models/sucwp2.mdl";
self.th_weapon=acidorb_select_power;
self.t_width=-1;
if(self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
acidorb_ready_power();
}
}
void acidorb_select (void)
{
if(self.artifact_active&ART_TOMEOFPOWER)
acidorb_select_power();
else
acidorb_select_normal();
}
void acidorb_deselect_normal (void)
{
self.wfs = advanceweaponframe($ndesel213,$ndesel223);
self.th_weapon=acidorb_deselect_normal;
if(self.wfs==WF_CYCLE_WRAPPED)
W_SetCurrentAmmo();
}
void acidorb_deselect_power (void)
{
self.wfs = advanceweaponframe($pselon234,$pselon224);
self.th_weapon=acidorb_deselect_power;
if(self.wfs==WF_CYCLE_WRAPPED)
W_SetCurrentAmmo();
}
void acidorb_deselect (void)
{
if(self.artifact_active&ART_TOMEOFPOWER)
acidorb_deselect_power();
else
acidorb_deselect_normal();
}

779
ai.hc Normal file
View File

@ -0,0 +1,779 @@
/*
* $Header: /HexenWorld/Siege/Ai.hc 10 5/25/98 1:38p Mgummelt $
*/
void(entity etemp, entity stemp, entity stemp, float dmg) T_Damage;
/*
.enemy
Will be world if not currently angry at anyone.
.pathcorner
The next path spot to walk toward. If .enemy, ignore .pathcorner
When an enemy is killed, the monster will try to return to it's path.
.hunt_time
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 .pathcorner when
time > .pausetime.
walkmove(angle, speed) primitive is all or nothing
*/
//float ArcherCheckAttack (void);
//float MedusaCheckAttack (void);
void()SetNextWaypoint;
//void()SpiderMeleeBegin;
//void()spider_onwall_wait;
float(entity targ , entity from)infront_of_ent;
void(entity proj)mezzo_choose_roll;
//void()hive_die;
//void()check_climb;
//
// globals
//
float current_yaw;
//
// 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
//
float sight_entity_time;
float(float v) anglemod =
{
while (v >= 360)
v = v - 360;
while (v < 0)
v = v + 360;
return v;
};
//============================================================================
/*
=============
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 =
{
vector spot1, spot2;
float r,melee;
if((self.solid==SOLID_BSP||self.solid==SOLID_TRIGGER)&&self.origin=='0 0 0')
spot1=(self.absmax+self.absmin)*0.5;
else
spot1 = self.origin + self.view_ofs;
if((targ.solid==SOLID_BSP||targ.solid==SOLID_TRIGGER)&&targ.origin=='0 0 0')
spot2=(targ.absmax+targ.absmin)*0.5;
else
spot2 = targ.origin + targ.view_ofs;
r = vlen (spot1 - spot2);
if (self.classname=="monster_mummy")
melee = 50;
else
melee = 100;
if (r < melee)
return RANGE_MELEE;
if (r < 500)
return RANGE_NEAR;
if (r < 1000)
return RANGE_MID;
return RANGE_FAR;
};
/*
=============
visible2ent
returns 1 if the entity is visible to self, even if not infront ()
=============
*/
float visible2ent (entity targ, entity forent)
{
vector spot1, spot2;
if((forent.solid==SOLID_BSP||forent.solid==SOLID_TRIGGER)&&forent.origin=='0 0 0')
spot1=(forent.absmax+forent.absmin)*0.5;
else
spot1 = forent.origin + forent.view_ofs;
if((targ.solid==SOLID_BSP||targ.solid==SOLID_TRIGGER)&&targ.origin=='0 0 0')
spot2=(targ.absmax+targ.absmin)*0.5;
else
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, TRUE, forent); // see through other monsters
if(trace_ent.thingtype>=THINGTYPE_WEBS)
traceline (trace_endpos, spot2, TRUE, trace_ent);
// else if (trace_inopen && trace_inwater)//FIXME? Translucent water?
// return FALSE; // sight line crossed contents
if (trace_fraction == 1)
{
if(forent.flags&FL_MONSTER)
{
if(visibility_good(targ,0.15 - skill/20))
return TRUE;
}
else
return TRUE;
}
return FALSE;
}
/*
=============
infront_of_ent
returns 1 if the targ is in front (in sight) of from
=============
*/
float infront_of_ent (entity targ , entity from)
{
vector vec,spot1,spot2;
float accept,dot;
if(from.classname=="player")
makevectors (from.v_angle);
/* else if(from.classname=="monster_medusa")
makevectors (from.angles+from.angle_ofs);
*/ else
makevectors (from.angles);
if((from.solid==SOLID_BSP||from.solid==SOLID_TRIGGER)&&from.origin=='0 0 0')
spot1=(from.absmax+from.absmin)*0.5;
else
spot1 = from.origin + from.view_ofs;
spot2=(targ.absmax+targ.absmin)*0.5;
vec = normalize (spot2 - spot1);
dot = vec * v_forward;
accept = 0.3;
if ( dot > accept)
return TRUE;
return FALSE;
}
/*
=============
visible
returns 1 if the entity is visible to self, even if not infront ()
=============
*/
float visible (entity targ)
{
return visible2ent(targ,self);
}
/*
=============
infront
returns 1 if the entity is in front (in sight) of self
=============
*/
float infront (entity targ)
{
return infront_of_ent(targ,self);
}
//============================================================================
/*
===========
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 ()
{
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;
if(self.spawnflags&PLAY_DEAD)
{
// dprint("getting up!!!\n");
self.think=self.th_possum_up;
self.spawnflags(-)PLAY_DEAD;
}
else
self.think = self.th_run;
// self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
thinktime self : 0.1;
// SUB_AttackFinished (1); // wait a while before first attack
};
void SightSound (void)
{
if (self.classname == "monster_archer")
sound (self, CHAN_VOICE, "archer/sight.wav", 1, ATTN_NORM);
else if (self.classname == "monster_archer_lord")
sound (self, CHAN_VOICE, "archer/sight2.wav", 1, ATTN_NORM);
else if (self.classname == "monster_mummy")
sound (self, CHAN_WEAPON, "mummy/sight.wav", 1, ATTN_NORM);
else if (self.classname == "monster_mummy_lord")
sound (self, CHAN_WEAPON, "mummy/sight2.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 + 1;
}
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(float dont_hunt) FindTarget =
{
entity client;
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(!deathmatch&&(self.classname=="monster_imp_lord"||self.classname=="cube_of_force"))
// return FindMonsterTarget();
if (sight_entity_time >= time&&sight_entity!=world)
{
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(self.classname=="monster_imp_lord"&&client==self.controller)
// return FALSE;
if (client == self.enemy)
return FALSE;
if (client.flags & FL_NOTARGET)
return FALSE;
r = range (client);
if (r == RANGE_FAR)
return FALSE;
if(self.siege_team)
if(client.siege_team==self.siege_team)//SIEGE
return FALSE;
if(!visibility_good(client,5))
{
// dprint("Monster has low visibility on ");
// dprint(client.netname);
// dprintf("(%s)\n",client.visibility);
return FALSE;
}
// if(self.think!=spider_onwall_wait)
if (r == RANGE_NEAR)
{
if (client.show_hostile < time && !infront (client))
return FALSE;
}
else if (r == RANGE_MID)
{
if (!infront (client))
return FALSE;
}
if (!visible (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;
}
}
/* if(self.spawnflags&PLAY_DEAD)
{
if(r==RANGE_MELEE)
{
if(!dont_hunt)
FoundTarget ();
return TRUE;
}
else if(!infront_of_ent(self,self.enemy)&&random()<0.1&&random()<0.1)
{
if(!dont_hunt)
FoundTarget ();
return TRUE;
}
else
{
self.enemy=world;
return FALSE;
}
}
*/
if(!dont_hunt)
FoundTarget ();
return TRUE;
};
//void()SpiderJumpBegin;
//=============================================================================
void(float dist) ai_forward =
{
walkmove (self.angles_y, dist, FALSE);
};
void(float dist) ai_back =
{
walkmove ( (self.angles_y+180), dist, FALSE);
};
/*
=============
ai_pain
stagger back a bit
=============
*/
void(float dist) ai_pain =
{
// ai_back (dist);
float away;
away = vectoyaw (self.origin - self.enemy.origin)+90*random(0.5,-0.5);
walkmove (away, dist,FALSE);
};
/*
=============
ai_painforward
stagger back a bit
=============
*/
void(float dist) ai_painforward =
{
walkmove (self.ideal_yaw, dist, FALSE);
};
/*
=============
ai_walk
The monster is walking it's beat
=============
*/
void(float dist) ai_walk =
{
MonsterCheckContents();
movedist = dist;
// check for noticing a player
if(self.classname!="monster_pirhana")
if (FindTarget (FALSE))
return;
movetogoal (dist);
};
/*
=============
ai_stand
The monster is staying in one place for a while, with slight angle turns
=============
*/
void() ai_stand =
{
MonsterCheckContents();
if(self.classname!="monster_pirhana")
if (FindTarget (FALSE))
return;
if(self.spawnflags&PLAY_DEAD)
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 (FALSE))
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
Within angle to launch attack?
============
*/
float() FacingIdeal =
{
local float delta;
delta = anglemod(self.angles_y - self.ideal_yaw);
if (delta > 45 && delta < 315)
return FALSE;
return TRUE;
};
//=============================================================================
float() CheckAnyAttack =
{
// if (self.model=="models/medusa.mdl"||self.model=="models/medusa2.mdl")
// return(MedusaCheckAttack ());
if (!enemy_vis)
return FALSE;
// if (self.model=="models/archer.mdl")
// return(ArcherCheckAttack ());
if(self.goalentity==self.controller)
return FALSE;
return CheckAttack ();
};
/*
=============
ai_attack_face
Turn in place until within an angle to launch an attack
=============
*/
void() ai_attack_face =
{
self.ideal_yaw = enemy_yaw;
ChangeYaw ();
if (FacingIdeal()) // Ready to go get em
{
if (self.attack_state == AS_MISSILE)
self.th_missile ();
else if (self.attack_state == AS_MELEE)
self.th_melee ();
self.attack_state = AS_STRAIGHT;
}
};
/*
=============
ai_run_slide
Strafe sideways, but stay at aproximately the same range
=============
*/
void ai_run_slide ()
{
float ofs;
self.ideal_yaw = enemy_yaw;
ChangeYaw ();
if (self.lefty)
ofs = 90;
else
ofs = -90;
if (walkmove (self.ideal_yaw + ofs, movedist, FALSE))
return;
self.lefty = 1 - self.lefty;
walkmove (self.ideal_yaw - ofs, movedist, FALSE);
}
/*
=============
ai_run
The monster has an enemy it is trying to kill
=============
*/
void(float dist) ai_run =
{
MonsterCheckContents();
movedist = dist;
// see if the enemy is dead
if (!self.enemy.flags2&FL_ALIVE||(self.enemy.artifact_active&ARTFLAG_STONED&&self.classname!="monster_medusa"))
{
self.enemy = world;
// FIXME: look all around for other targets
if (self.oldenemy.health > 0)
{
self.enemy = self.oldenemy;
HuntTarget ();
}
else if(coop)
{
if(!FindTarget(TRUE)) //Look for other enemies in the area
{
if (self.pathentity)
self.th_walk ();
else
self.th_stand ();
return;
}
}
else
{
if (self.pathentity)
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)
{
if(self.classname!="monster_pirhana")
self.search_time = time + 5;
if(self.mintel)
{
self.goalentity=self.enemy;
self.wallspot=(self.enemy.absmin+self.enemy.absmax)*0.5;
}
}
else
{
if(coop)
{
if(!FindTarget(TRUE))
if(self.model=="models/spider.mdl")
{
if(random()<0.5)
SetNextWaypoint();
}
else
SetNextWaypoint();
}
if(self.mintel)
if(self.model=="models/spider.mdl")
{
if(random()<0.5)
SetNextWaypoint();
}
else
SetNextWaypoint();
}
if(random()<0.5&&(!self.flags&FL_SWIM)&&(!self.flags&FL_FLY)&&(self.spawnflags&JUMP))
CheckJump();
// look for other coop players
if ((coop||dmMode==DM_SIEGE) && self.search_time < time)
{
if (FindTarget (FALSE))
return;
}
enemy_infront = infront(self.enemy);
enemy_range = range(self.enemy);
enemy_yaw = vectoyaw(self.goalentity.origin - self.origin);
if ((self.attack_state == AS_MISSILE) || (self.attack_state == AS_MELEE)) // turning to attack
{
ai_attack_face ();
return;
}
if (CheckAnyAttack ())
return; // beginning an attack
if (self.attack_state == AS_SLIDING)
{
ai_run_slide ();
return;
}
// head straight in
// if(self.netname=="spider")
// check_climb();
movetogoal (dist); // done in C code...
};

787
ai2.hc Normal file
View File

@ -0,0 +1,787 @@
/*
* $Header: /HexenWorld/Siege/ai2.hc 4 5/25/98 1:38p Mgummelt $
*/
void(entity etemp, entity stemp, entity stemp, float dmg) T_Damage;
/*
.enemy
Will be world if not currently angry at anyone.
.pathcorner
The next path spot to walk toward. If .enemy, ignore .pathcorner
When an enemy is killed, the monster will try to return to it's path.
.hunt_time
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 .pathcorner when
time > .pausetime.
walkmove(angle, speed) primitive is all or nothing
*/
void()SetNextWaypoint;
float(entity targ , entity from)infront_of_ent;
float()eidolon_check_attack;
void()multiplayer_health;
//void()check_climb;
//
// globals
//
float current_yaw;
//
// 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
//
float sight_entity_time;
void()riderpath_init;
void(float move_speed)riderpath_move;
float(float move_speed)eidolon_riderpath_move;
void() eidolon_guarding;
void()hive_die;
float(float v) anglemod =
{
while (v >= 360)
v = v - 360;
while (v < 0)
v = v + 360;
return v;
};
//============================================================================
/*
=============
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,melee;
if((self.solid==SOLID_BSP||self.solid==SOLID_TRIGGER)&&self.origin=='0 0 0')
spot1=(self.absmax+self.absmin)*0.5;
else
spot1 = self.origin + self.view_ofs;
if((targ.solid==SOLID_BSP||targ.solid==SOLID_TRIGGER)&&targ.origin=='0 0 0')
spot2=(targ.absmax+targ.absmin)*0.5;
else
spot2 = targ.origin + targ.view_ofs;
r = vlen (spot1 - spot2);
if (self.classname=="monster_mummy")
melee = 50;
else
melee = 100;
if (r < melee)
return RANGE_MELEE;
if (r < 500)
return RANGE_NEAR;
if (r < 1000)
return RANGE_MID;
return RANGE_FAR;
};
/*
=============
visible2ent
returns 1 if the entity is visible to self, even if not infront ()
=============
*/
float visible2ent (entity targ, entity forent)
{
vector spot1, spot2;
if((forent.solid==SOLID_BSP||forent.solid==SOLID_TRIGGER)&&forent.origin=='0 0 0')
spot1=(forent.absmax+forent.absmin)*0.5;
else
spot1 = forent.origin + forent.view_ofs;
if((targ.solid==SOLID_BSP||targ.solid==SOLID_TRIGGER)&&targ.origin=='0 0 0')
spot2=(targ.absmax+targ.absmin)*0.5;
else
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, TRUE, forent); // see through other monsters
if(trace_ent.thingtype>=THINGTYPE_WEBS)
traceline (trace_endpos, spot2, TRUE, trace_ent);
else if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if (trace_fraction == 1)
return TRUE;
return FALSE;
}
/*
=============
infront_of_ent
returns 1 if the targ is in front (in sight) of from
=============
*/
float infront_of_ent (entity targ , entity from)
{
vector vec,spot1,spot2;
float accept,dot;
if(from.classname=="player")
makevectors (from.v_angle);
/* else if(from.classname=="monster_medusa")
makevectors (from.angles+from.angle_ofs);
*/ else
makevectors (from.angles);
if((from.solid==SOLID_BSP||from.solid==SOLID_TRIGGER)&&from.origin=='0 0 0')
spot1=(from.absmax+from.absmin)*0.5;
else
spot1 = from.origin + from.view_ofs;
spot2=(targ.absmax+targ.absmin)*0.5;
vec = normalize (spot2 - spot1);
dot = vec * v_forward;
accept = 0.3;
if ( dot > accept)
return TRUE;
return FALSE;
}
/*
=============
visible
returns 1 if the entity is visible to self, even if not infront ()
=============
*/
float visible (entity targ)
{
return visible2ent(targ,self);
}
/*
=============
infront
returns 1 if the entity is in front (in sight) of self
=============
*/
float infront (entity targ)
{
return infront_of_ent(targ,self);
}
//============================================================================
/*
===========
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 ()
{
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;
if(self.spawnflags&PLAY_DEAD)
{
// dprint("getting up!!!\n");
self.think=self.th_possum_up;
self.spawnflags(-)PLAY_DEAD;
}
else
self.think = self.th_run;
// self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
thinktime self : 0.1;
// SUB_AttackFinished (1); // wait a while before first attack
};
void SightSound (void)
{
if (self.classname == "monster_archer")
sound (self, CHAN_VOICE, "archer/sight.wav", 1, ATTN_NORM);
else if (self.classname == "monster_archer_lord")
sound (self, CHAN_VOICE, "archer/sight2.wav", 1, ATTN_NORM);
else if (self.classname == "monster_mummy")
sound (self, CHAN_WEAPON, "mummy/sight.wav", 1, ATTN_NORM);
else if (self.classname == "monster_mummy_lord")
sound (self, CHAN_WEAPON, "mummy/sight2.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 + 1;
}
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(float dont_hunt) FindTarget =
{
entity client;
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(!deathmatch&&(self.classname=="monster_imp_lord"||self.classname=="cube_of_force"))
return FindMonsterTarget();
if (sight_entity_time >= time)
{
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;
r = range (client);
if (r == RANGE_FAR)
return FALSE;
if (r == RANGE_NEAR)
{
if (client.show_hostile < time && !infront (client))
return FALSE;
}
else if (r == RANGE_MID)
{
if (!infront (client))
return FALSE;
}
if (!visible (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;
}
}
/* if(self.spawnflags&PLAY_DEAD)
{
if(r==RANGE_MELEE)
{
if(!dont_hunt)
FoundTarget ();
return TRUE;
}
else if(!infront_of_ent(self,self.enemy)&&random()<0.1&&random()<0.1)
{
if(!dont_hunt)
FoundTarget ();
return TRUE;
}
else
{
self.enemy=world;
return FALSE;
}
}
*/
if(!dont_hunt)
FoundTarget ();
return TRUE;
};
//=============================================================================
void(float dist) ai_forward =
{
walkmove (self.angles_y, dist, FALSE);
};
void(float dist) ai_back =
{
walkmove ( (self.angles_y+180), dist, FALSE);
};
/*
=============
ai_pain
stagger back a bit
=============
*/
void(float dist) ai_pain =
{
// ai_back (dist);
float away;
away = vectoyaw (self.origin - self.enemy.origin)+90*random(0.5,-0.5);
walkmove (away, dist,FALSE);
};
/*
=============
ai_painforward
stagger back a bit
=============
*/
void(float dist) ai_painforward =
{
walkmove (self.ideal_yaw, dist, FALSE);
};
/*
=============
ai_walk
The monster is walking it's beat
=============
*/
void(float dist) ai_walk =
{
MonsterCheckContents();
movedist = dist;
// check for noticing a player
if (FindTarget (FALSE))
return;
if(self.classname=="monster_eidolon")
{
if (!self.path_current)
riderpath_init();
if(!eidolon_riderpath_move(dist))
{
if(self.think==self.th_walk)
self.think=eidolon_guarding;
}
else if(self.think==eidolon_guarding)
self.think=self.th_walk;
}
else
movetogoal (dist);
};
/*
=============
ai_stand
The monster is staying in one place for a while, with slight angle turns
=============
*/
void() ai_stand =
{
MonsterCheckContents();
if (FindTarget (FALSE))
return;
if(self.spawnflags&PLAY_DEAD)
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 (FALSE))
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
Within angle to launch attack?
============
*/
float() FacingIdeal =
{
local float delta;
delta = anglemod(self.angles_y - self.ideal_yaw);
if (delta > 45 && delta < 315)
return FALSE;
return TRUE;
};
//=============================================================================
float() CheckAnyAttack =
{
if (!enemy_vis)
return FALSE;
if(self.classname=="monster_eidolon")
if(self.goalentity==self.controller)
return FALSE;
else
return eidolon_check_attack();
return CheckAttack ();
};
/*
=============
ai_attack_face
Turn in place until within an angle to launch an attack
=============
*/
void() ai_attack_face =
{
self.ideal_yaw = enemy_yaw;
ChangeYaw ();
if (FacingIdeal()) // Ready to go get em
{
if (self.attack_state == AS_MISSILE)
self.th_missile ();
else if (self.attack_state == AS_MELEE)
self.th_melee ();
self.attack_state = AS_STRAIGHT;
}
};
/*
=============
ai_run_slide
Strafe sideways, but stay at aproximately the same range
=============
*/
void ai_run_slide ()
{
float ofs;
self.ideal_yaw = enemy_yaw;
ChangeYaw ();
if (self.lefty)
ofs = 90;
else
ofs = -90;
if (walkmove (self.ideal_yaw + ofs, movedist, FALSE))
return;
self.lefty = 1 - self.lefty;
walkmove (self.ideal_yaw - ofs, movedist, FALSE);
}
/*
=============
ai_run
The monster has an enemy it is trying to kill
=============
*/
void(float dist) ai_run =
{
MonsterCheckContents();
movedist = dist;
// see if the enemy is dead
if (!self.enemy.flags2&FL_ALIVE||(self.enemy.artifact_active&ARTFLAG_STONED&&self.classname!="monster_medusa"))
{
self.enemy = world;
// FIXME: look all around for other targets
if (self.oldenemy.health > 0)
{
self.enemy = self.oldenemy;
HuntTarget ();
}
else if(coop)
{
if(!FindTarget(TRUE)) //Look for other enemies in the area
{
if (self.pathentity)
self.th_walk ();
else
self.th_stand ();
return;
}
}
else
{
if (self.pathentity)
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;
if(self.mintel)
{
self.goalentity=self.enemy;
self.wallspot=(self.enemy.absmin+self.enemy.absmax)*0.5;
}
}
else
{
if(coop)
{
if(!FindTarget(TRUE))
if(self.model=="models/spider.mdl")
{
if(random()<0.5)
SetNextWaypoint();
}
else
SetNextWaypoint();
}
if(self.mintel)
if(self.model=="models/spider.mdl")
{
if(random()<0.5)
SetNextWaypoint();
}
else
SetNextWaypoint();
}
if(random()<0.5&&(!self.flags&FL_SWIM)&&(!self.flags&FL_FLY)&&(self.spawnflags&JUMP))
CheckJump();
// look for other coop players
if (coop && self.search_time < time)
{
if (FindTarget (FALSE))
return;
}
enemy_infront = infront(self.enemy);
enemy_range = range(self.enemy);
if(self.classname!="monster_eidolon")
enemy_yaw = vectoyaw(self.goalentity.origin - self.origin);
if ((self.attack_state == AS_MISSILE) || (self.attack_state == AS_MELEE)) // turning to attack
{
if(self.classname!="monster_eidolon")
ai_attack_face ();
return;
}
if (CheckAnyAttack ())
return; // beginning an attack
if (self.attack_state == AS_SLIDING)
{
ai_run_slide ();
return;
}
// head straight in
// if(self.netname=="spider")
// check_climb();
if(self.classname=="monster_eidolon")
{
if(!self.path_current)
riderpath_init();
if(!eidolon_riderpath_move(dist))
{
if(self.think==self.th_run)
eidolon_guarding();
}
else if(self.think==eidolon_guarding)
self.th_run();
}
else
movetogoal (dist); // done in C code...
};
//FAKE FUNCTIONS
void SpiderJumpBegin()
{
}
float mezzo_choose_roll (entity null)
{
return FALSE;
}

657
allplay.hc Normal file
View File

@ -0,0 +1,657 @@
/*=========================================
FUNCTIONS THAT ALL PLAYERS WILL CALL
===========================================*/
void() bubble_bob;
vector VelocityForDamage (float dm)
{
local vector v;
v = randomv('-100 -100 200', '100 100 300');
if (dm > -50)
v = v * 0.7;
else if (dm > -200)
v = v * 2;
else
v = v * 10;
return v;
}
void ReadySolid ()
{
if(!self.headmodel)
self.headmodel="models/flesh1.mdl";//Temp until player head models are in
MakeSolidCorpse ();
}
void StandardPain(void)
{
if(self.playerclass==CLASS_ASSASSIN||self.playerclass==CLASS_SUCCUBUS)
if (random() > 0.5)
sound (self, CHAN_VOICE, "player/asspain1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/asspain2.wav", 1, ATTN_NORM);
else if (random() > 0.5)
sound (self, CHAN_VOICE, "player/palpain1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/palpain2.wav", 1, ATTN_NORM);
}
void PainSound (void)
{
if (self.health <= 0)
return;
if (self.deathtype == "teledeath"||self.deathtype == "teledeath2"||self.deathtype == "teledeath3"||self.deathtype == "teledeath4")
{
sound (self, CHAN_VOICE, "player/telefrag.wav", 1, ATTN_NONE);
return;
}
if (self.pain_finished > time)
return;
self.pain_finished = time + 0.5;
// FIXME: Are we doing seperate sounds for these different pains????
if(self.model=="models/yakman.mdl")
{
sound (self, CHAN_VOICE, "eidolon/pain.wav", 1, ATTN_NORM);
return;
}
else if (self.model=="models/sheep.mdl")
sheep_sound(1);
else if (/*self.watertype == CONTENT_WATER &&*/ self.waterlevel == 3)
{
if(self.playerclass==CLASS_ASSASSIN||self.playerclass==CLASS_SUCCUBUS)
sound (self, CHAN_VOICE, "player/assdrown.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/paldrown.wav", 1, ATTN_NORM);
}
else //if (self.watertype == CONTENT_SLIME)
{
StandardPain();
}
/* else if (self.watertype == CONTENT_LAVA)
{
if(self.playerclass==CLASS_ASSASSIN)
if (random() > 0.5)
sound (self, CHAN_VOICE, "player/asspain1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/asspain2.wav", 1, ATTN_NORM);
else if (random() > 0.5)
sound (self, CHAN_VOICE, "player/palpain1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/palpain2.wav", 1, ATTN_NORM);
}
else
{
if(self.playerclass==CLASS_ASSASSIN)
if (random() > 0.5)
sound (self, CHAN_VOICE, "player/asspain1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/asspain2.wav", 1, ATTN_NORM);
else if (random() > 0.5)
sound (self, CHAN_VOICE, "player/palpain1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/palpain2.wav", 1, ATTN_NORM);
}*/
}
void player_pain (entity attacker,float total_damage)
{
//FIX this = need to check if firing, else make idle frames of all
// weapons frame 0?
//if (self.weaponframe)
// return;
if(self.playerclass==CLASS_SUCCUBUS)
{
if(self.flags&FL_SPECIAL_ABILITY2)
{//Sound &/or effect?
if(self.level>9)
{
self.greenmana+=total_damage;
self.bluemana+=total_damage;
}
else
{
if(self.level>6)
self.greenmana+=total_damage*(self.level - 2/10);
self.bluemana+=total_damage*(self.level/10);
}
if(self.bluemana>self.max_mana)
self.bluemana=self.max_mana;
if(self.greenmana>self.max_mana)
self.greenmana=self.max_mana;
}
}
else if(self.playerclass==CLASS_DWARF)
if(self.super_damage_time<time&&self.health<self.max_health/3&&random(self.max_health)>self.health)
{//if hit while at @30% health & not berzerked in last minute, chance to berzerk
self.super_damage=4;
self.super_damage_time=time+30;
self.colormap=140;
centerprint(self,"You are in a Berzerker Rage!!!\n");
}
self.climbing=FALSE;
self.climbspot='0 0 0';
self.last_climb=time;
if (self.last_attack + 0.5 > time || self.button0)
return;
PainSound();
// self.weaponframe=0;//Why?
if (self.hull==HULL_PLAYER||self.playerclass==CLASS_DWARF)
self.act_state=ACT_PAIN;
else
self.act_state=ACT_CROUCH_MOVE;//No pain animation for crouch- maybe jump?
//Make it make you stand up?
}
void DeathBubblesSpawn ()
{
entity bubble;
vector offset;
offset_x = random(18,-18);
offset_y = random(18,-18);
if (pointcontents(self.owner.origin+self.owner.view_ofs)!=CONTENT_WATER)
{
remove(self);
return;
}
bubble = spawn_temp();
setmodel (bubble, "models/s_bubble.spr");
setorigin (bubble, self.owner.origin+self.owner.view_ofs+offset);
bubble.movetype = MOVETYPE_NOCLIP;
bubble.solid = SOLID_NOT;
bubble.velocity = '0 0 17';
thinktime bubble : 0.5;
bubble.think = bubble_bob;
bubble.classname = "bubble";
bubble.frame = 0;
bubble.cnt = 0;
bubble.abslight=0.5;
bubble.drawflags(+)DRF_TRANSLUCENT|MLS_ABSLIGHT;
setsize (bubble, '-8 -8 -8', '8 8 8');
thinktime self : 0.1;
self.think = DeathBubblesSpawn;
self.air_finished = self.air_finished + 1;
if (self.air_finished >= self.bubble_count)
remove(self);
}
void DeathBubbles (float num_bubbles)
{
entity bubble_owner;
// if(self.classname=="contents damager")
// bubble_owner = self.enemy;
// else
bubble_owner = self;
starteffect(CE_DEATHBUBBLES, bubble_owner, bubble_owner.view_ofs, num_bubbles);
}
void DeathSound ()
{
// water death sounds
if (self.waterlevel == 3)
{
DeathBubbles(20);
if(self.playerclass==CLASS_ASSASSIN||self.playerclass==CLASS_SUCCUBUS)
sound (self, CHAN_VOICE, "player/assdieh2.wav", 1, ATTN_NONE);
else
sound (self, CHAN_VOICE, "player/paldieh2.wav", 1, ATTN_NONE);
return;
}
else
{
if(self.playerclass==CLASS_ASSASSIN||self.playerclass==CLASS_SUCCUBUS)
if (random() > 0.5)
sound (self, CHAN_VOICE, "player/assdie1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/assdie2.wav", 1, ATTN_NORM);
else if (random() > 0.5)
sound (self, CHAN_VOICE, "player/paldie1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/paldie2.wav", 1, ATTN_NORM);
}
return;
}
void PlayerDead ()
{
self.nextthink = -1;
// allow respawn after a certain time
self.deadflag = DEAD_DEAD;
if(self.model!=self.headmodel)
{
self.angles_x=self.angles_z=0;
pitch_roll_for_slope('0 0 0');
}
}
void ThrowGib (string gibname, float dm)
{
entity new;
new = spawn_temp();
new.origin = (self.absmin+self.absmax)*0.5;
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;
thinktime new : random(20,10);
new.scale=random(.5,.9);
new.frame = 0;
new.flags = 0;
}
void ThrowHead (string gibname, float dm)
{
vector org;
if(self.decap==2)
{//Brains!
if(self.movedir=='0 0 0')
{
self.movedir=normalize(self.origin+self.view_ofs-self.enemy.origin+self.enemy.proj_ofs);
self.movedir_z=0;
}
traceline(self.origin + self.view_ofs, self.origin+self.view_ofs+self.movedir*100, FALSE, self);
if (trace_fraction < 1&&!trace_ent.flags2&FL_ALIVE&&trace_ent.solid==SOLID_BSP)
{
self.wallspot=trace_endpos;
ZeBrains(trace_endpos, trace_plane_normal, random(1.3,2), rint(random(1)),0);
}
else
self.wallspot='0 0 0';
}
setmodel (self, gibname);
self.frame = 0;
self.takedamage = DAMAGE_NO;
if(self.classname!="player")
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_BOUNCE;
self.mass = 1;
self.view_ofs = '0 0 8';
self.proj_ofs='0 0 2';
self.hull=HULL_POINT;
org=self.origin;
org_z=self.absmax_z - 4;
setsize (self, '-4 -4 -4', '4 4 4');
setorigin(self,org);
self.flags(-)FL_ONGROUND;
self.avelocity = randomv('0 -600 0', '0 600 0');
if(self.decap==2)
self.velocity = VelocityForDamage (dm)+'0 0 50';
else
self.velocity = VelocityForDamage (dm)+'0 0 200';
if(self.decap==2||(self.decap==1&&vlen(self.velocity)>300))
{
if(self.wallspot=='0 0 0')
self.wallspot=org;
// self.pausetime=time+5;//watch splat or body
}
self.think=PlayerDead;
thinktime self : 1;
}
void PlayerUnCrouching ()
{
tracearea (self.origin,self.origin+'0 0 28','-16 -16 0','16 16 28',FALSE,self);
if (trace_fraction < 1)
{
centerprint(self,"No room to stand up here!\n");
self.crouch_stuck = 1;
return;
}
setsize (self, '-16 -16 0', '16 16 56');
self.hull=HULL_PLAYER;
if (self.viewentity.classname=="chasecam")
self.view_ofs = '0 0 0';
PlayerSpeed_Calc(self);
self.crouch_time = time;
if (self.velocity_x || self.velocity_y)
self.act_state=ACT_RUN;
else
self.act_state=ACT_STAND;
}
void PlayerCrouching ()
{
if (self.health <= 0)
return;
setsize (self,'-16 -16 0','16 16 28');
self.hull=HULL_CROUCH;
if (self.viewentity.classname=="chasecam")
self.view_ofs = '0 0 0';
self.absorb_time=time + 0.3;
PlayerSpeed_Calc(self);
self.crouch_time = time;
self.crouch_stuck = 0;
self.act_state=ACT_CROUCH_MOVE;
}
void PlayerCrouch ()
{
if(self.playerclass==CLASS_DWARF)
return;
if (self.hull==HULL_PLAYER)
PlayerCrouching();
else if (self.hull==HULL_CROUCH)
PlayerUnCrouching();
}
void GibPlayer (vector dir)
{
vector curAngs;
self.deadflag = DEAD_DEAD;
curAngs = vectoangles(dir);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_PLAYER_DEATH);
//WriteEntity (MSG_MULTICAST, self);
WriteCoord(MSG_MULTICAST, self.origin_x);
WriteCoord(MSG_MULTICAST, self.origin_y);
WriteCoord(MSG_MULTICAST, self.origin_z);
// make the dir stuff work
WriteByte (MSG_MULTICAST, curAngs_y * 256.0 / 360.0);
WriteByte (MSG_MULTICAST, curAngs_x * 256.0 / 360.0);
if(self.health < -80)
{
WriteByte (MSG_MULTICAST, 300);
}
else
{
WriteByte (MSG_MULTICAST, 140);
}
if (self.deathtype == "teledeath"||self.deathtype == "teledeath2"||self.deathtype == "teledeath3"||self.deathtype == "teledeath4")
{
WriteByte (MSG_MULTICAST, 2);
}
else if(self.health<-80)
{
WriteByte (MSG_MULTICAST, 0);
}
else
{
WriteByte (MSG_MULTICAST, 1);
}
multicast(self.origin,MULTICAST_PHS_R);
ThrowHead (self.headmodel, self.health);
}
void DecapPlayer ()
{
entity headless;
headless=spawn();
headless.classname="headless";
headless.decap=TRUE;
headless.movetype=MOVETYPE_STEP;
headless.solid=SOLID_PHASE;
headless.frame=50;
headless.skin=self.skin;
//Took this out so you can't fall "into" it...
// headless.owner=self;
headless.thingtype=self.thingtype;
headless.angles_y=self.angles_y;
setmodel(headless,self.model);
setsize(headless,'-16 -16 0','16 16 36');
setorigin(headless,self.origin);
headless.playerclass=self.playerclass;
headless.think=self.th_goredeath;
thinktime headless : 0;
self.health=self.health*4;
if(self.health>-30)
self.health=-30;
if(self.decap==2)
{
ThrowHead ("models/flesh1.mdl", self.health);
SpawnPuff(self.origin+self.view_ofs,'0 0 0',fabs(self.health),self);
}
else
ThrowHead (self.headmodel, self.health);
ThrowGib ("models/flesh1.mdl", self.health);
ThrowGib ("models/flesh2.mdl", self.health);
ThrowGib ("models/flesh3.mdl", self.health);
self.deadflag = DEAD_DEAD;
if (random() < 0.5)
sound(self,CHAN_VOICE,"player/decap.wav",1,ATTN_NORM);
else if (random() < 0.5)
sound (self, CHAN_VOICE, "player/gib1.wav", 1, ATTN_NONE);
else
sound (self, CHAN_VOICE, "player/gib2.wav", 1, ATTN_NONE);
}
void PlayerDie (float damage, vector dir)
{
stuffcmd(self,"fov 90\n");
stopSound(self,0);
if(self.viewentity!=self)
{
if(self.viewentity.classname=="chasecam")
remove(self.viewentity);
self.viewentity=self;
CameraViewPort(self,self);
CameraViewAngles(self,self);
}
msg_entity=self;
WriteByte(MSG_ONE, SVC_CLEAR_VIEW_FLAGS);
WriteByte(MSG_ONE,255);
self.artifact_low =
self.artifact_active =
self.invisible_time =
self.effects=
self.colormap=0;
if (deathmatch || coop)
DropBackpack();
if(self.model=="models/sheep.mdl")
self.headmodel="";
self.weaponmodel="";
self.deadflag = DEAD_DYING;
self.solid = SOLID_NOT;
self.flags(-)FL_ONGROUND;
self.movetype = MOVETYPE_TOSS;
self.attack_finished=self.teleport_time=self.pausetime=time;
self.drawflags=self.effects=FALSE;
if (self.velocity_z < 10)
self.velocity_z += random(300);
self.artifact_active = 0;
self.rings_active =0;
if (self.deathtype == "teledeath"||self.deathtype == "teledeath2"||self.deathtype == "teledeath3"||self.deathtype == "teledeath4")
{
self.decap=0;
self.health=-99;
}
if(self.deathtype=="ice shatter"||self.deathtype=="stone crumble")
{
shatter();
ThrowHead(self.headmodel,self.health);
if(self.health<-99)
self.health=-99;
return;
}
else if(self.decap)
{
DecapPlayer();
if(self.health<-99)
self.health=-99;
return;
}
else if(self.health < -40||self.model=="models/sheep.mdl"||damage > 50)//self.modelindex==modelindex_sheep)
{
GibPlayer (dir + '0 0 1');
if(self.health<-99)
self.health=-99;
return;
}
DeathSound();
self.angles_x = 0;
self.angles_z = 0;
if(self.bloodloss==666)
DecapPlayer();
else
{
self.act_state=ACT_DEAD;
player_frames();
}
if(self.health<-99)
self.health=-99;
}
void set_suicide_frame ()
{ // used by klill command and diconnect command
if (self.model != self.init_model)
return; // already gibbed
//have a self.deathframe value? Or just if-thens
// self.frame = $deatha11;
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_TOSS;
self.deadflag = DEAD_DEAD;
self.nextthink = -1;
}
void Head ()
{
ThrowSolidHead(0);
}
void Corpse ()
{
MakeSolidCorpse();
}
void SolidPlayer ()
{
entity corpse;
corpse = spawn();
if(self.angles_x>15||self.angles_x<-15)
self.angles_x=0;
if(self.angles_z>15||self.angles_z<-15)
self.angles_z=0;
corpse.angles = self.angles;
setmodel(corpse,self.model);
corpse.frame = self.frame;
corpse.colormap = self.colormap;
corpse.movetype = self.movetype;
corpse.velocity = self.velocity;
corpse.flags = 0;
corpse.effects = 0;
corpse.skin = self.skin;
corpse.controller = self;
corpse.thingtype=self.thingtype;
setorigin (corpse, self.origin);
if(self.model==self.headmodel)
{
//self.classname=
corpse.classname="head";//So they don't get mixed up with players
corpse.think=Head;
}
else
{
//self.classname=
corpse.classname="corpse";//So they don't get mixed up with players
corpse.think=Corpse;
}
thinktime corpse : 0;
}
void player_behead ()
{
self.frame=self.level+self.cnt;
makevectors(self.angles);
if(!self.cnt)
MeatChunks (self.origin + '0 0 50',v_up*200, 3,self);
else if (self.cnt==1)
{
SpawnPuff (self.origin+v_forward*8, '0 0 48', 30,self);
sound (self, CHAN_AUTO, "misc/decomp.wav", 1, ATTN_NORM);
}
else if (self.cnt==3)
{
SpawnPuff (self.origin+v_forward*16, '0 0 36'+v_forward*16, 20,self);
sound (self, CHAN_AUTO, "misc/decomp.wav", 1, ATTN_NORM);
}
else if (self.cnt==5)
{
SpawnPuff (self.origin+v_forward*28, '0 0 20'+v_forward*32, 15,self);
sound (self, CHAN_AUTO, "misc/decomp.wav", 0.8, ATTN_NORM);
}
else if (self.cnt==8)
{
SpawnPuff (self.origin+v_forward*40, '0 0 10'+v_forward*40, 10,self);
sound (self, CHAN_AUTO, "misc/decomp.wav", 0.6, ATTN_NORM);
}
if (self.frame==self.dmg)
{
SpawnPuff (self.origin+v_forward*56, '0 0 -5'+v_forward*40, 5,self);
sound (self, CHAN_AUTO, "misc/decomp.wav", 0.4, ATTN_NORM);
ReadySolid();
}
else
{
self.think=player_behead;
thinktime self : 0.1;
}
self.cnt+=1;
}

185
altdeath.hc Normal file
View File

@ -0,0 +1,185 @@
void ice_melt (void)
{
self.scale -= 0.05;
if (self.scale<=0.05)
remove(self);
else
self.think=ice_melt;
thinktime self : 0.05;
}
void ice_think (void)
{
if(self.velocity=='0 0 0')
{
self.touch=SUB_Null;
self.think=ice_melt;
thinktime self : 1.5;
}
else
{
self.think=ice_think;
thinktime self : 0.1;
}
}
void ice_hit (void)
{
if (random()<0.2)
{
particleexplosion(self.origin,14,20,5);
remove(self);
}
}
void todust (void)
{
particleexplosion(self.origin,self.aflag,20,5);
remove(self);
}
void pebble_hit (void)
{
self.wait=self.wait + 1;
sound(self,CHAN_BODY,"misc/rubble.wav",1,ATTN_NORM);
if(self.wait>=3||random()<0.1)
todust();
else
{
self.think=todust;
thinktime self : 2;
}
}
/*
void ash_hit (void)
{
sound(self,CHAN_BODY,"misc/rubble.wav",1,ATTN_NORM);
self.wait=self.wait + 1;
if(self.wait>=3||random()<0.2)
todust();
else
{
self.think=todust;
thinktime self : 1;
}
}
*/
void throw_shard (vector org,vector dir,vector spin,string type,vector ownersize)
{
float chunk_size;
newmis=spawn_temp();
newmis.movetype=MOVETYPE_BOUNCE;
newmis.solid=SOLID_TRIGGER;
newmis.velocity=dir;
newmis.avelocity=spin;
chunk_size=(ownersize_x+ownersize_y+ownersize_z)/3;
newmis.scale=random(0.5)*chunk_size/24;
if(!newmis.scale)
newmis.scale=0.3;
newmis.classname="type";
setmodel(newmis,"models/shard.mdl");
if(type=="ice")
{
newmis.skin=0;
newmis.frame=0;
newmis.touch=ice_hit;
newmis.think=ice_think;
thinktime newmis : 1;
newmis.drawflags(+)DRF_TRANSLUCENT|MLS_ABSLIGHT;
newmis.abslight=0.75;
}
else if(type=="pebbles")
{
newmis.skin=1;
newmis.frame=rint(random(1,2));
newmis.touch=pebble_hit;
newmis.speed=16;
newmis.aflag=10;
}
/* else if(type=="ashes")
{
newmis.skin=2;
newmis.frame=rint(random(1,2));
newmis.touch=ash_hit;
newmis.speed=1;
newmis.aflag=10;
}
*/ setsize(newmis,'0 0 0','0 0 0');
setorigin(newmis,org);
}
void shatter ()
{
vector dir,spin,org;
float numshards,maxshards,rng;
string type;
if(self.movechain!=world&&!self.movechain.flags&FL_CLIENT)
remove(self.movechain);
if(self.scale==0)
self.scale=1;
if(self.classname=="snowball")
maxshards=random(4,2);
else
maxshards=random(7,10);
org=(self.absmin+self.absmax)*0.5;
if(self.deathtype=="ice shatter"||self.deathtype=="ice melt")
{
//origin color radius count
particleexplosion(org,14,25,50);
// particle2(org,'-50 -50 -50','50 50 50',145,14,50);
if(self.deathtype=="ice shatter")
rng=600;
else
rng=self.size_x/2;
type="ice";
}
else if(self.deathtype=="stone crumble")
{
sound(self,CHAN_BODY,"misc/sshatter.wav",1,ATTN_NORM);
particleexplosion(org,10,60,50);
// particle2(org,'-30 -30 -30','30 30 30',16,10,50);
rng=450;
type="pebbles";
}
/* else if(self.deathtype=="burnt crumble")
{
sound(self,CHAN_BODY,"misc/bshatter.wav",1,ATTN_NORM);
particleexplosion(org,1,60,50);
// particle2(org,'-30 -30 -30','30 30 30',1,10,50);
rng=200;
type="ashes";
}
*/
if(type == "ice")
{
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_ICEHIT);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
WriteByte (MSG_MULTICAST, 2); // type of icehit -> shatter type
multicast(self.origin,MULTICAST_PHS_R);
}
else
{
// do stone junk
while(numshards<maxshards)
{
dir_x=random(0-rng,rng);
dir_y=random(0-rng,rng);
dir_z=random(0-rng,rng);
spin_x=random(300,-300);
spin_y=random(300,-300);
spin_z=random(300,-300);
throw_shard(org,dir,spin,type,self.size);
numshards+=1;
}
}
if(self.movechain!=world&&!self.movechain.flags&FL_CLIENT)
remove(self.movechain);
if(self.classname!="player")
remove(self);
}

93
amtest.hc Normal file
View File

@ -0,0 +1,93 @@
/*
* $Header: /HexenWorld/Siege/Amtest.hc 3 5/25/98 1:38p Mgummelt $
*/
void() test_teleport_touch;
void() tele_done;
/*QUAKED test_teleport (0 .5 .8) ?
Teleporter testing
-------------------------FIELDS-------------------------
None
--------------------------------------------------------
*/
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
-------------------------FIELDS-------------------------
None
--------------------------------------------------------
*/
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);
};

898
archer.hc Normal file
View File

@ -0,0 +1,898 @@
/*
* $Header: /HexenWorld/Siege/archer.hc 4 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\monsters\archerK\final\archer.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\monsters\archerK\final
$origin 0 0 0
$base base skin
$skin skin
$flags 0
//
$frame backup1 backup2 backup3 backup4 backup5
$frame backup6 backup7 backup8
//
$frame deathA1 deathA2 deathA3 deathA4 deathA5
$frame deathA6 deathA7 deathA8 deathA9 deathA10
$frame deathA11 deathA12 deathA13 deathA14 deathA15
$frame deathA16 deathA17 deathA18 deathA19 deathA20
$frame deathA21 deathA22
//
$frame draw1 draw2 draw3 draw4 draw5
$frame draw6 draw7 draw8 draw9 draw10
$frame draw11 draw12 draw13
//
$frame duck1 duck2 duck3 duck4 duck5
$frame duck6 duck7 duck8 duck9 duck10
$frame duck11 duck12 duck13 duck14
//
$frame fire1 fire2 fire3 fire4
//
$frame pain1 pain2 pain3 pain4 pain5
$frame pain6 pain7 pain8 pain9 pain10
$frame pain11 pain12 pain13 pain14 pain15
$frame pain16
//
$frame patrol1 patrol2 patrol3 patrol4 patrol5
$frame patrol6 patrol7 patrol8 patrol9 patrol10
$frame patrol11 patrol12 patrol13 patrol14 patrol15
$frame patrol16 patrol17 patrol18 patrol19 patrol20
$frame patrol21 patrol22
//
$frame redraw1 redraw2 redraw3 redraw4 redraw5
$frame redraw6 redraw7 redraw8 redraw9 redraw10
$frame redraw11 redraw12
//
$frame tranA1 tranA2 tranA3 tranA4 tranA5
$frame tranA6 tranA7 tranA8 tranA9 tranA10
$frame tranA11 tranA12 tranA13
//
$frame tranB1 tranB2 tranB3 tranB4 tranB5
$frame tranB6 tranB7 tranB8 tranB9 tranB10
$frame tranB11 tranB12 tranB13 tranB14 tranB15
$frame tranB16
//
$frame tranC1 tranC2 tranC3 tranC4 tranC5
$frame tranC6 tranC7 tranC8 tranC9 tranC10
//
$frame tranD1 tranD2 tranD3 tranD4 tranD5
$frame tranD6 tranD7 tranD8 tranD9
//
$frame waitA1 waitA2 waitA3 waitA4 waitA5
$frame waitA6 waitA7 waitA8 waitA9 waitA10
$frame waitA11 waitA12 waitA13 waitA14 waitA15
$frame waitA16 waitA17 waitA18
//
$frame waitB1 waitB2 waitB3 waitB4 waitB5
$frame waitB6 waitB7 waitB8 waitB9 waitB10
$frame waitB11 waitB12
//
$frame walk1 walk2 walk3 walk4 walk5
$frame walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12 walk13 walk14 walk15
$frame walk16
float ARCHER_STUCK = 2; // Archer can't run
float GREEN_ARROW = 0;
float RED_ARROW = 1;
float GOLD_ARROW = 2;
void archer_run(void);
void archer_stand(void);
void archerredraw(void);
void archerdraw(void);
void()archerdrawhold;
void archermissile(void);
void()archer_check_defense;
float archer_check_shot(void)
{
vector spot1,spot2;
makevectors(self.angles);
// see if any entities are in the way of the shot
spot1 = self.origin + v_right * 10 + v_up * 36;
spot2 = self.enemy.origin + self.enemy.view_ofs;
traceline (spot1, spot2, FALSE, self);
if (trace_ent.thingtype >= THINGTYPE_WEBS)
traceline(trace_endpos, spot2, FALSE, trace_ent);
if (trace_ent != self.enemy)
{
if ((trace_ent.thingtype!=THINGTYPE_GLASS) || !trace_ent.takedamage ||
(trace_ent.flags & FL_MONSTER && trace_ent.classname!="player_sheep"))
{
return FALSE;
}
}
return TRUE;
}
void archer_duck () [++ $duck1..$duck14]
{
ai_face();
if(cycle_wrapped)
{
setsize(self,'-16 -16 0','16 16 56');
if(infront(self.enemy))
self.think=archermissile;
else
self.think=archerdrawhold;
thinktime self : 0;
return;
}
else if (self.frame==$duck1)
if (self.classname == "monster_archer")
sound (self, CHAN_VOICE, "archer/growl.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "archer/pain2.wav", 1, ATTN_NORM);
else if (self.frame == $duck5)
setsize(self,'-16 -16 0','16 16 28');
else if (self.frame==$duck7)
{
archer_check_defense();
thinktime self :0.2;
}
}
void archer_check_defense()
{
entity enemy_proj;
if(random(2)>skill/10+self.skin/2)
return;
if (self.enemy.last_attack+0.5<time&&self.oldenemy.last_attack+0.5<time)
return;
enemy_proj=look_projectiles();
if(!enemy_proj)
if(lineofsight(self,self.enemy))
{
enemy_proj=self.enemy;
self.level=vlen(self.enemy.origin-self.origin)/1000;
}
else
return;
if(mezzo_check_duck(enemy_proj))
{
if(self.think==archer_duck)
self.frame=$duck6;
else
{
self.think=archer_duck;
thinktime self : 0;
}
return;
}
}
void archer_arrow_touch(void)
{
float damg;
vector delta;
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
if (self.owner.classname == "monster_archer")
damg = random(5,7);
else
{
if (self.classname == "red_arrow")
damg = random(8,12);
else // the gold arrow
damg = random(13,17);
}
if ((other.classname == "player") && (self.classname == "gold_arrow"))
{
delta = other.origin - self.origin;
other.velocity = delta * 10;
if (other.flags & FL_ONGROUND)
other.flags (-) FL_ONGROUND;
other.velocity_z = 150;
}
T_Damage (other, self, self.owner, damg );
self.origin = self.origin - 8 * normalize(self.velocity) - '0 0 40';
sound (self, CHAN_WEAPON, "weapons/explode.wav", 1, ATTN_NORM);
if (self.classname == "gold_arrow")
CreateSpark (self.origin);
else if (self.classname == "red_arrow")
CreateRedSpark (self.origin);
else
CreateGreenSpark (self.origin);
remove(self);
}
void archer_dying (void) [++ $deathA1..$deathA22]
{
stopSound(self,CHAN_WEAPON);
//sound (self, CHAN_WEAPON, "misc/null.wav", 1, ATTN_NORM);
if (self.health < -80)
{
chunk_death();
remove(self);
}
if (cycle_wrapped)
{
self.frame = $deathA22;
MakeSolidCorpse();
}
}
void() archer_die =
{
// check for gib
if (self.health < -30)
{
chunk_death();
return;
}
else
{
if (self.classname == "monster_archer")
sound (self, CHAN_VOICE, "archer/death.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "archer/death2.wav", 1, ATTN_NORM);
}
archer_dying();
};
/*-----------------------------------------
archer_pain - flinch in pain
-----------------------------------------*/
void archer_pain_anim () [++ $pain1 .. $pain16]
{
if (self.frame == $pain2)
{
if (self.classname == "monster_archer")
sound (self, CHAN_VOICE, "archer/pain.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "archer/pain2.wav", 1, ATTN_NORM);
}
if (self.frame==$pain16)
{
self.pain_finished = time + random(4,6);
archerredraw();
}
}
void archer_pain (entity attacker, float damg)
{
if ((self.frame >= $pain1) && (self.frame <= $pain16)) // Still going through pain anims
return;
if (self.attack_state == AS_MISSILE)
return;
// Hurt him, will he flinch or fight back?
setsize(self,'-16 -16 0','16 16 56');
if ((self.pain_finished > time) || (random() < .5))
{
archerredraw();
}
else
archer_pain_anim();
}
void archer_launcharrow (float arrowtype,vector spot1,vector spot2)
{
self.last_attack=time;
makevectors(self.angles);
if (arrowtype==GREEN_ARROW)
{
sound (self, CHAN_WEAPON, "archer/arrowg.wav", 1, ATTN_NORM);
Create_Missile(self,spot1,spot2, "models/akarrow.mdl","green_arrow",0,1000,archer_arrow_touch);
}
else if (arrowtype==RED_ARROW)
{
sound (self, CHAN_WEAPON, "archer/arrowr.wav", 1, ATTN_NORM);
CreateRedFlash(spot1);
Create_Missile(self,spot1,spot2,"models/akarrow.mdl","red_arrow",1,1000,archer_arrow_touch);
}
else
{
sound (self, CHAN_WEAPON, "archer/arrowg.wav", 1, ATTN_NORM);
CreateRedFlash(spot1);
Create_Missile(self,spot1,spot2,"models/akarrow.mdl","gold_arrow",2,1000,archer_arrow_touch);
}
newmis.drawflags(+)MLS_ABSLIGHT;
newmis.abslight=0.5;
thinktime newmis : 2.5;
}
/*-----------------------------------------
archerdrawdone - drawing his bow to fire
-----------------------------------------*/
void archerdrawdone () [-- $tranA7..$tranA1]
{
archer_check_defense();
walkmove(self.angles_y,0.5,FALSE);
if(visible(self.enemy))
ai_face();
if(cycle_wrapped)
{
self.pausetime = time + random(.5,2);
self.attack_state = AS_WAIT;
archer_run();
}
}
/*-----------------------------------------
archermissile - fire his arrow
-----------------------------------------*/
void archermissile () [++ $fire1..$fire4]
{
float enemy_range,chance,ok,tspeed;
vector spot1, spot2;
self.attack_state = AS_MISSILE;
if(visible(self.enemy))
ai_face();
else
{
self.think=self.th_run;
thinktime self : 0;
return;
}
if (self.frame == $fire2) // FIRE!!!!
{
makevectors(self.angles);
spot1 = self.origin + v_forward*4 + v_right * 10 + v_up * 36;
if(self.classname=="monster_archer_lord")
{
tspeed=vlen(self.enemy.velocity);
if(tspeed>100)
spot2=extrapolate_pos_for_speed(spot1,1000,self.enemy,0.3);
}
if(spot2=='0 0 0')
{
spot2 = self.enemy.origin + self.enemy.view_ofs;
traceline (spot1, spot2, FALSE, self);
if(trace_ent.thingtype>=THINGTYPE_WEBS)
traceline (trace_endpos, spot2, FALSE, trace_ent);
if (trace_ent == self.enemy)
ok=TRUE;
else if((trace_ent.health<=25||trace_ent.thingtype>=THINGTYPE_WEBS)&&trace_ent.takedamage&&(!trace_ent.flags&FL_MONSTER||trace_ent.classname=="player_sheep"))
ok=TRUE;
}
else
ok=TRUE;
if(ok)
{
enemy_range = range(self.enemy);
if (enemy_range < RANGE_MELEE) // Which arrow to use?
chance = 0.80;
else if (enemy_range < RANGE_NEAR)
chance = 0.50;
else if (enemy_range < RANGE_MID)
chance = 0.30;
else if (enemy_range < RANGE_FAR)
chance = 0.10;
if (self.classname=="monster_archer")
{
if (random(1) < chance)
archer_launcharrow(RED_ARROW,spot1,spot2);
else
archer_launcharrow(GREEN_ARROW,spot1,spot2);
}
else // Archer Lord
{
if (random(1) < chance)
archer_launcharrow(GOLD_ARROW,spot1,spot2);
else
archer_launcharrow(RED_ARROW,spot1,spot2);
}
self.attack_finished = time + random(.5,1);
if(!self.skin)
chance-=0.3;
chance+=skill/10;
// Reattack?
if (random () > chance) // Is he done?
archerdrawdone();
}
else
{
self.attack_finished = time + random();
stopSound(self,CHAN_WEAPON);
//sound (self, CHAN_WEAPON, "misc/null.wav", 1, ATTN_NORM);
archer_run();
return;
}
}
if(cycle_wrapped)
{
self.frame = $draw10 ;
archerredraw();
}
else if(visible(self.enemy))
ai_face();
}
/*-----------------------------------------
archerredraw - redrawing his bow to fire
-----------------------------------------*/
void archerredraw () [++ $redraw1..$redraw12]
{
self.attack_state = AS_MISSILE;
archer_check_defense();
if (self.frame == $redraw8)
sound (self, CHAN_WEAPON, "archer/draw.wav", 1, ATTN_NORM);
if (cycle_wrapped)
archermissile();
else if(visible(self.enemy))
ai_face();
else
{
self.think=self.th_run;
thinktime self : 0;
return;
}
}
/*-----------------------------------------
archerdrawhold - waiting for right chance to attack
-----------------------------------------*/
void archerdrawhold ()
{
float chance,startframe,endframe;
if(visible(self.enemy))
ai_face();
else
{
self.think=self.th_run;
thinktime self : 0;
return;
}
archer_check_defense();
startframe=$waitB1;
endframe=$waitB12;
if (!self.spawnflags & ARCHER_STUCK)
{
if (vlen(self.enemy.origin - self.origin)<=200)
{
if(infront(self.enemy))
if(walkmove(self.angles_y+180,3,FALSE))
{
startframe=$backup1;
endframe=$backup8;
}
}
}
AdvanceFrame(startframe,endframe);
self.think=archerdrawhold;
thinktime self : 0.05;
enemy_range = range(self.enemy);
if (enemy_range < RANGE_NEAR && random() < 0.4)
archermissile();
else if (cycle_wrapped||random()<skill/20+self.skin/10)
{
if (!archer_check_shot())
{
stopSound(self,CHAN_WEAPON);
//sound (self, CHAN_WEAPON, "misc/null.wav", 1, ATTN_NORM);
self.attack_state = AS_STRAIGHT;
self.think = archer_run;
thinktime self : HX_FRAME_TIME;
return;
}
if (self.classname == "monster_archer") // Monster archer's not so smart
{
if (enemy_range <= RANGE_MELEE)
chance = 1;
else if (enemy_range <= RANGE_NEAR)
chance = 0.70;
else if (enemy_range <= RANGE_MID)
chance = 0.60;
else if (enemy_range <= RANGE_FAR)
chance = 0.50;
}
else
chance = 1;
if (random() < chance)
archermissile();
}
}
/*-----------------------------------------
archerdraw - drawing his bow to fire
-----------------------------------------*/
void archerdraw () [++ $tranA1..$tranA13]
{
archer_check_defense();
if (self.frame == $tranA1) // See if he should even try to shoot
{
if (!archer_check_shot())
{
self.attack_state = AS_STRAIGHT;
self.think = archer_run;
thinktime self : HX_FRAME_TIME;
return;
}
}
if (self.frame == $tranA6)
sound (self, CHAN_WEAPON, "archer/draw.wav", 1, ATTN_NORM);
if ((self.frame >= $tranA1) && (self.frame <= $tranA13))
walkmove(self.angles_y+180,.28,FALSE);
if (cycle_wrapped) // Archer has drawn the arrow
archerdrawhold();
else if (visible(self.enemy))
ai_face();
else
{
self.think=self.th_run;
thinktime self : 0;
return;
}
if ((random(1)<.10) && (self.frame == $walk1))
{
if (self.classname == "monster_archer")
sound (self, CHAN_BODY, "archer/growl.wav", 1, ATTN_NORM);
else
{
if (random() < .70)
sound (self, CHAN_BODY, "archer/growl2.wav", 1, ATTN_NORM);
else
sound (self, CHAN_BODY, "archer/growl3.wav", 1, ATTN_NORM);
}
}
}
/*-----------------------------------------
archer_run - run towards the enemy
-----------------------------------------*/
void archer_run(void)
{
self.think = archer_run;
thinktime self : HX_FRAME_TIME;
archer_check_defense();
if ((random(1)<.10) && (self.frame == $walk1))
{
if (self.classname == "monster_archer")
sound (self, CHAN_VOICE, "archer/growl.wav", 1, ATTN_NORM);
else
{
if (random() < .70)
sound (self, CHAN_VOICE, "archer/growl2.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "archer/growl3.wav", 1, ATTN_NORM);
}
}
if ((self.spawnflags & ARCHER_STUCK) || (self.attack_state == AS_WAIT))
{
AdvanceFrame($waitA1,$waitA18);
ai_run(0);
}
else
{
AdvanceFrame($walk1,$walk16);
ai_run(4);
}
}
/*-----------------------------------------
archer_walk - walking his beat
-----------------------------------------*/
void archer_walk(void) [++ $patrol1..$patrol22]
{
thinktime self : HX_FRAME_TIME + .01; // Make him move a little slower so his run will look faster
archer_check_defense();
if ((random()<.05) && (self.frame == $patrol1))
{
if (self.classname == "monster_archer")
sound (self, CHAN_VOICE, "archer/growl.wav", 1, ATTN_NORM);
else
{
if (random() < .70)
sound (self, CHAN_VOICE, "archer/growl2.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "archer/growl3.wav", 1, ATTN_NORM);
}
}
if (self.spawnflags & ARCHER_STUCK) // No moving
{
self.frame = $patrol1; // FIXME: this should be the wait animations
ai_walk(0);
}
else
ai_walk(2.3);
}
/*-----------------------------------------
archer_stand - standing and waiting
-----------------------------------------*/
void archer_stand(void) [++ $waitA1..$waitA18]
{
if (random()<0.5)
{
archer_check_defense();
ai_stand();
}
}
/*QUAKED monster_archer (1 0.3 0) (-16 -16 0) (16 16 50) AMBUSH STUCK JUMP PLAY_DEAD DORMANT
The Archer Knight monster
-------------------------FIELDS-------------------------
Health : 80
Experience Pts: 25
Favorite TV shows: Friends & Baywatch
Favorite Color: Blue
Likes: Shooting arrows into people and long walks along the beach
Dislikes: Anything having to do with Pauly Shore
--------------------------------------------------------
*/
void monster_archer ()
{
if (deathmatch)
{
remove(self);
return;
}
if (!self.flags2 & FL_SUMMONED)
{
precache_archer();
}
CreateEntityNew(self,ENT_ARCHER,"models/archer.mdl",archer_die);
self.th_stand = archer_stand;
self.th_walk = archer_walk;
self.th_run = archer_run;
self.th_melee = archerdraw;
self.th_missile = archerdraw;
self.th_pain = archer_pain;
self.decap = 0;
self.headmodel = "models/archerhd.mdl";
self.mintel = 7;
self.monsterclass = CLASS_GRUNT;
self.experience_value = 25;
self.health = 80;
self.flags (+) FL_MONSTER;
self.yaw_speed = 10;
self.view_ofs = '0 0 40';
walkmonster_start();
}
/*QUAKED monster_archer_lord (1 0.3 0) (-16 -16 0) (16 16 50) AMBUSH STUCK JUMP PLAY_DEAD DORMANT
The Archer Lord monster
-------------------------FIELDS-------------------------
Health : 325
Experience Pts: 200
Favorite Cities: Madrid & Las Vegas
Favorite Flower: Orchid
What people don't know about me: I cry at sad movies
What people say when they see me: Don't shoot!! Don't shoot!!
--------------------------------------------------------
*/
void monster_archer_lord ()
{
if (deathmatch)
{
remove(self);
return;
}
if (!self.flags2 & FL_SUMMONED)
{
precache_model("models/archer.mdl");
precache_model("models/archerhd.mdl");
precache_model("models/gspark.spr");
precache_sound ("archer/arrowg.wav");
precache_sound ("archer/arrowr.wav");
precache_sound ("archer/growl2.wav");
precache_sound ("archer/growl3.wav");
precache_sound ("archer/pain2.wav");
precache_sound ("archer/sight2.wav");
precache_sound ("archer/death2.wav");
precache_sound ("archer/draw.wav");
}
CreateEntityNew(self,ENT_ARCHER,"models/archer.mdl",archer_die);
self.th_stand = archer_stand;
self.th_walk = archer_walk;
self.th_run = archer_run;
self.th_melee = archerdraw;
self.th_missile = archerdraw;
self.th_pain = archer_pain;
self.decap = 0;
self.headmodel = "models/archerhd.mdl";
self.mintel = 7;
self.monsterclass = CLASS_HENCHMAN;
self.experience_value = 200;
self.health = 325;
self.skin = 1;
self.flags (+) FL_MONSTER;
self.yaw_speed = 10;
self.view_ofs = '0 0 40';
walkmonster_start();
}
/*
=================
ArcherCheckAttack
=================
*/
float ArcherCheckAttack (void)
{
local vector spot1, spot2;
local entity targ;
local float chance;
// if (enemy_range <= RANGE_MELEE) // Enemy is too close...attack
// {
// self.attack_state = AS_MISSILE;
self.pain_finished = 0;
// self.attack_finished = 0;
// }
if (self.attack_finished > time)
return FALSE;
if (!enemy_vis)
return FALSE;
if (enemy_range == RANGE_FAR)
{
if (self.attack_state != AS_STRAIGHT)
{
self.attack_state = AS_STRAIGHT;
archer_run ();
}
return FALSE;
}
targ = self.enemy;
makevectors(self.angles);
// see if any entities are in the way of the shot
spot1 = self.origin + v_right * 10 + v_up * 36;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, FALSE, self);
if(trace_ent.thingtype>=THINGTYPE_WEBS)
traceline (trace_endpos, spot2, FALSE, trace_ent);
if (trace_ent != targ)
if((trace_ent.health>25&&trace_ent.thingtype!=THINGTYPE_GLASS)||!trace_ent.takedamage||(trace_ent.flags&FL_MONSTER&&trace_ent.classname!="player_sheep"))
{
self.attack_state = AS_STRAIGHT;
return FALSE;
}
// Chances of attack
// 50% at MID range
// 65% at NEAR range
// 80% at MELEE range
enemy_range = range(self.enemy);
if (enemy_range == RANGE_MELEE)
chance = 0.40;
else if (enemy_range == RANGE_NEAR)
chance = 0.3;
else if (enemy_range == RANGE_MID)
chance = 0.2;
else
chance = 0;
if ((random () < chance) && (self.attack_state != AS_MISSILE)) // Will he attack?
{
self.attack_state = AS_MISSILE;
return TRUE;
}
if (enemy_range == RANGE_MID)
{
if (random (1) < .5) // Will he side step?
self.attack_state = AS_SLIDING;
else
self.attack_state = AS_STRAIGHT;
}
else
{
if (self.attack_state != AS_SLIDING)
self.attack_state = AS_SLIDING;
}
return FALSE;
}

1260
artifact.hc Normal file

File diff suppressed because it is too large Load Diff

429
assassin.hc Normal file
View File

@ -0,0 +1,429 @@
/*
* $Header: /HexenWorld/Siege/assassin.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\players\assassin\newfinal\assassin.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\players\assassin\newfinal
$origin 0 0 0
$base BASE Skin
$skin Skin
$flags 0
//
$frame attdag1 attdag2 attdag3 attdag4 attdag5
$frame attdag6 attdag7 attdag8 attdag9 attdag10
$frame attdag11
//
$frame attstf1 attstf2 attstf3 attstf4
//
$frame attxbw1 attxbw2 attxbw3 attxbw4
//
$frame crouch1 crouch2 crouch3 crouch4 crouch5
$frame crouch6 crouch7 crouch8 crouch9 crouch10
$frame crouch11 crouch12 crouch13 crouch14 crouch15
$frame crouch16 crouch17 crouch18 crouch19 crouch20
//
$frame death1 death2 death3 death4 death5
$frame death6 death7 death8 death9 death10
$frame death11 death12 death13 death14 death15
$frame death16 death17 death18 death19 death20
//
$frame decap1 decap2 decap3 decap4 decap5
$frame decap6 decap7 decap8 decap9 decap10
$frame decap11 decap12 decap13 decap14 decap15
$frame decap16 decap17 decap18 decap19 decap20
$frame decap21 decap22 decap23 decap24 decap25
$frame decap26 decap27 decap28
//
$frame flydag1 flydag2 flydag3 flydag4 flydag5
$frame flydag6 flydag7 flydag8 flydag9 flydag10
$frame flydag11 flydag12 flydag13 flydag14 flydag15
//
$frame flystf1 flystf2 flystf3 flystf4 flystf5
$frame flystf6 flystf7 flystf8 flystf9 flystf10
$frame flystf11 flystf12 flystf13 flystf14 flystf15
//
$frame flyxbw1 flyxbw2 flyxbw3 flyxbw4 flyxbw5
$frame flyxbw6 flyxbw7 flyxbw8 flyxbw9 flyxbw10
$frame flyxbw11 flyxbw12 flyxbw13 flyxbw14 flyxbw15
//
$frame jump1 jump2 jump3 jump4 jump5
$frame jump6 jump7 jump8 jump9 jump10
$frame jump11 jump12
//
$frame paindag1 paindag2 paindag3 paindag4 paindag5
$frame paindag6 paindag7
//
$frame painstf1 painstf2 painstf3 painstf4 painstf5
$frame painstf6 painstf7
//
$frame painxbw1 painxbw2 painxbw3 painxbw4 painxbw5
$frame painxbw6 painxbw7
//
$frame rundag1 rundag2 rundag3 rundag4 rundag5
$frame rundag6 rundag7 rundag8 rundag9 rundag10
$frame rundag11 rundag12
//
$frame runstf1 runstf2 runstf3 runstf4 runstf5
$frame runstf6 runstf7 runstf8 runstf9 runstf10
$frame runstf11 runstf12
//
$frame runxbw1 runxbw2 runxbw3 runxbw4 runxbw5
$frame runxbw6 runxbw7 runxbw8 runxbw9 runxbw10
$frame runxbw11 runxbw12
//
$frame stddag1 stddag2 stddag3 stddag4 stddag5
$frame stddag6 stddag7 stddag8 stddag9 stddag10
$frame stddag11 stddag12 stddag13
//
$frame stdstf1 stdstf2 stdstf3 stdstf4 stdstf5
$frame stdstf6 stdstf7 stdstf8 stdstf9 stdstf10
$frame stdstf11 stdstf12 stdstf13
//
$frame stdxbw1 stdxbw2 stdxbw3 stdxbw4 stdxbw5
$frame stdxbw6 stdxbw7 stdxbw8 stdxbw9 stdxbw10
$frame stdxbw11 stdxbw12 stdxbw13
/*--------------------------
ACTUAL (UNIQUE TO CLASS) PLAYER CODE
----------------------------*/
void() player_assassin_run;
void() player_assassin_crouch_stand;
void() player_assassin_crouch_move;
void() player_assassin_stand;
float test_array [2] =
{
1, 2
};
void() player_assassin_jump=[++ test_array[1] .. test_array[2] ]
{
if(self.viewentity==self)
self.th_weapon();
if(cycle_wrapped)
{
if(!self.velocity_x && !self.velocity_y)
self.think=self.th_stand;
else
self.think=self.th_run;
}
};
void() player_assassin_swim =
{
if(self.viewentity==self)
self.th_weapon();
if(self.waterlevel<3)
if (self.velocity_x || self.velocity_y)
self.think=self.th_run;
else
self.think=self.th_stand;
};
void() player_assassin_hands_swim =[++$flydag1..$flydag15]
{
player_assassin_swim();
};
void() player_assassin_staff_swim =[++$flystf1..$flystf15]
{
player_assassin_swim();
};
void() player_assassin_xbow_swim =[++$flyxbw1..$flyxbw15]
{
player_assassin_swim();
};
void() player_assassin_fly =
{
if(self.viewentity==self)
self.th_weapon();
if(self.waterlevel>2)
self.think=self.th_swim;
else if(self.movetype!=MOVETYPE_FLY)
if (self.velocity_x || self.velocity_y)
self.think=self.th_run;
else
self.think=self.th_stand;
};
void() player_assassin_hands_fly =[++$flydag1..$flydag15]
{
player_assassin_fly();
};
void() player_assassin_staff_fly =[++$flystf1..$flystf15]
{
player_assassin_fly();
};
void() player_assassin_xbow_fly =[++$flyxbw1..$flyxbw15]
{
player_assassin_fly();
};
void() player_assassin_stand =
{
if(self.viewentity==self)
self.th_weapon();
if(self.hull==HULL_CROUCH)
self.think=player_assassin_crouch_stand;
else if(self.waterlevel>2)
self.think=self.th_swim;
else if(self.movetype==MOVETYPE_FLY)
self.think=self.th_fly;
else if (self.velocity_x || self.velocity_y)
self.think=self.th_run;
};
void() player_assassin_hands_stand =[++$stddag1..$stddag13]
{
player_assassin_stand();
};
void() player_assassin_staff_stand =[++$stdstf1..$stdstf13]
{
player_assassin_stand();
};
void() player_assassin_xbow_stand =[++$stdxbw1..$stdxbw13]
{
player_assassin_stand();
};
void() player_assassin_run =
{
if(self.viewentity==self)
self.th_weapon();
if(self.hull==HULL_CROUCH)
self.think=player_assassin_crouch_move;
else if(self.waterlevel>2)
self.think=self.th_swim;
else if(self.movetype==MOVETYPE_FLY)
self.think=self.th_fly;
else if (!self.velocity_x && !self.velocity_y)
self.think=self.th_stand;
};
void() player_assassin_hands_run =[++$rundag1..$rundag12]
{
player_assassin_run();
};
void() player_assassin_staff_run =[++$runstf1..$runstf12]
{
player_assassin_run();
};
void() player_assassin_xbow_run =[++$runxbw1..$runxbw12]
{
player_assassin_run();
};
void() player_assassin_crouch_stand =
{
if(self.viewentity==self)
self.th_weapon();
if(self.frame>$crouch20 || self.frame<$crouch1)
self.frame=$crouch1;
if(self.movetype==MOVETYPE_FLY)
self.think=self.th_fly;
else if(self.hull==HULL_PLAYER)
self.think=self.th_stand;
else if (self.velocity_x || self.velocity_y)
self.think=player_assassin_crouch_move;
thinktime self : HX_FRAME_TIME;
};
void() player_assassin_crouch_move =[++$crouch1..$crouch20]
{
if(self.viewentity==self)
self.th_weapon();
if(self.movetype==MOVETYPE_FLY)
self.think=player_assassin_fly;
else if(self.hull==HULL_PLAYER)
self.think=self.th_run;
else if (!self.velocity_x && !self.velocity_y)
self.think=player_assassin_crouch_stand;
};
void() player_assassin_attack=
{
if(self.viewentity==self)
self.th_weapon();
if(cycle_wrapped&&!self.button0)
{
if(!self.velocity_x && !self.velocity_y)
self.think=self.th_stand;
else
self.think=self.th_run;
}
};
void() player_assassin_hands_attack=[++$attdag1..$attdag11]
{
player_assassin_attack();
};
void() player_assassin_xbow_attack=[++$attxbw1..$attxbw4]
{
player_assassin_attack();
};
void() player_assassin_staff_attack=[++$attstf1..$attstf4]
{
player_assassin_attack();
};
void() player_assassin_pain=
{
if(self.viewentity==self)
self.th_weapon();
if(cycle_wrapped)
{
if(!self.velocity_x && !self.velocity_y)
self.think=self.th_stand;
else
self.think=self.th_run;
}
};
void() player_assassin_hands_pain =[++$paindag1..$paindag7]
{
if(self.frame==$paindag1)
PainSound();
player_assassin_pain();
};
void() player_assassin_staff_pain =[++$painstf1..$painstf7]
{
if(self.frame==$painstf1)
PainSound();
player_assassin_pain();
};
void() player_assassin_xbow_pain =[++$painxbw1..$painxbw7]
{
if(self.frame==$painxbw1)
PainSound();
player_assassin_pain();
};
void() player_assassin_die1=[++$death1..$death20]
{
if(cycle_wrapped)
{
self.frame=$death20;
self.think=PlayerDead;
}
};
void() player_assassin_die2=[++$death1..$death20]
{
if(cycle_wrapped)
{
self.frame=$death20;
self.think=PlayerDead;
}
};
void() player_assassin_behead =
{
self.level=$decap1;
self.dmg=$decap28;
self.cnt=0;
player_behead();
};
void Ass_Change_Weapon (void)
{
if(self.weapon==IT_WEAPON1||self.weapon==IT_WEAPON3)
{
self.th_stand=player_assassin_hands_stand;
if(self.weapon==IT_WEAPON3)
self.th_missile=grenade_throw;
else
self.th_missile=Ass_Pdgr_Fire;
self.th_run=player_assassin_hands_run;
self.th_pain=player_assassin_hands_pain;
self.th_swim=player_assassin_hands_swim;
self.th_fly=player_assassin_hands_fly;
}
else if(self.weapon==IT_WEAPON4)
{
self.th_stand=player_assassin_staff_stand;
self.th_missile=ass_setstaff_fire;
self.th_run=player_assassin_staff_run;
self.th_pain=player_assassin_staff_pain;
self.th_swim=player_assassin_staff_swim;
self.th_fly=player_assassin_staff_fly;
}
else
{
self.th_stand=player_assassin_xbow_stand;
self.th_missile=crossbow_fire;
self.th_run=player_assassin_xbow_run;
self.th_pain=player_assassin_xbow_pain;
self.th_swim=player_assassin_xbow_swim;
self.th_fly=player_assassin_xbow_fly;
}
if(self.hull!=HULL_CROUCH)
self.think=self.th_stand;
}
/*
void assassin_spurt ()
{
makevectors(self.angles);
SpawnPuff (self.origin+'0 0 56'+v_forward*12, '0 0 35',5,self);
thinktime self : 1;
}
void assassin_hurt(void)
{
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
self.takedamage=DAMAGE_YES;
self.flags2(+)FL_ALIVE;
self.thingtype=THINGTYPE_FLESH;
self.frame=$painstf4;
self.colormap=187;
setmodel (self, "models/assassin.mdl");
setsize (self, '-16 -16 0', '16 16 200');
self.hull=HULL_POINT;
self.health = self.max_health=2000;
self.mass = 2000;
self.drawflags(+)MLS_ABSLIGHT;
self.abslight=0.5;
}
*/

294
assgren.hc Normal file
View File

@ -0,0 +1,294 @@
/*
* $Header: /HexenWorld/Siege/assgren.hc 16 5/25/98 1:38p Mgummelt $
* Grenade Throw, Assassin.
*/
/*
==============================================================================
Q:\art\models\weapons\grenades\final\assgr.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\weapons\grenades\final
$origin 0 0 0
$base BASE skin
$skin skin
$flags 0
$frame select1 select2 select3 select4 select5
$frame select6
$frame idle
$frame throw1 throw2 throw3 throw4 throw5
$frame throw6 throw7 throw8 throw9 throw10
$frame throw11 throw12
void grenade_trail ()
{
if(self.lifetime<time)
{
self.think=self.th_die;
thinktime self : 0;
}
else
{
// particle4(self.origin,0.5,284,PARTICLETYPE_SLOWGRAV,3);
thinktime self : 0.05;
}
}
void() ThrowMiniGrenade =
{
self.cnt_grenades-=1;
makevectors(self.v_angle);
sound(self,CHAN_WEAPON,"misc/whoosh.wav",1,ATTN_NORM);
entity missile;
missile=spawn();
missile.owner=self;
missile.classname="minigrenade";
missile.movetype=MOVETYPE_BOUNCE;
missile.solid=SOLID_BBOX;
missile.takedamage=DAMAGE_YES;
missile.health=3;
missile.th_die=DarkExplosion;
missile.touch=GrenadeTouch2;
missile.dmg=50;
// missile.lifetime=time+2;
missile.o_angle = self.origin+self.proj_ofs+v_forward*8+v_right*8;
missile.speed=500+self.weaponframe_cnt*10;
// missile.velocity=(normalize(v_forward)+'0 0 .4')*missile.speed;
//UQ method
if(self.v_angle_x)
missile.velocity = v_forward*missile.speed + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
else
{
missile.velocity = aim(self, missile.o_angle,1000);
missile.velocity = missile.velocity * missile.speed;
missile.velocity_z = 200;
}
missile.angles = vectoangles(missile.velocity);
missile.avelocity=randomv('-300 -300 -300','300 300 300');
setmodel(missile,"models/assgren.mdl");
missile.scale=0.77;
setsize(missile,'0 0 0','0 0 0');
setorigin(missile,missile.o_angle);
missile.think=missile.th_die;//grenade_trail;
thinktime missile : 2;//0;
};
void AssGrenExplosion ()
{
entity ignore;
// if(self.controller.classname=="multigrenade")
// sound(self.controller,CHAN_BODY,"weapons/explode.wav",1,ATTN_NORM);
// else
// sound(self,CHAN_AUTO,"weapons/explode.wav",1,ATTN_NORM);
ignore=world;
T_RadiusDamage (self, self.owner, self.dmg, ignore);
// BecomeExplosion(FALSE);
remove (self);
}
void() SuperGrenadeExplode =
{
entity missile;
float attack_counter,number_explosions;
self.takedamage=DAMAGE_NO;
self.th_die = SUB_Null;
attack_counter=0;
number_explosions=rint(random(3,6));
while(attack_counter<number_explosions)
{
attack_counter+=1;
// if(random()<0.5)
missile=spawn_temp();
// else
// missile=spawn();
missile.owner=self.owner;
missile.classname="minigrenade";
if(self.classname=="multigrenade")
{
missile.controller=self;
if(self.cnt)
self.cnt=FALSE;
else
self.cnt=TRUE;
}
if((self.classname=="multigrenade"&&self.cnt)||(self.classname!="multigrenade"&&self.movetype==MOVETYPE_BOUNCE))
{
missile.movetype=MOVETYPE_BOUNCE;
missile.velocity_x=random(-300,300);
missile.velocity_y=random(-300,300);
missile.velocity_z=random(50,150);
}
else
{
missile.movetype=MOVETYPE_FLYMISSILE;
missile.velocity_x=random(-40,40);
missile.velocity_y=random(-40,40);
missile.velocity_z=random(150,300);
}
missile.dmg=self.dmg=self.dmg*(0.7+random(0.2));
if(missile.dmg<70)
missile.dmg=70;
missile.solid=SOLID_NOT;
// setmodel(missile,"models/null.spr");
setsize(missile,'0 0 0','0 0 0');
setorigin(missile,self.origin);
if(missile.dmg>70)
missile.think=SuperGrenadeExplode;
else
missile.think=AssGrenExplosion;
thinktime missile : random(0.1,0.6);
missile.effects (+) EF_NODRAW;
}
self.dmg*=2;
if(self.classname=="multigrenade")
{
//testing: put back in damage!!!!!!
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_BIGGRENADE);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
multicast(self.origin,MULTICAST_PHS_R);
// remove(self);
if(random()<0.3)
MonsterQuake(200);
MultiExplode();
}
else
AssGrenExplosion();
};
void() ThrowMultiGrenade =
{//FIXME: too many t_rad's?
entity missile;
makevectors(self.v_angle);
sound(self,CHAN_WEAPON,"misc/whoosh.wav",1,ATTN_NORM);
missile=spawn();
missile.frags=TRUE;
missile.owner=self;
missile.classname="multigrenade";
missile.movetype=MOVETYPE_BOUNCE;
missile.solid=SOLID_BBOX;
missile.takedamage=DAMAGE_YES;
missile.health=3;
missile.th_die=SuperGrenadeExplode;
missile.touch=GrenadeTouch2;
missile.dmg=250;//simulates max level for now
missile.o_angle = self.origin+self.proj_ofs+v_forward*8+v_right*8;
missile.speed=500+self.weaponframe_cnt*10;
// missile.velocity=(normalize(v_forward)+'0 0 .4')*missile.speed;
//UQ method
if(self.v_angle_x)
missile.velocity = v_forward*missile.speed + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
else
{
missile.velocity = aim(self, missile.o_angle,1000);
missile.velocity = missile.velocity * missile.speed;
missile.velocity_z = 200;
}
missile.angles = vectoangles(missile.velocity);
missile.avelocity=randomv('-300 -300 -300','300 300 300');
setmodel(missile,"models/assgren.mdl");
missile.scale=2;
setsize (missile, '0 0 0', '0 0 0');
setorigin(missile,missile.o_angle);
missile.lifetime=time+2;
missile.think=grenade_trail;
thinktime missile : 0;
};
void()grenade_select;
void()grenade_throw;
void grenade_idle(void)
{
self.th_weapon=grenade_idle;
self.weaponframe=$idle;
}
void grenade_reload (void)
{
self.th_weapon=grenade_reload;
self.wfs = advanceweaponframe($select1,$select6);
self.weaponmodel = "models/v_assgr.mdl";
if (self.wfs==WF_CYCLE_WRAPPED)
grenade_idle();
}
void grenade_throw (void)
{
self.th_weapon=grenade_throw;
self.wfs = advanceweaponframe($throw1,$throw12);
if(self.button0&&self.weaponframe==$throw5)
{
self.weaponframe=$throw4;
if(self.weaponframe_cnt<50)
self.weaponframe_cnt+=1;
}
else if(self.weaponframe==$throw10)
{
if(self.artifact_active&ART_TOMEOFPOWER)
{
ThrowMultiGrenade();
self.attack_finished=time + 2;
}
else
{
ThrowMiniGrenade();
self.attack_finished=time+0.3;
}
self.weaponframe_cnt=0;
}
else if (self.wfs==WF_CYCLE_WRAPPED)
grenade_reload();
}
void grenade_select (void)
{
//selection sound?
self.th_weapon=grenade_select;
self.wfs = advanceweaponframe($select1,$select6);
self.weaponmodel = "models/v_assgr.mdl";
if (self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
grenade_idle();
}
}
void grenade_deselect (void)
{
//selection sound?
self.th_weapon=grenade_deselect;
self.wfs = advanceweaponframe($select6,$select1);
if (self.wfs==WF_CYCLE_WRAPPED)
W_SetCurrentAmmo();
}

90
assweap.hc Normal file
View File

@ -0,0 +1,90 @@
void() SnakeHit =
{
if(other==self.owner||(other.owner==self.owner&&other.classname=="snakearrow"))
return;
if(other.takedamage)
{
other.bloodloss=other.bloodloss+1;
SpawnPuff(other.origin,'0 0 0',self.mass,other);
T_Damage(other,self,self.owner,self.mass);
}
remove(self);
// MultiExplode();
};
void() FireSnakeArrow =
{
local entity missile;
missile=spawn();
missile.classname="snakearrow";
missile.movetype=MOVETYPE_FLYMISSILE;
missile.solid=SOLID_BBOX;
// missile.takedamage=DAMAGE_YES;
// missile.health=10;
if(self.classname=="player")
{
makevectors(self.v_angle);
missile.owner=self;
missile.mass=100;
missile.aflag=TRUE;
missile.o_angle=self.v_angle;
self.attack_finished=time + 0.5;
}
else
{
makevectors(self.o_angle);
missile.o_angle=self.o_angle;
}
// missile.th_die=MultiExplode;
missile.touch=SnakeHit;
missile.velocity=normalize(v_forward)*(350+self.mass);
// setmodel(missile,"models/laser.mdl");
missile.skin=2;
setsize(missile,'0 0 0','0 0 0');
if(self.classname=="snakearrow")
{
missile.owner=self.owner;
missile.mass=self.mass=self.mass*0.5;
setorigin(missile,self.origin);
if(self.aflag)
{
self.aflag=missile.aflag=FALSE;
missile.velocity=missile.velocity+v_right*30;
self.velocity=self.velocity-v_right*30;
}
else
{
self.aflag=missile.aflag=TRUE;
missile.velocity=missile.velocity+v_up*30;
self.velocity=self.velocity-v_up*30;
}
if(self.mass>10)
{
self.think=FireSnakeArrow;
self.nextthink=time + 0.15;
}
else
{
self.think=SUB_Remove;
self.nextthink=time+5;
}
}
else
setorigin(missile,self.origin+self.proj_ofs+v_forward*8);
missile.angles=vectoangles(missile.velocity);
if(missile.mass>10)
{
missile.think=FireSnakeArrow;
missile.nextthink=time + 0.15;
}
else
{
missile.think=SUB_Remove;
missile.nextthink=time+5;
}
};

329
axe.hc Normal file
View File

@ -0,0 +1,329 @@
/*
* $Header: /HexenWorld/Siege/axe.hc 22 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\weapons\axe\final\axe.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\weapons\axe\final
$origin 10 -10 10
$base BASE skin
$skin skin
$flags 0
$frame AxeRoot1
$frame 1stAxe1 1stAxe2 1stAxe3 1stAxe4 1stAxe5
$frame 1stAxe6 1stAxe7 1stAxe8
$frame 1stAxe11 1stAxe12 1stAxe14
$frame 1stAxe15 1stAxe17 1stAxe18
$frame 1stAxe21 1stAxe22 1stAxe23
$frame 1stAxe25 1stAxe27
float AXE_DAMAGE = 24;
float AXE_ADD_DAMAGE = 6;
void() T_PhaseMissileTouch;
void() T_PhaseMissileTouch =
{
local float damg;
self.flags (-) FL_ONGROUND; // So it never thinks it is touching the ground
if (other == self.owner)
return; // don't explode on owner
if ((self.enemy == other) && (other != world)) // Can't hit same enemy twice in a row but you can hit world twice
return;
self.cnt +=1;
// self.velocity = self.velocity * 0.75; // client's not interested in this happening...
self.angles = vectoangles(self.velocity);
if (pointcontents(self.origin) == CONTENT_SKY)
{
stopSound(self,0);
remove(self);
return;
}
if (other.health) // Hit something that can be hurt
{
if(self.classname == "powerupaxeblade")
{
damg = random(25, 45);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_AXE_EXPLODE);
WriteCoord (MSG_MULTICAST, self.origin_x - self.movedir_x * 16);
WriteCoord (MSG_MULTICAST, self.origin_y - self.movedir_y * 16);
WriteCoord (MSG_MULTICAST, self.origin_z - self.movedir_z * 16);
multicast(self.origin,MULTICAST_PHS_R);
T_RadiusDamage (self, self.owner, 30.0, other);
// get rid of it here or something?
}
else
{
damg = random(30,50);
}
T_Damage (other, self, self.owner, damg );
self.counter -=1;
self.enemy = other;
}
else
{
self.enemy = other;
if (self.cnt <4) // Bounce three times then die
{
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_AXE_BOUNCE);
WriteCoord (MSG_MULTICAST, self.origin_x - self.movedir_x * 16);
WriteCoord (MSG_MULTICAST, self.origin_y - self.movedir_y * 16);
WriteCoord (MSG_MULTICAST, self.origin_z - self.movedir_z * 16);
multicast(self.origin,MULTICAST_PHS_R);
}
else
self.counter = 0;
}
// Time is up
if (self.lifetime < time)
self.counter = 0;
if (self.counter < 1)
{
remove(self);
return;
}
self.think();
};
void axeblade_gone(void)
{
stopSound(self,0);
if (self.skin==0)
CreateLittleWhiteFlash(self.origin);
else
CreateLittleBlueFlash(self.origin);
remove(self);
}
/*void axeblade_run (void) [ ++ 0 .. 5]
{
self.angles = vectoangles(self.velocity);
if (self.lifetime < time)
axeblade_gone();
}*/
void axeblade_think(void)
{
self.movedir = normalize(self.velocity);
self.angles = vectoangles(self.movedir);
traceline(self.origin, self.origin + self.movedir * 330.0, TRUE, self);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_AXE);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
WriteByte (MSG_MULTICAST, self.angles_y*256.0/360.0);
WriteByte (MSG_MULTICAST, self.angles_x*256.0/360.0);
WriteByte (MSG_MULTICAST, trace_fraction * 100);
multicast(self.origin,MULTICAST_PVS);
thinktime self : 0.3;
if (self.lifetime < time)
axeblade_gone();
}
void launch_axe (vector dir_mod,vector angle_mod)
{
entity missile;
self.attack_finished = time + 0.4;
missile = spawn ();
CreateEntityNew(missile,ENT_AXE_BLADE,"models/axblade.mdl",SUB_Null);
missile.owner = self;
missile.classname = "ax_blade";
// set missile speed
makevectors (self.v_angle + dir_mod);
missile.velocity = normalize(v_forward);
missile.movedir = missile.velocity;
// PUT THIS BACK PLEASE
missile.velocity = missile.velocity * 1100;
missile.touch = T_PhaseMissileTouch;
// Point it in the proper direction
missile.angles = vectoangles(missile.velocity);
missile.angles += angle_mod;
// set missile duration
missile.counter = 4; // Can hurt two things before disappearing
missile.cnt = 0; // Counts number of times it has hit walls
missile.lifetime = time + 2; // Or lives for 2 seconds and then dies when it hits anything
setorigin (missile, self.origin + self.proj_ofs + v_forward*10 + v_right * 1);
if (self.artifact_active & ART_TOMEOFPOWER)
{
missile.frags=TRUE;
missile.classname = "powerupaxeblade";
missile.skin = 1;
missile.drawflags = (self.drawflags & MLS_MASKOUT)| MLS_POWERMODE;
}
else
missile.classname = "axeblade";
// thinktime missile : HX_FRAME_TIME;
// missile.think = axeblade_run;
missile.think = axeblade_think;
thinktime missile : 0.3;
missile.effects (+) EF_NODRAW;
entity oldself;
oldself = self;
self = missile;
missile.think();
self = oldself;
}
/*
================
axeblade_fire
================
*/
void() axeblade_fire =
{
float damg,damg_mod;
damg=random(7) + 5;
// damg=500;
damg_mod=melee_dmg_mod_for_strength(self.strength);
damg*=damg_mod;
if(self.playerclass==CLASS_DWARF)
FireMelee (damg,0,32);
else
FireMelee (damg,0,64);
/* if ((self.artifact_active & ART_TOMEOFPOWER) && (self.greenmana >= 8))
{
FireMelee (50,25,64);
weapon_sound(self, "paladin/axgen.wav");
launch_axe('0 3 0','0 0 0'); // Side
launch_axe('0 -3 0','0 0 0'); // Side
self.greenmana -= 8;
}
else if (self.greenmana >= 2)
{
FireMelee (WEAPON1_BASE_DAMAGE,WEAPON1_ADD_DAMAGE,64);
if (self.greenmana >= 2)
{
weapon_sound(self, "paladin/axgen.wav");
launch_axe('0 0 0','0 0 0');
self.greenmana -= 2;
}
}
*/
};
void axe_ready (void)
{
self.th_weapon=axe_ready;
self.weaponframe = $AxeRoot1;
}
void axe_select (void)
{
self.wfs = advanceweaponframe($1stAxe18,$1stAxe3);
if (self.weaponframe == $1stAxe14)
{
weapon_sound(self, "weapons/vorpswng.wav");
}
self.weaponmodel = "models/axe.mdl";
self.th_weapon=axe_select;
self.last_attack=time;
if (self.wfs == WF_LAST_FRAME)
{
self.attack_finished = time - 1;
axe_ready();
}
}
void axe_deselect (void)
{
self.wfs = advanceweaponframe($1stAxe18,$1stAxe3);
self.th_weapon=axe_deselect;
self.oldweapon = IT_WEAPON2;
if (self.wfs == WF_LAST_FRAME)
W_SetCurrentAmmo();
}
void axe_a (void)
{
self.wfs = advanceweaponframe($1stAxe1,$1stAxe25);
self.th_weapon = axe_a;
// These frames are used during selection animation
if ((self.weaponframe >= $1stAxe2) && (self.weaponframe <= $1stAxe4))
self.weaponframe +=1;
else if ((self.weaponframe >= $1stAxe6) && (self.weaponframe <= $1stAxe7))
self.weaponframe +=1;
if (self.weaponframe == $1stAxe15)
{
//sound (self, CHAN_WEAPON, "weapons/vorpswng.wav", 1, ATTN_NORM);
weapon_sound(self, "weapons/vorpswng.wav");
axeblade_fire();
}
if (self.wfs == WF_LAST_FRAME)
axe_ready();
}
void pal_axe_fire(void)
{
axe_a ();
if (self.artifact_active & ART_TOMEOFPOWER)
self.attack_finished = time + .7;
else if(self.playerclass==CLASS_DWARF)
self.attack_finished = time + 0.1;//time+rate_and_acc_for_weap[(self.playerclass - 1)*6+(self.weapon - 1)*2];
else
self.attack_finished = time + 0.2;//time+rate_and_acc_for_weap[(self.playerclass - 1)*6+(self.weapon - 1)*2];
}

886
barrel.hc Normal file
View File

@ -0,0 +1,886 @@
/*
* $Header: /HexenWorld/Siege/barrel.hc 11 5/31/98 2:58p Mgummelt $
*/
/*
==============================================================================
BARRELS
==============================================================================
*/
$cd \art\models\objects\barrel\final
$base base 128 128
$skin skin
$frame resting
//Checks to see if the bounding boxes of the 2 ents overlap at any point.
//Not intended for BSP models- bounding box models only
float overlapped (entity ent1, entity ent2)
{
vector mins1,maxs1,mins2,maxs2;
float overlapped_axes;
mins1=ent1.absmin;
maxs1=ent1.absmax;
mins2=ent2.absmin;
maxs2=ent2.absmax;
if(mins1_x>maxs2_x||maxs1_x<mins2_x)
return FALSE;
else
{
// dprint("X axes overlap\n");
overlapped_axes+=1;
}
if(mins1_y>maxs2_y||maxs1_y<mins2_y)
return FALSE;
else
{
// dprint("Y axes overlap\n");
overlapped_axes+=1;
}
if(mins1_z>maxs2_z||maxs1_z<mins2_z)
return FALSE;
else
{
// dprint("Z axes overlap\n");
overlapped_axes+=1;
}
if(overlapped_axes==3)
{
// dprint("All 3 axes overlap!\n");
return TRUE;
}
return FALSE;
}
void obj_barrel_fake_chunk_death(void)
{
vector space;
float spacecube,model_cnt,scalemod;
string deathsound;
space = self.absmax - self.absmin;
spacecube = space_x * space_y * space_z;
model_cnt = spacecube / 8192; // (16 * 16 * 16)
deathsound="fx/woodbrk.wav";
sound (self, CHAN_VOICE, deathsound, 1, ATTN_NORM);
if (spacecube < 5000)
{
scalemod = .20;
model_cnt = model_cnt * 3; // Because so few pieces come out of a small object
}
else if (spacecube < 50000)
{
scalemod = .45;
model_cnt = model_cnt * 3; // Because so few pieces come out of a small object
}
else if (spacecube < 500000)
{
scalemod = .50;
}
else if (spacecube < 1000000)
{
scalemod = .75;
}
else
{
scalemod = 1;
}
if(model_cnt>CHUNK_MAX)
model_cnt=CHUNK_MAX;
while (model_cnt>0)
{
if (chunk_cnt < CHUNK_MAX*2)
{
CreateModelChunks(space,scalemod);
chunk_cnt+=1;
}
model_cnt-=1;
}
make_chunk_reset();
self.solid = SOLID_NOT;
// self.effects = EF_NODRAW;
if(self.trigger_field)
remove(self.trigger_field);
}
void barrel_go ();
void rep_barrel_wait ()
{
entity item;
//float dist,s1,s2;
// dprint("Barrel checking to respawn\n");
item = findradius(self.origin, 256);
while (item)
{
// dprint("Barrel found ents\n");
if (item.solid&&item.solid!=SOLID_TRIGGER&&item.solid!=SOLID_BSP&&item!=self)
{
// dprint("Barrel found solid\n");
// dist = vhlen(item.origin-self.origin);
// s1 = item.maxs_x*1.5;
// s2 = 24;//barrel size, at most- 22.6 if 16 by 16
// if(s1+s2>=dist)
if(overlapped(self,item))
{
// dprint("Barrel waiting- too close to ");
// dprint(item.classname);
// dprint("\n");
self.think = rep_barrel_wait;
thinktime self : 2;
return;
}
}
item = item.chain;
}
barrel_go();
}
void spawn_rep_barrel (void)
{
obj_barrel_fake_chunk_death();
setorigin(self,self.wallspot);
self.effects=self.flags=self.flags2=self.frame=self.fire_damage=0;
self.enemy=world;
self.classname=self.netname;
self.flags2(+)FL_SUMMONED;
self.angles=self.velocity=self.avelocity='0 0 0';
self.health=self.max_health;
self.think=rep_barrel_wait;
thinktime self : 0.5;
setmodel(self,"models/null.spr");
// dprintv("Barrel respawning with %s angles\n",self.angles);
/*
entity replacement;
replacement=spawn();
replacement.spawnflags=self.spawnflags;
setmodel(replacement,"models/null.spr");
setorigin(replacement,self.wallspot);
replacement.frags=self.frags;
replacement.classname=self.netname;
replacement.flags2(+)FL_SUMMONED;
replacement.targetname=self.targetname;
replacement.think=rep_barrel_wait;
replacement.nextthink = time + 1;
*/
}
//BIG FIRE========================================================
void burn_out ()
{
if(self.scale>0.1)
{
self.scale-=0.1;
setsize(self.trigger_field,'-24 -24 0'*self.scale,'24 24 48'*self.scale);
thinktime self : 0.01;
self.dmg=self.trigger_field.dmg=self.scale*3;
}
else
{
remove(self.trigger_field);
stopSound(self,0);
remove(self);
}
}
void spawn_big_fire(vector org)
{
entity bigfire,oself;
bigfire=spawn();
oself=self;
self = bigfire;
self.dmg=2;
self.classname="big greek fire";
self.drawflags(+)SCALE_ORIGIN_BOTTOM|DRF_TRANSLUCENT|MLS_FIREFLICKER;
self.scale = 1;
setmodel(self,"models/newfire.mdl");
setorigin(self,org);
spawn_burnfield(org);
setsize(self.trigger_field,'-48 -48 0','48 48 64');
sound (self,CHAN_UPDATE+PHS_OVERRIDE_R, "misc/flamloop.wav", 0.5, ATTN_LOOP);
self.think = burn_out;
thinktime self : 30;//burn for 30 seconds
self=oself;
}
//GREEK FIRE========================================================
void obj_barrel_gfire_explode (void)
{
T_RadiusDamage (self, self, random(150,200), self);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_PURIFY2_EXPLODE);
WriteCoord (MSG_MULTICAST, self.origin_x - self.movedir_x * 8);
WriteCoord (MSG_MULTICAST, self.origin_y - self.movedir_y * 8);
WriteCoord (MSG_MULTICAST, self.origin_z - self.movedir_z * 8);
multicast(self.origin,MULTICAST_PHS_R);
spawn_big_fire(self.origin);
if(self.spawnflags&BARREL_RESPAWN)
{
spawn_rep_barrel();
// obj_barrel_fake_chunk_death();
return;
}
remove(self);
}
//void MakeExplosion(string explodemodel);
void()barrel_check_float;
/*void obj_barrel_gravity()
{
local vector slope;
if(self.ltime <= time)
{
slope = getslope(self);
if(slope != self.dest)
{
self.speed = trace_plane_normal_z * 20;
self.ideal_yaw =
self.dest = trace_plane_normal;
}
self.ltime = time + 0.4;
}
thinktime self : 0.05;
}
*/
void float(void)
{
float x_mod, y_mod, z_mod;
vector org;
org=self.origin;
if(pointcontents(org)==CONTENT_WATER||pointcontents(org)==CONTENT_SLIME||pointcontents(org)==CONTENT_LAVA)
{
if(self.velocity_x)
self.velocity_x/=1.1;
if(self.velocity_y)
self.velocity_y/=1.1;
org_z+= self.maxs_z*0.77;//float only 23% above waterlevel
if(pointcontents(org)==CONTENT_WATER||pointcontents(org)==CONTENT_SLIME||pointcontents(org)==CONTENT_LAVA)
{
// self.flags(+)FL_SWIM;
self.flags(-)FL_ONGROUND;
if(self.velocity_z<77)
self.velocity_z=80;
else
self.velocity_z+=random(0,0.01);
}
else
{
self.velocity_z-=random(0,0.01);
}
if(random()<0.3)
{
y_mod=random(-0.15,0.15);
if(random()<0.5)
self.angles_y+=y_mod;
else
self.angles_y+=y_mod;
}
if(random()<0.3)
{
x_mod=random(-0.15,0.15);
if(fabs(self.angles_x+x_mod)>10)
self.angles_x-=x_mod;
else
self.angles_x+=x_mod;
}
if(random()<0.3)
{
z_mod=random(-0.15,0.15);
if(fabs(self.angles_z+z_mod)>10)
self.angles_z-=z_mod;
else
self.angles_z+=z_mod;
}
thinktime self : 0.1;
}
else
{
self.angles_z=self.angles_z=0;
self.classname="barrel";
self.think=barrel_check_float;
thinktime self : 0.5;
}
}
void barrel_check_float (void)
{
vector org;
org=self.origin;
if(pointcontents(org)==CONTENT_WATER||pointcontents(org)==CONTENT_SLIME||pointcontents(org)==CONTENT_LAVA&&(!self.spawnflags&BARREL_SINK))
{
self.classname=="barrel_floating";
self.think=float;
thinktime self : 0;
}
else
{
self.classname="barrel";
self.think=barrel_check_float;
thinktime self : 0.5;
}
}
/*
* obj_barrel_explode() -- Blows the barrel up.
*/
void obj_barrel_explode_go()
{
entity attacker;
if(self.enemy.flags2&FL_ALIVE)//give credit to person who blew it up
attacker=self.enemy;
else
attacker=self;
T_RadiusDamage(self, attacker, 200,self);//00, self);
// sound(self, CHAN_VOICE, "weapons/explode.wav", 1, ATTN_NORM);
particleexplosion(self.origin + '0 0 83',384,60,40);
starteffect(CE_LG_EXPLOSION , (self.absmin+self.absmax)*0.5);
if(self.spawnflags&BARREL_RESPAWN)
{
spawn_rep_barrel();
// obj_barrel_fake_chunk_death();
return;
}
chunk_death();
}
void obj_barrel_explode ()
{
//delay so too many don't cause crash
self.th_die=SUB_Null;
self.takedamage = DAMAGE_NO;
self.think=obj_barrel_explode_go;
if(dmMode==DM_SIEGE)
thinktime self : 0;
else
thinktime self : random()+0.05;
}
void obj_barrel_use_explode ()
{//no delay
self.th_die=SUB_Null;
self.takedamage = DAMAGE_NO;
self.think=obj_barrel_explode_go;
thinktime self : 0;
}
void()monster_rat;
void rat_spawn(float offset)
{
newmis=spawn();
newmis.angles_y=self.angles_y+offset*60;
newmis.flags2(+)FL_SUMMONED;
if(self.target)
newmis.target=self.target;
makevectors(newmis.angles);
setorigin(newmis,self.origin+v_forward*16);
newmis.think=monster_rat;
thinktime newmis : 0;
}
void barrel_die ()
{
self.solid=SOLID_NOT;
if(self.model!="models/gfire.mdl")
{
if(random()<0.3||self.target!=""||self.classname=="monster_ratnest")
{
float r;
r=rint(random(3,6));
while(r>0)
{
rat_spawn(r);
r-=1;
}
}
}
else
{
//particleexplosion(self.origin + '0 0 24',264,60,40);
sound(self,CHAN_AUTO,"raven/outwater.wav",1,ATTN_NORM);
}
if(self.spawnflags&BARREL_RESPAWN)
{
spawn_rep_barrel();
// obj_barrel_fake_chunk_death();
return;
}
if(self.classname!="monster_ratnest")
chunk_death();
else
remove(self);
}
/*
* obj_barrel_slide() -- Slides a barrel in the direction given in self.movedir.
*/
/*
void obj_barrel_slide()
{
local entity victim;
local float direction;
//old if function, direction was null
// if(walkmove(direction, self.count) == FALSE)
if(!walkmove(self.cnt, self.count, FALSE))
{
//Is this supposed to push something else it hits?
victim = findradius(self.origin, self.count + 38);
while(victim)
{
if(victim.movetype != MOVETYPE_NONE && victim != self)
{
direction = vectoyaw(victim.origin - self.origin);
if(self.cnt <= 60 && direction >= 300)
direction -= 360;
if(direction > self.cnt - 60 &&
direction < self.cnt + 60)
victim.velocity += (victim.origin - self.origin) * self.count;
}
victim = victim.chain;
}
}
// if(!self.spawnflags & BARREL_DOWNHILL)
// self.count -= 0.7;
// if(self.count < 0.5)
// self.think = obj_barrel_gravity;
//What is this supposed to do?
// obj_barrel_gravity();
// reduce self.count to simulate friction, right?
self.count = self.count - 1;
if(self.count<=0)
{
self.think=SUB_Null;
self.nextthink = -1;
}
else
thinktime self : 0.05;
}
*/
void obj_barrel_roll (void)
{
self.v_angle_y=self.angles_y;
self.v_angle_x=self.v_angle_z=0;
makevectors(self.v_angle);
self.velocity-=self.movedir*self.speed;
self.movedir=normalize(v_forward);
self.speed/=1.01;
self.anglespeed=self.speed/7.7;
if(self.speed<1&&self.speed>-1)
{
self.velocity = '0 0 0';
self.think = SUB_Null;
self.nextthink = -1;
}
else
{
vector dircheck;
// float hitcheck;
//Rolling sound
if(self.flags&FL_ONGROUND)
{
self.flags(-)FL_ONGROUND;
self.last_onground=time;
self.level=TRUE;
}
else if(self.level)
{
self.level=FALSE;
self.last_onground = time - 1;
self.speed/=2;//slow down if go off cliff, looks weird otherwise
}
self.velocity+=self.movedir*self.speed;
self.angles_x-=self.anglespeed;
self.think=obj_barrel_roll;
thinktime self : 0.05;
dircheck=normalize(self.velocity);
makevectors(self.angles);
traceline(self.origin,self.origin+dircheck*39,FALSE,self);
if(trace_fraction==1)
{
traceline(self.origin+v_right*16,self.origin+v_right*16+dircheck*39,FALSE,self);
if(trace_fraction==1)
traceline(self.origin-v_right*16,self.origin-v_right*16+dircheck*39,FALSE,self);
}
if(trace_fraction<1)
{
sound(self,CHAN_AUTO,"fx/thngland.wav",1,ATTN_NORM); // landing thud
self.speed*=-0.25;
self.last_onground=time - 1;
obj_fly_hurt(trace_ent);
self.velocity=dircheck*self.speed;
}
}
}
/*
* obj_barrel_shoot() -- Called when a barrel is shot.
*/
void obj_barrel_shoot()
{
sound(self,CHAN_AUTO,"fx/thngland.wav",1,ATTN_NORM); // landing thud
// if(self.aflag)
// return;
/*
self.movedir = normalize(self.origin - self.enemy.origin);
self.velocity=self.velocity + self.movedir*self.count;
self.avelocity_y=random(100,300);
self.velocity_z=self.velocity_z + 50;
if(self.velocity_z>150)
self.velocity_z=150;
self.flags(-)FL_ONGROUND;
*/
}
/*
* obj_barrel_use() -- Called when a barrel is triggered.
*/
void barrel_drop ()
{
self.movetype=MOVETYPE_FLYMISSILE;
// setorigin(self,self.origin - '0 0 20');
self.flags(-)FL_PUSH|FL_ONGROUND;
self.velocity='0 0 -200';
self.touch=self.th_die;
}
void obj_barrel_use()
{
// if(other.movetype == MOVETYPE_STEP)
// obj_pull();
// else
obj_barrel_explode();
}
void obj_barrel_gfire_light ()
{
self.use=SUB_Null;
self.th_die = obj_barrel_gfire_explode;
sound (self, CHAN_AUTO, "weapons/expsmall.wav", 1, ATTN_NORM);
starteffect(CE_FLOOR_EXPLOSION , self.origin+'0 0 110');
self.frame=1;
sound(self,CHAN_UPDATE+PHS_OVERRIDE_R,"misc/flamloop.wav",0.5,ATTN_LOOP);
self.effects(+)EF_UPDATESOUND|EF_BRIGHTLIGHT;
}
void spawn_barrel(float barrel_type)
{
if(dmMode==DM_SIEGE)
self.spawnflags(+)BARREL_RESPAWN;
self.frags=barrel_type;
if(!self.flags2&FL_SUMMONED)
{
precache_model("models/barrel.mdl");
if(barrel_type==BARREL_NORMAL)
precache_model("models/rat.mdl");
}
CreateEntityNew(self,ENT_BARREL,"models/barrel.mdl",chunk_death);
if(self.spawnflags&ON_SIDE)
{
self.aflag=1;
self.frame=1;
self.v_angle=self.angles;
setsize(self, '-18 -13 -13','18 13 13');
self.hull=HULL_CROUCH;
}
else
{
setsize(self, '-13 -13 0','13 13 36');
self.hull=HULL_PLAYER;
}
if (self.scale)
self.mass *=self.scale;
self.netname=self.classname;
self.classname = "barrel";
self.flags(+)FL_PUSH;
self.touch = obj_push;
self.th_pain = obj_barrel_shoot;
if (barrel_type==BARREL_NORMAL)
{
self.th_die = barrel_die;
self.skin=0;
}
else if (barrel_type==BARREL_INDESTRUCTIBLE)
{
self.health = 999999;
self.th_die = SUB_Null;
self.skin=1;
}
else if (barrel_type==BARREL_EXPLODING)
{
self.th_die = obj_barrel_explode;
self.skin=2;
}
else if (barrel_type==BARREL_GFIRE)
{
self.th_die = barrel_die;
setmodel(self,"models/gfire.mdl");
setsize(self,'-16 -16 0','16 16 56');
self.hull=HULL_PLAYER;
self.use=obj_barrel_gfire_light;
}
if(!self.spawnflags&BARREL_SINK)
{
self.think=barrel_check_float;
thinktime self : 0;
}
if(pointcontents(self.origin)!=CONTENT_EMPTY&&(!self.spawnflags&BARREL_SINK))
{
self.classname="barrel_floating";
self.think=float;
thinktime self : 0;
}
else if(!self.flags2&FL_SUMMONED&&!self.spawnflags&BARREL_NO_DROP)
droptofloor();
if(self.spawnflags&DROP_USE)
{
self.movetype=MOVETYPE_NONE;
self.use=barrel_drop;
if(barrel_type==BARREL_EXPLODING)
self.th_die=obj_barrel_use_explode;
}
else if(self.targetname)
if(barrel_type==BARREL_EXPLODING)
self.use=obj_barrel_use_explode;
else
self.use=self.th_die;
if(self.spawnflags&BARREL_RESPAWN)
self.wallspot=self.origin;
spawn_push_trigger(3);
}
/*QUAKED obj_barrel (0.3 0.1 0.6) (-13 -13 0) (13 13 36) DOWNHILL NO_DROP ON_SIDE SINK DROP_USE RESPAWN
A barrel, just a plain old barrel
-------------------------FIELDS-------------------------
.health - How hard it is to smash
Default: 25
DOWNHILL - This barrel will slide downhill with gravity.
NO_DROP - Will not drop to floor before spawning
ON_SIDE - Will make the barrel appear to be on it's side, the top will point right (90 degrees)
Note- barrels on their side must be placed at least 13 units above the floor.
SINK - Sinks in water
DROP_USE - Barrel has no gravity until used, then will drop
RESPAWN - Barrel will RESPAWN at it's initial origin when it is destroyed
--------------------------------------------------------
*/
void obj_barrel(void)
{
if(self.spawnflags&DROP_USE)
self.spawnflags(+)BARREL_NO_DROP;
precache_sound("misc/squeak.wav");
if(self.health)
self.max_health=self.health;
spawn_barrel(BARREL_NORMAL);
if(!self.max_health)
self.max_health=self.health;
self.mass = 75;
}
/*QUAKED obj_barrel_indestructible (0.3 0.1 0.6) (-13 -13 0) (13 13 36) DOWNHILL NO_DROP ON_SIDE SINK DROP_USE RESPAWN
A barrel you just can't break
-------------------------FIELDS-------------------------
DOWNHILL - This barrel will slide downhill with gravity.
NO_DROP - Will not drop to floor before spawning
ON_SIDE - Will make the barrel appear to be on it's side, the top will point right (90 degrees)
Note- barrels on their side must be placed at least 13 units above the floor.
SINK - Sinks in water
DROP_USE - Barrel has no gravity until used, then will drop
RESPAWN - Barrel will RESPAWN at it's initial origin when it is destroyed
--------------------------------------------------------
*/
void obj_barrel_indestructible(void)
{
if(self.spawnflags&DROP_USE)
self.spawnflags(+)BARREL_NO_DROP;
if(self.health)
self.max_health=self.health;
spawn_barrel(BARREL_INDESTRUCTIBLE);
if(!self.max_health)
self.max_health=self.health;
self.mass = 95;
}
/*QUAKED obj_barrel_exploding (0.3 0.1 0.6) (-13 -13 0) (13 13 36) DOWNHILL NO_DROP ON_SIDE SINK DROP_USE RESPAWN
An exploding barrel with red XXX on the side
WARNING!: Putting too many exploding barrels next to each other will cause a crash, there is no way around this, so if it happens, it's to be considered a Designer error!
Putting them in lines and chains seems to be ok, as long as you don't stack them or group them too closely, more than 4 in a tight group is probably pushing it.
-------------------------FIELDS-------------------------
.health - How hard it is to blow up
Default: 25
.targetname - set a targetname on a barrel and it will not delay when it explodes (default is arandom delay to prevent too many explosions at once)
DOWNHILL - This barrel will slide downhill with gravity.
NO_DROP - Will not drop to floor before spawning
ON_SIDE - Will make the barrel appear to be on it's side, the top will point right (90 degrees)
Note- barrels on their side must be placed at least 13 units above the floor.
SINK - Sinks in water
DROP_USE - Barrel has no gravity until used, then will drop
RESPAWN - Barrel will RESPAWN at it's initial origin when it is destroyed
--------------------------------------------------------
*/
void obj_barrel_exploding(void)
{
if(self.spawnflags&DROP_USE)
self.spawnflags(+)BARREL_NO_DROP;
if(self.health)
self.max_health=self.health;
spawn_barrel(BARREL_EXPLODING);
if(!self.max_health)
self.max_health=self.health;
self.mass = 85;
}
/*QUAKED obj_barrel_gfire (0.3 0.1 0.6) (-13 -13 0) (13 13 36) DOWNHILL NO_DROP ON_SIDE SINK DROP_USE RESPAWN
Greek fire barrel
Use a torch to light them
-------------------------FIELDS-------------------------
.health - How hard it is to blow up
Default: 25
.targetname - set a targetname on a barrel and it will not delay when it explodes (default is arandom delay to prevent too many explosions at once)
DOWNHILL - This barrel will slide downhill with gravity.
NO_DROP - Will not drop to floor before spawning
ON_SIDE - Will make the barrel appear to be on it's side, the top will point right (90 degrees)
Note- barrels on their side must be placed at least 13 units above the floor.
SINK - Sinks in water
DROP_USE - Barrel has no gravity until used, then will drop
RESPAWN - Barrel will RESPAWN at it's initial origin when it is destroyed
--------------------------------------------------------
*/
void obj_barrel_gfire(void)
{
precache_model("models/newfire.mdl");
precache_model("models/gfire.mdl");
precache_sound("misc/flamloop.wav");
precache_sound("misc/gflaunch.wav");
if(self.spawnflags&DROP_USE)
self.spawnflags(+)BARREL_NO_DROP;
if(self.health)
self.max_health=self.health;
spawn_barrel(BARREL_GFIRE);
self.mass = 100;
if(!self.max_health)
self.max_health=self.health;
}
void barrel_go(void)
{
// dprint("Barrel_go: ready to respawn\n");
if(self.classname=="obj_barrel_normal")
{
// dprint("Respawning normal barrel\n");
if(self.spawnflags&DROP_USE)
self.spawnflags(+)BARREL_NO_DROP;
spawn_barrel(BARREL_NORMAL);
self.mass = 75;
}
else if(self.classname=="obj_barrel_indestructible")
{
// dprint("Respawning invincible barrel\n");
if(self.spawnflags&DROP_USE)
self.spawnflags(+)BARREL_NO_DROP;
spawn_barrel(BARREL_INDESTRUCTIBLE);
self.mass = 95;
}
else if(self.classname=="obj_barrel_exploding")
{
// dprint("Respawning explode barrel\n");
if(self.spawnflags&DROP_USE)
self.spawnflags(+)BARREL_NO_DROP;
spawn_barrel(BARREL_EXPLODING);
self.mass = 100;//85
}
else if(self.classname=="obj_barrel_gfire")
{
// dprint("Respawning gfire barrel\n");
if(self.spawnflags&DROP_USE)
self.spawnflags(+)BARREL_NO_DROP;
spawn_barrel(BARREL_GFIRE);
self.mass = 100;//85
}
else
{
// dprint("NO BARREL TYPE!!!\n");
if(self.spawnflags&DROP_USE)
self.spawnflags(+)BARREL_NO_DROP;
spawn_barrel(BARREL_EXPLODING);
self.mass = 100;//85
}
}

290
bldrain.hc Normal file
View File

@ -0,0 +1,290 @@
/*
==============================================================================
Q:\art\models\weapons\spllbook\spllbook.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\weapons\spllbook
$origin 0 0 0
$base BASE skin
$skin skin
$flags 0
//
$frame normal02 normal03 normal04 normal05 normal06
$frame normal07 normal08 normal09 normal10 normal11
$frame normal12 normal13
//
$frame idlean12 idlean13 idlean14 idlean15 idlean16
$frame idlean17 idlean18 idlean19 idlean20 idlean21
$frame idlean22 idlean23 idlean24 idlean25 idlean26
$frame idlean27 idlean28 idlean29 idlean30 idlean31
$frame idlean32 idlean33 idlean34 idlean35
//
$frame idlebn36 idlebn37 idlebn38 idlebn39 idlebn40
$frame idlebn41 idlebn42 idlebn43 idlebn44 idlebn45
$frame idlebn46 idlebn47 idlebn48 idlebn49 idlebn50
$frame idlebn51 idlebn52 idlebn53 idlebn54 idlebn55
$frame idlebn56 idlebn57 idlebn58 idlebn59
//
$frame select80 select81 select82 select83 select84
$frame select85 select86 select87 select88 select89
$frame select90 select91 select92 select93 select94
$frame select95 select96 select97 select98 select99
void BloodMissileTouch (void)
{
if(pointcontents(self.origin)==CONTENT_SKY)
{
remove(self);
return;
}
if(other.classname==self.classname&&other.owner==self.owner)
return;
self.movedir=normalize(self.velocity);
if(!other.takedamage)
{
if(self.frags)
{
//counter for number of bounces
sound (self, CHAN_WEAPON, "succubus/brnbounce.wav", 1, ATTN_NORM);
if(self.dmg>=2)
self.dmg-=1;
starteffect(CE_BRN_BOUNCE,self.origin - self.movedir*8 - '0 0 6','0 0 0',HX_FRAME_TIME);//CreateRedFlash(self.origin);
self.health += 45;
thinktime self : 0;
return;
}
else
{
starteffect(CE_BLDRN_EXPL, self.origin-self.movedir*6,'0 0 0', HX_FRAME_TIME);
sound (self, CHAN_WEAPON, "succubus/brnwall.wav", 1, ATTN_NORM);
remove(self);
return;
}
}
spawn_touchpuff(self.dmg,other);
T_Damage(other,self,self.owner,self.dmg);
starteffect(CE_BLDRN_EXPL, self.origin-self.movedir*6,'0 0 0', HX_FRAME_TIME);
sound(self,CHAN_AUTO,"succubus/brnhit.wav",1,ATTN_NORM);
remove(self);
}
void BloodMissileFade ()
{
self.angles=vectoangles(self.velocity);
if(self.health>30)
{
self.health-=60;
thinktime self : 0.3;
if(self.dmg>=1.75)
self.dmg-=0.75;
}
else
{
remove(self);
return;
}
traceline(self.origin, self.origin + self.movedir * 240, FALSE, newmis);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_BLOODRAIN);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
WriteByte (MSG_MULTICAST, self.angles_y*256.0/360.0);
WriteByte (MSG_MULTICAST, self.angles_x*256.0/360.0);
WriteByte (MSG_MULTICAST, trace_fraction * 240.0);
WriteByte (MSG_MULTICAST, self.health);
multicast(self.origin,MULTICAST_PVS);
}
void FireBloodMissile (float offset)
{
float f_dist;
makevectors(self.v_angle);
self.effects(+)EF_MUZZLEFLASH;
newmis=spawn();
newmis.classname="blood missile";
newmis.owner=self;
newmis.effects(+) EF_NODRAW;
f_dist=8;
if(self.artifact_active&ART_TOMEOFPOWER)
{
newmis.health=250;
newmis.dmg=random(40,60);
f_dist=16;
newmis.solid=SOLID_PHASE;
newmis.movetype=MOVETYPE_BOUNCEMISSILE;
newmis.frags=TRUE;
}
else
{
newmis.dmg=random(15,22);
newmis.health=90;
newmis.frags=FALSE;
newmis.movetype=MOVETYPE_FLYMISSILE;
}
newmis.solid=SOLID_BBOX;
newmis.touch=BloodMissileTouch;
newmis.speed=800;
newmis.velocity=normalize(v_forward)*newmis.speed;// + spread;
newmis.movedir=normalize(newmis.velocity);
newmis.angles=vectoangles(newmis.velocity);
setmodel(newmis,"models/sucwp1p.mdl");
setsize(newmis,'0 0 0','0 0 0');
setorigin(newmis,self.origin+self.proj_ofs+v_forward*f_dist-v_right*12 + v_right*(offset*3) - '0 0 6');
weapon_sound(self, "succubus/brnfire.wav");
newmis.think=BloodMissileFade;
thinktime newmis : 0.3;
traceline(newmis.origin, newmis.origin + newmis.movedir * 240, FALSE, newmis);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_BLOODRAIN);
WriteCoord (MSG_MULTICAST, newmis.origin_x);
WriteCoord (MSG_MULTICAST, newmis.origin_y);
WriteCoord (MSG_MULTICAST, newmis.origin_z);
WriteByte (MSG_MULTICAST, newmis.angles_y*256.0/360.0);
WriteByte (MSG_MULTICAST, newmis.angles_x*256.0/360.0);
WriteByte (MSG_MULTICAST, trace_fraction * 240.0);
WriteByte (MSG_MULTICAST, newmis.health);
multicast(self.origin,MULTICAST_PVS);
}
void blrn_power(float offset)
{
if(self.attack_finished>time)
return;
FireBloodMissile(offset);
self.attack_finished=time+0.7;
self.punchangle_x=3;
}
void blrn_normal()
{
if(self.attack_finished>time)
return;
FireBloodMissile(0);
self.attack_finished=time+0.4;
}
/*======================
ACTION
select
deselect
ready loop
relax loop
fire once
fire loop
ready to relax(after short delay)
relax to ready(Fire delay? or automatic if see someone?)
=======================*/
void()bloodrain_ready;
void() Suc_Blrn_Fire;
void bloodrain_fire (void)
{
if(self.button0&&self.weaponframe==$normal07 &&!self.artifact_active&ART_TOMEOFPOWER)
self.weaponframe=$normal07;
else
self.wfs = advanceweaponframe($normal02,$normal13);
if(self.weaponframe<=$normal07)
self.weaponframe+=1;
self.th_weapon=bloodrain_fire;
self.last_attack=time;
if(self.wfs==WF_CYCLE_WRAPPED)
bloodrain_ready();
if(self.artifact_active&ART_TOMEOFPOWER)
{
// if(self.weaponframe>=$normal07 && self.weaponframe<=$normal09)
// blrn_power((self.weaponframe - $normal08) *3);
if(self.weaponframe==$normal07)
blrn_power(0);
}
else if(self.weaponframe==$normal07)
blrn_normal();
}
void() Suc_Blrn_Fire =
{
self.weaponframe_cnt=0;
bloodrain_fire();
thinktime self : 0;
};
void bloodrain_jellyfingers ()
{
self.wfs = advanceweaponframe($idlebn36,$idlebn59);
self.th_weapon=bloodrain_jellyfingers;
if(self.wfs==WF_CYCLE_WRAPPED)
bloodrain_ready();
}
void bloodrain_ready (void)
{
self.wfs = advanceweaponframe($idlean12,$idlean35);
if(random()<0.1&&self.weaponframe==$idlean35)
self.th_weapon=bloodrain_jellyfingers;
else
self.th_weapon=bloodrain_ready;
}
void bloodrain_select (void)
{
self.wfs = advanceweaponframe($select80,$select99);
self.weaponmodel = "models/sucwp1.mdl";
self.th_weapon=bloodrain_select;
if(self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
bloodrain_ready();
}
}
void bloodrain_deselect (void)
{
self.wfs = advanceweaponframe($select99,$select80);
self.th_weapon=bloodrain_deselect;
if(self.wfs==WF_CYCLE_WRAPPED)
W_SetCurrentAmmo();
}

512
boner.hc Normal file
View File

@ -0,0 +1,512 @@
/*
* $Header: /HexenWorld/Siege/boner.hc 19 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\weapons\spllbook\spllbook.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\weapons\spllbook
$origin 0 0 0
$base BASE skin
$skin skin
$flags 0
//
$frame fire1 fire2 fire3 fire4 fire5
$frame fire6 fire7 fire8 fire9 fire10
$frame fire11 fire12
//
$frame go2mag01 go2mag02 go2mag03 go2mag04 go2mag05
$frame go2mag06 go2mag07 go2mag08 go2mag09 go2mag10
$frame go2mag11 go2mag12 go2mag13
//
$frame go2shd01 go2shd02
$frame go2shd03 go2shd04 go2shd05 go2shd06 go2shd07
$frame go2shd08 go2shd09 go2shd10 go2shd11 go2shd12
$frame go2shd13 go2shd14
//
$frame idle1 idle2 idle3 idle4 idle5
$frame idle6 idle7 idle8 idle9 idle10
$frame idle11 idle12 idle13 idle14 idle15
$frame idle16 idle17 idle18 idle19 idle20
$frame idle21 idle22
//
$frame mfire1 mfire2 mfire3 mfire4 mfire5
$frame mfire6 mfire7 mfire8
//
$frame midle01 midle02 midle03 midle04 midle05
$frame midle06 midle07 midle08 midle09 midle10
$frame midle11 midle12 midle13 midle14 midle15
$frame midle16 midle17 midle18 midle19 midle20
$frame midle21 midle22
//
$frame mselect01 mselect02 mselect03 mselect04 mselect05
$frame mselect06 mselect07 mselect08 mselect09 mselect10
$frame mselect11 mselect12 mselect13 mselect14 mselect15
$frame mselect16 mselect17 mselect18 mselect19 mselect20
//
$frame select1 select2 select3 select4 select5
$frame select6 select7
/*
==============================================================================
MULTI-DAMAGE
Collects multiple small damages into a single damage
==============================================================================
*/
float RicochetCount;
void(vector org)smolder;
void(vector org, float damage) Ricochet =
{
//float r;
RicochetCount+=1;
if(RicochetCount > 7)
{
RicochetCount = 0;
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_HWBONERIC);
WriteCoord (MSG_MULTICAST, org_x);
WriteCoord (MSG_MULTICAST, org_y);
WriteCoord (MSG_MULTICAST, org_z);
if(damage > 100)
damage = 100;
WriteByte (MSG_MULTICAST, damage * 2);
multicast(self.origin,MULTICAST_PHS_R);
/* particle4(org,3,random(368,384),PARTICLETYPE_GRAV,damage*2);
r = random(100);
if (r > 95)
sound (targ,CHAN_AUTO,"weapons/ric1.wav",1,ATTN_NORM);
else if (r > 91)
sound (targ,CHAN_AUTO,"weapons/ric2.wav",1,ATTN_NORM);
else if (r > 87)
sound (targ,CHAN_AUTO,"weapons/ric3.wav",1,ATTN_NORM);
*/
}
};
entity multi_ent;
float multi_damage;
void() ClearMultDamg =
{
multi_ent = world;
multi_damage = 0;
};
void() ApplyMultDamg =
{
float kicker, inertia;
if (!multi_ent)
return;
entity loser,winner;
winner=self;
loser=multi_ent;
kicker = multi_damage * 7 - vlen(winner.origin - loser.origin);
if(kicker>0)
{
if(loser.flags&FL_ONGROUND)
{
loser.flags(-)FL_ONGROUND;
loser.velocity_z = loser.velocity_z + 150;
}
if (loser.mass<=10)
inertia = 1;
else inertia = loser.mass/10;
if(loser==self)
loser.velocity = loser.velocity - (normalize(loser.v_angle) * (kicker / inertia));
else loser.velocity = loser.velocity + (normalize(winner.v_angle) * (kicker / inertia));
SpawnPuff (loser.origin, loser.velocity*0.1, multi_damage*0.25,loser);
T_Damage (loser, winner, winner, multi_damage);
}
};
void(entity hit, float damage) AddMultDamg =
{
if (!hit)
return;
if (hit != multi_ent)
{
ApplyMultDamg ();
multi_damage = damage;
multi_ent = hit;
}
else
multi_damage = multi_damage + damage;
};
void(float damage, vector dir) TraceHit =
{
local vector vel, org;
vel = (normalize(dir + v_factorrange('-1 -1 0','1 1 0')) + 2 * trace_plane_normal) * 200;
org = trace_endpos - dir*4;
if (trace_ent.takedamage)
{
AddMultDamg (trace_ent, damage);
}
else
Ricochet(org,damage);
};
void(float shotcount, vector dir, vector spread) InstantDamage =
{
vector direction;
vector src;
makevectors(self.v_angle);
src = self.origin + self.proj_ofs+'0 0 6'+v_forward*10;
ClearMultDamg ();
while (shotcount > 0)
{
direction = dir + random(-1,1)*spread_x*v_right;
direction += random(-1,1)*spread_y*v_up;
traceline (src, src + direction*2048, FALSE, self);
if (trace_fraction != 1.0)
TraceHit (4, direction);
shotcount = shotcount - 1;
}
ApplyMultDamg ();
};
void bone_shard_touch ()
{
if(other==self.owner)
return;
//string hitsound;
if(other.takedamage)
{
// hitsound="necro/bonenhit.wav";
T_Damage(other, self,self.owner,self.dmg);
}
else
{
// hitsound="necro/bonenwal.wav";
T_RadiusDamage(self,self.owner,self.dmg*2,self.owner);
}
// starteffect(CE_WHITE_SMOKE, self.origin,'0 0 0', HX_FRAME_TIME);
// sound(self,CHAN_WEAPON,hitsound,1,ATTN_NORM);
// particle4(self.origin,3,random(368,384),PARTICLETYPE_GRAV,self.dmg/2);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_HWBONEPOWER2);
if(other.takedamage)
{
WriteByte(MSG_MULTICAST, 1);
}
else
{
WriteByte(MSG_MULTICAST, 0);
}
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
multicast(self.origin,MULTICAST_PHS_R);
remove(self);
}
void bone_shard_touch2 (void)
{
endeffect(MSG_ALL,self.wrq_effect_id);
bone_shard_touch();
}
void bone_removeshrapnel (void)
{
remove(self);
}
// shrapnel is too much net hit, will be faked by client only shards
// although the server will have invisible shards for damage determination
void fire_bone_shrapnel ()
{
vector shard_vel;
newmis=spawn();
newmis.classname = "bone_fake_shrapnel"; //so reflection won't send turneffect
newmis.owner=self.owner;
newmis.movetype=MOVETYPE_BOUNCE;
newmis.solid=SOLID_PHASE;
newmis.effects (+) EF_NODRAW;
newmis.touch=bone_shard_touch;
newmis.dmg=15;
newmis.think=bone_removeshrapnel;
thinktime newmis : 3;
newmis.speed=777;
trace_fraction=0;
trace_ent=world;
while(trace_fraction!=1&&!trace_ent.takedamage)
{
shard_vel=randomv('1 1 1','-1 -1 -1');
traceline(self.origin,self.origin+shard_vel*36,TRUE,self);
}
newmis.velocity=shard_vel*newmis.speed;
newmis.avelocity=randomv('777 777 777','-777 -777 -777');
// setmodel(newmis,"models/boneshrd.mdl");
setsize(newmis,'0 0 0','0 0 0');
setorigin(newmis,self.origin+shard_vel*8);
// newmis.wrq_effect_id = starteffect(CE_BONESHRAPNEL, newmis.origin, newmis.velocity,
// newmis.angles,newmis.avelocity);
}
void bone_shatter ()
{
float shard_count;
endeffect(MSG_ALL,self.wrq_effect_id);
shard_count=20;
while(shard_count)
{
fire_bone_shrapnel();
shard_count-=1;
}
}
void bone_power_touch ()
{
//vector randomvec;
// sound(self,CHAN_WEAPON,"necro/bonephit.wav",1,ATTN_NORM);
if(other.takedamage)
{
T_Damage(other, self,self.owner,self.dmg*2);
}
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_HWBONEPOWER);
if(other.takedamage)
{
WriteByte (MSG_MULTICAST, 4); //number of ghosts
}
else
{
WriteByte(MSG_MULTICAST, 0); //no ghosts
}
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
WriteCoord (MSG_MULTICAST, self.movedir_x);
WriteCoord (MSG_MULTICAST, self.movedir_y);
WriteCoord (MSG_MULTICAST, self.movedir_z);
multicast(self.origin,MULTICAST_PHS_R);
self.solid=SOLID_NOT;
self.flags2(+)FL2_ADJUST_MON_DAM;
T_RadiusDamage(self,self.owner,self.dmg,other);
bone_shatter();
/* dprint("Doing final effect\n");
starteffect(CE_BONE_EXPLOSION, self.origin-self.movedir*6,'0 0 0', HX_FRAME_TIME);
particle4(self.origin,50,random(368,384),PARTICLETYPE_GRAV,10);
dprint("removing\n");
*/ remove(self);
}
void bone_fire(float powered_up, vector ofs)
{
//SOUND
vector org;
makevectors(self.v_angle);
newmis=spawn();
newmis.owner=self;
newmis.movetype=MOVETYPE_FLYMISSILE;
newmis.solid=SOLID_BBOX;
newmis.speed=1000;
org=self.origin+self.proj_ofs+v_forward*8+v_right*(ofs_y+12)+v_up*ofs_z;
setorigin(newmis,org);
if(powered_up)
{
newmis.velocity=v_forward*newmis.speed;
self.punchangle_x=-2;
// sound(self,CHAN_WEAPON,"necro/bonefpow.wav",1,ATTN_NORM);
self.attack_finished=time + 1.3;
newmis.classname = "bone_powered";
newmis.dmg=80;//was 200
newmis.frags=TRUE;
// newmis.takedamage=DAMAGE_YES;
// newmis.health=3;
// newmis.th_die=bone_shatter;
newmis.touch=bone_power_touch;
// newmis.avelocity=randomv('777 777 777','-777 -777 -777');
// setmodel(newmis,"models/bonelump.mdl");
setsize(newmis,'0 0 0','0 0 0');
self.greenmana-=20;
newmis.effects (+) EF_NODRAW;
org = randomv('777 777 777','-777 -777 -777');
newmis.wrq_effect_id = starteffect(CE_HWBONEBALL, newmis.origin, newmis.velocity,
newmis.angles,org);
}
else
{
newmis.classname = "bone_normal";
newmis.speed+=random(500);
newmis.velocity=v_forward*newmis.speed;
newmis.dmg=10;
newmis.touch=bone_shard_touch2;
newmis.effects (+) EF_NODRAW;
// setmodel(newmis,"models/boneshot.mdl");
setsize(newmis,'0 0 0','0 0 0');
// newmis.velocity+=v_right*ofs_y*10+v_up*ofs_z*10;
// newmis.angles=vectoangles(newmis.velocity);
// newmis.avelocity_z=random(777,-777);
newmis.wrq_effect_id = starteffect(CE_BONESHARD, newmis.origin, newmis.velocity);
}
}
void bone_normal()
{
vector dir;
//sound
// sound(self,CHAN_WEAPON,"necro/bonefnrm.wav",1,ATTN_NORM);
self.effects(+)EF_MUZZLEFLASH;
makevectors(self.v_angle);
dir=normalize(v_forward);
InstantDamage(4,dir,'0.1 0.1 0.1');
// InstantDamage(12,dir,'0.1 0.1 0.1');
self.greenmana-=0.5;
self.attack_finished=time+0.3;
}
void bone_fire_once()
{
vector ofs;
ofs_z=random(-5,5);
ofs_x=random(-5,5);
ofs_y=random(-5,5);
bone_fire(FALSE,ofs);
}
/*======================
ACTION
select
deselect
ready loop
relax loop
fire once
fire loop
ready to relax(after short delay)
relax to ready(Fire delay? or automatic if see someone?)
=======================*/
void()boneshard_ready;
void() Nec_Bon_Attack;
void boneshard_fire (void)
{
self.wfs = advanceweaponframe($fire1,$fire12);
if(self.button0&&self.weaponframe>$fire3 &&!self.artifact_active&ART_TOMEOFPOWER)
self.weaponframe=$fire3;
self.th_weapon=boneshard_fire;
self.last_attack=time;
if(self.wfs==WF_CYCLE_WRAPPED||self.greenmana<1||(self.greenmana<10&&self.artifact_active&ART_TOMEOFPOWER))
boneshard_ready();
else if(self.weaponframe==$fire3)
if(self.artifact_active&ART_TOMEOFPOWER)
bone_fire(TRUE,'0 0 0');
else
bone_normal();
if(random()<0.5&&!self.artifact_active&ART_TOMEOFPOWER&&self.weaponframe<=$fire6)
bone_fire_once();
}
void() Nec_Bon_Attack =
{
boneshard_fire();
thinktime self : 0;
};
void boneshard_jellyfingers ()
{
self.wfs = advanceweaponframe($idle1,$idle22);
self.th_weapon=boneshard_jellyfingers;
if(self.wfs==WF_CYCLE_WRAPPED)
boneshard_ready();
}
void boneshard_ready (void)
{
self.weaponframe=$idle1;
if(random()<0.1&&random()<0.3&&random()<0.5)
self.th_weapon=boneshard_jellyfingers;
else
self.th_weapon=boneshard_ready;
}
void boneshard_select (void)
{
self.wfs = advanceweaponframe($select7,$select1);
self.weaponmodel = "models/spllbook.mdl";
self.th_weapon=boneshard_select;
if(self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
boneshard_ready();
}
}
void boneshard_deselect (void)
{
self.wfs = advanceweaponframe($select1,$select7);
self.th_weapon=boneshard_deselect;
if(self.wfs==WF_CYCLE_WRAPPED)
W_SetCurrentAmmo();
}
void boneshard_select_from_mmis (void)
{
self.wfs = advanceweaponframe($go2shd01,$go2shd14);
self.weaponmodel = "models/spllbook.mdl";
self.th_weapon=boneshard_select_from_mmis;
if(self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
boneshard_ready();
}
}

395
boss.hc Normal file
View File

@ -0,0 +1,395 @@
/*
* $Header: /HexenWorld/Siege/Boss.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
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 ();
};
/*QUAK-ED monster_boss (1 0 0) (-128 -128 -24) (128 128 256)
Monster Boss
-------------------------FIELDS-------------------------
None
--------------------------------------------------------
*/
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();
}
};
/*QUAK-ED event_lightning (0 1 1) (-16 -16 -16) (16 16 16)
Just for boss level.
-------------------------FIELDS-------------------------
None
--------------------------------------------------------
*/
void() event_lightning =
{
self.use = lightning_use;
};

185
boulder.hc Normal file
View File

@ -0,0 +1,185 @@
/*
* $Header: /HexenWorld/Siege/boulder.hc 3 5/25/98 1:38p Mgummelt $
*/
$cd \art\models\objects\boulder\final
$base base 128 128
$skin skin
$frame resting
void() boulder_find_path;
//============================================================================
void(entity targ) boulder_moveto_target =
{
SUB_CalcMove(targ.origin, 50, boulder_find_path);
if (!targ.target) remove(self);
else self.target = targ.target;
};
void() boulder_next =
{
local entity targ;
dprint("finding path\n");
targ = find(world, targetname, self.target);
if (!targ) remove(self);
boulder_moveto_target(targ);
};
void() boulder_find_path =
{
local entity targ;
dprint("finding path\n");
targ = find(world, targetname, self.target);
if (!targ) remove(self);
self.target = targ.target;
self.nextthink = self.ltime + 0.1;
self.think = boulder_next;
};
//============================================================================
vector() BoulderChunkVelocity =
{
local vector v;
v = randomv('-140 -140 70', '140 140 210');
return v;
};
void(vector space) BoulderCreateSpriteChunks =
{
local entity sprite;
sprite = spawn();
space = randomv(space);
setorigin (sprite, self.absmin + space);
setmodel (sprite, "gfx/stone.spr");
setsize (sprite, '0 0 0', '0 0 0');
sprite.movetype = MOVETYPE_BOUNCE;
sprite.solid = SOLID_NOT;
sprite.velocity = BoulderChunkVelocity();
sprite.think = SUB_Remove;
sprite.ltime = time;
sprite.nextthink = time + 1 + random()*1;
};
void(vector space) BoulderCreateModelChunks =
{
local entity chunk;
chunk = spawn();
space_x = space_x * random();
space_y = space_y * random();
space_z = space_z * random();
setorigin (chunk, self.absmin + space);
setmodel (chunk, "models/shard.mdl");
chunk.skin=1;
setsize (chunk, '0 0 0', '0 0 0');
chunk.movetype = MOVETYPE_BOUNCE;
chunk.solid = SOLID_NOT;
chunk.velocity = BoulderChunkVelocity();
chunk.think = SUB_Remove;
chunk.avelocity_x = random()*1200;
chunk.avelocity_y = random()*1200;
chunk.avelocity_z = random()*1200;
chunk.ltime = time;
chunk.nextthink = time + 1 + random();
};
void() boulder_die =
{
local vector space;
local float holdcount,spritecount,chunkcount;
space = self.absmax - self.absmin;
holdcount = space_x + space_y + space_z;
spritecount = holdcount/8;
chunkcount = holdcount/16;
sound (self, CHAN_VOICE, "raven/wallbrk.wav", 1, ATTN_NORM);
while (spritecount>0)
{
// CreateSpriteChunks(space);
spritecount = spritecount - 1;
}
while (chunkcount>0)
{
BoulderCreateModelChunks(space);
chunkcount = chunkcount - 1;
}
remove(self);
};
void() boulder_crush =
{
dprint("Crusha!\n");
T_Damage (other, self, self, 50);
};
void() boulder_use =
{
self.velocity_x = 100 * random();
self.velocity_y = 100 * random();
self.velocity_z = 400;
self.avelocity_x = random()*1200;
self.avelocity_y = random()*1200;
self.avelocity_z = random()*1200;
self.movetype = MOVETYPE_BOUNCE;
};
/*QUAKED trap_boulder (0.3 0.1 0.6) (-13 -13 -14) (13 13 22)
A boulder
-------------------------FIELDS-------------------------
none
--------------------------------------------------------
*/
void() trap_boulder =
{
local entity boulder;
boulder = spawn();
precache_model2("models/boulder.mdl");
setmodel(self, "models/boulder.mdl");
self.health = 75;
self.max_health = self.health;
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_BOUNCE;
self.th_die = boulder_die;
//self.touch = boulder_use;
self.blocked = boulder_crush;
//self.use= boulder_use;
self.takedamage = DAMAGE_YES;
self.think = boulder_find_path;
self.nextthink = self.ltime + 0.1;
};

363
breakabl.hc Normal file
View File

@ -0,0 +1,363 @@
/*
* $Header: /HexenWorld/Siege/breakabl.hc 7 5/31/98 2:58p Mgummelt $
*/
/*
==============================================================================
BREAKABLE BRUSHES
==============================================================================
*/
float BREAK_KILLALL = 1;
float BREAK_HIERARCH = 2;
float BREAK_NOLINK = 4;
float BREAK_CHECKNAME = 8;
float BREAK_ORDERED = 16;
float BREAK_TRANSLUCENT = 32;
float BREAK_INVINCIBLE = 64;
float BREAK_INVISIBLE = 128;
float (entity e1, entity e2) EntitiesTouching;
float breakhealth[21] =
{
0,
75, // THINGTYPE_GREYSTONE
50, // THINGTYPE_WOOD
100, // THINGTYPE_METAL
30, // THINGTYPE_FLESH
999, // THINGTYPE_FIRE
25, // THINGTYPE_CLAY
35, // THINGTYPE_LEAVES
35, // THINGTYPE_HAY
75, // THINGTYPE_BROWNSTONE
35, // THINGTYPE_CLOTH
35, // THINGTYPE_WOOD_LEAF
75, // THINGTYPE_WOOD_METAL
65, // THINGTYPE_WOOD_STONE
90, // THINGTYPE_METAL_STONE
60, // THINGTYPE_METAL_CLOTH
10, // THINGTYPE_WEB
10, // THINGTYPE_GLASS
50, // THINGTYPE_ICE
10, // THINGTYPE_CLEARCLASS
10 // THINGTYPE_CLEARCLASS
};
//============================================================================
void linkBreakables()
{
local entity t, starte;
local vector cmins, cmaxs;
if (self.enemy) return; // already linked by another breakable
if (self.spawnflags & BREAK_NOLINK)
{
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 breakable
if (self.health) starte.health = self.health;
if (self.targetname) starte.targetname = self.targetname;
t = find (t, classname, self.classname);
if (!t)
{
self.enemy = starte; // make the chain a loop
self = self.owner;
if (self.health) return;
if (self.targetname) return;
if (self.items) return;
return;
}
if (EntitiesTouching(self,t) &&
(((self.spawnflags & BREAK_CHECKNAME) && (self.netname == t.netname)) ||
(!self.spawnflags & BREAK_CHECKNAME)))
{
if (t.enemy)
{
//dprint("cross connected brushes!!\n");
return;
}
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);
}
//============================================================================
void brush_use_hierarchy()
{
local entity starte, oself, other;
local float headNum;
oself = starte = self;
headNum = self.frags;
do
{
if (self.frags >= headNum)
self.th_die();
self = self.enemy;
} while ( (self != starte) && (self != world) && (self.frags != self.cnt));
}
void brush_use_ordered()
{
local entity starte, oself;
starte = oself = self;
self.health = self.max_health;
if (self.frags == self.cnt)
self.th_die();
else do
{
self = self.enemy;
} while ( (self != oself) && (self != world) && (self.frags != self.cnt));
if (self.frags == self.cnt && self != world && self != oself) self.th_die();
do
{
oself.cnt += 1;
oself = oself.enemy;
} while ( (oself != starte) && (oself != world) );
}
void brush_use()
{
local entity starte, other;
starte = self;
activator = other;
if (starte.spawnflags & BREAK_KILLALL)
{
do
{
other = self.enemy;
self.th_die();
self = other;
} while ( (self != starte) && (self != world) );
}
else
{
// dprint("Chunkalicious baby!\n");
self.th_die();
}
}
void brush_no_link_use (void)
{
//entity found, starte;
SUB_UseTargets();
/* if(self.target)
{
found=find(found,targetname,self.target);
if(found!=world)
{
starte=found;
found.think=found.use;
thinktime found : 0;
found=find(found,targetname,self.target);
while(found!=starte&&found!=world)
{
found.think=found.use;
thinktime found : 0;
found=find(found,targetname,self.target);
}
}
}
*/
self.th_die();
}
void breakable_hurt_use(entity attacker,float total_damage)
{
string otarg;
otarg = self.target;
self.target = self.pain_target;
activator=attacker;
SUB_UseTargets();
self.target = otarg;
}
/*QUAKED breakable_brush (0 0 1) ? KILLALL HIERARCH NOLINK CHECKNAME ORDERED TRANSLUCENT INVINCIBLE INVISIBLE
Breakable window or wall
You can manually control the heirarchy of breaking by targeting all the brushes you want this brush to break.
If you target a light with this object and turn on the "breaklight" spawnflag, it will turn off that light when it's broken. The light will default to 300 if no lightvalue1 is given.
AUTOMATIC LINKING OPTIONS:
killall - when killed, the brush will kill all connected brushes
hierarch - link all brushes in a hierarchy. The hierarchy priority is set in the
frags field of each brush. Lower numbers will kill higher numbers. If
brushes share the same priority, they will die at the same time.
nolink - don't automatically link this brush with other brushes (use only manual targeting to link)
checkname - link brushes, but also check the name you place in the netname field.
Brushes must then not only touch, but also have the same netname to link
ordered - like hierarch, except that no matter which brush you kill, the brushes
will always break in a certain order. The order is set in the frags field.
The brush with a frags set to 1 will break first, brush with frags set to
2 will break second, etc.
OTHER FIELDS:
translucent - you can see through it
invincible - can't be shot and broken, but will break by linking
-------------------------FIELDS-------------------------
flag - order number
thingtype - type of chunks and sprites it will generate
0 - glass (default)
1 - grey stone
2 - wood
3 - metal
4 - flesh
5 - fire
6 - clay
7 - leaves
8 - hay
9 - brown stone
10 - cloth
11 - wood & leaf
12 - wood & metal
13 - wood stone
14 - metal stone
15 - metal cloth
16 - spider web
19 - clear glass
20 - red glass
25 - DIRT!
health - amount of damage item can take. Default is based on thingtype
glass - 25
grey stone - 75
wood - 50
metal - 100
flesh - 30
fire - 999
clay - 25
leaves - 35
hay - 35
brown stone - 75
cloth - 35
wood&leaf - 35
wood&metal - 75
wood&stone - 65
metal&stone - 90
metal&cloth - 60
others - 25
abslight - to set the absolute light level
pain_target - uses this target everytime the brush is hit
--------------------------------------------------------
*/
void breakable_brush()
{
self.max_health = self.health;
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
setorigin (self, self.origin);
setmodel (self, self.model);
if (self.spawnflags & BREAK_ORDERED)
{
self.th_die = brush_use_ordered;
self.cnt = 1;
}
else if (self.spawnflags & BREAK_HIERARCH)
self.th_die = brush_use_hierarchy;
else
self.th_die = brush_use;
if (self.spawnflags & BREAK_TRANSLUCENT)
self.drawflags(+)DRF_TRANSLUCENT;
if(!self.thingtype)
self.thingtype=THINGTYPE_GLASS;
if (!self.health)
if(self.thingtype<21)
self.health=breakhealth[self.thingtype];
else
self.health = 50;
self.max_health = self.health;
if (self.flags)
self.frags = self.flags;
if (self.abslight)
self.drawflags(+)MLS_ABSLIGHT;
if (self.spawnflags&BREAK_INVINCIBLE)
self.takedamage = DAMAGE_NO;
else
self.takedamage = DAMAGE_YES;
// self.takedamage = DAMAGE_NO_GRENADE;
if (self.spawnflags&BREAK_INVISIBLE)
{
self.effects (+) EF_NODRAW;
self.th_die = SUB_Remove;
}
else
self.th_die = chunk_death;
if(self.spawnflags&BREAK_NOLINK)
self.use=self.th_die;//brush_no_link_use;
else
{
self.use = brush_use;
self.think=linkBreakables;
self.nextthink=self.ltime+0.1;
}
if(self.pain_target!="")
self.th_pain = breakable_hurt_use;
self.ltime = time;
}

215
bridge.hc Normal file
View File

@ -0,0 +1,215 @@
/*
* $Header: /HexenWorld/Siege/Bridge.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
ROPE BRIDGES
==============================================================================
*/
/*
* Rope Bridge entity fields:
* ----------------------------
* .owner - First link in this bridge.
* .count - Number of the last link in the bridge.
* .cnt - Number of this link.
* .movechain - Next link in the chain. Not used for last link.
* .dmg - Amount of stress being put on this link.
* .enemy - Last entity which was putting weight on this link.
* .speed - Distance this link will sway in the wind.
* .yaw_speed - Distance this link is from its origin cos of wind.
*/
/*
* ropebridge_touch() -- Affects the bridge when it's walked on.
*/
void ropebridge_touch()
{
local entity link;
local float difference;
if(other.movetype != MOVETYPE_STEP && other.movetype != MOVETYPE_WALK)
return;
if(other == self.enemy)
return;
link = self.owner.movechain;
self.enemy = other;
while(link != self) // Links from start to self
{
link.dmg = link.dmg - link.cnt / self.cnt;
link = link.movechain;
}
self.dmg = self.dmg + self.cnt;
difference = 1 / (self.count - self.cnt);
link = self.movechain;
while(link.movechain) // Links from self to end
{
link.dmg = link.dmg - difference * (self.count - link.cnt);
link = link.movechain;
}
link = self.owner.movechain;
while(link.movechain)
{
link.oldorigin_z = link.dmg;
setorigin(link, link.origin + link.oldorigin);
link = link.movechain;
}
}
/*
* ropebridge_relieveweight() -- Relieves weight from touching monsters/players.
*/
void ropebridge_relieveweight(entity focal)
{
local entity link;
link = self.owner.movechain;
}
/*
* ropebridge_think() -- Sways the entire bridge a little.
*/
void ropebridge_think()
{
local entity link;
link = self.movechain;
while(link.movechain)
{
if(link.enemy != world)
if(!EntitiesTouching(link, link.enemy))
{
ropebridge_relieveweight(link);
link.enemy = world;
}
if(link.t_length)
setorigin(link, link.origin + (link.movedir * link.yaw_speed));
else
setorigin(link, link.origin - (link.movedir * link.yaw_speed));
if(link.t_width)
{
link.yaw_speed += 0.7;
if(link.yaw_speed >= link.speed)
{
link.t_width = 0;
link.yaw_speed = link.speed;
}
}
else {
link.yaw_speed -= 0.7;
if(link.yaw_speed < 0)
{
link.t_length = 0;
link.t_width = 1;
link.yaw_speed = 0;
}
}
link = link.movechain;
}
self.nextthink = time + 0.05;
}
/*
* ropebridge_init() -- Sets up each link of the bridge.
* Only called by the first link.
*/
void ropebridge_init()
{
local entity link;
local float midpoint, thispoint;
link = self;
while(link.target)
{
if(link.classname != "ropebridge")
{
bprint("Error: Rope bridge link ");
bprint(ftos(self.count));
bprint(" is targeted wrong\n");
return;
}
link.owner = self;
link.movechain = find(world, targetname, link.target);
link.cnt = self.count;
link = link.movechain;
self.count = self.count + 1;
}
link = self;
midpoint = self.count * 0.5;
thispoint = 1;
while(thispoint <= self.count)
{
if(thispoint < midpoint)
link.speed = sqrt(thispoint - 1);
else
link.speed = sqrt(self.count - thispoint);
link.yaw_speed = link.speed;
link.count = self.count;
link = link.movechain;
thispoint = thispoint + 1;
}
self.nextthink = time + 0.05;
self.think = ropebridge_think;
}
/*QUAKED ropebridge_link (0.3 0.1 0.6) ? START
A link of a rope bridge which sways in the wind and drops a little when it's walked on.
--------------------------------------
.target - The next link in the bridge.
Don't set if it's the last
link.
START - Check this if this is the
first link in the bridge.
--------------------------------------
*/
void ropebridge_link()
{
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
self.classname = "ropebridge";
self.movedir = '0 1 -0.4';
setmodel (self, self.model);
setorigin(self, self.origin);
if(self.spawnflags)
{
self.count = 1;
self.nextthink = time + 0.05;
self.think = ropebridge_init;
}
else
self.touch = ropebridge_touch;
}

238
builtin.hc Normal file
View File

@ -0,0 +1,238 @@
//**************************************************************************
//**
//** builtin.hc
//**
//** $Header: /HexenWorld/Siege/builtin.hc 19 5/25/98 1:38p Mgummelt $
//**
//**************************************************************************
// Sets v_forward, etc.
void makevectors(vector ang) : 1;
void setorigin(entity e, vector o) : 2;
// Set movetype and solid before calling.
void setmodel(entity e, string m) : 3;
void setsize(entity e, vector min, vector max) : 4;
void lightstylestatic(float style, float value) : 5;
void debugbreak(void) : 6;
// Returns 0 - 1.
float random(void) : 7;
void sound(entity e, float chan, string samp, float vol, float atten) : 8;
vector normalize(vector v) : 9;
void error(string e) : 10;
void objerror(string e) : 11;
float vlen(vector v) : 12;
float vectoyaw(vector v) : 13;
entity spawn(void) : 14;
void remove(entity e) : 15;
// Sets trace_* globals.
void traceline(vector v1, vector v2, float nomonsters,
entity forent) : 16;
// Returns a client to look for.
entity checkclient(void) : 17;
entity find(entity start, .string fld, string match) : 18;
// For sounds in demo and retail version.
string precache_sound(string s) : 19;
// For models in demo and retail version.
string precache_model(string s) : 20;
void stuffcmd(entity client, string s) : 21;
entity findradius(vector org, float rad) : 22;
void bprint(float level, string s) : 23;
void sprint(entity client, float level, string s) : 24;
void dprint(string s) : 25;
string ftos(float f) : 26;
string vtos(vector v) : 27;
// Prints all edicts.
void coredump(void) : 28;
void traceon(void) : 29;
void traceoff(void) : 30;
// Prints an entire edict.
void eprint(entity e) : 31;
// Returns TRUE or FALSE.
float walkmove (float yaw, float dist, float set_trace) : 32;
float tracearea(vector v1, vector v2, vector mins, vector maxs,
float nomonsters, entity forent) : 33;
// TRUE if landed on floor.
float droptofloor(void) : 34;
void lightstyle(float style, string value) : 35;
// Round to nearest int.
float rint(float v) : 36;
// Largest integer <= v.
float floor(float v) : 37;
// Smallest integer >= v.
float ceil(float v) : 38;
// Award experience to player.
//void AwardExperience(entity ToEnt, entity FromEnt, float Amount) : 39;
// TRUE if self is on ground.
float checkbottom(entity e) : 40;
// Returns a CONTENT_*.
float pointcontents(vector v) : 41;
// Start a particle effect.
void particle2(vector o, vector dmin, vector dmax, float color,
float type, float count) : 42;
float fabs(float f) : 43;
// Returns a shooting vector.
vector aim(entity e,vector d,float speed) : 44;
// Returns the cvar value.
float cvar(string s) : 45;
// Put a string into local que.
void localcmd(string s) : 46;
// For looping through all ents.
entity nextent(entity e) : 47;
// Start a particle effect.
void particle(vector o, vector d, float color, float count) : 48;
// Turn towards self.ideal_yaw at self.yaw_speed.
float ChangeYaw(void) : 49;
// Calculate distance, ignoring z.
float vhlen(vector v) : 50;
vector vectoangles(vector v) : 51;
void WriteByte(float to, float f) : 52;
void WriteChar(float to, float f) : 53;
void WriteShort(float to, float f) : 54;
void WriteLong(float to, float f) : 55;
void WriteCoord(float to, float f) : 56;
void WriteAngle(float to, float f) : 57;
void WriteString(float to, string s) : 58;
void WriteEntity(float to, entity s) : 59;
void dprintf(string s, float num) : 60;
float cos(float angle) : 61;
float sin(float angle) : 62;
float AdvanceFrame(float start, float end) : 63;
void dprintv(string s, vector vec) : 64;
float RewindFrame(float start, float end) : 65;
void setclass(entity e, float value) : 66;
void movetogoal(float step) : 67;
// For files in demo and retail version.
string precache_file(string s) : 68;
void makestatic(entity e) : 69;
void changelevel(string level, string spot) : 70;
// Returns the current value of a light style.
float lightstylevalue(float style) : 71;
// Sets a cvar value.
void cvar_set(string var, string val) : 72;
// Same as sprint(), but centered.
void centerprint(entity client, string s) : 73;
void ambientsound(vector pos, string samp, float vol, float atten) : 74;
// For models only in retail version.
string precache_model2(string s) : 75;
// For sounds only in retail version.
string precache_sound2(string s) : 76;
// For files only in retail version.
string precache_file2(string s) : 77;
// Sets parm1... to the values at level start for coop respawn.
void setspawnparms(entity e) : 78;
void plaque_draw(float to, float index) : 79;
// Create rain.
void rain_go(vector v1, vector v2, vector e_size, vector dir,
float color, float count) : 80;
// Particle explosion.
void particleexplosion(vector v,float f,float c,float s) : 81;
// Move a step.
float movestep(float x, float y, float z, float set_trace) : 82;
// Returns TRUE or FALSE (move other).
float advanceweaponframe(float startframe, float endframe) : 83;
float sqrt(float num1) : 84;
void particle3(vector o, vector box, float color, float type, float count) : 85;
void particle4(vector o, float radius, float color, float type, float count) : 86;
// m will used as: models/puzzle/m.mdl
void setpuzzlemodel(entity e, string m) : 87;
//float starteffect(float to, float effect) : 88;
float starteffect(...) : 88;
float endeffect(float to, float effect_id) : 89;
string precache_puzzle_model(string s) : 90;
vector concatv(vector in, vector limit) : 91;
string getstring(float id) : 92;
entity spawn_temp(void) : 93;
vector v_factor(vector factor) : 94;
// returns (v_right * factor_x) + (v_forward * factor_y) + (v_up * factor_z)
vector v_factorrange(vector start, vector end) : 95;
string precache_sound3(string s) : 96;
string precache_model3(string s) : 97;
string precache_file3(string s) : 98;
void logfrag(entity killer, entity killee) : 99; // add to stats
string infokey(entity e, string key) : 100; // get a key value (world = serverinfo)
float stof(string s) : 101; // convert string to float
void multicast(vector where, float set) : 102; // sends the temp message to a set
void turneffect(float effect_id, vector pos, vector dir) : 103;
void updateeffect(...) : 104; //have server send an update message (type-specific) to clients
// format: updateeffect(<effect index>, <effect type>, <type-specific extra info>);
void setseed(float seed) : 105; //seed is really a short int
float seedrand(void) : 106;
void multieffect(...) : 107;
float getmeid(void) : 108;
void weapon_sound(entity e, string s) : 109; //net efficient weapon sound on entity
void bcenterprint2(string s, string s) : 110; // center prints two concated strings to all clients
void print_indexed(float to, float level, float index): 111;//print string in strings.txt indicated by index
void centerprint2(entity e, string s, string s) : 112;
void print_name(float to, float level, entity who) : 113;//print name of who
void stopSound(entity e, float chan) : 114;
void updateSoundPos(entity e, float chan) : 115;
string precache_sound5(string s) : 116;
string precache_model5(string s) : 117;
string precache_file5(string s) : 118;
void setsiegeteam(entity who, float s_team) : 119;
void updateSiegeInfo(void) : 120;

479
buttons.hc Normal file
View File

@ -0,0 +1,479 @@
/*
* $Header: /HexenWorld/Siege/Buttons.hc 3 5/25/98 1:38p Mgummelt $
*/
// button and multiple button
float SPAWNFLAG_BUTTON_ACTIVATE = 1;
float FIRE_MULTIPLE = 4;
void() button_wait;
void() button_return;
void() pressure_use;
void() pressure_touch;
void() button_wait =
{
self.state = STATE_TOP;
if(self.wait==-1)
if(!self.inactive)
self.nextthink=-1;
else
self.nextthink=self.ltime+0.3;
else
self.nextthink = self.ltime + self.wait;
self.think = button_return;
activator = self.enemy;
if (!self.inactive)
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_NO_GRENADE; // can be shot again
};
void() button_blocked =
{ // do nothing, just don't come all the way back out
};
void() button_fire =
{
string s;
if (self.inactive)
{
if (other.classname == "player" && self.msg2)
{
s = getstring(self.msg2);
centerprint(other, s);
}
return;
}
if (self.state == STATE_UP)
return;
self.check_ok = TRUE;
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.flags&FL_PUSH)&&other.classname!="player")
return;
// if(self.inactive)
// return;
if (self.state == STATE_TOP) 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) ? deactivated FIREONLY FIRE_MULTIPLE x x x
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,
unless it's a pressure plate, in which case it will not return to it's position until it's not being touched anymore.
FIREONLY - has to be killed, touching won't do it.
FIRE_MULTIPLE - can be shot over and over (give it a high health)
-----------------------FIELDS-------------------------
"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 can be killed and touched
"abslight" - to set the absolute light level
"soundtype"
0) steam metal
1) wooden clunk
2) metallic click
3) in-out
deactivated - button must be activated before it will work
--------------------------------------------------------
*/
void() func_button =
{
// local float gtemp, ftemp;
if (self.soundtype == 0)
{
precache_sound ("buttons/button1.wav");
self.noise = "buttons/button1.wav";
}
if (self.soundtype == 1)
{
precache_sound ("buttons/button2.wav");
self.noise = "buttons/button2.wav";
}
if (self.soundtype == 2)
{
precache_sound ("buttons/button3.wav");
self.noise = "buttons/button3.wav";
}
if (self.soundtype == 3)
{
precache_sound ("buttons/button4.wav");
self.noise = "buttons/button4.wav";
}
SetMovedir ();
if (self.abslight)
self.drawflags(+)MLS_ABSLIGHT;
self.classname="button";
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;
if(self.spawnflags&FIRE_MULTIPLE)
self.th_pain = button_use;//for multiple uses
self.th_die = button_killed;
self.takedamage = DAMAGE_NO_GRENADE;
}
if (!self.spawnflags & 2)
{
if (!self.health) self.health = 10;
self.touch = button_touch;
}
if (!self.speed)
self.speed = 40;
if (!self.wait)
self.wait = 1;
if (!self.lip)
self.lip = 4;
//If activatable, set usable flags off
if(self.spawnflags&SPAWNFLAG_BUTTON_ACTIVATE)
self.inactive=TRUE;
else self.inactive=FALSE;
self.state = STATE_BOTTOM;
self.pos1 = self.origin;
self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
self.ltime = time;
};
/*
-------------------------------------------------------------------------
*/
float pressure_weight_check ()
{
vector org;
float len, totalmass;
entity head;
org = (self.absmax + self.absmin)*0.5;
len = vlen(self.absmax - self.absmin)*0.66;
head = findradius(org, len);
while (head)
{
if(head!=self)
{
if(head.flags2&FL_ALIVE)
totalmass += head.mass*10;
else
totalmass += head.mass;
/* if(head.netname)
dprint(head.netname);
else
dprint(head.classname);
dprint(" weight added\n");
*/ }
head = head.chain;
}
/* dprint("Measured mass: ");
dprint(ftos(totalmass));
dprint("\n");
dprint("Required mass: ");
dprint(ftos(self.mass));
dprint("\n");
*/
if (totalmass >= self.mass)
return TRUE;
else
return FALSE;
}
float pressure_bounds_check ()
{
vector org1,org2,org3,org4, center,found_bottom;
float radius;
entity found;
org1_z=org2_z=org3_z=org4_z=self.absmax_z+3;
org1_x = self.absmin_x;
org1_y = self.absmin_y;
org2_x = self.absmin_x;
org2_y = self.absmax_y;
org3_x = self.absmax_x;
org3_y = self.absmin_y;
org4_x = self.absmax_x;
org4_y = self.absmax_y;
center=(self.absmax+self.absmin)*0.5;
center_z=self.absmax_z;
radius=fabs(self.absmax_x-center_x);
found=findradius(center,radius);
while(found)
{
found_bottom=(found.absmin+found.absmax)*0.5;
found_bottom_z=found.absmin_z;
if(found!=self)
if(found_bottom_x>self.absmin_x&&found_bottom_x<self.absmax_x)
if(found_bottom_y>self.absmin_y&&found_bottom_y<self.absmax_y)
if(found_bottom_z>=self.absmax_z - 3&&found_bottom_z<=self.absmax_z+7)
return TRUE;
else
dprint("Not right height\n");
else
dprint("Not right y\n");
else
dprint("Not right x\n");
found=found.chain;
}
return FALSE;
}
void() pressure_wait =
{
float tripped;
tripped=TRUE;
if(!pressure_bounds_check())
tripped=FALSE;
if (!pressure_weight_check())
tripped=FALSE;
if(tripped)
{
self.check_ok = TRUE;
self.nextthink = self.ltime + 0.05;
}
else
{
self.check_ok = FALSE;
pressure_use();
self.touch = pressure_touch;
SUB_CalcMove(self.pos1, self.speed, SUB_Null);
}
};
void() pressure_fire =
{
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_UP;
self.touch = SUB_Null;
SUB_UseTargets();
SUB_CalcMove (self.pos2, self.speed, pressure_wait);
};
void() pressure_use =
{
self.enemy = activator;
pressure_fire ();
};
void() pressure_touch =
{
if(other==world)
return;
entity found;
float inbounds,enough_weight;
if(pressure_bounds_check())
inbounds=TRUE;
if (pressure_weight_check())
enough_weight=TRUE;
if(inbounds)
{
if(enough_weight)
{
self.check_ok = TRUE;
self.touch = SUB_Null;
pressure_use();
}
else
{
if(self.pain_finished<time&&other!=self.goalentity)
if(other.classname=="player")
{
centerprint(other,"Looks like it needs more weight...\n");
self.pain_finished=time+1;
}
else
{
found=findradius(other.origin,128);
while(found)
{
if(found.classname=="player")
{
centerprint(found,"Looks like it needs more weight...\n");
self.pain_finished=time+1;
found=world;
}
else
found=found.chain;
}
}
}
}
self.goalentity=other;
};
void() pressure_blocked =
{
float tripped;
tripped=TRUE;
if(!pressure_bounds_check())
tripped=FALSE;
if (!pressure_weight_check())
tripped=FALSE;
if(tripped)
{
self.check_ok = TRUE;
self.touch = SUB_Null;
pressure_use();
return;
}
};
/*QUAKED func_pressure (0 .5 .8) ? ACTIVATE
-----------------------FIELDS-------------------------
"mass" amount of mass a plate must have on it to fire-this can be cumulative so you have to put more than one thing on pressure plate to work (default 0)
NOTE:
Player mass ~= 60-80
Normal barrel mass = 75
Normal barrel mass = 85
Indestructible barrel mass = 95
"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
"soundtype"
0) steam metal
1) wooden clunk
2) metallic click
3) in-out
--------------------------------------------------------
*/
void func_pressure (void)
{
//local float gtemp, ftemp;
if (self.soundtype == 0)
{
precache_sound ("buttons/airbut1.wav");
self.noise = "buttons/airbut1.wav";
}
if (self.soundtype == 1)
{
precache_sound ("buttons/switch21.wav");
self.noise = "buttons/switch21.wav";
}
if (self.soundtype == 2)
{
precache_sound ("buttons/switch02.wav");
self.noise = "buttons/switch02.wav";
}
if (self.soundtype == 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 = pressure_blocked;
self.use = pressure_use;
self.touch = pressure_touch;
self.ltime = time;
if (self.health)
{
self.max_health = self.health;
self.th_die = button_killed;
self.takedamage = DAMAGE_NO_GRENADE;
}
else
self.touch = pressure_touch;
if (!self.speed)
self.speed = 40;
if (!self.wait)
self.wait = 1;
if (!self.lip)
self.lip = 4;
//If activatable, set usable flags off
if(self.spawnflags&SPAWNFLAG_BUTTON_ACTIVATE)
self.inactive=TRUE;
// else
// self.inactive=FALSE;
self.state = STATE_BOTTOM;
self.pos1 = self.origin;
self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
}

275
camera.hc Normal file
View File

@ -0,0 +1,275 @@
/*
* $Header: /HexenWorld/Siege/camera.hc 8 5/26/98 1:26a Mgummelt $
*/
void(entity voyeur, entity viewthing) CameraViewPort =
{//FIXME: Doesn't work in H2W
msg_entity = voyeur;
WriteByte (MSG_ONE, SVC_SETVIEWPORT);
WriteEntity (MSG_ONE, viewthing);
};
void(entity voyeur, entity viewthing) CameraViewAngles =
{//FIXME: Doesn't work in H2W
msg_entity = voyeur;
WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
if(viewthing.classname=="camera_remote")
WriteAngle(MSG_ONE, 360-viewthing.angles_x);
else
WriteAngle(MSG_ONE, viewthing.angles_x);
WriteAngle(MSG_ONE, viewthing.angles_y);
WriteAngle(MSG_ONE, viewthing.angles_z);
};
/*QUAKED target_null (1 0 0) (-8 -8 -8) (8 8 8)
A null target for the camera
-------------------------FIELDS-------------------------
none
--------------------------------------------------------
*/
void target_null (void)
{
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_NONE;
precache_model ("models/sprites/null.spr");
setmodel(self,"models/sprites/null.spr");
}
/*-----------------------------------------
play_camera - play noise for when popping in or out of camera mode
-----------------------------------------*/
void() play_camera =
{
// sound (self, CHAN_VOICE, "misc/camera.wav", 1, ATTN_NORM);
remove (self);
};
/*-----------------------
AllyVision (see through teammate's eyes)
------------------------*/
void AllyVision (entity voyeur,entity ally)
{
entity snd_ent;
// if(deathmatch)
if(voyeur.cameramode==world||voyeur.cameramode==voyeur)
if (voyeur.weaponmodel!= string_null)
{
voyeur.lastweapon = voyeur.weaponmodel;
voyeur.weaponmodel = string_null;
}
voyeur.view_ofs=ally.view_ofs;
voyeur.cameramode = ally;
voyeur.camera_time = time + 10;
voyeur.attack_finished = voyeur.camera_time;
voyeur.oldangles = voyeur.angles;
stuffcmd (voyeur, "bf\n");
msg_entity = voyeur;
CameraViewPort(voyeur,ally);
WriteByte (MSG_ONE, 10); // 10 = SVC_SETVIEWANGLES
WriteAngle (MSG_ONE,ally.v_angle_x); // pitch
WriteAngle (MSG_ONE,ally.v_angle_y); // yaw
WriteAngle (MSG_ONE,ally.v_angle_z); // roll
//put back in
snd_ent = spawn ();
snd_ent.origin = ally.origin;
thinktime snd_ent : HX_FRAME_TIME;
snd_ent.think = play_camera;
}
/*-----------------------------------------
CameraUse - place player in camera remote
-----------------------------------------*/
void CameraUse (void)
{
return;
entity snd_ent;
other = other.enemy; // Use the enemy of the trigger or button
if (other.classname != "player")
return;
stuffcmd (other, "bf\n");
if(deathmatch)
other.view_ofs='0 0 0';
other.cameramode = self;
other.camera_time = time + self.wait;
other.oldangles = other.angles;
other.lastweapon = other.weaponmodel;
other.weaponmodel = string_null;
CameraViewPort(other,self);
WriteByte (MSG_ONE, 10); // 10 = SVC_SETVIEWANGLES
WriteAngle (MSG_ONE,360 - self.angles_x); // pitch
WriteAngle (MSG_ONE,self.angles_y); // yaw
WriteAngle (MSG_ONE,self.angles_z); // roll
snd_ent = spawn ();
snd_ent.origin = self.origin;
thinktime snd_ent : HX_FRAME_TIME;
snd_ent.think = play_camera;
}
/*-----------------------------------------
CameraReturn - return the player to his body
-----------------------------------------*/
void CameraReturn(void)
{
entity snd_ent;
self.cameramode = world;
self.weaponmodel = self.lastweapon;
self.view_ofs=self.proj_ofs+'0 0 6';
stuffcmd (self, "bf\n");
self.angles = self.oldangles;
self.idealroll = 0;
CameraViewPort(self,self);
CameraViewAngles(self,self);
snd_ent = spawn ();
snd_ent.origin = self.origin;
thinktime snd_ent : HX_FRAME_TIME;
snd_ent.think = play_camera;
}
/*-----------------------------------------
camera_target- point the camera at it's target
-----------------------------------------*/
void camera_target (void)
{
self.enemy = find (world,targetname,self.target);
self.angles = vectoangles(self.enemy.origin - self.origin);
}
/*QUAKED camera_remote (1 0 0) (-8 -8 -8) (8 8 8)
A camera which the player becomes when triggered.
-------------------------FIELDS-------------------------
"wait" - amount of time player is stuck in camera mode
(default 3 seconds)
To point camera in a direction
target a "target_null" entity
or fill out the angle fields:
angles_x - pitch of camera
angles_y - yaw of camera
--------------------------------------------------------
*/
void camera_remote (void)
{
if(deathmatch)
{
remove(self);
return;
}
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_NONE;
precache_model ("models/sprites/null.spr");
setmodel(self,"models/sprites/null.spr");
self.use = CameraUse;
if (!self.wait)
self.wait = 3;
if (self.target)
{
self.think = camera_target;
self.nextthink = time + 0.02; // Give target a chance to spawn into the world
}
setsize(self, '-1 -1 0', '1 1 1');
}
void CameraThink ()
{
vector viewdir;
vector spot1,spot2;
self.level=cvar("chase_back");
if(self.cnt<self.level)
self.cnt+=1;
else if(self.cnt>self.level)
self.cnt-=1;
makevectors(self.owner.v_angle);
viewdir=normalize(v_forward);
spot1=self.owner.origin+self.owner.proj_ofs+'0 0 6';
spot2=spot1-viewdir*self.cnt;
traceline(spot1,spot2,TRUE,self.owner);
viewdir=normalize(spot1-trace_endpos);
setorigin(self,trace_endpos+viewdir*4);
self.think=CameraThink;
thinktime self : 0;
}
void ToggleChaseCam (entity voyeur)
{
if(voyeur.viewentity.classname=="chasecam")
{
//Turn off camera view
CameraViewPort(voyeur,voyeur);
CameraViewAngles(voyeur,voyeur);
remove(voyeur.viewentity);
voyeur.viewentity=voyeur;
voyeur.view_ofs=voyeur.proj_ofs+'0 0 6';
voyeur.attack_finished=0;
voyeur.weaponmodel=voyeur.lastweapon;
voyeur.oldweapon=FALSE;
W_SetCurrentAmmo();
}
else
{
if(voyeur.cameramode!=voyeur&&voyeur.cameramode!=world)
centerprint(voyeur,"Chase camera not available while in another camera mode\n");
voyeur.lastweapon=voyeur.weaponmodel;
voyeur.oldweapon=0;
voyeur.weaponmodel="";
makevectors(voyeur.v_angle);
voyeur.viewentity=spawn();
voyeur.viewentity.owner=voyeur;
voyeur.viewentity.angles=voyeur.angles;
voyeur.viewentity.level=cvar("chase_back");
if(!voyeur.viewentity.level)
voyeur.viewentity.level=68;
voyeur.viewentity.cnt=4;
voyeur.viewentity.classname="chasecam";
voyeur.view_ofs='0 0 0';
setmodel(voyeur.viewentity,"models/null.spr");
setsize(voyeur.viewentity, '0 0 0','0 0 0');
setorigin(voyeur.viewentity,voyeur.origin+voyeur.proj_ofs+'0 0 6'-v_forward*4);
CameraViewPort(voyeur,voyeur.viewentity);
CameraViewAngles(voyeur,voyeur.viewentity);
voyeur.viewentity.think=CameraThink;
thinktime voyeur.viewentity : 0;
}
}

83
cameramg.hc Normal file
View File

@ -0,0 +1,83 @@
void(entity voyeur, entity viewthing) CameraViewPort =
{//FIXME: Doesn't seem to work if it's out of vis- only
// remembers last spot it was at last time it WAS in vis
msg_entity = voyeur;
WriteByte (MSG_ONE, SVC_SETVIEWPORT);
WriteEntity (MSG_ONE, viewthing);
};
void(entity voyeur, entity viewthing) CameraViewAngles =
{//FIXME: Doesn't seem to work if it's out of vis- only
// remembers last angles it was at last time it WAS in vis
msg_entity = voyeur;
WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
if(viewthing.classname=="camera_remote")
WriteAngle(MSG_ONE, 360-viewthing.angles_x);
else
WriteAngle(MSG_ONE, viewthing.angles_x);
WriteAngle(MSG_ONE, viewthing.angles_y);
WriteAngle(MSG_ONE, viewthing.angles_z);
};
void CameraThink ()
{
vector viewdir;
vector spot1,spot2;
self.level=cvar("chase_back");
if(self.cnt<self.level)
self.cnt+=1;
else if(self.cnt>self.level)
self.cnt-=1;
makevectors(self.owner.v_angle);
viewdir=normalize(v_forward);
spot1=self.owner.origin+self.owner.proj_ofs+'0 0 6';
spot2=spot1-viewdir*self.cnt;
traceline(spot1,spot2,TRUE,self.owner);
viewdir=normalize(spot1-trace_endpos);
setorigin(self,trace_endpos+viewdir*4);
self.think=CameraThink;
thinktime self : 0;
}
void MakeCamera ()
{
if(self.viewentity.classname=="chasecam")
{
//Turn off camera view
CameraViewPort(self,self);
CameraViewAngles(self,self);
self.attack_finished=0;
W_SetCurrentAmmo();
remove(self.viewentity);
self.viewentity=self;
self.view_ofs=self.proj_ofs+'0 0 6';
}
else
{
self.lastweapon=self.weaponmodel;
self.weaponmodel="";
makevectors(self.v_angle);
self.viewentity=spawn();
self.viewentity.owner=self;
self.viewentity.angles=self.angles;
self.viewentity.level=cvar("chase_back");
if(!self.viewentity.level)
self.viewentity.level=68;
self.viewentity.cnt=4;
self.viewentity.classname="chasecam";
self.view_ofs='0 0 0';
setmodel(self.viewentity,"models/null.spr");
setsize(self.viewentity, '0 0 0','0 0 0');
setorigin(self.viewentity,self.origin+self.proj_ofs+'0 0 6'-v_forward*4);
CameraViewPort(self,self.viewentity);
CameraViewAngles(self,self.viewentity);
self.viewentity.think=CameraThink;
thinktime self.viewentity : 0;
}
}

411
cat2.hc Normal file
View File

@ -0,0 +1,411 @@
/*QUAKED obj_catapult2 (0 .5 .8) (-150 -150 0) (150 150 28) ?
"speed" Throw speed (300 default)
"wait" wait before resetting (3 default)
"health" Just how tough is it (defaults to 1000)
"mass" How hard is it to push (defaults to 1000)
"thingtype" Defaults to THINGTYPE_WOOD
"aflag" - Max distance it can be pushed from start pos (default 256)
"-1" disables this
"sounds"
0) no sound
1) stone
2) base
3) stone chain
4) screechy metal
*/
void catapult_ready (void)
{
//FIXME: No linking in touch, do it all in here with a tracearea (is that working?) and findradius
// if(self.flags&FL_ONGROUND&&world.model!="maps/siege3.bsp")
// self.movetype = MOVETYPE_NONE;
if(self.origin!=self.oldorigin||self.angles!=self.o_angle)
{
entity found;
vector dir,org,fmins,fmaxs;
// dprint("updating dependancies\n");
makevectors(self.angles);
dir=normalize(v_forward);
org=self.origin+dir*-4*self.level;
org_z=self.absmax_z;
found=nextent(world);
while(found)
{
//Find ground entity
fmins=found.mins;
fmaxs=found.maxs;
fmins_z=0;
fmaxs_z=8;
tracearea(found.origin+'0 0 1',found.origin-'0 0 8',fmins,fmaxs,FALSE,found);
if(trace_ent!=self)
found.catapulter=world;
if(vhlen(found.origin-org)<2*self.level&&found.catapulter==self)
{
float repos_dist,repos_dist_cnt,repos_dir_angle;
vector repos_dir;
entity save_ent;
// dprint(found.classname);
// dprint(" updated\n");
repos_dir=org+found.pos_ofs - found.origin;
repos_dist=vlen(repos_dir);
repos_dir=normalize(repos_dir);
repos_dir_angle=vectoyaw(repos_dir);
save_ent=self;
self=found;
while(repos_dist_cnt<repos_dist)
{
repos_dist_cnt+=1;
if(!walkmove(repos_dir_angle,1,FALSE))
repos_dist_cnt=repos_dist;
}
self=save_ent;
// setorigin(found,org+found.pos_ofs);
found.angles=self.angles+found.angle_ofs;
found.velocity='0 0 0';
found.flags(+)FL_ONGROUND;
}
found=nextent(found);
}
}
if(self.angles_y>self.o_angle_y)
AdvanceFrame(33,42);
else if(self.angles_y<self.o_angle_y)
AdvanceFrame(42,33);
self.o_angle=self.angles;
self.oldorigin=self.origin;
self.think=catapult_ready;
thinktime self : 0;
}
void() catapult_reset =
{
if(self.frame==22)
{
sound(self,CHAN_VOICE,"misc/catdrop.wav",1,ATTN_NORM);
self.frame=0;
}
if(self.frame>=20)
{
sound(self,CHAN_VOICE,"misc/catreset.wav",1,ATTN_NORM);
self.frame=20;
self.think=catapult_ready;
thinktime self : 0;
}
else
{
self.frame+=1;
self.think=catapult_reset;
thinktime self : 0.05;
}
};
void catapult_wait (void)
{
entity firstcat, catdude;
firstcat=catdude=find(world,classname,other.catapulter.classname);
while(catdude)
{
if(other.catapulter==self)
other.catapulter=world;
catdude=find(catdude,classname,other.catapulter.classname);
if(catdude==firstcat)
catdude=world;
}
self.think=catapult_reset;
thinktime self : self.wait;
}
void catapult_fire (void)
{
if(self.frame==20||self.frame>22)
{
sound(self,CHAN_VOICE,"misc/catlnch.wav",1,ATTN_NORM);
entity found;
vector dir,org,addvel;
float distance, force,centrifugal,throwback;
found=nextent(world);
makevectors(self.angles);
dir=normalize(v_forward);
org=self.origin+dir*-4*self.level;
org_z=self.absmax_z;
while(found)
{
distance=vhlen(found.origin-org);
// if(found.catapulter==self)
if(distance<2*self.level&&found.origin_z>self.origin_z+self.maxs_z*0.75)//&&found.catapulter==self)
{
// inertia?
found.catapult_time=time+3;
found.catapulter=world;
traceline(found.origin,found.origin-'0 0 33',FALSE,found);
if(trace_ent!=self)
{//off back edge, throw backwards
throwback=TRUE;
centrifugal=vhlen(found.origin-org);
force=self.speed + random(-100,100) + centrifugal*4;//Ignore mass, Not exact physics, but feels better
addvel=dir*-1*force+v_right*random(-50,50);//Give some left-right innacuracy to it
force=self.speed + random(-100,100)+ centrifugal*4;
addvel_z=force;
}
else
{
throwback=FALSE;
centrifugal=vhlen(found.origin-self.origin);
force=self.speed + random(-100,100) + centrifugal*4;//4 Ignore mass, Not exact physics, but feels better
addvel=dir*force+v_right*random(-50,50);//Give some left-right innacuracy to it
force=self.speed + random(-100,100)+ centrifugal*4;
addvel_z=force;//FIXME: CAP at ???
}
// if(found.playerclass==CLASS_DWARF)
// addvel*=1.05;
found.velocity+=addvel;
if(!found.touch)
found.touch=obj_push;
found.flags(-)FL_ONGROUND;
if(found.classname=="player"&&found.playerclass!=CLASS_SUCCUBUS)
{
found.teleport_time=time+1.7;//No mario
}
if(!found.flags2&FL_ALIVE)
{
found.velocity=found.velocity*1.3;
if(throwback)
found.avelocity=found.velocity*(48-centrifugal)*random(-1,1);
else
found.avelocity=found.velocity*random(-1,1);
found.movetype=MOVETYPE_BOUNCE;
}
if(found.model=="models/sheep.mdl")
{
if(found.classname!="player")
{
found.velocity=found.velocity*1.3;
found.teleport_time+=666;//impact damage forever
found.touch=found.th_die;
found.enemy = self.enemy;
if(found.trigger_field)
remove(found.trigger_field);
}
found.avelocity=found.velocity*random(-1,1);
found.movetype=MOVETYPE_BOUNCE;
sound(found,CHAN_VOICE,"misc/sheepfly.wav",1,ATTN_NORM);
found.pain_finished=time+1;
}
if(found.model=="models/barrel.mdl")
{
found.touch = found.th_die;//Maybe make them always explode on touch
if(found.netname=="obj_barrel_gfire")
sound(self,CHAN_BODY,"misc/gflaunch.wav",1,ATTN_NORM);
if(found.trigger_field)
remove(found.trigger_field);
found.enemy = self.enemy;
found.think = found.th_die;
thinktime found : 5;
}
}
found=nextent(found);
}
}
if(self.frame>=22)
{
self.frame=22;
self.think=catapult_wait;
thinktime self : 0;
}
else
{
self.frame+=1;
self.think=catapult_fire;
thinktime self : 0.05;
}
}
void catapult_pain (void)
{
if(!self.enemy.flags2&FL_ALIVE&&self.enemy.classname!="blood missile")
return;
if(self.frame==20||self.frame>22)
catapult_fire();
}
void catapult2_touch(void)
{
if(other.solid==SOLID_BSP||other==self.movechain||other==world)
return;
/* dprint(other.classname);
dprint("\n");
dprint(ftos(other.absmin_z));
dprint(" > ");
dprint(ftos(self.absmax_z));
dprint("?\n");*/
if(other.origin_z-(other.mins_z*0.75)>=self.origin_z+(self.maxs_z*0.75))
{
if(other.solid!=SOLID_TRIGGER&&other.movetype&&other.catapulter!=self&&other.catapult_time<time+0.1)
{
vector dir,org;
float distance;
makevectors(self.angles);
dir=normalize(v_forward);
org=self.origin+dir*-4*self.level;
org_z=self.absmax_z;
distance=vhlen(other.origin-org);
if(distance<=2*self.level)
{
// dprint(other.classname);
// dprint(" locked and loaded!\n");
other.catapult_time=time+0.1;
other.catapulter=self;
other.velocity=self.velocity;
other.pos_ofs=other.origin-org;
other.angle_ofs=self.angles-other.angles;
}
other.flags(+)FL_ONGROUND;
}
}
//WAS pushable...
else if(other.classname=="player"&&(vlen(other.velocity)>100||coop||deathmatch)&&other.flags&FL_ONGROUND&&(other.impulse==13||self.last_use_time + 2>time))
{//only players can directly push it
// Push or spin
vector dir1, dir2,move_vel,dest_spot;
float magnitude,dot_forward,inertia;//,dot_right;
if(other.impulse == 13)
self.last_use_time = time;
self.angles_x=self.angles_z=0;
makevectors(self.angles);
magnitude=400;//vlen(other.velocity);
inertia=1/(self.mass/10);
dir1=normalize(self.origin-other.origin);
dir2=normalize(v_forward);
dir1_z=dir2_z=0;
dot_forward= dir1*dir2;
if(dot_forward >0.8)
{
move_vel=dir2*magnitude*inertia*5;
dest_spot=self.origin+(move_vel*0.01);
if(self.aflag!=-1)
if(vhlen(dest_spot-self.wallspot)>=self.aflag)
return;
// walkmove(self.angles_y,1,FALSE);
// dprint("Move forward\n");
self.velocity=move_vel;//FIXME: adds up if do += (for multiple pushers)
// dprint(vtos(self.velocity));
self.flags(-)FL_ONGROUND;
AdvanceFrame(23,32);
}
else if(dot_forward<-0.8)
{
move_vel=dir2*-1*magnitude*inertia*5;
dest_spot=self.origin+(move_vel*0.01);
if(self.aflag!=-1)
if(vhlen(dest_spot-self.wallspot)>=self.aflag)
return;
// dprint("Move backwards\n");
// walkmove(self.angles_y,-1,FALSE);
self.velocity=move_vel;//FIXME: adds up if do += (for multiple pushers)
self.flags(-)FL_ONGROUND;
AdvanceFrame(32,23);
}
// if(self.movechain)
// setorigin(self.movechain,self.origin+'0 0 26');
/* else
{
dir1=normalize(other.velocity);
dir2=normalize(v_right);
dot_right= dir1*dir2;
if(dot_right >0.2)
{
if(dot_forward >0.2)
{
self.angles_y-=1*magnitude/100;
}
else if(dot_forward<-0.2)
{
self.angles_y+=1*magnitude/100;
}
}
else if(dot_right<-0.2)
{
if(dot_forward >0.2)
{
self.angles_y+=1*magnitude/100;
}
else if(dot_forward<-0.2)
{
self.angles_y-=1*magnitude/100;
}
}
}*/
}
}
void obj_catapult2 (void)
{
precache_model("models/cattest.mdl");
precache_sound ("misc/catlnch.wav");
precache_sound ("misc/catreset.wav");
precache_sound ("misc/catdrop.wav");
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_PUSHPULL;
self.touch=catapult2_touch;
// setmodel (self, "models/catapult.mdl");
setmodel (self, "models/cattest.mdl");
setsize(self,'-145 -145 0','145 145 26');
self.hull=HULL_SCORPION;
setorigin (self, self.origin);
self.wallspot=self.origin;
if(self.aflag==0)
self.aflag=256;//Max dist to move from origin- not working? Set to movetyp NONE if gets too far? then can;t turn...
self.classname="catapult";
self.level = 30;
self.frame=20;
self.th_pain=catapult_pain;
self.th_weapon=catapult_fire;
if (!self.speed)
self.speed = 300;//Too strong?
if (self.wait==0)
self.wait = 3;
self.th_die = chunk_death;
self.takedamage = DAMAGE_YES;
self.use=catapult_fire;
if(!self.thingtype)
self.thingtype = THINGTYPE_WOOD;
if(!self.mass)
self.mass = 1000;
if (!self.health)
self.health=1000;
self.max_health = self.health = self.health*2;
self.think=catapult_ready;
thinktime self : 0;
spawn_push_trigger(10);
}

89
catapult.hc Normal file
View File

@ -0,0 +1,89 @@
void movechain_target (void)
{
if(self.target)
{
entity found;
found=find(world,targetname,self.target);
if(found==self)
{
found=nextent(self);
found=find(found,targetname,self.target);
}
self.movechain=found;
found.flags(+)FL_MOVECHAIN_ANGLE;
}
else
{
dprint(self.classname);
dprint(" has no target set\n");
}
self.nextthink=-1;
}
void BSP_stop (void)
{
self.velocity='0 0 0';
self.think=BSP_stop;
self.nextthink=time - 1;
}
void BSP_push (void)
{
vector pos,dir;
if(other.absmin_z>self.absmin_z+4||vlen(other.velocity)<150)
return;
dir=normalize(other.velocity+self.velocity);
dir_z=0;
pos=dir*10+self.origin;
SUB_CalcMove(pos,10,BSP_stop);
}
/*QUAKED obj_stairs (0 .5 .8) ?
*/
void obj_stairs (void)
{
if(!self.thingtype)
self.thingtype=THINGTYPE_WOOD;
if(self.health)
{
self.takedamage=DAMAGE_NO_GRENADE;
self.th_die=chunk_death;
}
self.flags(+)FL_PUSH;
self.solid=SOLID_BSP;
self.movetype=MOVETYPE_PUSH;
self.touch=BSP_push;
setmodel (self, self.model);
setsize(self,self.mins,self.maxs);
setorigin(self,self.origin);
}
/*QUAKED obj_bridge (0 .5 .8) ?
*/
void obj_bridge (void)
{
if(!self.thingtype)
self.thingtype=THINGTYPE_WOOD;
if(self.health)
{
self.takedamage=DAMAGE_NO_GRENADE;
self.th_die=chunk_death;
}
self.solid=SOLID_SLIDEBOX;
self.movetype=MOVETYPE_PUSHPULL;
self.touch=obj_push;
setmodel (self, self.model);
setsize(self,self.mins,self.maxs);
setorigin(self,self.origin);
}
void() catapult_button_turn=
{
};
void() catapult_button_think=
{
};

662
chunk.hc Normal file
View File

@ -0,0 +1,662 @@
/*
* $Header: /HexenWorld/Siege/chunk.hc 10 5/25/98 1:38p Mgummelt $
*/
void ThrowSolidHead (float dm);
void blood_splatter()
{
SpawnPuff(self.origin,normalize(self.velocity)*-20,10,self);
remove(self);
}
void ThrowBlood (vector org,vector dir)
{
entity blood;
blood=spawn_temp();
blood.solid=SOLID_BBOX;
blood.movetype=MOVETYPE_TOSS;
blood.touch=blood_splatter;
blood.velocity=dir;
blood.avelocity=randomv('-700 -700 -700','700 700 700');
blood.thingtype=THINGTYPE_FLESH;
setmodel(blood,"models/bldspot4.spr"); // 8 x 8 sprite size
setsize(blood,'0 0 0','0 0 0');
setorigin(blood,org);
}
void ZeBrains (vector spot, vector normal, float scaling, float face, float roll)
{
newmis=spawn();
newmis.scale=scaling;
newmis.angles=vectoangles(normal);
if(face)
newmis.angles_y+=180;
newmis.angles_z=roll;
setmodel(newmis,"models/brains.mdl");
setsize(newmis,'0 0 0','0 0 0');
setorigin(newmis,spot+normal*1);
newmis.think=corpseblink;
thinktime newmis : 30;
spot=newmis.origin;
makevectors(normal);
ThrowBlood(spot,(normal+random(0.75,0.75)*v_up+random(0.75,0.75)*v_right)*random(200,400));
ThrowBlood(spot,(normal+random(0.75,0.75)*v_up+random(0.75,0.75)*v_right)*random(200,400));
ThrowBlood(spot,(normal+random(0.75,0.75)*v_up+random(0.75,0.75)*v_right)*random(200,400));
ThrowBlood(spot,(normal+random(0.75,0.75)*v_up+random(0.75,0.75)*v_right)*random(200,400));
ThrowBlood(spot,(normal+random(0.75,0.75)*v_up+random(0.75,0.75)*v_right)*random(200,400));
}
void ChunkRemove (void)
{
chunk_cnt-=1;
SUB_Remove ();
}
vector ChunkVelocity (void)
{
local vector v;
v_x = 300 * crandom();
v_y = 300 * crandom();
v_z = random(100,400);
v = v * 0.7;
return v;
}
void ThrowSingleChunk (string chunkname,vector location,float life_time,float skinnum)
{
entity chunk;
if (chunk_cnt < CHUNK_MAX)
{
chunk=spawn_temp();
setmodel (chunk, chunkname);
chunk.frame = 0;
setsize (chunk, '0 0 0', '0 0 0');
chunk.movetype = MOVETYPE_BOUNCE;
chunk.solid = SOLID_NOT;
chunk.takedamage = DAMAGE_NO;
chunk.velocity = ChunkVelocity();
chunk.think = ChunkRemove;
chunk.flags(-)FL_ONGROUND;
chunk.origin = location;
chunk.avelocity_x = random(10);
chunk.avelocity_y = random(10);
chunk.avelocity_z = random(30);
chunk.skin = skinnum;
chunk.ltime = time;
thinktime chunk : life_time;
chunk_cnt+=1;
}
}
void MeatChunks (vector org,vector dir,float chunk_count,entity loser)
{
float final;
entity chunk;
while(chunk_count)
{
chunk=spawn_temp();
chunk_count-=1;
final = random();
if(loser.model=="models/spider.mdl")
{
if (final < 0.33)
setmodel (chunk, "models/sflesh1.mdl");
else if (final < 0.66)
setmodel (chunk, "models/sflesh2.mdl");
else
setmodel (chunk, "models/sflesh3.mdl");
}
else if (final < 0.33)
setmodel (chunk, "models/flesh1.mdl");
else if (final < 0.66)
setmodel (chunk, "models/flesh2.mdl");
else
setmodel (chunk, "models/flesh3.mdl");
setsize (chunk, '0 0 0', '0 0 0');
// chunk.skin=1;
chunk.movetype = MOVETYPE_BOUNCE;
chunk.solid = SOLID_NOT;
if(dir=='0 0 0')
chunk.velocity = ChunkVelocity();
else
chunk.velocity=dir;//+randomv('-200 -200 -200','200 200 200');
chunk.think = ChunkRemove;
chunk.avelocity_x = random(1200);
chunk.avelocity_y = random(1200);
chunk.avelocity_z = random(1200);
chunk.scale = .45;
chunk.ltime = time;
thinktime chunk : random(2);
setorigin (chunk, org);
}
}
void CreateModelChunks (vector space,float scalemod)
{
entity chunk;
float final;
chunk = spawn_temp();
space_x = space_x * random();
space_y = space_y * random();
space_z = space_z * random();
setorigin (chunk, self.absmin + space);
final = random();
if ((self.thingtype==THINGTYPE_GLASS) || (self.thingtype==THINGTYPE_REDGLASS) ||
(self.thingtype==THINGTYPE_CLEARGLASS) || (self.thingtype==THINGTYPE_WEBS))
{
if (final<0.20)
setmodel (chunk, "models/shard1.mdl");
else if (final<0.40)
setmodel (chunk, "models/shard2.mdl");
else if (final<0.60)
setmodel (chunk, "models/shard3.mdl");
else if (final<0.80)
setmodel (chunk, "models/shard4.mdl");
else
setmodel (chunk, "models/shard5.mdl");
if (self.thingtype==THINGTYPE_CLEARGLASS)
{
chunk.skin=1;
chunk.drawflags (+) DRF_TRANSLUCENT;
}
else if (self.thingtype==THINGTYPE_REDGLASS)
chunk.skin=2;
else if (self.thingtype==THINGTYPE_WEBS)
{
chunk.skin=3;
// chunk.drawflags (+) DRF_TRANSLUCENT;
}
}
else if (self.thingtype==THINGTYPE_WOOD)
{
if (final < 0.25)
setmodel (chunk, "models/splnter1.mdl");
else if (final < 0.50)
setmodel (chunk, "models/splnter2.mdl");
else if (final < 0.75)
setmodel (chunk, "models/splnter3.mdl");
else
setmodel (chunk, "models/splnter4.mdl");
}
else if (self.thingtype==THINGTYPE_METAL)
{
if (final < 0.25)
setmodel (chunk, "models/metlchk1.mdl");
else if (final < 0.50)
setmodel (chunk, "models/metlchk2.mdl");
else if (final < 0.75)
setmodel (chunk, "models/metlchk3.mdl");
else
setmodel (chunk, "models/metlchk4.mdl");
}
else if (self.thingtype==THINGTYPE_FLESH)
{
if(self.model=="models/spider.mdl")
{
if (final < 0.33)
setmodel (chunk, "models/sflesh1.mdl");
else if (final < 0.66)
setmodel (chunk, "models/sflesh2.mdl");
else
setmodel (chunk, "models/sflesh3.mdl");
}
else if (final < 0.33)
setmodel (chunk, "models/flesh1.mdl");
else if (final < 0.66)
setmodel (chunk, "models/flesh2.mdl");
else
setmodel (chunk, "models/flesh3.mdl");
if(self.classname=="hive")
chunk.skin=1;
}
else if (self.thingtype==THINGTYPE_BROWNSTONE||self.thingtype==THINGTYPE_DIRT)
{
if (final < 0.25)
setmodel (chunk, "models/schunk1.mdl");
else if (final < 0.50)
setmodel (chunk, "models/schunk2.mdl");
else if (final < 0.75)
setmodel (chunk, "models/schunk3.mdl");
else
setmodel (chunk, "models/schunk4.mdl");
chunk.skin = 1;
}
else if (self.thingtype==THINGTYPE_CLAY)
{
if (final < 0.25)
setmodel (chunk, "models/clshard1.mdl");
else if (final < 0.50)
setmodel (chunk, "models/clshard2.mdl");
else if (final < 0.75)
setmodel (chunk, "models/clshard3.mdl");
else
setmodel (chunk, "models/clshard4.mdl");
}
else if (self.thingtype==THINGTYPE_LEAVES)
{
if (final < 0.33)
setmodel (chunk, "models/leafchk1.mdl");
else if (final < 0.66)
setmodel (chunk, "models/leafchk2.mdl");
else
setmodel (chunk, "models/leafchk3.mdl");
}
else if (self.thingtype==THINGTYPE_HAY)
{
if (final < 0.33)
setmodel (chunk, "models/hay1.mdl");
else if (final < 0.66)
setmodel (chunk, "models/hay2.mdl");
else
setmodel (chunk, "models/hay3.mdl");
}
else if (self.thingtype==THINGTYPE_CLOTH)
{
if (final < 0.33)
setmodel (chunk, "models/clthchk1.mdl");
else if (final < 0.66)
setmodel (chunk, "models/clthchk2.mdl");
else
setmodel (chunk, "models/clthchk3.mdl");
}
else if (self.thingtype==THINGTYPE_WOOD_LEAF)
{
if (final < 0.14)
setmodel (chunk, "models/splnter1.mdl");
else if (final < 0.28)
setmodel (chunk, "models/leafchk1.mdl");
else if (final < 0.42)
setmodel (chunk, "models/splnter2.mdl");
else if (final < 0.56)
setmodel (chunk, "models/leafchk2.mdl");
else if (final < 0.70)
setmodel (chunk, "models/splnter3.mdl");
else if (final < 0.84)
setmodel (chunk, "models/leafchk3.mdl");
else
setmodel (chunk, "models/splnter4.mdl");
}
else if (self.thingtype==THINGTYPE_WOOD_METAL)
{
if (final < 0.125)
setmodel (chunk, "models/splnter1.mdl");
else if (final < 0.25)
setmodel (chunk, "models/metlchk1.mdl");
else if (final < 0.375)
setmodel (chunk, "models/splnter2.mdl");
else if (final < 0.50)
setmodel (chunk, "models/metlchk2.mdl");
else if (final < 0.625)
setmodel (chunk, "models/splnter3.mdl");
else if (final < 0.75)
setmodel (chunk, "models/metlchk3.mdl");
else if (final < 0.875)
setmodel (chunk, "models/splnter4.mdl");
else
setmodel (chunk, "models/metlchk4.mdl");
}
else if (self.thingtype==THINGTYPE_WOOD_STONE)
{
if (final < 0.125)
setmodel (chunk, "models/splnter1.mdl");
else if (final < 0.25)
setmodel (chunk, "models/schunk1.mdl");
else if (final < 0.375)
setmodel (chunk, "models/splnter2.mdl");
else if (final < 0.50)
setmodel (chunk, "models/schunk2.mdl");
else if (final < 0.625)
setmodel (chunk, "models/splnter3.mdl");
else if (final < 0.75)
setmodel (chunk, "models/schunk3.mdl");
else if (final < 0.875)
setmodel (chunk, "models/splnter4.mdl");
else
setmodel (chunk, "models/schunk4.mdl");
}
else if (self.thingtype==THINGTYPE_METAL_STONE)
{
if (final < 0.125)
setmodel (chunk, "models/metlchk1.mdl");
else if (final < 0.25)
setmodel (chunk, "models/schunk1.mdl");
else if (final < 0.375)
setmodel (chunk, "models/metlchk2.mdl");
else if (final < 0.50)
setmodel (chunk, "models/schunk2.mdl");
else if (final < 0.625)
setmodel (chunk, "models/metlchk3.mdl");
else if (final < 0.75)
setmodel (chunk, "models/schunk3.mdl");
else if (final < 0.875)
setmodel (chunk, "models/metlchk4.mdl");
else
setmodel (chunk, "models/schunk4.mdl");
}
else if (self.thingtype==THINGTYPE_METAL_CLOTH)
{
if (final < 0.14)
setmodel (chunk, "models/metlchk1.mdl");
else if (final < 0.28)
setmodel (chunk, "models/clthchk1.mdl");
else if (final < 0.42)
setmodel (chunk, "models/metlchk2.mdl");
else if (final < 0.56)
setmodel (chunk, "models/clthchk2.mdl");
else if (final < 0.70)
setmodel (chunk, "models/metlchk3.mdl");
else if (final < 0.84)
setmodel (chunk, "models/clthchk3.mdl");
else
setmodel (chunk, "models/metlchk4.mdl");
}
else if (self.thingtype==THINGTYPE_ICE)
{
setmodel(chunk,"models/shard.mdl");
chunk.skin=0;
chunk.frame=random(2);
chunk.drawflags(+)DRF_TRANSLUCENT|MLS_ABSLIGHT;
chunk.abslight=0.5;
}
else// if (self.thingtype==THINGTYPE_GREYSTONE)
{
if (final < 0.25)
setmodel (chunk, "models/schunk1.mdl");
else if (final < 0.50)
setmodel (chunk, "models/schunk2.mdl");
else if (final < 0.75)
setmodel (chunk, "models/schunk3.mdl");
else
setmodel (chunk, "models/schunk4.mdl");
chunk.skin = 0;
}
setsize (chunk, '0 0 0', '0 0 0');
chunk.movetype = MOVETYPE_BOUNCE;
chunk.solid = SOLID_NOT;
chunk.velocity = ChunkVelocity();
chunk.think = ChunkRemove;
chunk.avelocity_x = random(1200);
chunk.avelocity_y = random(1200);
chunk.avelocity_z = random(1200);
if(self.classname=="monster_eidolon")
chunk.scale=random(2.1,2.5);
else
chunk.scale = random(scalemod,scalemod + .1);
chunk.ltime = time;
thinktime chunk : random(2);
}
void DropBackpack(void); // in items.hc
// Put a little splat down if it will fit
void TinySplat (vector location)
{
vector holdplane;
entity splat;
traceline (location + v_up*8 + v_right * 8 + v_forward * 8,location - v_up*32 + v_right * 8 + v_forward * 8, TRUE, self);
holdplane = trace_plane_normal;
if(trace_fraction==1) // Nothing below victim
return;
traceline (location + v_up*8 - v_right * 8 + v_forward * 8,location - v_up*32 - v_right * 8 + v_forward * 8, TRUE, self);
if ((holdplane != trace_plane_normal) || (trace_fraction==1))
return;
traceline (location + v_up*8 + v_right * 8 - v_forward * 8,location - v_up*32 + v_right * 8 - v_forward * 8, TRUE, self);
if ((holdplane != trace_plane_normal) || (trace_fraction==1))
return;
traceline (location + v_up*8 - v_right * 8 - v_forward * 8,location - v_up*32 - v_right * 8 - v_forward * 8, TRUE, self);
if ((holdplane != trace_plane_normal) || (trace_fraction==1))
return;
traceline (location + v_up*8 ,location - v_up*32 , TRUE, self);
splat=spawn();
splat.owner=self;
splat.classname="bloodsplat";
splat.movetype=MOVETYPE_NONE;
splat.solid=SOLID_NOT;
// Flat to the surface
trace_plane_normal_x = trace_plane_normal_x * -1;
trace_plane_normal_y = trace_plane_normal_y * -1;
splat.angles = vectoangles(trace_plane_normal);
setmodel(splat,"models/bldspot4.spr"); // 8 x 8 sprite
setsize(splat,'0 0 0','0 0 0');
setorigin(splat,trace_endpos + '0 0 2');
}
void BloodSplat(void)
{
entity splat;
vector holdangles;
if (random() < .5)
{
holdangles_x = random(-30,-20);
holdangles_y = random(30,20);
}
else
{
holdangles_x = random(30,20);
holdangles_y = random(-30,-20);
}
holdangles_z = 16;
TinySplat (self.origin + holdangles);
if (random() < .5)
{
holdangles_x = random(-30,-10);
holdangles_y = random(30,10);
}
else
{
holdangles_x = random(30,10);
holdangles_y = random(-30,-10);
}
holdangles_z = 16;
TinySplat (self.origin + holdangles);
makevectors (self.angles);
traceline (self.origin + v_up*8,self.origin - v_up*32, TRUE, self);
if(trace_fraction==1) // Nothing below victim
{
dprint("\n no floor ");
return;
}
splat=spawn();
splat.owner=self;
splat.classname="bloodsplat";
splat.movetype=MOVETYPE_NONE;
splat.solid=SOLID_NOT;
// Flat to the surface
trace_plane_normal_x = trace_plane_normal_x * -1;
trace_plane_normal_y = trace_plane_normal_y * -1;
splat.angles = vectoangles(trace_plane_normal);
// setmodel(splat,"models/bldspot1.spr"); // 30 x 30 sprite size
setmodel(splat,"models/bldspot2.spr"); // 20 x 20 sprite size
// setmodel(splat,"models/bldspot3.spr"); // 18 x 18 sprite size
// setmodel(splat,"models/bldspot4.spr"); // 8 x 8 sprite size
setsize(splat,'0 0 0','0 0 0');
setorigin(splat,trace_endpos + '0 0 2');
}
void chunk_reset ()
{
chunk_cnt=FALSE;
remove(self);
}
void make_chunk_reset ()
{
newmis=spawn();
newmis.think=chunk_reset;
thinktime newmis : 1.5;
}
void chunk_death (void)
{
vector space;
float spacecube,model_cnt; //,scalemod;
string deathsound;
DropBackpack();
// BloodSplat();
space = self.absmax - self.absmin;
spacecube = space_x * space_y * space_z;
model_cnt = spacecube / 8192; // (16 * 16 * 16)
if ((self.thingtype==THINGTYPE_GLASS) || (self.thingtype==THINGTYPE_CLEARGLASS) || (self.thingtype==THINGTYPE_REDGLASS))
deathsound="fx/glassbrk.wav";
else if ((self.thingtype==THINGTYPE_WOOD) || (self.thingtype==THINGTYPE_WOOD_METAL))
if(self.classname=="bolt")
deathsound="assassin/arrowbrk.wav";
else
deathsound="fx/woodbrk.wav";
else if ((self.thingtype==THINGTYPE_GREYSTONE) || (self.thingtype==THINGTYPE_BROWNSTONE) ||
(self.thingtype==THINGTYPE_WOOD_STONE) || (self.thingtype==THINGTYPE_METAL_STONE)||self.thingtype==THINGTYPE_DIRT)
deathsound="fx/wallbrk.wav";
else if ((self.thingtype==THINGTYPE_METAL) || (self.thingtype==THINGTYPE_METAL_CLOTH))
deathsound="fx/metalbrk.wav";
else if ((self.thingtype==THINGTYPE_CLOTH) || (self.thingtype==THINGTYPE_REDGLASS))
deathsound="fx/clothbrk.wav";
else if (self.thingtype==THINGTYPE_FLESH)
{
//Made temporary changes to make weapons look and sound
//better, more blood and gory sounds.
if(self.health<-80)
deathsound="player/megagib.wav";
else
deathsound="player/gib1.wav";
sound(self,CHAN_AUTO,deathsound,1,ATTN_NORM);
self.level=-666;
}
else if (self.thingtype==THINGTYPE_CLAY)
deathsound="fx/claybrk.wav";
else if ((self.thingtype==THINGTYPE_LEAVES) || (self.thingtype==THINGTYPE_WOOD_LEAF))
deathsound="fx/leafbrk.wav";
else if (self.thingtype==THINGTYPE_ICE)
deathsound="misc/icestatx.wav";
else
deathsound="fx/wallbrk.wav";
if(self.level!=-666)
sound (self, CHAN_VOICE, deathsound, 1, ATTN_NORM);
// Scale 0 - 50,000 small
// 50,000 - 500,000 medium
// 500,000 large
// 1,000,000 + huge
/* if (spacecube < 5000)
{
scalemod = .20;
model_cnt = model_cnt * 3; // Because so few pieces come out of a small object
}
else if (spacecube < 50000)
{
scalemod = .45;
model_cnt = model_cnt * 3; // Because so few pieces come out of a small object
}
else if (spacecube < 500000)
{
scalemod = .50;
}
else if (spacecube < 1000000)
{
scalemod = .75;
}
else
{
scalemod = 1;
}
if(model_cnt>CHUNK_MAX)
model_cnt=CHUNK_MAX;
while (model_cnt>0)
{
if (chunk_cnt < CHUNK_MAX*2)
{
CreateModelChunks(space,scalemod);
chunk_cnt+=1;
}
model_cnt-=1;
}
*/
make_chunk_reset();
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_CHUNK2);
WriteCoord(MSG_MULTICAST, self.absmin_x);
WriteCoord(MSG_MULTICAST, self.absmin_y);
WriteCoord(MSG_MULTICAST, self.absmin_z);
WriteCoord(MSG_MULTICAST, space_x);
WriteCoord(MSG_MULTICAST, space_y);
WriteCoord(MSG_MULTICAST, space_z);
WriteByte(MSG_MULTICAST, self.thingtype);
multicast(self.absmin+0.5*space,MULTICAST_PHS_R);
if(self.classname=="monster_eidolon")
return;
SUB_UseTargets();
// if(self.classname=="door"||self.classname=="door_rotating")
if(self.ondeath_target!="")
{
string otarg;
otarg = self.target;
self.target=self.ondeath_target;
SUB_UseTargets();
self.target=otarg;
dprint("Door using it's ondeath target\n");
}
if(self.trigger_field)
remove(self.trigger_field);
if(self.headmodel!=""&&self.classname!="head")
ThrowSolidHead (50);
else
remove(self);
}

3511
client.hc Normal file

File diff suppressed because it is too large Load Diff

161
combat.hc Normal file
View File

@ -0,0 +1,161 @@
/*
* $Header: /HexenWorld/Siege/COMBAT.hc 16 5/25/98 10:56p Mgummelt $
*/
void(vector org, vector vel, float damage, entity victim) SpawnPuff;
float MetalHitSound (float targettype)
{
//entity found;
if(targettype==THINGTYPE_FLESH)
{
sound (self, CHAN_WEAPON, "weapons/met2flsh.wav", 1, ATTN_NORM);
return TRUE;
}
else
{
// found=find(world,classname,"misc_ripples");
// if(found)
// starteffect(CE_RIPPLE, found.origin,'0 0 0',HX_FRAME_TIME);
if(targettype==THINGTYPE_WOOD||targettype==THINGTYPE_DIRT)
{
sound (self, CHAN_WEAPON, "weapons/met2wd.wav", 1, ATTN_NORM);
return TRUE;
}
else if(targettype==THINGTYPE_METAL)
{
sound (self, CHAN_WEAPON, "weapons/met2met.wav", 1, ATTN_NORM);
return TRUE;
}
else if(targettype==THINGTYPE_BROWNSTONE||targettype==THINGTYPE_GREYSTONE)
{
sound (self, CHAN_WEAPON, "weapons/met2stn.wav", 1, ATTN_NORM);
return TRUE;
}
return FALSE;
}
}
/*
================
FireMelee
================
*/
void FireMelee (float damage_base,float damage_mod,float attack_radius)
{
vector source;
vector org;
float damg;//, backstab;
float chance,point_chance;
makevectors (self.v_angle);
source = self.origin+self.proj_ofs;
traceline (source, source + v_forward*64, FALSE, self);
if (trace_fraction == 1.0)
{
traceline (source, source + v_forward*64 - (v_up * 30), FALSE, self); // 30 down
if (trace_fraction == 1.0)
{
traceline (source, source + v_forward*64 + v_up * 30, FALSE, self); // 30 up
if (trace_fraction == 1.0)
return;
}
}
org = trace_endpos + (v_forward * 4);
if (trace_ent.takedamage)
{
//FIXME:Add multiplier for level and strength
if(self.playerclass==CLASS_PALADIN&&self.weapon==IT_WEAPON2&&!trace_ent.flags2&FL_ALIVE)
damage_base*=1.3;
if(self.playerclass==CLASS_DWARF)
if(self.weapon==IT_WEAPON2&&!trace_ent.flags2&FL_ALIVE)
{
if(flammable(trace_ent))
damage_base*=2.2;
else if(trace_ent.thingtype==THINGTYPE_DIRT)
damage_base*=1.5;
else
damage_base*=1.2;
}
else
damage_base*=1.2;
/* if(trace_ent.flags2&FL_ALIVE&&self.playerclass==CLASS_ASSASSIN)//!fov(self,trace_ent,90)
{
vector t_vf,m_vf;
makevectors(trace_ent.angles);
t_vf = v_forward;
makevectors(self.angles);
m_vf = v_forward;
makevectors(self.v_angle);
if(t_vf*m_vf>0.5)//facing generally the same direction
{
CreateRedFlash(trace_endpos);
damage_base=trace_ent.health*random(0.75,1.2);
if(damage_base>100)
damage_base = 100;
backstab=TRUE;
}
}*/
damg = random(damage_mod+damage_base,damage_base);
SpawnPuff (org, '0 0 0', damg,trace_ent);
T_Damage (trace_ent, self, self, damg);
/* if(backstab)
{
if(!trace_ent.flags2&FL_ALIVE)
centerprint(self,"Critical Hit Backstab!\n");
else
centerprint(self,"Backstab!\n");
}*/
if(trace_ent.thingtype==THINGTYPE_FLESH)
sound (self, CHAN_WEAPON, "weapons/slash.wav", 1, ATTN_NORM);
else if(!MetalHitSound(trace_ent.thingtype))
sound (self, CHAN_WEAPON, "weapons/hitwall.wav", 1, ATTN_NORM);
// Necromancer stands a chance of vampirically stealing health points
if (self.playerclass == CLASS_NECROMANCER)
{
if ((trace_ent.flags & FL_MONSTER) || (trace_ent.flags & FL_CLIENT))
{
chance = self.level * .05;
if (chance > random())
{
point_chance = self.level;
point_chance *= random();
if (point_chance < 1)
point_chance = 1;
sound (self, CHAN_BODY, "weapons/drain.wav", 1, ATTN_NORM);
self.health += point_chance;
if (self.health>self.max_health)
self.health = self.max_health;
}
}
}
}
else
{ // hit wall
if(!MetalHitSound(trace_ent.thingtype))
sound (self, CHAN_WEAPON, "weapons/hitwall.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_GUNSHOT);
WriteByte (MSG_BROADCAST, 1);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
}
}

805
constant.hc Normal file
View File

@ -0,0 +1,805 @@
/*
* $Header: /HexenWorld/Siege/constant.hc 74 6/01/98 2:49a Mgummelt $
*/
//
// constants
//
float FALSE = 0;
float TRUE = 1;
float HX_FRAME_TIME = 0.05;
float HX_FPS = 20;
// edict.flags
float FL_FLY = 1;
float FL_SWIM = 2;
float FL_PUSH = 4; // Object is pushable
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
float FL_FLASHLIGHT = 8192; // quake 2 thingy
float FL_ARTIFACTUSED = 16384; // an artifact was just used
float FL_MOVECHAIN_ANGLE = 32768; // when in a move chain, will update the angle
float FL_FIRERESIST = 65536; // resistant to fire and heat and lava
float FL_FIREHEAL = 131072; // healed by fire, heat, and lava
float FL_COLDHEAL = 524288; // healed by freezing
float FL_ARCHIVE_OVERRIDE = 1048576; // quake 2 thingy
float FL_CLASS_DEPENDENT = 2097152; // model will appear different to each player
float FL_SPECIAL_ABILITY1 = 4194304; // has 1st special ability
float FL_SPECIAL_ABILITY2 = 8388608; // has 2nd special ability
//edict.flags2
//FIXME: Shielded and small may be able to be determined by
//other means...
float FL2_ADJUST_MON_DAM = 1; //Do more damage to monsters
float FL_NODAMAGE = 2; //Special flag put on a missle to make it not do damage- used only by mezzoman
float FL_SMALL = 4; //Small enough to be crsuhed underfoot
float FL_ALIVE = 8; //Dead or alive.
float FL_FAKE_WATER = 16; //Fake water
float FL_SUMMONED = 32; //Summoned monster, stops it from precaching
float FL_LEDGEHOLD = 64; //Can realistically pull yourself up over ledges, etc.
float FL2_FADE_UP = 128; //Succ.
float FL2_HARDFALL = 256; //Hit hard- Siege
float FL_TORNATO_SAFE = 512;
float FL2_DEADMEAT = 1024; //Tagged for death
float FL_CHAINED = 2048; //Held by chains
float FL2_CROUCHED = 4096;
float FL2_CROUCH_TOGGLE = 8192;
float FL2_FIRERESIST = 16384; // resistant to fire and heat and lava
float FL2_WALLCLIMB = 32768; // can climb walls
float FL2_EXCALIBUR = 65536; // Using excalibur
float FL2_REPLACEMENT = 131072; // replacement throne rrom key
float FL2_POISONED = 262144; // healed by freezing
float FL2_HASKEY = 524288;
float FL2_PARRIED = 1048576;
float FL2_ONFIRE = 4194304; // on fire
// edict.drawflags
float MLS_MASKIN = 7; // MLS: Model Light Style
float MLS_MASKOUT = 248;
float MLS_NONE = 0;
float MLS_FULLBRIGHT = 1;
float MLS_POWERMODE = 2;
float MLS_TORCH = 3;
float MLS_FIREFLICKER = 4;
float MLS_INVIS = 5;
//float MLS_INVIS = 6;
float MLS_ABSLIGHT = 7;
float SCALE_TYPE_MASKIN = 24;
float SCALE_TYPE_MASKOUT = 231;
float SCALE_TYPE_UNIFORM = 0; // Scale X, Y, and Z
float SCALE_TYPE_XYONLY = 8; // Scale X and Y
float SCALE_TYPE_ZONLY = 16; // Scale Z
float SCALE_ORIGIN_MASKIN = 96;
float SCALE_ORIGIN_MASKOUT = 159;
float SCALE_ORIGIN_CENTER = 0; // Scaling origin at object center
float SCALE_ORIGIN_BOTTOM = 32; // Scaling origin at object bottom
float SCALE_ORIGIN_TOP = 64; // Scaling origin at object top
float DRF_TRANSLUCENT = 128;
// Artifact Flags
float AFL_CUBE_RIGHT = 1;
float AFL_CUBE_LEFT = 2;
float AFL_TORCH = 4;
float AFL_SUPERHEALTH = 8;
// 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 and no gravity
float MOVETYPE_PUSHPULL = 13; // pushable/pullable object
float MOVETYPE_SWIM = 14; // object won't move out of water
// particle types
float PARTICLETYPE_STATIC = 0;
float PARTICLETYPE_GRAV = 1;
float PARTICLETYPE_FASTGRAV = 2;
float PARTICLETYPE_SLOWGRAV = 3;
float PARTICLETYPE_FIRE = 4;
float PARTICLETYPE_EXPLODE = 5;
float PARTICLETYPE_EXPLODE2 = 6;
float PARTICLETYPE_BLOB = 7;
float PARTICLETYPE_BLOB2 = 8;
float PARTICLETYPE_RAIN = 9;
float PARTICLETYPE_C_EXPLODE = 10;
float PARTICLETYPE_C_EXPLODE2 = 11;
float PARTICLETYPE_SPIT = 12;
float PARTICLETYPE_FIREBALL = 13;
float PARTICLETYPE_ICE = 14;
float PARTICLETYPE_SPELL = 15;
//MISSION PACK
float PARTICLETYPE_DARKEN = 24; //Particle will darken to darkest color of that shade, valid only for colors <= 232
float PARTICLETYPE_REDFIRE = 26; //Particle will darken to darkest color of that shade, valid only for colors <= 232
float PARTICLETYPE_ACIDBALL = 27; //Built-in model trail
float PARTICLETYPE_BLUESTEP = 28; //Built-in model trail
// Hexen hull constants
float HULL_IMPLICIT = 0; //Choose the hull based on bounding box- like in Quake
float HULL_POINT = 1; //0 0 0, 0 0 0
float HULL_PLAYER = 2; //'-16 -16 0', '16 16 56'
float HULL_SCORPION = 3; //'-24 -24 -20', '24 24 20'
float HULL_CROUCH = 4; //'-16 -16 0', '16 16 28'
//Next 2 clip though world?
float HULL_HYDRA = 5; //'-28 -28 -24', '28 28 24'
float HULL_GOLEM = 6; //???,???
// Keep around old constants until all references are removed
float HULL_OLD = 0;
float HULL_SMALL = 1;
float HULL_NORMAL = 2;
float HULL_BIG = 3;
// 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
float SOLID_PHASE = 5; // will interact with all objects except entities with FL_MONSTER & FL_CLIENT - those it will pass through
// 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; // Entity cannot be hurt
float DAMAGE_YES = 1; // Can be hurt
float DAMAGE_NO_GRENADE = 2; // Will not trigger a grenade to explode
// use inventory flags to show which item is the current item
float INV_NONE = 0;
float INV_TORCH = 1;
float INV_HP_BOOST = 2;
float INV_SUPER_HP_BOOST = 3;
float INV_MANA_BOOST = 4;
float INV_TELEPORT = 5;
float INV_TOME = 6;
float INV_SUMMON = 7;
float INV_INVISIBILITY = 8;
float INV_GLYPH = 9;
float INV_HASTE = 10;
float INV_BLAST = 11;
float INV_POLYMORPH = 12;
float INV_FLIGHT = 13;
float INV_CUBEOFFORCE = 14;
float INV_INVINCIBILITY = 15;
float ARTIFACT_TORCH = 1;
float ARTIFACT_HP_BOOST = 2;
float ARTIFACT_SUPER_HP_BOOST = 3;
float ARTIFACT_MANA_BOOST = 4;
float ARTIFACT_TELEPORT = 5;
float ARTIFACT_TOME = 6;
float ARTIFACT_SUMMON = 7;
float ARTIFACT_INVISIBILITY = 8;
float ARTIFACT_GLYPH = 9;
float ARTIFACT_HASTE = 10;
float ARTIFACT_BLAST = 11;
float ARTIFACT_POLYMORPH = 12;
float ARTIFACT_FLIGHT = 13;
float ARTIFACT_CUBEOFFORCE = 14;
float ARTIFACT_INVINCIBILITY = 15;
float ARTIFACT_ARROWS = 16;
float ARTIFACT_GRENADES = 17;
float ARTIFACT_CLIMB = 18;
// Use ring flags to show which rings hero carries
float RING_NONE = 0;
float RING_FLIGHT = 1;
float RING_WATER = 2;
float RING_REGENERATION = 4;
float RING_TURNING = 8;
// Use artifact flags to show which artifacts are in use
float ART_NONE = 0;
float ART_HASTE = 1;
float ART_INVINCIBILITY = 2;
float ART_TOMEOFPOWER = 4;
float ART_INVISIBILITY = 8;
float ARTFLAG_FROZEN = 16; // 32
float ARTFLAG_STONED = 32; // 64
float ARTFLAG_DIVINE_INTERVENTION = 64; // 128
float ART_CLIMB = 128; // 256
// Gobal skin textures
float GLOBAL_SKIN_STONE = 100;
float GLOBAL_SKIN_ICE = 101;
float GLOBAL_SKIN_NOTEAM = 102;//just black
// Player Classes
float CLASS_NONE = 0;
float CLASS_PALADIN = 1;
float CLASS_CRUSADER = 2;
float CLASS_NECROMANCER = 3;
float CLASS_ASSASSIN = 4;
//MP
float CLASS_SUCCUBUS = 5;
//Siege
float CLASS_DWARF = 6;
// Monster Classes
float CLASS_GRUNT = 1;
float CLASS_HENCHMAN = 2;
float CLASS_LEADER = 3;
float CLASS_BOSS = 4;
float CLASS_FINAL_BOSS = 5;
float MAX_HEALTH = 200;
// Player Mode
float MODE_NORMAL = 0; // normal play mode
float MODE_CAMERA = 1; // player is a camera right now
float AS_STRAIGHT = 1;
float AS_SLIDING = 2;
float AS_MELEE = 3;
float AS_MISSILE = 4;
float AS_WAIT = 5;
float AS_FERRY = 6;
// Generic Weapon Names
float IT_WEAPON1 = 4096;
float IT_WEAPON2 = 1;
float IT_WEAPON3 = 2;
float IT_WEAPON4 = 4;
float IT_TESTWEAP = 8;
float IT_WEAPON4_1 = 16; // First half of weapon
float IT_WEAPON4_2 = 32; // Second half of weapon
// paladin weapons
float IT_GAUNTLETS = 4096;
float IT_ARMOR1 = 8192;
float IT_ARMOR2 = 16384;
float IT_ARMOR3 = 32768;
float IT_SUPERHEALTH = 65536;
float IT_INVISIBILITY = 524288;
float IT_INVULNERABILITY = 1048576;
float IT_SUIT = 2097152;
float IT_QUAD = 4194304;
// rings - amount of time they work
float FLIGHT_TIME = 30;
float WATER_TIME = 30;
float ABSORPTION_TIME = 30;
float REGEN_TIME = 30;
float TURNING_TIME = 30;
// artifacts - amount of time they work
float HASTE_TIME = 15;
float TOME_TIME = 30;
float RESPAWN_TIME = 30;
// weapon damage values
float WEAPON1_BASE_DAMAGE = 12;
float WEAPON1_ADD_DAMAGE = 12;
float WEAPON1_PWR_BASE_DAMAGE = 30;
float WEAPON1_PWR_ADD_DAMAGE = 20;
float WEAPON1_PUSH = 5;
// glyph of the ancients
float GLYPH_BASE_DAMAGE = 100;
float GLYPH_ADD_DAMAGE = 20;
// Modifier for HASTE
//float HASTE_MOD = 2;
float BLAST_RADIUS = 200;
float BLASTDAMAGE = 2;
// Damage values for attacks from monsters
float DMG_ARCHER_PUNCH = 4;
float DMG_MUMMY_PUNCH = 8;
float DMG_MUMMY_BITE = 2;
//Thing Types
float THINGTYPE_GREYSTONE = 1;
float THINGTYPE_WOOD = 2;
float THINGTYPE_METAL = 3;
float THINGTYPE_FLESH = 4;
float THINGTYPE_FIRE = 5;
float THINGTYPE_CLAY = 6;
float THINGTYPE_LEAVES = 7;
float THINGTYPE_HAY = 8;
float THINGTYPE_BROWNSTONE = 9;
float THINGTYPE_CLOTH = 10;
float THINGTYPE_WOOD_LEAF = 11;
float THINGTYPE_WOOD_METAL = 12;
float THINGTYPE_WOOD_STONE = 13;
float THINGTYPE_METAL_STONE = 14;
float THINGTYPE_METAL_CLOTH = 15;
float THINGTYPE_WEBS = 16;
float THINGTYPE_GLASS = 17;
float THINGTYPE_ICE = 18;
float THINGTYPE_CLEARGLASS = 19;
float THINGTYPE_REDGLASS = 20;
float THINGTYPE_ACID = 21;
float THINGTYPE_METEOR = 22;
float THINGTYPE_GREENFLESH = 23;
float THINGTYPE_BONE = 24;
float THINGTYPE_DIRT = 25;
// 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;
float STATE_MOVING = 4;
vector VEC_ORIGIN = '0 0 0';
vector VEC_HULL_MIN = '-16 -16 -24';
vector VEC_HULL_MAX = '16 16 32';
//Temp- because player models origins are at feet,
//Above values raise them 12 above the floor!
//But what about monsters using this Hull size??
//vector VEC_HULL_MIN = '-16 -16 0';
//vector VEC_HULL_MAX = '16 16 56';
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_UPDATE_KINGOFHILL = 51;//MP
float SVC_SET_VIEW_TINT = 53;
float SVC_SET_VIEW_FLAGS = 56;
float SVC_CLEAR_VIEW_FLAGS = 57;
float SVC_MIDI_NAME = 65;
// Client Effects
float CE_RAIN = 1;
float CE_FOUNTAIN = 2;
float CE_QUAKE = 3;
float CE_WHITE_SMOKE = 4;
float CE_BLUESPARK = 5;
float CE_YELLOWSPARK = 6;
float CE_SM_CIRCLE_EXP = 7;
float CE_BG_CIRCLE_EXP = 8;
float CE_SM_WHITE_FLASH = 9;
float CE_WHITE_FLASH = 10;
float CE_YELLOWRED_FLASH = 11;
float CE_BLUE_FLASH = 12;
float CE_SM_BLUE_FLASH = 13;
float CE_RED_FLASH = 14;
float CE_SM_EXPLOSION = 15;
float CE_LG_EXPLOSION = 16;
float CE_FLOOR_EXPLOSION = 17;
float CE_RIDER_DEATH = 18;
float CE_BLUE_EXPLOSION = 19;
float CE_GREEN_SMOKE = 20;
float CE_GREY_SMOKE = 21;
float CE_RED_SMOKE = 22;
float CE_SLOW_WHITE_SMOKE = 23;
float CE_REDSPARK = 24;
float CE_GREENSPARK = 25;
float CE_TELESMK1 = 26;
float CE_TELESMK2 = 27;
float CE_ICE_HIT = 28;// icehit.spr 0-5
float CE_MEDUSA_HIT = 29;// medhit.spr 0-6
float CE_MEZZO_REFLECT = 30;// mezzoref.spr 0-5
float CE_FLOOR_EXPLOSION2 = 31;// flrexpl2.spr 0-19
float CE_XBOW_EXPLOSION = 32;// xbowexpl.spr 0-16
float CE_NEW_EXPLOSION = 33;// gen_expl.spr 0-13
float CE_MAGIC_MISSILE_EXPLOSION = 34;// mm_expld.spr
float CE_GHOST = 35;// ghost.spr- translucent
float CE_BONE_EXPLOSION = 36;// bonexpld.spr
float CE_REDCLOUD = 37;// rcloud.spr
float CE_TELEPORTERPUFFS = 38;
float CE_TELEPORTERBODY = 39;
float CE_BONESHARD = 40;
float CE_BONESHRAPNEL = 41;
float CE_HWMISSILESTAR = 42;
float CE_HWEIDOLONSTAR = 43;
float CE_HWSHEEPINATOR = 44;
float CE_TRIPMINE = 45;
float CE_HWBONEBALL = 46;
float CE_HWRAVENSTAFF = 47;
float CE_TRIPMINESTILL = 48;
float CE_SCARABCHAIN = 49;
float CE_SM_EXPLOSION2 = 50;
float CE_HWSPLITFLASH = 51;
float CE_HWXBOWSHOOT = 52;
float CE_HWRAVENPOWER = 53;
float CE_HWDRILLA = 54;
float CE_DEATHBUBBLES = 55;
//MISSION PACK
float CE_RIPPLE = 56;
float CE_BLDRN_EXPL = 57;
float CE_ACID_MUZZFL = 58;
float CE_ACID_HIT = 59;
float CE_FIREWALL_SMALL = 60;
float CE_FIREWALL_MEDIUM = 61;
float CE_FIREWALL_LARGE = 62;
float CE_LBALL_EXPL = 63;
float CE_ACID_SPLAT = 64;
float CE_ACID_EXPL = 65;
float CE_FBOOM = 66;
float CE_BOMB = 67;
float CE_BRN_BOUNCE = 68;
float CE_LSHOCK = 69;
float CE_FLAMEWALL = 70;
float CE_FLAMEWALL2 = 71;
float CE_FLOOR_EXPLOSION3 = 72;
float CE_ONFIRE = 73;
float CE_FLAMESTREAM = 74;
// Temporary entities
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_STREAM_CHAIN = 25;
float TE_STREAM_SUNSTAFF1 = 26;
float TE_STREAM_SUNSTAFF2 = 27;
float TE_STREAM_LIGHTNING = 28;
float TE_STREAM_COLORBEAM = 29;
float TE_STREAM_ICECHUNKS = 30;
float TE_STREAM_GAZE = 31;
float TE_STREAM_FAMINE = 32;
float TE_BIGGRENADE = 33;
float TE_CHUNK = 34;
float TE_HWBONEPOWER = 35;
float TE_HWBONEPOWER2 = 36;
float TE_METEORHIT = 37;
float TE_HWRAVENDIE = 38;
float TE_HWRAVENEXPLODE = 39;
float TE_XBOWHIT = 40;
float TE_CHUNK2 = 41;
float TE_ICEHIT = 42;
float TE_ICESTORM = 43;
float TE_HWMISSILEFLASH = 44;
float TE_SUNSTAFF_CHEAP = 45;
float TE_LIGHTNING_HAMMER = 46;
float TE_DRILLA_EXPLODE = 47;
float TE_DRILLA_DRILL = 48;
float TE_HWTELEPORT = 49;
float TE_SWORD_EXPLOSION = 50;
float TE_AXE_BOUNCE = 51;
float TE_AXE_EXPLODE = 52;
float TE_TIME_BOMB = 53;
float TE_FIREBALL = 54;
float TE_SUNSTAFF_POWER = 55;
float TE_PURIFY2_EXPLODE = 56;
float TE_PLAYER_DEATH = 57;
float TE_PURIFY1_EFFECT = 58;
float TE_TELEPORT_LINGER = 59;
float TE_LINE_EXPLOSION = 60;
float TE_METEOR_CRUSH = 61;
//MP
float TE_STREAM_LIGHTNING_SMALL = 62;
float TE_ACIDBALL = 63;
float TE_ACIDBLOB = 64;
float TE_FIREWALL = 65;
float TE_FIREWALL_IMPACT = 66;
float TE_HWBONERIC = 67;
float TE_POWERFLAME = 68;
float TE_BLOODRAIN = 69;
float TE_AXE = 70;
float TE_PURIFY2_MISSILE = 71;
float TE_SWORD_SHOT = 72;
float TE_ICESHOT = 73;
float TE_METEOR = 74;
float TE_LIGHTNINGBALL = 75;
float TE_MEGAMETEOR = 76;
float TE_CUBEBEAM = 77;
float TE_LIGHTNINGEXPLODE = 78;
float TE_ACID_BALL_FLY = 79;
float TE_ACID_BLOB_FLY = 80;
float TE_CHAINLIGHTNING = 81;
// Stream flags
float STREAM_ATTACHED = 16;
float STREAM_TRANSLUCENT = 32;
// 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 CHAN_UPDATE = 7;// All sounds on this channel are updated by the EF_UPDATESOUND flag
//MP
float PHS_OVERRIDE_R = 8;//CHAN_????+PHS_OVERRIDE_R Forces the sound channel to be reliable and not use the PHS
float SOUND_STARTED = 7777777;//Just used to keep track of whether I played a certain sound or not- 7777777 because t_dith is used as time+X elsewhere in code
float SOUND_STOPPED = 0;//clears out t_width fpr next playsound check
float ATTN_NONE = 0;
float ATTN_NORM = 1;
float ATTN_IDLE = 2;
float ATTN_STATIC = 3;
//MP
float ATTN_LOOP = 4;//Sound will start on client even if volume is 0- so if player comes into range, it will be playing- attenuates like ATTN_NORM
// 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;//used for sword impacts and firing
float EF_BRIGHTLIGHT = 4;//used a lot
float EF_TORCHLIGHT = 6;//4 and 2?
float EF_DIMLIGHT = 8;//torch
float EF_DARKLIGHT = 16;
float EF_DARKFIELD = 32;//haste
float EF_LIGHT = 64;//small light field
float EF_NODRAW = 128;//invis
//end of first byte sent to clients
//where is 256 and 512?
float EF_ONFIRE = 1024;//on fire
float EF_INVINC_CIRC = 16;//Succubus' invincibility effect
float EF_POWERFLAMEBURN = 2048;
float EF_POWERFLAME = 4096;
float EF_UPDATESOUND = 8192;
float EF_POISON_GAS = 2097152;//MP
float EF_ACIDBLOB = 4194304;//MP
//float EF_PURIFY2_EFFECT = 2097152;
//float EF_AXE_EFFECT = 4194304;
//float EF_SWORD_EFFECT = 8388608;
float EF_TORNADO_EFFECT = 16777216;
float EF_ICESTORM_EFFECT = 33554432;
//float EF_ICEBALL_EFFECT = 67108864;
//float EF_METEOR_EFFECT = 134217728;
float EF_HAMMER_EFFECTS = 268435456;
float EF_BEETLE_EFFECTS = 536870912;
// 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
float MSG_MULTICAST = 4; // for multicast() call
// message levels
float PRINT_LOW = 0; // pickup messages
float PRINT_MEDIUM = 1; // death messages
float PRINT_HIGH = 2; // critical messages
float PRINT_CHAT = 3; // also goes to chat console
// multicast sets
float MULTICAST_ALL = 0; // every client
float MULTICAST_PHS = 1; // within hearing
float MULTICAST_PVS = 2; // within sight
float MULTICAST_ALL_R = 3; // every client, reliable
float MULTICAST_PHS_R = 4; // within hearing, reliable
float MULTICAST_PVS_R = 5; // within sight, reliable
float STEP_HEIGHT = 18; // Max step height
// monster AI states
float AI_DECIDE = 0; // An action was just finished - time to decide what to do
float AI_STAND = 1; // Standing guard
float AI_WALK = 2; // Walking
float AI_CHARGE = 4; // Charging enemy
float AI_WANDER = 8; // Wandering around mindlessly
float AI_MELEE_ATTACK = 16; //
float AI_MISSILE_ATTACK = 32; //
float AI_MISSILE_REATTACK = 64; // Attacking again from attack stance (archer)
float AI_PAIN = 128; // Monster has only 1 type of pain
float AI_PAIN_CLOSE = 256; // Pain when close to enemy
float AI_PAIN_FAR = 512; // Pain when far from enemy
float AI_DEAD = 1024; //
float AI_TURNLOOK = 2048; // Turning to look for enemy
float AI_DEAD_GIB = 4096; // Can be gibbed when killed
float AI_DEAD_TWITCH = 8192; // Twitches while dead
// Return values for AdvanceFrame()
float AF_NORMAL = 0;
float AF_BEGINNING = 1;
float AF_END = 2;
float CHUNK_MAX = 30; // Max number of chunks (models) that can be alive at one time
float MAX_LEVELS = 10;
// server flags
float SFL_EPISODE_1 = 1;
float SFL_EPISODE_2 = 2;
float SFL_EPISODE_3 = 4;
float SFL_EPISODE_4 = 8;
float SFL_NEW_UNIT = 16;
float SFL_NEW_EPISODE = 32;
// = 64;
// = 128;
float SFL_CROSS_TRIGGER_1 = 256;
float SFL_CROSS_TRIGGER_2 = 512;
float SFL_CROSS_TRIGGER_3 = 1024;
float SFL_CROSS_TRIGGER_4 = 2048;
float SFL_CROSS_TRIGGER_5 = 4096;
float SFL_CROSS_TRIGGER_6 = 8192;
float SFL_CROSS_TRIGGER_7 = 16384;
float SFL_CROSS_TRIGGER_8 = 32768;
float SFL_CROSS_TRIGGERS = 65280;
float attck_cnt;
float WF_NORMAL_ADVANCE = 0; // States when using advanceweaponframe
float WF_CYCLE_STARTED = 1;
float WF_CYCLE_WRAPPED = 2;
float WF_LAST_FRAME = 3;
float WORLDTYPE_CASTLE = 0;
float WORLDTYPE_EGYPT = 1;
float WORLDTYPE_MESO = 2;
float WORLDTYPE_ROMAN = 3;
//Spawnflags for monster spawners
float IMP = 1;
float ARCHER = 2;
float WIZARD = 4;
float SCORPION = 8;
float SPIDER = 16;
float ONDEATH = 32;
float QUIET = 64;
float TRIGGERONLY = 128;
//spawnflag for all monsters
float JUMP = 4; //Gives monster the ability to jump
float PLAY_DEAD = 8; //Makes a monster play dead at start
float NO_DROP = 32; //Keeps them from dropping to the ground at spawntime
//spawnflag for items, weapons, artifacts
float FLOATING = 1; //Keeps them from dropping to the ground at spawntime
//Spawnflags for barrels
float BARREL_DOWNHILL = 1;
float BARREL_NO_DROP = 2;
float ON_SIDE = 4;
float BARREL_SINK = 8;
float DROP_USE = 16;//Barrel won't drop unless used
float BARREL_RESPAWN = 32;//Upon death, barrel will respawn at it's initial origin
//Barrel types
float BARREL_UNBREAKABLE = 16;
float BARREL_NORMAL = 32;
float BARREL_EXPLODING = 64;
float BARREL_INDESTRUCTIBLE = 128;
float BARREL_GFIRE = 256;
//For func_rotate
float GRADUAL = 32;
float TOGGLE_REVERSE = 64;
float KEEP_START = 128;
float NO_RESPAWN = 0; // For the spawning of artifacts
float RESPAWN = 1;
float RING_REGENERATION_MAX = 150; // Number of health points ring gives you back
float RING_FLIGHT_MAX = 60; // Number of seconds you can fly
float RING_WATER_MAX = 60; // Number of seconds you can stay under water
float RING_TURNING_MAX = 60; // Number of seconds you can turn missiles
float SVC_SETVIEWPORT = 5; // Net.Protocol 0x05- for camera
float SVC_SETVIEWANGLES = 10; // Net.Protocol 0x0A- for camera
//act_states - for player anim
float ACT_STAND = 0;
float ACT_RUN = 1;
float ACT_SWIM_FLY = 2;
float ACT_ATTACK = 3;
float ACT_PAIN = 4;
float ACT_JUMP = 5;
float ACT_CROUCH_STAND = 6;
float ACT_CROUCH_MOVE = 7;
float ACT_DEAD = 8;
float ACT_DECAP = 9;
float XBOW_IMPACT_DEFAULT = 0;
float XBOW_IMPACT_GREENFLESH = 2;
float XBOW_IMPACT_REDFLESH = 4;
float XBOW_IMPACT_WOOD = 6;
float XBOW_IMPACT_STONE = 8;
float XBOW_IMPACT_METAL = 10;
float XBOW_IMPACT_ICE = 12;
float XBOW_IMPACT_MUMMY = 14;
float DM_CAPTURE_THE_TOKEN = 1;
float DM_HUNTER = 2;
float DM_SIEGE = 3;
float GF_HAS_TOKEN = 1;
float GF_HAS_LEFT_HUNTER = 2;
//MISSION PACK
//for worldspawn
float MISSIONPACK = 1;//Spawnflag on world to use some mission-pack specific code for brush ents
float WSF_SIEGE = 2;//Spawnflag on world to use some mission-pack specific code for brush ents
//SIEGE
float ST_DEFENDER = 1;
float ST_ATTACKER = 2;
float ACT_YAK_HIT = 2;
float ACT_YAK_HOWL = 9;
float IT_WEAPON5 = 32;
float IT_WEAPON6 = 64;
float IT_WEAPON7 = 128;
float IT_WEAPON8 = 256;
float WP_DEFENDERS = 10;//Defenders win pic
float WP_ATTCROWN = 11;//Attackers capture crown
float WP_ATTKILL = 12;//Attackers wipe out defenders
float MAX_CLASS = 6;//Dwarf
//Siege
float SVC_HASKEY = 79; // [byte] [byte]
float SVC_NONEHASKEY = 80; // [byte] [byte]
float SVC_ISDOC = 81; // [byte] [byte]
float SVC_NODOC = 82; // [byte] [byte]

107
corpse.hc Normal file
View File

@ -0,0 +1,107 @@
/*
* $Header: /HexenWorld/Siege/Corpse.hc 5 6/01/98 2:49a Mgummelt $
*/
void corpseblink (void)
{
self.think = corpseblink;
thinktime self : 0.1;
self.scale -= 0.10;
if (self.scale < 0.10)
remove(self);
}
void init_corpseblink (void)
{
CreateYRFlash(self.origin);
self.drawflags (+) DRF_TRANSLUCENT | SCALE_TYPE_ZONLY | SCALE_ORIGIN_BOTTOM;
corpseblink();
}
void() Spurt =
{
float bloodleak;
makevectors(self.angles);
bloodleak=rint(random(3,8));
SpawnPuff (self.origin+v_forward*24+'0 0 -22', '0 0 -5'+ v_forward*random(20,40), bloodleak,self);
sound (self, CHAN_AUTO, "misc/decomp.wav", 0.3, ATTN_NORM);
if (self.lifetime < time||self.watertype==CONTENT_LAVA)
T_Damage(self,world,world,self.health);
else
{
self.think=Spurt;
thinktime self : random(0.5,6.5);
}
};
void () CorpseThink =
{
self.think = CorpseThink;
thinktime self : 3;
if (self.watertype==CONTENT_LAVA) // Corpse fell in lava
T_Damage(self,self,self,self.health);
else if (self.lifetime < time) // Time is up, begone with you
init_corpseblink();
};
/*
* This uses entity.netname to hold the head file (for CorpseDie())
* hack so that we don't have to set anything outside this function.
*/
void()MakeSolidCorpse =
{
vector newmaxs;
// Make a gibbable corpse, change the size so we can jump on it
//Won't be necc to pass headmdl once everything has it's .headmodel
//value set in spawn
self.th_die = chunk_death;
self.touch = obj_push;
self.health = random(10,25);
self.takedamage = DAMAGE_YES;
self.solid = SOLID_PHASE;
self.experience_value = 0;
if(self.classname!="monster_hydra")
self.movetype = MOVETYPE_STEP;//Don't get in the way
if(!self.mass)
self.mass=1;
//To fix "player stuck" probem
newmaxs=self.maxs;
if(newmaxs_z>5)
newmaxs_z=5;
setsize (self, self.mins,newmaxs);
if(self.flags&FL_ONGROUND)
self.velocity='0 0 0';
self.flags(-)FL_MONSTER;
self.controller = self;
self.onfire = FALSE;
pitch_roll_for_slope('0 0 0');
if ((self.decap) && (self.classname == "player"))
{
if (deathmatch||teamplay)
self.lifetime = time + random(20,40); // decompose after 40 seconds
else
self.lifetime = time + random(10,20); // decompose after 20 seconds
self.owner=self;
self.think=Spurt;
thinktime self : random(1,4);
}
else
{
self.lifetime = time + random(10,20); // disappear after 20 seconds
self.think=CorpseThink;
thinktime self : 0;
}
};

481
crossbow.hc Normal file
View File

@ -0,0 +1,481 @@
/*
* $Header: /HexenWorld/Siege/crossbow.hc 38 6/16/98 12:00p Ggribb $
*/
/*
==============================================================================
Q:\art\models\weapons\crossbow\final\crossbow.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\weapons\crossbow\final
$origin 0 0 0
$base base skin
$skin skin
$flags 0
//
$frame select1 select2 select3 select4 select5
$frame select6 select7 select8 select9 select10
$frame select11 select12 select13 select14 select15
//
$frame shoot1 shoot2 shoot3 shoot4 shoot5
$frame shoot6 shoot7 shoot8 shoot9 shoot10
$frame shoot11 shoot12 shoot13 shoot14 shoot15
$frame shoot16 shoot17 shoot18 shoot19
void flashspin ()
{
if(self.lifetime<time)
remove(self);
else
{
self.scale+=0.05;
thinktime self : 0.075;
}
}
void MakeFlash(vector org)
{
newmis=spawn_temp();
newmis.movetype=MOVETYPE_NOCLIP;
newmis.angles=vectoangles(v_forward);
newmis.avelocity_z=random(200,700);
newmis.scale=0.1;
newmis.drawflags(+)MLS_ABSLIGHT|SCALE_ORIGIN_CENTER;
newmis.abslight=0.5;
newmis.lifetime=time+0.3;
newmis.think=flashspin;
thinktime newmis : 0;
setmodel(newmis,"models/arrowhit.mdl");
setsize(newmis,'0 0 0','0 0 0');
setorigin(newmis,org);
}
void() FallAndRemove =
{
//self.enemy.movetype?
traceline(self.origin,self.origin-'0 0 24',TRUE,self);
if(pointcontents(self.origin)==CONTENT_SOLID||trace_fraction<1)
remove(self);
self.movetype=MOVETYPE_BOUNCE;
self.velocity_z=random(-60,-150);
self.flags(-)FL_ONGROUND;
self.avelocity=RandomVector('50 50 50');
self.think=SUB_Remove;
thinktime self : self.wait;
};
void() CB_BoltStick=
{
if(self.wait<=time)
if(self.classname=="bolt")
{
self.wait=2;
self.think=FallAndRemove;
}
else if(self.classname=="stickmine")
self.think=MultiExplode;
else
self.think=DarkExplosion;
else if(self.enemy.health<=0&&self.health)
{
self.health=0;
if(self.classname=="bolt")
{
self.wait=random(1,3);
self.think=FallAndRemove;
}
else
{
self.movetype=MOVETYPE_BOUNCE;
self.velocity_z=random(-100,100);
self.avelocity=RandomVector('50 50 50');
}
}
else if(self.movetype!=MOVETYPE_BOUNCE)
{
setorigin(self,self.enemy.origin+self.view_ofs);
self.angles=self.o_angle + self.enemy.angles;
self.think=CB_BoltStick;
}
thinktime self : 0;
};
/*
void burner_think ()
{
vector org,vel;
if(self.lifetime<time||self.enemy.health<0)
{
sound(self.enemy,CHAN_BODY,"misc/null.wav",1,ATTN_NORM);
remove(self);
return;
}
else if(pointcontents(self.enemy.origin)==CONTENT_WATER)
{
sound (self.enemy, CHAN_BODY, "misc/fout.wav", 1, ATTN_NORM);
smolder((self.enemy.absmin+self.enemy.absmax)*0.5);
remove(self);
return;
}
else
{
org=(self.enemy.absmin+self.enemy.absmax)*0.5+randomv(self.enemy.size*-0.25,self.enemy.size*0.25);
vel=randomv('-3 -3 0','3 3 7');
if(random()<=0.33)
starteffect(CE_FLAMESTREAM, org,vel, 0);
else if(random()<=0.5)
starteffect(CE_GREEN_SMOKE, org,vel, 0);
else
starteffect(CE_RED_SMOKE, org,vel, 0);
thinktime self : random(0.5);
T_Damage(self.enemy,self,self.owner,2);
sound(self.enemy,CHAN_BODY,"raven/fire1.wav",1,ATTN_NORM);
}
}
void spawn_burner (entity loser)
{
entity burner;
burner=spawn();
burner.owner=self.owner;
burner.enemy=loser;
burner.lifetime=time+random(5)+15;
burner.think=burner_think;
thinktime burner : 0;
sound(self,CHAN_AUTO,"weapons/fbfire.wav",1,ATTN_NORM);
starteffect(CE_LG_EXPLOSION , self.origin);
}
*/
void() CB_BoltHit=
{//FIXME: Flaming arrows catch wood & flesh on fire
if(other==self.owner||(other.owner==self.owner&&other.classname==self.classname))
return;
vector stickdir, stickspot,center,hitspot;
float rad,stick,hitdmg,skiprest,headdist;
v_forward=normalize(self.velocity);
hitdmg=(vlen(self.velocity) - 600)/10;
if(hitdmg<5)
hitdmg=5;
if(other.health>200&&other.thingtype!=THINGTYPE_FLESH)//So it can't break catapults and ballistas and ramparts
hitdmg=1;
sound(self,CHAN_BODY,"misc/null.wav",1,ATTN_NORM);
setsize(self,'0 0 0','0 0 0');
self.takedamage=DAMAGE_NO;
self.velocity='0 0 0';
self.movetype=MOVETYPE_NOCLIP;
self.solid=SOLID_NOT;
self.touch=SUB_Null;
self.health=other.health;
if(other.thingtype==THINGTYPE_FLESH)
sound(self, CHAN_WEAPON, "assassin/arr2flsh.wav", 1, ATTN_NORM);
else if(other.thingtype==THINGTYPE_WOOD)
sound(self, CHAN_WEAPON, "assassin/arr2wood.wav", 1, ATTN_NORM);
else
sound(self, CHAN_WEAPON, "weapons/met2stn.wav", 1, ATTN_NORM);
MakeFlash(self.origin-v_forward*8);
if(other.takedamage)
{
if(other.solid!=SOLID_BSP)
if(self.frags)
if(flammable(other))
spawn_burner(other,FALSE);
if(other.flags2&FL_ALIVE&&other.classname!="player_sheep")
{
headdist=vlen(other.origin+other.view_ofs - self.origin);
hitspot=self.origin+v_forward*headdist;
if(vlen(hitspot-self.origin)<10)//head shot, instant kill
{
T_Damage(other,self,self.owner,other.health+30);
skiprest=TRUE;
}
}
if(!skiprest)
if(self.classname=="bolt")
{
if(other.thingtype==THINGTYPE_FLESH||other.classname=="barrel")
T_Damage(other,self,self.owner,hitdmg);
else
T_Damage(other,self,self.owner,random(2,5));
}
else
T_Damage(other,self,self.owner,3);
SpawnPuff(self.origin+v_forward*8,'0 0 0'-v_forward*24,10,other);
if(other.solid!=SOLID_BSP)
{
//Put it right below view of player
if(other.classname=="player")
{
stickdir_z=other.origin_z+other.proj_ofs_z+ 1;
stickdir=other.origin+normalize(self.origin-other.origin)*12;
stick=TRUE;
setorigin(self,stickdir);
}
else
{
rad=(other.maxs_x+other.maxs_z)*0.5;
center=(other.absmax+other.absmin)*0.5;
stickspot=self.origin+v_forward*other.maxs_x*2;
if(vlen(center-stickspot)<rad*0.5)
{
stick=TRUE;
setorigin(self,stickspot);
}
else
stick=FALSE;
}
self.wait=time + random(0.1,2);
}
}
else
{
CreateWhiteSmoke(self.origin-v_forward*8,'0 0 8',HX_FRAME_TIME);
SpawnPuff(self.origin+v_forward*8,'0 0 0'-v_forward*24,10,world);
if(self.classname=="bolt")
{
if(random()<0.7)
chunk_death();
else if(random()<0.5)
{
self.movetype=MOVETYPE_BOUNCE;
self.velocity_z=-20;
self.flags(-)FL_ONGROUND;
self.avelocity_x=random(-360,360);
self.avelocity_y=random(-360,360);
self.avelocity_z=random(-360,360);
self.touch=SUB_Null;
self.think=SUB_Remove;
thinktime self : random(0.5,1.5);
return;
}
}
else
stick=TRUE;
self.wait=time + random(1,3);
}
//FIXME: only stick in if thingtype is wood or flesh,
//otherwise, no damage and bounce off!
if(other.movetype||other.takedamage||stick||self.health)
{
if(stick)
{
self.enemy=other;
self.view_ofs=(self.origin-other.origin);
self.o_angle=(self.angles-self.enemy.angles);
if(other.health)
self.health=other.health;
else
self.health=FALSE;
self.think=CB_BoltStick;
thinktime self : 0;
}
else if(self.classname=="bolt")
remove(self);
else
DarkExplosion();
}
else
{
self.movetype=MOVETYPE_NONE;
if(self.classname=="bolt")
self.think=SUB_Remove;
else
self.think=DarkExplosion;
thinktime self : 2;
}
};
void ArrowFlyThink (void)
{
if(self.lifetime<time&&self.mins=='0 0 0')
{
self.takedamage=DAMAGE_YES;
// setsize(self,'-3 -3 -2','3 3 2');
}
if(self.model=="models/flaming.mdl")
{
self.frame+=1;
if(self.frame>9)
self.frame=0;
}
if(self.lifetime<time&&!self.frags)
{
self.velocity_z-=30;
self.angles=vectoangles(self.velocity);
}
self.think=ArrowFlyThink;
thinktime self : 0.05;
}
void ArrowSound (void)
{
//attn_static instead?
// sound(self,CHAN_BODY,"assassin/arrowfly.wav",1,ATTN_NORM);
self.think=ArrowFlyThink;
thinktime self : 0;
}
void FlamingArrowThink (void)
{
float waterornot;
waterornot=pointcontents(self.origin);
if(waterornot==CONTENT_WATER||waterornot==CONTENT_SLIME)
{
sound (self, CHAN_WEAPON, "misc/fout.wav", 1, ATTN_NORM);
DeathBubbles(1);
setmodel(self,"models/NFarrow.mdl");
}
ArrowSound();
}
void ArrowThink (void)
{
vector dir;
dir=normalize(self.velocity);
traceline(self.origin,self.origin+dir*1000,FALSE,self);
if(!trace_ent.takedamage)
HomeThink();
self.angles=vectoangles(self.velocity);
if(self.classname=="bolt")
self.think=ArrowSound;
else
self.think=FlamingArrowThink;
thinktime self : 0;
}
void(float powered_up) FireCB_Bolt =
{
entity missile;
float offset,speed_mod;
vector v_offset;
self.cnt_arrows-=1;
makevectors(self.v_angle);
missile=spawn();
missile.owner=self;
missile.solid=SOLID_BBOX;
missile.hull=HULL_POINT;
missile.health=3;
// if(deathmatch)
// offset*=.333;
if(powered_up)
{
if(self.torchtime>time)
{
missile.frags=TRUE;
missile.thingtype=THINGTYPE_METAL;
setmodel(missile,"models/flaming.mdl");
missile.speed=random(1100,1400);
missile.classname="flarrow";
missile.drawflags(+)MLS_ABSLIGHT|MLS_FIREFLICKER;
missile.abslight = .75;
}
else
{
missile.classname="bolt";
missile.thingtype=THINGTYPE_WOOD_METAL;
setmodel(missile,"models/arrow.mdl");
speed_mod=melee_dmg_mod_for_strength (self.strength);
missile.speed=random(1100,1400);
}
}
else
{
missile.classname="bolt";
missile.thingtype=THINGTYPE_WOOD;
setmodel(missile,"models/arrow.mdl");
speed_mod=melee_dmg_mod_for_strength (self.strength);
missile.speed=800+100*(random(speed_mod));
}
missile.movetype=MOVETYPE_FLYMISSILE;
missile.th_die=chunk_death;
missile.touch=CB_BoltHit;
float num_weap;
num_weap=num_for_weap (self.weapon);
offset = rate_and_acc_for_weap [(self.playerclass - 1)*6+(num_weap - 1)*2+1]/2;
v_offset = v_right*(random(offset)*2 - offset) + v_up*(random(offset)*2 - offset) + v_forward;
v_offset = normalize(v_offset);
missile.o_angle=missile.velocity=normalize(v_offset)*missile.speed;
missile.angles=vectoangles(missile.velocity);
if(!powered_up)
{
missile.think = Missile_Arc;
thinktime missile : 0.2;
}
// missile.lifetime=time+0.2;
setsize(missile,'0 0 0','0 0 0');
setorigin(missile,self.origin+self.proj_ofs+v_forward*8);
};
void()crossbow_fire;
void crossbow_idle(void)
{
self.th_weapon=crossbow_idle;
self.weaponframe=$shoot19;
}
void crossbow_fire (void)
{
float num_weap;
self.wfs = advanceweaponframe($shoot1,$shoot18);
self.th_weapon=crossbow_fire;
if(self.button0&&self.weaponframe==$shoot2 &&self.weapon==IT_WEAPON3)
self.weaponframe=$shoot1;
else if (self.weaponframe == $shoot2)
{
num_weap = num_for_weap (self.weapon);
if(self.playerclass==CLASS_ASSASSIN&&self.weapon==IT_WEAPON3)
{
sound(self,CHAN_WEAPON,"assassin/firefblt.wav",1,ATTN_NORM);
FireCB_Bolt(TRUE);
self.attack_finished=time+2;//rate_and_acc_for_weap[(self.playerclass - 1)*6+(num_weap - 1)*2];
}
else
{
sound(self,CHAN_WEAPON,"assassin/firebolt.wav",1,ATTN_NORM);
FireCB_Bolt(FALSE);
self.attack_finished=time+rate_and_acc_for_weap[(self.playerclass - 1)*6+(num_weap - 1)*2];
}
}
else if (self.wfs==WF_CYCLE_WRAPPED)
crossbow_idle();
}
void crossbow_select (void)
{
//selection sound?
self.wfs = advanceweaponframe($select15,$select1);
self.weaponmodel = "models/xbow2.mdl";
self.th_weapon=crossbow_select;
if (self.weaponframe==$select1)
{
self.attack_finished = time - 1;
crossbow_idle();
}
}
void crossbow_deselect (void)
{
self.wfs = advanceweaponframe($select1,$select15);
self.th_weapon=crossbow_deselect;
if (self.wfs==WF_CYCLE_WRAPPED)
W_SetCurrentAmmo();
}

385
crusader.hc Normal file
View File

@ -0,0 +1,385 @@
/*
* $Header: /HexenWorld/Siege/crusader.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\players\crusader\final\crusader.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\players\crusader\final
$origin 0 0 0
$base BASE skin
$skin skin
$flags 0
//
$frame crouch1 crouch2 crouch3 crouch4 crouch5
$frame crouch6 crouch7 crouch8 crouch9 crouch10
$frame crouch11 crouch12 crouch13 crouch14 crouch15
$frame crouch16 crouch17 crouch18 crouch19 crouch20
//
$frame decap1 decap2 decap3 decap4 decap5
$frame decap6 decap7 decap8 decap9 decap10
$frame decap11 decap12 decap13 decap14 decap15
$frame decap16 decap17 decap18 decap19 decap20
$frame decap21 decap22 decap23 decap24 decap25
$frame decap26 decap27 decap28
//
$frame die1 die2 die3 die4 die5
$frame die6 die7 die8 die9 die10
$frame die11 die12 die13 die14 die15
$frame die16 die17 die18 die19 die20
//
$frame FINLPOLY
//
$frame HmrFly1 HmrFly2 HmrFly3 HmrFly4 HmrFly5
$frame HmrFly6 HmrFly7 HmrFly8 HmrFly9 HmrFly10
$frame HmrFly11 HmrFly12 HmrFly13 HmrFly14 HmrFly15
//
$frame HmrHit1 HmrHit2 HmrHit3 HmrHit4 HmrHit5
$frame HmrHit6 HmrHit7 HmrHit8 HmrHit9 HmrHit10
//
$frame hmrPain1 hmrPain2 hmrPain3 hmrPain4 hmrPain5
$frame hmrPain6 hmrPain7 hmrPain8
//
$frame HmrStn1 HmrStn2 HmrStn3 HmrStn4 HmrStn5
$frame HmrStn6 HmrStn7 HmrStn8 HmrStn9 HmrStn10
$frame HmrStn11 HmrStn12 HmrStn13
//
$frame HmrRun1 HmrRun2 HmrRun3 HmrRun4 HmrRun5
$frame HmrRun6 HmrRun7 HmrRun8 HmrRun9 HmrRun10
$frame HmrRun11 HmrRun12
//
$frame IceFly1 IceFly2 IceFly3 IceFly4 IceFly5
$frame IceFly6 IceFly7 IceFly8 IceFly9 IceFly10
$frame IceFly11 IceFly12 IceFly13 IceFly14 IceFly15
//
$frame IcePain1 IcePain2 IcePain3 IcePain4 IcePain5
$frame IcePain6 IcePain7 IcePain8
//
$frame IceRun1 IceRun2 IceRun3 IceRun4 IceRun5
$frame IceRun6 IceRun7 IceRun8 IceRun9 IceRun10
$frame IceRun11 IceRun12
//
$frame IceShot1 IceShot2 IceShot3 IceShot4
//
$frame IceStn1 IceStn2 IceStn3 IceStn4 IceStn5
$frame IceStn6 IceStn7 IceStn8 IceStn9 IceStn10
$frame IceStn11 IceStn12 IceStn13
//
$frame jump1 jump2 jump3 jump4 jump5
$frame jump6 jump7 jump8 jump9 jump10
$frame jump11 jump12 jump13
//
$frame SunFly1 SunFly2 SunFly3 SunFly4 SunFly5
$frame SunFly6 SunFly7 SunFly8 SunFly9 SunFly10
$frame SunFly11 SunFly12 SunFly13 SunFly14
//
$frame SunPain1 SunPain2 SunPain3 SunPain4 SunPain5
$frame SunPain6 SunPain7 SunPain8
//
$frame SunRun1 SunRun2 SunRun3 SunRun4 SunRun5
$frame SunRun6 SunRun7 SunRun8 SunRun9 SunRun10
$frame SunRun11 SunRun12
//
$frame SunShot1 SunShot2 SunShot3 SunShot4 SunShot5
//
$frame SunStn1 SunStn2 SunStn3 SunStn4 SunStn5
$frame SunStn6 SunStn7 SunStn8 SunStn9 SunStn10
$frame SunStn11 SunStn12 SunStn13
/*--------------------------
ACTUAL (UNIQUE TO CLASS) PLAYER CODE
----------------------------*/
void() player_crusader_run;
void() player_crusader_crouch_stand;
void() player_crusader_crouch_move;
void() player_crusader_stand;
void() player_crusader_jump=[++$jump1..$jump13]//FIX
{
if(self.viewentity==self)
self.th_weapon();
if(cycle_wrapped)
{
if(!self.velocity_x && !self.velocity_y)
self.think=self.th_stand;
else
self.think=self.th_run;
}
};
void() player_crusader_swim =
{
if(self.viewentity==self)
self.th_weapon();
if(self.waterlevel<3)
if (self.velocity_x || self.velocity_y)
self.think=self.th_run;
else
self.think=self.th_stand;
};
void() player_crusader_hammer_swim =[++$HmrFly1..$HmrFly15]
{
player_crusader_swim();
};
void() player_crusader_sunstaff_swim =[++$SunFly1..$SunFly14]
{
player_crusader_swim();
};
void() player_crusader_ice_swim =[++$IceFly1..$IceFly15]
{
player_crusader_swim();
};
void() player_crusader_fly =
{
if(self.viewentity==self)
self.th_weapon();
if(self.waterlevel>2)
self.think=self.th_swim;
else if(self.movetype!=MOVETYPE_FLY)
if (self.velocity_x || self.velocity_y)
self.think=self.th_run;
else
self.think=self.th_stand;
};
void() player_crusader_hammer_fly =[++$HmrFly1..$HmrFly15]
{
player_crusader_fly();
};
void() player_crusader_sunstaff_fly =[++$SunFly1..$SunFly14]
{
player_crusader_fly();
};
void() player_crusader_ice_fly =[++$IceFly1..$IceFly15]
{
player_crusader_fly();
};
void() player_crusader_stand =
{
if(self.viewentity==self)
self.th_weapon();
if(self.hull==HULL_CROUCH)
self.think=player_crusader_crouch_stand;
else if(self.waterlevel>2)
self.think=self.th_swim;
else if(self.movetype==MOVETYPE_FLY)
self.think=self.th_fly;
else if (self.velocity_x || self.velocity_y)
self.think=self.th_run;
};
void() player_crusader_hammer_stand =[++$HmrStn1..$HmrStn13]
{
player_crusader_stand();
};
void() player_crusader_sunstaff_stand =[++$SunStn1..$SunStn13]
{
player_crusader_stand();
};
void() player_crusader_ice_stand =[++$IceStn1..$IceStn13]
{
player_crusader_stand();
};
void() player_crusader_run =
{
if(self.viewentity==self)
self.th_weapon();
if(self.hull==HULL_CROUCH)
self.think=player_crusader_crouch_move;
else if(self.waterlevel>2)
self.think=self.th_swim;
else if(self.movetype==MOVETYPE_FLY)
self.think=self.th_fly;
else if (!self.velocity_x && !self.velocity_y)
self.think=self.th_stand;
};
void() player_crusader_hammer_run =[++$HmrRun1..$HmrRun12]
{
player_crusader_run();
};
void() player_crusader_sunstaff_run =[++$SunRun1..$SunRun12]
{
player_crusader_run();
};
void() player_crusader_ice_run =[++$IceRun1..$IceRun12]
{
player_crusader_run();
};
void() player_crusader_crouch_stand =
{
if(self.viewentity==self)
self.th_weapon();
if(self.frame>$crouch20 || self.frame<$crouch1)
self.frame=$crouch1;
if(self.movetype==MOVETYPE_FLY)
self.think=self.th_fly;
else if(self.hull==HULL_PLAYER)
self.think=self.th_stand;
else if (self.velocity_x || self.velocity_y)
self.think=player_crusader_crouch_move;
self.nextthink=time + HX_FRAME_TIME;
};
void() player_crusader_crouch_move =[++$crouch1..$crouch20]
{
if(self.viewentity==self)
self.th_weapon();
if(self.movetype==MOVETYPE_FLY)
self.think=player_crusader_fly;
else if(self.hull==HULL_PLAYER)
self.think=self.th_run;
else if (!self.velocity_x && !self.velocity_y)
self.think=player_crusader_crouch_stand;
};
void() player_crusader_attack=
{
if(self.viewentity==self)
self.th_weapon();
if(cycle_wrapped&&!self.button0)
{
if(!self.velocity_x && !self.velocity_y)
self.think=self.th_stand;
else
self.think=self.th_run;
}
};
void() player_crusader_hammer_attack=[++$HmrHit1..$HmrHit10]
{
player_crusader_attack();
};
void() player_crusader_ice_attack=[++$IceShot1..$IceShot4]
{
player_crusader_attack();
};
void() player_crusader_sunstaff_attack=[++$SunShot1..$SunShot5]
{
player_crusader_attack();
};
void() player_crusader_pain=
{
if(self.viewentity==self)
self.th_weapon();
if(cycle_wrapped)
{
if(!self.velocity_x && !self.velocity_y)
self.think=self.th_stand;
else
self.think=self.th_run;
}
};
void() player_crusader_hammer_pain =[++$HmrPain1..$HmrPain8]
{
if(self.frame==$HmrPain1)
PainSound();
player_crusader_pain();
};
void() player_crusader_sunstaff_pain =[++$SunPain1..$SunPain8]
{
if(self.frame==$SunPain1)
PainSound();
player_crusader_pain();
};
void() player_crusader_ice_pain =[++$IcePain1..$IcePain8]
{
if(self.frame==$IcePain1)
PainSound();
player_crusader_pain();
};
void() player_crusader_die1=[++$die1..$die20]
{
if(cycle_wrapped)
{
self.frame=$die20;
self.think=PlayerDead;
}
};
void() player_crusader_behead =
{
self.level=$decap1;
self.dmg=$decap28;
self.cnt=0;
player_behead();
};
void Cru_Change_Weapon (void)
{
if(self.weapon==IT_WEAPON1)
{
self.th_stand=player_crusader_hammer_stand;
self.th_missile=player_crusader_hammer_attack;
self.th_run=player_crusader_hammer_run;
self.th_pain=player_crusader_hammer_pain;
self.th_swim=player_crusader_hammer_swim;
self.th_fly=player_crusader_hammer_fly;
}
else if(self.weapon==IT_WEAPON2)
{
self.th_stand=player_crusader_ice_stand;
self.th_missile=player_crusader_ice_attack;
self.th_run=player_crusader_ice_run;
self.th_pain=player_crusader_ice_pain;
self.th_swim=player_crusader_ice_swim;
self.th_fly=player_crusader_ice_fly;
}
else
{
self.th_stand=player_crusader_sunstaff_stand;
self.th_missile=player_crusader_sunstaff_attack;
self.th_run=player_crusader_sunstaff_run;
self.th_pain=player_crusader_sunstaff_pain;
self.th_swim=player_crusader_sunstaff_swim;
self.th_fly=player_crusader_sunstaff_fly;
}
if(self.hull!=HULL_CROUCH)
self.think=self.th_stand;
}

282
cube.hc Normal file
View File

@ -0,0 +1,282 @@
/*
* $Header: /HexenWorld/Siege/cube.hc 4 5/25/98 1:38p Mgummelt $
*/
float cube_distance = 500;
void CubeDie(void)
{
self.owner.artifact_flags(-)self.artifact_flags;
remove(self);
}
float cube_find_target(void)
{
entity item;
item = findradius(self.origin, cube_distance);
while (item)
{
if ((item.flags & FL_MONSTER) || ((item.classname == "player") && deathmatch == 1) && item.health > 0)
{
tracearea (self.origin,item.origin,self.mins,self.maxs,FALSE,self);
if (trace_ent == item)
{
if (!item.effects & EF_NODRAW)
{
self.enemy = item;
return TRUE;
}
}
}
item = item.chain;
}
return FALSE;
}
void do_fireball(vector offset);
vector CubeDirection[6] =
{
'90 0 0',
'-90 0 0',
'0 90 0',
'0 -90 0',
'0 0 90',
'0 0 -90'
};
void cube_fire(void)
{
// float RanVal;
float Distance;
entity temp;
if (time > self.monster_duration || self.owner.health <= 0 || self.shot_cnt >= 10)
{
CubeDie();
return;
}
if (!self.enemy)
{
self.cnt += 1;
if (self.cnt > 5)
{
cube_find_target();
self.cnt = 0;
}
}
if (self.enemy)
{
if (self.enemy.health <= 0)
{
self.enemy = world;
//self.drawflags (+) DRF_TRANSLUCENT;
}
}
if (self.enemy)
{
if (random() < .7)
{
Distance = vlen(self.origin - self.enemy.origin);
if (Distance > cube_distance*2)
{
self.enemy = world;
//self.drawflags (+) DRF_TRANSLUCENT;
}
else
{
// Got to do this otherwise tracearea sees right through you
temp = self.owner;
self.owner = self;
tracearea (self.origin,self.enemy.origin,self.mins,self.maxs,FALSE,self);
if (trace_ent == self.enemy)
{
self.adjust_velocity = CubeDirection[random(0,5)];
self.abslight = 1;
self.shot_cnt += 1;
do_fireball('0 0 0');
}
else
{
self.enemy = world;
//self.drawflags (+) DRF_TRANSLUCENT;
}
self.owner = temp;
}
}
}
}
void cube_rotate(void)
{
vector NewOffset;
NewOffset = concatv(self.adjust_velocity,'5 5 5');
self.adjust_velocity -= NewOffset;
self.v_angle += NewOffset;
}
vector CubeFollowRate = '14 14 14';
vector CubeAttackRate = '3 3 3';
void CubeThinkerB(void)
{
vector NewSpot;
float Distance;
thinktime self : 0.05;
if (!self.owner.flags2 & FL_ALIVE)
{
CubeDie();
return;
}
if (self.adjust_velocity == '0 0 0')
{
cube_fire();
if (self.adjust_velocity == '0 0 0')
{
if (random() < 0.02)
{
self.adjust_velocity = CubeDirection[random(0,5)];
}
}
}
cube_rotate();
if (self.abslight > .1)
self.abslight -= 0.1;
self.angles = self.owner.angles + self.v_angle;
self.count += random(4,6);
if (self.count > 360)
{
self.count -= 360;
}
Distance = vlen(self.origin - self.owner.origin);
if (Distance > cube_distance)
{
self.enemy = world;
//self.drawflags (+) DRF_TRANSLUCENT;
}
if (self.enemy != world)
{
NewSpot = self.enemy.origin + self.enemy.view_ofs;
if (self.artifact_flags & AFL_CUBE_LEFT)
{
NewSpot += (cos(self.count) * 40 * '1 0 0') + (sin(self.count) * 40 * '0 1 0');
}
else
{
NewSpot += (sin(self.count) * 40 * '1 0 0') + (cos(self.count) * 40 * '0 1 0');
}
self.movedir_z += random(10,12);
if (self.movedir_z > 360)
{
self.movedir_z -= 360;
}
NewSpot_z += sin(self.movedir_z) * 10;
NewSpot = self.origin + concatv(NewSpot - self.origin, CubeAttackRate);
}
else
{
makevectors(self.owner.v_angle);
if (self.artifact_flags & AFL_CUBE_LEFT)
{
NewSpot = self.owner.origin + self.owner.view_ofs + '0 0 10' + v_factor('40 60 0');
}
else
{
NewSpot = self.owner.origin + self.owner.view_ofs + '0 0 10' + v_factor('-40 60 0');
}
self.movedir_z += random(10,12);
if (self.movedir_z > 360)
{
self.movedir_z -= 360;
}
NewSpot += (v_right * cos(self.count) * 15) + (v_up * sin(self.count) * 15) +
(v_forward * sin(self.movedir_z) * 15);
NewSpot = self.origin + concatv(NewSpot - self.origin, CubeFollowRate);
}
setorigin(self,NewSpot);
}
void UseCubeOfForce(void)
{
entity cube;
if ((self.artifact_flags & AFL_CUBE_LEFT) &&
(self.artifact_flags & AFL_CUBE_RIGHT))
{ // Already got two running
return;
}
cube = spawn();
cube.owner = self;
cube.solid = SOLID_SLIDEBOX;
cube.movetype = MOVETYPE_NOCLIP;//MOVETYPE_FLY;
cube.flags (+) FL_FLY | FL_NOTARGET;
setorigin (cube, cube.owner.origin);
setmodel (cube, "models/cube.mdl");
setsize (cube, '-5 -5 -5', '5 5 5');
cube.classname = "cube_of_force";
cube.health = 10;
cube.dmg = -1;
if (self.artifact_flags & AFL_CUBE_LEFT)
{
self.artifact_flags (+) AFL_CUBE_RIGHT;
cube.artifact_flags (+) AFL_CUBE_RIGHT;
}
else
{
self.artifact_flags (+) AFL_CUBE_LEFT;
cube.artifact_flags (+) AFL_CUBE_LEFT;
}
cube.think = CubeThinkerB;
cube.th_die = CubeDie;
thinktime cube : 0.01;
cube.monster_duration = time + 45;
cube.shot_cnt = 0;
cube.movedir = '100 100 0';
cube.count = random(360);
self.movedir_z = random(360);
// cube.drawflags (+) DRF_TRANSLUCENT;
cube.drawflags (+) MLS_ABSLIGHT;
cube.abslight = .1;
self.cnt_cubeofforce -= 1;
}

1308
damage.hc Normal file

File diff suppressed because it is too large Load Diff

5
defs.hc Normal file
View File

@ -0,0 +1,5 @@
/*
* $Header: /HexenWorld/Siege/Defs.hc 3 5/25/98 1:38p Mgummelt $
*/
// !!! Not used !!!

368
demon.hc Normal file
View File

@ -0,0 +1,368 @@
/*
* $Header: /HexenWorld/Siege/Demon.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
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 ();
};
/*QUAK-ED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) Ambush
-----------------------FIELDS-------------------------
--------------------------------------------------------
*/
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 ("weapons/slash.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 =
{
local vector vec;
// 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, "weapons/slash.wav", 1, ATTN_NORM);
ldmg = 10 + 5*random();
T_Damage (self.enemy, self, self, ldmg);
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);
}
}
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;
};

129
dmlevels.hc Normal file
View File

@ -0,0 +1,129 @@
/*===========================
Level listings for DM- seperate .hc file to make it easy to find.
Change the order to whatever you want and recompile the progs.dat.
MG
=============================*/
void FindDMLevel(void)
{
serverflags (+) SFL_NEW_UNIT;
nextmap = string_null;
if(dmMode == DM_SIEGE)
{//FIXME: Check a text file for the next map, else use Siege11?
nextmap = "siege";
}
else if (cvar("registered") != 0 || cvar("oem") != 0)
{//registered
if (mapname == "demo1")
nextmap = "demo2";
else if (mapname == "demo2")
nextmap = "demo3";
else if (mapname == "demo3")
nextmap = "village1";
else if (mapname == "village1")
nextmap = "village2";
else if (mapname == "village2")
nextmap = "village3";
else if (mapname == "village3")
nextmap = "village4";
else if (mapname == "village4")
nextmap = "village5";
else if (mapname == "village5")
nextmap = "rider1a";
else if (mapname == "rider1a")
nextmap = "demo1";
else if (mapname == "meso1")
nextmap = "meso2";
else if (mapname == "meso2")
nextmap = "meso3";
else if (mapname == "meso3")
nextmap = "meso4";
else if (mapname == "meso4")
nextmap = "meso5";
else if (mapname == "meso5")
nextmap = "meso6";
else if (mapname == "meso6")
nextmap = "meso8";
else if (mapname == "meso8")
nextmap = "meso9";
else if (mapname == "meso9")
nextmap = "meso1";
else if (mapname == "egypt1")
nextmap = "egypt2";
else if (mapname == "egypt2")
nextmap = "egypt3";
else if (mapname == "egypt3")
nextmap = "egypt4";
else if (mapname == "egypt4")
nextmap = "egypt5";
else if (mapname == "egypt5")
nextmap = "egypt6";
else if (mapname == "egypt6")
nextmap = "egypt7";
else if (mapname == "egypt7")
nextmap = "rider2c";
else if (mapname == "rider2c")
nextmap = "egypt1";
else if (mapname == "romeric1")
nextmap = "romeric2";
else if (mapname == "romeric2")
nextmap = "romeric3";
else if (mapname == "romeric3")
nextmap = "romeric4";
else if (mapname == "romeric4")
nextmap = "romeric5";
else if (mapname == "romeric5")
nextmap = "romeric6";
else if (mapname == "romeric6")
nextmap = "romeric7";
else if (mapname == "romeric7")
nextmap = "romeric1";
else if (mapname == "cath")
nextmap = "tower";
else if (mapname == "tower")
nextmap = "castle4";
else if (mapname == "castle4")
nextmap = "castle5";
else if (mapname == "castle5")
nextmap = "eidolon";
else if (mapname == "eidolon")
nextmap = "cath";
else if (mapname == "ravdm1")
nextmap = "ravdm2";
else if (mapname == "ravdm2")
nextmap = "ravdm3";
else if (mapname == "ravdm3")
nextmap = "ravdm4";
else if (mapname == "ravdm4")
nextmap = "ravdm5";
else if (mapname == "ravdm5")
nextmap = "hwdm1";
else if (mapname == "hwdm1")
nextmap = "hwdm2";
else if (mapname == "hwdm2")
nextmap = "hwdm3";
else if (mapname == "hwdm3")
nextmap = "hwdm4";
else if (mapname == "hwdm4")
nextmap = "hwdm5";
else if (mapname == "hwdm5")
nextmap = "ravdm1";
}
else
{//demo
if (mapname == "demo1")
nextmap = "demo2";
else if (mapname == "demo2")
nextmap = "ravdm1";
else if (mapname == "ravdm1")
nextmap = "demo1";
}
}

369
dog.hc Normal file
View File

@ -0,0 +1,369 @@
/*
* $Header: /HexenWorld/Siege/Dog.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
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, "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
==============
*/
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 =
{
local vector vec;
// 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;
};
//===========================================================================
/*QUAK-ED monster_dog (1 0 0) (-32 -32 -24) (32 32 40) Ambush
-----------------------FIELDS-------------------------
--------------------------------------------------------
*/
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();
};

1798
doors.hc Normal file

File diff suppressed because it is too large Load Diff

88
dthfire.hc Normal file
View File

@ -0,0 +1,88 @@
void trap_death_fireball_use ();
void trap_death_fireball_wait ();
void death_fireball_touch ()
{
local float damg;
sound (self, CHAN_WEAPON, "misc/combust.wav", 1, ATTN_NORM);
damg = (12 + random(1,10));
if (other.health)
T_Damage (other, self, self.owner, damg );
T_RadiusDamage (self, self.owner, damg, other);
self.origin = self.origin - 8*normalize(self.velocity);
remove(self);
}
void trap_death_fireball_wait ()
{
self.think = trap_death_fireball_use;
thinktime self : random(0.1, 2);
}
void death_fireball_think ()
{
if ((vlen(self.velocity) < 50))
{
dprint("KABLOEY!\n");
MeteoriteFizzle();
return;
}
particle4(self.origin,75,random(272,288),PARTICLETYPE_FIREBALL,random(5,10));
self.think=death_fireball_think;
thinktime self : 0.1;
}
void trap_death_fireball_use ()
{
entity fireball;
vector vec;
makevectors(self.angles);
vec = v_up;
vec_x += random(-0.2,0.2);
vec_y += random(-0.2,0.2);
sound (self, CHAN_WEAPON, "raven/littorch.wav", 1, ATTN_NORM);
fireball = spawn ();
fireball.movetype = MOVETYPE_BOUNCE;
fireball.solid = SOLID_BBOX;
fireball.speed=random(600, 1000);
fireball.velocity=vec*fireball.speed;
fireball.touch = death_fireball_touch;
fireball.dmg=self.dmg;
fireball.owner = self;
fireball.angles = vectoangles (fireball.velocity);
fireball.think = death_fireball_think;
thinktime fireball : 0.1;
self.last_attack=time;
setmodel (fireball, "models/dthball.mdl");
setsize (fireball, '0 0 0', '0 0 0');
setorigin (fireball,self.origin);
}
/*QUAKED trap_death_fireball (1 0.3 0) (0 0 0) (16 16 16)
-------------------------FIELDS-------------------------
.wait = How long to wait between firings (default 0.5)
.dmg = How much damage to do with each shot (default 10)
--------------------------------------------------------
*/
void () trap_death_fireball =
{
precache_sound("imp/fireball.wav");
precache_model("models/drgnball.mdl");
if(!self.wait)
self.wait=0.5;
if(!self.dmg)
self.dmg=10;
self.use = trap_death_fireball_wait;
};

970
dthhorse.hc Normal file
View File

@ -0,0 +1,970 @@
/*
* $Header: /HexenWorld/Siege/dthhorse.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\monsters\RdrDeath\Horse\
==============================================================================
*/
// For building the model
$cd Q:\art\models\monsters\RdrDeath\Horse\Final
$origin 0 0 0
$base base skin
$skin skin
$flags 0
// Horse frames
$frame Hgall1 Hgall2 Hgall3 Hgall4 Hgall5
$frame Hgall6 Hgall7 Hgall8 Hgall9 Hgall10
$frame Hgall11 Hgall12
$framevalue 0
// Rider Frames
$frame Rgall1 Rgall2 Rgall3 Rgall4 Rgall5
$frame Rgall6 Rgall7 Rgall8 Rgall9 Rgall10
$frame Rgall11 Rgall12
//
$frame Rsickl1 Rsickl2 Rsickl3 Rsickl4 Rsickl5
$frame Rsickl6 Rsickl7 Rsickl8 Rsickl9 Rsickl10
$frame Rsickl11 Rsickl12
float death_color[12] =
{
15,
14,
13,
12,
10,
8,
6,
5,
7,
10,
13,
0
};
/* 15,
13,
11,
9,
7,
5,
3,
1,
5,
10,
12,
0
*/
float death_start[1] =
{
$Hgall1
};
float death_end[1] =
{
$Hgall12
};
float death_speed[1] =
{
12
};
// Array to align frames
float DeathRiderFrames[4] =
{
$Rgall1, // Animation for gallop
$Rsickl1, // Animation for attack #1
$Rsickl8, // Attack Frame 1
$Rsickl9 // Attack Frame 2
};
float DH_STAGE_NORMAL = 0;
float DH_STAGE_ATTACK1 = 4;
float DH_STAGE_ATTACK2 = 8;
float DH_STAGE_ATTACK3 = 16;
void die_out ()
{
if(self.owner.cnt>0)
self.owner.cnt -= 1;
sound(self,CHAN_BODY,"death/fout.wav",1,ATTN_NORM);
remove(self);
}
void circle_of_fire ()
{
self.angles_y+=15;
if(self.angles_y>360)
self.angles_y-=360;
if (self.dmg >= 80)
{
self.think=die_out;
thinktime self : 4.2;
}
else
{
setorigin(self,self.o_angle-'0 0 76');
self.dmg+=3.33;
T_RadiusDamage(self,self.owner,self.dmg/3,self.owner);
makevectors(self.angles);
setorigin(self,self.o_angle+v_forward*100);
SpawnMummyFlame();
self.think=circle_of_fire;
thinktime self : 0.05;
}
}
void go_boom()
{
sound (newmis, CHAN_AUTO, "weapons/expsmall.wav", 1, ATTN_NORM);
BecomeExplosion(CE_FLOOR_EXPLOSION);
}
void fire_circ_hit ()
{
self.touch=SUB_Null;
self.solid=SOLID_NOT;
self.movetype=MOVETYPE_NONE;
self.effects=EF_NODRAW;
self.angles='0 0 0';
sound(self,CHAN_VOICE,"eidolon/flamend.wav",1,ATTN_NORM);
sound(self,CHAN_BODY,"misc/fburn_bg.wav",1,ATTN_NORM);
if(other.takedamage)
{
setorigin(self,other.origin+'0 0 100');
self.angles_y=other.angles_y;
}
self.o_angle=self.origin;
self.ideal_yaw=self.angles_y;
newmis=spawn();
newmis.owner = self.owner;
traceline(self.origin,self.origin-'0 0 600',TRUE,self);
setorigin(newmis,trace_endpos);
newmis.think=go_boom;
thinktime newmis : 0;
self.dmg=0;
self.think=circle_of_fire;
thinktime self : 0;
}
void firecirc_fall_think()
{
if (self.lifetime < time || vlen(self.enemy.origin - self.origin) < 40)
{
other=self.enemy;
self.think=self.touch;
thinktime self : 0;
return;
}
HomeThink();
self.angles=vectoangles(self.velocity);
AdvanceFrame(0,9);
self.think = firecirc_fall_think;
thinktime self : 0.1;
}
void drop_fire_circ ()
{
self.cnt += 1;
self.attack_finished = time + 10;
if(!self.enemy.flags2&FL_ALIVE)
self.enemy=find(world,classname,"player");
if(!self.enemy)
return;
sound (self, CHAN_WEAPON, "death/dthfire.wav", 1, ATTN_NONE);
Create_Missile(self,self.origin + v_forward*4 + v_right * 10 + v_up * 36,
self.movechain.enemy.origin+self.movechain.enemy.view_ofs + self.movechain.size+'0 0 30',"models/fireball.mdl","circfire",0,700,fire_circ_hit);
newmis.enemy=newmis.lockentity=self.enemy;
newmis.movetype=MOVETYPE_FLYMISSILE;
newmis.speed=700; //Speed
newmis.turn_time=0.5; //Lower the number, tighter the turn
newmis.lifetime = time + 3;
newmis.think=firecirc_fall_think;
newmis.owner = self;
thinktime newmis : 0;
}
void bone_think(void)
{
remove(self);
}
void bone_touch(void)
{
self.flags (-) FL_ONGROUND;
if (self.classname == "b4" || self.classname == "b5")
remove(self);
if (self.count)
remove(self);
self.avelocity_x /= 2;
self.avelocity_y /= 2;
self.avelocity_z /= 2;
if (self.classname == "b6")
self.velocity_z /= 2;
else
self.velocity_z /= 4;
particle4(self.origin + '0 0 10', random(20), 256+random(80, 95), PARTICLETYPE_GRAV, random(10));
self.think = chunk_death;
thinktime self : 0.1;
T_Damage(other, self, self.owner, random(1,3));
}
void generate_bone(void)
{
entity bone;
float chance,c2;
vector place;
bone = spawn();
bone.owner = self.owner;
bone.solid = SOLID_BBOX;
bone.movetype = MOVETYPE_BOUNCE;
chance = self.enemy.angles_y + random(-50,50);
c2 = random(170,250);
place_x = c2 * cos(chance);
place_y = c2 * sin(chance);
place_z = -10;
place += self.maxs;
bone.avelocity = randomv('-400 -400 -400', '400 400 400');
chance = random();
if (chance < 0.1) // rib
{
setmodel(bone,"models/boss/bone1.mdl");
bone.classname = "b1";
}
else if (chance < 0.2) // femer?
{
setmodel(bone,"models/boss/bone2.mdl");
bone.classname = "b2";
}
else if (chance < 0.3) // skull
{
setmodel(bone,"models/boss/bone6.mdl");
bone.classname = "b6";
}
else if (chance < 0.6) // Small piece
{
setmodel(bone,"models/boss/bone4.mdl");
bone.classname = "b4";
}
else // Sharp peice
{
setmodel(bone,"models/boss/bone5.mdl");
bone.classname = "b5";
bone.avelocity = '0 0 0';
}
setsize(bone, '0 0 0', '0 0 0');
setorigin(bone, place);
place = self.enemy.origin - bone.origin;
place_z = 0;
place = normalize(place);
place *= random(200,280);
place_z = random(-400, -600);
bone.velocity = place;
if (random() < 0.8)
self.count = 1;
bone.netname="deathbone";
bone.touch = bone_touch;
bone.think = bone_think;
thinktime bone : 5;
}
void bones_think(void)
{
if (time > self.monster_duration)
{
if(self.owner.cnt>0)
self.owner.cnt -= 1;
remove(self);
return;
}
thinktime self : 0.1;
traceline(self.enemy.origin,self.enemy.origin + '0 0 999', 1, self.enemy);
self.maxs = trace_endpos;
traceline(self.enemy.origin,self.enemy.origin - '0 0 999', 1, self.enemy);
self.mins = trace_endpos;
generate_bone();
if (random() < 0.8)
generate_bone();
if (random() < 0.5)
generate_bone();
}
void death_bones(void)
{
entity dr;
sound (self, CHAN_BODY, "death/dthlaugh.wav", 1, ATTN_NONE);
dr = spawn();
dr.owner = self.owner;
dr.solid = SOLID_NOT;
dr.movetype = MOVETYPE_NONE;
dr.effects = EF_NODRAW;
dr.monster_duration = time + random(4,6);
dr.enemy = self.enemy;
dr.think = bones_think;
thinktime dr : HX_FRAME_TIME;
}
void death_missile_die(void)
{
if(self.owner.cnt>0)
self.owner.cnt -= 1;
CreateRedCloud (self.origin,'0 0 0',HX_FRAME_TIME);
remove(self.trigger_field.trigger_field);
remove(self.trigger_field);
remove(self);
}
void death_missile_touch(void)
{
remove(self.trigger_field.trigger_field);
remove(self.trigger_field);
if (other.classname != "player")
{//FIXME: temp effect
if(self.owner.cnt>0)
self.owner.cnt -= 1;
MultiExplode();
return;
}
death_bones();
remove(self);
}
void death_missile_think(void)
{
//float diff,adjust;
if(self.lifetime<=time)
{
remove(self.trigger_field.trigger_field);
remove(self.trigger_field);
remove(self);
}
else
{
thinktime self : 0.1;
self.trigger_field.trigger_field.origin = self.trigger_field.origin;
self.trigger_field.trigger_field.angles = self.trigger_field.angles;
self.trigger_field.origin = self.wallspot;
self.trigger_field.angles = self.o_angle;
self.o_angle=self.angles;
self.wallspot=self.origin;
HomeThink();
self.angles=vectoangles(self.velocity);
}
/*
if (self.lifetime < time)
{
self.th_die();
return;
}
self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
self.count += 9;
if (self.count > 360)
self.count = -360;
adjust = sin(self.count) * 20;
self.trigger_field.trigger_field.origin = self.trigger_field.origin;
self.trigger_field.trigger_field.angles = self.trigger_field.angles;
self.trigger_field.origin = self.origin;
self.trigger_field.angles = self.angles;
ChangeYaw();
walkmove(self.angles_y + adjust, 25, TRUE);
if (trace_ent)
{
other = trace_ent;
death_missile_touch();
}
diff = self.enemy.origin_z - self.origin_z + self.enemy.view_ofs_z;
if (diff > 10)
diff = 10;
else if (diff < -10)
diff = -10;
diff += adjust / 4;
movestep(0,0,diff,FALSE);
*/
}
void death_missile_2_touch(void)
{
float damg;
if(self.owner.cnt>0)
self.owner.cnt -= 1;
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
damg = random(4,8);
T_Damage (other, self, self.owner, damg );
self.origin = self.origin - 8 * normalize(self.velocity) - '0 0 40';
sound (self, CHAN_WEAPON, "weapons/explode.wav", 1, ATTN_NORM);
CreateRedSpark (self.origin);
remove(self);
}
void death_missile_2_think (void)
{
if (self.lifetime < time || !self.enemy.flags2 & FL_ALIVE)
{
if(self.owner.cnt>0)
self.owner.cnt -= 1;
sound (self, CHAN_WEAPON, "weapons/explode.wav", 1, ATTN_NORM);
CreateRedSpark (self.origin);
remove(self);
}
else
{
HomeThink();
self.angles = vectoangles(self.velocity);
self.think=famine_missile_think;
thinktime self : 0.1;
}
}
void death_missile_2(float dir)
{
entity newmis;
vector diff;
if(!self.enemy.flags2&FL_ALIVE)
self.enemy=find(world,classname,"player");
if(!self.enemy)
return;
self.cnt += 1;
self.attack_finished = time + 7;
newmis = spawn ();
newmis.enemy=newmis.lockentity=self.enemy;
newmis.owner = self;
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_BBOX;
setmodel (newmis, "models/famshot.mdl");
setsize (newmis, '0 0 0', '0 0 0');
setorigin (newmis, self.origin + '0 0 120');
newmis.angles = self.angles;
makevectors(self.angles);
// if (infront(self.enemy))
diff = v_forward * 16;
// else
// diff = v_forward * -16;
newmis.velocity = normalize(diff);
newmis.angles = vectoangles(newmis.velocity);
if (dir == 0)
newmis.angles_y -= 25;
else if (dir == 2)
newmis.angles_y += 25;
makevectors (newmis.angles);
newmis.velocity = normalize(v_forward);
if (dir ==1)
newmis.speed=800; //Speed
else
newmis.speed=700; //Speed
newmis.classname = "deathmissile";
newmis.angles = vectoangles(newmis.velocity);
newmis.veer=FALSE; //No random wandering
newmis.turn_time=2.25; //Lower the number, tighter the turn
newmis.lifetime = time + 3;
newmis.think=famine_missile_think;
thinktime newmis : 0.1;
newmis.touch = famine_missile_touch;
}
void death_missile(void)
{
entity dm;
if(!self.enemy.flags2&FL_ALIVE)
self.enemy=find(world,classname,"player");
if(!self.enemy)
return;
self.cnt += 1;
self.attack_finished = time + 10;
dm = spawn();
dm.enemy=dm.lockentity=self.enemy;
dm.solid = SOLID_BBOX;
dm.movetype = MOVETYPE_FLYMISSILE;
dm.classname = "death_missile";
// dm.flags (+) FL_FLY;
dm.drawflags (+) DRF_TRANSLUCENT | MLS_POWERMODE;
dm.enemy = self.enemy;
// dm.yaw_speed = 8;
dm.takedamage = DAMAGE_YES;
dm.health = 10;
dm.owner = self;
dm.scale = 1.5;
setmodel(dm,"models/boss/bone3.mdl");
setorigin(dm, self.movechain.origin+self.movechain.size);
dm.think = death_missile_think;
dm.touch = death_missile_touch;
dm.th_die = death_missile_die;
dm.lifetime = time + 5;
dm.speed=500;
dm.veer=50; //some random wandering
dm.turn_time=2; //Lower the number, tighter the turn
setsize(dm,'0 0 0', '0 0 0');
thinktime dm : HX_FRAME_TIME;
dm.trigger_field = spawn();
dm = dm.trigger_field;
dm.classname = "death_missile";
dm.solid = SOLID_NOT;
dm.movetype = MOVETYPE_FLYMISSILE;
dm.flags (+) FL_FLY;
dm.drawflags (+) DRF_TRANSLUCENT | MLS_POWERMODE | SCALE_TYPE_UNIFORM;
dm.enemy = self.enemy;
dm.owner = dm.trigger_field;
dm.lifetime = time + 5;
setmodel(dm,"models/boss/bone3.mdl");
setsize(dm,'0 0 0', '0 0 0');
setorigin(dm, self.origin);
dm.trigger_field = spawn();
dm = dm.trigger_field;
dm.classname = "death_missile";
dm.solid = SOLID_NOT;
dm.movetype = MOVETYPE_FLYMISSILE;
dm.flags (+) FL_FLY;
dm.drawflags (+) DRF_TRANSLUCENT | MLS_POWERMODE | SCALE_TYPE_UNIFORM;
dm.enemy = self.enemy;
dm.owner = dm.trigger_field;
dm.scale = .5;
dm.lifetime = time + 5;
setmodel(dm,"models/boss/bone3.mdl");
setsize(dm,'0 0 0', '0 0 0');
setorigin(dm, self.origin);
sound (dm, CHAN_BODY, "ambience/moan1.wav", 1, ATTN_NORM);
}
void create_deathrider(entity horse)
{
entity rider;
rider = spawn();
rider.monsterclass = CLASS_BOSS;
rider.solid = SOLID_NOT;
rider.movetype = MOVETYPE_NONE;
rider.origin = horse.origin;
rider.angles = self.angles;
setmodel (rider, "models/boss/dthrider.mdl");
rider.skin = 0;
horse.movechain = rider;
self.cnt = 0;
rider.flags (+) FL_MOVECHAIN_ANGLE;
}
void ghost_tint ()
{
if(self.cnt<12)
{
if(!self.cnt)
{
self.touch=SUB_Null;
self.effects=EF_NODRAW;
}
self.enemy.colormap = self.enemy.movechain.colormap = 2*16+
death_color[self.cnt];
self.cnt+=1;
thinktime self : 0.05;
}
else
{
self.enemy.colormap = self.enemy.movechain.colormap = 0;
remove(self);
}
}
void ghost_touch ()
{
if(other.classname!="rider_death"||self.lifespan>time)
return;
else
{
if(!self.owner.flags2&FL_ALIVE)
self.owner.enemy=other;
sound(self.enemy,CHAN_VOICE,"death/victory.wav",1,ATTN_NONE);
self.think=ghost_tint;
thinktime self : 0;
}
}
void ghost_think ()
{
if(self.scale<=2.4)
self.scale+=0.1;
if(self.speed<333)
self.speed+=7;
HomeThink();
self.flags(-)FL_ONGROUND;
self.angles=vectoangles(self.velocity);
thinktime self : 0.1;
}
void spawn_ghost (entity attacker)
{
float r;
newmis=spawn();
newmis.movetype=MOVETYPE_NOCLIP;
newmis.solid=SOLID_TRIGGER;
newmis.classname=newmis.netname="Booberry";
newmis.owner=self;
newmis.drawflags(+)MLS_POWERMODE|DRF_TRANSLUCENT;
newmis.scale=0.5;
newmis.enemy=newmis.lockentity=attacker;
self.enemy=newmis;
newmis.flags2(+)FL_ALIVE;
newmis.veer=100;
newmis.speed=100;
newmis.lifespan=time+7;
newmis.turn_time=2;
newmis.hoverz=TRUE;
newmis.touch=ghost_touch;
newmis.think=ghost_think;
makevectors(self.angles);
newmis.velocity=v_forward*150+v_up*30;
newmis.angles=vectoangles(newmis.velocity);
newmis.think=ghost_think;
thinktime newmis : 1;
setmodel(newmis,"models/booberry.mdl");
setsize(newmis,'-8 -8 -8','8 8 8');
newmis.hull=HULL_POINT;
setorigin(newmis,(self.absmin+self.absmax)*0.5);
r=random();
if(r<0.33)
newmis.noise="ambience/moan1.wav";
else if(r<0.66)
newmis.noise="ambience/moan2.wav";
else
newmis.noise="ambience/moan3.wav";
sound(newmis,CHAN_AUTO,newmis.noise,1,ATTN_NONE);
}
void deathhorse_move(void)
{
float retval, r;
if (self.velocity)
self.velocity = self.velocity * 0.9;
if (coop)
checkenemy();
if(!self.enemy.flags2&FL_ALIVE&&self.enemy!=world)
self.enemy=world;
self.think = deathhorse_move;
thinktime self : HX_FRAME_TIME;
retval = AdvanceFrame(death_start[self.rider_gallop_mode],death_end[self.rider_gallop_mode]);
self.movechain.angles = self.angles;
self.movechain.origin = self.origin;
if (!self.path_current)
{
riderpath_init();
}
if (self.frame == 4 || self.frame == 6 || self.frame == 8 || self.frame == 10)
{
r = random();
if (r < 0.2)
sound (self, CHAN_BODY, "death/clop.wav", 0.3, ATTN_NORM);
else if (r < 0.4)
sound (self, CHAN_BODY, "death/clop1.wav", 0.3, ATTN_NORM);
else if (r < 0.6)
sound (self, CHAN_BODY, "death/clop2.wav", 0.3, ATTN_NORM);
else
sound (self, CHAN_BODY, "death/clop3.wav", 0.3, ATTN_NORM);
}
riderpath_move(self.speed);
if (retval == AF_BEGINNING)
{
retval = fabs(self.rider_y_change);
// Force a new gallop frame in
self.frame = death_start[self.rider_gallop_mode];
self.monster_stage = DH_STAGE_NORMAL;
if (self.rider_gallop_mode == 0)
{
if (!self.enemy)
{
self.enemy = find(world, classname, "player");
while(!self.enemy.flags2&FL_ALIVE&&self.enemy!=world)
self.enemy = find(self.enemy, classname, "player");
}
if (self.enemy != world && random() < 0.7+skill/10&&!self.cnt)
{
r = random();
if (r < 0.3)
self.monster_stage = DH_STAGE_ATTACK1;
else if (r < 0.6)
self.monster_stage = DH_STAGE_ATTACK3;
else
self.monster_stage = DH_STAGE_ATTACK2;
}
}
}
if (self.cnt && self.attack_finished < time) self.cnt = 0;
if (self.monster_stage && self.enemy.flags2 & FL_ALIVE)
{
if (self.rider_gallop_mode == 0)
{
if (self.monster_stage == DH_STAGE_ATTACK1)
{
self.movechain.frame = DeathRiderFrames[1] +
(self.frame - death_start[self.rider_gallop_mode]);
if (self.movechain.frame == DeathRiderFrames[2])
{
sound (self, CHAN_WEAPON, "death/dthfire.wav", 1, ATTN_NONE);
death_missile();
}
}
else if (self.monster_stage == DH_STAGE_ATTACK2)
{
self.movechain.frame = DeathRiderFrames[1] +
(self.frame - death_start[self.rider_gallop_mode]);
if (self.movechain.frame == 18)
sound (self, CHAN_WEAPON, "death/shot.wav", 1, ATTN_NORM);
if (self.movechain.frame == 18 || self.movechain.frame == 20 || self.movechain.frame == 22)
death_missile_2(FALSE);
}
else if (self.monster_stage == DH_STAGE_ATTACK3)
{
self.movechain.frame = DeathRiderFrames[1] +
(self.frame - death_start[self.rider_gallop_mode]);
if (self.movechain.frame == DeathRiderFrames[2])
drop_fire_circ();
}
self.colormap = self.movechain.colormap =
death_color[self.frame - death_start[self.rider_gallop_mode]];
if(self.colormap)
{
self.colormap+=8*16;
self.movechain.colormap+=8*16;
}
}
}
else
{
self.movechain.frame = DeathRiderFrames[self.rider_gallop_mode] +
(self.frame - death_start[self.rider_gallop_mode]);
}
// make sure we use the last attack frame before we go out of the mode
if (retval == AF_END)
{
self.monster_stage = DH_STAGE_NORMAL;
}
if (fabs(death_speed[self.rider_gallop_mode] - self.speed) < 0.2)
self.speed = death_speed[self.rider_gallop_mode];
else if (death_speed[self.rider_gallop_mode] > self.speed)
self.speed += 0.2;
else
self.speed -= 0.2;
}
/*QUAKED rider_death (1 0 0) (-55 -55 -24) (55 55 100) TRIGGER_WAIT
Death rider monster. You must place rider_path entites
on the map. The rider will first proceed to the
rider_path point with a path_id of 1.
-------------------------FIELDS-------------------------
map: next map to go to when you kill the rider
target: start spot on the next map
--------------------------------------------------------
*/
void rider_death(void)
{
if (deathmatch)
{
remove(self);
return;
}
precache_model2 ("models/boss/dthhorse.mdl");
precache_model2 ("models/boss/dthrider.mdl");
precache_model2 ("models/famshot.mdl");
precache_model2 ("models/boss/bone1.mdl");
precache_model2 ("models/boss/bone2.mdl");
precache_model2 ("models/boss/bone3.mdl");
precache_model2 ("models/boss/bone4.mdl");
precache_model2 ("models/boss/bone5.mdl");
precache_model2 ("models/boss/bone6.mdl");
precache_model2 ("models/mumshot.mdl");
precache_model2 ("models/booberry.mdl");
precache_sound2 ("mummy/mislfire.wav");
precache_sound2 ("eidolon/flamend.wav");
precache_sound2 ("misc/fburn_bg.wav");
precache_sound2 ("death/fout.wav");
precache_sound2 ("death/dthdie.wav");
precache_sound2 ("death/dthfire.wav");
precache_sound2 ("death/victory.wav");
precache_sound2 ("death/dthlaugh.wav");
precache_sound2 ("death/clop.wav");
precache_sound2 ("death/clop1.wav");
precache_sound2 ("death/clop2.wav");
precache_sound2 ("death/clop3.wav");
precache_sound2 ("death/shot.wav");
precache_sound2 ("ambience/moan1.wav");
precache_sound2 ("ambience/moan2.wav");
precache_sound2 ("ambience/moan3.wav");
rider_init();
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_FLY;
self.thingtype = THINGTYPE_FLESH;
self.yaw_speed = 4;
setmodel (self, "models/boss/dthhorse.mdl");
self.hull = HULL_POINT;
self.skin = 0;
self.flags (+) FL_FLY|FL_MONSTER;
self.flags2(+) FL_ALIVE;
self.monsterclass = CLASS_BOSS;
setsize (self, '-55 -55 -24', '55 55 100');
self.health = 3500;
self.experience_value = 1000;
self.dflags = 0;
self.rider_gallop_mode = 0;
self.speed = death_speed[self.rider_gallop_mode];
self.rider_path_distance = 100;
self.monster_stage = DH_STAGE_NORMAL;
self.mass = 30000;
create_deathrider(self);
self.noise = "death/dthdie.wav";
self.delay = 3;
self.th_save = deathhorse_move;
self.think = multiplayer_health;
thinktime self : 1;
}

1303
eidolon.hc Normal file

File diff suppressed because it is too large Load Diff

358
enforcer.hc Normal file
View File

@ -0,0 +1,358 @@
/*
* $Header: /HexenWorld/Siege/Enforcer.hc 4 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
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);
WriteByte (MSG_BROADCAST, 1);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
}
remove(self);
};
void(vector org, vector vec) LaunchLaser =
{
local vector vec;
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 ();
};
/*QUAK-ED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) Ambush
-----------------------FIELDS-------------------------
--------------------------------------------------------
*/
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();
};

780
entity.hc Normal file
View File

@ -0,0 +1,780 @@
//**************************************************************************
//**
//** entity.hc
//**
//** $Header: /HexenWorld/Siege/entity.hc 33 6/01/98 2:49a Mgummelt $
//**
//**************************************************************************
// SYSTEM FIELDS -----------------------------------------------------------
// (entvars_t C structure, *** = don't modify in HexC) ---------------------
// *** Model index in the precached list.
.float modelindex;
// *** Origin + mins / maxs
.vector absmin, absmax;
// Local time for entity.
.float ltime;
.float lastruntime; // *** to allow entities to run out of sequence
.float movetype;
.float solid;
// ***
.vector origin;
// ***
.vector oldorigin;
.vector velocity;
.vector angles;
.vector avelocity;
// Temp angle adjust from damage or recoil.
.vector punchangle;
// Spawn function.
.string classname;
.string model;
.float frame;
.float skin;
.float effects;
.float scale;
.float drawflags;
.float abslight;
// Bounding box extents relative to origin.
.vector mins, maxs;
// maxs - mins
.vector size;
// Which clipping hull to use.
.float hull;
.void() touch;
.void() use;
.void() think;
// For doors or plats, called when can't push other.
.void() blocked;
.float nextthink;
.entity groundentity;
// Stats
.float stats_restored;
.float frags;
.float weapon;
.string weaponmodel;
.float weaponframe;
.float health; // HP
.float max_health; // Max HP
.float playerclass; // 0 (none), 1-6
.float next_playerclass; // 0 (none), 1-6
.float has_portals; // 1 if user has portals expansion
.float bluemana; // Blue mana
.float greenmana; // Green mana
.float max_mana; // Maximum amount of mana for current class / level
.float armor_amulet; // Health of amulet armor
.float armor_bracer; // Health of bracer armor
.float armor_breastplate; // Health of breastplate armor
.float armor_helmet; // Health of helmet armor
.float level; // Player level
.float intelligence; // Player INT
.float wisdom; // Player WIS
.float dexterity; // Player DEX
.float strength; // Player STR
.float experience; // Accumulated experience points
.float ring_flight; // Health of rings 0 - 100
.float ring_water; //
.float ring_turning; //
.float ring_regeneration; //
.float haste_time; // When hast is depleted
.float tome_time; // When tome of power is depleted
.string puzzle_inv1; // Puzzle piece inventory...
.string puzzle_inv2;
.string puzzle_inv3;
.string puzzle_inv4;
.string puzzle_inv5;
.string puzzle_inv6;
.string puzzle_inv7;
.string puzzle_inv8;
// Experience this entity is worth when killed or used.
.float experience_value;
// Bit flags.
.float items;
.float takedamage;
.entity chain;
.float deadflag;
// Add to origin to get eye point.
.vector view_ofs;
// Fire.
.float button0;
// Use.
.float button1;
// Jump.
.float button2;
// Weapon changes, misc.
.float impulse;
.float fixangle;
// View / targeting angle for players.
.vector v_angle;
// Calculated pitch angle for slopes.
.float idealpitch;
.float idealroll;
.float hoverz;
.string netname;
.entity enemy;
.float flags;
.float flags2;
.float artifact_flags;
.float colormap;
.float team;
.float light_level;
.float wpn_sound;
.float targAng;
.float targPitch;
.float targDist;
// Don't back up.
.float teleport_time;
// Save this fraction of incoming damage.
.float armortype;
.float armorvalue;
// 0 = not in, 1 = feet, 2 = waist, 3 = eyes.
.float waterlevel;
// A contents value.
.float watertype;
// 0 = not in a friction entity, else the friction of the entity.
.float friction;
.float ideal_yaw;
.float yaw_speed;
//rj.entity aiment;
// A pathentity or an enemy. also used by axeblade for it's tail
.entity goalentity;
.float spawnflags;
// The target of this entity.
.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;
// Who launched a missile.
.entity owner;
// Mostly or doors, but also used for waterjump.
.vector movedir;
// Trigger messages.
.float message;
// Either a CD track number or a sound number.
.float soundtype;
// Contains names of .WAVs to play.
.string noise, noise1, noise2, noise3;
.float rings; // Which rings hero has
.float rings_active; // Shows which rings have been activated
.float rings_low; // Shows which rings are low on power
.float artifacts; // Which artifact hero has
.float artifact_active; // Shows which artifact have been activated
.float artifact_low; // Shows which artifact is running out
.float hasted; // % of normal speed player has been hasted
.float inventory; // Which item is currently chosen?
//rj.float ordr_cnt; // Number of items in order
// make sure you change references to:
// max_ammo2() DropBackpack() BackpackTouch()
// when adding or changing inventory fields
.float cnt_torch; // Count of inventory item - Torch
.float cnt_h_boost; // Count of inventory item - Health Boost
.float cnt_sh_boost; // Count of inventory item - Super Health Boost
.float cnt_mana_boost; // Count of inventory item - Mana Boost
.float cnt_teleport; // Count of inventory item - Teleport
.float cnt_tome; // Count of inventory item - Tome of Power
.float cnt_summon; // Count of inventory item - Summon
.float cnt_invisibility; // Count of inventory item - Invisibility
.float cnt_glyph; // Count of inventory item - Glyph of the Ancients
.float cnt_haste; // Count of inventory item - Haste
.float cnt_blast; // Count of inventory item - Blast Radius
.float cnt_polymorph; // Count of inventory item - Polymorph
.float cnt_flight; // Count of inventory item - Flight
.float cnt_cubeofforce; // Count of inventory item - Cube of Force
.float cnt_invincibility; // Count of inventory item - Invincibility
.entity cameramode;
.entity movechain;
.void() chainmoved;
.float string_index; // Index used for global string table
.float gravity; //Gravity, duh
.float siege_team; //ST_ATTACKER or ST_DEFENDER
// END SYSTEM FIELDS -------------------------------------------------------
// Flag the compiler.
void end_sys_fields;
// World fields
.string wad;
.string map;
.float worldtype; // 0=medieval 1=metal 2=base
.string killtarget;
// QuakeEd fields
.float light_lev; // Not used by game, but parsed by light util
.float style;
// Monster AI, doubled over for player
.void() th_stand;
.void() th_walk; //player_crouch_move
.void() th_run;
.void() th_missile; //player_attack
.void() th_melee;
.void(entity attacker, float damage) th_pain;
.void() th_die;
.void() th_save; // In case you need to save/restore a thinking state
// Mad at this player before taking damage.
.entity oldenemy;
.float speed;
.float lefty;
.float search_time;
.float attack_state;
// Monster AI stuff
.float monster_stage;
.float monster_duration; // Stage duration
.float monster_awake;
.float monster_check;
.vector monster_last_seen;
// because of how physics works, certain calls to the touch
// function of other entities involving the player do not
// allow you to adjust the velocity, so you have to do it
// outside of the inner physics stuff
.vector adjust_velocity;
.union
{ // Entity type specific stuff
struct // player stuff
{
float splash_time; // When to generate the next splash
float camera_time; //
float weaponframe_cnt; //
float attack_cnt; // Shows which attack animation can be used
float ring_regen_time; // When to add the next point of health
float ring_flight_time; // When to update ring of flight health
float ring_water_time; // When to update ring of waterbreathing health
float ring_turning_time;// When to update ring of turning health
float super_damage; // Player does this much more damage (Like Crusader with Special Ability #2)
float super_damage_low; // Flag the super damage is low
float puzzles_cheat; // Allows player past puzzle triggers
float camptime; // Amount of time player has been motionless
float crouch_time; // Next time player should run crouch subroutine
float crouch_stuck; // If set this means the player has released the crouch key in an area too small to uncrouch in
float divine_time; // Amount of time flash happens in divine intervention
float act_state; // Anim info
float raven_cnt; // Number of raven's this guys has in the world
float newclass; // If doing a quick class change
float poweredFlags; // Which weapons are available for being powered up in tomeMode 2
float last_use_time; // when i last performed operation (inv. use, sheepify, suicide) that shouldn't rapid-fire.
float jail_time;
};
struct
{ // Fallen Angel
float fangel_SaveFrame;
float fangel_Count;
float shoot_cnt;
float shoot_time; // Time of last shot
float z_movement;
float z_duration;
float drop_time;
};
struct
{ // Fallen Angel's Spell
float spell_angle;
};
struct
{ // Hydra
float hydra_FloatTo;
float hydra_chargeTime;
};
struct
{ // Spider
float spiderType; // SPIDER_? types
float spiderActiveCount; // Tallies "activity"
float spiderGoPause; // Active/pause threshold
float spiderPauseLength; // Pause duration in frames
float spiderPauseCount; // Tallies paused frames
};
struct
{ // Scorpion
float scorpionType; // SCORPION_? types
float scorpionRest; // Resting state counter
float scorpionWalkCount; // Counts walking frames
};
struct
{ // Golem
float golemSlideCounter;
float golemBeamDelay;
float golemBeamOff1;
float golemBeamOff2;
};
struct
{ // Imp
float impType; // IMP_? types
};
struct
{ // Mummy
float parts_gone;
float mummy_state;
float mummy_state_time;
};
struct
{ // Artifacts
float artifact_respawn; // Should respawn?
float artifact_ignore_owner_time;
float artifact_ignore_time;
float artifact_name;
};
struct
{ // Rider path
float next_path_1;
float next_path_2;
float next_path_3;
float next_path_4;
float path_id;
float next_path_5;
float next_path_6;
};
struct
{ // Rider triggers
float rt_chance;
};
struct
{ // Rider data
float rider_gallop_mode;
float rider_last_y_change;
float rider_y_change;
float rider_death_speed;
float rider_path_distance;
float rider_move_adjustment;
};
struct
{ // War rider axe
float waraxe_offset;
float waraxe_horizontal;
float waraxe_track_inc;
float waraxe_track_limit;
float waraxe_max_speed;
float waraxe_max_height;
};
struct
{ // War rider's quake
float wrq_effect_id;
float wrq_radius;
float wrq_count;
};
struct
{ // Rider's beam
float beam_angle_a;
float beam_angle_b;
float beam_max_scale;
float beam_direction;
float beam_speed;
};
struct
{ // Used by smoke generator
float z_modifier;
};
struct
{
float last_health; // Used by bell entity
};
struct // For raven staff Ravens
{
float idealpitch;
float pitchdowntime;
float searchtime; // Amount of time bird has been searching
float next_action; // Next time to take action
float searchtime; // When search was first started
float damage_max; // Amount of damage each raven can do before it has to leave
float raven_effect_id; //effect id number
entity raven_owner; //owner field can get modified by refections
vector last_vel; // last updated velocity, tells when change needed
};
struct
{ // fish
float fish_speed;
float fish_leader_count;
};
struct
{ // Used by particle explosion entity.
float exploderadius;
};
struct
{ // Skull missiles from skullwizard
float scream_time;
};
struct
{
float attack_cnt;
};
struct
{ // Pestalance's Hive
float beginframe;
};
struct
{ // Soul spheres
float sound_time;
};
struct
{ // Cube of force
float shot_cnt; // Number of shots the force cube has shot
};
struct
{ // xbow bolts
entity firstbolt; // maintain list of bolts that use same effect, so it can be removed when all bolts are gone
entity nextbolt;
float boltnum; // when i tell effect to change, it has to know which bolt changes
float xbo_effect_id;
vector xbo_startpos;//save where bolt is fired from; since bolts don't accelerate,
//can just send the distance they travelled instead of ending position
float fusetime;//determine how long tomed bolts wait til exploding when they are shot
float xbo_teleported;//bolt has just been teleported.
};
};
// Once we can do unions above end_sys, have this with the field 'playerclass'
.float monsterclass;
// FIXME: Remove the ring of spell turning and all references to this
.float turn_time;
// Triggers / doors
.string puzzle_piece_1;
.string puzzle_piece_2;
.string puzzle_piece_3;
.string puzzle_piece_4;
.float no_puzzle_msg;
// Puzzle Item
.string puzzle_id;
// More rider stuff that can't be in the union
.entity path_current;
.vector oldangles;
.string lastweapon; // Weapon model player had before changing to camera mode
.float lifetime;
.float lifespan;
.float walkframe;
.float wfs; // Weapon frame state
.float attack_finished;
.float pain_finished;
.float invisible_finished;
.float invincible_time, invincible_sound;
.float invisible_time;
.float super_damage_time;
// 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 show_hostile;
// Player jump flag.
.float jump_flag;
// Player swimming sound flag.
.float swim_flag;
// When time > air_finished, start drowning.
.float air_finished;
// Keeps track of the number of bubbles.
.float bubble_count;
// Keeps track of how the player died.
.string deathtype;
// Object stuff.
.string mdl;
.vector mangle; // Angle at start
// Only used by secret door.
.vector oldorigin;
.float t_length, t_width;
// Things color.
.float color;
// Count of things (used by rain entity)
.float counter;
// Can these be made part of a union??
.float plaqueflg; // 0 if not using a plaque, 1 if using a plaque
.vector plaqueangle; // Angle player was facing when the plaque was touched
// Doors, etc.
.vector dest, 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 pathentity;
// Doors.
.float aflag;
.float dmg; // Damage done by door when hit
// Misc flag.
.float cnt;
// What type of thing is this?
.float thingtype;
// Amount of time left on torch.
.float torchtime;
// Next torch think.
.void() torchthink;
// Amount of time left on the super health.
.float healthtime;
// Subs
.void() think1;
.vector finaldest, finalangle;
// For counting triggers
.float count;
.float spawn_health; // Set to >0 to spawn instant health
// Plats/doors/buttons
.float lip;
.float state;
.vector pos1, pos2; // Top and bottom positions
.float height;
// Sounds
//.float waitmin, waitmax;
//.float distance;
//.float volume;
.vector orgnl_mins, orgnl_maxs; // original bounding box
.float veer; //Amount of veer when Veer function called (included in HomeThink Function)
//The higher the number, the more drastic the wander is.
.float homerate;//Turning rate on homing missiles, is used as the nextthink time
//so the lower the number, the tighter thr turn radius.
//From the SpiralThink function, a value of FALSE will
//stop it from randomly homing while spiraling,
//a value of TRUE will allow it to randomly Home, but
//does not effect rate of homing since it only calls
//it randomly.
.float mass; //NOTE: 1 = @18.5 pounds.
//How much they weigh- should be used in all velocity mods
//(pushing, impact, throwing). Used as a divider, so
//the higher the number, the higher the mass, the less
//distance it will go. Make sure it's >0
//Buttons and pressure plates can use this too so that
//if a light object is placed on it, it won't activate
//(but it should be cumulative so that you can stack several
//light objects to increase mass and activate it)
//Also, a light player (featherfall?) could get around
//certain traps?
.float onfire; //A value that, when FALSE means the object is not on
//fire. A greater than zero value indicates how fast
//the thing is burning. The higher the number, the higher
//the damage and the more flames.
.vector o_angle;//Just to remember an old angle or vector
//Player
.float bloodloss;//For the Bleed() function which will remove health
//and add graphic. Set to 666 for beheading death.
.float oldweapon;//For remembering your last weapon, has many uses
//Monsters (and some projectiles)
.entity controller; //What is the owner of this thing, this allows
//it to touch it's owner if you set the owner
//to self.
.float init_modelindex;//initial model index, so you can switch away and back
.string init_model;
//Player Only th_***
.void() th_swim;
.void() th_jump;
.void() th_fly;
.void() th_die1;
.void() th_die2;
.void() th_goredeath;
.void() th_possum; //Monster playing dead
.void() th_possum_up; //Monster getting up from playing dead
.float last_attack; //Used for weapons that go into rest mode after
//a while
.entity shield;
.float frozen; //Can't be a flag, is a counter
.float oldskin;
.void() oldthink;
.void() th_weapon;
.float decap; //To know if was beheaded, not a flag, set to 2 if
//head should explode
.string headmodel;
.void() oldtouch; //These two are for when you're frozen and thaw out
.float oldmovetype;
.float target_scale;
.float scalerate;
.float blizzcount;
.float tripwire_cnt;
.float imp_count;
.vector proj_ofs; //Projectile offset, different from view_ofs.
.string spawnername; //for monster spawner
.entity catapulter;
.float catapult_time;
.float last_onground; //Timer- helps keep track of how long something has been in the air.
.vector pos_ofs; //Position ofset
.vector angle_ofs; //Angle offset
.float safe_time; //How long after a tornado throws you that it cant pick you up again
.float absorb_time; //for 0.3 seconds after crouching, you will absorb 1/2 of your falling damage upon impact
.float mintel; //Monster intelligence- temp since entity.hc was checked out
.vector wallspot; //Last place enemy was seen- for waypoint ai
.vector lastwaypointspot;//explains itself
.entity lockentity; //for waypoint system
.float last_impact; //Last time touch function was called
.float inactive;
.float msg2;
.string msg3;
.string nexttarget; //For target transferral
.float upside_down;
.float lightvalue1;
.float lightvalue2;
.float fadespeed;
.float point_seq; //Waypoint sequence number
.float sheep_time; //How long you will be a sheep for
.float sheep_sound_time;
.float still_time; //How long she's been standing still
.float visibility_offset; //How hard it is to see and aim at entity, from 0 to 1
//0 is totally visible, 1 is invisible
.float check_ok; //For trigger check, instead of re-using aflag
.entity check_chain; //for trigger_check, keeps track of it's targetted entities
.void() th_spawn; //Monster function you spawned with
.float freeze_time;
.float level_frags;
.float visibility;
entity sight_entity; //So monsters wake up other monsters
.entity viewentity;
.float sv_flags; //temp serverflags fix
.float dmgtime;
.float healamount, healtype;
.float anglespeed;
.float angletime;
.float movetime;
.float hit_z;
.float torncount;
.entity path_last;
.float dflags;
.float gameFlags;
.entity targetPlayer;
//MISSION PACK
.float fire_damage;
.float standard_grav;
.float init_exp_val;
.entity credit_enemy;
.string close_target;
//SIEGE
.float cnt_grenades;
.float cnt_arrows;
.float last_time;
.float beast_time;
.float climbing;
.vector climbspot;
.float last_climb;
.float fov_val;
.float zoom_time;
.float fail_chance;
.void() th_init;
.vector init_org;
.string ondeath_target;
.string pain_target;

1
entity2.hc Normal file
View File

@ -0,0 +1 @@

102
eric.hc Normal file
View File

@ -0,0 +1,102 @@
void()trap_fireball_use;
void trap_fireball_wait ()
{
self.use = trap_fireball_use;
self.think=SUB_Null;
self.nextthink=-1;
}
void fireball_think ()
{
particle4(self.origin,3,random(160,176),PARTICLETYPE_FIREBALL,random(10,20));
self.think=fireball_think;
thinktime self : 0.1;
}
void trap_fireball_use ()
{
entity fireball;
vector vec;
float dot;
if(self.spawnflags&1)
{
self.think=trap_fireball_wait;
thinktime self : 0;
}
else
{
self.use=trap_fireball_wait;
self.think = trap_fireball_use;
thinktime self : self.wait;
}
if(self.goalentity)
self.enemy=self.goalentity;
else
self.enemy = find (world, classname, "player");
if((visible(self.enemy)&&self.enemy!=world)||self.goalentity==self.enemy)
{
vec=normalize((self.enemy.absmin+self.enemy.absmax)*0.5-self.origin);
makevectors(self.angles);
dot = v_forward*vec;
if(dot>0.6||self.goalentity==self.enemy)
{
sound (self, CHAN_WEAPON, "imp/fireball.wav", 1, ATTN_NORM);
fireball = spawn ();
fireball.movetype = MOVETYPE_FLYMISSILE;
fireball.solid = SOLID_BBOX;
fireball.speed=1000;
fireball.velocity=vec*fireball.speed;
fireball.touch = fireballTouch;
fireball.dmg=self.dmg;
fireball.owner = self;
fireball.angles = vectoangles (fireball.velocity);
fireball.think = fireball_think;
thinktime fireball : 0.05;
self.last_attack=time;
setmodel (fireball, "models/drgnball.mdl");
setsize (fireball, '0 0 0', '0 0 0');
setorigin (fireball,self.origin);
}
}
}
void locate_first_target ()
{
self.goalentity=find(world,targetname,self.target);
if(!self.goalentity)
dprint("ERROR: Targeted Fireball can't find target\n");
}
/*QUAKED trap_fireball (1 0.3 0) (0 0 0) (16 16 16) TRIGGER_ONLY
New item for QuakeEd
It works! It really works!
If TRIGGER_ONLY is turned on, it will fire once each time it's triggered (used)
otherwise, each time it's used, it's turned on or off.
If it's targetted to something, it will fire at that rather than tracking the player.
-------------------------FIELDS-------------------------
.wait = How long to wait between firings (default 0.5)
.dmg = How much damage to do with each shot (default 10)
--------------------------------------------------------
*/
void () trap_fireball =
{
precache_sound2("imp/fireball.wav");
precache_model2("models/drgnball.mdl");
if(!self.wait)
self.wait=0.5;
if(!self.dmg)
self.dmg=10;
if(self.target)
{
self.think=locate_first_target;
thinktime self : 0.5;
}
self.use = trap_fireball_use;
};

345
explode.hc Normal file
View File

@ -0,0 +1,345 @@
void() CB_BoltStick;
//void FireMeteor (string type);
//void FireAcidBlob (string type);
void()BlowUp=
{
if(self.dmg<2.5)
{
T_RadiusDamage (self, self.owner, self.dmg*100, world);
self.dmg += 0.1;
self.think=BlowUp;
thinktime self : 0.025;
}
else
{
self.think=SUB_Remove;
thinktime self : 0;
}
};
void() SprayFire=
{
local entity fireballblast;
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_FIREBALL);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
multicast(self.origin,MULTICAST_PHS_R);
fireballblast=spawn();
fireballblast.effects (+) EF_NODRAW;
fireballblast.movetype=MOVETYPE_NOCLIP;
fireballblast.owner=self.owner;
fireballblast.classname="fireballblast";
fireballblast.solid=SOLID_NOT;
setsize(fireballblast,'0 0 0','0 0 0');
setorigin(fireballblast,self.origin);
fireballblast.dmg=0.1;
fireballblast.think=BlowUp;
thinktime fireballblast : 0;
remove(self);
};
void SmallExplosion (void)
{
sound(self,CHAN_AUTO,"weapons/explode.wav",0.5,ATTN_NORM);
BecomeExplosion(CE_SM_EXPLOSION);
}
void DarkExplosion ()
{
entity ignore;
if(self.classname=="timebomb")
{
sound(self,CHAN_AUTO,"weapons/explode.wav",1,ATTN_NORM);
ignore=self.enemy;
}
else if(self.classname=="pincer")
{
// sound(self,CHAN_BODY,"weapons/explode.wav",1,ATTN_NORM);
ignore=self.owner;
// ignore = world;
}
else
{
if(self.controller.classname=="multigrenade")
sound(self.controller,CHAN_BODY,"weapons/explode.wav",1,ATTN_NORM);
else
sound(self,CHAN_AUTO,"weapons/explode.wav",1,ATTN_NORM);
ignore=world;
}
T_RadiusDamage (self, self.owner, self.dmg, ignore);
if(self.classname=="minigrenade"&&random()<0.5)
BecomeExplosion(FALSE);
else if(self.classname=="flaming arrow")
{
starteffect(CE_XBOW_EXPLOSION,self.origin);
remove(self);
}
else if (self.classname == "pincer")
{
endeffect(MSG_ALL,self.xbo_effect_id);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_DRILLA_EXPLODE);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
multicast(self.origin,MULTICAST_PHS_R);
remove(self);
}
else
{
starteffect(CE_NEW_EXPLOSION,self.origin);
remove(self);
}
}
void() MultiExplode =
{
float nummeteorites;
//FIXME: For some reason, the light casting effects in Hex2
//are a lot more costly than they were in Quake...
if(self.classname=="stickmine")
{
SprayFire();
return;
}
T_RadiusDamage (self, self.owner, self.dmg, world);
if(self.classname=="meteor"||self.classname=="acidblob")
{
nummeteorites=random(3,10);
if(deathmatch||coop)
{
if(self.classname=="acidblob")
{
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_CHUNK);
WriteCoord(MSG_MULTICAST, self.origin_x);
WriteCoord(MSG_MULTICAST, self.origin_y);
WriteCoord(MSG_MULTICAST, self.origin_z);
WriteCoord(MSG_MULTICAST, 0);
WriteCoord(MSG_MULTICAST, 0);
WriteCoord(MSG_MULTICAST, 300);
WriteByte(MSG_MULTICAST, self.thingtype);
WriteByte(MSG_MULTICAST, nummeteorites);
multicast(self.origin,MULTICAST_PHS_R);
}
// else
// starteffect(CE_CHUNK, self.origin, THINGTYPE_METEOR,'0 0 600', nummeteorites);
}
/* else while(nummeteorites>0)
{
if(self.classname=="acidblob")//FIXME: Need wet acid explode sound
{
if(nummeteorites==1)
sound(self,CHAN_BODY,"succubus/blobexpl.wav",1,ATTN_NORM);
FireAcidBlob("aciddrop");
}
else
FireMeteor("minimeteor");
nummeteorites =nummeteorites - 1;
}*/
}
/*
if(self.classname=="meteor")
{
local float nummeteorites;
nummeteorites=random(3,10);
while(nummeteorites>0)
{
FireMeteor("minimeteor");
nummeteorites =nummeteorites - 1;
}
}
*/
if(self.flags2&FL_SMALL)
SmallExplosion();
else
{
BecomeExplosion(FALSE);
}
};
void() SuperGrenadeExplode;
void() GrenadeTouch2 =
{
if (other == self.owner)
return; // don't explode on owner
if(other.owner==self.owner&&other.classname==self.classname&&self.classname=="minigrenade")
return;
if (other.takedamage==DAMAGE_YES)//let them damage b_models on impact?
{
if(self.classname=="minigrenade")
{//special case- does 50 pts to other, 25rad to everyone else
if(other.solid==SOLID_BSP&&other.thingtype==THINGTYPE_METAL)
self.dmg/=2;//less damage to metal doors, 25 direct, 12.5 rad
T_Damage(other,self,self.owner,self.dmg);
T_RadiusDamage (self, self.owner, self.dmg/2, other);
self.dmg=0;
self.think=DarkExplosion;
thinktime self : 0;
return;
}
else
{
T_Damage(other,self,self.owner,self.dmg);
self.dmg/=2;
}
if(self.classname=="multigrenade")
self.think=SuperGrenadeExplode;
else if(self.classname=="flaming arrow")//self.classname=="minigrenade"||
self.think=DarkExplosion;
else
self.think=MultiExplode;
thinktime self : 0;
}
else
{
sound (self, CHAN_WEAPON, "assassin/gbounce.wav", 1, ATTN_NORM); // bounce sound
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
}
};
void StickMineStick ()
{
if(self.wait<=time)
self.think=MultiExplode;
else if(self.enemy.health<=0&&self.health)
{
self.health=0;
self.movetype=MOVETYPE_BOUNCE;
self.velocity_z=random(-100,100);
self.avelocity=RandomVector('50 50 50');
}
else if(self.movetype!=MOVETYPE_BOUNCE)
{
setorigin(self,self.enemy.origin+self.view_ofs);
self.angles=self.o_angle + self.enemy.angles;
self.think=StickMineStick;
}
thinktime self : 0;
}
void() StickMineTouch =
{
if(other==self.owner)
return;
self.skin=1;
vector stickdir;
self.touch=SUB_Null;
if(other.takedamage)
{
sound(self,CHAN_WEAPON,"weapons/met2flsh.wav",1,ATTN_NORM);
T_Damage(other,self,self.owner,3);
if(other.solid!=SOLID_BSP)
{
// makevectors(self.angles);
stickdir=other.origin+normalize(self.origin-other.origin)*12;
//Modify height for shorter or taller models like imp, golem, spider, etc.
if(other.classname=="player")
//Put it right below view of player
stickdir_z=other.origin_z+other.proj_ofs_z + 1;
else if(other.classname=="monster_spider")
stickdir_z=(self.origin_z+(other.origin_z+other.size_z*0.2)*3)*0.25;
else stickdir_z=(self.origin_z+(other.origin_z+other.size_z*0.6)*3)*0.25;
setorigin(self,stickdir);
SpawnPuff(self.origin+v_forward*8,'0 0 0'-v_forward*24,10,other);
}
}
else
{
setorigin(self,self.origin+normalize(self.velocity)*-3);
sound(self,CHAN_WEAPON,"weapons/met2stn.wav",1,ATTN_NORM);
SpawnPuff(self.origin+v_forward*8,'0 0 0'-v_forward*24,10,world);
}
self.velocity='0 0 0';
self.movetype=MOVETYPE_NOCLIP;
self.solid=SOLID_NOT;
self.touch=SUB_Null;
self.wait=time + 1;
self.health=other.health;
if(other.takedamage)
{
self.enemy=other;
self.view_ofs=(self.origin-other.origin);
self.o_angle=(self.angles-self.enemy.angles);
//self.enemy=world;
self.movetype=MOVETYPE_NONE;
//self.think=MultiExplode;
self.think=StickMineStick;
thinktime self : 0;
}
else
{
self.enemy=world;
self.movetype=MOVETYPE_NONE;
self.think=MultiExplode;
thinktime self : 0.5;
}
};
void() Use_Fireball =
{
self.attack_finished=time + 1;//So you can't have a ton of them
makevectors(self.v_angle);
//sound
entity missile;
missile=spawn();
missile.owner=self;
missile.classname="stickmine";
missile.movetype=MOVETYPE_BOUNCE;
missile.solid=SOLID_BBOX;
missile.touch=StickMineTouch;
missile.dmg=50;
missile.velocity=normalize(v_forward)*700 +v_up*200;
missile.avelocity=RandomVector('300 300 300');
missile.lifetime=time+60;
setmodel (missile, "models/glyphwir.mdl");
setsize(missile,'0 0 0','0 0 0');
setorigin(missile,self.origin+self.proj_ofs+v_forward*16);
missile.think=MultiExplode;
thinktime missile : 10;
};
float GetImpactType (entity impacted)
{
float hittype;
if (impacted.classname == "mummy")//mummys don't bleed
hittype = XBOW_IMPACT_MUMMY;
else if (impacted.classname == "spider")//spiders bleed green
hittype = XBOW_IMPACT_GREENFLESH;
else if (impacted.thingtype == THINGTYPE_FLESH)
hittype = XBOW_IMPACT_REDFLESH;
else if (impacted.thingtype == THINGTYPE_WOOD||impacted.thingtype==THINGTYPE_DIRT)
hittype = XBOW_IMPACT_WOOD;
else if ((impacted.thingtype==THINGTYPE_GREYSTONE) || (impacted.thingtype==THINGTYPE_BROWNSTONE))
hittype = XBOW_IMPACT_STONE;
else if (impacted.thingtype==THINGTYPE_METAL)
hittype = XBOW_IMPACT_METAL;
else if (impacted.thingtype==THINGTYPE_ICE)
hittype = XBOW_IMPACT_ICE;
else
hittype = XBOW_IMPACT_DEFAULT;
return (hittype);
}

86
fablade.hc Normal file
View File

@ -0,0 +1,86 @@
/*
* $Header: /HexenWorld/Siege/FAblade.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\monsters\Fangel\wingblad\FAblade.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\monsters\Fangel\wingblad
$origin 0 0 0
$base BASE skin1
$skin skin1
$flags 0
//
$frame BLADE
void() faBladeTouch =
{
float damg;
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
damg = random(8,16);
if (other.health)
T_Damage (other, self, self.owner, damg );
sound (self, CHAN_WEAPON, "weapons/expsmall.wav", 1, ATTN_NORM);
self.origin = self.origin - 8*normalize(self.velocity);
CreateGreenSmoke(self.origin, '0 0 8', HX_FRAME_TIME * 4);
remove(self);
};
// Frame Code
void() frame_BLADE = [ $BLADE , frame_BLADE ] { };
void(vector offset, float set_speed, vector dest_offset) do_faBlade =
{
entity missile;
vector vec;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.flags = FL_FLY;
missile.health = 10;
missile.drawflags=MLS_ABSLIGHT;
missile.abslight=0.5;
setmodel (missile, "models/fablade.mdl");
setsize (missile, '0 0 0', '0 0 0');
// set missile speed
makevectors (self.angles);
setorigin (missile, self.origin + v_factor(offset));
vec = self.enemy.origin - missile.origin + self.enemy.proj_ofs + dest_offset;
vec = normalize(vec);
missile.velocity = (vec+aim_adjust(self.enemy))*set_speed;
missile.angles = vectoangles(missile.velocity);
missile.touch = faBladeTouch;
};

806
famhorse.hc Normal file
View File

@ -0,0 +1,806 @@
/*
* $Header: /HexenWorld/Siege/famhorse.hc 4 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\monsters\RdrFam\Horse\Final\famhorse.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\monsters\RdrFam\Horse\Final
$origin 0 0 0
$base base skin
$skin skin
$flags 0
// Horse frames
$frame Hrear1 Hrear2 Hrear3 Hrear4 Hrear5
$frame Hrear6 Hrear7 Hrear8 Hrear9 Hrear10
$frame Hrear11 Hrear12 Hrear13 Hrear14 Hrear15
$frame Hrear16 Hrear17 Hrear18 Hrear19 Hrear20
$frame Hrear21 Hrear22 Hrear23 Hrear24 Hrear25
$frame Hrear26 Hrear27 Hrear28 Hrear29 Hrear30
$frame Hrear31 Hrear32 Hrear33 Hrear34 Hrear35
$frame Hrear36 Hrear37 Hrear38 Hrear39 Hrear40
$frame Hrear41 Hrear42 Hrear43 Hrear44 Hrear45
$frame Hrear46 Hrear47 Hrear48 Hrear49 Hrear50
//
$frame HtranA1 HtranA2 HtranA3 HtranA4 HtranA5
$frame HtranA6 HtranA7 HtranA8 HtranA9 HtranA10
$frame HtranA11 HtranA12 HtranA13 HtranA14 HtranA15
$frame HtranA16
//
$frame HtranB1 HtranB2 HtranB3 HtranB4 HtranB5
$frame HtranB6 HtranB7 HtranB8 HtranB9 HtranB10
$frame HtranB11 HtranB12 HtranB13 HtranB14 HtranB15
$frame HtranB16
//
$frame Htrot1 Htrot2 Htrot3 Htrot4 Htrot5
$frame Htrot6 Htrot7 Htrot8 Htrot9 Htrot10
$frame Htrot11 Htrot12
$framevalue 0
//----------------------------------------------------------------
// Rider Frames
//----------------------------------------------------------------
$frame Frear1 Frear2 Frear3 Frear4 Frear5
$frame Frear6 Frear7 Frear8 Frear9 Frear10
$frame Frear11 Frear12 Frear13 Frear14 Frear15
$frame Frear16 Frear17 Frear18 Frear19 Frear20
$frame Frear21 Frear22 Frear23 Frear24 Frear25
$frame Frear26 Frear27 Frear28 Frear29 Frear30
$frame Frear31 Frear32 Frear33 Frear34 Frear35
$frame Frear36 Frear37 Frear38 Frear39 Frear40
$frame Frear41 Frear42 Frear43 Frear44 Frear45
$frame Frear46 Frear47 Frear48 Frear49 Frear50
//
$frame Fscale1 Fscale2 Fscale3 Fscale4 Fscale5
$frame Fscale6 Fscale7 Fscale8 Fscale9 Fscale10
$frame Fscale11 Fscale12 Fscale13 Fscale14 Fscale15
$frame Fscale16 Fscale17 Fscale18 Fscale19 Fscale20
$frame Fscale21 Fscale22 Fscale23 Fscale24 Fscale25
$frame Fscale26 Fscale27 Fscale28 Fscale29 Fscale30
$frame Fscale31 Fscale32 Fscale33 Fscale34 Fscale35
$frame Fscale36 Fscale37 Fscale38 Fscale39 Fscale40
$frame Fscale41 Fscale42 Fscale43 Fscale44 Fscale45
$frame Fscale46 Fscale47 Fscale48 Fscale49 Fscale50
$frame Fscale51 Fscale52 Fscale53 Fscale54 Fscale55
$frame Fscale56 Fscale57 Fscale58 Fscale59 Fscale60
$frame Fscale61 Fscale62 Fscale63 Fscale64 Fscale65
$frame Fscale66 Fscale67 Fscale68 Fscale69 Fscale70
//
$frame FtranA1 FtranA2 FtranA3 FtranA4 FtranA5
$frame FtranA6 FtranA7 FtranA8 FtranA9 FtranA10
$frame FtranA11 FtranA12 FtranA13 FtranA14 FtranA15
$frame FtranA16
//
$frame FtranB1 FtranB2 FtranB3 FtranB4 FtranB5
$frame FtranB6 FtranB7 FtranB8 FtranB9 FtranB10
$frame FtranB11 FtranB12 FtranB13 FtranB14 FtranB15
$frame FtranB16
//
$frame Ftrot1 Ftrot2 Ftrot3 Ftrot4 Ftrot5
$frame Ftrot6 Ftrot7 Ftrot8 Ftrot9 Ftrot10
$frame Ftrot11 Ftrot12 Ftrot13 Ftrot14 Ftrot15
$frame Ftrot16
float fam_start[1] =
{
$Htrot1
};
float fam_end[1] =
{
$Htrot12
};
float fam_speed[1] =
{
5.5 // Normal speed
};
// Array to align frames
float FamRiderFrames[5] =
{
$Ftrot1, // Animation for fast gallop
$FtranA1, // Animation for start of rear
$Frear1, // Animation for rear
$FtranB1, // Animation for end of rear
$Fscale1 // Attack Sequence #1
};
float FH_STAGE_NORMAL = 0;
float FH_STAGE_BEGIN_REAR = 1;
float FH_STAGE_MIDDLE_REAR = 2;
float FH_STAGE_END_REAR = 3;
float FH_STAGE_ATTACK = 4;
float FH_STAGE_STANDING = 5;
float FH_STAGE_LAUGHING = 6;
float FH_STAGE_ATTACK2 = 7;
float pulltime;
float looktime;
float hurttime;
void famhorse_move(void);
void famhorse_rear(void);
void do_fambeam (entity lowner,float tag, float lflags, float duration, vector spot1, vector spot2)
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_STREAM_FAMINE);
WriteEntity (MSG_BROADCAST, lowner);
WriteByte (MSG_BROADCAST, tag+lflags);
WriteByte (MSG_BROADCAST, duration);
WriteCoord (MSG_BROADCAST, spot1_x);
WriteCoord (MSG_BROADCAST, spot1_y);
WriteCoord (MSG_BROADCAST, spot1_z);
WriteCoord (MSG_BROADCAST, spot2_x);
WriteCoord (MSG_BROADCAST, spot2_y);
WriteCoord (MSG_BROADCAST, spot2_z);
}
void famine_pain(void)
{
float chance,rear_chance;
rear_chance = self.health / self.max_health;
if (rear_chance < .50)
rear_chance = .5;
if (self.monster_stage == FH_STAGE_NORMAL)
{
// Force a new gallop frame in
self.frame = fam_start[self.rider_gallop_mode];
chance = random();
if (chance > rear_chance) // Like the Lone Ranger but he disappears
{
self.think = famhorse_rear;
self.monster_stage = FH_STAGE_BEGIN_REAR;
}
else if (chance < 0.20) // Told himself a joke
{
self.monster_stage = FH_STAGE_LAUGHING;
self.movechain.frame = $FtranB1;
}
else if (chance < 0.60) // Missile attack
{
self.monster_stage = FH_STAGE_ATTACK2;
self.movechain.frame = $Fscale1;
}
}
}
void famine_blinkin(void)
{
thinktime self : HX_FRAME_TIME;
self.think = famine_blinkin;
self.scale += 0.10;
self.movechain.scale += 0.10;
if (self.scale >= 1)
{
self.scale=1;
self.movechain.scale=1;
thinktime self : HX_FRAME_TIME;
self.think = famhorse_rear;
}
}
// Find a point to start at close to the player
vector famine_pointcheck(void)
{
entity search;
float diff, holddiff;
vector newspot,holdpos;
search = find(world, classname, "rider_path");
diff = 99999;
while(search != world)
{
holddiff = vlen(search.origin - self.enemy.origin);
if (holddiff < diff)
{
traceline (search.origin, search.origin - '0 0 600' , FALSE, self);
holdpos=trace_endpos;
tracearea (holdpos,holdpos + '0 0 40','-55 -55 -24', '55 55 150',FALSE,self);
if (trace_fraction == 1.0 && trace_ent == world) // Check no one is standing where monster wants to be
{
diff = holddiff;
newspot= holdpos;
self.path_current = search;
}
}
search = find(search, classname, "rider_path");
}
return (newspot);
}
/*-----------------------------------------
famine_init - looking for a spot to come back in
-----------------------------------------*/
void famine_blinkin_init (void)
{
vector holdspot;
holdspot = famine_pointcheck();
setorigin(self,holdspot);
setmodel (self, "models/boss/famhorse.mdl");
setsize (self, '-40 -40 0', '40 40 100');
self.hull = HULL_POINT;
self.solid = SOLID_SLIDEBOX;
self.takedamage = DAMAGE_YES;
setmodel (self.movechain, "models/boss/famrider.mdl");
self.movechain.flags (+) FL_MOVECHAIN_ANGLE;
walkmove(self.angles_y, .01, TRUE); // You have to move it a little bit to make it solid
riderpath_findnext(); // Find the next path point to turn the horse in that direction
self.ideal_yaw = vectoyaw(self.path_current.origin - self.origin);
self.angles_y = self.ideal_yaw;
sound (self, CHAN_BODY, "skullwiz/blinkin.wav", 1, ATTN_NORM);
CreateRedCloud (self.origin + '0 0 40','0 0 0',HX_FRAME_TIME);
thinktime self : HX_FRAME_TIME;
self.think = famine_blinkin;
}
/*-----------------------------------------
famine_blinkout - blink out
-----------------------------------------*/
void famine_blinkout(void)
{
thinktime self : HX_FRAME_TIME / 2;
self.think = famine_blinkout;
self.scale -= 0.10;
self.movechain.scale -= 0.10;
if ((self.scale > 0.79) && (self.scale < 0.89))
{
sound (self, CHAN_BODY, "skullwiz/blinkout.wav", 1, ATTN_NORM);
CreateRedCloud (self.origin + '0 0 40','0 0 0',HX_FRAME_TIME);
}
if (self.scale < 0.10)
{
setmodel(self,string_null);
setmodel(self.movechain,string_null);
thinktime self : random(0.5,3); // Reappear when
self.think = famine_blinkin_init;
}
}
void famine_blinkout_init(void)
{
self.takedamage = DAMAGE_NO; // So t_damage won't force him into another state
self.solid = SOLID_NOT;
self.scale = 1;
self.drawflags (+) SCALE_TYPE_XYONLY;
self.movechain.takedamage = DAMAGE_NO; // So t_damage won't force him into another state
self.movechain.scale = 1;
self.movechain.drawflags (+) SCALE_TYPE_XYONLY;
famine_blinkout();
}
void famine_missile_touch(void)
{
float damg;
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
damg = random(8,16);
T_Damage (other, self, self.owner, damg );
self.origin = self.origin - 8 * normalize(self.velocity) - '0 0 40';
sound (self, CHAN_WEAPON, "weapons/explode.wav", 1, ATTN_NORM);
CreateRedSpark (self.origin);
remove(self);
}
void famine_missile_think (void)
{
if (self.lifetime < time)
{
sound (self, CHAN_WEAPON, "weapons/explode.wav", 1, ATTN_NORM);
CreateRedSpark (self.origin);
remove(self);
}
else
{
HomeThink();
self.angles = vectoangles(self.velocity);
self.think=famine_missile_think;
thinktime self : HX_FRAME_TIME;
}
}
void famine_missile(float dir)
{
entity newmis;
vector diff;
newmis = spawn ();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_BBOX;
setmodel (newmis, "models/famshot.mdl");
setsize (newmis, '0 0 0', '0 0 0');
setorigin (newmis, self.origin + '0 0 120');
newmis.angles = self.angles;
diff = (self.enemy.origin + self.enemy.view_ofs) - self.origin + '0 0 120' ;
newmis.velocity = normalize(diff);
newmis.angles = vectoangles(newmis.velocity);
if (dir == 0)
newmis.angles_y -= 25;
else if (dir == 2)
newmis.angles_y += 25;
makevectors (newmis.angles);
newmis.velocity = normalize(v_forward);
if (dir ==1)
newmis.speed=800; //Speed
else
newmis.speed=700; //Speed
newmis.classname = "faminemissile";
newmis.angles = vectoangles(newmis.velocity);
newmis.veer=FALSE; //No random wandering
newmis.turn_time=5; //Lower the number, tighter the turn
newmis.ideal_yaw=FALSE;//Only track things in front
newmis.lifetime = time + 2;
newmis.think=famine_missile_think;
thinktime newmis : 0;
newmis.touch = famine_missile_touch;
}
void famine_missilespawner(void)
{
CreateRedFlash(self.origin + '0 0 120');
sound (self, CHAN_WEAPON, "famine/shot.wav", 1, ATTN_NORM);
famine_missile(0);
famine_missile(1);
famine_missile(2);
}
/* ---------------------------
Create the rider
---------------------------*/
void create_famrider(entity horse)
{
entity rider;
rider = spawn();
rider.solid = SOLID_NOT;
rider.movetype = MOVETYPE_NONE;
rider.origin = horse.origin;
rider.angles = self.angles;
setmodel (rider, "models/boss/famrider.mdl");
rider.skin = 0;
horse.movechain = rider;
rider.flags (+) FL_MOVECHAIN_ANGLE;
}
/* ---------------------------
The horse is rearing
---------------------------*/
void famhorse_rear(void)
{
float retval;
thinktime self : HX_FRAME_TIME;
if (self.monster_stage == FH_STAGE_BEGIN_REAR)
{
retval = AdvanceFrame($HtranA1,$HtranA16);
if (self.frame > $HtranA10)
self.speed = 1;
riderpath_move(self.speed);
if (self.frame == $HtranA8)
sound (self, CHAN_VOICE, "famine/whinny.wav", 1, ATTN_NORM);
if (retval == AF_END)
self.monster_stage = FH_STAGE_MIDDLE_REAR;
self.movechain.frame = FamRiderFrames[1] + (self.frame - $HtranA1);
}
else if (self.monster_stage == FH_STAGE_MIDDLE_REAR)
{
retval = AdvanceFrame($Hrear1,$Hrear50);
if (self.frame == $Hrear10)
{
famine_blinkout_init();
return;
}
if (self.enemy)
{
if (self.enemy.health > 0)
{
if (self.frame == $Hrear30)
famine_missilespawner();
}
}
if (retval == AF_END)
{
if (self.enemy != world && random() < 0.7)
self.monster_stage = FH_STAGE_STANDING;
else
self.monster_stage = FH_STAGE_END_REAR;
}
self.movechain.frame = FamRiderFrames[2] + (self.frame - $Hrear1);
}
else if (self.monster_stage == FH_STAGE_STANDING)
{
if (random() < 0.5)
self.monster_stage = FH_STAGE_END_REAR;
}
else if (self.monster_stage == FH_STAGE_END_REAR)
{
retval = AdvanceFrame($HtranB1,$HtranB16);
if (self.frame < $HtranB11)
self.speed =0;
else if (self.frame < $HtranB13)
self.speed = fam_speed[self.rider_gallop_mode] * .5;
else
self.speed = fam_speed[self.rider_gallop_mode];
if (retval == AF_END)
{
self.think = famhorse_move;
self.monster_stage = FH_STAGE_NORMAL;
}
riderpath_move(self.speed);
self.movechain.frame = FamRiderFrames[3] + (self.frame - $HtranB1);
}
}
void check_remove ()
{
thinktime self : 1;
if(pulltime<time)
remove(self);
}
/* ---------------------------
The horse is running around
---------------------------*/
void famhorse_move(void)
{
float retval,chance,rear_chance,damage,diff2;
vector diff,hold_velocity;
entity newent;
vector holdvel, holdangles,spot1;
self.think = famhorse_move;
thinktime self : HX_FRAME_TIME;
// Advance horse frame
retval = AdvanceFrame(fam_start[self.rider_gallop_mode],fam_end[self.rider_gallop_mode]);
if (self.frame == $Htrot6 || self.frame == $Htrot11)
{
chance = random();
if (chance < .33)
sound (self, CHAN_VOICE, "famine/clop1.wav", 1, ATTN_NORM);
else if (chance < .66)
sound (self, CHAN_VOICE, "famine/clop2.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "famine/clop3.wav", 1, ATTN_NORM);
}
if (!self.path_current) // Look for a path to follow
riderpath_init();
riderpath_move(self.speed);
if ((!self.enemy) || (self.enemy.health <= 0))
{
if (!FindTarget(TRUE))
self.enemy = world;
self.goalentity = self.enemy;
}
if ((retval == AF_BEGINNING) && (self.monster_stage == FH_STAGE_NORMAL) && (self.enemy!=world))
{
if (random() < .05)
sound(self,CHAN_AUTO,"famine/snort.wav",1,ATTN_NORM);
retval = fabs(self.rider_y_change);
// Force a new gallop frame in
self.frame = fam_start[self.rider_gallop_mode];
rear_chance = self.health / self.max_health;
if (rear_chance < .50)
rear_chance = .5;
chance = random();
if (chance > rear_chance) // Like the Lone Ranger but he disappears
{
self.think = famhorse_rear;
self.monster_stage = FH_STAGE_BEGIN_REAR;
}
else if (chance < 0.05) // Told himself a joke
{
self.monster_stage = FH_STAGE_LAUGHING;
self.movechain.frame = $FtranB1;
}
// Find an enemy??
else if ((self.rider_gallop_mode == 0) && (looktime < time))
{
traceline (self.origin + '0 0 120',self.enemy.origin , FALSE, self);
if (self.enemy)
{
if (self.enemy == trace_ent)
{
chance = random();
if (chance < .30) // The famous pull attack
{
pulltime = time + random(2,5);
self.monster_stage = FH_STAGE_ATTACK;
self.movechain.frame = $Fscale1;
sound(self,CHAN_WEAPON,"famine/pull.wav",1,ATTN_NORM);
}
else if (chance < .70) // Missile attack
{
self.monster_stage = FH_STAGE_ATTACK2;
self.movechain.frame = $Fscale1;
}
}
}
}
}
// Is rider attacking player
if (self.monster_stage == FH_STAGE_ATTACK)
{
if ((self.movechain.frame == $Fscale9) && (self.enemy.health > 0))
{
newent = spawn();
setorigin (newent, self.origin + '0 0 120');
setmodel (newent, "models/soulball.mdl");
self.controller = newent;
self.controller.think=check_remove;
thinktime self.controller : 0;
}
if ((self.movechain.frame == $Fscale10) && (self.enemy.health > 0))
{
diff = self.enemy.origin - self.origin + '0 0 120';
holdvel = normalize(diff);
holdangles = vectoangles(holdvel);
// traceline in front and behind because the beam is wide
makevectors (holdangles);
spot1 = self.origin + '0 0 120' + v_right * 25;
traceline (spot1,self.enemy.origin , FALSE, self);
if (trace_ent != self.enemy)
{
pulltime = 0;
}
else
{
spot1 = self.origin + '0 0 120' - v_right * 25;
traceline (spot1,self.enemy.origin , FALSE, self);
if (trace_ent != self.enemy)
pulltime = 0;
}
if (pulltime)
{
self.movechain.drawflags(+)MLS_ABSLIGHT;
self.movechain.abslight = .5;
do_fambeam (self,1,STREAM_ATTACHED, 1, self.origin + '0 0 120', self.enemy.origin);
self.enemy.velocity = '0 0 0';
setorigin (self.controller, self.origin + '0 0 120');
diff = self.enemy.origin - self.origin;
hold_velocity = normalize(diff);
hold_velocity = hold_velocity * -250;
self.enemy.velocity = self.enemy.velocity + hold_velocity;
if(vlen(self.enemy.velocity)>500)
self.enemy.velocity=normalize(self.enemy.velocity)*500;
self.enemy.flags (-) FL_ONGROUND;
}
if (hurttime < time)
{
diff2 = vlen(self.enemy.origin - self.origin);
damage = 300/diff2;
if (damage < 2)
damage=2;
else if (damage >8)
damage = 8;
T_Damage (self.enemy, self, self, damage);
if (self.enemy.health <= 0)
{
if(self.controller)
remove(self.controller);
stopSound(self,CHAN_WEAPON);
//sound(self,CHAN_WEAPON,"misc/null.wav",1,ATTN_NORM);
}
hurttime = time + 1;
}
if (pulltime < time)
{
if(self.controller)
remove(self.controller);
stopSound(self,CHAN_WEAPON);
//sound(self,CHAN_WEAPON,"misc/null.wav",1,ATTN_NORM);
self.movechain.drawflags(-)MLS_ABSLIGHT;
self.movechain.frame += 50;
looktime = time + random(5,10);
}
}
else
{
self.movechain.frame += 1;
}
if (self.movechain.frame >= $Fscale70)
self.monster_stage = FH_STAGE_NORMAL;
}
else if (self.monster_stage == FH_STAGE_ATTACK2)
{
if (self.movechain.frame == $Fscale10)
{
famine_missilespawner();
self.movechain.frame += 50;
}
self.movechain.frame += 1;
if (self.movechain.frame >= $Fscale70)
self.monster_stage = FH_STAGE_NORMAL;
}
else if (self.monster_stage == FH_STAGE_LAUGHING)
{
self.movechain.frame += 1;
if (self.movechain.frame == $FtranB6)
sound (self.movechain, CHAN_VOICE, "famine/laugh.wav", 1, ATTN_NORM);
else if (self.movechain.frame >= $FtranB16)
self.monster_stage = FH_STAGE_NORMAL;
}
}
/*QUAKED rider_famine (1 0 0) (-55 -55 -24) (55 55 150) TRIGGER_WAIT
Famine rider monster. You must place rider_path entites
on the map. The rider will first proceed to the
rider_path point with a path_id of 1.
-------------------------FIELDS-------------------------
map: next map to go to when you kill the rider
target: start spot on the next map
--------------------------------------------------------
*/
void rider_famine(void)
{
if (deathmatch)
{
remove(self);
return;
}
precache_model3 ("models/boss/famhorse.mdl");
precache_model3 ("models/boss/famrider.mdl");
precache_model3 ("models/famshot.mdl");
precache_sound3 ("famine/die.wav");
precache_sound3 ("famine/laugh.wav");
precache_sound3 ("famine/whinny.wav");
precache_sound3 ("famine/pull.wav");
precache_sound3 ("famine/shot.wav");
precache_sound3 ("famine/snort.wav");
precache_sound3 ("famine/clop1.wav");
precache_sound3 ("famine/clop2.wav");
precache_sound3 ("famine/clop3.wav");
precache_sound3 ("misc/null.wav");
precache_sound3 ("raven/blast.wav");
precache_sound3 ("skullwiz/blinkout.wav");
precache_sound3 ("skullwiz/blinkin.wav");
rider_init();
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
self.thingtype = THINGTYPE_FLESH;
self.yaw_speed = 2;
setmodel (self, "models/boss/famhorse.mdl");
self.skin = 0;
setsize (self, '-40 -40 0', '40 40 100');
self.health = self.max_health = 2200;
self.th_pain = famine_pain;
self.rider_gallop_mode = 0;
self.speed = fam_speed[self.rider_gallop_mode];
self.rider_path_distance = 75;
self.monster_stage = FH_STAGE_NORMAL;
self.mass = 30000;
self.flags (+) FL_MONSTER;
self.flags2 (+) FL_ALIVE;
self.monsterclass = CLASS_BOSS;
self.yaw_speed = 10;
self.experience_value = 500;
create_famrider(self);
self.attack_finished = 0;
self.hull = HULL_POINT;
looktime =0;
hurttime = 0;
self.noise="famine/die.wav";
self.th_save = famhorse_move;
self.think = multiplayer_health;
thinktime self : 1;
}

895
fangel.hc Normal file
View File

@ -0,0 +1,895 @@
/*
* $Header: /HexenWorld/Siege/fangel.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\monsters\Fangel\final\fangel.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\monsters\Fangel\final
$origin 0 0 0
$base BASE skin
$skin skin
$flags 0
//
$frame fblock1 fblock2 fblock3 fblock4 fblock5
$frame fblock6 fblock7 fblock8 fblock9 fblock10
$frame fblock11 fblock12 fblock13 fblock14 fblock15
$frame fblock16 fblock17 fblock18 fblock19 fblock20
$frame fblock21
//
$frame fdeth1 fdeth2 fdeth3 fdeth4 fdeth5
$frame fdeth6 fdeth7 fdeth8 fdeth9 fdeth10
$frame fdeth11 fdeth12 fdeth13 fdeth14 fdeth15
$frame fdeth16 fdeth17 fdeth18 fdeth19 fdeth20
$frame fdeth21 fdeth22 fdeth23 fdeth24 fdeth25
$frame fdeth26 fdeth27 fdeth28 fdeth29 fdeth30
$frame fdeth31 fdeth32 fdeth33 fdeth34 fdeth35
$frame fdeth36 fdeth37 fdeth38 fdeth39 fdeth40
//
$frame ffly1 ffly2 ffly3 ffly4 ffly5
$frame ffly6 ffly7 ffly8 ffly9 ffly10
$frame ffly11 ffly12 ffly13 ffly14 ffly15
$frame ffly16 ffly17 ffly18 ffly19 ffly20
$frame ffly21 ffly22 ffly23 ffly24 ffly25
$frame ffly26 ffly27 ffly28 ffly29 ffly30
//
$frame fhand1 fhand2 fhand3 fhand4 fhand5
$frame fhand6 fhand7 fhand8 fhand9 fhand10
$frame fhand11 fhand12 fhand13 fhand14 fhand15
$frame fhand16 fhand17 fhand18 fhand19 fhand20
$frame fhand21 fhand22
//
$frame fmove1 fmove2 fmove3 fmove4 fmove5
$frame fmove6 fmove7 fmove8 fmove9 fmove10
$frame fmove11 fmove12 fmove13 fmove14 fmove15
$frame fmove16 fmove17 fmove18 fmove19 fmove20
//
$frame fpain1 fpain2 fpain3 fpain4 fpain5
$frame fpain6 fpain7 fpain8 fpain9 fpain10
$frame fpain11 fpain12
//
$frame ftranA1 ftranA2 ftranA3 ftranA4 ftranA5
$frame ftranA6 ftranA7 ftranA8 ftranA9 ftranA10
$frame ftranA11 ftranA12 ftranA13 ftranA14 ftranA15
$frame ftranA16 ftranA17 ftranA18 ftranA19 ftranA20
//
$frame ftranB1 ftranB2 ftranB3 ftranB4 ftranB5
$frame ftranB6 ftranB7 ftranB8 ftranB9 ftranB10
$frame ftranB11 ftranB12 ftranB13 ftranB14 ftranB15
$frame ftranB16 ftranB17 ftranB18 ftranB19 ftranB20
//
$frame fwing1 fwing2 fwing3 fwing4 fwing5
$frame fwing6 fwing7 fwing8 fwing9 fwing10
$frame fwing11 fwing12 fwing13 fwing14 fwing15
$frame fwing16 fwing17 fwing18 fwing19 fwing20
$frame fwing21 fwing22 fwing23 fwing24 fwing25
$frame fwing26 fwing27 fwing28 fwing29 fwing30
// Function protos
void() fangel_blockframes;
void fangel_handframes (void);
void fangel_wingframes (void);
void fangel_flyframes (void);
// Constants
float fangel_attack_speed = 11;
float fangel_move_speed = 6;
float () fangel_check_incoming =
{
entity item;
vector vec, realVec;
float dot;
if(range(self.enemy)<=RANGE_MELEE)
return FALSE;
if(fov(self,self.enemy,30)&&self.enemy.last_attack+0.75>time)
{
self.th_save = self.think;
self.fangel_Count = 0;
fangel_blockframes();
return TRUE;
}
if(random()>0.4 + skill/10 + self.skin/10)
return FALSE;
item = findradius(self.origin, 256);
while (item)
{
if (item.owner.classname == "player" && (item.movetype == MOVETYPE_FLYMISSILE ||
item.movetype == MOVETYPE_BOUNCEMISSILE || item.movetype==MOVETYPE_BOUNCE))
{
vec = normalize(self.origin - item.origin + self.view_ofs);
realVec = normalize(item.velocity);
dot= vec*realVec;
if (dot >= 0.4)
{
self.th_save = self.think;
self.fangel_Count = 0;
fangel_blockframes();
return TRUE;
}
}
item = item.chain;
}
return FALSE;
};
// Monster Stages
float FANGEL_STAGE_WAIT = 0;
float FANGEL_STAGE_FLY = 1;
float FANGEL_STAGE_FLOAT = 2;
float FANGEL_STAGE_SIDESTEP = 3;
//float FANGEL_STAGE_STRAIGHT = 3;
//float FANGEL_STAGE_REVERSE = 4;
//float FANGEL_STAGE_ATTACK = 10;
void() fangel_check_wing =
{
float retval;
if(!self.enemy)
return;
enemy_infront = visible(self.enemy);
// If we are flying, don't attack as often
if (self.monster_stage == FANGEL_STAGE_FLY && random() < 0.5)
enemy_infront = 0;
if (enemy_infront)
{
self.th_save = self.think;
enemy_range = range (self.enemy);
if (random() < 0.5)
retval = CheckMonsterAttack(MA_FAR_MELEE,1);
else
retval = CheckMonsterAttack(MA_MISSILE,1);
}
else retval = MA_NOATTACK;
if (retval != MA_SUCCESSFUL)
fangel_check_incoming();
else
self.yaw_speed = fangel_attack_speed;
};
void fangel_find_spot (void)
{
float crj, radius,dist;
vector vec;
crj=0;
while(crj < 50)
{
radius = random(100,200);
vec = randomv('0 0 0', '360 360 0');
vec = normalize(vec);
vec = self.enemy.origin + vec*radius;
vec_z = vec_z + random(20, 40) + self.enemy.view_ofs_z;
tracearea (self.origin,vec,self.mins,self.maxs,FALSE,self);
if (trace_fraction == 1)
{
self.monster_last_seen = vec;
dist = self.origin_z - self.monster_last_seen_z;
if (dist < -20)
self.z_movement = random(0,2);
else if (dist > 20 )
self.z_movement = random(-2,0);
else
self.z_movement = random(-2,2); // Give her a little up and down movement
self.z_duration = time + HX_FRAME_TIME * random(15,25);
return;
}
crj += 1;
}
self.monster_stage = FANGEL_STAGE_FLOAT;
self.monster_duration = random(20,30);
}
void() fangel_init =
{ // Set the fallen angel ready
dprint(self.enemy.classname);
dprint("- Found enemy\n");
self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
self.think=self.th_stand;
thinktime self : random(.1,.6);
self.count = 0;
self.monster_stage = FANGEL_STAGE_FLY;
self.monster_duration = 0;
self.goalentity = self.enemy;
self.monster_awake = TRUE;
if (self.skin)
self.drawflags (+) MLS_POWERMODE;
fangel_find_spot();
};
void fangel_wait (void)
{
thinktime self : 0.15;
LocateTarget();
if(self.enemy) // We found a target
fangel_init();
else if(random(100)<5&&self.t_width<time)
{
self.t_width=time+7;
if(self.skin)
sound(self,CHAN_AUTO,"fangel/ambi2.wav",random(0.5,1),ATTN_NORM);
else
sound(self,CHAN_AUTO,"fangel/ambi1.wav",random(0.5,1),ATTN_NORM);
}
}
void fangel_sidestep (void)
{
float retval;
float dist;
float chance;
self.monster_duration -= 1;
dist = random(1,4); // Movement distance this turn
retval = walkmove(self.angles_y + 90, dist, FALSE);
if (!retval)
{
self.monster_stage = FANGEL_STAGE_FLY;
fangel_find_spot();
self.think = fangel_flyframes;
self.nextthink = time;
return;
}
dist = self.origin_z - self.monster_last_seen_z;
if (dist < -20)
{
self.z_movement = random(0,2);
self.z_duration = time + HX_FRAME_TIME * random(15,25);
}
else if (dist > 20 )
{
self.z_movement = random(-2,0);
self.z_duration = time + HX_FRAME_TIME * random(15,25);
}
if (self.monster_duration <= 0)
{
chance = random();
if (chance < .33)
{
self.monster_stage = FANGEL_STAGE_FLOAT;
self.monster_duration = random(10,30);
}
else if (chance < .66)
self.think = fangel_handframes; // Come back fighting
else
self.think = fangel_wingframes; // Come back fighting
}
}
void fangel_fly (float thrust)
{
float retval;
float dist;
float Length;
Length = vhlen(self.origin - self.monster_last_seen);
self.ideal_yaw = vectoyaw(self.monster_last_seen - self.origin);
ChangeYaw();
dist = (2.0 + thrust * 4); // Movement distance this turn
if (Length < 20)
{
if (random() < 0.1)
fangel_find_spot();
else
{
self.monster_stage = FANGEL_STAGE_FLOAT;
self.monster_duration = random(10,30);
}
return;
}
retval = walkmove(self.angles_y, dist, FALSE);
if (!retval)
{
fangel_find_spot();
return;
}
dist = self.origin_z - self.monster_last_seen_z;
if (dist < -20)
{
self.z_movement = random(2,4);
self.z_duration = time + HX_FRAME_TIME * random(15,25);
}
else if (dist > 20)
{
self.z_movement = random(-2,-4);
self.z_duration = time + HX_FRAME_TIME * random(15,25);
}
if (self.z_duration > time)
movestep(0,0,self.z_movement, FALSE);
}
void () fangel_float =
{
self.monster_duration = self.monster_duration - 1;
ai_face();
enemy_range = range (self.enemy); // Attack if they are too near
if ((enemy_range <= RANGE_NEAR) && (random() < .25))
self.monster_duration = 0;
else if ((enemy_range <= RANGE_MELEE) && (random() < .90))
self.monster_duration = 0;
if (self.monster_duration <= 0)
{
self.monster_stage = FANGEL_STAGE_FLY;
fangel_find_spot();
}
};
void fangel_move (float thrust)
{
check_z_move(thrust/2);
// movestep(0,0,thrust/2, FALSE);
if (self.monster_stage == FANGEL_STAGE_WAIT)
{
dprint("Waiting\n");
fangel_wait();
return;
}
else if (self.monster_stage == FANGEL_STAGE_FLY)
{
fangel_fly(thrust);
return;
}
else if (self.monster_stage == FANGEL_STAGE_SIDESTEP)
{
fangel_sidestep();
return;
}
else if (self.monster_stage == FANGEL_STAGE_FLOAT)
{
fangel_float();
return;
}
}
void () fangel_prepare_attack =
{
ai_face();
};
void () fangel_hand_fire =
{
fangel_prepare_attack();
sound (self, CHAN_WEAPON, "fangel/hand.wav", 1, ATTN_NORM);
do_faSpell('10 -4 8',400);
do_faSpell('10 -4 8',300);
};
void () fangel_wing_fire =
{
fangel_prepare_attack();
sound (self, CHAN_WEAPON, "fangel/wing.wav", 1, ATTN_NORM);
makevectors (self.angles);
do_faBlade('8 6 4',360, v_right*2);
do_faBlade('-8 6 4',360, v_right*(-2));
};
float fangel_fly_offsets[20] =
{
0,
0.1,
0.2,
0.3,
0.4,
0.5,
0.6,
0.7,
0.8,
0.9,
1,
0.9,
0.8,
0.7,
0.6,
0.5,
0.4,
0.3,
0.2,
0.1
};
// Frame Code
void() fangel_blockframes =
{
float RetVal;
float chance;
self.think = fangel_blockframes;
thinktime self : HX_FRAME_TIME;
if(self.velocity!='0 0 0')
self.velocity=self.velocity*0.7;
// Turn to face the attacker
ai_face();
check_z_move(3);
// movestep(0,0,-1, FALSE); // Float down while deflecting shots
if (self.fangel_Count)
{
self.fangel_Count -= 1;
RetVal = 3;
}
else if(fov(self,self.enemy,30)&&self.enemy.last_attack+0.75>time&&self.frame == $fblock13)
self.fangel_Count+=1;
else
RetVal = AdvanceFrame($fblock1,$fblock21);
if (self.frame==$fblock21) // Only deflect after this frame
{
if(self.movechain)
remove(self.movechain);
self.movechain=world;
}
if (RetVal == AF_END)
{
self.takedamage = DAMAGE_YES;
chance = random();
if (chance < .1)
self.think = self.th_save;
else if (chance < .60)
self.think = fangel_handframes; // Come back fighting
else
self.think = fangel_wingframes; // Come back fighting
}
else if (RetVal == AF_NORMAL)
{
if (self.frame == $fblock13)
self.fangel_Count = 40;
}
if (self.frame == $fblock9)
{
self.takedamage = DAMAGE_NO;
spawn_reflect();
}
};
void() fangel_deathframes =
{
entity stemp;//,skull;
if(self.health<=-40)
{
chunk_death();
return;
}
self.think = fangel_deathframes;
thinktime self : HX_FRAME_TIME;
traceline (self.origin, self.origin - '0 0 250',FALSE,self);
particle2(trace_endpos,'-30 -30 50','30 30 100',384,PARTICLETYPE_SPELL,80);
if (self.frame == 26)
self.drop_time = time + .25;
if ((self.frame == 27) && (!self.flags & FL_ONGROUND))
{
self.frame = 26;
self.velocity_z = -20;
if (self.drop_time < time) // Dropping too long so let her die.
self.frame = 27;
}
/*Should she spew a head if not chunked?
if (self.frame == $fdeth40)
{
skull= spawn();
CreateEntityNew(skull,ENT_FANGEL_HEAD,"models/h_fangel.mdl",chunk_death);
skull.flags(-)FL_ONGROUND;
skull.avelocity_x = random(30);
skull.avelocity_y = random(30);
skull.avelocity_z = random(80);
thinktime skull : random(4,10);
skull.think = MakeSolidCorpse;
setorigin(skull,self.origin);
}
*/
if (AdvanceFrame($fdeth1,$fdeth40) == AF_BEGINNING)
remove(self);
if (self.frame == $fdeth1)
self.movetype = MOVETYPE_STEP;
if (self.frame == $fdeth10)
{
if (self.classname == "monster_fallen_angel")
sound (self, CHAN_WEAPON, "fangel/death.wav", 1, ATTN_NORM);
else
sound (self, CHAN_WEAPON, "fangel/death2.wav", 1, ATTN_NORM);
}
};
void fangel_flyforward (void)
{
AdvanceFrame($fmove1,$fmove20);
self.frame += 1;
fangel_move(3*fangel_fly_offsets[self.frame - $fmove1]);
if (self.frame == $fmove2)
sound (self, CHAN_WEAPON, "fangel/fly.wav", 1, ATTN_NORM);
if ((self.frame >= $fmove6 && self.frame <= $fmove8) ||
(self.frame >= $fmove16 && self.frame <= $fmove18))
{
self.fangel_SaveFrame = self.frame;
fangel_check_wing();
}
}
void fangel_flyother (void)
{
AdvanceFrame($ffly1,$ffly30);
fangel_move(3*fangel_fly_offsets[rint((self.frame - $ffly1)*.65)]);
if (self.frame == $ffly1)
sound (self, CHAN_WEAPON, "fangel/fly.wav", 1, ATTN_NORM);
if ((self.frame >= $ffly11 && self.frame <= $ffly13) ||
(self.frame >= $ffly26 && self.frame <= $ffly28))
{
self.fangel_SaveFrame = self.frame;
fangel_check_wing();
}
}
void() fangel_flyframes =
{
self.think = fangel_flyframes;
thinktime self : HX_FRAME_TIME;
fangel_check_incoming();
if(self.velocity!='0 0 0')
self.velocity=self.velocity*0.7;
if (self.monster_stage == FANGEL_STAGE_FLY)
fangel_flyforward();
else
fangel_flyother();
};
void fangel_handframes (void)
{
self.think = fangel_handframes;
thinktime self : HX_FRAME_TIME;
fangel_check_incoming();
if (AdvanceFrame($fhand1,$fhand22) == AF_END)
{
fangel_prepare_attack();
if (random() < .25)
{
self.monster_stage = FANGEL_STAGE_SIDESTEP;
self.monster_duration = random(20,40);
fangel_find_spot();
self.think = fangel_flyframes;
}
else
{
self.think = self.th_save;
}
self.frame = self.fangel_SaveFrame;
self.yaw_speed = fangel_move_speed;
}
else
{
if (self.frame == $fhand12) fangel_hand_fire();
else fangel_prepare_attack();
}
}
void() fangel_painframes =
{
float chance;
self.think = fangel_painframes;
thinktime self : HX_FRAME_TIME;
if (AdvanceFrame($fpain1,$fpain12) == AF_END)
{
fangel_check_incoming();
chance = random();
if (chance < .33)
self.think = self.th_save;
else if (chance < .66)
self.think = fangel_handframes; // Come back fighting
else
self.think = fangel_wingframes; // Come back fighting
self.frame = self.fangel_SaveFrame;
}
};
void() fangel_wingframes =
{
self.think = fangel_wingframes;
thinktime self : HX_FRAME_TIME;
if (AdvanceFrame($fwing1,$fwing30) == AF_END)
{
fangel_prepare_attack();
if (random() < .25)
{
self.monster_stage = FANGEL_STAGE_SIDESTEP;
self.monster_duration = random(20,40);
fangel_find_spot();
self.think = fangel_flyframes;
}
else
self.think = self.th_save;
self.frame = self.fangel_SaveFrame;
self.yaw_speed = fangel_move_speed;
}
else
{
if (self.classname == "monster_fallen_angel")
{
if (self.frame == $fwing21)
{
if (self.shoot_cnt < 3)
{
if (self.shoot_time < time)
{
fangel_wing_fire();
self.shoot_cnt += 1;
self.shoot_time = time + HX_FRAME_TIME * 3;
}
self.frame = $fwing20;
}
else
self.shoot_cnt =0;
}
else
fangel_prepare_attack();
}
else
{
if (self.frame == $fwing21)
{
if (self.shoot_cnt < 10)
{
vector org;
org=self.origin-'0 0 5';
traceline(org,(self.enemy.absmin+self.enemy.absmax)*0.5,TRUE,self);
if (trace_fraction==1)
{
self.effects(+)EF_MUZZLEFLASH;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_STREAM_COLORBEAM); //beam type
WriteEntity (MSG_BROADCAST, self); //owner
WriteByte (MSG_BROADCAST, 0); //tag + flags
WriteByte (MSG_BROADCAST, 1); //time
WriteByte (MSG_BROADCAST, rint(random(0,4))); //color
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, self, 3,"sunbeam");
self.frame -= 1;
self.shoot_cnt += 1;
}
self.frame = $fwing20;
}
else
self.shoot_cnt =0;
}
else
fangel_prepare_attack();
}
}
};
void(entity attacker, float damage) fangel_pain =
{
if (random(self.health) > damage||self.pain_finished>time)
return; // didn't flinch
self.pain_finished=time + 1 + self.skin;
if (self.health < 50)
self.drawflags (-) DRF_TRANSLUCENT|MLS_POWERMODE;
if ((self.frame >= $ffly11 && self.frame <= $ffly13) ||
(self.frame >= $ffly26 && self.frame <= $ffly28))
{
if (self.classname == "monster_fallen_angel")
sound (self, CHAN_WEAPON, "fangel/pain.wav", 1, ATTN_NORM);
else
sound (self, CHAN_WEAPON, "fangel/pain2.wav", 1, ATTN_NORM);
self.fangel_SaveFrame = self.frame;
// didn't want to use self.think just in case we just began to attack
self.th_save = fangel_flyframes;
fangel_painframes();
}
};
void() init_fangel =
{
if (deathmatch)
{
remove(self);
return;
}
self.monster_stage = FANGEL_STAGE_WAIT;
precache_model2 ("models/fangel.mdl");
precache_model2 ("models/faspell.mdl");
precache_model2 ("models/fablade.mdl");
precache_model2 ("models/h_fangel.mdl");
precache_sound2("fangel/fly.wav");
precache_sound2("fangel/deflect.wav");
precache_sound2("fangel/hand.wav");
precache_sound2("fangel/wing.wav");
CreateEntityNew(self,ENT_FANGEL,"models/fangel.mdl",fangel_deathframes);
self.skin = 0;
self.hull = HULL_BIG;
if (self.classname == "monster_fallen_angel")
{
precache_sound2("fangel/ambi1.wav");
self.skin = 0;
self.health = 250;
self.experience_value = 150;
}
else
{
precache_sound2("fangel/ambi2.wav");
self.skin = 1;
self.health = 500;
self.experience_value = 400;
}
self.th_stand = fangel_flyframes;
self.th_walk = fangel_flyframes;
self.th_run = fangel_flyframes;
self.th_pain = fangel_pain;
self.th_die = fangel_deathframes;
self.th_missile = fangel_handframes;
self.th_melee = fangel_wingframes;
self.headmodel="models/h_fangel.mdl";
total_monsters += 1;
self.ideal_yaw = self.angles * '0 1 0';
self.yaw_speed = fangel_move_speed;
self.view_ofs = '0 0 -5';
self.use = monster_use;
self.mintel = 3;
self.flags (+) FL_FLY | FL_MONSTER;
self.flags2 (+) FL_ALIVE;
if (self.classname == "monster_fallen_angel_lord")
self.drawflags (+) DRF_TRANSLUCENT;
self.pausetime = 99999999;
self.frame=$fhand1;
self.think=fangel_wait;
thinktime self : 0;
// self.th_stand ();
};
/*QUAKED monster_fallen_angel (1 0.3 0) (-14 -14 -41) (14 14 23) AMBUSH STUCK JUMP PLAY_DEAD DORMANT
New item for QuakeEd
-------------------------FIELDS-------------------------
--------------------------------------------------------
*/
void() monster_fallen_angel =
{
precache_sound2("fangel/death.wav");
precache_sound2("fangel/pain.wav");
init_fangel();
};
/*QUAKED monster_fallen_angel_lord (1 0.3 0) (-14 -14 -41) (14 14 23) AMBUSH STUCK JUMP PLAY_DEAD DORMANT
New item for QuakeEd
-------------------------FIELDS-------------------------
--------------------------------------------------------
*/
void() monster_fallen_angel_lord =
{
precache_sound2("fangel/death2.wav");
precache_sound2("fangel/pain2.wav");
init_fangel();
};

141
faspell.hc Normal file
View File

@ -0,0 +1,141 @@
/*
* $Header: /HexenWorld/Siege/FAspell.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\monsters\Fangel\spell\FAspell.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\monsters\Fangel\spell
$origin 0 0 0
$base BASE skin1
$skin skin1
$flags 0
//
$frame SPELL01 SPELL02 SPELL03 SPELL04 SPELL05
$frame SPELL06 SPELL07 SPELL08 SPELL09
void() faSpellTouch =
{
float damg;
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
damg = random(12,22);
if (other.health)
T_Damage (other, self, self.owner, damg );
T_RadiusDamage (self, self.owner, damg, other);
sound (self, CHAN_WEAPON, "weapons/explode.wav", 1, ATTN_NORM);
self.origin = self.origin - 8*normalize(self.velocity);
CreateRedSpark(self.origin);
remove(self);
};
// Frame Code
/*
void() frame_SPELL01 = [ $SPELL01 , frame_SPELL02 ] { };
void() frame_SPELL02 = [ $SPELL02 , frame_SPELL03 ] { };
void() frame_SPELL03 = [ $SPELL03 , frame_SPELL04 ] { };
void() frame_SPELL04 = [ $SPELL04 , frame_SPELL05 ] { };
void() frame_SPELL05 = [ $SPELL05 , frame_SPELL06 ] { };
void() frame_SPELL06 = [ $SPELL06 , frame_SPELL07 ] { };
void() frame_SPELL07 = [ $SPELL07 , frame_SPELL08 ] { };
void() frame_SPELL08 = [ $SPELL08 , frame_SPELL09 ] { };
void() frame_SPELL09 = [ $SPELL09 , frame_SPELL01 ] { };
*/
void() faspell_frames =
{
float old_angle, old_count;
vector new_posA, new_posB, posA, posB;
self.think = faspell_frames;
thinktime self : HX_FRAME_TIME;
AdvanceFrame($SPELL01,$SPELL09);
AdvanceFrame($SPELL01,$SPELL09);
old_angle = self.spell_angle;
old_count = self.count;
self.spell_angle += random(32,42);
if (self.spell_angle >= 360) self.spell_angle -= 360;
if (self.count < 6)
self.count += 0.6;
makevectors (self.angles);
posA = v_right * sin(self.spell_angle) * self.count;
posB = v_right * sin(old_angle) * old_count;
new_posA = (posA-posB);
posA = v_up * cos(self.spell_angle) * self.count;
posB = v_up * cos(old_angle) * old_count;
new_posB = (posA-posB);
new_posA += new_posB;
movestep(new_posA_x,new_posA_y,new_posA_z, FALSE);
if(self.lifetime<time)
remove(self);
};
void(vector offset, float set_speed) do_faSpell =
{
entity missile;
vector vec;
self.last_attack=time;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.flags = FL_FLY;
missile.health = 10;
missile.drawflags=MLS_FIREFLICKER;
setmodel (missile, "models/faspell.mdl");
setsize (missile, '0 0 0', '0 0 0');
// set missile speed
makevectors (self.angles);
setorigin (missile, self.origin + v_factor(offset));
vec = self.enemy.origin - missile.origin + self.enemy.proj_ofs;
vec = normalize(vec);
missile.velocity = (vec+aim_adjust(self.enemy))*set_speed;
missile.angles = vectoangles(missile.velocity);
missile.spell_angle = random(360);
missile.count = 1;
missile.touch = faSpellTouch;
missile.think = faspell_frames;
missile.lifetime=time+3;
thinktime missile : HX_FRAME_TIME;
};

224
fight.hc Normal file
View File

@ -0,0 +1,224 @@
/*
* $Header: /HexenWorld/Siege/FIGHT.hc 5 5/25/98 1:38p Mgummelt $
*/
/*
* 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 anglemod(float v);
void ChooseTurn(vector dest);
void ai_face();
float CheckMonsterAttack(float AttackType, float ChanceModifier);
float enemy_vis, enemy_infront, enemy_range;
float enemy_yaw;
float MAX_MELEE = 1;
float MAX_MISSILE = 2;
float MAX_BOTH = 3;
float MAX_FAR_MELEE = 4;
float MAX_SHORT_MISSILE = 8;
/*
* CheckAttack() -- The player is in view, so decide to move or launch an
* attack. Returns FALSE if movement should continue.
*/
float CheckAttack()
{
vector spot1, spot2;
entity targ;
float chance;
targ = self.enemy;
// see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = (targ.absmin+targ.absmax)*0.5;
traceline (spot1, spot2, FALSE, self);
if(trace_ent.thingtype>=THINGTYPE_WEBS)
traceline (trace_endpos, spot2, FALSE, trace_ent);
if (trace_ent != targ)
if(trace_ent.health>25||!trace_ent.takedamage||(trace_ent.flags&FL_MONSTER&&trace_ent.classname!="player_sheep"))
return FALSE;//Don't have a clear shot, and don't want to shoot obstruction
//FIXME: check for translucent water?
if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if (enemy_range == RANGE_MELEE)
{ // melee attack
if (self.th_melee)
{
self.th_melee ();
return TRUE;
}
}
//FIXME: check for darkness, maybe won't fire, maybe aim will be off
// 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 (random(0,2));
return TRUE;
}
return FALSE;
}
/*
* ai_face() -- Keep facing the enemy.
*/
void ai_face()
{
self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
// 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 visible(entity targ);
float infront(entity targ);
float range (entity targ);
void ai_charge(float d)
{
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);
self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
ChangeYaw();
makevectors (self.angles);
dtemp = self.enemy.origin - 30*v_right;
heading = vectoyaw(dtemp - self.origin);
walkmove(heading, 20, FALSE);
}
/*
* ai_melee()
*/
void ai_melee()
{//Bad idea- doesn't care where around self player is!
vector org1,org2;
float ldmg;
if (!self.enemy)
return; // removed before stroke
org1=self.origin+self.proj_ofs;
org2=self.enemy.origin;
if(vlen(org2-org1)>60)
return;
traceline(org1,org2,FALSE,self);
if(trace_ent!=self.enemy)
{
org2=(self.enemy.absmin+self.enemy.absmax)*0.5;
traceline(org1,org2,FALSE,self);
}
if(!trace_ent.takedamage)
return;
if(self.model=="models/spider.mdl")
ldmg=random(self.scale*3);
else
ldmg = random(9);
T_Damage (trace_ent, self, self, ldmg);
}
/*
* ai_melee_side()
*/
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(9);
T_Damage (self.enemy, self, self, ldmg);
}

144
fireball.hc Normal file
View File

@ -0,0 +1,144 @@
/*
* $Header: /HexenWorld/Siege/fireball.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
FIREBALL
==============================================================================
*/
// For building the model
$cd c:\model\fireball // Directory to find model in
$origin 0 0 0
// baseframe is in iceimp.3ds
$base fireball
// skin is in iceimp.lbm
$skin fireball
// Imp throwing
$frame firbal1 firbal2 firbal3 firbal4 firbal5
$frame firbal6 firbal7 firbal8 firbal9 firbal10
//============================================================================
void FireFizzle (void)
{
sound (self, CHAN_WEAPON, "misc/fout.wav", 1, ATTN_NORM);
DeathBubbles(1);
remove(self);
}
void() fireballTouch =
{
local float damg;
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
if (self.dmg == -1)
damg = random(5,10);
else if (self.dmg)
damg = self.dmg;
else
damg = random(12,22);
if (other.health)
{
if (self.owner.classname == "cube_of_force")
T_Damage (other, self.owner, self.owner.owner, damg );
else
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, damg, other);
// sound (self, CHAN_WEAPON, "weapons/explode.wav", 1, ATTN_NORM);
self.origin = self.origin - 8*normalize(self.velocity);
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);
remove(self);
// BecomeExplosion ();
};
//============================================================================
void fireball_1(void)
{
float retval;
self.nextthink = time + HX_FRAME_TIME;
retval = AdvanceFrame($firbal1,$firbal10);
if (retval == AF_BEGINNING)
{
if (pointcontents(self.origin) != CONTENT_EMPTY)
FireFizzle();
}
}
//============================================================================
void(vector offset) do_fireball =
{
entity missile;
vector vec;
missile = spawn ();
missile.owner = self;
missile.speed=500;
if(self.classname=="monster_imp_lord")
{
missile.dmg=random(80,120);
missile.speed+=500;
missile.scale=2;
}
else
missile.dmg = self.dmg;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.health = 10;
setmodel (missile, "models/fireball.mdl");
setsize (missile, '0 0 0', '0 0 0');
// set missile speed
makevectors (self.angles);
vec = self.origin + self.view_ofs + v_factor(offset);
setorigin (missile, vec);
vec = self.enemy.origin - missile.origin + self.enemy.view_ofs;
vec = normalize(vec);
missile.velocity = (vec+aim_adjust(self.enemy))*missile.speed;
missile.angles = vectoangles('0 0 0'-missile.velocity);
missile.touch = fireballTouch;
missile.think = fireball_1;
missile.nextthink = time + HX_FRAME_TIME;
};

552
fish.hc Normal file
View File

@ -0,0 +1,552 @@
/*
* $Header: /HexenWorld/Siege/Fish.hc 9 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\monsters\FISH\FISH1.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\monsters\FISH
$origin 0 0 0
$base BASE SKIN
$skin SKIN
$skin SKIN2
$flags 0
//
$frame SWIM01 SWIM02 SWIM03 SWIM04 SWIM05
$frame SWIM06 SWIM07 SWIM08 SWIM09 SWIM10
$frame SWIM11 SWIM12 SWIM13 SWIM14 SWIM15
$frame SWIM16 SWIM17 SWIM18 SWIM19 SWIM20
$frame SWIM21 SWIM22 SWIM23 SWIM24 SWIM25
$frame SWIM26 SWIM27 SWIM28 SWIM29 SWIM30
$frame SWIM31 SWIM32 SWIM33 SWIM34 SWIM35
$frame SWIM36 SWIM37 SWIM38 SWIM39 SWIM40
// Frame Code
float FISH_STAGE_MOVE = 1;
float FISH_STAGE_FOLLOW = 2;
float FISH_STAGE_BORED = 3;
void fish_hover(void);
void fish_move(void);
float fish_friends(void)
{
entity item,test;
float bad;
item = findradius(self.origin, 100);
while (item)
{
if (item.classname == "monster_fish" && item != self)
{
test = item.goalentity;
bad = FALSE;
while(test != world && bad != TRUE)
{
if (test == self) bad = TRUE;
test = test.goalentity;
}
if (!bad)
{
self.goalentity = item;
self.goalentity.fish_leader_count += 1;
return TRUE;
}
}
item = item.chain;
}
return FALSE;
}
void fish_follow(void)
{
thinktime self : HX_FRAME_TIME;
AdvanceFrame($SWIM01,$SWIM40);
if (random() > 0.1)
return;
if (random() < .05)
{
self.monster_duration = random(250,450);
self.monster_stage = FISH_STAGE_BORED;
self.think = fish_hover;
self.goalentity.fish_leader_count -= 1;
self.goalentity = world;
//dprint("Fish got bored\n");
// self.drawflags (-) MLS_ABSLIGHT;
}
self.movedir = self.monster_last_seen - self.origin + randomv('-20 -20 -25', '20 20 25');
if (self.goalentity.goalentity)
{
self.goalentity.fish_leader_count -= 1;
self.goalentity = self.goalentity.goalentity;
self.goalentity.fish_leader_count += 1;
}
self.monster_last_seen = self.goalentity.origin;
self.count = 80 + random(20);
self.movedir_x /= self.count;
self.movedir_y /= self.count;
self.movedir_z /= self.count;
self.fish_speed = vhlen(self.movedir);
self.think = fish_move;
}
void fish_move(void)
{
float retval;
thinktime self : HX_FRAME_TIME;
AdvanceFrame($SWIM01,$SWIM40);
self.ideal_yaw = vectoyaw(self.movedir);
ChangeYaw();
retval = walkmove(self.angles_y, self.fish_speed, FALSE);
retval = movestep(0, 0, self.movedir_z, FALSE);
/* if (retval != 2)
{
self.goalentity = world;
self.monster_stage = FISH_STAGE_MOVE;
}
*/
if (self.count >= 170)
self.fish_speed *= 1.05;
else if (self.count < 30)
self.fish_speed *= .9;
self.count -= 1;
if (self.count < 1)
{
self.count = 0;
if (self.monster_stage == FISH_STAGE_MOVE)
{
if (fish_friends())
{
self.monster_stage = FISH_STAGE_FOLLOW;
self.think = fish_follow;
self.monster_last_seen = self.goalentity.origin;
//self.drawflags (+) MLS_ABSLIGHT;
//self.abslight = 0;
//self.goalentity.drawflags (+) MLS_ABSLIGHT;
//self.goalentity.abslight = 2.5;
//dprint("Following!\n");
}
else
self.think = fish_hover;
}
else if (self.monster_stage == FISH_STAGE_FOLLOW)
self.think = fish_follow;
else if (self.monster_stage == FISH_STAGE_BORED)
self.think = fish_hover;
}
}
void fish_hover(void)
{
float try;
thinktime self : HX_FRAME_TIME;
AdvanceFrame($SWIM01,$SWIM40);
if (self.monster_stage == FISH_STAGE_BORED)
{
self.monster_duration -= 1;
if (self.monster_duration <= 0)
self.monster_stage = FISH_STAGE_MOVE;
}
if (random() < 0.02)
{
try = 0;
while (try < 10)
{
self.movedir = randomv('-100 -100 -30', '100 100 30');
tracearea(self.origin, self.origin + self.movedir, self.mins, self.maxs, FALSE, self);
if (trace_fraction == 1)
{
self.think = fish_move;
self.count = 170 + random(30);
self.movedir_x /= 400;
self.movedir_y /= 400;
self.movedir_z /= 400;
self.fish_speed = vhlen(self.movedir);
try = 999;
}
try += 1;
}
}
}
void fish_die(void)
{
remove(self);
}
/*QUAKED monster_fish (1 0 0) (-16 -16 -8) (16 16 8)
Ambient Fish
-------------------------FIELDS-------------------------
skin: 0 = bright colored, 1 = darker colored
--------------------------------------------------------
*/
void monster_fish(void)
{
precache_model2 ("models/fish.mdl");
self.takedamage = DAMAGE_YES;
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_FLY;
self.flags (+) FL_SWIM | FL_MONSTER;
self.yaw_speed = 2;
self.hull = HULL_PLAYER;
self.monster_stage = FISH_STAGE_MOVE;
self.mass = 99999; // Big fishies!
// self.drawflags (+) MLS_POWERMODE;
setmodel (self, "models/fish.mdl");
self.skin = 0;
setsize (self, '-10 -10 -8', '10 10 8');
self.health = 1;
self.th_die = fish_die;
self.think = fish_hover;
thinktime self : HX_FRAME_TIME;
}
//SIEGE PIRHANA
void() swimmonster_start_go =
{
// if(!self.touch)
// self.touch=obj_push;
self.ideal_yaw = self.angles * '0 1 0';
if (!self.yaw_speed)
self.yaw_speed = 10;
if(self.view_ofs=='0 0 0');
self.view_ofs = '0 0 2';
if(self.proj_ofs=='0 0 0');
self.proj_ofs = '0 0 2';
self.use = monster_use;
self.flags(+)FL_MONSTER;
if (self.target)
{
self.goalentity = self.pathentity = find(world, targetname, self.target);
if (!self.pathentity)
{
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+=random(0.5);
};
void() swimmonster_start =
{
// spread think times so they don't all happen at same time
self.takedamage=DAMAGE_YES;
self.nextthink+=random(0.5);
self.think = swimmonster_start_go;
total_monsters = total_monsters + 1;
self.monster_awake=TRUE;
};
void()fish_melee;
void pirhana_flop_back ()
{
if(pointcontents(self.origin)==CONTENT_WATER)
{
self.avelocity='0 0 0';
self.movetype=MOVETYPE_SWIM;
self.angles_x=self.angles_z=0;
self.think = self.th_stand;
thinktime self : 0;
return;
}
if(self.cnt>3)
{
self.cnt=0;
setorigin(self,self.init_org);
self.think=pirhana_flop_back;
thinktime self: 0.5;
}
else
{
self.cnt+=1;
self.velocity=normalize(self.wallspot - self.origin);
self.velocity=self.velocity*400;
self.velocity_z=270;
self.avelocity=self.velocity*random(-3,3);
self.flags(-)FL_ONGROUND;
self.think=pirhana_flop_back;
thinktime self: 2;
}
}
void pirhana_throw ()
{
self.wallspot=self.origin;
self.velocity=normalize(self.enemy.origin+(random(self.enemy.maxs_z)*'0 0 1')-self.origin);
self.angles=vectoangles(self.velocity);
self.velocity=self.velocity*400+' 0 0 200';
self.movetype=MOVETYPE_BOUNCE;
self.flags(-)FL_ONGROUND;
self.touch=fish_melee;
self.think=pirhana_flop_back;
thinktime self: 2;
}
void pirhana_check_enemy ()
{
if(pointcontents(self.enemy.origin)==CONTENT_WATER)
self.search_time=time+5;
if(self.enemy.health<=0||self.enemy.rings & RING_WATER||self.search_time<time)
self.enemy=world;
else
if(self.search_time<=time+4.5)
{
if(self.last_time<time)
{
if(random()<0.5)
{
if(vlen(self.enemy.origin-self.origin)<200)
{
if(lineofsight(self,self.enemy)||random()<0.3)
{
self.last_time=time+10;
self.think=pirhana_throw;
thinktime self : 0;
pirhana_throw();
}
}
}
}
}
}
void pirhana_hunt ()
{
//Ideas...
//When find one tell all other pirhana so they don't have to do
//this search? Better yet, have only one thinker that does all the
//monster finding/checking for all the fish?
//Also allow some fish to be interrupted or ignore someone so they
//can go after multiple targets? Choose target by range?
entity found;
if(self.enemy.health>0)
return;
found=nextent(world);
while(found!=world)
{
if(pointcontents(found.origin)==CONTENT_WATER&&
found.takedamage&&
found.classname!=self.classname&&
found.thingtype==THINGTYPE_FLESH&&
(!found.rings & RING_WATER))
{
self.monster_awake=TRUE;
self.enemy=self.goalentity=found;
found=world;
self.think=self.th_run;
thinktime self : 0;
}
else
found=nextent(found);
}
}
void fish_run () //[++0 .. 39 ]
{
self.think=fish_run;
thinktime self: 0.05;
if(self.velocity_x||self.velocity_y||self.velocity_z)
self.velocity=self.velocity*0.75;
pirhana_check_enemy();
if(!self.enemy)
{
if(self.pathentity)
self.think=self.th_walk;
else
self.think=self.th_stand;
thinktime self : 0;
return;
}
ai_run(self.speed*0.75);
if(random()<0.05)
pirhana_hunt();
}
void fish_walk () //[++0 .. 39 ]
{
self.think=fish_walk;
thinktime self: 0.05;
if(self.velocity_x||self.velocity_y||self.velocity_z)
self.velocity=self.velocity*0.75;
pirhana_check_enemy();
ai_walk(self.speed/3);
if(random()<0.05)
pirhana_hunt();
}
void fish_stand () //[++0 .. 39 ]
{
self.think=fish_stand;
thinktime self: 0.05;
if(self.velocity_x||self.velocity_y||self.velocity_z)
self.velocity=self.velocity*0.75;
pirhana_check_enemy();
ai_stand();
if(random()<0.05)
pirhana_hunt();
}
void fish_melee ()
{
vector delta,hitspot;
float ldmg;
if(self.attack_finished>time)
return;
if (!self.enemy)
return; // removed before bite
hitspot = self.enemy.origin+(random(self.enemy.maxs_z))*'0 0 1';
delta = hitspot- self.origin;
if (vlen(delta) > 60)
return;
if(random()<0.3)
sound (self.enemy, CHAN_ITEM, "spider/bite.wav", 1, ATTN_NORM);
ldmg = (random() + random()) * 3;
if(self.enemy.health<=ldmg)
ldmg=100;
T_Damage (self.enemy, self, self, ldmg);
MeatChunks (hitspot,randomv('-200 -200 0','200 200 400'), 3,self.enemy);
SpawnPuff (hitspot, '0 0 0', 3,self.enemy);
if(self.movetype==MOVETYPE_BOUNCE)
self.attack_finished=time + 1;
}
void fish_attack()// [++0 .. 39 ]
{
self.think=fish_attack;
thinktime self: 0.05;
if(self.velocity_x||self.velocity_y||self.velocity_z)
self.velocity=self.velocity*0.75;
pirhana_check_enemy();
/*
if(pointcontents(self.enemy.origin)!=CONTENT_WATER)
{
if(vlen(self.enemy.origin-self.origin)<128)
if(random()<0.05)
{
self.flags(+)FL_FLY;
self.flags(-)FL_SWIM;
}
if(self.flags&FL_SWIM)
self.enemy=world;
}
*/
if(!self.enemy)
{
if(self.pathentity)
self.think=self.th_walk;
else
self.think=self.th_stand;
thinktime self : 0;
return;
}
ai_charge(self.speed);
if(random()<0.3)
fish_melee();
}
/*QUAKED monster_pirhana (1 0 0) (-16 -16 0) (16 16 28)
*/
void() monster_pirhana =
{
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
precache_model ("models/fish.mdl");
precache_sound ("spider/bite.wav");
setmodel (self,"models/fish.mdl");
setsize (self, '0 0 0', '0 0 0');
// setsize (self, '-4 -4 -4', '4 4 4');
self.hull=HULL_POINT;//use pentacles
self.health=10000000;
self.init_org=self.origin;
/*
if(skill==3)
self.health = 800;
else
self.health = 400;
*/
self.mass = 0.1;
self.speed=14+random(6);
self.thingtype=THINGTYPE_FLESH;
self.th_stand = fish_stand;
self.th_walk = fish_walk;
self.th_run = fish_run;
self.th_die = chunk_death;
self.th_melee = fish_attack;
// self.flags2(+)FL_ALIVE;
self.flags(+)FL_SWIM;
swimmonster_start ();
};

15
flag.hc Normal file
View File

@ -0,0 +1,15 @@
/*
* $Header: /HexenWorld/Siege/Flag.hc 3 5/25/98 1:38p Mgummelt $
*/
/*QUAKED item_deathball (.3 .3 1) (0 0 0) (32 32 32)
-----------------------FIELDS-------------------------
--------------------------------------------------------
*/
void() deathball_touch;
void() item_deathball =
{
self.touch = deathball_touch;
};

782
flameorb.hc Normal file
View File

@ -0,0 +1,782 @@
/*
==============================================================================
Q:\art\models\weapons\spllbook\spllbook.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\weapons\spllbook
$origin 0 0 0
$base BASE skin
$skin skin
$flags 0
//
$frame idlebn01 idlebn02 idlebn03 idlebn04 idlebn05
$frame idlebn06 idlebn07 idlebn08 idlebn09 idlebn10
$frame idlebn11 idlebn12 idlebn13 idlebn14 idlebn15
$frame idlebn16 idlebn17 idlebn18 idlebn19 idlebn20
$frame idlebn21 idlebn22 idlebn23 idlebn24 idlebn25
//
$frame idlean26 idlean27 idlean28 idlean29 idlean30
$frame idlean31 idlean32 idlean33 idlean34 idlean35
$frame idlean36 idlean37 idlean38 idlean39 idlean40
$frame idlean41 idlean42 idlean43 idlean44 idlean45
$frame idlean46 idlean47 idlean48 idlean49 idlean50
//
$frame normal51 normal52 normal53 normal54 normal55
$frame normal56 normal57 normal58 normal59 normal60
$frame normal61 normal62 normal63 normal64
//
$frame topowr65 topowr66 topowr67 topowr68 topowr69
$frame topowr70 topowr71 topowr72 topowr73 topowr74
$frame topowr75 topowr76 topowr77 topowr78 topowr79
$frame topowr80 topowr81 topowr82 topowr83 topowr84
//
$frame pidleb085 pidleb086 pidleb087 pidleb088 pidleb089
$frame pidleb090 pidleb091 pidleb092 pidleb093 pidleb094
$frame pidleb095 pidleb096 pidleb097 pidleb098 pidleb099
$frame pidleb100 pidleb101 pidleb102 pidleb103 pidleb104
$frame pidleb105 pidleb106 pidleb107 pidleb108 pidleb109
//
$frame pidlea110 pidlea111 pidlea112 pidlea113 pidlea114
$frame pidlea115 pidlea116 pidlea117 pidlea118 pidlea119
$frame pidlea120 pidlea121 pidlea122 pidlea123 pidlea124
$frame pidlea125 pidlea126 pidlea127 pidlea128 pidlea129
$frame pidlea130 pidlea131 pidlea132 pidlea133 pidlea134
//
$frame powern135 powern136 powern137 powern138 powern139
$frame powern140 powern141 powern142 powern143 powern144
$frame powern145 powern146 powern147 powern148
//
$frame tonrml149 tonrml150 tonrml151 tonrml152 tonrml153
$frame tonrml154 tonrml155 tonrml156 tonrml157 tonrml158
$frame tonrml159 tonrml160 tonrml161 tonrml162 tonrml163
$frame tonrml164 tonrml165 tonrml166 tonrml167 tonrml168
//
$frame ndesel213 ndesel214 ndesel215 ndesel216 ndesel217
$frame ndesel218 ndesel219 ndesel220 ndesel221 ndesel222
$frame ndesel223
//
$frame pselon224 pselon225 pselon226 pselon227 pselon228
$frame pselon229 pselon230 pselon231 pselon232 pselon233
$frame pselon234
/*
void burner_think ()
{
if(self.lifetime<time||self.enemy.health<0)
{
stopSound(self.enemy,CHAN_BODY);
//sound(self.enemy,CHAN_BODY,"misc/null.wav",1,ATTN_NORM);
self.enemy.flags2 (-) FL2_ONFIRE;
self.enemy.effects (-) EF_DIMLIGHT;
self.enemy.effects (-) EF_ONFIRE;
remove(self);
return;
}
else if(pointcontents(self.enemy.origin)==CONTENT_WATER)
{
sound (self.enemy, CHAN_BODY, "misc/fout.wav", 1, ATTN_NORM);
smolder((self.enemy.absmin+self.enemy.absmax)*0.5);
self.enemy.flags2 (-) FL2_ONFIRE;
self.enemy.effects (-) EF_DIMLIGHT;
self.enemy.effects (-) EF_ONFIRE;
remove(self);
return;
}
else
{
//org=(self.enemy.absmin+self.enemy.absmax)*0.5+randomv(self.enemy.size*-0.25,self.enemy.size*0.25);
//vel=randomv('-3 -3 0','3 3 7');
//starteffect(CE_ONFIRE, org,vel, 0);
//sound(self.enemy,CHAN_BODY,"raven/fire1.wav",1,ATTN_NORM);
thinktime self : random(0.5);
T_Damage(self.enemy,self,self.owner,self.enemy.fire_damage + random(1));
}
}
void spawn_burner (entity loser)
{
if (loser.flags2 & FL2_ONFIRE)
{
loser.fire_damage += 2;
return;
}
if (coop && loser.classname == "player" && loser.team == self.owner.team && teamplay)
return;
loser.fire_damage = 2;
entity burner;
burner=spawn();
burner.owner=self.owner;
burner.enemy=loser;
burner.lifetime=time+random(5)+5;
burner.think=burner_think;
burner.effects (+) EF_NODRAW;
burner.enemy.effects (+) EF_DIMLIGHT;
thinktime burner : 0;
burner.enemy.flags2 (+) FL2_ONFIRE;
burner.enemy.effects (+) EF_ONFIRE;
//sound(self,CHAN_AUTO,"weapons/fbfire.wav",1,ATTN_NORM);
starteffect(CE_LG_EXPLOSION , self.origin);
}
*/
float isFlammable()
{
if (other.thingtype == THINGTYPE_FLESH ||
other.thingtype == THINGTYPE_WOOD ||
other.thingtype == THINGTYPE_HAY ||
other.thingtype == THINGTYPE_LEAVES ||
other.thingtype == THINGTYPE_CLOTH ||
other.thingtype == THINGTYPE_WOOD_LEAF ||
other.thingtype == THINGTYPE_WOOD_METAL ||
other.thingtype == THINGTYPE_WOOD_STONE ||
other.thingtype == THINGTYPE_METAL_CLOTH)
{
return 1;
}
return 0;
}
void flamestream_touch ()
{
self.velocity = '0 0 0';
if(other.classname=="flamestream")
return;
if(other.takedamage)
{
float old_health;
vector other_org;
if (isFlammable())
{
spawn_burner(other,FALSE);
}
other_org=other.origin;
old_health=other.health;
T_Damage(other,self,self.owner,self.dmg + random(1,5));
if(other.health<=0&&old_health>0)
smolder(other_org);
}
else
{
T_RadiusDamage(self,self.owner,40,self.owner);
}
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_FIREWALL_IMPACT);
WriteCoord (MSG_MULTICAST, self.origin_x - self.movedir_x * 24);
WriteCoord (MSG_MULTICAST, self.origin_y - self.movedir_y * 24);
WriteCoord (MSG_MULTICAST, self.origin_z - self.movedir_z * 24);
multicast(self.origin,MULTICAST_PHS_R);
remove(self);
}
void flamestreamThink()
{
makevectors(self.angles);
float old_health;
vector other_org;
traceline(self.origin, self.origin + '0 0 -256', FALSE, self);
if (trace_ent)
{
if (isFlammable())
{
spawn_burner(trace_ent,FALSE);
}
other_org=trace_ent.origin;
old_health=trace_ent.health;
if(trace_ent.health<=0&&old_health>0)
{
smolder(other_org);
}
}
self.angles = vectoangles(self.movedir);
traceline(self.origin, self.origin + self.movedir * 450, FALSE, self);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_FIREWALL);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
WriteByte (MSG_MULTICAST, self.angles_y*256.0/360.0);
WriteByte (MSG_MULTICAST, self.angles_x*256.0/360.0);
WriteByte (MSG_MULTICAST, trace_fraction * 8.0);
multicast(self.origin,MULTICAST_PVS);
if (self.lifetime < time) self.touch();
self.think = flamestreamThink;
thinktime self : 0.3;
}
// regular attack
void flamestream_fire ()
{
self.effects (+) EF_MUZZLEFLASH;
self.greenmana-=4;
self.punchangle_x = -2;
makevectors(self.v_angle);
self.velocity+=normalize(v_forward) * -100;
self.flags(-)FL_ONGROUND;
newmis=spawn();
newmis.classname="flamestream";
newmis.owner=self;
newmis.movetype=MOVETYPE_FLYMISSILE;
newmis.solid=SOLID_BBOX;
newmis.touch=flamestream_touch;
newmis.dmg=40;
newmis.lifetime=time+2;
newmis.o_angle=self.origin+self.proj_ofs+v_forward*16-v_right*16-v_up*16;
newmis.movedir=v_forward;
newmis.speed=1500+random(50);
newmis.velocity=newmis.movedir*newmis.speed;
setmodel(newmis,"models/null.spr");
setsize(newmis,'-6 -6 -6','6 6 6');
newmis.level=0;
newmis.hull=HULL_POINT;
setorigin(newmis,newmis.o_angle);
newmis.wallspot=newmis.origin;
newmis.count = 20;
newmis.cnt = 0;
newmis.effects (+) EF_NODRAW;
newmis.think=flamestreamThink;
thinktime newmis : 0.3;
newmis.angles = vectoangles(newmis.movedir);
traceline(newmis.origin, newmis.origin + newmis.movedir * 450, FALSE, newmis);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_FIREWALL);
WriteCoord (MSG_MULTICAST, newmis.origin_x);
WriteCoord (MSG_MULTICAST, newmis.origin_y);
WriteCoord (MSG_MULTICAST, newmis.origin_z);
WriteByte (MSG_MULTICAST, newmis.angles_y*256.0/360.0);
WriteByte (MSG_MULTICAST, newmis.angles_x*256.0/360.0);
WriteByte (MSG_MULTICAST, trace_fraction * 8.0);
multicast(self.origin,MULTICAST_PVS);
}
void flameball_touch()
{
if (other.takedamage)
{
float old_health;
vector other_org;
// sound(self,CHAN_BODY,"succubus/flamend.wav",0.5,ATTN_NORM);
other_org=other.origin;
old_health=other.health;
T_Damage(other,self,self.owner,random(10,20));
if(other.health<=0&&old_health>0)
smolder(other_org);
}
/* else//no need for this why damage it if it can't take damage?
{
T_Damage(other, self.owner, self.owner, 10);
}*/
// these'll be made on the client
/* rand = random();
if (rand < 0.2)
starteffect(CE_SM_EXPLOSION, self.origin-self.movedir*6, '0 0 6', 0);
else if (rand < 0.3)
starteffect(CE_FBOOM, self.origin-self.movedir*6, '0 0 6', 0);
else
starteffect(CE_BOMB, self.origin-self.movedir*6, '0 0 6', 0);*/
remove(self);
}
void flameball_think()
{
// starteffect(CE_FLAMESTREAM, self.origin, '0 0 2', 0);
self.think = SUB_Remove;
thinktime self : 2;
}
void flameball_spawn(vector pos, entity targ)
{
newmis = spawn();
newmis.classname = "flameball";
newmis.owner = self.owner;
setmodel(newmis, "models/sucwp1p.mdl");
setsize(newmis, '-3 -3 -3', '3 3 3');
newmis.hull = HULL_POINT;
newmis.solid = SOLID_BBOX;
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.drawflags (+) MLS_ABSLIGHT;
newmis.abslight = 0.5;
newmis.frame = 4;
newmis.effects (+) EF_NODRAW; // these'll be made on the client
setorigin(newmis, pos);
pos = targ.origin - newmis.origin;
pos = normalize(pos);
pos *= 800 + random(100);
newmis.velocity = pos;
newmis.angles = vectoangles(newmis.velocity);
newmis.movedir = normalize(newmis.velocity);
// starteffect(CE_FLAMESTREAM, newmis.origin, '0 0 0', 0);
newmis.touch = flameball_touch;
newmis.think = flameball_think;
thinktime newmis : 0.05;
}
void flameswarmBoom()
{
local vector rand;
if (self.lifetime < time || self.lockentity.origin == '0 0 0')
{
self.lockentity.effects (-) EF_POWERFLAMEBURN;
remove(self);
return;
}
if (self.attack_finished < time)
{
sound(self,CHAN_BODY,"succubus/flamend.wav",0.5,ATTN_NORM);
self.attack_finished = time + 1.5;
}
makevectors(self.lockentity.angles);
rand = self.lockentity.origin + '0 0 200' + randomv('-140 -140 -140', '140 140 140');
traceline(self.lockentity.origin, rand, TRUE, self);
flameball_spawn(trace_endpos, self.lockentity);
self.think = flameswarmBoom;
thinktime self : 0.1;
}
void flameswarm_touch ()
{
entity found,loser;
float lastdist,dist;
float old_health;
vector loser_org;
self.velocity = '0 0 0';
if(other.classname=="flamestream")
return;
loser=other;
if(!loser.takedamage)
{
found=findradius(self.origin,200);
lastdist=200;
dist=0;
while(found)
{
dist=vlen((loser.absmin+loser.absmax)*0.5-self.origin);
if(dist<lastdist)
{
lastdist=dist;
loser=found;
}
found=found.chain;
}
sound(self,CHAN_BODY,"succubus/flampow.wav",0.5,ATTN_NORM);
starteffect(CE_FBOOM, self.origin-self.movedir*6,'0 0 0', 0);
T_RadiusDamage(self,self.owner,50+random(1,10),self.owner);
remove(self);
}
else
{
loser_org=loser.origin;
old_health=loser.health;
//starteffect(CE_FBOOM, self.origin-self.movedir*6,'0 0 0', 0);
T_Damage(other, self.owner, self.owner, 20);
if(loser.health<=0&&old_health>0)
smolder(loser_org);
sound(self,CHAN_BODY,"succubus/flampow.wav",0.5,ATTN_NORM);
self.lockentity = loser;
self.lifetime = time + 3;
self.solid = SOLID_NOT;
self.effects (+) EF_NODRAW;
loser.effects (+) EF_POWERFLAMEBURN;
self.think = flameswarmBoom;
thinktime self : 0.1;
return;
}
}
void flameswarmThink()
{
self.angles = vectoangles(self.movedir);
makevectors(self.angles);
traceline(self.origin, self.origin + self.movedir * 450, FALSE, self);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_POWERFLAME);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
WriteByte (MSG_MULTICAST, self.angles_y*256.0/360.0);
WriteByte (MSG_MULTICAST, self.angles_x*256.0/360.0);
WriteByte (MSG_MULTICAST, trace_fraction * 8.0);
WriteLong (MSG_MULTICAST, time);
multicast(self.origin,MULTICAST_PVS);
if (self.lifetime < time) self.touch();
self.think = flameswarmThink;
thinktime self : 0.3;
}
// tome of power attack
void flameswarm_fire()
{
makevectors(self.v_angle);
self.greenmana-=8;
self.effects(+)EF_MUZZLEFLASH;
self.velocity+=normalize(v_forward) * -200;
self.punchangle_x = -6;
self.flags(-)FL_ONGROUND;
newmis=spawn();
newmis.classname="flamestream";
newmis.owner=self;
newmis.movetype=MOVETYPE_FLYMISSILE;
newmis.solid=SOLID_BBOX;
newmis.abslight=1;
newmis.touch=flameswarm_touch;
newmis.dmg=40;
newmis.lifetime=time+2;
newmis.o_angle=self.origin+self.proj_ofs+v_forward*16-v_right*24-v_up*16;
newmis.movedir=v_forward;
newmis.speed=1250+random(50);
newmis.velocity=newmis.movedir*newmis.speed;
setmodel(newmis,"models/null.spr");
setsize(newmis,'-6 -6 -6','6 6 6');
newmis.level=0;
newmis.hull=HULL_POINT;
setorigin(newmis,newmis.o_angle);
newmis.wallspot=newmis.origin;
newmis.angles = vectoangles(newmis.velocity);
newmis.effects (+) EF_NODRAW;
newmis.think=flameswarmThink;
thinktime newmis : 0.3;
newmis.angles = vectoangles(newmis.movedir);
traceline(newmis.origin, newmis.origin + newmis.movedir * vlen(newmis.velocity)*.3, FALSE, newmis);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_POWERFLAME);
WriteCoord (MSG_MULTICAST, newmis.origin_x);
WriteCoord (MSG_MULTICAST, newmis.origin_y);
WriteCoord (MSG_MULTICAST, newmis.origin_z);
WriteByte (MSG_MULTICAST, newmis.angles_y*256.0/360.0);
WriteByte (MSG_MULTICAST, newmis.angles_x*256.0/360.0);
WriteByte (MSG_MULTICAST, trace_fraction * 8.0);
WriteLong (MSG_MULTICAST, time);
multicast(self.origin,MULTICAST_PVS);
}
/*======================
ACTION
select
deselect
ready loop
relax loop
fire once
fire loop
ready to relax(after short delay)
relax to ready(Fire delay? or automatic if see someone?)
=======================*/
void()flameorb_ready_power;
void()flameorb_ready_normal;
void flameorb_fire (void)
{
if(self.artifact_active&ART_TOMEOFPOWER)
self.wfs = advanceweaponframe($powern135,$powern148);
else
self.wfs = advanceweaponframe($normal51,$normal64);
/*if(self.button0&&self.weaponframe>$normal60 &&!self.artifact_active&ART_TOMEOFPOWER)
self.weaponframe=$normal60;*/
self.th_weapon=flameorb_fire;
self.last_attack=time;
if(self.wfs==WF_CYCLE_WRAPPED||self.greenmana<1||(self.greenmana<10&&self.artifact_active&ART_TOMEOFPOWER))
{
self.t_width=-1;
self.weaponframe_cnt=0;
if(!self.artifact_active&ART_TOMEOFPOWER)
{
self.aflag=FALSE;
//self.attack_finished=time+0.2;
self.attack_finished=time+0.5; // 0.2 is REALLY fast for an attack this visually expensive
flameorb_ready_normal();
}
else
{
self.attack_finished = time + 1;
flameorb_ready_power();
}
}
else if(self.weaponframe==$normal52)
{
if(self.t_width==-1)
{
sound(self,CHAN_BODY,"succubus/flamstrt.wav",0.5,ATTN_NORM);
self.t_width=FALSE;
}
if(self.t_width<time)
{
//sound(self,CHAN_WEAPON,"succubus/flamloop.wav",0.5,ATTN_NORM);
self.t_width=time+0.45;
}
if(!self.weaponframe_cnt)
flamestream_fire();
self.weaponframe_cnt+=1;
if(self.weaponframe_cnt==20)
self.weaponframe_cnt=0;
}
else if(self.weaponframe == $powern136)//Fixme: hold this frame for a few
{
sound(self,CHAN_BODY,"succubus/flamstrt.wav",0.5,ATTN_NORM);
flameswarm_fire();
}
}
void Suc_Forb_Fire()
{
flameorb_fire();
thinktime self : 0;
}
void flameorb_jellyfingers_normal ()
{
self.wfs = advanceweaponframe($idlebn01,$idlebn25);
self.th_weapon=flameorb_jellyfingers_normal;
if(self.wfs==WF_CYCLE_WRAPPED)
if(self.artifact_active&ART_TOMEOFPOWER)
flameorb_ready_power();
else
flameorb_ready_normal();
}
void flameorb_jellyfingers_power ()
{
self.wfs = advanceweaponframe($pidleb085,$pidleb108);
self.th_weapon=flameorb_jellyfingers_power;
if(self.wfs==WF_CYCLE_WRAPPED)
if(self.artifact_active&ART_TOMEOFPOWER)
flameorb_ready_power();
else
flameorb_ready_normal();
}
void flameorb_to_power (void)
{
self.wfs = advanceweaponframe($topowr65,$topowr84);
self.th_weapon=flameorb_to_power;
if(self.wfs==WF_CYCLE_WRAPPED)
flameorb_ready_power();
}
void flameorb_to_normal (void)
{
self.wfs = advanceweaponframe($tonrml149,$tonrml168);
self.th_weapon=flameorb_to_normal;
if(self.wfs==WF_CYCLE_WRAPPED)
flameorb_ready_normal();
}
void flameorb_ready_normal (void)
{
self.wfs = advanceweaponframe($idlean26,$idlean50);
if(random()<0.1&&self.weaponframe==$idlean50)
self.th_weapon=flameorb_jellyfingers_normal;
else
self.th_weapon=flameorb_ready_normal;
if(self.artifact_active&ART_TOMEOFPOWER)
{
self.weaponframe=$topowr65;
flameorb_to_power();
}
}
void flameorb_ready_power (void)
{
self.wfs = advanceweaponframe($pidlea110,$pidlea134);
if(random()<0.1&&self.weaponframe==$pidlea134)
self.th_weapon=flameorb_jellyfingers_power;
else
self.th_weapon=flameorb_ready_power;
if(!self.artifact_active&ART_TOMEOFPOWER)
{
self.weaponframe=$tonrml149;
flameorb_to_normal();
}
}
void flameorb_select_normal (void)
{
self.wfs = advanceweaponframe($ndesel223,$ndesel213);
self.weaponmodel = "models/sucwp3.mdl";
self.th_weapon=flameorb_select_normal;
self.t_width=-1;
if(self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
flameorb_ready_normal();
}
}
void flameorb_select_power (void)
{
self.wfs = advanceweaponframe($pselon224,$pselon234);
self.weaponmodel = "models/sucwp3.mdl";
self.th_weapon=flameorb_select_power;
self.t_width=-1;
if(self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
flameorb_ready_power();
}
}
void flameorb_select (void)
{
self.weaponframe_cnt = 0;
if(self.artifact_active&ART_TOMEOFPOWER)
flameorb_select_power();
else
flameorb_select_normal();
}
void flameorb_deselect_normal (void)
{
self.wfs = advanceweaponframe($ndesel213,$ndesel223);
self.th_weapon=flameorb_deselect_normal;
if(self.wfs==WF_CYCLE_WRAPPED)
W_SetCurrentAmmo();
}
void flameorb_deselect_power (void)
{
self.wfs = advanceweaponframe($pselon234,$pselon224);
self.th_weapon=flameorb_deselect_power;
if(self.wfs==WF_CYCLE_WRAPPED)
W_SetCurrentAmmo();
}
void flameorb_deselect (void)
{
if(self.artifact_active&ART_TOMEOFPOWER)
flameorb_deselect_power();
else
flameorb_deselect_normal();
}

425
flames.hc Normal file
View File

@ -0,0 +1,425 @@
void(vector org) SpawnFlameAt;
void () FireDie =
{
T_RadiusDamage (self, self.owner, (self.dmg - 1)*125+25, world);
self.origin = self.origin - 8*normalize(self.velocity);
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 (FALSE);
remove(self);
};
void() FireDamage =
{
local float damagemult;
if(self.trigger_field.skin>110)
self.wait=0;
else self.wait = self.wait - 1;
if (self.trigger_field.classname == "player" && self.owner.classname != "player")
self.owner = self.trigger_field;
if (self.trigger_field.waterlevel > 2)
if(self.trigger_field.watertype == CONTENT_LAVA)
{
if(self.trigger_field.classname=="player")
{
sprintname(self.owner,PRINT_MEDIUM,self.trigger_field);
sprint(self.owner," jumped out of the frying pan into the fire!\n");
}
self.trigger_field.effects = 0;
self.trigger_field.onfire = 0;
remove(self);
// FireDie();
}
else
{
if(self.trigger_field.classname=="player")
{
sound (self.owner, CHAN_WEAPON, "misc/fout.wav", 1, ATTN_NORM);
sprintname(self.owner,PRINT_MEDIUM,self.trigger_field);
}
sprint(self.owner," saved his ass by jumping in the water!\n");
self.trigger_field.effects = 0;
self.trigger_field.onfire = 0;
remove(self);
}
if ((self.waterlevel > 2) || (self.watertype == CONTENT_WATER) || (self.watertype == CONTENT_SLIME) || (pointcontents(self.origin) == CONTENT_WATER) || (pointcontents(self.origin) == CONTENT_SLIME))
{
sound (self.owner, CHAN_WEAPON, "misc/fout.wav", 1, ATTN_NORM);
sprint(self.owner,"Fireball fizzled underwater\n");
self.trigger_field.effects = 0;
self.trigger_field.onfire = 0;
remove(self);
}
// if (self.aflag != 5)
// {
//Non-explosive death
if ((self.wait < 1) || (self.trigger_field.health<=0))
{
self.trigger_field.effects = 0;
self.trigger_field.onfire = 0;
remove(self);
}
// }
// else if (self.wait < 1 || self.trigger_field.health <= 6)
// {
//explosive fireball death
// self.dmg = 2;
// self.trigger_field.onfire = 0;
// self.trigger_field.effects = 0;
// FireDie();
// }
if(self.trigger_field.onfire>0.5)
self.trigger_field.onfire=0.5;//Max out damage at 0.5 per think
if (!self.trigger_field.flags&FL_FIRERESIST)
{
if(self.aflag>0.1)
damagemult=self.aflag;
else
damagemult=0.1;
if(self.trigger_field.flags&FL_FIREHEAL)
self.trigger_field.health=self.trigger_field.health+2*damagemult*self.trigger_field.onfire;
else
T_Damage (self.trigger_field, self, self.owner, damagemult*self.trigger_field.onfire);
}
if(self.trigger_field.health<=17)
if(self.trigger_field.thingtype==THINGTYPE_WOOD)
{
self.trigger_field.skin=111;
self.trigger_field.deathtype="burnt crumble";
}
else if(self.trigger_field.thingtype==THINGTYPE_FLESH)
{
self.trigger_field.skin=112;
self.trigger_field.deathtype="burnt crumble";
}
//FIXME: need 3 different fire models to put on them,
//randomly choose one & scale it to their size, add more
// if they're more on fire. No more than 3. Only one
//fire sound, from "invisible" one doing actual damage.
//Use movechain function to link flames to target
if(random()<0.5)
SpawnFlameAt (self.origin);//This is causing an edict overflow hard crash...
self.origin = self.trigger_field.origin + '0 0 6';
self.think = FireDamage;
thinktime self : 0.1;
};
void() FireTouch2 =
{
self.trigger_field.effects = EF_BRIGHTLIGHT;
if(self.trigger_field.onfire<=0)
self.trigger_field.onfire = 1;
self.think=FireDamage;
thinktime self : 0;
};
void() FireTouch =
{
local float damg;
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
if (other.takedamage&&other.thingtype!=1&&other.thingtype!=0&&other.thingtype!=3&&other.skin<111)
{
if(other.onfire)
{
other.onfire=other.onfire+0.1;
remove(self);
}
else
other.onfire=0.1;
sound (self, CHAN_WEAPON, "misc/combust.wav", 1, ATTN_NORM);
self.trigger_field = other;
self.origin = other.origin + '0 0 6';
if (other.classname == "player" || self.aflag == 5)
self.wait = 180;
else
self.wait = 40;
setsize (self, '0 0 0', '0 0 0');
self.think=FireTouch2;
thinktime self : 0;
self.movetype = MOVETYPE_NOCLIP;
self.velocity = '0 0 0' ;
self.avelocity = '0 0 1000';
if ((other.waterlevel < 2) && (other.classname == "player"))
sprint(other, "You're burning up!\n");
return;
}
else if (self.movetype == MOVETYPE_FLYMISSILE)
remove(self);
// FireDie();
sound (self, CHAN_WEAPON, "misc/fburn_sm.wav", 0.75, ATTN_STATIC); // bounce sound
SpawnPuff(self.origin,'0 0 0', 10,other);
// spawn_touchblood (10);
SpawnFlameAt (self.origin);
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
if (self.aflag == 5)
{
self.trigger_field=self.enemy;
thinktime self : 0.05;
self.think = FireTouch2;
}
};
void () FireThink =
{
if (pointcontents(self.origin)==CONTENT_WATER||pointcontents(self.origin)==CONTENT_SLIME||(self.waterlevel > 2))
FireFizzle();
self.attack_finished = self.attack_finished + 0.1;
if (self.attack_finished > 5)
// if(self.model=="models/lavaball.spr")
// FireDie();
// else
remove(self);
thinktime self : 0.1;
self.think = FireThink;
};
void(entity loser) SpawnFlameOn =
{
if(pointcontents(loser.origin)<-2)
return;
//Used by player, archvile, and stickmine
local entity fire;
if (pointcontents(self.origin) < -2)
{
sound (self, CHAN_WEAPON, "misc/fout.wav", 1, ATTN_NORM);
return;
}
fire = spawn ();
fire.controller = self;
fire.movetype = MOVETYPE_NOCLIP;
fire.solid = SOLID_NOT;
fire.velocity = '0 0 0' ;
fire.avelocity = '0 0 1000';
fire.classname = "fire";
fire.dmg = 1;
fire.aflag = 0.25;
setmodel (fire, "models/null.spr");
fire.effects=EF_NODRAW;
setsize (fire, '0 0 0', '0 0 0');
if(self.classname=="fireballblast"||self.classname=="flaming arrow")
{
fire.enemy = loser;
setorigin (fire, (loser.absmax+loser.absmin)*0.5);
fire.owner=self;
}
else
{
setorigin (fire, (self.enemy.absmax+self.enemy.absmin)*0.5);
fire.enemy = self.enemy;
fire.owner = self.controller;
}
sound (fire, CHAN_WEAPON, "misc/combust.wav", 1, ATTN_NORM);
if(!loser.onfire)
loser.onfire=0.1;
else
{
loser.onfire+=0.1;
remove(fire);
return;
}
fire.trigger_field = loser;
if (loser.classname == "player")
fire.wait = 120;
else
fire.wait = 40;
thinktime fire : 0.1;
fire.think=FireTouch2;
};
void(vector org) SpawnFlameAt =
{
if(pointcontents(self.origin)<-2)
return;
local entity fireflame;
local float xorg, yorg, zorg;
fireflame = spawn();
setmodel (fireflame, "models/flame2.mdl");
fireflame.movetype = MOVETYPE_FLY;
fireflame.solid = SOLID_NOT;
fireflame.classname = "missile";
fireflame.drawflags(+)MLS_ABSLIGHT;
fireflame.abslight=0.5;
fireflame.frame = rint(random());
setsize (fireflame, '-2 -2 -2', '1 1 1');
xorg = random(-15,15);
yorg = random(-15,15);
zorg = random(-25,25);
setorigin (fireflame, org + v_forward * xorg + v_right * yorg + v_up * zorg);
fireflame.velocity_x += random(-40,40);
fireflame.velocity_y += random(-40,40);
fireflame.velocity_z += random(300);
fireflame.avelocity = '0 0 0';
if (random() < 0.3)
sound (self, CHAN_WEAPON, "misc/fburn_sm.wav", 1, ATTN_NORM);
thinktime fireflame : 0.5; // remove after half second
fireflame.think = SUB_Remove;
};
/*
================
FlameTouch
================
*/
void () FlameTouch =
{
local float rn;
//Scale size relative to other.size?
if (other.takedamage)
{
if(other.flags&FL_FIREHEAL)
other.health=other.health+1;
else if (!other.flags&FL_FIRERESIST)
T_Damage(other,self,self.owner,5);
if(other.thingtype==THINGTYPE_FLESH||other.thingtype==THINGTYPE_WOOD)
{
//set on fire
rn = random();
// 50% chance
if (rn <= 0.5||other.onfire>=1)
{
if(other.onfire)
other.onfire = other.onfire + 0.1;
remove(self);
}
other.onfire = other.onfire + 0.1;
if(self.owner.movetype==MOVETYPE_NONE)
self.wait = 20;
else self.wait = 60;
self.aflag = 0.1;
self.trigger_field = other;
self.think = FireTouch2;
thinktime self : 0;
self.solid = SOLID_NOT;
setmodel (self,"models/flame2.mdl");
}
else if(self.netname=="firespike")
{
//FIXME:else sprite
remove(self);
}
}
else
{
if(self.netname=="firespike")
{
if(other.thingtype==THINGTYPE_FLESH||other.thingtype==THINGTYPE_WOOD)
SpawnFlameAt(self.origin);
//FIXME:else sprite
remove(self);
}
else
{
self.velocity = '0 0 0';
self.velocity_z = random(24,48);
}
}
};
/*
================
W_FireFlame
================
*/
void(float offset) W_FireFlame =
{
local entity flame;
local float rn;
if(self.movetype!=MOVETYPE_NONE)
{
if (self.waterlevel > 2)
{
// makevectors (self.v_angle);
rn = random();
if (rn < 0.5)
sound (self, CHAN_WEAPON, "player/swim1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_WEAPON, "player/swim2.wav", 1, ATTN_NORM);
flame=spawn();
flame.owner=flame;
setorigin(flame,self.origin+self.proj_ofs + v_forward * 32 + v_up * random(8,16));
flame.think=DeathBubblesSpawn;
thinktime flame : 0;
return;
}
// Take away a shell
// self.currentammo = self.ammo_shells = self.ammo_shells - 1;
}
else if((random()>=0.1&&random()>=0.2)||(!other.takedamage))
return;
sound (self, CHAN_WEAPON, "paladin/purfire.wav", 1, ATTN_NORM);
flame = spawn ();
flame.owner = self;
flame.movetype = MOVETYPE_FLYMISSILE;
flame.solid = SOLID_BBOX;
flame.classname = "fire";
flame.drawflags(+)MLS_ABSLIGHT;
flame.abslight=0.5;
// set flame speed
if(self.classname=="player"&&self.playerclass==CLASS_PALADIN&&self.weapon==IT_WEAPON4)
{
self.punchangle_x= -1;
setmodel (flame, "models/purfir1.mdl");
flame.netname="firespike";
}
else
setmodel (flame, "models/flame2.mdl");
setsize (flame, '0 0 0', '0 0 0');
if(self.movetype==MOVETYPE_NONE)
{
flame.velocity='0 0 100';
setorigin (flame, self.origin + '0 0 16');
}
else
{
makevectors (self.v_angle);
flame.velocity = normalize(v_forward)*700 + v_up*random(32) + v_right * random(0-offset,offset);
setorigin (flame, self.origin+self.proj_ofs + v_forward * 32 + v_up * random(-8,8));
}
if(flame.netname=="firespike")
flame.angles=vectoangles(flame.velocity);
// flame.effects = 6;
flame.touch = FlameTouch;
flame.think = FireThink;
thinktime flame : 0;
self.attack_finished=time + 0.1;
};

52
flamswrd.hc Normal file
View File

@ -0,0 +1,52 @@
/*
* $Header: /HexenWorld/Siege/flamswrd.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
FLAME SWORD
==============================================================================
*/
// For building the model
$cd q:\art\models\weapons\flamswrd\final
$origin 0 0 54
$base base
$skin skin
//============================================================================
$frame swg000 swg001 swg002 swg003 swg004
$frame swg005 swg006 swg007 swg008 swg009
$frame swg010 swg011 swg012 swg013 swg014
$frame swg015 swg016
//frame bswg000 bswg001 bswg002 bswg003 bswg004
//$frame bswg005 bswg006 bswg007 bswg008 bswg009
//$frame bswg010 bswg011 bswg012 bswg013 bswg014
//$frame bswg015
//============================================================================
// Flame Sword
void() player_swing1 = [$swg000, player_swing2 ] {self.weaponframe=1;};
void() player_swing2 = [$swg001, player_swing3 ] {self.weaponframe=2;};
void() player_swing3 = [$swg002, player_swing4 ] {self.weaponframe=3;};
void() player_swing4 = [$swg003, player_swing5 ] {self.weaponframe=4;};
void() player_swing5 = [$swg004, player_swing6 ] {self.weaponframe=5;};
void() player_swing6 = [$swg005, player_swing7 ] {self.weaponframe=6;};
void() player_swing7 = [$swg006, player_swing8 ] {self.weaponframe=7;};
void() player_swing8 = [$swg007, player_swing9 ] {self.weaponframe=8;};
void() player_swing9 = [$swg008, player_swing10 ] {self.weaponframe=9;};
void() player_swing10 = [$swg009, player_swing11 ] {self.weaponframe=10;};
void() player_swing11 = [$swg010, player_swing12 ] {self.weaponframe=11;};
void() player_swing12 = [$swg011, player_swing13 ] {self.weaponframe=12;};
void() player_swing13 = [$swg012, player_swing14 ] {self.weaponframe=13;};
void() player_swing14 = [$swg013, player_swing15 ] {self.weaponframe=14;};
void() player_swing15 = [$swg014, player_swing16 ] {self.weaponframe=15;};
void() player_swing16 = [$swg015, player_swing1 ] {self.weaponframe=16;};

483
fx.hc Normal file
View File

@ -0,0 +1,483 @@
/*
* $Header: /HexenWorld/Siege/fx.hc 7 5/25/98 1:38p Mgummelt $
*/
float WHITE_PUFF = 0;
float RED_PUFF = 1;
float GREEN_PUFF = 2;
float GREY_PUFF = 3;
void CreateTeleporterBodyEffect (vector org,vector vel,float framelength)
{
starteffect(CE_TELEPORTERBODY, org,vel,framelength);
}
void CreateTeleporterSmokeEffect (vector org,vector vel,float framelength)
{
starteffect(CE_TELEPORTERPUFFS, org,vel,framelength);
}
// ============= SMOKE ================================
void CreateWhiteSmoke (vector org,vector vel,float framelength)
{
starteffect(CE_WHITE_SMOKE, org,vel,framelength);
}
void CreateRedSmoke (vector org,vector vel,float framelength)
{
starteffect(CE_RED_SMOKE, org,vel, framelength);
}
void CreateGreySmoke (vector org,vector vel,float framelength)
{
starteffect(CE_GREY_SMOKE, org,vel, framelength);
}
void CreateGreenSmoke (vector org,vector vel,float framelength)
{
starteffect(CE_GREEN_SMOKE, org,vel, framelength);
}
void CreateRedCloud (vector org,vector vel,float framelength)
{
starteffect(CE_REDCLOUD, org,vel, framelength);
}
// ============= FLASHES ================================
void CreateLittleWhiteFlash (vector spot)
{
starteffect(CE_SM_WHITE_FLASH,spot);
}
void CreateLittleBlueFlash (vector spot)
{
starteffect(CE_SM_BLUE_FLASH,spot);
}
void CreateBlueFlash (vector spot)
{
starteffect(CE_BLUE_FLASH,spot);
}
void CreateWhiteFlash (vector spot)
{
starteffect(CE_WHITE_FLASH, spot);
}
void CreateYRFlash (vector spot)
{
starteffect(CE_YELLOWRED_FLASH,spot);
}
// ============= EXPLOSIONS =============================
void CreateBlueExplosion (vector spot)
{
starteffect(CE_BLUE_EXPLOSION,spot);
}
void CreateExplosion29 (vector spot)
{
starteffect(CE_BG_CIRCLE_EXP,spot);
}
void CreateFireCircle (vector spot)
{
starteffect(CE_SM_CIRCLE_EXP,spot);
}
// ============= SPARKS =============================
void CreateRedSpark (vector spot)
{
starteffect(CE_REDSPARK,spot);
}
void CreateGreenSpark (vector spot)
{
starteffect(CE_GREENSPARK,spot);
}
void CreateBSpark (vector spot)
{
starteffect(CE_BLUESPARK,spot);
}
void CreateSpark (vector spot)
{
starteffect(CE_YELLOWSPARK,spot);
}
//FIXME:This should be a temp entity
void splash_run (void)
{
float result;
result = AdvanceFrame(0,5);
self.nextthink = time + HX_FRAME_TIME;
self.think = splash_run;
if (result == AF_END)
{
self.nextthink = time + HX_FRAME_TIME;
self.think = SUB_Remove;
}
}
void CreateWaterSplash (vector spot)
{
entity newent;
newent = spawn();
setmodel (newent, "models/wsplash.spr");
setorigin (newent, spot);
newent.movetype = MOVETYPE_NOCLIP;
newent.solid = SOLID_NOT;
newent.velocity = '0 0 0';
newent.nextthink = time + 0.05;
newent.think = splash_run;
}
/*
================
SpawnPuff
================
*/
void SpawnPuff (vector org, vector vel, float damage,entity victim)
{
float part_color;
float rad;
if (victim.thingtype==THINGTYPE_FLESH && victim.classname!="mummy" && victim.netname != "spider")
part_color = 256 + 8 * 16 + random(9); //Blood red
else if ((victim.thingtype==THINGTYPE_GREYSTONE) || (victim.thingtype==THINGTYPE_BROWNSTONE))
part_color = 256 + 20 + random(8); // Gray
else if (victim.thingtype==THINGTYPE_METAL)
part_color = 256 + (8 * 15); // Sparks
else if (victim.thingtype==THINGTYPE_WOOD||victim.thingtype==THINGTYPE_DIRT)
part_color = 256 + (5 * 16) + random(8); // Wood chunks
else if (victim.thingtype==THINGTYPE_ICE)
part_color = 406+random(8); // Ice particles
else if (victim.netname == "spider")
part_color = 256 + 183 + random(8); // Spider's have green blood
else
part_color = 256 + (3 * 16) + 4; // Dust Brown
rad=vlen(vel);
if(!rad)
rad=random(10,20);
particle4(org,rad,part_color,PARTICLETYPE_FASTGRAV,2 * damage);
}
/*-----------------------------------------
redblast - the red flash sprite
-----------------------------------------*/
void(vector spot) CreateRedFlash =
{
starteffect(CE_RED_FLASH,spot);
};
void() DeathBubblesSpawn;
void () flash_remove =
{
remove(self);
};
void GenerateTeleportSound (entity center)
{
string telesnd;
float r;
r=rint(random(4))+1;
if(r==1)
telesnd="misc/teleprt1.wav";
else if(r==2)
telesnd="misc/teleprt2.wav";
else if(r==3)
telesnd="misc/teleprt3.wav";
else if(r==4)
telesnd="misc/teleprt4.wav";
else
telesnd="misc/teleprt5.wav";
sound(center,CHAN_AUTO,telesnd,1,ATTN_NORM);
}
void GenerateTeleportEffect(vector spot1,float teleskin)
{
// entity sound_ent;
if (self.attack_finished > time)
return;
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_HWTELEPORT);
WriteCoord (MSG_MULTICAST, spot1_x);
WriteCoord (MSG_MULTICAST, spot1_y);
WriteCoord (MSG_MULTICAST, spot1_z);
WriteShort (MSG_MULTICAST, teleskin);
multicast(spot1,MULTICAST_PHS_R);
/*
sound_ent = spawn();
setorigin(sound_ent,spot1);
GenerateTeleportSound(sound_ent);
sound_ent.think = SUB_Remove;
thinktime sound_ent : 2;
CreateTeleporterBodyEffect (spot1,'0 0 0',teleskin); // 3rd parameter is the skin
CreateTeleporterSmokeEffect (spot1,'0 0 0',HX_FRAME_TIME);
CreateTeleporterSmokeEffect (spot1 + '0 0 64','0 0 0',HX_FRAME_TIME);
// GenerateTeleportSound(newent);
// if (self.scale < 0.11)
// {
// particle4(self.origin + '0 0 40',random(5,10),20,PARTICLETYPE_FASTGRAV,random(20,30));
// particle4(self.origin + '0 0 40',random(5,10),250,PARTICLETYPE_FASTGRAV,random(20,30));
// remove(self);
// }
*/
}
void smoke_generator_use(void)
{
self.use = smoke_generator_use;
self.nextthink = time + HX_FRAME_TIME;
if (!self.wait)
self.wait = 2;
self.owner = other;
if (self.lifespan)
self.lifetime = time + self.lifespan;
}
void smoke_generator_run(void)
{
if (self.thingtype == WHITE_PUFF)
CreateWhiteSmoke(self.origin, '0 0 8', HX_FRAME_TIME *3);
else if (self.thingtype == RED_PUFF)
CreateRedSmoke(self.origin, '0 0 8', HX_FRAME_TIME *3);
else if (self.thingtype == GREEN_PUFF)
CreateRedSmoke(self.origin, '0 0 8', HX_FRAME_TIME *3);
else if (self.thingtype == GREY_PUFF)
CreateGreySmoke(self.origin, '0 0 8', HX_FRAME_TIME *3);
self.nextthink = time + random(self.wait);
self.think = smoke_generator_run;
if ((self.lifespan) && (self.lifetime < time))
remove(self);
}
/*QUAKED fx_smoke_generator (0 1 1) (-8 -8 -8) (8 8 8)
Generates smoke puffs
-------------------------FIELDS-------------------------
wait - how often it should generate smoke (default 2)
thingtype - type of smoke to generate
0 - white puff (fire place)
1 - red (lava)
2 - green (slime)
3 - grey (oil)
lifespan - fill this in and it will only puff for this long
--------------------------------------------------------
*/
void() fx_smoke_generator =
{
setmodel(self, "models/null.spr");
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_NONE;
setsize (self,'0 0 0' , '0 0 0');
self.th_die = SUB_Remove;
if (!self.targetname) // Not targeted by anything so puff away
self.nextthink = time + HX_FRAME_TIME;
self.use = smoke_generator_use;
if (!self.wait)
self.wait = 2;
self.think = smoke_generator_run;
};
void (vector org) fx_flash =
{
local entity newent;
newent = spawn();
setmodel (newent, "models/s_bubble.spr");
// setmodel (newent, newent.model);
// newent.modelindex = 0;
// newent.model = "";
setorigin (newent, org + '0 0 24');
newent.movetype = MOVETYPE_NOCLIP;
newent.solid = SOLID_NOT;
newent.velocity = '0 0 0';
newent.nextthink = time + 0.5;
newent.think = flash_remove;
newent.classname = "bubble";
newent.effects = EF_BRIGHTLIGHT;
setsize (newent, '-8 -8 -8', '8 8 8');
};
/*
void () friction_change_touch =
{
if (other == self.owner)
return;
if (other.classname == "player")
other.friction=self.friction;
};
*/
/*QUAK-ED fx_friction_change (0 1 1) ?
Set the friction within this area.
-------------------------FIELDS-------------------------
'friction' : this is how quickly the player will slow down after he ceases indicating movement (lets go of arrow keys).
1 : normal friction
>0 & <1 : slippery
>1 : high friction
--------------------------------------------------------
*/
/*
void() fx_friction_change =
{
self.movetype = MOVETYPE_NONE;
self.owner = self;
self.solid = SOLID_TRIGGER;
setorigin (self, self.origin);
setmodel (self, self.model);
self.modelindex = 0;
self.model = "";
setsize (self, self.mins , self.maxs);
self.touch = friction_change_touch;
};
*/
void() explosion_done =
{
self.effects=EF_DIMLIGHT;
};
void() explosion_use =
{
/*
if (self.spawnflags & FLASH)
{
self.effects=EF_BRIGHTLIGHT;
self.think=p_explosion_done;
self.nextthink= time + 1;
}
*/
sound (self, CHAN_BODY, self.noise1, 1, ATTN_NORM);
particleexplosion(self.origin,self.color,self.exploderadius,self.counter);
};
/*QUAK-ED fx_particle_explosion (0 1 1) ( -5 -5 -5) (5 5 5) FLASH
Gives off a spray of particles like an explosion.
-------------------------FIELDS-------------------------
FLASH will cause a brief flash of light.
"color" is the color of the explosion. Particle colors dim as they move away from the center point.
color values :
31 - white
47 - light blue
63 - purple
79 - light green
85 - light brown
101 - red (default)
117 - light blue
133 - yellow
149 - green
238 - red to orange
242 - purple to red
246 - green to purple
250 - blue - green
254 - yellow to blue
"exploderadius" is the distance the particles travel before disappearing. 1 - 10 (default 5)
"soundtype" the type of sound made during explosion
0 - no sound
1 - rocket explosion (default)
2 - grenade shoot
"counter" the number of particles to create
1 - 1024
512 (default)
--------------------------------------------------------
*/
/*
void() fx_particle_explosion =
{
self.effects=0;
self.use=explosion_use;
self.movetype = MOVETYPE_NOCLIP;
self.owner = self;
self.solid = SOLID_NOT;
setorigin (self, self.origin);
setmodel (self, self.model);
setsize (self, self.mins , self.maxs);
// Explosion color
if ((!self.color) || (self.color>254))
self.color=101;
// Explosion sound is what type????
if (self.soundtype>2)
self.soundtype=0;
else if (!self.soundtype)
self.soundtype=1;
if (self.soundtype==0)
self.noise1 = ("misc/null.wav");
else if (self.soundtype==1)
self.noise1 = ("weapons/explode.wav");
else if (self.soundtype==2)
self.noise1 = ("weapons/grenade.wav");
self.exploderadius = 10 - self.exploderadius; // This is backwards in builtin function
// Explosion radius
if ((self.exploderadius<1) || (self.exploderadius>10))
self.exploderadius=5;
// Particle count
if ((self.counter<1) || (self.counter>1024))
self.counter=512;
};
*/

263
gauntlet.hc Normal file
View File

@ -0,0 +1,263 @@
/*
==============================================================================
GAUNTLET
==============================================================================
*/
// For building the model
$cd q:/art/models/weapons/gauntlet/final
$origin 0 5 10
$base base4 512 473
$skin skin3
// FRAME: 1
$frame GntRoot1
// FRAMES: 2 - 14
$frame 1stGnt1 1stGnt2 1stGnt3 1stGnt4 1stGnt5
$frame 1stGnt6 1stGnt7 1stGnt8 1stGnt9 1stGnt10
$frame 1stGnt11 1stGnt12 1stGnt14
// FRAMES 15 - 28
$frame 2ndGnt1 2ndGnt2 2ndGnt3 2ndGnt4 2ndGnt5
$frame 2ndGnt6 2ndGnt7 2ndGnt8 2ndGnt9 2ndGnt10
$frame 2ndGnt11 2ndGnt12 2ndGnt13 2ndGnt15
$frame 2ndGnt16 2ndGnt19
// FRAMES 29 - 40
$frame 3rdGnt1 3rdGnt3 3rdGnt5
$frame 3rdGnt10
$frame 3rdGnt11 3rdGnt12 3rdGnt13 3rdGnt14 3rdGnt15
$frame 3rdGnt17
$frame 3rdGnt21 3rdGnt22
// Frames 41 - 54
$frame GntTap1 GntTap2 GntTap3 GntTap4 GntTap5
$frame GntTap11 GntTap12 GntTap13 GntTap14 GntTap15
$frame GntTap16 GntTap17 GntTap18 GntTap19
// FRAMES: 55 - 67
$frame 7thGnt1 7thGnt2 7thGnt3
$frame 7thGnt6 7thGnt7 7thGnt8 7thGnt9 7thGnt10
$frame 7thGnt11 7thGnt12 7thGnt13 7thGnt14
$frame 7thGnt19
float GAUNT_BASE_DAMAGE = 16;
float GAUNT_ADD_DAMAGE = 12;
float GAUNT_PWR_BASE_DAMAGE = 30;
float GAUNT_PWR_ADD_DAMAGE = 20;
float GAUNT_PUSH = 4;
void W_SetCurrentWeapon(void);
void gauntlet_fire (float anim)
{
vector source;
vector org;
float damg;
entity hitGuy;
makevectors (self.v_angle);
source = self.origin + self.proj_ofs;
traceline (source, source + v_forward*64, FALSE, self); // Straight in front
if (trace_fraction == 1.0)
{
traceline (source, source + v_forward*64 - (v_up * 30), FALSE, self); // 30 down
if (trace_fraction == 1.0)
{
traceline (source, source + v_forward*64 + v_up * 30, FALSE, self); // 30 up
if (trace_fraction == 1.0)
return;
}
}
org = trace_endpos + (v_forward * 4);
if (trace_ent.takedamage)
{
SpawnPuff (org, '0 0 0', 20,trace_ent);
if (self.artifact_active & ART_TOMEOFPOWER)
{
//damg = GAUNT_PWR_BASE_DAMAGE + random(GAUNT_PWR_ADD_DAMAGE);
if(trace_ent.classname == "player")
{
damg = 30 + random(25);
}
else
{
damg = 2; // let the wall collision do the damage
}
org = trace_endpos + (v_forward * -1);
CreateWhiteFlash(org);
sound (self, CHAN_WEAPON, "weapons/gauntht1.wav", 1, ATTN_NORM);
}
else
{
damg = GAUNT_BASE_DAMAGE + random(GAUNT_ADD_DAMAGE);
sound (self, CHAN_WEAPON, "weapons/gauntht1.wav", 1, ATTN_NORM);
}
hitGuy = trace_ent;
T_Damage (trace_ent, self, self, damg);
if(self.artifact_active & ART_TOMEOFPOWER)
{
hitGuy.velocity += normalize(hitGuy.origin - self.origin)*800;
hitGuy.velocity_z += 600;
hitGuy.flags(-)FL_ONGROUND;
}
}
else
{ // hit wall
sound (self, CHAN_WEAPON, "weapons/gauntht2.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_GUNSHOT);
WriteByte (MSG_BROADCAST, 1);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
org = trace_endpos + (v_forward * -1);
org += '0 0 10';
CreateWhiteSmoke(org,'0 0 2',HX_FRAME_TIME);
}
}
void gauntlet_ready (void)
{
self.th_weapon=gauntlet_ready;
self.weaponframe = $GntRoot1;
}
void gauntlet_twitch (void)
{
self.wfs = advanceweaponframe($GntTap1,$GntTap19);
self.th_weapon = gauntlet_twitch;
if (self.weaponframe == $GntTap3)
sound (self, CHAN_VOICE, "fx/wallbrk.wav", 1, ATTN_NORM);
if (self.wfs == WF_LAST_FRAME)
gauntlet_ready();
}
void gauntlet_select (void)
{
self.wfs = advanceweaponframe($2ndGnt6,$2ndGnt1);
self.weaponmodel = "models/gauntlet.mdl";
self.th_weapon=gauntlet_select;
self.last_attack=time;
self.attack_cnt = 0;
if (self.wfs == WF_LAST_FRAME)
{
self.attack_finished = time - 1;
gauntlet_twitch();
}
}
void gauntlet_deselect (void)
{
self.wfs = advanceweaponframe($2ndGnt1,$2ndGnt6);
self.th_weapon=gauntlet_deselect;
self.oldweapon = IT_WEAPON1;
if (self.wfs == WF_LAST_FRAME)
{
W_SetCurrentAmmo();
}
}
void gauntlet_d (void)
{
self.wfs = advanceweaponframe($7thGnt3,$7thGnt19);
self.th_weapon = gauntlet_d;
if (self.weaponframe == $7thGnt6) // Frame 57
sound (self, CHAN_WEAPON, "weapons/gaunt1.wav", 1, ATTN_NORM);
else if (self.weaponframe == $7thGnt9) // Frame 63
gauntlet_fire(4);
if (self.wfs == WF_LAST_FRAME)
gauntlet_ready();
}
void gauntlet_c (void)
{
self.wfs = advanceweaponframe($3rdGnt1,$3rdGnt22);
self.th_weapon = gauntlet_c;
if (self.weaponframe == $3rdGnt5)
sound (self, CHAN_WEAPON, "weapons/gaunt1.wav", 1, ATTN_NORM);
else if (self.weaponframe == $3rdGnt12)
gauntlet_fire(3);
if (self.wfs == WF_LAST_FRAME)
gauntlet_ready();
}
void gauntlet_b (void)
{
self.wfs = advanceweaponframe($2ndGnt1,$2ndGnt19);
self.th_weapon = gauntlet_b;
if ((self.weaponframe == $2ndGnt4) || (self.weaponframe == $2ndGnt5))
self.weaponframe == $2ndGnt6;
if (self.weaponframe == $2ndGnt6)
sound (self, CHAN_WEAPON, "weapons/gaunt1.wav", 1, ATTN_NORM);
else if (self.weaponframe == $2ndGnt9)
gauntlet_fire(2);
if (self.wfs == WF_LAST_FRAME)
gauntlet_ready();
}
void gauntlet_a (void)
{
self.wfs = advanceweaponframe($1stGnt1,$1stGnt14);
self.th_weapon = gauntlet_a;
if (self.weaponframe == $1stGnt2)
sound (self, CHAN_WEAPON, "weapons/gaunt1.wav", 1, ATTN_NORM);
else if (self.weaponframe == $1stGnt4)
gauntlet_fire(1);
if (self.wfs == WF_LAST_FRAME)
gauntlet_ready();
}
void pal_gauntlet_fire(void)
{
// r = random(); // Eventually attacks will be random in order
if (self.attack_cnt < 1)
gauntlet_a ();
else if (self.attack_cnt < 2)
gauntlet_b ();
else if (self.attack_cnt < 3)
gauntlet_c ();
else if (self.attack_cnt < 4)
{
gauntlet_d ();
self.attack_cnt=-1;
}
self.attack_cnt += 1;
self.attack_finished = time + 0.5;
}

111
gfire.hc Normal file
View File

@ -0,0 +1,111 @@
//FIRE HURT FIELD========================================================
void fire_hurt_field_touch ()
{
if(self.attack_finished>time)
return;
if(self.inactive)
return;
if(other.health<=0)
return;
self.attack_finished=time+HX_FRAME_TIME;
T_Damage(other,self,self,self.dmg);
if(self.owner.classname=="big greek fire")
if(!other.flags2&FL2_ONFIRE);
{//torch 'em
if(flammable(other))
spawn_burner(other,TRUE);
}
else
other.fire_damage += 1;//burn more!
if(self.t_width<time)
{
self.t_width=time+0.6;
sound(self,CHAN_WEAPON,"crusader/sunhit.wav",1,ATTN_NORM);
}
}
void init_fire_hurt_field ()
{
InitTrigger();
self.touch=fire_hurt_field_touch;
}
void spawn_burnfield (vector org)
{//Make a trigger_flame_hurt around flame
entity fhf;
fhf=spawn();
fhf.model=self.model;
fhf.effects=EF_NODRAW;
self.trigger_field=fhf;
fhf.owner=self;
// setsize(fhf,'-3 -3 0','3 3 9');
setorigin(fhf,org);
if(self.dmg)
fhf.dmg=self.dmg;
else
fhf.dmg=self.dmg=.2;
fhf.classname="fire hurt field";
fhf.think=init_fire_hurt_field;
fhf.nextthink=time;
}
//BIG FIRE========================================================
void burn_out ()
{
if(self.scale>0.1)
{
self.scale-=0.1;
setsize(self.trigger_field,'-24 -24 0'*self.scale,'24 24 48'*self.scale);
thinktime self : 0.01;
self.dmg=self.trigger_field.dmg=self.scale*3;
}
else
{
remove(self.trigger_field);
stopSound(self,0);
remove(self);
}
}
/*QUAKED light_newfire (0 1 0) (-10 -10 -13) (10 10 41) START_LOW HURT
Large yellow flame
----------------------------------
If triggered, will toggle between lightvalue1 and lightvalue2
.lightvalue1 (default 0)
.lightvalue2 (default 11, equivalent to 300 brightness)
Two values the light will fade-toggle between, 0 is black, 25 is brightest, 11 is equivalent to a value of 300.
.fadespeed (default 1) = How many seconds it will take to complete the desired lighting change
The light will start on at a default of the higher light value unless you turn on the startlow flag.
START_LOW = will make the light start at the lower of the lightvalues you specify (default uses brighter)
HURT = Will hurt things that touch it.
.dmg = how much to hurt people who touch fire - damage/20th of a second. Default = .2;
NOTE: IF YOU DON'T PLAN ON USING THE DEFAULTS, ALL LIGHTS IN THE BANK OF LIGHTS NEED THIS INFO
*/
void spawn_big_fire(vector org)
{
entity bigfire;
bigfire=spawn();
oself=self;
self = bigfire;
self.dmg=2;
self.classname="big greek fire";
self.drawflags(+)SCALE_ORIGIN_BOTTOM|DRF_TRANSLUCENT|MLS_FIREFLICKER;
self.scale = 1;
setmodel(self,"models/newfire.mdl");
setorigin(self,org);
spawn_burnfield(org);
setsize(self.trigger_field,'-24 -24 0','24 24 48');
sound (self,CHAN_LOOP+PHS_OVERRIDE_R, "misc/flamloop.wav", 0.5, ATTN_LOOP);
self.think = burn_out;
thinktime self : 10;
self=oself;
};

159
gib.hc Normal file
View File

@ -0,0 +1,159 @@
/*
* $Header: /HexenWorld/Siege/gib.hc 5 5/25/98 1:38p Mgummelt $
*/
vector() ChunkVelocity =
{
local vector v;
v = randomv('-210 -210 -210', '210 210 280');
return v;
};
void(vector space) CreateSpriteChunks =
{
local entity sprite;
sprite = spawn();
space = randomv(space);
setorigin (sprite, self.absmin + space);
if (self.thingtype==THINGTYPE_GLASS)
setmodel (sprite, "gfx/glass.spr");
else
setmodel (sprite, "gfx/stone.spr");
setsize (sprite, '0 0 0', '0 0 0');
sprite.movetype = MOVETYPE_BOUNCE;
sprite.solid = SOLID_NOT;
sprite.velocity = ChunkVelocity();
sprite.think = SUB_Remove;
sprite.ltime = time;
sprite.nextthink = time + 1 + random()*1;
};
void(vector space) CreateModelChunks =
{
local entity chunk;
local float final;
chunk = spawn();
space_x = space_x * random();
space_y = space_y * random();
space_z = space_z * random();
setorigin (chunk, self.absmin + space);
if (self.thingtype==THINGTYPE_GLASS)
{
final = random();
if (final<0.20)
setmodel (chunk, "models/shard1.mdl");
else if (final<0.40)
setmodel (chunk, "models/shard2.mdl");
else if (final<0.60)
setmodel (chunk, "models/shard3.mdl");
else if (final<0.80)
setmodel (chunk, "models/shard4.mdl");
else
setmodel (chunk, "models/shard5.mdl");
}
else if (self.thingtype==THINGTYPE_WOOD)
{
final = random();
if (final < 0.25)
setmodel (chunk, "models/splnter1.mdl");
else if (final < 0.50)
setmodel (chunk, "models/splnter2.mdl");
else if (final < 0.75)
setmodel (chunk, "models/splnter3.mdl");
else
setmodel (chunk, "models/splnter4.mdl");
}
else if (self.thingtype==THINGTYPE_METAL)
{
final = random();
if (final < 0.25)
setmodel (chunk, "models/metlchk1.mdl");
else if (final < 0.50)
setmodel (chunk, "models/metlchk2.mdl");
else if (final < 0.75)
setmodel (chunk, "models/metlchk3.mdl");
else
setmodel (chunk, "models/metlchk4.mdl");
}
else if (self.thingtype==THINGTYPE_FLESH)
{
final = random();
if (final < 0.33)
setmodel (chunk, "models/flesh1.mdl");
else if (final < 0.66)
setmodel (chunk, "models/flesh2.mdl");
else
setmodel (chunk, "models/flesh3.mdl");
}
else setmodel (chunk, "models/flesh1.mdl");
setsize (chunk, '0 0 0', '0 0 0');
chunk.movetype = MOVETYPE_BOUNCE;
chunk.solid = SOLID_NOT;
chunk.velocity = ChunkVelocity();
chunk.think = SUB_Remove;
chunk.avelocity_x = random()*1200;
chunk.avelocity_y = random()*1200;
chunk.avelocity_z = random()*1200;
chunk.ltime = time;
chunk.nextthink = time + 1 + random();
};
void () chunk_death =
{
local vector space;
local float holdcount,spritecount,chunkcount;
space = self.absmax - self.absmin;
holdcount = space_x + space_y + space_z;
spritecount = holdcount/8;
chunkcount = holdcount/16;
if (self.thingtype==THINGTYPE_GLASS)
sound (self, CHAN_VOICE, "raven/glassbrk.wav", 1, ATTN_NORM);
else if (self.thingtype==THINGTYPE_WOOD)
sound (self, CHAN_VOICE, "raven/woodbrk.wav", 1, ATTN_NORM);
else if ((self.thingtype==THINGTYPE_GREYSTONE) || (self.thingtype==THINGTYPE_BROWNSTONE)||self.thingtype==THINGTYPE_DIRT)
sound (self, CHAN_VOICE, "raven/wallbrk.wav", 1, ATTN_NORM);
else if (self.thingtype==THINGTYPE_METAL)
sound (self, CHAN_VOICE, "raven/metalbrk.wav", 1, ATTN_NORM);
else if (self.thingtype==THINGTYPE_FLESH)
sound (self, CHAN_VOICE, "raven/fleshbrk.wav", 1, ATTN_NORM);
else if (self.thingtype==THINGTYPE_CLOTH)
sound (self, CHAN_VOICE, "raven/clothbrk.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "raven/wallbrk.wav", 1, ATTN_NORM);
// FIXME: are we adding sprites to the deaths also???
// while (spritecount>0)
// {
// CreateSpriteChunks(space);
// spritecount = spritecount - 1;
// }
while (chunkcount>0)
{
CreateModelChunks(space);
chunkcount = chunkcount - 1;
}
SUB_UseTargets();
remove(self);
};

175
global.hc Normal file
View File

@ -0,0 +1,175 @@
//**************************************************************************
//**
//** global.hc
//**
//** $Header: /HexenWorld/Siege/global.hc 13 5/25/98 1:38p Mgummelt $
//**
//**************************************************************************
// SYSTEM GLOBALS (globalvars_t C structure) -------------------------------
entity self;
entity other;
entity world;
float time;
float frametime;
entity newmis; // if this is set, the entity that just
// run created a new missile that should
// be simulated immediately
// 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.
float force_retouch;
string mapname;
string startspot;
float deathmatch;
float randomclass;
float damageScale;
float meleeDamScale;//amount to scale damage when victim has melee weapon currently selected
float shyRespawn;
float spartanPrint;
float manaScale;
float tomeMode;
float tomeRespawn;
float w2Respawn;
float altRespawn;
float fixedLevel;
float autoItems;
float dmMode;
float easyFourth;
float patternRunner;
float coop;
float teamplay;
// Propagated from level to level, used to keep track of completed
// episodes.
float serverflags;
float total_secrets;
float total_monsters;
// Number of secrets found.
float found_secrets;
// Number of monsters killed.
float killed_monsters;
float chunk_cnt; // # of chunks currently existing (don't want to exceed max)
// Set by monster spawner to make sure monster init functions don't
// precache models after level is started.
float done_precache;
// Spawnparms are used to encode information about clients across server
// level changes.
float parm1, parm2, parm4, parm5, parm6, parm7, parm8,
parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16;
string parm3;
// Set by makevectors()
vector v_forward, v_up, v_right;
// Set by traceline().
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;
// Destination of single entity writes.
entity msg_entity;
// Set by OP_CSTATE ([++ $s..$e], [-- $s..$e]).
float cycle_wrapped;
float crouch_cnt;
float modelindex_assassin;
float modelindex_crusader;
float modelindex_paladin;
float modelindex_necromancer;
float modelindex_sheep;
float num_players;
float exp_mult;
float max_players;
float defLosses;
float attLosses;
// REQUIRED FUNCTIONS ------------------------------------------------------
// Only for testing
void main(void);
void StartFrame(void);
void PlayerPreThink(void);
void PlayerPostThink(void);
void ClientKill(void);
void ClientConnect(void);
void PutClientInServer(void);
void ClientReEnter(float TimeDiff);
void ClientDisconnect(void);
void ClassChangeWeapon(void);
void SetNewParms(void); // called when a client first connects to
// a server. sets parms so they can be
// saved off for restarts
void SetChangeParms(void); // call to set parms for self so they can
// be saved for a level transition
void SmitePlayer(); // Server smites a player
// END SYSTEM GLOBALS ------------------------------------------------------
// Flag the compiler.
void end_sys_globals;
float movedist;
// Set when a rule exits.
float gameover;
// NULL string, nothing should be held here.
string string_null;
// Function launch_spike() sets this after spawning it.
entity newmis;
// The entity that activated a trigger or brush.
entity activator;
// Set by T_Damage().
entity damage_attacker;
float framecount;
float skill;
float wp_deselect; // A flag showing a weapon is being deselected ignore impulse 10
entity print_ent1;
entity print_ent2;
string nextmap;
float START_LIT;
float g_timelimit;
float g_init_timelimit;
float g_fraglimit;
string g_keyname;
string g_keymdl;
float gamestarted;
float newsiege;

68
glyph.hc Normal file
View File

@ -0,0 +1,68 @@
/*
* $Header: /HexenWorld/Siege/glyph.hc 3 5/25/98 1:38p Mgummelt $
*/
void (float explodetype) BecomeExplosion ;
void () TouchGlyph =
{
local float damg;
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 (FALSE);
damg = GLYPH_BASE_DAMAGE + random(GLYPH_ADD_DAMAGE);
self.owner = self;
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, damg, other);
T_RadiusManaDamage (self, self.owner, damg, other);
remove(self);
};
void () DecrementGlyph =
{
if (self.lifetime > time)
{
self.nextthink = time + 1;
return;
}
else
TouchGlyph ();
};
void () Use_Glyph =
{
local entity glyph;
glyph = spawn();
glyph.owner = self;
// precache_model("models/glyph.mdl");
CreateEntityNew(self,ENT_GLYPH,"models/glyph.mdl",SUB_Null);
glyph.touch = TouchGlyph;
glyph.classname = "running_glyph";
setorigin (glyph, self.origin);
glyph.think = DecrementGlyph;
glyph.nextthink = time + 1;
glyph.lifetime = time + 10;
};

1436
golem.hc Normal file

File diff suppressed because it is too large Load Diff

383
golem_b.hc Normal file
View File

@ -0,0 +1,383 @@
//**************************************************************************
//**
//** golem_b.hc
//**
//** $Header: /HexenWorld/Siege/golem_b.hc 3 5/25/98 1:38p Mgummelt $
//**
//** Bronze golem.
//**
//**************************************************************************
// FRAMES ------------------------------------------------------------------
// Transition from still to attack stance
$frame gbirth1 gbirth2 gbirth3 gbirth4 gbirth5
$frame gbirth6 gbirth7 gbirth8 gbirth9 gbirth10
$frame gbirth11 gbirth12
// Death
$frame gdeath1 gdeath2 gdeath3 gdeath4 gdeath5
$frame gdeath6 gdeath7 gdeath8 gdeath9 gdeath10
$frame gdeath11 gdeath12 gdeath13 gdeath14 gdeath15
$frame gdeath16 gdeath17 gdeath18 gdeath19 gdeath20
$frame gdeath21 gdeath22 gdeath23 gdeath24 gdeath25
$frame gdeath26 gdeath27 gdeath28 gdeath29 gdeath30
$frame gdeath31 gdeath32 gdeath33 gdeath34 gdeath35
$frame gdeath36 gdeath37 gdeath38 gdeath39 gdeath40
$frame gdeath41 gdeath42 gdeath43 gdeath44 gdeath45
$frame gdeath46 gdeath47 gdeath48 gdeath49 gdeath50
$frame gdeath51
// Walking
$frame gwalk1 gwalk2 gwalk3 gwalk4 gwalk5
$frame gwalk6 gwalk7 gwalk8 gwalk9 gwalk10
$frame gwalk11 gwalk12 gwalk13 gwalk14 gwalk15
$frame gwalk16 gwalk17 gwalk18 gwalk19 gwalk20
$frame gwalk21 gwalk22 gwalk23 gwalk24 gwalk25
$frame gwalk26 gwalk27 gwalk28 gwalk29 gwalk30
$frame gwalk31 gwalk32 gwalk33 gwalk34 gwalk35
$frame gwalk36 gwalk37 gwalk38 gwalk39 gwalk40
$frame gwalk41 gwalk42 gwalk43 gwalk44 gwalk45
$frame gwalk46 gwalk47 gwalk48 gwalk49 gwalk50
$frame gwalk51 gwalk52 gwalk53 gwalk54 gwalk55
$frame gwalk56 gwalk57 gwalk58 gwalk59 gwalk60
// Transition from attack stance to walking
$frame gtran1 gtran2 gtran3 gtran4 gtran5
$frame gtran6 gtran7 gtran8 gtran9 gtran10
$frame gtran11 gtran12 gtran13 gtran14 gtran15
$frame gtran16 gtran17 gtran18 gtran19 gtran20
$frame gtran21 gtran22 gtran23 gtran24 gtran25
$frame gtran26
// Gem attack
$frame ggem1 ggem2 ggem3 ggem4 ggem5
$frame ggem6 ggem7 ggem8 ggem9 ggem10
$frame ggem11 ggem12 ggem13 ggem14 ggem15
$frame ggem16 ggem17 ggem18 ggem19 ggem20
$frame ggem21 ggem22 ggem23 ggem24 ggem25
// Left hand punch attack
$frame gLpnch1 gLpnch2 gLpnch3 gLpnch4 gLpnch5
$frame gLpnch6 gLpnch7 gLpnch8 gLpnch9 gLpnch10
$frame gLpnch11 gLpnch12 gLpnch13 gLpnch14 gLpnch15
$frame gLpnch16 gLpnch17 gLpnch18 gLpnch19 gLpnch20
$frame gLpnch21 gLpnch22
// Right hand pound attack
$frame gRpnd1 gRpnd2 gRpnd3 gRpnd4 gRpnd5
$frame gRpnd6 gRpnd7 gRpnd8 gRpnd9 gRpnd10
$frame gRpnd11 gRpnd12 gRpnd13 gRpnd14 gRpnd15
$frame gRpnd16 gRpnd17 gRpnd18 gRpnd19 gRpnd20
// Stomp attack
$frame gstomp1 gstomp2 gstomp3 gstomp4 gstomp5
$frame gstomp6 gstomp7 gstomp8 gstomp9 gstomp10
$frame gstomp11 gstomp12 gstomp13 gstomp14 gstomp15
$frame gstomp16 gstomp17 gstomp18 gstomp19 gstomp20
$frame gstomp21 gstomp22 gstomp23 gstomp24 gstomp25
$frame gstomp26 gstomp27 gstomp28 gstomp29 gstomp30
void GolemBMeleeDecide(void);
void GolemBPunchLeft(void);
void GolemBPoundRight(void);
// CODE --------------------------------------------------------------------
void() golemb_gbirth1 = [ $gbirth1 , golemb_gbirth2 ] { };
void() golemb_gbirth2 = [ $gbirth2 , golemb_gbirth3 ] { };
void() golemb_gbirth3 = [ $gbirth3 , golemb_gbirth4 ] { };
void() golemb_gbirth4 = [ $gbirth4 , golemb_gbirth5 ] { };
void() golemb_gbirth5 = [ $gbirth5 , golemb_gbirth6 ] { };
void() golemb_gbirth6 = [ $gbirth6 , golemb_gbirth7 ] { };
void() golemb_gbirth7 = [ $gbirth7 , golemb_gbirth8 ] { };
void() golemb_gbirth8 = [ $gbirth8 , golemb_gbirth9 ] { };
void() golemb_gbirth9 = [ $gbirth9 , golemb_gbirth10 ] { };
void() golemb_gbirth10 = [ $gbirth10 , golemb_gbirth11 ] { };
void() golemb_gbirth11 = [ $gbirth11 , golemb_gbirth12 ] { };
void() golemb_gbirth12 = [ $gbirth12 , golemb_gbirth1 ] { };
/*
void() golemb_ggem1 = [ $ggem1 , golemb_ggem2 ] { };
void() golemb_ggem2 = [ $ggem2 , golemb_ggem3 ] { };
void() golemb_ggem3 = [ $ggem3 , golemb_ggem4 ] { };
void() golemb_ggem4 = [ $ggem4 , golemb_ggem5 ] { };
void() golemb_ggem5 = [ $ggem5 , golemb_ggem6 ] { };
void() golemb_ggem6 = [ $ggem6 , golemb_ggem7 ] { };
void() golemb_ggem7 = [ $ggem7 , golemb_ggem8 ] { };
void() golemb_ggem8 = [ $ggem8 , golemb_ggem9 ] { };
void() golemb_ggem9 = [ $ggem9 , golemb_ggem10 ] { };
void() golemb_ggem10 = [ $ggem10 , golemb_ggem11 ] { };
void() golemb_ggem11 = [ $ggem11 , golemb_ggem12 ] { };
void() golemb_ggem12 = [ $ggem12 , golemb_ggem13 ] { };
void() golemb_ggem13 = [ $ggem13 , golemb_ggem14 ] { };
void() golemb_ggem14 = [ $ggem14 , golemb_ggem15 ] { };
void() golemb_ggem15 = [ $ggem15 , golemb_ggem16 ] { };
void() golemb_ggem16 = [ $ggem16 , golemb_ggem17 ] { };
void() golemb_ggem17 = [ $ggem17 , golemb_ggem18 ] { };
void() golemb_ggem18 = [ $ggem18 , golemb_ggem19 ] { };
void() golemb_ggem19 = [ $ggem19 , golemb_ggem20 ] { };
void() golemb_ggem20 = [ $ggem20 , golemb_ggem21 ] { };
void() golemb_ggem21 = [ $ggem21 , golemb_ggem22 ] { };
void() golemb_ggem22 = [ $ggem22 , golemb_ggem23 ] { };
void() golemb_ggem23 = [ $ggem23 , golemb_ggem24 ] { };
void() golemb_ggem24 = [ $ggem24 , golemb_ggem25 ] { };
void() golemb_ggem25 = [ $ggem25 , golemb_ggem1 ] { };
*/
/*
void() golemb_gLpnch1 = [ $gLpnch1 , golemb_gLpnch2 ] { };
void() golemb_gLpnch2 = [ $gLpnch2 , golemb_gLpnch3 ] { };
void() golemb_gLpnch3 = [ $gLpnch3 , golemb_gLpnch4 ] { };
void() golemb_gLpnch4 = [ $gLpnch4 , golemb_gLpnch5 ] { };
void() golemb_gLpnch5 = [ $gLpnch5 , golemb_gLpnch6 ] { };
void() golemb_gLpnch6 = [ $gLpnch6 , golemb_gLpnch7 ] { };
void() golemb_gLpnch7 = [ $gLpnch7 , golemb_gLpnch8 ] { };
void() golemb_gLpnch8 = [ $gLpnch8 , golemb_gLpnch9 ] { };
void() golemb_gLpnch9 = [ $gLpnch9 , golemb_gLpnch10 ] { };
void() golemb_gLpnch10 = [ $gLpnch10 , golemb_gLpnch11 ] { };
void() golemb_gLpnch11 = [ $gLpnch11 , golemb_gLpnch12 ] { };
void() golemb_gLpnch12 = [ $gLpnch12 , golemb_gLpnch13 ] { };
void() golemb_gLpnch13 = [ $gLpnch13 , golemb_gLpnch14 ] { };
void() golemb_gLpnch14 = [ $gLpnch14 , golemb_gLpnch15 ] { };
void() golemb_gLpnch15 = [ $gLpnch15 , golemb_gLpnch16 ] { };
void() golemb_gLpnch16 = [ $gLpnch16 , golemb_gLpnch17 ] { };
void() golemb_gLpnch17 = [ $gLpnch17 , golemb_gLpnch18 ] { };
void() golemb_gLpnch18 = [ $gLpnch18 , golemb_gLpnch19 ] { };
void() golemb_gLpnch19 = [ $gLpnch19 , golemb_gLpnch20 ] { };
void() golemb_gLpnch20 = [ $gLpnch20 , golemb_gLpnch21 ] { };
void() golemb_gLpnch21 = [ $gLpnch21 , golemb_gLpnch22 ] { };
void() golemb_gLpnch22 = [ $gLpnch22 , golem_run_init ] { };
*/
/*
void() golemb_gRpnd1 = [ $gRpnd1 , golemb_gRpnd2 ] { };
void() golemb_gRpnd2 = [ $gRpnd2 , golemb_gRpnd3 ] { };
void() golemb_gRpnd3 = [ $gRpnd3 , golemb_gRpnd4 ] { };
void() golemb_gRpnd4 = [ $gRpnd4 , golemb_gRpnd5 ] { };
void() golemb_gRpnd5 = [ $gRpnd5 , golemb_gRpnd6 ] { };
void() golemb_gRpnd6 = [ $gRpnd6 , golemb_gRpnd7 ] { };
void() golemb_gRpnd7 = [ $gRpnd7 , golemb_gRpnd8 ] { };
void() golemb_gRpnd8 = [ $gRpnd8 , golemb_gRpnd9 ] { };
void() golemb_gRpnd9 = [ $gRpnd9 , golemb_gRpnd10 ] { };
void() golemb_gRpnd10 = [ $gRpnd10 , golemb_gRpnd11 ] { };
void() golemb_gRpnd11 = [ $gRpnd11 , golemb_gRpnd12 ] { };
void() golemb_gRpnd12 = [ $gRpnd12 , golemb_gRpnd13 ] { };
void() golemb_gRpnd13 = [ $gRpnd13 , golemb_gRpnd14 ] { };
void() golemb_gRpnd14 = [ $gRpnd14 , golemb_gRpnd15 ] { };
void() golemb_gRpnd15 = [ $gRpnd15 , golemb_gRpnd16 ] { };
void() golemb_gRpnd16 = [ $gRpnd16 , golemb_gRpnd17 ] { };
void() golemb_gRpnd17 = [ $gRpnd17 , golemb_gRpnd18 ] { };
void() golemb_gRpnd18 = [ $gRpnd18 , golemb_gRpnd19 ] { };
void() golemb_gRpnd19 = [ $gRpnd19 , golemb_gRpnd20 ] { };
void() golemb_gRpnd20 = [ $gRpnd20 , golem_run_init ] { };
*/
/*
void() golemb_gstomp1 = [ $gstomp1 , golemb_gstomp2 ] { };
void() golemb_gstomp2 = [ $gstomp2 , golemb_gstomp3 ] { };
void() golemb_gstomp3 = [ $gstomp3 , golemb_gstomp4 ] { };
void() golemb_gstomp4 = [ $gstomp4 , golemb_gstomp5 ] { };
void() golemb_gstomp5 = [ $gstomp5 , golemb_gstomp6 ] { };
void() golemb_gstomp6 = [ $gstomp6 , golemb_gstomp7 ] { };
void() golemb_gstomp7 = [ $gstomp7 , golemb_gstomp8 ] { };
void() golemb_gstomp8 = [ $gstomp8 , golemb_gstomp9 ] { };
void() golemb_gstomp9 = [ $gstomp9 , golemb_gstomp10 ] { };
void() golemb_gstomp10 = [ $gstomp10 , golemb_gstomp11 ] { };
void() golemb_gstomp11 = [ $gstomp11 , golemb_gstomp12 ] { };
void() golemb_gstomp12 = [ $gstomp12 , golemb_gstomp13 ] { };
void() golemb_gstomp13 = [ $gstomp13 , golemb_gstomp14 ] { };
void() golemb_gstomp14 = [ $gstomp14 , golemb_gstomp15 ] { };
void() golemb_gstomp15 = [ $gstomp15 , golemb_gstomp16 ] { };
void() golemb_gstomp16 = [ $gstomp16 , golemb_gstomp17 ] { };
void() golemb_gstomp17 = [ $gstomp17 , golemb_gstomp18 ] { };
void() golemb_gstomp18 = [ $gstomp18 , golemb_gstomp19 ] { };
void() golemb_gstomp19 = [ $gstomp19 , golemb_gstomp20 ] { };
void() golemb_gstomp20 = [ $gstomp20 , golemb_gstomp21 ] { };
void() golemb_gstomp21 = [ $gstomp21 , golemb_gstomp22 ] { };
void() golemb_gstomp22 = [ $gstomp22 , golemb_gstomp23 ] { };
void() golemb_gstomp23 = [ $gstomp23 , golemb_gstomp24 ] { };
void() golemb_gstomp24 = [ $gstomp24 , golemb_gstomp25 ] { };
void() golemb_gstomp25 = [ $gstomp25 , golemb_gstomp26 ] { };
void() golemb_gstomp26 = [ $gstomp26 , golemb_gstomp27 ] { };
void() golemb_gstomp27 = [ $gstomp27 , golemb_gstomp28 ] { };
void() golemb_gstomp28 = [ $gstomp28 , golemb_gstomp29 ] { };
void() golemb_gstomp29 = [ $gstomp29 , golemb_gstomp30 ] { };
void() golemb_gstomp30 = [ $gstomp30 , golemb_gstomp1 ] { };
*/
/*
void() golemb_gtran1 = [ $gtran1 , golemb_gtran2 ] { };
void() golemb_gtran2 = [ $gtran2 , golemb_gtran3 ] { };
void() golemb_gtran3 = [ $gtran3 , golemb_gtran4 ] { };
void() golemb_gtran4 = [ $gtran4 , golemb_gtran5 ] { };
void() golemb_gtran5 = [ $gtran5 , golemb_gtran6 ] { };
void() golemb_gtran6 = [ $gtran6 , golemb_gtran7 ] { };
void() golemb_gtran7 = [ $gtran7 , golemb_gtran8 ] { };
void() golemb_gtran8 = [ $gtran8 , golemb_gtran9 ] { };
void() golemb_gtran9 = [ $gtran9 , golemb_gtran10 ] { };
void() golemb_gtran10 = [ $gtran10 , golemb_gtran11 ] { };
void() golemb_gtran11 = [ $gtran11 , golemb_gtran12 ] { };
void() golemb_gtran12 = [ $gtran12 , golemb_gtran13 ] { };
void() golemb_gtran13 = [ $gtran13 , golemb_gtran14 ] { };
void() golemb_gtran14 = [ $gtran14 , golemb_gtran15 ] { };
void() golemb_gtran15 = [ $gtran15 , golemb_gtran16 ] { };
void() golemb_gtran16 = [ $gtran16 , golemb_gtran17 ] { };
void() golemb_gtran17 = [ $gtran17 , golemb_gtran18 ] { };
void() golemb_gtran18 = [ $gtran18 , golemb_gtran19 ] { };
void() golemb_gtran19 = [ $gtran19 , golemb_gtran20 ] { };
void() golemb_gtran20 = [ $gtran20 , golemb_gtran21 ] { };
void() golemb_gtran21 = [ $gtran21 , golemb_gtran22 ] { };
void() golemb_gtran22 = [ $gtran22 , golemb_gtran23 ] { };
void() golemb_gtran23 = [ $gtran23 , golemb_gtran24 ] { };
void() golemb_gtran24 = [ $gtran24 , golemb_gtran25 ] { };
void() golemb_gtran25 = [ $gtran25 , golemb_gtran26 ] { };
void() golemb_gtran26 = [ $gtran26 , golemb_gtran1 ] { };
*/
void() golemb_gstand1 = [ $gbirth1, golemb_gstand1 ] { ai_stand(); };
//==========================================================================
//
// GolemBMeleeDecide
//
//==========================================================================
void GolemBMeleeDecide(void)
{
if(random() > 0.5)
{
GolemBPunchLeft();
}
else
{
GolemBPoundRight();
}
}
//==========================================================================
//
// GolemBPunchLeft
//
//==========================================================================
void GolemBPunchLeft(void) [++ $glpnch1..$glpnch22]
{
if(cycle_wrapped)
{
golem_run_init();
return;
}
if(self.frame == $glpnch8)
{
sound(self, CHAN_BODY, "golem/swing.wav", 1, ATTN_NORM);
}
if(self.frame > $glpnch9 && self.frame < $glpnch18)
{
ai_charge(2);
ai_melee();
}
ai_face();
}
//==========================================================================
//
// GolemBPoundRight
//
//==========================================================================
void GolemBPoundRight(void) [++ $grpnd1..$grpnd20]
{
if(cycle_wrapped)
{
golem_run_init();
return;
}
if(self.frame == $grpnd8)
{
sound(self, CHAN_BODY, "golem/swing.wav", 1, ATTN_NORM);
}
if(self.frame > $grpnd11 && self.frame < $grpnd17)
{
ai_charge(2);
ai_melee();
}
ai_face();
}
//==========================================================================
//
// golemb_pain
//
//==========================================================================
void golemb_pain(void)
{
if(self.pain_finished > time)
{
return;
}
if(golem_flinch($gwalk1, $gwalk60)) return;
if(golem_flinch($ggem1, $ggem25)) return;
if(golem_flinch($gLpnch1, $gLpnch22)) return;
if(golem_flinch($gRpnd1, $gRpnd20)) return;
golem_flinch($gstomp1, $gstomp30);
}
//==========================================================================
//
// monster_golem_bronze
//
//==========================================================================
/*QUAKED monster_golem_bronze (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH
Bronze Golem.
------- key / value ----------------------------
health = 500
experience_value = 275
------- spawnflags -----------------------------
AMBUSH
*/
void monster_golem_bronze(void)
{
if(deathmatch)
{
remove(self);
return;
}
precache_model2("models/golem_b.mdl");
// precache_model2("models/h_golem.mdl"); // empty for now
precache_sound2("golem/step.wav");
precache_sound2("golem/swing.wav");
precache_sound2("golem/mtlfall.wav");
precache_sound2("golem/stomp.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
self.thingtype = THINGTYPE_METAL;
self.yaw_speed = 10;
self.mass = 50;
self.mintel = 2;
setmodel(self, "models/golem_b.mdl");
setsize(self, '-20 -20 0', '20 20 80');
self.health = 500;
self.experience_value = 275;
self.th_stand = golemb_gstand1;
self.th_walk = golem_walk;
self.th_run = golem_run_init;
self.th_die = golem_die_init;
self.th_melee = GolemBMeleeDecide;
self.th_pain = golemb_pain;
self.view_ofs = '0 0 64';
walkmonster_start();
}

396
golem_i.hc Normal file
View File

@ -0,0 +1,396 @@
//**************************************************************************
//**
//** golem_i.hc
//**
//** $Header: /HexenWorld/Siege/golem_i.hc 3 5/25/98 1:38p Mgummelt $
//**
//** Iron golem.
//**
//**************************************************************************
// FRAMES ------------------------------------------------------------------
// Transition from still to attack stance
$frame gbirth1 gbirth2 gbirth3 gbirth4 gbirth5
$frame gbirth6 gbirth7 gbirth8 gbirth9 gbirth10
$frame gbirth11 gbirth12
// Death
$frame gdeath1 gdeath2 gdeath3 gdeath4 gdeath5
$frame gdeath6 gdeath7 gdeath8 gdeath9 gdeath10
$frame gdeath11 gdeath12 gdeath13 gdeath14 gdeath15
$frame gdeath16 gdeath17 gdeath18 gdeath19 gdeath20
$frame gdeath21 gdeath22 gdeath23 gdeath24 gdeath25
$frame gdeath26 gdeath27 gdeath28 gdeath29 gdeath30
$frame gdeath31 gdeath32 gdeath33 gdeath34 gdeath35
$frame gdeath36 gdeath37 gdeath38 gdeath39 gdeath40
$frame gdeath41 gdeath42 gdeath43 gdeath44 gdeath45
$frame gdeath46 gdeath47 gdeath48 gdeath49 gdeath50
$frame gdeath51
// Walking
$frame gwalk1 gwalk2 gwalk3 gwalk4 gwalk5
$frame gwalk6 gwalk7 gwalk8 gwalk9 gwalk10
$frame gwalk11 gwalk12 gwalk13 gwalk14 gwalk15
$frame gwalk16 gwalk17 gwalk18 gwalk19 gwalk20
$frame gwalk21 gwalk22 gwalk23 gwalk24 gwalk25
$frame gwalk26 gwalk27 gwalk28 gwalk29 gwalk30
$frame gwalk31 gwalk32 gwalk33 gwalk34 gwalk35
$frame gwalk36 gwalk37 gwalk38 gwalk39 gwalk40
$frame gwalk41 gwalk42 gwalk43 gwalk44 gwalk45
$frame gwalk46 gwalk47 gwalk48 gwalk49 gwalk50
$frame gwalk51 gwalk52 gwalk53 gwalk54 gwalk55
$frame gwalk56 gwalk57 gwalk58 gwalk59 gwalk60
// Transition from attack stance to walking
$frame gtran1 gtran2 gtran3 gtran4 gtran5
$frame gtran6 gtran7 gtran8 gtran9 gtran10
$frame gtran11 gtran12 gtran13 gtran14 gtran15
$frame gtran16 gtran17 gtran18 gtran19 gtran20
$frame gtran21 gtran22 gtran23 gtran24 gtran25
$frame gtran26
// Gem attack
$frame ggem1 ggem2 ggem3 ggem4 ggem5
$frame ggem6 ggem7 ggem8 ggem9 ggem10
$frame ggem11 ggem12 ggem13 ggem14 ggem15
$frame ggem16 ggem17 ggem18 ggem19 ggem20
$frame ggem21 ggem22 ggem23 ggem24 ggem25
// Left hand pound attack
$frame gLpnd1 gLpnd2 gLpnd3 gLpnd4 gLpnd5
$frame gLpnd6 gLpnd7 gLpnd8 gLpnd9 gLpnd10
$frame gLpnd11 gLpnd12 gLpnd13 gLpnd14 gLpnd15
$frame gLpnd16 gLpnd17 gLpnd18 gLpnd19 gLpnd20
// Right hand punch attack
$frame gRpnch1 gRpnch2 gRpnch3 gRpnch4 gRpnch5
$frame gRpnch6 gRpnch7 gRpnch8 gRpnch9 gRpnch10
$frame gRpnch11 gRpnch12 gRpnch13 gRpnch14 gRpnch15
$frame gRpnch16 gRpnch17 gRpnch18 gRpnch19 gRpnch20
$frame gRpnch21 gRpnch22
void GolemIMeleeDecide(void);
void GolemIPunchRight(void);
void GolemIPoundLeft(void);
// CODE --------------------------------------------------------------------
void() golemi_gbirth1 = [ $gbirth1 , golemi_gbirth2 ] { };
void() golemi_gbirth2 = [ $gbirth2 , golemi_gbirth3 ] { };
void() golemi_gbirth3 = [ $gbirth3 , golemi_gbirth4 ] { };
void() golemi_gbirth4 = [ $gbirth4 , golemi_gbirth5 ] { };
void() golemi_gbirth5 = [ $gbirth5 , golemi_gbirth6 ] { };
void() golemi_gbirth6 = [ $gbirth6 , golemi_gbirth7 ] { };
void() golemi_gbirth7 = [ $gbirth7 , golemi_gbirth8 ] { };
void() golemi_gbirth8 = [ $gbirth8 , golemi_gbirth9 ] { };
void() golemi_gbirth9 = [ $gbirth9 , golemi_gbirth10 ] { };
void() golemi_gbirth10 = [ $gbirth10 , golemi_gbirth11 ] { };
void() golemi_gbirth11 = [ $gbirth11 , golemi_gbirth12 ] { };
void() golemi_gbirth12 = [ $gbirth12 , golemi_gbirth1 ] { };
/*
void() golemi_gdeath1 = [ $gdeath1 , golemi_gdeath2 ] { };
void() golemi_gdeath2 = [ $gdeath2 , golemi_gdeath3 ] { };
void() golemi_gdeath3 = [ $gdeath3 , golemi_gdeath4 ] { };
void() golemi_gdeath4 = [ $gdeath4 , golemi_gdeath5 ] { };
void() golemi_gdeath5 = [ $gdeath5 , golemi_gdeath6 ] { };
void() golemi_gdeath6 = [ $gdeath6 , golemi_gdeath7 ] { };
void() golemi_gdeath7 = [ $gdeath7 , golemi_gdeath8 ] { };
void() golemi_gdeath8 = [ $gdeath8 , golemi_gdeath9 ] { };
void() golemi_gdeath9 = [ $gdeath9 , golemi_gdeath10 ] { };
void() golemi_gdeath10 = [ $gdeath10 , golemi_gdeath11 ] { };
void() golemi_gdeath11 = [ $gdeath11 , golemi_gdeath12 ] { };
void() golemi_gdeath12 = [ $gdeath12 , golemi_gdeath13 ] { };
void() golemi_gdeath13 = [ $gdeath13 , golemi_gdeath14 ] { };
void() golemi_gdeath14 = [ $gdeath14 , golemi_gdeath15 ] { };
void() golemi_gdeath15 = [ $gdeath15 , golemi_gdeath16 ] { };
void() golemi_gdeath16 = [ $gdeath16 , golemi_gdeath17 ] { };
void() golemi_gdeath17 = [ $gdeath17 , golemi_gdeath18 ] { };
void() golemi_gdeath18 = [ $gdeath18 , golemi_gdeath19 ] { };
void() golemi_gdeath19 = [ $gdeath19 , golemi_gdeath20 ] { };
void() golemi_gdeath20 = [ $gdeath20 , golemi_gdeath21 ] { };
void() golemi_gdeath21 = [ $gdeath21 , golemi_gdeath22 ] { };
void() golemi_gdeath22 = [ $gdeath22 , golemi_gdeath23 ] { };
void() golemi_gdeath23 = [ $gdeath23 , golemi_gdeath24 ] { };
void() golemi_gdeath24 = [ $gdeath24 , golemi_gdeath25 ] { };
void() golemi_gdeath25 = [ $gdeath25 , golemi_gdeath26 ] { };
void() golemi_gdeath26 = [ $gdeath26 , golemi_gdeath27 ] { };
void() golemi_gdeath27 = [ $gdeath27 , golemi_gdeath28 ] { };
void() golemi_gdeath28 = [ $gdeath28 , golemi_gdeath29 ] { };
void() golemi_gdeath29 = [ $gdeath29 , golemi_gdeath30 ] { };
void() golemi_gdeath30 = [ $gdeath30 , golemi_gdeath31 ] { };
void() golemi_gdeath31 = [ $gdeath31 , golemi_gdeath32 ] { };
void() golemi_gdeath32 = [ $gdeath32 , golemi_gdeath33 ] { };
void() golemi_gdeath33 = [ $gdeath33 , golemi_gdeath34 ] { };
void() golemi_gdeath34 = [ $gdeath34 , golemi_gdeath35 ] { };
void() golemi_gdeath35 = [ $gdeath35 , golemi_gdeath36 ] { };
void() golemi_gdeath36 = [ $gdeath36 , golemi_gdeath37 ]
{
self.solid = SOLID_NOT;
};
void() golemi_gdeath37 = [ $gdeath37 , golemi_gdeath38 ] { };
void() golemi_gdeath38 = [ $gdeath38 , golemi_gdeath39 ] { };
void() golemi_gdeath39 = [ $gdeath39 , golemi_gdeath40 ] { };
void() golemi_gdeath40 = [ $gdeath40 , golemi_gdeath41 ] { };
void() golemi_gdeath41 = [ $gdeath41 , golemi_gdeath42 ] { };
void() golemi_gdeath42 = [ $gdeath42 , golemi_gdeath43 ] { };
void() golemi_gdeath43 = [ $gdeath43 , golemi_gdeath44 ] { };
void() golemi_gdeath44 = [ $gdeath44 , golemi_gdeath45 ] { };
void() golemi_gdeath45 = [ $gdeath45 , golemi_gdeath46 ] { };
void() golemi_gdeath46 = [ $gdeath46 , golemi_gdeath47 ] { };
void() golemi_gdeath47 = [ $gdeath47 , golemi_gdeath48 ] { };
void() golemi_gdeath48 = [ $gdeath48 , golemi_gdeath49 ] { };
void() golemi_gdeath49 = [ $gdeath49 , golemi_gdeath50 ] { };
void() golemi_gdeath50 = [ $gdeath50 , golemi_gdeath51 ] { };
void() golemi_gdeath51 = [ $gdeath51 , golemi_gdeath51 ] { };
*/
/*
void() golemi_ggem1 = [ $ggem1 , golemi_ggem2 ] {ai_face(); };
void() golemi_ggem2 = [ $ggem2 , golemi_ggem3 ] {ai_face(); };
void() golemi_ggem3 = [ $ggem3 , golemi_ggem4 ] {ai_face(); };
void() golemi_ggem4 = [ $ggem4 , golemi_ggem5 ] {ai_face(); };
void() golemi_ggem5 = [ $ggem5 , golemi_ggem6 ] {ai_face(); };
void() golemi_ggem6 = [ $ggem6 , golemi_ggem7 ] {ai_face(); };
void() golemi_ggem7 = [ $ggem7 , golemi_ggem8 ] {ai_face(); };
void() golemi_ggem8 = [ $ggem8 , golemi_ggem9 ] {ai_face(); };
void() golemi_ggem9 = [ $ggem9 , golemi_ggem10 ] {ai_face(); };
void() golemi_ggem10 = [ $ggem10 , golemi_ggem11 ] {ai_face(); };
void() golemi_ggem11 = [ $ggem11 , golemi_ggem12 ] {ai_face(); };
void() golemi_ggem12 = [ $ggem12 , golemi_ggem13 ] {ai_face(); };
void() golemi_ggem13 = [ $ggem13 , golemi_ggem14 ] {ai_face();};
void() golemi_ggem14 = [ $ggem14 , golemi_ggem15 ] {ai_face(); };
void() golemi_ggem15 = [ $ggem15 , golemi_ggem16 ] {ai_face(); };
void() golemi_ggem16 = [ $ggem16 , golemi_ggem17 ] {ai_face(); };
void() golemi_ggem17 = [ $ggem17 , golemi_ggem18 ] {ai_face();};
void() golemi_ggem18 = [ $ggem18 , golemi_ggem19 ] {ai_face(); };
void() golemi_ggem19 = [ $ggem19 , golemi_ggem20 ] {ai_face(); };
void() golemi_ggem20 = [ $ggem20 , golemi_ggem21 ] {ai_face(); };
void() golemi_ggem21 = [ $ggem21 , golemi_ggem22 ] {ai_face();};
void() golemi_ggem22 = [ $ggem22 , golemi_ggem23 ] {ai_face(); };
void() golemi_ggem23 = [ $ggem23 , golemi_ggem24 ] {ai_face(); };
void() golemi_ggem24 = [ $ggem24 , golemi_ggem25 ] {ai_face(); };
void() golemi_ggem25 = [ $ggem25 , golem_run_init ] {ai_face(); };
*/
/*
void() golemi_gLpnd1 = [ $gLpnd1 , golemi_gLpnd2 ] { };
void() golemi_gLpnd2 = [ $gLpnd2 , golemi_gLpnd3 ] { };
void() golemi_gLpnd3 = [ $gLpnd3 , golemi_gLpnd4 ] { };
void() golemi_gLpnd4 = [ $gLpnd4 , golemi_gLpnd5 ] { };
void() golemi_gLpnd5 = [ $gLpnd5 , golemi_gLpnd6 ] { };
void() golemi_gLpnd6 = [ $gLpnd6 , golemi_gLpnd7 ] { };
void() golemi_gLpnd7 = [ $gLpnd7 , golemi_gLpnd8 ] { };
void() golemi_gLpnd8 = [ $gLpnd8 , golemi_gLpnd9 ] { };
void() golemi_gLpnd9 = [ $gLpnd9 , golemi_gLpnd10 ] { };
void() golemi_gLpnd10 = [ $gLpnd10 , golemi_gLpnd11 ] { };
void() golemi_gLpnd11 = [ $gLpnd11 , golemi_gLpnd12 ] { };
void() golemi_gLpnd12 = [ $gLpnd12 , golemi_gLpnd13 ] { };
void() golemi_gLpnd13 = [ $gLpnd13 , golemi_gLpnd14 ] { };
void() golemi_gLpnd14 = [ $gLpnd14 , golemi_gLpnd15 ] { };
void() golemi_gLpnd15 = [ $gLpnd15 , golemi_gLpnd16 ] { };
void() golemi_gLpnd16 = [ $gLpnd16 , golemi_gLpnd17 ] { };
void() golemi_gLpnd17 = [ $gLpnd17 , golemi_gLpnd18 ] { };
void() golemi_gLpnd18 = [ $gLpnd18 , golemi_gLpnd19 ] { };
void() golemi_gLpnd19 = [ $gLpnd19 , golemi_gLpnd20 ] { };
void() golemi_gLpnd20 = [ $gLpnd20 , golem_run_init ] { };
*/
/*
void() golemi_gRpnch1 = [ $gRpnch1 , golemi_gRpnch2 ] { };
void() golemi_gRpnch2 = [ $gRpnch2 , golemi_gRpnch3 ] { };
void() golemi_gRpnch3 = [ $gRpnch3 , golemi_gRpnch4 ] { };
void() golemi_gRpnch4 = [ $gRpnch4 , golemi_gRpnch5 ] { };
void() golemi_gRpnch5 = [ $gRpnch5 , golemi_gRpnch6 ] { };
void() golemi_gRpnch6 = [ $gRpnch6 , golemi_gRpnch7 ] { };
void() golemi_gRpnch7 = [ $gRpnch7 , golemi_gRpnch8 ] { };
void() golemi_gRpnch8 = [ $gRpnch8 , golemi_gRpnch9 ] { };
void() golemi_gRpnch9 = [ $gRpnch9 , golemi_gRpnch10 ] { };
void() golemi_gRpnch10 = [ $gRpnch10 , golemi_gRpnch11 ] { };
void() golemi_gRpnch11 = [ $gRpnch11 , golemi_gRpnch12 ] { };
void() golemi_gRpnch12 = [ $gRpnch12 , golemi_gRpnch13 ] { };
void() golemi_gRpnch13 = [ $gRpnch13 , golemi_gRpnch14 ] { };
void() golemi_gRpnch14 = [ $gRpnch14 , golemi_gRpnch15 ] { };
void() golemi_gRpnch15 = [ $gRpnch15 , golemi_gRpnch16 ] { };
void() golemi_gRpnch16 = [ $gRpnch16 , golemi_gRpnch17 ] { };
void() golemi_gRpnch17 = [ $gRpnch17 , golemi_gRpnch18 ] { };
void() golemi_gRpnch18 = [ $gRpnch18 , golemi_gRpnch19 ] { };
void() golemi_gRpnch19 = [ $gRpnch19 , golemi_gRpnch20 ] { };
void() golemi_gRpnch20 = [ $gRpnch20 , golemi_gRpnch21 ] { };
void() golemi_gRpnch21 = [ $gRpnch21 , golemi_gRpnch22 ] { };
void() golemi_gRpnch22 = [ $gRpnch22 , golem_run_init ] { };
*/
/*
void() golemi_gtran1 = [ $gtran1 , golemi_gtran2 ] { };
void() golemi_gtran2 = [ $gtran2 , golemi_gtran3 ] { };
void() golemi_gtran3 = [ $gtran3 , golemi_gtran4 ] { };
void() golemi_gtran4 = [ $gtran4 , golemi_gtran5 ] { };
void() golemi_gtran5 = [ $gtran5 , golemi_gtran6 ] { };
void() golemi_gtran6 = [ $gtran6 , golemi_gtran7 ] { };
void() golemi_gtran7 = [ $gtran7 , golemi_gtran8 ] { };
void() golemi_gtran8 = [ $gtran8 , golemi_gtran9 ] { };
void() golemi_gtran9 = [ $gtran9 , golemi_gtran10 ] { };
void() golemi_gtran10 = [ $gtran10 , golemi_gtran11 ] { };
void() golemi_gtran11 = [ $gtran11 , golemi_gtran12 ] { };
void() golemi_gtran12 = [ $gtran12 , golemi_gtran13 ] { };
void() golemi_gtran13 = [ $gtran13 , golemi_gtran14 ] { };
void() golemi_gtran14 = [ $gtran14 , golemi_gtran15 ] { };
void() golemi_gtran15 = [ $gtran15 , golemi_gtran16 ] { };
void() golemi_gtran16 = [ $gtran16 , golemi_gtran17 ] { };
void() golemi_gtran17 = [ $gtran17 , golemi_gtran18 ] { };
void() golemi_gtran18 = [ $gtran18 , golemi_gtran19 ] { };
void() golemi_gtran19 = [ $gtran19 , golemi_gtran20 ] { };
void() golemi_gtran20 = [ $gtran20 , golemi_gtran21 ] { };
void() golemi_gtran21 = [ $gtran21 , golemi_gtran22 ] { };
void() golemi_gtran22 = [ $gtran22 , golemi_gtran23 ] { };
void() golemi_gtran23 = [ $gtran23 , golemi_gtran24 ] { };
void() golemi_gtran24 = [ $gtran24 , golemi_gtran25 ] { };
void() golemi_gtran25 = [ $gtran25 , golemi_gtran26 ] { };
void() golemi_gtran26 = [ $gtran26 , golemi_gtran1 ] { };
*/
void() golemi_gstand1 = [ $gbirth1, golemi_gstand1 ] { ai_stand(); };
//==========================================================================
//
// GolemIMeleeDecide
//
//==========================================================================
void GolemIMeleeDecide(void)
{
if(random() > 0.5)
{
GolemIPunchRight();
}
else
{
GolemIPoundLeft();
}
}
//==========================================================================
//
// GolemIPunchRight
//
//==========================================================================
void GolemIPunchRight(void) [++ $grpnch1..$grpnch22]
{
if(cycle_wrapped)
{
golem_run_init();
return;
}
if(self.frame == $grpnch8)
{
sound(self, CHAN_BODY, "golem/swing.wav", 1, ATTN_NORM);
}
if(self.frame > $grpnch9 && self.frame < $grpnch18)
{
ai_charge(2);
ai_melee();
}
ai_face();
}
//==========================================================================
//
// GolemIPoundLeft
//
//==========================================================================
void GolemIPoundLeft(void) [++ $glpnd1..$glpnd20]
{
if(cycle_wrapped)
{
golem_run_init();
return;
}
if(self.frame == $glpnd8)
{
sound(self, CHAN_BODY, "golem/swing.wav", 1, ATTN_NORM);
}
if(self.frame > $glpnd11 && self.frame < $glpnd17)
{
ai_charge(2);
ai_melee();
}
ai_face();
}
//==========================================================================
//
// golemi_pain
//
//==========================================================================
void golemi_pain(void)
{
if(self.pain_finished > time)
{
return;
}
if(golem_flinch($gwalk1, $gwalk60)) return;
if(golem_flinch($ggem1, $ggem25)) return;
if(golem_flinch($gRpnch1, $gRpnch22)) return;
golem_flinch($gLpnd1, $gLpnd20);
}
//==========================================================================
//
// monster_golem_iron
//
//==========================================================================
/*QUAKED monster_golem_iron (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH
Iron Golem.
------- key / value ----------------------------
health = 400
experience_value = 200
------- spawnflags -----------------------------
AMBUSH
*/
void monster_golem_iron(void)
{
if(deathmatch)
{
remove(self);
return;
}
precache_model2("models/golem_i.mdl");
// precache_model2("models/h_golem.mdl"); // empty for now
precache_sound2("golem/step.wav");
precache_sound2("golem/swing.wav");
precache_sound2("golem/mtlfall.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
self.thingtype = THINGTYPE_METAL;
self.yaw_speed = 10;
self.mass = 100;
self.mintel = 2;
setmodel(self, "models/golem_i.mdl");
setsize(self, '-20 -20 0', '20 20 80');
self.health = 400;
self.experience_value = 200;
self.th_stand = golemi_gstand1;
self.th_walk = golem_walk;
self.th_run = golem_run_init;
self.th_die = golem_die_init;
self.th_melee = GolemIMeleeDecide;
//self.th_missile = golemi_ggem1;
self.th_pain = golemi_pain;
self.view_ofs = '0 0 64';
walkmonster_start();
}

557
golem_s.hc Normal file
View File

@ -0,0 +1,557 @@
//**************************************************************************
//**
//** golem_s.hc
//**
//** $Header: /HexenWorld/Siege/golem_s.hc 3 5/25/98 1:38p Mgummelt $
//**
//** Stone golem. Also contains generic golem code.
//**
//**************************************************************************
// FRAMES ------------------------------------------------------------------
// Transition from still to attack stance
$frame gbirth1 gbirth2 gbirth3 gbirth4 gbirth5
$frame gbirth6 gbirth7 gbirth8 gbirth9 gbirth10
$frame gbirth11 gbirth12
// Death
$frame gdeath1 gdeath2 gdeath3 gdeath4 gdeath5
$frame gdeath6 gdeath7 gdeath8 gdeath9 gdeath10
$frame gdeath11 gdeath12 gdeath13 gdeath14 gdeath15
$frame gdeath16 gdeath17 gdeath18 gdeath19 gdeath20
$frame gdeath21 gdeath22 gdeath23 gdeath24 gdeath25
$frame gdeath26 gdeath27 gdeath28 gdeath29 gdeath30
$frame gdeath31 gdeath32 gdeath33 gdeath34 gdeath35
$frame gdeath36 gdeath37 gdeath38 gdeath39 gdeath40
$frame gdeath41 gdeath42 gdeath43 gdeath44 gdeath45
$frame gdeath46 gdeath47 gdeath48 gdeath49 gdeath50
$frame gdeath51
// Walking
$frame gwalk1 gwalk2 gwalk3 gwalk4 gwalk5
$frame gwalk6 gwalk7 gwalk8 gwalk9 gwalk10
$frame gwalk11 gwalk12 gwalk13 gwalk14 gwalk15
$frame gwalk16 gwalk17 gwalk18 gwalk19 gwalk20
$frame gwalk21 gwalk22 gwalk23 gwalk24 gwalk25
$frame gwalk26 gwalk27 gwalk28 gwalk29 gwalk30
$frame gwalk31 gwalk32 gwalk33 gwalk34 gwalk35
$frame gwalk36 gwalk37 gwalk38 gwalk39 gwalk40
$frame gwalk41 gwalk42 gwalk43 gwalk44 gwalk45
$frame gwalk46 gwalk47 gwalk48 gwalk49 gwalk50
$frame gwalk51 gwalk52 gwalk53 gwalk54 gwalk55
$frame gwalk56 gwalk57 gwalk58 gwalk59 gwalk60
// Transition from attack stance to walking
$frame gtran1 gtran2 gtran3 gtran4 gtran5
$frame gtran6 gtran7 gtran8 gtran9 gtran10
$frame gtran11 gtran12 gtran13 gtran14 gtran15
$frame gtran16 gtran17 gtran18 gtran19 gtran20
$frame gtran21 gtran22 gtran23 gtran24 gtran25
$frame gtran26
// Two hand pound attack
$frame gDpnd1 gDpnd2 gDpnd3 gDpnd4 gDpnd5
$frame gDpnd6 gDpnd7 gDpnd8 gDpnd9 gDpnd10
$frame gDpnd11 gDpnd12 gDpnd13 gDpnd14 gDpnd15
$frame gDpnd16 gDpnd17 gDpnd18 gDpnd19 gDpnd20
// Left hand punch attack
$frame gLpnch1 gLpnch2 gLpnch3 gLpnch4 gLpnch5
$frame gLpnch6 gLpnch7 gLpnch8 gLpnch9 gLpnch10
$frame gLpnch11 gLpnch12 gLpnch13 gLpnch14 gLpnch15
$frame gLpnch16 gLpnch17 gLpnch18 gLpnch19 gLpnch20
$frame gLpnch21 gLpnch22
// Right hand punch attack
$frame gRpnch1 gRpnch2 gRpnch3 gRpnch4 gRpnch5
$frame gRpnch6 gRpnch7 gRpnch8 gRpnch9 gRpnch10
$frame gRpnch11 gRpnch12 gRpnch13 gRpnch14 gRpnch15
$frame gRpnch16 gRpnch17 gRpnch18 gRpnch19 gRpnch20
$frame gRpnch21 gRpnch22
$framevalue 0
$frame tgrun1 tgrun2 tgrun3 tgrun4 tgrun5
$frame tgrun6 tgrun7 tgrun8 tgrun9 tgrun10
$frame tgrun11 tgrun12 tgrun13 tgrun14 tgrun15
$frame tgrun16 tgrun17 tgrun18 tgrun19 tgrun20
$frame tgrun21 tgrun22 tgrun23 tgrun24
$frame tgwalk1 tgwalk2 tgwalk3 tgwalk4 tgwalk5
$frame tgwalk6 tgwalk7 tgwalk8 tgwalk9 tgwalk10
$frame tgwalk11 tgwalk12 tgwalk13 tgwalk14 tgwalk15
$frame tgwalk16 tgwalk17 tgwalk18 tgwalk19 tgwalk20
$frame tgwalk21 tgwalk22 tgwalk23 tgwalk24 tgwalk25
$frame tgwalk26 tgwalk27 tgwalk28 tgwalk29 tgwalk30
$frame tgwalk31 tgwalk32 tgwalk33 tgwalk34
void GolemSPunchLeft(void);
void GolemSPunchRight(void);
void GolemSPound(void);
void golem_run_init(void);
// CODE --------------------------------------------------------------------
void() golems_gbirth1 = [ $gbirth1 , golems_gbirth2 ] { };
void() golems_gbirth2 = [ $gbirth2 , golems_gbirth3 ] { };
void() golems_gbirth3 = [ $gbirth3 , golems_gbirth4 ] { };
void() golems_gbirth4 = [ $gbirth4 , golems_gbirth5 ] { };
void() golems_gbirth5 = [ $gbirth5 , golems_gbirth6 ] { };
void() golems_gbirth6 = [ $gbirth6 , golems_gbirth7 ] { };
void() golems_gbirth7 = [ $gbirth7 , golems_gbirth8 ] { };
void() golems_gbirth8 = [ $gbirth8 , golems_gbirth9 ] { };
void() golems_gbirth9 = [ $gbirth9 , golems_gbirth10 ] { };
void() golems_gbirth10 = [ $gbirth10 , golems_gbirth11 ] { };
void() golems_gbirth11 = [ $gbirth11 , golems_gbirth12 ] { };
void() golems_gbirth12 = [ $gbirth12 , golems_gbirth1 ] { };
/*
void() golems_gDpnd1 = [ $gDpnd1 , golems_gDpnd2 ] { };
void() golems_gDpnd2 = [ $gDpnd2 , golems_gDpnd3 ] { };
void() golems_gDpnd3 = [ $gDpnd3 , golems_gDpnd4 ] { };
void() golems_gDpnd4 = [ $gDpnd4 , golems_gDpnd5 ] { };
void() golems_gDpnd5 = [ $gDpnd5 , golems_gDpnd6 ] { };
void() golems_gDpnd6 = [ $gDpnd6 , golems_gDpnd7 ] { };
void() golems_gDpnd7 = [ $gDpnd7 , golems_gDpnd8 ] { };
void() golems_gDpnd8 = [ $gDpnd8 , golems_gDpnd9 ] { };
void() golems_gDpnd9 = [ $gDpnd9 , golems_gDpnd10 ] { };
void() golems_gDpnd10 = [ $gDpnd10 , golems_gDpnd11 ] { };
void() golems_gDpnd11 = [ $gDpnd11 , golems_gDpnd12 ] { };
void() golems_gDpnd12 = [ $gDpnd12 , golems_gDpnd13 ] { };
void() golems_gDpnd13 = [ $gDpnd13 , golems_gDpnd14 ] { };
void() golems_gDpnd14 = [ $gDpnd14 , golems_gDpnd15 ] { };
void() golems_gDpnd15 = [ $gDpnd15 , golems_gDpnd16 ] { };
void() golems_gDpnd16 = [ $gDpnd16 , golems_gDpnd17 ] { };
void() golems_gDpnd17 = [ $gDpnd17 , golems_gDpnd18 ] { };
void() golems_gDpnd18 = [ $gDpnd18 , golems_gDpnd19 ] { };
void() golems_gDpnd19 = [ $gDpnd19 , golems_gDpnd20 ] { };
void() golems_gDpnd20 = [ $gDpnd20 , golem_run_init ] { };
void() golems_gLpnch1 = [ $gLpnch1 , golems_gLpnch2 ] { };
void() golems_gLpnch2 = [ $gLpnch2 , golems_gLpnch3 ] { };
void() golems_gLpnch3 = [ $gLpnch3 , golems_gLpnch4 ] { };
void() golems_gLpnch4 = [ $gLpnch4 , golems_gLpnch5 ] { };
void() golems_gLpnch5 = [ $gLpnch5 , golems_gLpnch6 ] { };
void() golems_gLpnch6 = [ $gLpnch6 , golems_gLpnch7 ] { };
void() golems_gLpnch7 = [ $gLpnch7 , golems_gLpnch8 ] { };
void() golems_gLpnch8 = [ $gLpnch8 , golems_gLpnch9 ] { };
void() golems_gLpnch9 = [ $gLpnch9 , golems_gLpnch10 ] { };
void() golems_gLpnch10 = [ $gLpnch10 , golems_gLpnch11 ] { };
void() golems_gLpnch11 = [ $gLpnch11 , golems_gLpnch12 ] { };
void() golems_gLpnch12 = [ $gLpnch12 , golems_gLpnch13 ] { };
void() golems_gLpnch13 = [ $gLpnch13 , golems_gLpnch14 ] { };
void() golems_gLpnch14 = [ $gLpnch14 , golems_gLpnch15 ] { };
void() golems_gLpnch15 = [ $gLpnch15 , golems_gLpnch16 ] { };
void() golems_gLpnch16 = [ $gLpnch16 , golems_gLpnch17 ] { };
void() golems_gLpnch17 = [ $gLpnch17 , golems_gLpnch18 ] { };
void() golems_gLpnch18 = [ $gLpnch18 , golems_gLpnch19 ] { };
void() golems_gLpnch19 = [ $gLpnch19 , golems_gLpnch20 ] { };
void() golems_gLpnch20 = [ $gLpnch20 , golems_gLpnch21 ] { };
void() golems_gLpnch21 = [ $gLpnch21 , golems_gLpnch22 ] { };
void() golems_gLpnch22 = [ $gLpnch22 , golem_run_init ] { };
void()
golems_gRpnch1 = [$gRpnch1 golems_gRpnch2 ],
golems_gRpnch2 = [$gRpnch2 golems_gRpnch3 ],
golems_gRpnch3 = [$gRpnch3 golems_gRpnch4 ],
golems_gRpnch4 = [$gRpnch4 golems_gRpnch5 ],
golems_gRpnch5 = [$gRpnch5 golems_gRpnch6 ],
golems_gRpnch6 = [$gRpnch6 golems_gRpnch7 ],
golems_gRpnch7 = [$gRpnch7 golems_gRpnch8 ],
golems_gRpnch8 = [$gRpnch8 golems_gRpnch9 ],
golems_gRpnch9 = [$gRpnch9 golems_gRpnch10 ],
golems_gRpnch10 = [$gRpnch10 golems_gRpnch11 ],
golems_gRpnch11 = [$gRpnch11 golems_gRpnch12 ],
golems_gRpnch12 = [$gRpnch12 golems_gRpnch13 ],
golems_gRpnch13 = [$gRpnch13 golems_gRpnch14 ],
golems_gRpnch14 = [$gRpnch14 golems_gRpnch15 ],
golems_gRpnch15 = [$gRpnch15 golems_gRpnch16 ],
golems_gRpnch16 = [$gRpnch16 golems_gRpnch17 ],
golems_gRpnch17 = [$gRpnch17 golems_gRpnch18 ],
golems_gRpnch18 = [$gRpnch18 golems_gRpnch19 ],
golems_gRpnch19 = [$gRpnch19 golems_gRpnch20 ],
golems_gRpnch20 = [$gRpnch20 golems_gRpnch21 ],
golems_gRpnch21 = [$gRpnch21 golems_gRpnch22 ],
golems_gRpnch22 = [$gRpnch22 golem_run_init ];
*/
/*
void() golems_gtran1 = [ $gtran1 , golems_gtran2 ] { };
void() golems_gtran2 = [ $gtran2 , golems_gtran3 ] { };
void() golems_gtran3 = [ $gtran3 , golems_gtran4 ] { };
void() golems_gtran4 = [ $gtran4 , golems_gtran5 ] { };
void() golems_gtran5 = [ $gtran5 , golems_gtran6 ] { };
void() golems_gtran6 = [ $gtran6 , golems_gtran7 ] { };
void() golems_gtran7 = [ $gtran7 , golems_gtran8 ] { };
void() golems_gtran8 = [ $gtran8 , golems_gtran9 ] { };
void() golems_gtran9 = [ $gtran9 , golems_gtran10 ] { };
void() golems_gtran10 = [ $gtran10 , golems_gtran11 ] { };
void() golems_gtran11 = [ $gtran11 , golems_gtran12 ] { };
void() golems_gtran12 = [ $gtran12 , golems_gtran13 ] { };
void() golems_gtran13 = [ $gtran13 , golems_gtran14 ] { };
void() golems_gtran14 = [ $gtran14 , golems_gtran15 ] { };
void() golems_gtran15 = [ $gtran15 , golems_gtran16 ] { };
void() golems_gtran16 = [ $gtran16 , golems_gtran17 ] { };
void() golems_gtran17 = [ $gtran17 , golems_gtran18 ] { };
void() golems_gtran18 = [ $gtran18 , golems_gtran19 ] { };
void() golems_gtran19 = [ $gtran19 , golems_gtran20 ] { };
void() golems_gtran20 = [ $gtran20 , golems_gtran21 ] { };
void() golems_gtran21 = [ $gtran21 , golems_gtran22 ] { };
void() golems_gtran22 = [ $gtran22 , golems_gtran23 ] { };
void() golems_gtran23 = [ $gtran23 , golems_gtran24 ] { };
void() golems_gtran24 = [ $gtran24 , golems_gtran25 ] { };
void() golems_gtran25 = [ $gtran25 , golems_gtran26 ] { };
void() golems_gtran26 = [ $gtran26 , golems_gtran1 ] { };
*/
void() golems_gstand1 = [ $gbirth1, golems_gstand1 ]
{
ai_stand();
};
//==========================================================================
//
// GolemSMeleeDecide
//
//==========================================================================
void GolemSMeleeDecide(void)
{
float rnd;
rnd = random();
if(rnd > 0.66)
{
GolemSPunchLeft();
}
else if(rnd > 0.33)
{
GolemSPunchRight();
}
else
{
GolemSPound();
}
}
//==========================================================================
//
// GolemSPunchLeft
//
//==========================================================================
void GolemSPunchLeft(void) [++ $glpnch1..$glpnch22]
{
if(cycle_wrapped)
{
golem_run_init();
return;
}
if(self.frame == $glpnch8)
{
sound(self, CHAN_BODY, "golem/swing.wav", 1, ATTN_NORM);
}
if(self.frame > $glpnch9 && self.frame < $glpnch18)
{
ai_charge(2);
ai_melee();
}
ai_face();
}
//==========================================================================
//
// GolemSPunchRight
//
//==========================================================================
void GolemSPunchRight(void) [++ $grpnch1..$grpnch22]
{
if(cycle_wrapped)
{
golem_run_init();
return;
}
if(self.frame == $grpnch8)
{
sound(self, CHAN_BODY, "golem/swing.wav", 1, ATTN_NORM);
}
if(self.frame > $grpnch9 && self.frame < $grpnch18)
{
ai_charge(2);
ai_melee();
}
ai_face();
}
//==========================================================================
//
// GolemSPound
//
//==========================================================================
void GolemSPound(void) [++ $gdpnd1..$gdpnd20]
{
if(cycle_wrapped)
{
golem_run_init();
return;
}
if(self.frame == $gdpnd8)
{
sound(self, CHAN_BODY, "golem/swing.wav", 1, ATTN_NORM);
}
if(self.frame > $gdpnd9 && self.frame < $gdpnd18)
{
ai_charge(2);
ai_melee();
}
ai_face();
}
//==========================================================================
//
// golem_run
//
//==========================================================================
void golem_run(void)
{
vector tvec;
if(self.count == 20)
{
if(self.frame == $tgrun24)
{
self.frame = $tgrun1;
}
else
{
self.frame += 1;
}
ai_run(6);
}
else
{
if(self.frame == $tgwalk34)
{
self.frame = $tgwalk1;
}
else
{
self.frame += 1;
}
ai_run(3);
}
// if(self.frame == $gwalk27 || self.frame == $gwalk58)
// {
// sound(self, CHAN_BODY, "golem/step.wav", 1, ATTN_NORM);
// }
thinktime self : HX_FRAME_TIME;
}
void golem_run_init(void)
{
if(self.count == 20)
{
if(self.frame < $tgrun1 || self.frame > $tgrun24)
{
self.frame = $tgrun1;
}
ai_run(2);
}
else
{
if(self.frame < $tgwalk1 || self.frame > $tgwalk34)
{
self.frame = $tgwalk1;
}
ai_run(1);
}
thinktime self : HX_FRAME_TIME;
self.think = golem_run;
}
//==========================================================================
//
// golem_walk
//
//==========================================================================
void golem_walk(void) [++ $gwalk1..$gwalk60]
{
if(self.frame == $gwalk27 || self.frame == $gwalk58)
{
sound(self, CHAN_BODY, "golem/step.wav", 1, ATTN_NORM);
}
ai_walk(1);
}
//==========================================================================
//
// golem_die
//
//==========================================================================
void golem_die(void)
{
if(self.frame == $gdeath51)
{
self.nextthink = time - 1;
/* if(self.classname == "monster_golem_stone")
{
}
else if(self.classname == "monster_golem_iron")
{
}
else
{ // Assumed bronze
}
*/
MakeSolidCorpse();
return;
}
if(self.frame == $gdeath36)
{
self.solid = SOLID_NOT;
}
if(self.health<-50)
self.think=chunk_death;
if(self.flags&FL_ONGROUND)
self.frame += 1;
self.nextthink = time + HX_FRAME_TIME;
}
void golem_die_init(void) [ $gdeath1, golem_die ]
{
}
//==========================================================================
//
// golem_flinch
//
//==========================================================================
float golem_flinch(float firstFrame, float lastFrame)
{
if(self.frame < firstFrame || self.frame > lastFrame)
{
return 0;
}
self.nextthink = self.nextthink+0.1+random()*0.2;
self.frame = self.frame - 8 - rint(random() * 12);
self.pain_finished = time + 1;
if(self.frame < firstFrame)
{ // Wrap
self.frame = lastFrame + 1 - (firstFrame - self.frame);
}
return 1;
}
//==========================================================================
//
// golems_pain
//
//==========================================================================
void golems_pain(void)
{
/* float i;
i = (self.drawflags&MLS_MASKIN)+1;
if(i > 7)
{
i = 0;
}
self.drawflags = (self.drawflags&MLS_MASKOUT)|i;
dprint("mls=");
dprint(ftos(i));
dprint("\n");
*/
if(self.count == 20)
{
self.count = 0;
}
else
{
self.count = 20;
}
if(self.pain_finished > time)
{
return;
}
if(golem_flinch($gwalk1, $gwalk60)) return;
if(golem_flinch($gLpnch1, $gLpnch22)) return;
if(golem_flinch($gRpnch1, $gRpnch22)) return;
golem_flinch($gDpnd1, $gDpnd20);
}
//==========================================================================
//
// monster_golem_stone
//
//==========================================================================
/*QUAKED monster_golem_stone (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH
Stone Golem.
------- key / value ----------------------------
health = 200
experience_value = 125
------- spawnflags -----------------------------
AMBUSH
*/
void monster_golem_stone(void)
{
if(deathmatch)
{
remove(self);
return;
}
//precache_model("models/golem_s.mdl");
precache_model("models/goltest.mdl");
// precache_model("models/h_golem.mdl"); // empty for now
precache_sound2("golem/awaken.wav");
precache_sound2("golem/step.wav");
precache_sound2("golem/swing.wav");
precache_sound2("golem/stnpain.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
self.thingtype = THINGTYPE_GREYSTONE;
self.yaw_speed = 10;
self.mass = 75;
self.mintel = 2;
//setmodel(self, "models/golem_s.mdl");
setmodel(self, "models/goltest.mdl");
//setsize(self, '-20 -20 0', '20 20 80');
setsize(self, '-20 -20 -20', '20 20 60');
self.scale = 1.5;
self.health = 200;
self.experience_value = 125;
self.th_stand = golems_gstand1;
self.th_walk = golem_walk;
self.th_run = golem_run_init;
self.th_die = golem_die_init;
self.th_melee = GolemSMeleeDecide;
//self.th_missile = golems_run_init;
self.th_pain = golems_pain;
self.view_ofs = '0 0 64';
walkmonster_start();
}

200
grenade2.hc Normal file
View File

@ -0,0 +1,200 @@
void() SmallExplosion =
{
particle (self.origin, '0 0 10', 242, 5);
self.movetype = MOVETYPE_NONE;
self.velocity = '0 0 0';
self.touch = SUB_Null;
self.solid = SOLID_NOT;
sound(self,CHAN_AUTO,"weapons/r_exp3.wav",0.25,ATTN_NORM);
remove(self);
};
void() CB_BoltStick;
void(float offset) W_FireFlame;
void()BlowUp=
{
if(self.mass<2.5)
{
self.v_angle_x=random()*360;
self.v_angle_y=random()*360;
self.v_angle_z=random()*360;
self.scale=self.mass;
// W_FireFlame(random()*360);
// W_FireFlame(random()*360);
T_RadiusDamage (self, self.owner, self.mass*100, world);
self.mass += 0.1;
self.think=BlowUp;
self.nextthink=time;//+0.1;
}
else
{
self.think=SUB_Remove;
self.nextthink=time;
}
};
void() SprayFire=
{
local entity fireballblast;
sound(self,CHAN_AUTO,"weapons/fbfire.wav",1,ATTN_NORM);
fireballblast=spawn();
fireballblast.movetype=MOVETYPE_NOCLIP;
fireballblast.owner=self.owner;
fireballblast.classname="fireballblast";
fireballblast.solid=SOLID_NOT;
fireballblast.drawflags +=MLS_ABSLIGHT+SCALE_TYPE_UNIFORM+SCALE_ORIGIN_CENTER;
fireballblast.abslight= 1;
fireballblast.scale=0.1;
setmodel(fireballblast,"progs/blast.mdl");
setsize(fireballblast,'0 0 0','0 0 0');
setorigin(fireballblast,self.origin);
fireballblast.effects=EF_BRIGHTLIGHT;
fireballblast.mass=0.1;
fireballblast.avelocity='50 50 50';
fireballblast.think=BlowUp;
fireballblast.nextthink=time;
};
void() GrenadeExplode2 =
{
if(self.classname=="stickmine")
SprayFire();
T_RadiusDamage (self, self.owner, self.mass, world);
if(self.small)
SmallExplosion();
else
{
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() MultipleExplode;
void() GrenadeTouch2 =
{
if (other == self.owner)
return; // don't explode on owner
if(other.owner==self.owner&&other.classname==self.classname&&self.classname=="minigrenade")
return;
// if (other.takedamage == DAMAGE_YES)
if (other.takedamage)
{
if(self.classname=="multigrenade")
MultipleExplode();
else GrenadeExplode2();
return;
}
sound (self, CHAN_WEAPON, "idweapons/tink1.wav", 1, ATTN_NORM); // bounce sound
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
};
void() StickMineTouch =
{
if(other==self.owner)
return;
local vector stickdir;
sound(self, CHAN_WEAPON, "idweapons/pkup.wav", 1, ATTN_NORM);
if(other.takedamage)
{
// makevectors(self.angles);
stickdir=other.origin+normalize(self.origin-other.origin)*12;
//Modify height for shorter or taller models like imp, golem, spider, etc.
if(other.classname=="player")
//Put it right below view of player
stickdir_z=other.origin_z+other.view_ofs_z - 5;
else if(other.classname=="monster_spider")
stickdir_z=(self.origin_z+(other.origin_z+other.size_z*0.2)*3)*0.25;
else stickdir_z=(self.origin_z+(other.origin_z+other.size_z*0.6)*3)*0.25;
setorigin(self,stickdir);
T_Damage(other,self,self.owner,3);
SpawnPuff(self.origin+v_forward*8,'0 0 0'-v_forward*24,10,other);
}
else
SpawnPuff(self.origin+v_forward*8,'0 0 0'-v_forward*24,10,world);
self.velocity='0 0 0';
self.movetype=MOVETYPE_NOCLIP;
self.solid=SOLID_NOT;
self.touch=SUB_Null;
self.wait=time + 2;
self.health=other.health;
if(other.movetype)
{
self.enemy=other;
self.view_ofs=(self.origin-other.origin);
self.o_angle=(self.angles-self.enemy.angles);
self.think=CB_BoltStick;
self.nextthink=time;
}
else
{
self.movetype=MOVETYPE_NONE;
self.think=GrenadeExplode2;
self.nextthink=time + 2;
}
};
void() Use_StickMine =
{
self.attack_finished=time + 0.2;
makevectors(self.v_angle);
//sound
local entity missile;
missile=spawn();
missile.owner=self;
missile.classname="stickmine";
missile.movetype=MOVETYPE_BOUNCE;
missile.solid=SOLID_BBOX;
// missile.takedamage=DAMAGE_YES;
// missile.health=10;
// missile.th_die=GrenadeExplode2;
missile.touch=StickMineTouch;
missile.mass=50;
missile.velocity=normalize(v_forward)*700 +v_up*200;
missile.avelocity_x=random()*600 - 300;
missile.avelocity_y=random()*600 - 300;
missile.avelocity_z=random()*600 - 300;
setmodel(missile,"progs/stikgren.mdl");
setsize(missile,'0 0 0','0 0 0');
setorigin(missile,self.origin+v_forward*16+'0 0 16');
missile.think=GrenadeExplode2;
missile.nextthink=time + 10;
};
void ParticleTesterThink(void)
{
if(attck_cnt==-1)
remove(self);
particle2(self.origin+'0 0 64', '0 0 0','0 0 0',rint(random()*255+1),attck_cnt,10);
self.think=ParticleTesterThink;
self.nextthink=time + 0.1;
}
void() ParticleTester=
{
local entity missile;
attck_cnt=0;
self.lifetime=TRUE;
missile=spawn();
missile.owner=self;
missile.movetype=MOVETYPE_BOUNCE;
missile.solid=SOLID_BBOX;
missile.velocity=normalize(v_forward)*300;
setmodel(missile,"progs/stikgren.mdl");
setsize(missile,'0 0 0','0 0 0');
setorigin(missile,self.origin+v_forward*16+'0 0 16');
missile.think=ParticleTesterThink;
missile.nextthink=time;
};

244
hamthrow.hc Normal file
View File

@ -0,0 +1,244 @@
/*
* $Header: /HexenWorld/Siege/hamthrow.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\weapons\warhammer\prjctile\hamthrow.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\weapons\warhammer\prjctile
$origin 0 0 0
$base BASE skin
$skin skin
$flags 0
//
$frame HAMMER1 HAMMER2 HAMMER3 HAMMER4 HAMMER5
$frame HAMMER6
// Frame Code
void() frame_HAMMER1 = [ $HAMMER1 , frame_HAMMER2 ] { };
void() frame_HAMMER2 = [ $HAMMER2 , frame_HAMMER3 ] { };
void() frame_HAMMER3 = [ $HAMMER3 , frame_HAMMER4 ] { };
void() frame_HAMMER4 = [ $HAMMER4 , frame_HAMMER5 ] { };
void() frame_HAMMER5 = [ $HAMMER5 , frame_HAMMER6 ] { };
void() frame_HAMMER6 = [ $HAMMER6 , frame_HAMMER1 ] { };
/*QUAKED hamthrow (1 0 0) (0 0 0) (50 50 50)
New item for QuakeEd
-------------------------FIELDS-------------------------
--------------------------------------------------------
*/
/*
void() hamthrow =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model2 ("models/hamthrow.mdl");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_NONE;
setmodel (self, "models/hamthrow.mdl");
self.skin = 0;
setsize (self, '0 0 0', '50 50 50');
self.health = 100;
};
*/
// Throwing Hammer
void() ThrowHammerThink =
{
if (self.aflag == 1)
{
if(visible(self.controller))
{
if (self.effects == 0)
self.effects = 8;
else if (self.effects == 8)
{
self.effects = 4;
sound(self, CHAN_WEAPON, "items/protect3.wav", 0.3, ATTN_NORM);
sprint(self.controller,"Mjolnir Beckons....\n");
self.wait = self.wait + 1;
}
else if (self.effects == 4)
self.effects = 8;
if (self.wait > 10)
{
sound(self.controller, CHAN_ITEM, "idweapons/pkup.wav",1, ATTN_NORM);
self.controller.amthammer = self.controller.amthammer + 1;
sprint(self.controller,"Mjolnir has magically returned\n");
// MagicEffect(self.controller);
remove(self);
}
}
else self.effects = 0;
self.nextthink = time + 0.5;
}
else
{
if (self.aflag == -1)
{
local vector vtemp,dir;
vtemp = self.controller.origin + '0 0 10';
dir = normalize(vtemp - self.origin);
if (self.watertype < -2)
self.velocity = dir * 150;
else self.velocity = dir * 375;
self.angles = vectoangles(self.velocity);
if (self.flags & FL_ONGROUND)// && self.follow == 0)
{
self.avelocity = '500 0 0';
self.flags = self.flags - FL_ONGROUND;
// self.follow = 1;
}
}
sound(self, CHAN_WEAPON, "weapons/whoosh.wav", 0.3, ATTN_NORM);
// SpawnFlame(self.origin);
self.nextthink = time + 0.2;
}
if(self.controller.health<=0)
{
GrenadeExplode2();
remove(self);
}
self.think = ThrowHammerThink;
};
void() HammerTouch =
{
local float inertia;
if (other == self.controller)
{
if (self.aflag!=0||self.bloodloss<time)
{
sound(other, CHAN_ITEM, "idweapons/pkup.wav",1, ATTN_NORM);
other.amthammer = other.amthammer + 1;
remove(self);
return;
}
else return;
}
else if (other.takedamage)
{
if(self.velocity != VEC_ORIGIN && other != self.controller)
if (self.aflag < 1)
{
// spawn_touchblood(40);
// SpawnChunk(self.origin, self.velocity);
other.punchangle_x = -20;
self.enemy = other;
if(other.health)
{
if (other.mass<=0)
inertia=1;
else
inertia = other.mass;
CastLightning();
other.velocity_x = other.velocity_x + self.velocity_x / inertia;
other.velocity_y = other.velocity_y + self.velocity_y / inertia;
other.velocity_z = other.velocity_z + 100;
if(other.flags&FL_ONGROUND)
other.flags = other.flags - FL_ONGROUND;
CastLightning();
CastLightning();
}
T_Damage(other, self, self.controller, 10);
}
/*
else if (other.classname == "player"&&other.amthammer==0)
{
sprint(self.controller,"Your Hammer was stolen by ");
sprint(self.controller,other.netname);
sprint(self.controller,"!\n");
sprint(other,"You got ");
sprint(other,self.controller.netname);
sprint(other,"'s Hammer!\n");
sound(other, CHAN_ITEM, "idweapons/pkup.wav",other.volume + 1, ATTN_NORM);
other.amthammer = other.amthammer + 1;
other.follow = 1;
other.impulse = 1;
remove(self);
}
*/
}
else
{
if (random()<0.5)
sound(self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
else
sound(self, CHAN_WEAPON, "idweapons/tink1.wav", 1, ATTN_NORM);
}
if (self.aflag < 1)
if (visible(self.controller))
self.aflag = -1;
else
{
if (self.aflag != 1)
sprint(self.controller,"You lost your Hammer!\n");
self.aflag = 1;
self.effects = 0;
self.avelocity = '300 300 300';
setsize(self, '-3 -3 -5', '3 3 3');
self.movetype = MOVETYPE_BOUNCE;
}
};
void() ThrowHammer =
{
local entity missile;
sound(self, CHAN_WEAPON, "weapons/whoosh.wav", 1, ATTN_NORM);
missile = spawn();
missile.owner = missile;
missile.controller = self;
missile.classname = "mjolnir";
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
makevectors(self.v_angle);
missile.velocity = aim(self, 10000);
missile.angles = vectoangles(missile.velocity);
if (self.waterlevel > 2)
missile.velocity = missile.velocity * 300;
else
missile.velocity = missile.velocity * 750;
missile.touch = HammerTouch;
missile.health = 100000;
missile.takedamage = DAMAGE_YES;
missile.th_die = T_MissileTouch;
missile.nextthink = time;
missile.bloodloss = time+2;
missile.think = ThrowHammerThink;
setmodel(missile, "models/hamthrow.mdl");
setsize(missile,'-1 -2 -4','1 2 4');
// setsize(missile, VEC_ORIGIN, VEC_ORIGIN);
setorigin(missile, self.origin + v_forward * FL_SWIM + '0 0 16');
missile.avelocity = '-500 0 0';
missile.aflag = 0;
// missile.effects = 4;
missile.mass=200;
self.amthammer = self.amthammer - 1;
self.attack_finished=time + 0.5;
};

72
head.hc Normal file
View File

@ -0,0 +1,72 @@
void(string gibname, float dm) ThrowGib;
vector(float dm) VelocityForDamage;
void CorpseThink (void);
void () HeadThink =
{
if ((self.lifetime<time&&(!deathmatch))||self.watertype == CONTENT_LAVA)
self.th_die();
else
{
self.think = HeadThink;
thinktime self : 0.5;
}
};
/*
* This uses entity.netname to hold the head file (for CorpseDie())
* hack so that we don't have to set anything outside this function.
*/
void ThrowSolidHead (float dm)
{
setmodel (self, self.headmodel);
if(self.headmodel==""||self.headmodel=="models/flesh1.mdl"
||self.headmodel=="models/flesh2.mdl"
||self.headmodel=="models/flesh3.mdl")
{
remove(self);
return;
}
self.headmodel="";
self.frame = 0;
self.movetype = MOVETYPE_STEP;
self.takedamage = DAMAGE_YES;
self.solid = SOLID_PHASE;
setsize (self, '-3 -3 -3', '3 3 3');//Allows step-over, but can't walk on or jump off them
if(!self.mass)
self.mass=1;
self.hull=HULL_POINT;
if (dm != -666)
{
if (dm < 40) // Give it a little push
dm = 40;
self.velocity = VelocityForDamage (dm);
}
setorigin(self,self.origin + '0 0 20');
self.flags(-)FL_ONGROUND;
self.health = 5;
self.th_die = chunk_death;
self.flags(-)FL_MONSTER;
self.angles=RandomVector('300 300 300');
self.classname = "head";
self.controller = self;
self.onfire = FALSE;
self.lifetime = time + random(10,20); // decompose after 20 seconds
if(!deathmatch && !coop && !teamplay)
{
self.think=CorpseThink;
thinktime self : 0.5;
}
else
{
self.think = SUB_Null;
self.nextthink = -1;
}
}

447
hknight.hc Normal file
View File

@ -0,0 +1,447 @@
/*
* $Header: /HexenWorld/Siege/Hknight.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
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;
}
};
/*QUAK-ED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush
-------------------------FIELDS-------------------------
--------------------------------------------------------
*/
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 ();
};

0
holotic.hc Normal file
View File

60
horse.hc Normal file
View File

@ -0,0 +1,60 @@
/*
* $Header: /HexenWorld/Siege/horse.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\monsters\RdrWar\tsthorse\horse.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\monsters\RdrWar\tsthorse
$origin 0 0 0
$base base skin
$skin skin
$flags 0
//
$frame horse
// Frame Code
void() frame_horse = [ $horse , frame_horse ] { };
void() rick_test =
{
entity rider;
if (deathmatch)
{
remove(self);
return;
}
rider = spawn_rider();
precache_model2 ("models/horse.mdl");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_FLY;
setmodel (self, "models/horse.mdl");
self.skin = 0;
setsize (self, '0 0 0', '50 50 50');
self.health = 100;
self.movechain = rider;
rider.origin = self.origin;
rider.flags = rider.flags | FL_MOVECHAIN_ANGLE;
self.avelocity = '100 100 100';
};

40
hurter.hc Normal file
View File

@ -0,0 +1,40 @@
/*
==============================================================================
HURTER (jweier)
==============================================================================
*/
void () hurter_touch =
{
local float damage;
damage = HRT_BASE_DAMAGE * random();
if (other.classname == "player")
{
T_Damage(other, self, self, damage);
}
};
void () hurter =
{
local entity hurt;
hurt = spawn ();
hurt.owner = self;
hurt.touch = hurter_touch;
hurt.movetype = MOVETYPE_NONE;
hurt.solid = SOLID_NOT;
//TODO: Make proper size (currently size of Fish)
setsize (self, '-16 -16 -24', '16 16 24');
//TODO: Add sound effect if any
//self.noise = "raven/in_hurt.wav";
hurt.classname = "hurter";
setorigin (hurt, hurt.origin);
};

842
hydra.hc Normal file
View File

@ -0,0 +1,842 @@
/*
* $Header: /HexenWorld/Siege/hydra.hc 3 5/25/98 1:38p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\monsters\hydra\final\hydra.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\monsters\hydra\final
$origin 0 0 0
$base base 450 200
$skin skin1
$flags 0
//
$frame hadie1 hadie2 hadie3 hadie4 hadie5
$frame hadie6 hadie7 hadie8 hadie9 hadie10
$frame hadie11 hadie12 hadie13 hadie14 hadie15
$frame hadie16 hadie17 hadie18 hadie19 hadie20
$frame hadie21 hadie22 hadie23 hadie24 hadie25
$frame hadie26 hadie27 hadie28 hadie29 hadie30
$frame hadie31 hadie32 hadie33 hadie34 hadie35
$frame hadie36
//
$frame hapan1 hapan2 hapan3 hapan4 hapan5
$frame hapan6 hapan7 hapan8 hapan9 hapan10
//
$frame hlft1 hlft2 hlft3 hlft4 hlft5
$frame hlft6 hlft7 hlft8 hlft9 hlft10
$frame hlft11 hlft12 hlft13 hlft14 hlft15
$frame hlft16 hlft17 hlft18 hlft19 hlft20
$frame hlft21 hlft22 hlft23 hlft24 hlft25
$frame hlft26 hlft27 hlft28 hlft29 hlft30
//
$frame hopen1 hopen2 hopen3 hopen4 hopen5
$frame hopen6 hopen7 hopen8
//
$frame hrit1 hrit2 hrit3 hrit4 hrit5
$frame hrit6 hrit7 hrit8 hrit9 hrit10
$frame hrit11 hrit12 hrit13 hrit14 hrit15
$frame hrit16 hrit17 hrit18 hrit19 hrit20
$frame hrit21 hrit22 hrit23 hrit24 hrit25
$frame hrit26 hrit27 hrit28 hrit29 hrit30
//
$frame hsdie1 hsdie2 hsdie3 hsdie4 hsdie5
$frame hsdie6 hsdie7 hsdie8 hsdie9 hsdie10
$frame hsdie11 hsdie12 hsdie13 hsdie14 hsdie15
$frame hsdie16 hsdie17 hsdie18 hsdie19 hsdie20
$frame hsdie21 hsdie22 hsdie23 hsdie24 hsdie25
$frame hsdie26 hsdie27 hsdie28 hsdie29 hsdie30
$frame hsdie31 hsdie32 hsdie33 hsdie34 hsdie35
$frame hsdie36
//
$frame hspan1 hspan2 hspan3 hspan4 hspan5
$frame hspan6 hspan7 hspan8 hspan9 hspan10
//
$frame hspit1 hspit2 hspit3 hspit4 hspit5
$frame hspit6 hspit7 hspit8 hspit9 hspit10
$frame hspit11 hspit12
//
$frame hswim1 hswim2 hswim3 hswim4 hswim5
$frame hswim6 hswim7 hswim8 hswim9 hswim10
$frame hswim11 hswim12 hswim13 hswim14 hswim15
$frame hswim16 hswim17 hswim18 hswim19 hswim20
//
$frame htent1 htent2 htent3 htent4 htent5
$frame htent6 htent7 htent8 htent9 htent10
$frame htent11 htent12 htent13 htent14 htent15
$frame htent16 htent17 htent18 htent19 htent20
$frame htent21 htent22 htent23 htent24
// Monster Stages
float HYDRA_STAGE_WAIT = 0;
float HYDRA_STAGE_SWIM = 1;
float HYDRA_STAGE_FLOAT = 2;
float HYDRA_STAGE_STRAIGHT = 3;
float HYDRA_STAGE_REVERSE = 4;
float HYDRA_STAGE_CHARGE = 5;
float HYDRA_STAGE_ATTACK = 10;
void hydra_attack(void);
void hydra_CloseFrames(void);
void hydra_move(float thrust);
void hydra_bob(void);
void hydra_init(void)
{ // Set the hydra ready for swim
self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
self.think = self.th_run;
thinktime self : random(.1,.6);
self.count = 0;
self.monster_stage = HYDRA_STAGE_SWIM;
self.hydra_FloatTo = 0;
self.goalentity = self.enemy;
self.monster_awake = TRUE;
}
void hydra_wait(void)
{
if (LocateTarget())
{ // We found a target
hydra_init();
}
}
// Starting frames for making a large turn
//void hydra_BigLeft(void);
//void hydra_BigRight(void);
// Starting frames for making a short turn
//void hydra_ShortLeft(void);
//void hydra_ShortRight(void);
void hydra_OpenFrames(void);
void hydra_TentFrames(void);
void hydra_SpitFrames(void);
float hydra_check_blind_melee();
void hydra_charge_finish()
{
self.yaw_speed = 5;
self.cnt = time + random(5,10);
if (CheckMonsterAttack(MA_MELEE, 3.0))
{
self.monster_stage += HYDRA_STAGE_ATTACK;
self.monster_check = 0;
self.think = hydra_attack;
thinktime self : 0.05;
return;
}
self.monster_stage = HYDRA_STAGE_SWIM;
self.think = self.th_run;
thinktime self : 0.1;
}
void hydra_charge()
{
float dist;
self.yaw_speed = 8;
check_pos_enemy();
ai_face();
dist = vlen(self.enemy.origin - self.origin);
movetogoal(dist / 8);
if (range(self.enemy) == RANGE_MELEE)
{
self.monster_check = 0;
hydra_charge_finish();
return;
}
if (self.hydra_chargeTime < time)
{
self.monster_check = 0;
hydra_charge_finish();
return;
}
self.think = hydra_charge;
thinktime self : 0.05;
}
float hydra_check_blind_melee(void)
{
float dist, c1;//, c2;
if (self.enemy.watertype != CONTENT_WATER) return 0;
if (self.cnt > time) return 0;
dist = vhlen(self.enemy.origin - self.origin);
traceline(self.origin, self.enemy.origin, FALSE, self);
c1 = fov(self, self.enemy, 80);
if ((dist < 256) && c1 && trace_ent == self.enemy)
{
if (random() < 0.2)
return 1;
}
return 0;
}
void hydra_blind(void)
{
stuffcmd (self.enemy, "df\n");
self.hydra_chargeTime = time + 1;
self.think = hydra_charge;
thinktime self : 0.05;
}
void hydra_checkForBlind(void)
{
float r;
r = pointcontents(self.enemy.origin);
if (r != CONTENT_WATER)
{
self.think = self.th_run;
thinktime self : 0.1;
return;
}
r = vhlen(self.enemy.origin - self.origin);
if ((r < 256) && (fov(self, self.enemy, 80)) && (fov(self.enemy, self, 80)))
{
thinktime self : 0.1;
self.think = hydra_blind;
}
else
{
self.think = self.th_run;
thinktime self : 0.1;
}
}
void hydra_swim(float thrust)
{
float dist;
float temp;
if (self.velocity) self.velocity = self.velocity * 0.7;
if (!self.enemy.flags2 & FL_ALIVE)
{
self.goalentity = self.enemy = world;
self.monster_stage = HYDRA_STAGE_WAIT;
return;
}
dist = (4.0 + thrust*6); // Movement distance this turn
movetogoal(dist);
if (self.hydra_FloatTo == 0)
{
dist = self.enemy.origin_z - self.origin_z;
if (dist < -50) self.hydra_FloatTo = dist - random(60);
else if (dist > 50) self.hydra_FloatTo = dist + random(60);
}
if (self.hydra_FloatTo < -10)
{
temp = random(-3.5,-2.5);
// movestep(0,0,temp, FALSE);
self.hydra_FloatTo -= temp;
}
else if (self.hydra_FloatTo > 10)
{
temp = random(2.5,3.5);
// movestep(0,0,temp, FALSE);
self.hydra_FloatTo -= temp;
}
else self.hydra_FloatTo = 0;
self.th_save = self.think;
//checkenemy();
enemy_range = range (self.enemy);
if (hydra_check_blind_melee())
{
self.monster_check = 2;
hydra_attack();
}
dist = vlen(self.enemy.origin - self.origin);
if (dist > 350)
{
if (CheckMonsterAttack(MA_MISSILE,8.0))
return;
}
else
CheckMonsterAttack(MA_MELEE,3.0);
}
void hydra_float(void)
{
float Length;
if (self.velocity) self.velocity = self.velocity * 0.7;
Length = vhlen(self.origin - self.enemy.origin);
if (Length < 300.0)
{
self.monster_stage = HYDRA_STAGE_SWIM;
self.hydra_FloatTo = 0;
return;
}
/*self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
ChangeYaw();*/
ai_face();
self.th_save = self.think;
enemy_range = range (self.enemy);
if (hydra_check_blind_melee())
{
self.monster_check = 2;
hydra_attack();
}
CheckMonsterAttack(MA_MISSILE,8.0);
}
void hydra_reverse(void)
{
float retval;
float dist;
self.monster_duration -= 1;
dist = 4.0; // Movement distance this turn
retval = walkmove(self.angles_y + 180, dist, FALSE);
/*if (!retval)
{
self.ideal_yaw = FindDir();
self.monster_duration = 0;//random(40,70);
self.monster_stage = HYDRA_STAGE_STRAIGHT;
ChangeYaw();//hydra_turn(200);
return;
}*/
//self.monster_stage = HYDRA_STAGE_FLOAT;
}
void hydra_move(float thrust)
{
check_pos_enemy();
if (self.monster_stage == HYDRA_STAGE_SWIM)
{
hydra_swim(thrust);
return;
}
else if (self.monster_stage == HYDRA_STAGE_FLOAT)
{
hydra_float();
return;
}
else if (self.monster_stage == HYDRA_STAGE_WAIT)
{
hydra_wait();
return;
}
else if (self.monster_stage == HYDRA_STAGE_REVERSE)
{
// hydra_reverse();
return;
}
}
void hydra_attack(void)
{
if (self.monster_check > 0)
{
hydra_SpitFrames();
}
else
{
hydra_TentFrames();
}
}
void hydra_fire(void)
{
sound (self, CHAN_WEAPON, "hydra/spit.wav", 1, ATTN_NORM);
do_spit('0 0 0');
do_spit('0 0 0');
do_spit('0 0 0');
}
void hydra_tent(float TryHit)
{
ai_face();
check_pos_enemy();
if (TryHit)
{
makevectors(self.angles);
traceline(self.origin,self.origin+v_forward*128,FALSE,self);
if (trace_ent.takedamage)
{
sound (self, CHAN_WEAPON, "hydra/tent.wav", 1, ATTN_NORM);
T_Damage (trace_ent, self, self, random(1,2));
}
else
movetogoal(15);
}
}
void hydra_open(void)
{
ai_face();
}
void hydra_bob(void)
{
local float rnd1, rnd2, rnd3;
// local vector vtmp1, modi;
rnd1 = self.velocity_x + random(-10,10);
rnd2 = self.velocity_y + random(-10,10);
rnd3 = self.velocity_z + random(10);
if (rnd1 > 10)
rnd1 = 10;
if (rnd1 < -10)
rnd1 = -10;
if (rnd2 > 10)
rnd2 = 10;
if (rnd2 < -10)
rnd2 = -10;
/* if (rnd3 < 10)
rnd3 = 15;*/
if (rnd3 > 55)
rnd3 = 50;
self.velocity_x = rnd1;
self.velocity_y = rnd2;
self.velocity_z = rnd3;
}
// Swimming
float hydra_Swim[20] =
{
-0.2,
-0.1,
0.0,
0.1, // Top going down
0.2,
0.3,
0.4,
0.5, // middle
0.4,
0.3,
0.2,
0.1, // bottom
0.0,
-0.1,
-0.2,
-0.3,
-0.4,
-0.5, // middle
-0.4,
-0.3
};
// Top = 1, tr = 2, br = 3, tl = 4, bl = 5
float hydra_TentAttacks[24] =
{
0,
0,
0,
0,
1,
0,
3,
0,
4,
0,
0,
5,
0,
0,
0,
2,
0,
0,
0,
4,
3,
1,
0,
0
};
// Attacking others
void hydra_AttackDieFrames(void)
{
self.think = hydra_AttackDieFrames;
thinktime self : HX_FRAME_TIME;
if (self.frame != $hadie36)
AdvanceFrame($hadie1,$hadie36);
if (self.frame == $hadie35)
{
self.solid = SOLID_NOT;
MakeSolidCorpse();
}
if (self.frame >= $hadie13)
hydra_bob();
if(self.health<-30)
chunk_death();
}
void hydra_AttackPainFrames(void)
{
self.think = hydra_AttackPainFrames;
thinktime self : HX_FRAME_TIME;
AdvanceFrame($hapan1,$hapan10);
}
// Swimming others
void hydra_SwimDieFrames(void)
{
self.think = hydra_SwimDieFrames;
thinktime self : HX_FRAME_TIME;
if (self.frame != $hsdie36)
AdvanceFrame($hsdie1,$hsdie36);
if (self.frame == $hsdie35)
{
self.solid = SOLID_NOT;
MakeSolidCorpse();
}
if (self.frame >= $hsdie8)
hydra_bob();
if(self.health<-30)
chunk_death();
}
void hydra_SwimPainFrames(void)
{
self.think = hydra_SwimPainFrames;
thinktime self : HX_FRAME_TIME;
AdvanceFrame($hspan1,$hspan10);
}
// Attacking
void hydra_OpenFrames(void)
{
self.think = hydra_OpenFrames;
thinktime self : HX_FRAME_TIME;
if (self.enemy.watertype != CONTENT_WATER)
{
self.monster_stage = HYDRA_STAGE_FLOAT;
self.think = self.th_run;
thinktime self : 0.1;
return;
}
hydra_open();
if (AdvanceFrame($hopen1,$hopen8) == AF_END)
{
hydra_attack();
}
}
void hydra_CloseFrames(void)
{
self.think = hydra_CloseFrames;
thinktime self : HX_FRAME_TIME;
if (RewindFrame($hopen8,$hopen1) == AF_END)
{
self.monster_stage -= HYDRA_STAGE_ATTACK;
self.think = self.th_save;
}
}
void hydra_SpitFrames(void)
{
vector vecA,vecB;
self.think = hydra_SpitFrames;
thinktime self : HX_FRAME_TIME;
self.angles_y = vectoyaw(self.enemy.origin - self.origin);
if (AdvanceFrame($hspit1,$hspit12) == AF_END)
{
self.think = hydra_CloseFrames;
self.monster_check = -1;
}
else if (self.frame == $hspit7 && self.monster_check == 2)
{
sound (self, CHAN_WEAPON, "hydra/spit.wav", 1, ATTN_NORM);
vecA = self.enemy.origin - self.origin + self.enemy.proj_ofs;
vecA = vectoangles(vecA);
makevectors(vecA);
v_forward_z = 0 - v_forward_z;
vecA = v_factor('-40 400 -40');
vecB = v_factor('40 500 40');
particle2(self.origin+v_forward*40,vecA,vecB,256,12,400);
self.think = hydra_checkForBlind;
thinktime self : 0.1;
}
else if (self.frame == $hspit8 && self.monster_check == 1)
{
hydra_fire();
}
}
void hydra_TentFrames(void)
{
float r;
if (!self.enemy.flags2 & FL_ALIVE)
{
self.goalentity = self.enemy = world;
self.monster_stage = HYDRA_STAGE_WAIT;
self.think = self.th_stand;
thinktime self : 0.1;
return;
}
self.think = hydra_TentFrames;
thinktime self : 0.025;
if (AdvanceFrame($htent1,$htent24) == AF_END)
{
r = range(self.enemy);
if ((r == RANGE_MELEE) && (random(0, 1) < 0.3))
{
self.frame = $htent1;
hydra_tent(hydra_TentAttacks[self.frame - $htent1]);
}
else
self.think = hydra_CloseFrames;
}
else
{
hydra_tent(hydra_TentAttacks[self.frame - $htent1]);
}
}
// Regular swimming / movement
void hydra_SwimFrames(void)
{
self.think = hydra_SwimFrames;
thinktime self : HX_FRAME_TIME;
AdvanceFrame($hswim1,$hswim20);
if (self.frame == $hswim1)
sound (self, CHAN_WEAPON, "hydra/swim.wav", 1, ATTN_NORM);
hydra_move((hydra_Swim[self.frame - $hswim1]) + 0.3);
}
/*QUAKED misc_fountain (0 1 0.8) (0 0 0) (32 32 32)
New item for QuakeEd
-------------------------FIELDS-------------------------
angles 0 0 0 the direction it should move the particles
movedir 1 1 1 the force it should move them
color 256 the color
cnt 2 the number of particles each time
--------------------------------------------------------
*/
void misc_fountain(void)
{
starteffect(CE_FOUNTAIN, self.origin, self.angles,self.movedir,self.color,self.cnt);
}
void do_hydra_spit(void)
{
self.monster_check = 1;
self.monster_stage += HYDRA_STAGE_ATTACK;
sound (self, CHAN_WEAPON, "hydra/open.wav", 1, ATTN_NORM);
hydra_OpenFrames();
}
void do_hydra_tent(void)
{
self.monster_check = 0;
self.monster_stage += HYDRA_STAGE_ATTACK;
sound (self, CHAN_WEAPON, "hydra/open.wav", 1, ATTN_NORM);
hydra_OpenFrames();
}
void do_hydra_die(void)
{
self.flags (+) FL_SWIM;
sound (self, CHAN_WEAPON, "hydra/die.wav", 1, ATTN_NORM);
if (self.monster_stage >= HYDRA_STAGE_ATTACK)
hydra_AttackDieFrames();
else
hydra_SwimDieFrames();
}
void hydra_retreat()
{
self.monster_stage = HYDRA_STAGE_REVERSE;
self.think = self.th_run;
thinktime self : 0.1;
}
void hydra_pain(entity attacker, float damage)
{
sound (self, CHAN_WEAPON, "hydra/pain.wav", 1, ATTN_NORM);
}
void init_hydra(void)
{
if (deathmatch)
{
remove(self);
return;
}
self.monster_stage = HYDRA_STAGE_WAIT;
precache_model ("models/hydra.mdl");
precache_model ("models/spit.mdl");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_SWIM;
self.thingtype=THINGTYPE_FLESH;
self.classname="monster_hydra";
self.mass = 7;
setmodel (self, "models/hydra.mdl");
self.skin = 0;
setsize (self, '-30 -30 -24', '30 30 24');
self.hull = HULL_SCORPION;
//self.hull = HULL_HYDRA;
self.health = 125;
self.experience_value = 50;
self.mintel = 4;
self.th_stand = hydra_SwimFrames;
self.th_walk = hydra_SwimFrames;
self.th_run = hydra_SwimFrames;
self.th_pain = hydra_pain;
self.th_die = do_hydra_die;
self.th_missile = do_hydra_spit;
self.th_melee = do_hydra_tent;
self.takedamage = DAMAGE_YES;
self.flags2 (+) FL_ALIVE;
self.ideal_yaw = self.angles * '0 1 0';
if (!self.yaw_speed)
self.yaw_speed = 5;
self.view_ofs = '0 0 0';
self.use = monster_use;
self.flags (+) FL_SWIM | FL_MONSTER;
self.pausetime = 99999999;
total_monsters += 1;
thinktime self : random(0.5);
self.think = self.th_stand;
}
/*QUAKED monster_hydra (1 0.3 0) (-40 -40 -42) (40 40 42) STAND HOVER JUMP PLAY_DEAD DORMANT
New item for QuakeEd
-------------------------FIELDS-------------------------
NOTE: Normal QuakEd monster spawnflags don't apply here (no_jump, play_dead, no_drop)
--------------------------------------------------------
*/
void monster_hydra(void)
{
init_hydra();
precache_sound("hydra/pain.wav");
precache_sound("hydra/die.wav");
precache_sound("hydra/open.wav");
precache_sound("hydra/turn-s.wav");
precache_sound("hydra/turn-b.wav");
precache_sound("hydra/swim.wav");
precache_sound("hydra/tent.wav");
precache_sound("hydra/spit.wav");
}

0
ice_imp.hc Normal file
View File

652
icemace.hc Normal file
View File

@ -0,0 +1,652 @@
/*
* $Header: /HexenWorld/Siege/icemace.hc 19 6/01/98 2:49a Mgummelt $
*/
/*
==============================================================================
Q:\art\models\weapons\icestaff\final\icestaff.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\weapons\icestaff\final
$origin 10 -10 10
$base BASE skin
$skin skin
$skin skin2
$flags 0
//
$frame fire1a fire1b fire1c
$frame fire2a fire2b fire2c
$frame fire3a fire3b fire3c
$frame fire4a fire4b fire4c
$frame fire5a fire5b fire5c
//
$frame idle1 idle2 idle3 idle4 idle5
$frame idle6 idle7 idle8 idle9 idle10
$frame idle11 idle12 idle13 idle14 idle15
$frame idle16
//
$frame power1 power2 power3 power4 power5
$frame power6 power7 power8 power9
//
$frame select1 select2 select3 select4 select5
$frame select6 select7 select8 select9 select10
void() IceCubeThink =
{
if(self.freeze_time<time&&skill<3)
{
self.th_die();
return;
}
if(self.colormap>144)
{
self.colormap-=1;
self.abslight-=0.05;
}
else
{
self.colormap=0;
self.abslight=0.5;
self.skin=GLOBAL_SKIN_ICE;
}
if(random()<0.2&&random()<0.2)
sound(self,CHAN_AUTO,"misc/drip.wav",1,ATTN_NORM);
self.think=IceCubeThink;
thinktime self : 0.1;
};
void (entity loser,entity forwhom) SnowJob=
{
//FIXME: Make gradual- person slows down then stops
entity oself;
if(loser.solid==SOLID_BSP)
return;
if(coop)
if(loser.classname=="player"&&forwhom.classname=="player")
return;
if(teamplay)
if(loser.team==forwhom.team)
return;
if(loser.flags&FL_MONSTER&&loser.monsterclass>=CLASS_BOSS)
{
T_Damage(loser,self,forwhom,10);
return;
}
sound(loser,CHAN_BODY,"crusader/frozen.wav",1,ATTN_NORM);
loser.frozen=50;
loser.oldskin=loser.skin;
if(loser.classname!="player")
{
loser.colormap=159;
loser.thingtype=THINGTYPE_ICE;
loser.freeze_time=time+5;
if(loser.scale==0)
loser.scale = 1;
loser.lifetime=loser.scale;
loser.o_angle=loser.mins;
loser.v_angle=loser.maxs;
loser.enemy=forwhom;
loser.oldthink=loser.think;
loser.think=IceCubeThink;
thinktime loser : 0;
loser.touch=SUB_Null;
loser.th_pain=SUB_Null;
loser.wait = time + 3;
if(loser.angles_x==0&&loser.angles_z==0)
loser.drawflags(+)SCALE_ORIGIN_BOTTOM;
loser.oldmovetype=loser.movetype;
loser.movetype=MOVETYPE_TOSS;
loser.health=1;
loser.deathtype="ice melt";
loser.th_die=shatter;
// AwardExperience(forwhom,loser,loser.experience_value);
loser.experience_value=0;
oself=self;
self=loser;
SUB_UseTargets();
self=oself;
}
else
{
loser.credit_enemy=forwhom;//give credit to freezer
loser.artifact_active(+)ARTFLAG_FROZEN;
loser.colormap=159;
loser.thingtype=THINGTYPE_ICE;
loser.o_angle=loser.v_angle;
loser.pausetime = time + 10;
loser.attack_finished = time + 10;
//Temp -turns screen blue
loser.health=1;
thinktime loser : 10;
//Prevent interruption? loser.th_pain=SUB_Null;
}
loser.flags(-)FL_FLY;
loser.flags(-)FL_SWIM;
if(loser.flags&FL_ONGROUND)
loser.last_onground=time;
loser.flags(-)FL_ONGROUND;
//need to be able to reverse this...
loser.oldtouch=loser.touch;
loser.touch=obj_push;
loser.drawflags(+)DRF_TRANSLUCENT|MLS_ABSLIGHT;
loser.abslight=1;
};
/*void FreezeDie()
{
// FIXME - get all of this stuff over
//particleexplosion(self.origin,14,10,10);
//particle2(self.origin,'-10 -10 -10','10 10 10',145,14,5);
//if(self.movechain!=world)
// remove(self.movechain);
remove(self);
}*/
void remove_artflag ()
{
if(self.enemy.frozen<=0)
{
self.enemy.artifact_active(-)self.artifact_active;
}
remove(self);
}
void() FreezeTouch=
{
float hitType;
float removeBall;
removeBall = 0;
if(other==self.owner)
return;
//starteffect(CE_ICE_HIT,self.origin-self.movedir*8);
if(other.takedamage&&other.health&&other.frozen<=0&&other.thingtype==THINGTYPE_FLESH)//FIXME: Thingtype_flesh only
{ // hit someone who MIGHT be frozen by this attack - should always be players
//sound (self, CHAN_BODY, "crusader/icehit.wav", 1, ATTN_NORM);
hitType = 0;
if(other.freeze_time<=time)
{
other.frozen=0;
}
other.freeze_time=time+2.5;
other.frozen-=1.5;
if(other.classname=="player")
{
other.artifact_active(+)ARTFLAG_FROZEN;
newmis=spawn();
newmis.enemy=other;
newmis.artifact_active=ARTFLAG_FROZEN;
newmis.think=remove_artflag;
thinktime newmis : 0.3;
}
if(other.flags&FL_COLDHEAL)//Had to take out cold heal, so cold resist
{
T_Damage(other,self,self.owner,9);
}
else if((other.health<=10||(other.classname=="player"&&other.frozen<=-7&&other.health<200))&&other.solid!=SOLID_BSP&&!other.artifact_active&ART_INVINCIBILITY&&other.thingtype==THINGTYPE_FLESH&&other.health<100)
{
SnowJob(other,self.owner);
}
else
{
T_Damage(other,self,self.owner,20);
}
removeBall = 1;
}
else if(other.frozen<=0)
{ // hit a wall, I think
//sound (self, CHAN_BODY, "crusader/icewall.wav", 1, ATTN_NORM);
hitType = 1;
T_RadiusDamage(self,self.owner,30,self.owner);
self.touch=SUB_Null;
//shatter();
//remove(self);
removeBall = 1;
}
else
{
hitType = 1;
//sound(self,CHAN_BODY,"misc/tink.wav",1,ATTN_NORM);
}
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_ICEHIT);
WriteCoord (MSG_MULTICAST, self.origin_x - self.movedir_x * 8);
WriteCoord (MSG_MULTICAST, self.origin_y - self.movedir_y * 8);
WriteCoord (MSG_MULTICAST, self.origin_z - self.movedir_z * 8);
WriteByte (MSG_MULTICAST, hitType);
multicast(self.origin,MULTICAST_PVS);
if(removeBall)
{
remove(self);
}
};
void iceballThink(void)
{
self.movedir = normalize(self.velocity);
self.angles = vectoangles(self.movedir);
traceline(self.origin, self.origin + self.movedir * 360.0, FALSE, self);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_ICESHOT);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
WriteByte (MSG_MULTICAST, self.angles_y*256.0/360.0);
WriteByte (MSG_MULTICAST, self.angles_x*256.0/360.0);
WriteByte (MSG_MULTICAST, trace_fraction * 100);
multicast(self.origin,MULTICAST_PVS);
thinktime self : 0.3;
if (self.lifetime < time)
SUB_Remove();
}
void()FireFreeze=
{
//vector dir;
self.bluemana-=3;
self.attack_finished=time + 0.2;
self.punchangle_x= -1;
makevectors (self.v_angle);
//sound (self, CHAN_WEAPON, "crusader/icefire.wav", 1, ATTN_NORM);
weapon_sound(self, "crusader/icefire.wav");
newmis = spawn ();
newmis.owner = self;
newmis.movetype = MOVETYPE_BOUNCEMISSILE;
newmis.solid = SOLID_BBOX;
newmis.th_die=shatter;
newmis.deathtype="ice shatter";
newmis.touch = FreezeTouch;
newmis.classname = "snowball";
newmis.speed = 1200;
newmis.movedir=normalize(v_forward);
newmis.angles = vectoangles(self.movedir);
newmis.velocity = newmis.movedir * newmis.speed;
newmis.scale = newmis.scale * 1.5;
newmis.lifetime = time + 4;
setmodel (newmis, "models/iceshot1.mdl");
setsize (newmis, '0 0 0', '0 0 0');
setorigin (newmis, self.origin+self.proj_ofs + v_forward*8);
//newmis.effects(+)EF_ICEBALL_EFFECT;
newmis.effects(+)EF_NODRAW;
entity oldself;
oldself = self;
self = newmis;
newmis.think = iceballThink;
newmis.think();
self = oldself;
};
void() blizzard_think=
{
entity loser;
vector dir, top;
if(self.lifetime<time)
{
remove(self);
return;
}
self.color=random(15);
self.color=rint(self.color)+9*16+256;
dir_x=random(-100,100);
dir_y=random(-100,100);
top = '0 0 128';
top_x=top_y=self.level+1;
if(self.level<128)
self.level+=8;
makevectors(self.angles);
self.flags(-)FL_ONGROUND;
loser=findradius(self.origin,self.level);
while(loser)
{
if(loser.takedamage&&loser.health&&loser.frozen<=0&&loser!=self.owner&&loser.solid!=SOLID_BSP)
if(loser.flags&FL_COLDHEAL)
T_Damage(loser,self,self.owner,1);
else
{
loser.frozen-=1.2;
if((loser.frozen<-7||loser.health<15)&&loser.classname!="mjolnir"&&!loser.artifact_active&ART_INVINCIBILITY&&loser.thingtype==THINGTYPE_FLESH&&loser.health<100)
{
SnowJob(loser,self.owner);
}
else
{
T_Damage(loser,self,self.owner,12);
}
}
loser=loser.chain;
}
thinktime self : 0.1;
};
void() make_blizzard =
{
//FIXME: check all sides to make correct size,
//so won't go through walls. Use tracelines and
//use this info to set origin, size, and radius
//length.
//local vector sizeright,sizeleft,sizefront,sizeback,sizebottom,sizetop;
//Note: Limit to 2 per player. If 3rd made, erase first.
//Sound
entity found;
entity newShot;
float curShot = 0;
makevectors(self.angles);
if(other.frozen<=-2&&!other.artifact_active&ART_INVINCIBILITY&&other.thingtype==THINGTYPE_FLESH&&other.health<100)
{
if(other.frozen <= -2)
{
SnowJob(other,self.owner);
}
else
{
other.frozen -= 4;
}
}
found=findradius(self.origin,256);
while(found)
{
if(found.flags&FL_CLIENT&&found!=self.owner)
{
found.artifact_active(+)ARTFLAG_DIVINE_INTERVENTION;
found.divine_time = time + HX_FRAME_TIME;
}
found=found.chain;
}
while(curShot < 2)
{
newShot = spawn();
newShot.origin = self.origin;
newShot.touch=SUB_Null;
if(curShot == 0)
{
newShot.velocity = normalize(v_right)*180;
}
else
{
newShot.velocity = normalize(v_right)*-180;
}
newShot.movetype = MOVETYPE_FLY;
newShot.solid = SOLID_NOT;
newShot.classname="blizzard";
newShot.angles_y=other.angles_y;
newShot.effects (+) EF_ICESTORM_EFFECT;
newShot.lifetime=time + 3;
newShot.think=blizzard_think;
thinktime newShot : 0;
newShot.owner = self.owner;
setmodel(newShot,"models/null.spr");
setsize(newShot,'-48 -48 -32','48 48 32');
newShot.hull=HULL_GOLEM;
if(other.takedamage)
{
setorigin(newShot,(other.absmax+other.absmin)*0.5);
}
newShot.drawflags(+)SCALE_ORIGIN_CENTER;//DRF_TRANSLUCENT
curShot += 1;
}
remove(self);
};
void()sparkle=
{
// particle(self.origin,'0 0 0',random(-255,255),random(3,10));
// particleexplosion(self.origin,152+random(7),10,10);
particle2(self.origin,'-3 -3 -3','3 3 3',144+random(15),2,20);
particle2(self.origin,'-1 -1 -1','1 1 1',24+random(7),3,10);
self.think = sparkle;
thinktime self : 0.01;
};
void FireBlizzard (void)
{
self.attack_finished=time + 1.2;
self.bluemana-=10;
//sound (self, CHAN_WEAPON, "crusader/blizfire.wav", 1, ATTN_NORM);
weapon_sound(self, "crusader/blizfire.wav");
newmis=spawn();
newmis.owner=self;
self.blizzcount+=1;
newmis.blizzcount=self.blizzcount;
//newmis.movetype=MOVETYPE_FLYMISSILE;
newmis.movetype = MOVETYPE_TOSS;
newmis.solid=SOLID_BBOX;
newmis.touch=make_blizzard;
newmis.velocity=normalize(v_forward)*1000;
newmis.velocity=newmis.velocity + v_up*100;
newmis.movedir = normalize(newmis.velocity);
newmis.angles = vectoangles(newmis.movedir);
newmis.effects=EF_MUZZLEFLASH;
newmis.drawflags(+)SCALE_ORIGIN_CENTER;//DRF_TRANSLUCENT
setmodel(newmis,"models/ball.mdl");
setsize(newmis,'0 0 0','0 0 0');
setorigin(newmis,self.origin+self.proj_ofs+v_forward*16);
newmis.scale = .1;
}
/*======================
ACTION
select
deselect
ready loop
relax loop
fire once
fire loop
ready to relax(after short delay)
relax to ready(Fire delay? or automatic if see someone?)
=======================*/
void() Cru_Ice_Fire;
void icestaff_idle (void)
{
self.th_weapon=icestaff_idle;
self.wfs = advanceweaponframe($idle1,$idle16);
}
void icestaff_select (void)
{
self.th_weapon=icestaff_select;
self.wfs = advanceweaponframe($select1,$select10);
self.weaponmodel = "models/icestaff.mdl";
if (self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
icestaff_idle();
}
}
void icestaff_deselect (void)
{
self.wfs = advanceweaponframe($select10,$select1);
self.th_weapon=icestaff_deselect;
if (self.wfs == WF_LAST_FRAME)
W_SetCurrentAmmo();
}
void()icestaff_shard;
void icestaff_blizzard (void)
{
self.th_weapon=icestaff_blizzard;
self.wfs = advanceweaponframe($power1 , $power9);
if(self.wfs==WF_CYCLE_WRAPPED)
icestaff_idle();
else if(self.weaponframe==$power1)
if(self.artifact_active&ART_TOMEOFPOWER)
FireBlizzard();
else
icestaff_shard();
}
void icestaff_f1 (void)
{
self.th_weapon=icestaff_f1;
self.wfs = advanceweaponframe($fire1a,$fire1c);
if (self.wfs==WF_CYCLE_WRAPPED)
if(!self.button0)
icestaff_idle();
else
icestaff_shard();
else if (self.attack_finished<=time&&self.weaponframe==$fire1a)
if(self.artifact_active&ART_TOMEOFPOWER&&self.bluemana>=10)
icestaff_blizzard();
else if(!self.artifact_active&ART_TOMEOFPOWER&&self.bluemana>=1)
FireFreeze();
else
icestaff_idle();
}
void icestaff_f2 (void)
{
self.th_weapon=icestaff_f2;
self.wfs = advanceweaponframe($fire2a,$fire2c);
if (self.wfs==WF_CYCLE_WRAPPED)
if(!self.button0)
icestaff_idle();
else
icestaff_shard();
else if (self.attack_finished<=time&&self.weaponframe==$fire2a)
if(self.artifact_active&ART_TOMEOFPOWER&&self.bluemana>=10)
icestaff_blizzard();
else if(!self.artifact_active&ART_TOMEOFPOWER&&self.bluemana>=1)
FireFreeze();
else
icestaff_idle();
}
void icestaff_f3 (void)
{
self.th_weapon=icestaff_f3;
self.wfs = advanceweaponframe($fire3a,$fire3c);
if (self.wfs==WF_CYCLE_WRAPPED)
if(!self.button0)
icestaff_idle();
else
icestaff_shard();
else if (self.attack_finished<=time&&self.weaponframe==$fire3a)
if(self.artifact_active&ART_TOMEOFPOWER&&self.bluemana>=10)
icestaff_blizzard();
else if(!self.artifact_active&ART_TOMEOFPOWER&&self.bluemana>=1)
FireFreeze();
else
icestaff_idle();
}
void icestaff_f4 (void)
{
self.th_weapon=icestaff_f4;
self.wfs = advanceweaponframe($fire4a,$fire4c);
if (self.wfs==WF_CYCLE_WRAPPED)
if(!self.button0)
icestaff_idle();
else
icestaff_shard();
else if (self.attack_finished<=time&&self.weaponframe==$fire4a)
if(self.artifact_active&ART_TOMEOFPOWER&&self.bluemana>=10)
icestaff_blizzard();
else if(!self.artifact_active&ART_TOMEOFPOWER&&self.bluemana>=1)
FireFreeze();
else
icestaff_idle();
}
void icestaff_f5 (void)
{
self.th_weapon=icestaff_f5;
self.wfs = advanceweaponframe($fire5a,$fire5c);
if (self.wfs==WF_CYCLE_WRAPPED)
if(!self.button0)
icestaff_idle();
else
icestaff_shard();
else if (self.attack_finished<=time&&self.weaponframe==$fire5a)
if(self.artifact_active&ART_TOMEOFPOWER&&self.bluemana>=10)
icestaff_blizzard();
else if(!self.artifact_active&ART_TOMEOFPOWER&&self.bluemana>=1)
FireFreeze();
else
icestaff_idle();
}
void icestaff_shard (void)
{
float r;
r=rint(random(4)) + 1;
if(r==1)
icestaff_f1();
else if(r==2)
icestaff_f2();
else if(r==3)
icestaff_f3();
else if(r==4)
icestaff_f4();
else
icestaff_f5();
}
void Cru_Ice_Fire (void)
{
if(self.artifact_active&ART_TOMEOFPOWER)
icestaff_blizzard();
else
icestaff_shard();
}

234
iceshot.hc Normal file
View File

@ -0,0 +1,234 @@
void() rain_use;
void() IceCubeThink =
{
if((self.maxs_z-self.mins_z)>5)
if(pointcontents(self.origin-'0 0 23')==CONTENT_LAVA||self.frozen<=0)
{
if((self.maxs_z-self.mins_z)<25)
self.small=TRUE;
self.frozen=FALSE;
self.think=self.oldthink;
self.nextthink=time;
self.skin=self.oldskin;
self.touch=self.oldtouch;
self.movetype=self.oldmovetype;
self.drawflags-=DRF_TRANSLUCENT;
return;
}
if(pointcontents(self.origin)==CONTENT_WATER||pointcontents(self.origin)==CONTENT_SLIME)
{
self.frozen=self.frozen - 1;
self.scale -= 0.01;
}
if((!self.flags&FL_ONGROUND)&&pointcontents(self.origin+'0 0 -24')!=CONTENT_SOLID)
self.frags=TRUE;
if (self.frags&&(self.flags&FL_ONGROUND))
T_Damage(self,world,self.enemy,self.frags*10);
self.frozen=self.frozen - 0.2;
if(self.wait<=time)
{
self.scale -= 0.007;
self.mins = self.o_angle * (self.scale/self.lifetime);
self.maxs = self.v_angle * (self.scale/self.lifetime);
setsize(self,self.mins,self.maxs);
droptofloor();
}
if((self.maxs_z-self.mins_z)<=5||self.scale<=0.07)
{
// AwardExperience(self.enemy,self,0);
remove(self);
}
self.think=IceCubeThink;
self.nextthink=time+0.1;
};
void (entity loser,entity forwhom) SnowJob=
{
sound(loser,CHAN_AUTO,"weapons/frozen.wav",1,ATTN_NORM);
loser.frozen=50;
loser.oldskin=loser.skin;
loser.skin=105;
if(loser.classname!="player")
{
if(loser.scale==0)
loser.scale = 1;
loser.lifetime=loser.scale;
loser.o_angle=loser.mins;
loser.v_angle=loser.maxs;
loser.enemy=forwhom;
loser.oldthink=loser.think;
loser.think=IceCubeThink;
loser.nextthink=time;
// loser.nextthink=time+30;
loser.touch=SUB_Null;
//Prevent interruption? loser.th_pain=SUB_Null;
loser.wait = time + 10;
if(loser.angles_x==0&&loser.angles_z==0)
loser.drawflags+=SCALE_ORIGIN_BOTTOM;
loser.oldmovetype=loser.movetype;
loser.movetype=MOVETYPE_PUSHPULL;
loser.health=1;
}
else
{
loser.o_angle=loser.v_angle;
loser.pausetime = time + 20;
loser.attack_finished = time + 20;
//Temp -turns screen blue
loser.items+= IT_QUAD;
loser.health=1;
loser.nextthink=time + 20;
//Prevent interruption? loser.th_pain=SUB_Null;
}
if(loser.flags&FL_FLY)
loser.flags = loser.flags - FL_FLY;
if (loser.flags & FL_SWIM)
loser.flags = loser.flags - FL_SWIM;
if(loser.flags&FL_ONGROUND)
loser.flags = loser.flags - FL_ONGROUND;
//need to be able to reverse this...
loser.oldtouch=loser.touch;
loser.touch=obj_push;
loser.drawflags+=DRF_TRANSLUCENT;
};
void() FreezeTouch=
{
if(other.takedamage&&other.health&&(!other.frozen)&&(!other.flags&FL_COLDRESIST)&&(!other.flags&FL_COLDHEAL))
{
if((!other.frozen)&&other.health>12)
T_Damage(other,self,self.owner,10);
if(random()<0.2)
SnowJob(other,self.owner);
}
else if(other.flags&FL_COLDHEAL)
other.health=other.health+5;
else
T_RadiusDamage(self,self.owner,30,self.owner);
self.touch=SUB_Null;
self.deathtype="ice shatter";
shatter();
};
void()FreezeThink=
{
if((pointcontents(self.origin)==CONTENT_WATER&&random()<0.3)||pointcontents(self.origin)==CONTENT_LAVA||(pointcontents(self.origin)==CONTENT_SLIME&&random()<0.5)||self.wait<time)
{
if(pointcontents(self.origin)==CONTENT_LAVA)
sound (self, CHAN_WEAPON, "player/slimbrn2.wav", 1, ATTN_NORM);
remove(self);
}
self.think=FreezeThink;
self.nextthink=time + 0.5;
};
void()FireFreeze=
{
local vector dir;
makevectors (self.v_angle);
dir = normalize(v_forward);
sound (self, CHAN_WEAPON, "hknight/hit.wav", 1, ATTN_NORM);
newmis = spawn ();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_BBOX;
newmis.angles = vectoangles(dir);
newmis.touch = FreezeTouch;
newmis.classname = "snowball";
newmis.think = SUB_Remove;
newmis.nextthink = time + 6;
newmis.speed = 1200;
setmodel (newmis, "models/iceshot.mdl");
newmis.avelocity='-200 200 -200';
newmis.think=FreezeThink;
newmis.nextthink=time + 0.5;
newmis.wait=time + 3;
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
setorigin (newmis, self.origin + v_forward*8+'0 0 16');
newmis.velocity = dir * newmis.speed;
};
void() blizzard_think=
{
local entity loser;
if(self.lifetime<time)
remove(self);
rain_go(self.mins,self.maxs,self.size,self.color,self.counter);
if(self.pain_finished<time)
{
sound(self,CHAN_WEAPON,"test/blizzard.wav",1,ATTN_NORM);
self.pain_finished=time + 0.7;
}
loser=findradius(self.origin,128);
while(loser)
{
if(loser.takedamage&&loser.health&&!loser.frozen&&(!loser.flags&FL_COLDRESIST))
if(loser.flags&FL_COLDHEAL)
loser.health+=3;
else
{
T_Damage(loser,self,self.owner,5);
if(random()<0.2)
SnowJob(loser,self.owner);
}
loser=loser.chain;
}
self.nextthink = time + 0.1;
};
void() make_blizzard =
{
local entity blizzard;
blizzard=spawn();
blizzard.movetype = MOVETYPE_NOCLIP;
blizzard.solid = SOLID_NOT;
blizzard.classname="blizzard";
blizzard.owner = self.owner;
blizzard.modelindex = 0;
blizzard.color=150;
blizzard.lifetime=time + 30;
blizzard.think=blizzard_think;
blizzard.nextthink = time;
blizzard.counter=500;
setmodel (blizzard, "progs/null.spr");
setsize (blizzard, '-64 -64 -36', '64 64 128');
setorigin (blizzard, self.origin);
shatter();
};
void()sparkle=
{
particle(self.origin,'0 0 0',crandom()*255,random()*7+3);
self.think = sparkle;
self.nextthink = time+0.01;
};
void FireBlizzard (void)
{
self.attack_finished=time + 1;
newmis=spawn();
newmis.owner=self;
newmis.movetype=MOVETYPE_FLYMISSILE;
newmis.solid=SOLID_BBOX;
newmis.touch=make_blizzard;
newmis.velocity=normalize(v_forward)*1000;
newmis.effects=EF_MUZZLEFLASH;
newmis.think=sparkle;
newmis.nextthink=time;
setmodel(newmis,"progs/null.spr");
setsize(newmis,'0 0 0','0 0 0');
setorigin(newmis,self.origin+v_forward*16+'0 0 16');
}

591
idmodels.hc Normal file
View File

@ -0,0 +1,591 @@
/*
* $Header: /HexenWorld/Siege/idmodels.hc 3 5/25/98 1:38p Mgummelt $
*/
/* Old Id models */
/*
===============================================================================
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

1672
imp.hc Normal file

File diff suppressed because it is too large Load Diff

648
impulse.hc Normal file
View File

@ -0,0 +1,648 @@
/*
* $Header: /HexenWorld/Siege/impulse.hc 29 6/01/98 2:49a Mgummelt $
*/
void PlayerAdvanceLevel(float NewLevel);
void player_level_cheat(void);
void player_experience_cheat(void);
void Polymorph (entity loser);
//void create_swarm (void);
void restore_weapon ()
{//FIXME: use idle, not select
self.weaponframe = 0;
if (self.playerclass==CLASS_PALADIN)
{
if (self.weapon == IT_WEAPON1)
if(self.flags2&FL2_EXCALIBUR)
self.weaponmodel = "models/v_excal.mdl";
else
self.weaponmodel = "models/vorpal.mdl";
else if (self.weapon == IT_WEAPON2)
self.weaponmodel = "models/axe.mdl";
else if (self.weapon == IT_WEAPON3)
self.weaponmodel = "models/xbow2.mdl";
}
else if (self.playerclass==CLASS_CRUSADER)
{
if (self.weapon == IT_WEAPON1)
self.weaponmodel = "models/warhamer.mdl";
else
self.weaponmodel = "models/icestaff.mdl";
}
else if (self.playerclass==CLASS_NECROMANCER)
{
if (self.weapon == IT_WEAPON1)
self.weaponmodel = "models/sickle.mdl";
else if (self.weapon == IT_WEAPON2)
self.weaponmodel = "models/xbow2.mdl";
else
self.weaponmodel = "models/spllbook.mdl"; // FIXME: still need these models
}
else if (self.playerclass==CLASS_ASSASSIN)
{
if (self.weapon == IT_WEAPON1)
self.weaponmodel = "models/punchdgr.mdl";
else if (self.weapon == IT_WEAPON2)
self.weaponmodel = "models/xbow2.mdl";
else if (self.weapon == IT_WEAPON3)
self.weaponmodel = "models/crossbow.mdl";
else if (self.weapon == IT_WEAPON4)
self.weaponmodel = "models/v_assgr.mdl";
}
else if (self.playerclass==CLASS_SUCCUBUS)
{
if (self.weapon == IT_WEAPON1)
self.weaponmodel = "models/sucwp1.mdl";
else if (self.weapon == IT_WEAPON2)
self.weaponmodel = "models/vorpal.mdl";
else if (self.weapon == IT_WEAPON3)
self.weaponmodel = "models/xbow2.mdl";
else if (self.weapon == IT_WEAPON4)
self.weaponmodel = "models/v_assgr.mdl";
}
else if (self.playerclass==CLASS_DWARF)
{
if (self.weapon == IT_WEAPON1)
self.weaponmodel = "models/warhamer.mdl";
else if (self.weapon == IT_WEAPON2)
self.weaponmodel = "models/axe.mdl";
}
}
void see_coop_view ()
{
entity startent,found;
float gotone;
if(self.viewentity!=self)
centerprint(self,"Ally vision not available in chase camera mode\n");
if(!coop&&!teamplay)
{
centerprint(self,"Ally vision not available\n");
return;
}
if(self.cameramode==world)
startent=self;
else
startent=self.cameramode;
found=startent;
while(!gotone)
{
found=find(found,classname,"player");
if(found.flags&FL_CLIENT)
if((deathmatch&&teamplay&&found.team==self.team)||coop)
if(found.cameramode==world||found==self)
gotone=TRUE;
if(found==startent)
{
centerprint(self,"No allies available\n");
return;
}
}
if(found==self)
{
CameraReturn();
return;
}
centerprint(self,found.netname);
AllyVision(self,found);
self.weaponmodel=self.cameramode.weaponmodel;
self.weaponframe=self.cameramode.weaponframe;
}
void player_everything_cheat(float override)
{
if((deathmatch||coop)&&!override)
return;
CheatCommand(override); // Give them weapons and mana
// Artifact_Cheat(); // Give them all artifacts
self.puzzles_cheat = 1; // Get them past puzzles
// Then they leave home and never call you. The ingrates.
}
void PrintFrags()
{
entity lastent;
lastent=nextent(world);
while(lastent)
{
if(lastent.classname=="player")
{
bprint(PRINT_MEDIUM, lastent.netname);
bprint(PRINT_MEDIUM, " (L-");
bprint(PRINT_MEDIUM, ftos(lastent.level));
if(lastent.playerclass==CLASS_ASSASSIN)
bprint(PRINT_MEDIUM, " Assassin) ");
else if(lastent.playerclass==CLASS_PALADIN)
bprint(PRINT_MEDIUM, " Paladin) ");
else if(lastent.playerclass==CLASS_CRUSADER)
bprint(PRINT_MEDIUM, " Crusader) ");
else
bprint(PRINT_MEDIUM, " Necromancer) ");
bprint(PRINT_MEDIUM, " FRAGS: ");
bprint(PRINT_MEDIUM, ftos(lastent.frags));
bprint(PRINT_MEDIUM, " (LF: ");
bprint(PRINT_MEDIUM, ftos(lastent.level_frags));
bprint(PRINT_MEDIUM, ")\n");
}
lastent=find(lastent,classname,"player");
}
}
/*void()gravityup =
{
self.gravity+=0.01;
if(self.gravity==10)
self.gravity=0;
dprint(PRINT_MEDIUM, "Gravity: ");
dprint(PRINT_MEDIUM, ftos(self.gravity));
dprint(PRINT_MEDIUM, "\n");
};
void()gravitydown =
{
self.gravity-=0.01;
if(self.gravity==-10)
self.gravity=0;
dprint(PRINT_MEDIUM, "Gravity: ");
dprint(PRINT_MEDIUM, ftos(self.gravity));
dprint("\n");
};
*/
void player_stopfly(void)
{
self.movetype = MOVETYPE_WALK;
self.idealpitch = cvar("sv_walkpitch");
self.idealroll = 0;
}
void player_fly(void)
{
self.movetype = MOVETYPE_FLY;
self.velocity_z = 100; // A little push up
self.hoverz = .4;
}
void HeaveHo (void)
{
vector dir;
float inertia, lift;
if(!self.flags&FL_ONGROUND)
return;
makevectors(self.v_angle);
dir=normalize(v_forward);
traceline(self.origin+self.proj_ofs,self.origin+self.proj_ofs+dir*48,FALSE,self);
if (!trace_ent.flags&FL_ONGROUND)
return;
/*oops, now using a catapult will push it
if(trace_ent.classname=="catapult")
{
if(trace_ent.frame==20||trace_ent.frame>22)
{
trace_ent.think=catapult_fire;
thinktime trace_ent : 0;
}
return;
}
*/
if(trace_ent.movetype&&trace_ent.solid&&trace_ent!=world&&trace_ent.solid!=SOLID_BSP)//&&trace_ent.flags&FL_ONGROUND
{
if(!trace_ent.mass)
inertia = 1;
else if(trace_ent.mass<=50)
inertia=trace_ent.mass/10;
else
inertia=trace_ent.mass/100;
lift=(self.strength/30+0.5)*300/inertia;//was /40
if(lift>300)
lift=300;//don't throw it over your head
if(trace_ent.velocity_z<lift)
{
trace_ent.velocity_z+=lift;
if(trace_ent.velocity_z>lift)
trace_ent.velocity_z=lift;
}
else
return;
trace_ent.flags(-)FL_ONGROUND;
if(self.playerclass==CLASS_ASSASSIN||self.playerclass==CLASS_SUCCUBUS)
sound (self, CHAN_BODY,"player/assjmp.wav", 1, ATTN_NORM);
else
sound (self, CHAN_BODY,"player/paljmp.wav", 1, ATTN_NORM);
self.attack_finished=time+1;
}
}
void AddServerFlag(float addflag)
{
addflag=byte_me(addflag+8);
dprintf("Serverflags were: %s\n",serverflags);
dprintf("Added flag %s\n",addflag);
serverflags(+)addflag;
dprintf("Serverflags are now: %s\n",serverflags);
}
float CanClimb()
{
vector org;
makevectors(self.v_angle);
org = self.origin+self.proj_ofs;
traceline(org,org+v_forward*48,FALSE,self);
if(trace_fraction<1&&trace_ent.solid==SOLID_BSP)
return TRUE;
return FALSE;
}
void makeplayer ()
{
newmis=spawn();
setmodel(newmis,self.model);
setorigin(newmis,self.origin);
newmis.frame = self.frame;
newmis.angles=self.angles;
newmis.think=SUB_Remove;
newmis.skin=self.skin;
thinktime newmis : 10;
}
/*
============
ImpulseCommands
============
*/
void() ImpulseCommands =
{
entity search;
float total;
// string s2;
if(!self.impulse)
return;
/*
if(self.netname=="CHEATER")
switch(self.cnt)
{
case 0:
if(self.impulse == 3)
self.cnt+=1;
else
self.cnt=0;
break;
case 1:
if(self.impulse == 7)
self.cnt+=1;
else
self.cnt=0;
break;
case 2:
if(self.impulse == 1)
self.cnt+=1;
else
self.cnt=0;
break;
case 3:
if(self.impulse == 7)
self.cnt=0;
player_everything_cheat(TRUE);
break;
}*/
//Have to allow panic button and QuickInventory impulses to work as well as impulse 23
// if(self.flags2&FL_CHAINED&&self.impulse!=23)
// return;
/* else if (self.impulse == 56)
{//time left
string printnum;
float p1,p2,p3;
p1=cvar("timelimit")*60 - time;//find # of seconds left
p3=floor(p1/60);//find # of minutes
p2=(p1 - p3*60)/100;//leftover seconds, shift to right of decimal
p3+=p2;
printnum=ftos(p3);
sprint(self,PRINT_HIGH,printnum);
sprint(self,PRINT_HIGH,"\n");
// centerprint(self,printnum);
}*/
// else if (self.impulse == 99)
// ClientKill();
// else if (self.impulse == 98)
// makeplayer();
// else if (self.impulse ==149)
// dprintf("Serverflags are now: %s\n",serverflags);
if (self.impulse == 23&&!self.climbing) // To use inventory item
UseInventoryItem ();
// else if(self.impulse==33)
// see_coop_view();
else if(self.impulse==32)
PanicButton();
else if (self.impulse==34)
{
if(self.puzzle_inv1!="")
{
self.puzzle_id=self.puzzle_inv1;
DropPuzzlePiece();
self.puzzle_inv1=self.puzzle_id="";
}
else
centerprint(self,"You don't have the key!\n");
}
else if(self.impulse==35&&skill<3)
{
search = nextent(world);
total = 0;
while(search != world)
{
if (search.flags & FL_MONSTER)
{
total += 1;
remove(search);
}
search = nextent(search);
}
dprintf("Removed %s monsters\n",total);
}
else if (self.impulse==36&&skill<3)
{
search = nextent(world);
total = 0;
while(search != world)
{
if (search.flags & FL_MONSTER)
{
total += 1;
thinktime search : 99999;
}
search = nextent(search);
}
dprintf("Froze %s monsters\n",total);
}
else if (self.impulse==37&&skill<3)
{
search = nextent(world);
total = 0;
while(search != world)
{
if (search.flags & FL_MONSTER)
{
total += 1;
thinktime search : HX_FRAME_TIME;
}
search = nextent(search);
}
dprintf("UnFroze %s monsters\n",total);
}
else if(self.impulse==25)
{
if(deathmatch||coop)
{
self.impulse=0;
return;
}
else
{
self.cnt_tome += 1;
Use_TomeofPower();
}
}
else if(self.impulse==39&&skill<3)
{
if(deathmatch||coop)
{
self.impulse=0;
return;
}
else // Toggle flight
{
if (self.movetype != MOVETYPE_FLY)
player_fly();
else
player_stopfly();
}
}
else if (self.impulse == 42)
{
dprintv("Coordinates: %s\n", self.origin);
dprintv("Angles: %s\n",self.angles);
dprint("Map is ");
dprint(mapname);
dprint("\n");
}
else if(self.impulse==44)
DropInventoryItem();
else if (self.impulse >= 100 && self.impulse <= 115)
{
Inventory_Quick(self.impulse - 99);
}
else if(self.impulse == 201)
{
if(self.siege_team)
{
if(self.siege_team==ST_DEFENDER)
centerprint(self,"You are already a defender!\n");
else
centerprint(self,"Can't - you are an attacker!\n");
}
else
{
self.siege_team=ST_DEFENDER;
setsiegeteam(self,ST_DEFENDER);//update C and clients
}
}
else if (self.impulse == 202)
{
if(self.siege_team)
{
if(self.siege_team==ST_DEFENDER)
centerprint(self,"Can't - you are a defender!\n");
else
centerprint(self,"You are already an attacker!\n");
}
else
{
self.siege_team=ST_ATTACKER;
setsiegeteam(self,ST_ATTACKER);//update C and clients
}
}
else if (self.impulse == 203)
{
if(self.siege_team)
{
if(self.siege_team==ST_DEFENDER)
centerprint(self,"You are a defender!\n");
else
centerprint(self,"You are an attacker!\n");
}
else
centerprint(self,"No team!!!\n");
}
// else if (self.impulse == 255)
// PrintFrags();
if(self.model=="models/sheep.mdl")
{
self.impulse=0;
return;
}
else if (self.impulse >= 1 && self.impulse <= 8)
W_ChangeWeapon ();
// else if ((self.impulse == 10) && (wp_deselect == 0))
// CycleWeaponCommand ();
else if (self.impulse == 11)
ServerflagsCommand ();
// else if (self.impulse == 12)
// CycleWeaponReverseCommand ();
else if(self.impulse == 13)
{
if(self.playerclass==CLASS_ASSASSIN&&self.flags2&FL2_WALLCLIMB)
{
if(self.climbing==FALSE)
{
if(CanClimb())
{
if(self.last_climb+1<time)
Climb();
self.impulse = 0;
return;
}
}
else
{
ClimbDrop();
self.impulse = 0;
return;
}
}
HeaveHo();
}
else if (self.impulse == 14)
{
if (self.last_use_time < time - 10)//can only sheepify self after 10 secs of inactivity
{
Polymorph(self);
self.last_use_time = time;
}
}
else if (self.impulse == 22 &&!self.flags2 & FL2_CROUCHED) // To crouch
{
if(self.flags2 & FL2_CROUCH_TOGGLE)
self.flags2(-)FL2_CROUCH_TOGGLE;
else
self.flags2(+)FL2_CROUCH_TOGGLE;
// PlayerCrouch();
}
/* else if (self.impulse>170&&self.impulse<177&&cvar("registered")&&self.last_use_time < time - 10)
{
if(randomclass)
{
centerprint(self,"Cannot switch classes with randomclass active...\n");
self.impulse=0;
return;
}
if(self.level<3)
{
centerprint(self,"You must have achieved level 3 or higher to change class!\n");
self.impulse=0;
return;
}
if(self.impulse==171)//Quick Class-change hot-keys
if(self.playerclass==CLASS_PALADIN)
{
self.impulse=0;
return;
}
else
self.newclass=CLASS_PALADIN;
else if(self.impulse==172)
if(self.playerclass==CLASS_CRUSADER)
{
self.impulse=0;
return;
}
else
self.newclass=CLASS_CRUSADER;
else if(self.impulse==173)
if(self.playerclass==CLASS_NECROMANCER)
{
self.impulse=0;
return;
}
else
self.newclass=CLASS_NECROMANCER;
else if(self.impulse==174)
if(self.playerclass==CLASS_ASSASSIN)
{
self.impulse=0;
return;
}
else
self.newclass=CLASS_ASSASSIN;
else if(self.impulse==175)
if(self.playerclass==CLASS_SUCCUBUS)
{
self.impulse=0;
return;
}
else
self.newclass=CLASS_SUCCUBUS;
if(self.impulse==176)
if(self.playerclass==CLASS_DWARF)
{
self.impulse=0;
return;
}
else
self.newclass=CLASS_DWARF;
self.last_use_time = time;
self.effects=self.drawflags=FALSE;
remove_invincibility(self);
self.playerclass=self.newclass;//So it drops exp the right amount
drop_level(self,2);
newmis=spawn();
newmis.classname="classchangespot";
newmis.angles=self.angles;
setorigin(newmis,self.origin);
//what's this - it's code for single play which we don't need anymore
// if(!deathmatch&&!coop)
// parm7=self.newclass;//Just to tell respawn() not to use restart
// elsez----------++++++++++++++++++++++++++++++++
// {
self.model=self.init_model;
GibPlayer('0 0 1');
self.frags -= 2; // extra penalty
// }
respawn ();
}
*/
self.impulse = 0;
};

1408
invntory.hc Normal file

File diff suppressed because it is too large Load Diff

2541
items.hc Normal file

File diff suppressed because it is too large Load Diff

131
javelin.hc Normal file
View File

@ -0,0 +1,131 @@
/*
* $Header: /HexenWorld/Siege/javelin.hc 3 5/25/98 1:39p Mgummelt $
*/
/*
==============================================================================
GAUNTLET
==============================================================================
*/
$cd q:/art/models/weapons/javelin/final
$origin 0 5 10
//$rotatehtr 90 180 0
$base base skin
$skin skin
$frame jav000 jav001 jav002 jav003 jav004
$frame jav005 jav006 jav007 jav008 jav009
$frame jav010 jav011 jav012 jav013 jav014
$frame jav015 jav016 jav017 jav018
$frame jav019 jav020
void() W_FireJavelin;
void() T_MissileTouch;
//============================================================================
void() throwjav0 =[ $jav000, throwjav1 ] {self.weaponframe=0;};
void() throwjav1 =[ $jav001, throwjav2 ] {self.weaponframe=1;};
void() throwjav2 =[ $jav002, throwjav3 ] {self.weaponframe=2;};
void() throwjav3 =[ $jav003, throwjav4 ] {self.weaponframe=3;};
void() throwjav4 =[ $jav004, throwjav5 ] {self.weaponframe=4;};
void() throwjav5 =[ $jav005, throwjav6 ] {self.weaponframe=5;};
void() throwjav6 =[ $jav006, throwjav7 ] {self.weaponframe=6;};
void() throwjav7 =[ $jav007, throwjav8 ] {self.weaponframe=7;};
void() throwjav8 =[ $jav008, throwjav9 ] {self.weaponframe=8;};
void() throwjav9 =[ $jav009, throwjav10 ] {self.weaponframe=9;W_FireJavelin();};
void() throwjav10 =[ $jav010, throwjav11 ] {self.weaponframe=10;};
void() throwjav11 =[ $jav011, throwjav12 ] {self.weaponframe=11;};
void() throwjav12 =[ $jav012, throwjav13 ] {self.weaponframe=12;};
void() throwjav13 =[ $jav013, throwjav14 ] {self.weaponframe=13;};
void() throwjav14 =[ $jav014, throwjav15 ] {self.weaponframe=14;};
void() throwjav15 =[ $jav015, throwjav16 ] {self.weaponframe=15;};
void() throwjav16 =[ $jav016, throwjav17 ] {self.weaponframe=16;};
void() throwjav17 =[ $jav017, throwjav18 ] {self.weaponframe=17;};
void() throwjav18 =[ $jav018, throwjav19 ] {self.weaponframe=18;};
void() throwjav19 =[ $jav019, throwjav20 ] {self.weaponframe=19;};
void() throwjav20 =[ $jav020, self.th_run ] {self.weaponframe=20;};
//============================================================================
/*
================================
launch_javelin
================================
*/
void(vector org, vector dir) launch_javelin =
{
local entity missile;
missile = spawn ();
missile.owner = self;
missile.touch = T_MissileTouch;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.angles = vectoangles(dir);
missile.touch = T_MissileTouch;
missile.classname = "javelin";
org = org + '0 10 10';
setmodel (missile, "models/javproj.mdl");
setsize (missile, VEC_ORIGIN, VEC_ORIGIN);
setorigin (missile, org);
missile.velocity = dir * 800;
};
void() W_FireJavelin =
{
local vector dir;
local entity missile;
sound (self, CHAN_WEAPON, "raven/javthrow.wav", 1, ATTN_NORM);
self.punchangle_x = -2;
self.attack_finished = time + 0.5;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.classname = "javprojectile";
// set missile speed
makevectors (self.v_angle);
missile.velocity = aim(self, 1000);
missile.velocity = missile.velocity * 1000;
missile.angles = vectoangles(missile.velocity);
missile.touch = T_MissileTouch;
// set missile duration
missile.nextthink = time + 5;
missile.think = SUB_Remove;
setmodel (missile, "models/javproj.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin + v_forward*-14 + v_right * 16 + v_up * 32);
};
/*QUAKED wp_javelin (1 0 0) (-16 -16 -24) (16 16 40)
Javelin weapon for Paladin
-------------------------FIELDS-------------------------
none
--------------------------------------------------------
*/
void() wp_javelin =
{
if (deathmatch)
{
remove(self);
return;
}
};

22
jctest.hc Normal file
View File

@ -0,0 +1,22 @@
/*
* $Header: /HexenWorld/Siege/Jctest.hc 3 5/25/98 1:39p Mgummelt $
*/
void() jctrig =
{
dprint ("here\n\n");
lightstyle(0, "az");
};
/*QUAKED trigger_jctest (.5 .5 .5) ?
-------------------------FIELDS-------------------------
--------------------------------------------------------
*/
void() trigger_jctest =
{
setsize (self, self.mins, self.maxs);
self.solid = SOLID_EDGE;
self.touch = jctrig;
};

274
knight.hc Normal file
View File

@ -0,0 +1,274 @@
/*
* $Header: /HexenWorld/Siege/Knight.hc 3 5/25/98 1:39p Mgummelt $
*/
/*
==============================================================================
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 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 ();
};
/*QUAK-ED 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_atk1;
self.th_pain = knight_pain;
self.th_die = knight_die;
walkmonster_start ();
};

575
light.hc Normal file
View File

@ -0,0 +1,575 @@
/*
* $Header: /HexenWorld/Siege/light.hc 7 5/25/98 1:39p Mgummelt $
*/
/*
==========================================================
LIGHT.HC
MG
Lights can be toggled/faded, shot out, etc.
==========================================================
*/
float START_LOW = 1;
void initialize_lightstyle (void)
{
if(self.spawnflags&START_LOW)
if(self.lightvalue1<self.lightvalue2)
lightstylestatic(self.style, self.lightvalue1);
else
lightstylestatic(self.style, self.lightvalue2);
else
if(self.lightvalue1<self.lightvalue2)
lightstylestatic(self.style, self.lightvalue2);
else
lightstylestatic(self.style, self.lightvalue1);
}
void fadelight()
{
self.frags+=self.cnt;
self.light_lev+=self.frags;
lightstylestatic(self.style, self.light_lev);
self.count+=1;
//dprint(ftos(self.light_lev));
//dprint("\n");
if(self.count/20>=self.fadespeed)
{
//dprint("light timed out\n");
remove(self);
}
else if((self.cnt<0&&self.light_lev<=self.level)||(self.cnt>0&&self.light_lev>=self.level))
{
//dprint("light fade done\n");
lightstylestatic(self.style, self.level);
remove(self);
}
else
{
self.nextthink=time+0.05;
self.think=fadelight;
}
}
void lightstyle_change_think()
{
//dprint("initializing light change\n");
self.speed=self.lightvalue2 - self.lightvalue1;
self.light_lev=lightstylevalue(self.style);
if(self.light_lev==self.lightvalue1)
self.level = self.lightvalue2;
else if(self.light_lev==self.lightvalue2)
self.level = self.lightvalue1;
else if(self.speed>0)
if(self.light_lev<self.lightvalue1+self.speed*0.5)
self.level=self.lightvalue2;
else
self.level=self.lightvalue1;
else if(self.speed<0)
if(self.light_lev<self.lightvalue2-self.speed*0.5)
self.level=self.lightvalue1;
else
self.level=self.lightvalue2;
self.cnt=(self.level-self.light_lev)/self.fadespeed/20;
self.think = fadelight;
self.nextthink = time;
/*dprint("light style # ");
dprint(ftos(self.style));
dprint(":\n");
dprint("value1: ");
dprint(ftos(self.lightvalue1));
dprint("\n");
dprint("value2: ");
dprint(ftos(self.lightvalue2));
dprint("\n");
dprint("difference: ");
dprint(ftos(self.speed));
dprint("\n");
dprint("fadespeed: ");
dprint(ftos(self.fadespeed));
dprint("\n");
dprint("current light level: ");
dprint(ftos(self.light_lev));
dprint("\n");
dprint("target light level: ");
dprint(ftos(self.level));
dprint("\n");
dprint("luminosity interval: ");
dprint(ftos(self.cnt));
dprint("\n");*/
}
void lightstyle_change (entity light_targ)
{
//dprint("spawning light changer\n");
newmis=spawn();
newmis.lightvalue1=light_targ.lightvalue1;
newmis.lightvalue2=light_targ.lightvalue2;
newmis.fadespeed=light_targ.fadespeed;
newmis.style=self.style;
newmis.think=lightstyle_change_think;
newmis.nextthink=time;
}
void torch_death ()
{
lightstylestatic(self.style,0);
chunk_death();
}
void torch_think (void)
{
float lightstate;
lightstate=lightstylevalue(self.style);
if(!lightstate) //Use "off" frames
{
if(self.mdl)
setmodel(self,self.mdl);
self.drawflags(-)MLS_ABSLIGHT;
}
else
{
if(self.weaponmodel)
setmodel(self,self.weaponmodel);
self.drawflags(+)MLS_ABSLIGHT;
}
if(time>self.fadespeed)
self.nextthink=-1;
else
self.nextthink=time+0.05;
self.think=torch_think;
}
void torch_use (void)
{
self.fadespeed=time+other.fadespeed+1;
torch_think();
}
/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_LOW NO_REMOVE
Non-displayed fading light.
Default light value is 300
Default style is 0
----------------------------------
If triggered, will toggle between lightvalue1 and lightvalue2
.lightvalue1 (default 0)
.lightvalue2 (default 11, equivalent to 300 brightness)
Two values the light will fade-toggle between, 0 is black, 25 is brightest, 11 is equivalent to a value of 300.
.fadespeed (default 1) = How many seconds it will take to complete the desired lighting change
The light will start on at a default of the higher light value unless you turn on the startlow flag.
START_LOW = will make the light start at the lower of the lightvalues you specify (default uses brighter)
NO_REMOVE = Light entity will not be removed on spawn (for banks of triggered lights,one should stick around for reference)
NOTE: IF YOU DON'T PLAN ON USING THE DEFAULTS, ALL LIGHTS IN THE BANK OF LIGHTS NEED THIS INFO
*/
void light()
{
if (self.targetname == "")
{
remove(self);
}
else
{
if(!self.lightvalue2)
self.lightvalue2=11;
if(!self.fadespeed)
self.fadespeed = 1;
// dprintf("Targeted Light with style of %s, value of ",self.style);
// dprintf("%s\n",self.lightvalue2);
initialize_lightstyle();
// dprintf("My lightstyle was set to: %s\n",lightstylevalue(self.style));
remove(self);
// self.think=SUB_Remove;
// thinktime self : 1;
}
}
/*QUAK-ED light_globe (0 1 0) (-8 -8 -8) (8 8 8) START_LOW
Sphere globe light.
Default light value is 300
Default style is 0
----------------------------------
If triggered, will toggle between lightvalue1 and lightvalue2
.lightvalue1 (default 0)
.lightvalue2 (default 11, equivalent to 300 brightness)
Two values the light will fade-toggle between, 0 is black, 25 is brightest, 11 is equivalent to a value of 300.
.fadespeed (default 1) = How many seconds it will take to complete the desired lighting change
The light will start on at a default of the higher light value unless you turn on the startlow flag.
START_LOW = will make the light start at the lower of the lightvalues you specify (default uses brighter)
NOTE: IF YOU DON'T PLAN ON USING THE DEFAULTS, ALL LIGHTS IN THE BANK OF LIGHTS NEED THIS INFO
*/
/*
void() light_globe =
{
precache_model ("models/s_light.spr");
setmodel (self, "models/s_light.spr");
if(self.targetname)
self.use=torch_use;
self.mdl = "models/null.spr";
self.weaponmodel = "models/s_light.spr";
if(self.style>=32)
{
if(!self.lightvalue2)
self.lightvalue2=11;
if(!self.fadespeed)
self.fadespeed = 1;
initialize_lightstyle();
self.think = torch_think;
self.nextthink = time+1;
}
else
{
setmodel(self,self.weaponmodel);
makestatic (self);
}
};
*/
void() FireAmbient =
{
//FIXME: remove ambient sound if light is off, start it again if turned back on
precache_sound ("raven/flame1.wav");
// attenuate fast
ambientsound (self.origin, "raven/flame1.wav", 0.5, ATTN_STATIC);
};
/*QUAK-ED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20) START_LOW
Short wall torch
Default light value is 200
Default style is 0
----------------------------------
If triggered, will toggle between lightvalue1 and lightvalue2
.lightvalue1 (default 0)
.lightvalue2 (default 11, equivalent to 300 brightness)
Two values the light will fade-toggle between, 0 is black, 25 is brightest, 11 is equivalent to a value of 300.
.fadespeed (default 1) = How many seconds it will take to complete the desired lighting change
The light will start on at a default of the higher light value unless you turn on the startlow flag.
START_LOW = will make the light start at the lower of the lightvalues you specify (default uses brighter)
NOTE: IF YOU DON'T PLAN ON USING THE DEFAULTS, ALL LIGHTS IN THE BANK OF LIGHTS NEED THIS INFO
*/
void() light_torch_small_walltorch =
{
precache_model ("models/flame.mdl");
FireAmbient ();
if(self.targetname)
self.use=torch_use;
self.mdl = "models/null.spr";
self.weaponmodel = "models/flame.mdl";
self.abslight = .75;
if(self.style>=32)
{
if(!self.lightvalue2)
self.lightvalue2=11;
if(!self.fadespeed)
self.fadespeed = 1;
initialize_lightstyle();
self.think = torch_think;
self.nextthink = time+1;
}
else
{
self.drawflags(+)MLS_ABSLIGHT;
setmodel(self,self.weaponmodel);
makestatic (self);
}
};
/*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18) START_LOW
Large yellow flame
----------------------------------
If triggered, will toggle between lightvalue1 and lightvalue2
.lightvalue1 (default 0)
.lightvalue2 (default 11, equivalent to 300 brightness)
Two values the light will fade-toggle between, 0 is black, 25 is brightest, 11 is equivalent to a value of 300.
.fadespeed (default 1) = How many seconds it will take to complete the desired lighting change
The light will start on at a default of the higher light value unless you turn on the startlow flag.
START_LOW = will make the light start at the lower of the lightvalues you specify (default uses brighter)
NOTE: IF YOU DON'T PLAN ON USING THE DEFAULTS, ALL LIGHTS IN THE BANK OF LIGHTS NEED THIS INFO
*/
void() light_flame_large_yellow =
{
precache_model ("models/flame1.mdl");
FireAmbient ();
if(self.targetname)
self.use=torch_use;
self.abslight = .75;
self.mdl = "models/null.spr";
self.weaponmodel = "models/flame1.mdl";
if(self.style>=32)
{
if(!self.lightvalue2)
self.lightvalue2=11;
if(!self.fadespeed)
self.fadespeed = 1;
initialize_lightstyle();
self.think = torch_think;
self.nextthink = time+1;
}
else
{
self.drawflags(+)MLS_ABSLIGHT;
setmodel(self,self.weaponmodel);
makestatic (self);
}
};
/*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) START_LOW
Small yellow flame ball
----------------------------------
If triggered, will toggle between lightvalue1 and lightvalue2
.lightvalue1 (default 0)
.lightvalue2 (default 11, equivalent to 300 brightness)
Two values the light will fade-toggle between, 0 is black, 25 is brightest, 11 is equivalent to a value of 300.
.fadespeed (default 1) = How many seconds it will take to complete the desired lighting change
The light will start on at a default of the higher light value unless you turn on the startlow flag.
START_LOW = will make the light start at the lower of the lightvalues you specify (default uses brighter)
NOTE: IF YOU DON'T PLAN ON USING THE DEFAULTS, ALL LIGHTS IN THE BANK OF LIGHTS NEED THIS INFO
*/
void() light_flame_small_yellow =
{
precache_model ("models/flame2.mdl");
FireAmbient ();
if(self.targetname)
self.use=torch_use;
self.abslight = .75;
self.mdl = "models/null.spr";
self.weaponmodel = "models/flame2.mdl";
if(self.style>=32)
{
if(!self.lightvalue2)
self.lightvalue2=11;
if(!self.fadespeed)
self.fadespeed = 1;
initialize_lightstyle();
self.think = torch_think;
self.nextthink = time+1;
}
else
{
self.drawflags(+)MLS_ABSLIGHT;
setmodel(self,self.weaponmodel);
makestatic (self);
}
};
/*QUAK-ED light_flame_small_white (0 1 0) (-10 -10 -40) (10 10 40) START_LOW
Small white flame ball
----------------------------------
If triggered, will toggle between lightvalue1 and lightvalue2
.lightvalue1 (default 0)
.lightvalue2 (default 11, equivalent to 300 brightness)
Two values the light will fade-toggle between, 0 is black, 25 is brightest, 11 is equivalent to a value of 300.
.fadespeed (default 1) = How many seconds it will take to complete the desired lighting change
The light will start on at a default of the higher light value unless you turn on the startlow flag.
START_LOW = will make the light start at the lower of the lightvalues you specify (default uses brighter)
NOTE: IF YOU DON'T PLAN ON USING THE DEFAULTS, ALL LIGHTS IN THE BANK OF LIGHTS NEED THIS INFO
*/
/*
void() light_flame_small_white =
{
precache_model ("models/flame2.mdl");
FireAmbient ();
if(self.targetname)
self.use=torch_use;
self.abslight = .75;
self.mdl = "models/null.spr";
self.weaponmodel = "models/flame2.mdl";
if(self.style>=32)
{
if(!self.lightvalue2)
self.lightvalue2=11;
if(!self.fadespeed)
self.fadespeed = 1;
initialize_lightstyle();
self.think = torch_think;
self.nextthink = time+1;
}
else
{
self.drawflags(+)MLS_ABSLIGHT;
setmodel(self,self.weaponmodel);
makestatic (self);
}
};
*/
/*QUAKED light_gem (0 1 0) (-8 -8 -8) (8 8 8) START_LOW
A gem that displays light.
Default light value is 300
Default style is 0
----------------------------------
If triggered, will toggle between lightvalue1 and lightvalue2
.lightvalue1 (default 0)
.lightvalue2 (default 11, equivalent to 300 brightness)
Two values the light will fade-toggle between, 0 is black, 25 is brightest, 11 is equivalent to a value of 300.
.fadespeed (default 1) = How many seconds it will take to complete the desired lighting change
The light will start on at a default of the higher light value unless you turn on the startlow flag.
START_LOW = will make the light start at the lower of the lightvalues you specify (default uses brighter)
NOTE: IF YOU DON'T PLAN ON USING THE DEFAULTS, ALL LIGHTS IN THE BANK OF LIGHTS NEED THIS INFO
*/
void() light_gem =
{
precache_model ("models/gemlight.mdl");
if(self.targetname)
self.use=torch_use;
self.mdl = "models/null.spr";
self.weaponmodel = "models/gemlight.mdl";
self.abslight = .75;
if(self.style>=32)
{
if(!self.lightvalue2)
self.lightvalue2=11;
if(!self.fadespeed)
self.fadespeed = 1;
initialize_lightstyle();
self.think = torch_think;
self.nextthink = time+1;
}
else
{
self.drawflags(+)MLS_ABSLIGHT;
setmodel(self,self.weaponmodel);
makestatic (self);
}
};
void fade_down ();
void fade_up ();
void wait_fade_down ()
{
self.aflag*=-1;
self.think=fade_down;
thinktime self : self.delay;
}
void wait_fade_up ()
{
self.aflag*=-1;
self.think=fade_up;
thinktime self : self.delay;
}
void fade_down ()
{
self.light_lev=lightstylevalue(self.style);
if(self.light_lev==self.level)
{
if(self.spawnflags&1)
wait_fade_up();
else
{
self.think=SUB_Null;
self.nextthink=-1;
}
return;
}
self.think=fade_down;
thinktime self : self.wait;
self.light_lev+=self.aflag;
if(self.light_lev<0)
self.light_lev=0;
else if(self.light_lev<self.level)
self.light_lev=self.level;
lightstylestatic(self.style, self.light_lev);
}
void fade_up ()
{
self.light_lev=lightstylevalue(self.style);
if(self.light_lev==self.lightvalue1)
{
if(self.spawnflags&1)
wait_fade_down();
else
{
self.think=SUB_Null;
self.nextthink=-1;
}
return;
}
self.think=fade_up;
thinktime self : self.wait;
self.light_lev+=self.aflag;
if(self.light_lev>25)
self.light_lev=25;
else if(self.light_lev>self.lightvalue1)
self.light_lev=self.lightvalue1;
lightstylestatic(self.style, self.light_lev);
}
/*QUAKED ambient_lightfader (.5 .5 .5) (-4 -4 -4) (4 4 4) TOGGLE
"wait" - how long to wait between fade steps (only 25 light values)
default 60 (1 minute)
"level" - what light value to stop at (from 1 - 25)
default 0
"aflag" - direction and increment to fade at (1 is one step brighter, -1 is default-fade down 1 step)
default -1
TOGGLE - Will reach end of it's fade, then start fading back in/out the other way
"delay" - If toggled, how long to wait before changing fade direction and starting again.
default 300 (5 minutes)
*/
void al_delayed_init ()
{
float savelevel;
self.use=SUB_Null;
self.lightvalue1 = lightstylevalue(self.style);
if(self.aflag>0)
{
if(self.level<self.lightvalue1)
{
savelevel = self.level;
self.level = self.lightvalue1;
self.lightvalue1=self.level;
}
self.think = fade_up;
}
else
{
if(self.level>self.lightvalue1)
{
savelevel = self.level;
self.level = self.lightvalue1;
self.lightvalue1=self.level;
}
self.think = fade_down;
}
thinktime self : self.wait;
}
void ambient_lightfader ()
{
// if(!self.wait)
self.wait = 180;
if(!self.aflag)
self.aflag=-1;
if(!self.delay)
self.delay = 180;
self.use=al_delayed_init;
self.think=al_delayed_init;
thinktime self : 180;//start fading after 3 minutes if not used first
}

424
lightning.hc Normal file
View File

@ -0,0 +1,424 @@
/*
===============================================================================
LIGHTNING.HC
MG
Lightning and Sunbeam effects, and thunderstorm
===============================================================================
*/
void smolder_think ()
{
vector ofs;
ofs_x=random(-10,10);
ofs_y=random(-10,10);
particle(self.origin+ofs, '0 0 100', random(272,288), random(1,10));
if(random()<0.1&&random()<0.5)
CreateWhiteSmoke(self.origin,'0 0 8',HX_FRAME_TIME * 2);
thinktime self : 0.1;
if(time>self.lifetime)
remove(self);
}
void smolder (vector org)
{
newmis=spawn();
setorigin(newmis,org);
newmis.effects=EF_NODRAW;
newmis.lifetime=time+7;
newmis.think=smolder_think;
thinktime newmis : 0;
}
void shock_think()
{
if (self.skin ==0)
self.skin = 1;
else
self.skin = 0;
self.scale-=0.1;
thinktime self : 0.05;
if(time>self.lifetime||self.scale<=0.1)
remove(self);
}
void spawnshockball (vector org)
{
newmis=spawn();
newmis.drawflags(+)MLS_TORCH;
setmodel (newmis, "models/vorpshok.mdl");
setorigin(newmis, org);
newmis.lifetime=time+1;
newmis.angles_z=90;
newmis.think=shock_think;
thinktime newmis : 0;
newmis.scale=2.5;
}
/*
=================
LightningDamage
=================
*/
void (vector endpos) ThroughWaterZap =
{
entity waterloser, attacker;
float damg;
waterloser = spawn();
setorigin (waterloser, endpos);
if(self.classname=="mjolnir")
damg=128;
else
damg=666*2;
attacker=self;
if(self.classname!="player")
if(self.owner.classname=="player")
attacker=self.owner;
else if(self.controller.classname=="player")
attacker=self.controller;
T_RadiusDamageWater (waterloser, self, damg,self);
remove (waterloser);
};
void (vector startpos) ThroughWater =
{
vector endpos;
float mover;
mover = 600;
while (mover)
{
mover = mover - 10;
endpos = startpos + v_forward * mover;
if (pointcontents(endpos) == CONTENT_WATER || pointcontents(endpos) == CONTENT_SLIME)
ThroughWaterZap(endpos);
else if (pointcontents(endpos) == CONTENT_SOLID)
return;
}
};
void do_lightning_dam (entity from, float damage, string type)
{
vector loser_org;
if((trace_ent.classname=="monster_eidolon"||trace_ent.classname=="obj_chaos_orb")&&type=="lightning")
return;
if (type != "cubebeam")
particle (trace_endpos, '0 0 100', 225, damage*4);
if(type=="lightning")
spawnshockball((trace_ent.absmax+trace_ent.absmin)*0.5);
loser_org=trace_ent.origin;
T_Damage (trace_ent, from, from, damage);
if(trace_ent.health<=0)
smolder(loser_org);
if(type=="lightning")
sound(trace_ent,CHAN_AUTO,"misc/lighthit.wav",1,ATTN_NORM);
else if (type != "cubebeam")
sound(trace_ent,CHAN_AUTO,"crusader/sunhit.wav",1,ATTN_NORM);
}
void(vector p1, vector p2, entity from, float damage,string type) LightningDamage =
{
entity e1, e2;// swap;
vector f;
float inertia;//absorb;
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(type=="lightning"&&(pointcontents(trace_endpos) == CONTENT_WATER || pointcontents(trace_endpos) == CONTENT_SLIME))
ThroughWaterZap(trace_endpos);
else if(type=="lightning"&&(trace_ent.watertype == CONTENT_WATER || trace_ent.watertype == CONTENT_SLIME))
T_RadiusDamageWater (self, self, 666*2,self);
else if(self.classname=="mjolnir"&&trace_ent==self.controller)
bprint(PRINT_MEDIUM, "");
else if (trace_ent.takedamage)
{
if (trace_ent.mass<=10)
inertia=1;
else
inertia = trace_ent.mass/10;
do_lightning_dam(from,damage,type);
if (self.classname=="mjolnir"&&(trace_ent.flags&FL_ONGROUND)&&type=="lightning")
{
trace_ent.velocity_z = trace_ent.velocity_z + 400/inertia;
trace_ent.flags(-)FL_ONGROUND;
}
}
else if(type=="lightning")
ThroughWater(p1);
e1 = trace_ent;
traceline (p1 + f, p2 + f, FALSE, self);
if(self.classname=="mjolnir"&&trace_ent==self.controller)
bprint(PRINT_MEDIUM, "");
else if(trace_ent != e1 && trace_ent.takedamage)
do_lightning_dam(from,damage,type);
e2 = trace_ent;
traceline (p1 - f, p2 - f, FALSE, self);
if(self.classname=="mjolnir"&&trace_ent==self.controller)
bprint(PRINT_MEDIUM, "");
else if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
do_lightning_dam(from,damage,type);
};
void do_lightning (entity lowner,float tag, float lflags, float duration, vector spot1, vector spot2, float ldamg,float te_type)
{
vector damage_dir;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, te_type);
WriteEntity (MSG_BROADCAST, lowner);
WriteByte (MSG_BROADCAST, tag+lflags);
WriteByte (MSG_BROADCAST, duration);
WriteCoord (MSG_BROADCAST, spot1_x);
WriteCoord (MSG_BROADCAST, spot1_y);
WriteCoord (MSG_BROADCAST, spot1_z);
WriteCoord (MSG_BROADCAST, spot2_x);
WriteCoord (MSG_BROADCAST, spot2_y);
WriteCoord (MSG_BROADCAST, spot2_z);
if(ldamg)
{
if(self.owner.classname=="player")
lowner=self.owner;
else if(self.controller.classname=="player")
lowner=self.controller;
damage_dir=normalize(spot2-spot1);
LightningDamage (spot1-damage_dir*15, spot2+damage_dir*15, lowner, ldamg,"lightning");
}
}
void(float max_strikes, float damg) CastLightning =
{
//Not working, I want 3 seperate beams, when get that, drop damage to 10
vector org, dir,tospot;
float number_strikes;
self.effects(+)EF_MUZZLEFLASH;
if(max_strikes==0)
max_strikes=1;
while(max_strikes>number_strikes)
{
if(random()<0.7)
sound(self.enemy,CHAN_AUTO,"crusader/lghtn1.wav",1,ATTN_NORM);
else
sound(self.enemy,CHAN_AUTO,"crusader/lghtn2.wav",1,ATTN_NORM);
if(self.enemy.solid==SOLID_BSP&&self.enemy.origin=='0 0 0')
org=(self.enemy.absmin+self.enemy.absmax)*0.5;
else
{
org=self.enemy.origin;
org_z += 0.5*self.enemy.maxs_z;
}
dir=org;
dir_x+= random(-300,300);
dir_y+= random(-300,300);
dir_z+= 500;
traceline(org,dir,TRUE,self);
tospot=org;
org=trace_endpos;
do_lightning (self,number_strikes,0,4,org,tospot,damg,TE_STREAM_LIGHTNING);
number_strikes+=1;
}
};
void()rolling_thunder;
void thunder_clear ()
{
self.owner.aflag-=1;
remove(self);
}
void thunder_sound ()
{
float sound_vol;
sound_vol=self.lightvalue2/25;
if(sound_vol>1)
sound_vol=1;
else if(sound_vol<0)
sound_vol=0.1;
sound (self, CHAN_VOICE, "ambience/thunder1.wav", sound_vol, ATTN_NORM);
thinktime self : 5;
self.think=thunder_clear;
}
void spawn_thunder ()
{
self.aflag+=1;
newmis=spawn();
self.angles_y=random(360);
makevectors(self.angles);
setorigin(newmis,self.origin+v_forward*self.lightvalue2*10);
newmis.owner=self;
newmis.lightvalue2=self.lightvalue2;
newmis.think=thunder_sound;
thinktime newmis : 2.5 - self.lightvalue2/10;
}
void flash_wait ()
{
lightstylestatic(self.style,self.lightvalue1);
self.think=rolling_thunder;
thinktime self : 0;
}
void lightning_strike (void)
{
vector org,tospot, lightn_dir;
float dist, num_branches;
dist=random(self.frags);
self.angles_y=random(360);
makevectors(self.angles);
traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
org=trace_endpos;
tospot=org-'0 0 1000';
traceline(org,tospot,TRUE,self);
tospot=trace_endpos;
tospot_x+=random(-100,100);
tospot_y+=random(-100,100);
dist=vlen(tospot-org);
newmis=spawn();
setorigin(newmis,org);
if(random()<0.5)
sound(newmis,CHAN_AUTO,"crusader/lghtn1.wav",1,ATTN_NORM);
else
sound(newmis,CHAN_AUTO,"crusader/lghtn2.wav",1,ATTN_NORM);
newmis.think=SUB_Remove;
thinktime newmis : 3;
num_branches = rint(random(3,7));
while(num_branches)
{
self.level+=1;
if(self.level>=8)
self.level=0;
if (self.lockentity.classname == "monster_buddha")
do_lightning (self.lockentity,self.level,STREAM_ATTACHED,4,org,tospot,50,TE_STREAM_LIGHTNING);
else
do_lightning (self,self.level,STREAM_ATTACHED,4,org,tospot,10000,TE_STREAM_LIGHTNING);
lightn_dir=normalize(tospot-org);
org=org + lightn_dir*random(num_branches+dist/10,num_branches+dist/5);//Include trace_fraction?
tospot=org-'0 0 1000';
traceline(trace_endpos,tospot,TRUE,self);
tospot=trace_endpos;
if(random()<0.5)
tospot_x+=random(125,375);
else
tospot_x-=random(125,375);
if(random()<0.5)
tospot_y+=random(125,375);
else
tospot_y-=random(125,375);
/*if(trace_fraction<0.01)
{
dprint("not into ground\n");
num_branches=0;
}
else*/
num_branches-=1;
}
}
void rolling_thunder (void)
{
if(random(100)>=self.wait)
{
if(self.spawnflags&1&&random(100)<self.dmg)
{
self.lightvalue2=25;
lightning_strike();
}
else
{
float lightburst;
lightburst=random(0.1,1.1)*(25 - self.lightvalue1);
self.lightvalue2=self.lightvalue1+lightburst;
if(self.aflag<=3)
spawn_thunder();
}
lightstylestatic(self.style,self.lightvalue2);
self.think=flash_wait;
thinktime self : random(0.3);
}
else
{
self.think=rolling_thunder;
thinktime self : random(0.1,1.1);
}
}
void thunder_use (void)
{
if(self.spawnflags&1)
{
self.lightvalue2=25;
lightning_strike();
}
else
{
float lightburst;
lightburst=random(0.1,1.1)*(25 - self.lightvalue1);
self.lightvalue2=self.lightvalue1+lightburst;
spawn_thunder();
}
lightstylestatic(self.style,self.lightvalue2);
self.think=flash_wait;
thinktime self : random(0.3);
}
/*QUAKED light_thunderstorm (0 1 0) (-8 -8 -8) (8 8 8) LIGHTNING
Default light value is 300
This will create a light source that will occaisionally flash with light followed shortly by an ambient thunder sound
.wait = the shorter the wait, the more active the thunderstorm. Valid values for this are 1 - 100. 100 is a stupid value because it will never thunder! Default is 33
.dmg = how often lighting strikes, 0 will be the equvalent of never, 100 will be very frequent. default is 10
.lightvalue1 = the light value the storm should always return to. Valid range is 0 - 25, 25 being the brightest. Default is 11 (about 300 brightness)
.frags = The radius in which lightning can stike from this entity. (default=1000)
The LIGHTNING spawnflag will make it cast random lightning strikes
NOTE: These MUST be targeted. They will never actually be used by the trigger, but targeting is required to give them a distince lightstyle
Targeting can be used to link several thunderstorms together so they all use the same lightstyle (they'll all flash at the same time)
*/
void light_thunderstorm()
{
if(self.targetname)
self.use=thunder_use;
else
{
remove(self);
return;
}
precache_sound("ambience/thunder1.wav");
precache_sound("crusader/lghtn1.wav");
precache_sound("crusader/lghtn2.wav");
if(!self.frags)
self.frags=1000;
if(!self.wait)
self.wait=33;
if(!self.lightvalue1)
self.lightvalue1=11;
if(!self.dmg&&self.spawnflags&1)
self.dmg=10;
// self.dmg=100;
lightstylestatic(self.style,self.lightvalue1);
self.think=rolling_thunder;
thinktime self : 0;
}

607
lightwp.hc Normal file
View File

@ -0,0 +1,607 @@
/*
==============================================================================
$Header: /HexenWorld/Siege/lightwp.hc 22 5/25/98 1:39p Mgummelt $
==============================================================================
*/
// For building the model
$cd Q:\art\models\weapons\spllbook
$origin 0 0 0
$base BASE skin
$skin skin
$flags 0
//
$frame fidle1 fidle2 fidle3 fidle4 fidle5
$frame fidle6 fidle7 fidle8 fidle9 fidle10
$frame fidle11 fidle12 fidle13 fidle14 fidle15
$frame fidle16
//
$frame nidle1 nidle2 nidle3 nidle4 nidle5
$frame nidle6 nidle7 nidle8 nidle9 nidle10
$frame nidle11 nidle12 nidle13 nidle14 nidle15
$frame nidle16
//
$frame normal1 normal2 normal3 normal4 normal5
$frame normal6 normal7 normal8 normal9 normal10
$frame normal11 normal12 normal13 normal14 normal15
$frame normal16
//
$frame pidle1 pidle2 pidle3 pidle4 pidle5
$frame pidle6 pidle7 pidle8 pidle9 pidle10
$frame pidle11 pidle12 pidle13 pidle14 pidle15
$frame pidle16
//
$frame power1 power2 power3 power4 power5
$frame power6 power7 power8 power9 power10
$frame power11 power12 power13 power14 power15
$frame power16
//
$frame select1 select2 select3 select4 select5
$frame select6 select7 select8 select9 select10
$frame select11 select12
/*
======================
Lightning Bolts Test
Unpowered: Ball Lightning
Powered: Chain lightning- arcs between monsters
======================
*/
void lball_remove ()
{
stopSound(self,0);
remove(self);
}
void LightningBallTouch ()
{
float zap_other;
if(other.classname==self.classname&&other.owner==self.owner)
return;
self.level=FALSE;
if(other.takedamage)
{
T_Damage(other,self,self.owner,self.dmg);
if(other.flags&FL_MONSTER)
zap_other=TRUE;
}
self.dmg = random(70, 100);
T_RadiusDamage(self,self.owner,self.dmg,other);
// stopSound(self,0);
// sound(self,CHAN_AUTO,"crusader/lghtn2.wav",1,ATTN_NORM);
// starteffect(CE_LBALL_EXPL,self.origin-self.movedir*8,0.05);
/* if(zap_other)
{
org=self.origin;
tospot=normalize((other.absmin+other.absmax)*0.5-org);
tospot=org+tospot*(random(75)+75);
//do_lightning (self.owner,zap_cnt,0,4,org,tospot,100,TE_STREAM_LIGHTNING);
damage_dir=normalize(tospot-org);
LightningDamage (org-damage_dir*15, tospot+damage_dir*15, self.owner, 100,"lightning");
}
while(zap_cnt<3)//8)
{
self.angles=randomv('0 0 0','360 360 360');
makevectors(self.angles);
org=self.origin;
tospot=org+v_forward*(random(75)+75);
//do_lightning (self.owner,zap_cnt,0,4,org,tospot,50,TE_STREAM_LIGHTNING);
damage_dir=normalize(tospot-org);
LightningDamage (org-damage_dir*15, tospot+damage_dir*15, self.owner, 100,"lightning");
zap_cnt+=1;
}*/
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_LIGHTNINGEXPLODE);
WriteEntity (MSG_MULTICAST, self.owner);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
multicast(self.origin,MULTICAST_PHS_R);
remove(self);
}
void lightningHomeThink()
{
vector moveAng;
HomeThink();
moveAng = vectoangles(self.velocity);
traceline(self.origin, self.origin + self.velocity*.2, FALSE, self);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_LIGHTNINGBALL);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
WriteByte (MSG_MULTICAST, moveAng_y*256.0/360.0);
WriteByte (MSG_MULTICAST, moveAng_x*256.0/360.0);
WriteShort(MSG_MULTICAST, vlen(self.velocity));
WriteByte (MSG_MULTICAST, trace_fraction * 100);
multicast(self.origin,MULTICAST_PVS);
thinktime self : 0.2;
if (self.lifetime < time)
SUB_Remove();
}
void FireLightningBall ()
{
entity lball;
makevectors(self.v_angle);
self.effects(+)EF_MUZZLEFLASH;
stuffcmd (self, "bf\n");
lball=spawn();
lball.classname="lightning ball";
lball.owner=self;
lball.drawflags(+)SCALE_ORIGIN_CENTER;
lball.movetype=MOVETYPE_FLYMISSILE;
lball.solid=SOLID_BBOX;
lball.level=TRUE;
lball.touch=LightningBallTouch;
lball.dmg=random(60,100);
lball.speed=1000;
lball.velocity=normalize(v_forward)*lball.speed;
lball.angles=randomv('-600 -600 -600','600 600 600');
setmodel(lball,"models/lball.mdl");
setsize(lball,'0 0 0','0 0 0');
lball.scale=0.75;
setorigin(lball,self.origin+self.proj_ofs+v_forward*10);
// sound(self,CHAN_AUTO,"succubus/firelbal.wav",1,ATTN_NORM);
lball.turn_time=2;
// lball.dmg=random(45,55);
lball.effects=EF_DIMLIGHT|EF_UPDATESOUND;
lball.frags=TRUE;
lball.veer=100;
lball.homerate=0.1;
lball.lifetime=time+2.5;
lball.th_die=lball_remove;
//lball.think=HomeThink;
lball.hoverz=TRUE;
//thinktime lball : 0.2;
lball.t_width=time+random(0.02,0.5);
// sound(lball,CHAN_UPDATE+PHS_OVERRIDE_R,"succubus/buzz2.wav",1,ATTN_LOOP);
lball.effects(+)EF_NODRAW;
entity oldself;
oldself = self;
self = lball;
lball.think = lightningHomeThink;
lball.think();
self = oldself;
}
void LilLightningThink()
{
T_Damage(self.enemy, self.owner, self.owner, self.dmg);
remove(self);
}
void AttachLilLightning(float damage, entity nTarg, entity from)
{
entity newGuy;
newGuy = spawn();
newGuy.effects (+) EF_NODRAW;
newGuy.dmg = damage;
newGuy.owner = from;
newGuy.enemy = nTarg;
newGuy.think = LilLightningThink;
thinktime newGuy : 0.0;
}
void(vector p1, vector p2, entity from, float damage) LightningDamage2 =
{
entity e1, e2;// swap;
vector f;
float inertia;//absorb;
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)
{
if (trace_ent.mass<=10)
{
inertia=1;
}
else
{
inertia = trace_ent.mass/10;
}
WriteCoord(MSG_MULTICAST, trace_ent.origin_x);
WriteCoord(MSG_MULTICAST, trace_ent.origin_y);
WriteCoord(MSG_MULTICAST, trace_ent.origin_z + 32);
AttachLilLightning(damage, trace_ent, from);
}
e1 = trace_ent;
traceline (p1 + f, p2 + f, FALSE, self);
if(trace_ent != e1 && trace_ent.takedamage)
{
WriteCoord(MSG_MULTICAST, trace_ent.origin_x);
WriteCoord(MSG_MULTICAST, trace_ent.origin_y);
WriteCoord(MSG_MULTICAST, trace_ent.origin_z + 32);
AttachLilLightning(damage, trace_ent, from);
}
e2 = trace_ent;
traceline (p1 - f, p2 - f, FALSE, self);
if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
{
WriteCoord(MSG_MULTICAST, trace_ent.origin_x);
WriteCoord(MSG_MULTICAST, trace_ent.origin_y);
WriteCoord(MSG_MULTICAST, trace_ent.origin_z + 32);
AttachLilLightning(damage, trace_ent, from);
}
};
void do_lightning2 (entity lowner,float tag, float lflags, float duration, vector spot1, vector spot2, float ldamg)
{
vector damage_dir;
// lowner=self.owner;
damage_dir=normalize(spot2-spot1);
LightningDamage2 (spot1-damage_dir*15, spot2+damage_dir*15, lowner, ldamg);
}
void branch_fire (vector org)
{
vector tospot, lightn_dir;
float num_branches;
tospot=org+v_forward*1000;
traceline(org,tospot,TRUE,self);
tospot=trace_endpos;
num_branches = 3;
self.count=0;
while(num_branches)
{
self.count+=1;
if(self.count>=8)
self.count=0;
do_lightning2 (self,self.count,STREAM_ATTACHED,4,org,tospot,30);
lightn_dir=normalize(tospot-org);
org=org + lightn_dir*random(num_branches+20,num_branches+45);//Include trace_fraction?
tospot=org+v_forward*1000;
traceline(trace_endpos,tospot,TRUE,self);
tospot=trace_endpos;
if(random()<0.5)
tospot+=v_right*random(150,400);
else
tospot-=v_right*random(150,400);
if(random()<0.5)
tospot+=v_up*random(150,400);
else
tospot-=v_up*random(150,400);
num_branches-=1;
}
}
void shebitch_chain_lightning_strike ()
{
vector org, tospot;
float damg,damg_thresh, zap_count,fov_check;
entity loser, lastloser,firstloser;
float numTargs;
numTargs = 0;
if(self.attack_finished>time)
return;
self.greenmana-=4;
self.bluemana-=4;
self.attack_finished=time+0.2;
self.effects(+)EF_MUZZLEFLASH;
makevectors(self.v_angle);
org=self.origin+self.proj_ofs+v_forward*36;
loser=findradius(org,1000);
firstloser=lastloser=loser;
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_CHAINLIGHTNING);
WriteEntity(MSG_MULTICAST, self);
WriteCoord(MSG_MULTICAST, org_x);
WriteCoord(MSG_MULTICAST, org_y);
WriteCoord(MSG_MULTICAST, org_z);
while((loser!=world)&&(numTargs < 5))
{
if(loser.health&&loser.flags2&FL_ALIVE&&loser!=self)
{
tospot=(loser.absmin+loser.absmax)*0.5;
traceline(org,tospot,TRUE,self);
if(infront(loser))
{
if(lastloser==firstloser)
{
fov_check=vlen(loser.origin-self.origin);
fov_check=(50/fov_check);
if(fov_check>1)
fov_check=1;
fov_check*=10;//at further distances, cone is smaller
if(!fov(loser,self,fov_check))
trace_fraction=0;
}
}
else
trace_fraction=0;
if(trace_fraction==1)
{
if(loser.flags&FL_MONSTER)
damg_thresh=40;
else
damg_thresh=random(15,25);
if(loser.health>damg_thresh)
damg=damg_thresh;
else
damg=1000;
self.count+=1;
if(self.count>=8)
self.count=0;
tospot=(loser.absmin+loser.absmax)*0.5;
zap_count+=1;
do_lightning2 (self,self.count,STREAM_ATTACHED,4,org,tospot,damg);
numTargs += 1; // ensure that there are fewer than 5 targets hit...
org=tospot;
if(lastloser==self)
firstloser=loser;
lastloser=loser;
}
}
loser=loser.chain;
}
if(!zap_count)
{
branch_fire(org);
traceline(org, org + v_forward * 128, TRUE, self);
WriteCoord(MSG_MULTICAST, org_x + v_forward_x * 128 * trace_fraction);
WriteCoord(MSG_MULTICAST, org_y + v_forward_y * 128 * trace_fraction);
WriteCoord(MSG_MULTICAST, org_z + v_forward_z * 128 * trace_fraction);
}
WriteCoord(MSG_MULTICAST, 0);
WriteCoord(MSG_MULTICAST, 0);
WriteCoord(MSG_MULTICAST, 0);
multicast(self.origin,MULTICAST_PVS);
}
void()lightning_ready_power;
void()lightning_ready_normal;
void lightning_fire_normal (void)
{
if(self.weaponframe_cnt)
self.wfs = advanceweaponframe($fidle1,$fidle16);
else
{
self.wfs = advanceweaponframe($normal1,$normal16);
if(self.weaponframe==$normal2)
{
if(self.effects&EF_DIMLIGHT)
self.lefty=TRUE;
else
self.effects(+)EF_DIMLIGHT;
}
else if(self.weaponframe==$normal16)
{
if(!self.lefty)
self.effects(-)EF_DIMLIGHT;
else
self.lefty=FALSE;
}
}
self.th_weapon=lightning_fire_normal;
self.last_attack=time;
if(self.artifact_active&ART_TOMEOFPOWER)
{
if(self.effects&EF_DIMLIGHT)
{
if(!self.lefty)
self.effects(-)EF_DIMLIGHT;
else
self.lefty=FALSE;
}
lightning_ready_power();
}
else if(self.greenmana<6||
self.bluemana<6||
(!self.button0&&self.weaponframe==$normal16)
)
{
if(self.effects&EF_DIMLIGHT)
{
if(!self.lefty)
self.effects(-)EF_DIMLIGHT;
else
self.lefty=FALSE;
}
lightning_ready_normal();
}
else if(self.weaponframe==$normal12 ||(self.weaponframe>=$fidle1 &&self.weaponframe<=$fidle16))
{
if(self.attack_finished<time)
{
self.weaponframe_cnt=FALSE;
FireLightningBall();
sound(self,CHAN_WEAPON,"succubus/firelbal.wav",1,ATTN_NORM);
self.bluemana-=6;
self.greenmana-=6;
self.attack_finished=time+1;
self.weaponframe=$normal13;
}
else
self.weaponframe_cnt=TRUE;
}
}
void lightning_fire_power (void)
{
self.wfs = advanceweaponframe($power1,$power16);
self.th_weapon=lightning_fire_power;
self.last_attack=time;
if(!self.artifact_active&ART_TOMEOFPOWER)
{
stopSound(self,CHAN_UPDATE);
self.effects(-)EF_UPDATESOUND;
self.t_width=SOUND_STOPPED;
lightning_ready_normal();
}
else if(self.greenmana<4||self.bluemana<4||!self.button0)
{
stopSound(self,CHAN_UPDATE);
self.effects(-)EF_UPDATESOUND;
self.t_width=SOUND_STOPPED;
lightning_ready_power();
}
else
{
if(self.t_width!=SOUND_STARTED)
{
sound(self,CHAN_UPDATE+PHS_OVERRIDE_R,"succubus/firelght.wav",1,ATTN_LOOP);
self.effects(+)EF_UPDATESOUND;
self.t_width=SOUND_STARTED;
}
if(!self.weaponframe_cnt)
shebitch_chain_lightning_strike();
self.weaponframe_cnt+=1;
if(self.weaponframe_cnt==4)
self.weaponframe_cnt=0;
}
}
void() Suc_Litn_Fire =
{
self.weaponframe_cnt=FALSE;
if(self.artifact_active&ART_TOMEOFPOWER)
lightning_fire_power();
else
lightning_fire_normal();
thinktime self : 0;
};
void lightning_ready_power (void)
{
if(random()<=0.07)
{
self.weaponframe=$pidle1 + rint(random(15));
sound(self,CHAN_WEAPON,"succubus/buzz.wav",1,ATTN_NORM);
self.effects(+)EF_MUZZLEFLASH;
}
else
self.weaponframe=$pidle1;
self.th_weapon=lightning_ready_power;
if(!self.artifact_active&ART_TOMEOFPOWER)
lightning_ready_normal();
}
void lightning_ready_flip (void)
{
self.wfs = advanceweaponframe($nidle1,$nidle16);
self.th_weapon=lightning_ready_flip;
if(self.wfs==WF_CYCLE_WRAPPED)
lightning_ready_normal();
}
void lightning_ready_normal (void)
{
self.weaponframe=$normal1;
self.th_weapon=lightning_ready_normal;
if(self.artifact_active&ART_TOMEOFPOWER)
lightning_ready_power();
else if(random(1000)<1)
{
sound (self, CHAN_WEAPON, "weapons/vorpswng.wav", 1, ATTN_NORM);
lightning_ready_flip();
}
}
void lightning_ready (void)
{
if(self.artifact_active&ART_TOMEOFPOWER)
lightning_ready_power();
else
lightning_ready_normal();
}
void lightning_select (void)
{
self.wfs = advanceweaponframe($select1,$select12);
self.weaponmodel = "models/sucwp4.mdl";
self.th_weapon=lightning_select;
if(self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
lightning_ready_flip();
}
}
void lightning_deselect (void)
{
self.wfs = advanceweaponframe($select12,$select1);
self.th_weapon=lightning_deselect;
if(self.wfs==WF_CYCLE_WRAPPED)
W_SetCurrentAmmo();
}

0
lonbow.hc Normal file
View File

310
magicmis.hc Normal file
View File

@ -0,0 +1,310 @@
/*
* $Header: /HexenWorld/Siege/magicmis.hc 21 5/25/98 1:39p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\weapons\spllbook\spllbook.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\weapons\spllbook
$origin 0 0 0
$base BASE skin
$skin skin
$flags 0
//
$frame fire1 fire2 fire3 fire4 fire5
$frame fire6 fire7 fire8 fire9 fire10
$frame fire11 fire12
//
$frame go2mag01 go2mag02 go2mag03 go2mag04 go2mag05
$frame go2mag06 go2mag07 go2mag08 go2mag09 go2mag10
$frame go2mag11 go2mag12 go2mag13
$frame go2shd1 go2shd2
$frame go2shd3 go2shd4 go2shd5 go2shd6 go2shd7
$frame go2shd8 go2shd9
$frame go2shd10 go2shd11 go2shd12 go2shd13 go2shd14
//
$frame idle1 idle2 idle3 idle4 idle5
$frame idle6 idle7 idle8 idle9 idle10
$frame idle11 idle12 idle13 idle14 idle15
$frame idle16 idle17 idle18 idle19 idle20
$frame idle21 idle22
//
$frame mfire1 mfire2 mfire3 mfire4 mfire5
$frame mfire6 mfire7 mfire8
//
$frame midle01 midle02 midle03 midle04 midle05
$frame midle06 midle07 midle08 midle09 midle10
$frame midle11 midle12 midle13 midle14 midle15
$frame midle16 midle17 midle18 midle19 midle20
$frame midle21 midle22
//
$frame mselect01 mselect02 mselect03 mselect04 mselect05
$frame mselect06 mselect07 mselect08 mselect09 mselect10
$frame mselect11 mselect12 mselect13 mselect14 mselect15
$frame mselect16 mselect17 mselect18 mselect19 mselect20
//
$frame select1 select2 select3 select4 select5
$frame select6 select7
void MagicMissileTouch (void)
{
if(other.classname==self.classname&&other.owner==self.owner)
return;
self.level=FALSE;
if(other.takedamage)
{
if(!other.flags2&FL_ALIVE)
self.dmg/=3;//less damage to non-living things
T_Damage(other,self,self.owner,self.dmg);
}
T_RadiusDamage(self,self.owner,self.dmg,other);
// sound(self,CHAN_AUTO,"weapons/explode.wav",1,ATTN_NORM);
starteffect(CE_MAGIC_MISSILE_EXPLOSION,self.origin-self.movedir*8,0.05);
remove(self);
}
void MagicMissileThink()
{
HomeThink();
if(self.lifetime<time)
self.th_die();
else
thinktime self : self.homerate;
}
void FireMagicMissile (float offset)
{
//entity star1,star2;
vector spread;
if(self.classname=="monster_eidolon")
v_forward=self.v_angle;
else
makevectors(self.v_angle);
self.effects(+)EF_MUZZLEFLASH;
newmis=spawn();
newmis.classname="magic missile";
newmis.owner=self;
newmis.drawflags(+)SCALE_ORIGIN_CENTER;//|DRF_TRANSLUCENT;
newmis.movetype=MOVETYPE_FLYMISSILE;
newmis.solid=SOLID_BBOX;
newmis.drawflags(+)MLS_FIREFLICKER;
newmis.touch=MagicMissileTouch;
newmis.dmg=random(7,17);
newmis.speed=1000;
spread=normalize(v_right)*(offset*25);
newmis.velocity=normalize(v_forward)*newmis.speed + spread;
newmis.movedir=normalize(newmis.velocity);
newmis.avelocity_z=random(300,600);
newmis.level=TRUE;
setsize(newmis,'0 0 0','0 0 0');
if(self.classname=="monster_eidolon")
{
newmis.scale=0.75;
setorigin(newmis,self.origin+self.proj_ofs+v_forward*48+v_right*20);
weapon_sound(self, "eidolon/spell.wav");
// sound(self,CHAN_AUTO,"eidolon/spell.wav",1,ATTN_NORM);
}
else
{
newmis.scale=0.5;
setorigin(newmis,self.origin+self.proj_ofs+v_forward*8+v_right*7+'0 0 5');
weapon_sound(self, "necro/mmfire.wav");
// sound(newmis,CHAN_AUTO,"necro/mmfire.wav",1,ATTN_NORM);
}
if(self.artifact_active&ART_TOMEOFPOWER)
{
if(self.classname=="monster_eidolon")
{
newmis.enemy=self.enemy;
newmis.classname = "eidolon spell";
newmis.turn_time=3;
newmis.dmg=random(30,40);
}
else
{
newmis.turn_time=2;
newmis.dmg=random(30,35);
}
newmis.frags=TRUE;
newmis.veer=100;
newmis.homerate=0.2;
newmis.lifetime=time+5;
newmis.think=MagicMissileThink;
newmis.th_die = SUB_Remove;
newmis.hoverz=TRUE;
thinktime newmis : 0.1;
setmodel(newmis,"models/ball.mdl");
}
else
{
newmis.lifetime=time+5;
newmis.veer=100;
newmis.think=VeerThink;
thinktime newmis : 0.2;
setmodel(newmis,"models/ball.mdl");
}
// note to coders:
// the ball model is NOT necessarily used, the networking code
// will turn the ball into a tightly packed list of locations
// those locations will have the newmmis model displayed
// unless scale is set to .1 (for powered ice mace)
// eidolon's attack will also appear as a magic missile now
return;
}
void FireFlash ()
{
vector org;
makevectors(self.v_angle);
org = self.origin+self.proj_ofs+'0 0 5'+v_right*2+v_forward*6;
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_HWMISSILEFLASH);
WriteCoord(MSG_MULTICAST, org_x);
WriteCoord(MSG_MULTICAST, org_y);
WriteCoord(MSG_MULTICAST, org_z);
WriteCoord(MSG_MULTICAST, self.v_angle_x*-1);
WriteCoord(MSG_MULTICAST, self.v_angle_y);
multicast(org,MULTICAST_PHS_R);
}
void mmis_power()
{
if(self.attack_finished>time)
return;
FireFlash();
FireMagicMissile(-3);
FireMagicMissile(0);
FireMagicMissile(3);
self.greenmana-=10;
self.attack_finished=time+0.7;
}
void mmis_normal()
{
if(self.attack_finished>time)
return;
FireFlash();
FireMagicMissile(0);
self.greenmana-=2;
self.attack_finished=time+0.3;
}
/*======================
ACTION
select
deselect
ready loop
relax loop
fire once
fire loop
ready to relax(after short delay)
relax to ready(Fire delay? or automatic if see someone?)
=======================*/
void()magicmis_ready;
void() Nec_Mis_Attack;
void magicmis_fire (void)
{
if(self.button0&&self.weaponframe==$mfire5 &&!self.artifact_active&ART_TOMEOFPOWER)
self.weaponframe=$mfire5;
else
self.wfs = advanceweaponframe($mfire1,$mfire8);
self.th_weapon=magicmis_fire;
self.last_attack=time;
if(self.wfs==WF_CYCLE_WRAPPED||self.greenmana<2)//||(self.artifact_active&ART_TOMEOFPOWER&&self.bluemana<10))
magicmis_ready();
else if(self.weaponframe==$mfire5)// &&self.attack_finished<=time)
// if(self.artifact_active&ART_TOMEOFPOWER)
// mmis_power();
// else
mmis_normal();
}
void() Nec_Mis_Attack =
{
magicmis_fire();
thinktime self : 0;
};
void magicmis_jellyfingers ()
{
self.wfs = advanceweaponframe($midle01,$midle22);
self.th_weapon=magicmis_jellyfingers;
if(self.wfs==WF_CYCLE_WRAPPED)
magicmis_ready();
}
void magicmis_ready (void)
{
self.weaponframe=$midle01;
if(random()<0.1&&random()<0.3&&random()<0.5)
self.th_weapon=magicmis_jellyfingers;
else
self.th_weapon=magicmis_ready;
}
void magicmis_select (void)
{
self.wfs = advanceweaponframe($mselect01,$mselect20);
self.weaponmodel = "models/spllbook.mdl";
self.th_weapon=magicmis_select;
if(self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
magicmis_ready();
}
}
void magicmis_deselect (void)
{
self.wfs = advanceweaponframe($mselect20,$mselect01);
self.th_weapon=magicmis_deselect;
if(self.wfs==WF_CYCLE_WRAPPED)
W_SetCurrentAmmo();
}
void magicmis_select_from_bone (void)
{
self.wfs = advanceweaponframe($go2mag01,$go2mag13);
self.weaponmodel = "models/spllbook.mdl";
self.th_weapon=magicmis_select_from_bone;
if(self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
magicmis_ready();
}
}

79
math.hc Normal file
View File

@ -0,0 +1,79 @@
/*
* $Header: /HexenWorld/Siege/math.hc 3 5/25/98 1:39p Mgummelt $
*/
/*
* crandom() -- Returns a random number between -1 and 1.
*/
float crandom()
{
return random(-1,1);
}
float fexp(float base,float exponent)
{//MG
float exp_count;
exponent=rint(exponent);
if(exponent==0)
return 1;
if(exponent<0)
{
base=1/base;
exponent=fabs(exponent);
}
if(exponent==1)
return base;
exponent-=1;
while(exp_count<exponent)
{
exp_count+=1;
base=base*base;
}
return base;
}
float byte_me(float mult)
{//MG
float mult_count,base;
mult=rint(mult);
if(mult==0)
return 0;
if(mult==1)
return 1;
if(mult==-1)
return -1;
if(mult<0)
{
base= -1;
mult=fabs(mult);
}
else
base=1;
mult-=1;
while(mult_count<mult)
{
mult_count+=1;
base=base*2;
}
return base;
}
vector RandomVector (vector vrange)
{
vector newvec;
newvec_x=random(vrange_x,0-vrange_x);
newvec_y=random(vrange_y,0-vrange_y);
newvec_z=random(vrange_z,0-vrange_z);
return newvec;
}

951
medusa.hc Normal file
View File

@ -0,0 +1,951 @@
/*
* $Header: /HexenWorld/Siege/medusa.hc 4 5/25/98 1:39p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\monsters\medusa\medusa.hc
MG
==============================================================================
*/
// For building the model
$cd Q:\art\models\monsters\medusa
$origin 0 0 0
$base BASE-F skin
$skin skin
$skin SKIN2
$flags 0
//MEDUSA.MDL
//
$frame looklf1 looklf2 looklf3 looklf4 looklf5
$frame looklf6 looklf7 looklf8 looklf9 looklf10
$frame looklf11 looklf12 looklf13 looklf14 looklf15
$frame looklf16 looklf17 looklf18 looklf19 looklf20
$frame looklf21 looklf22 looklf23 looklf24 looklf25
$frame looklf26 looklf27 looklf28 looklf29
//
$frame lookrt1 lookrt2 lookrt3 lookrt4 lookrt5
$frame lookrt6 lookrt7 lookrt8 lookrt9 lookrt10
$frame lookrt11 lookrt12 lookrt13 lookrt14 lookrt15
$frame lookrt16 lookrt17 lookrt18 lookrt19 lookrt20
$frame lookrt21 lookrt22 lookrt23 lookrt24 lookrt25
$frame lookrt26 lookrt27 lookrt28 lookrt29
//
$frame medusa1 medusa2 medusa3 medusa4 medusa5
$frame medusa6 medusa7 medusa8 medusa9 medusa10
$frame medusa11 medusa12 medusa13 medusa14 medusa15
$frame medusa16 medusa17 medusa18 medusa19 medusa20
$frame medusa21 medusa22 medusa23 medusa24 medusa25
$frame medusa26 medusa27 medusa28 medusa29
//
$frame ratatt1 ratatt2 ratatt3 ratatt4 ratatt5
$frame ratatt6 ratatt7 ratatt8 ratatt9 ratatt10
$frame ratatt11 ratatt12 ratatt13 ratatt14 ratatt15
$frame ratatt16 ratatt17 ratatt18 ratatt19 ratatt20
$frame ratatt21 ratatt22 ratatt23 ratatt24 ratatt25
$frame ratatt26 ratatt27 ratatt28 ratatt29
//
$frame ratlft1 ratlft2 ratlft3 ratlft4 ratlft5
$frame ratlft6 ratlft7 ratlft8 ratlft9 ratlft10
$frame ratlft11 ratlft12 ratlft13 ratlft14 ratlft15
$frame ratlft16 ratlft17 ratlft18 ratlft19 ratlft20
$frame ratlft21 ratlft22 ratlft23 ratlft24 ratlft25
$frame ratlft26 ratlft27 ratlft28 ratlft29
//
$frame ratrit1 ratrit2 ratrit3 ratrit4 ratrit5
$frame ratrit6 ratrit7 ratrit8 ratrit9 ratrit10
$frame ratrit11 ratrit12 ratrit13 ratrit14 ratrit15
$frame ratrit16 ratrit17 ratrit18 ratrit19 ratrit20
$frame ratrit21 ratrit22 ratrit23 ratrit24 ratrit25
$frame ratrit26 ratrit27 ratrit28 ratrit29
//
$frame stand1 stand2 stand3 stand4 stand5
$frame stand6 stand7 stand8 stand9 stand10
$frame stand11 stand12 stand13 stand14 stand15
$frame stand16 stand17 stand18 stand19 stand20
$frame stand21 stand22 stand23 stand24 stand25
$frame stand26 stand27 stand28 stand29
//
$frame swipe1 swipe2 swipe3 swipe4 swipe5
$frame swipe6 swipe7 swipe8 swipe9 swipe10
$frame swipe11 swipe12 swipe13 swipe14 swipe15
$frame swipe16 swipe17 swipe18 swipe19 swipe20
$frame swipe21 swipe22 swipe23 swipe24 swipe25
$frame swipe26 swipe27 swipe28 swipe29
//MEDUSA2.MDL
$framevalue 0
//
$frame adecap1 adecap2 adecap3 adecap4 adecap5
$frame adecap6 adecap7 adecap8 adecap9 adecap10
$frame adecap11 adecap12 adecap13 adecap14 adecap15
$frame adecap16 adecap17 adecap18 adecap19 adecap20
$frame adecap21 adecap22 adecap23 adecap24 adecap25
$frame adecap26 adecap27 adecap28 adecap29 adecap30
$frame adecap31 adecap32 adecap33 adecap34 adecap35
$frame adecap36 adecap37 adecap38 adecap39 adecap40
$frame adecap41 adecap42 adecap43 adecap44 adecap45
$frame adecap46 adecap47 adecap48 adecap49 adecap50
$frame adecap51 adecap52 adecap53 adecap54 adecap55
$frame adecap56 adecap57 adecap58 adecap59 adecap60
$frame adecap61 adecap62 adecap63 adecap64 adecap65
$frame adecap66 adecap67 adecap68 adecap69 adecap70
$frame adecap71 adecap72 adecap73 adecap74 adecap75
$frame adecap76 adecap77 adecap78 adecap79 adecap80
$frame adecap81 adecap82 adecap83 adecap84 adecap85
$frame adecap86 adecap87 adecap88
//
$frame bdecap1 bdecap2 bdecap3 bdecap4 bdecap5
$frame bdecap6 bdecap7 bdecap8 bdecap9 bdecap10
$frame bdecap11 bdecap12 bdecap13 bdecap14 bdecap15
$frame bdecap16 bdecap17 bdecap18 bdecap19 bdecap20
$frame bdecap21 bdecap22 bdecap23 bdecap24 bdecap25
//
$frame death01 death02 death03 death04 death05
$frame death06 death07 death08 death09 death10
$frame death11 death12 death13 death14 death15
$frame death16 death17 death18 death19 death20
//
$frame pain1 pain2 pain3 pain4 pain5
$frame pain6 pain7 pain8 pain9 pain10
$frame pain11
//
$frame rnatlf1 rnatlf2 rnatlf3 rnatlf4 rnatlf5
$frame rnatlf6 rnatlf7 rnatlf8 rnatlf9 rnatlf10
$frame rnatlf11 rnatlf12 rnatlf13 rnatlf14 rnatlf15
$frame rnatlf16 rnatlf17 rnatlf18 rnatlf19 rnatlf20
$frame rnatlf21
//
$frame rnatrt1 rnatrt2 rnatrt3 rnatrt4 rnatrt5
$frame rnatrt6 rnatrt7 rnatrt8 rnatrt9 rnatrt10
$frame rnatrt11 rnatrt12 rnatrt13 rnatrt14 rnatrt15
$frame rnatrt16 rnatrt17 rnatrt18 rnatrt19 rnatrt20
$frame rnatrt21
//
$frame runatt1 runatt2 runatt3 runatt4 runatt5
$frame runatt6 runatt7 runatt8 runatt9 runatt10
$frame runatt11 runatt12 runatt13 runatt14 runatt15
$frame runatt16 runatt17 runatt18 runatt19 runatt20
$frame runatt21 runatt22 runatt23 runatt24 runatt25
$frame runatt26 runatt27 runatt28 runatt29
//====================================================================
float MEDUSA_LOOK = 0;
float MEDUSA_RATTLE = 1;
float MEDUSA_HEADBUTT = 2;
float MEDUSA_SNAKES = 3;
void(entity attacker,float total_damage)medusa_pain;
void()medusa_attack_right;
void()medusa_attack_left;
void()medusa_attack;
void(float action)MedusaSelectDir;
void medusa_check_use_model (string modelstring)
{
if(self.model!=modelstring)
{
setmodel(self,modelstring);
setsize(self,'-16 -16 0','16 16 56');
}
}
void snake_remove ()
{
particleexplosion(self.origin,random(176,192),30,20);
remove(self);
}
void() SnakeHit =
{
if(other==self.owner||(other.owner==self.owner&&other.classname=="snakearrow"))
return;
starteffect(CE_MEDUSA_HIT,self.origin);
sound(other,CHAN_AUTO,"medusa/hitplayr.wav",1,ATTN_NORM);
if(other.takedamage)
{
other.bloodloss=other.bloodloss+1;
SpawnPuff(other.origin,'0 0 0',self.dmg,other);
//Snakehit sprite
T_Damage(other,self,self.owner,self.dmg);
}
snake_remove();
};
void snake_fly ()
{
particle4(self.origin,10,256+random(176,192),PARTICLETYPE_GRAV,3);
if(random()<0.1)
CreateGreenSmoke(self.origin,'0 0 0',HX_FRAME_TIME);
HomeThink();
self.think=snake_fly;
thinktime self : 0.05;
}
void FireSnakeArrow (vector offset)
{
//FIXME: add a greenish particle trail?
self.last_attack=time;
makevectors(self.angles);
//identity
newmis=spawn();
newmis.owner=self;
newmis.classname="snakearrow";
//Movement and solidity
newmis.movetype=MOVETYPE_FLYMISSILE;
newmis.solid=SOLID_BBOX;
//rendering
newmis.abslight=0.3;
newmis.drawflags(+)MLS_ABSLIGHT;
//velocity
newmis.speed=500;
newmis.o_angle=normalize((self.goalentity.origin+self.goalentity.view_ofs) - (self.origin+self.view_ofs+offset));
newmis.velocity=newmis.o_angle*newmis.speed;
newmis.angles=vectoangles(newmis.velocity);
//impact
newmis.touch=SnakeHit;
newmis.dmg=3;
//behaviour
newmis.lockentity=newmis.enemy=self.enemy;//lockentity means it will never track any other ent
newmis.veer=50; //slight veering, random course modifications
newmis.th_die=snake_remove;
newmis.think=snake_fly;
newmis.hoverz=TRUE; //slow down on turns
thinktime newmis : 0;
//appearance,size, and position, always in this order!!!
setmodel(newmis,"models/snakearr.mdl");
setsize(newmis,'0 0 0','0 0 0');
setorigin(newmis,self.origin+self.view_ofs+v_forward*8+offset);
}
void MedusaAttacks (void)
{
vector source, org;
float damg;
if(self.monster_stage==MEDUSA_SNAKES)
{
self.attack_finished=time+2;
sound (self,CHAN_WEAPON,"medusa/attack2.wav",1,ATTN_NORM);
FireSnakeArrow(v_up*12);
FireSnakeArrow(v_right*12);
FireSnakeArrow(v_right*-12);
}
else
{
self.attack_finished=time+1;
makevectors (self.angles+self.angle_ofs);
source = self.origin+self.view_ofs;
traceline (source, source + v_forward*48, FALSE, self);
if (trace_fraction == 1.0)
return;
org = trace_endpos + (v_forward * 4);
sound (self, CHAN_WEAPON, "weapons/gauntht1.wav", 1, ATTN_NORM);
if (trace_ent.takedamage)
{
damg = random(10,18);
SpawnPuff (org, '0 0 0', 20,trace_ent);
T_Damage (trace_ent, self, self, damg);
//punchangle
// if(other.classname=="player")
// other.punchangle=???
}
else
{ // hit wall
SpawnPuff (trace_endpos, '0 0 0', 20,self);
medusa_pain(self,0);
}
}
}
void()medusa_attack_left = [++ $rnatlf1 .. $rnatlf21]
{
medusa_check_use_model("models/medusa2.mdl");
if(self.frame==$rnatlf21)
self.think=self.th_run;
else if(self.frame==$rnatlf4)
MedusaAttacks();
};
void()medusa_attack_right = [++ $rnatrt1 .. $rnatrt21]
{
medusa_check_use_model("models/medusa2.mdl");
if(self.frame==$rnatrt21)
self.think=self.th_run;
else if(self.frame==$rnatrt4)
MedusaAttacks();
};
void()medusa_attack = [++ $runatt1 .. $runatt29]
{
medusa_check_use_model("models/medusa2.mdl");
if(self.frame==$runatt29)
self.think= self.th_run;
else if(self.frame==$runatt12)
MedusaAttacks();
};
void()MedusaGazeLoop;
void MedusaGaze (vector org, vector destiny, entity loser) [++ $medusa1 .. $medusa29]
{
//Anim?
//sound, temp ent
self.last_attack=time;
if(!self.aflag)
{
sound (self,CHAN_WEAPON,"medusa/attack1.wav",1,ATTN_NORM);
self.aflag=TRUE;
}
medusa_check_use_model("models/medusa.mdl");
ai_face();
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_STREAM_GAZE);
WriteByte (MSG_BROADCAST, 1+STREAM_ATTACHED);
WriteByte (MSG_BROADCAST, 4);
WriteEntity (MSG_BROADCAST, self);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
WriteCoord (MSG_BROADCAST, destiny_x);
WriteCoord (MSG_BROADCAST, destiny_y);
WriteCoord (MSG_BROADCAST, destiny_z);
if(loser.health<=10&&!loser.artifact_active&ART_INVINCIBILITY)
{
sound(loser,CHAN_BODY,"medusa/stoned.wav",1,ATTN_NORM);
self.attack_finished=time+7;
loser.skin = GLOBAL_SKIN_STONE;
loser.think=loser.th_pain=loser.th_run=SUB_Null;
loser.attack_finished=loser.teleport_time=loser.pausetime = time+10000000000;
loser.nextthink=-1;
loser.th_die = chunk_death;
loser.thingtype = THINGTYPE_GREYSTONE;
loser.health = 10;
loser.touch = obj_push;
loser.flags(-)FL_FLY;
loser.flags(-)FL_SWIM;
if(loser.classname!="player")
loser.movetype = MOVETYPE_STEP;//step?
else
loser.o_angle=loser.v_angle;
loser.solid = SOLID_BBOX;
loser.artifact_active(+)ARTFLAG_STONED;
//Greying palette effect
}
else
{
T_Damage(loser,self,self,3);
if(loser.classname=="player"&&random()<0.2+skill/10+self.skin/5)
{
loser.o_angle=loser.v_angle;
loser.pausetime=time+random(0.05,0.3);
if(random()<0.5)
{
loser.attack_finished=time+random(0.05,0.3);
if(random()<0.5)
thinktime loser : 0.2;
}
}
}
if(lineofsight(self,loser)&&!loser.artifact_active&ARTFLAG_STONED)
{
self.goalentity=loser;
self.think=MedusaGazeLoop;
thinktime self : 0.1;
}
else
{
self.aflag=FALSE;
stopSound(self,CHAN_WEAPON);
//sound (self,CHAN_WEAPON,"misc/null.wav",1,ATTN_NORM);
self.attack_finished=time+2;
self.think=self.th_run;
thinktime self : 0;
}
}
void MedusaGazeLoop()
{
MedusaGaze(self.origin+self.view_ofs,self.goalentity.origin+self.goalentity.view_ofs,self.goalentity);
}
void MedusaSwipe () [++ $swipe1 .. $swipe29]
{
self.last_attack=time;
if(cycle_wrapped)
{
self.attack_finished=time+1;
self.think=self.th_run;
thinktime self : 0;
}
else if(self.frame==$swipe1)
{
sound(self,CHAN_VOICE,"medusa/sight.wav",1,ATTN_NORM);
sound(self,CHAN_BODY,"weapons/vorpswng.wav",1,ATTN_NORM);
}
else if(self.frame>=$swipe6 &&self.frame<=$swipe10)
{
makevectors(self.angles);
traceline(self.origin+'0 0 23',self.origin+'0 0 23'-v_forward*72+v_right*($swipe7 - self.frame)*10,FALSE,self);
if(trace_ent.takedamage)
{
T_Damage(trace_ent,self,self,7);
sound(trace_ent,CHAN_BODY,"weapons/met2flsh.wav",1,ATTN_NORM);
SpawnPuff(trace_endpos,'0 0 0',7,trace_ent);
trace_ent.velocity+=v_right*-200;
trace_ent.velocity_z+=100;
trace_ent.flags(-)FL_ONGROUND;
}
}
else if(self.frame>$swipe10)
ai_face();
}
float MedusaCheckAttack (void)
{
vector org,dir,destiny;
float r, loscheck1,loscheck2;
if(random()<0.5 - skill/10 - self.skin/5||self.enemy==world)
return FALSE;
org=self.origin+self.view_ofs;
if (time < self.attack_finished)
return FALSE;
if (!enemy_vis)
{
if(self.goalentity.classname=="waypoint")
{
if(visible2ent(self.enemy,self.goalentity))
{
MedusaSelectDir(MEDUSA_SNAKES);
return TRUE;
}
}
return FALSE;
}
if(!enemy_infront)
{
if(enemy_range==RANGE_MELEE)
{
MedusaSwipe();
return TRUE;
}
}
if (enemy_range == RANGE_FAR)
{
if (self.attack_state != AS_STRAIGHT)
self.attack_state = AS_STRAIGHT;
return FALSE;
}
// see if any entities are in the way of the shot
dir = self.enemy.origin + self.enemy.view_ofs;
traceline (org, dir, FALSE, self);
if (trace_ent != self.enemy)
{ // don't have a clear shot, so move to a side
if (self.attack_state != AS_SLIDING)
self.attack_state == AS_SLIDING;
return FALSE;
}
else
self.attack_state == AS_STRAIGHT;
destiny = self.enemy.origin+self.enemy.view_ofs;
//FIXME: account for z difference
loscheck1=lineofsight(self.enemy,self);
loscheck2=lineofsight(self,self.enemy);
r=random();
if(!self.enemy.artifact_active&ARTFLAG_STONED&&loscheck1&& (loscheck2|| (r<0.1&&infront_of_ent(self,self.enemy)) ) )
{
MedusaGaze(org,destiny,self.enemy);
return TRUE;
}
if (enemy_range == RANGE_MELEE)
{
MedusaSelectDir(MEDUSA_HEADBUTT);
return TRUE;
}
else if (enemy_range == RANGE_NEAR)
r = 0.2;
else if (enemy_range == RANGE_MID)
r = 0.3;
if (random () < r)
{
MedusaSelectDir(MEDUSA_SNAKES);
return TRUE;
}
return FALSE;
}
//====================================================================
void()medusa_look_right;
void MedusaHeadTouch ()
{
if(self.velocity!='0 0 0'&&!other.flags2&FL_ALIVE)
sound(self,CHAN_AUTO,"weapons/hithurt2.wav",1,ATTN_NORM);
}
void()MedusaHeadDying;
void MedusaHeadDead () [++ 0 .. 45]
{
thinktime self : 0.1;
ai_face();
if(self.frame==20)
sound(self,CHAN_VOICE,"medusa/sight.wav",0.5,ATTN_NORM);
else if(self.frame==45)
{
self.aflag=TRUE;
self.think=MedusaHeadDying;
}
}
void MedusaHeadDying () [++ 46 .. 105]
{
if(pointcontents(self.origin)==CONTENT_SOLID)
{
chunk_death();
return;
}
if(self.velocity=='0 0 0')
if(!self.aflag)
{
if(self.angles_x<-10||self.angles_x>10)
self.angles_x=0;
if(self.angles_z<-10||self.angles_z>10)
self.angles_z=0;
self.solid = SOLID_BBOX;
self.think=MedusaHeadDead;
thinktime self : 0;
}
else if(self.frame==105)
{
self.skin=1;
self.think=init_corpseblink;
thinktime self : 5;
}
}
void MedusaThrowHead ()
{
newmis = spawn();
newmis.owner=self;
newmis.enemy=newmis.goalentity=self.enemy;
newmis.yaw_speed=3;
setmodel (newmis, self.headmodel);
self.headmodel="";
setsize (newmis, '-3 -3 -3', '3 3 3');
setorigin(newmis,self.absmax - '0 0 15');
newmis.velocity = randomv('-200 -200 200','200 200 600');
newmis.movetype = MOVETYPE_BOUNCE;
if(pointcontents(newmis.origin)==CONTENT_SOLID)
newmis.solid = SOLID_NOT;
else
newmis.solid = SOLID_BBOX;
newmis.takedamage=DAMAGE_YES;
newmis.thingtype=self.thingtype;
newmis.th_die=chunk_death;
newmis.touch=MedusaHeadTouch;
newmis.health=25;
newmis.scale=2;
newmis.avelocity_x = random(600);
newmis.avelocity_y = random(600);
newmis.avelocity_z = random(600);
newmis.think=MedusaHeadDying;
thinktime newmis : 0;
}
void medusa_decap_drop ()[++ $bdecap1 .. $bdecap25]
{
if(self.frame==$bdecap9)
sound(self,CHAN_BODY,"player/land.wav",1,ATTN_NORM);
else if(self.frame==$bdecap25)
MakeSolidCorpse();
}
void medusa_decap_loop ()[++ $adecap1..$adecap88]
{
if(random()<0.5)
self.angles_y+=random(-3,3);
walkmove(self.angles_y,self.speed*random(),FALSE);
if(random()<0.2)
{
sound (self, CHAN_VOICE, "misc/decomp.wav", 0.3, ATTN_NORM);
SpawnPuff (self.origin+'0 0 56', '0 0 35',5,self);
}
if(self.frame==$adecap48)
sound(self,CHAN_BODY,"medusa/rattle.wav",1,ATTN_NORM);
if(cycle_wrapped)
{
self.think=medusa_decap_drop;
thinktime self : 0;
}
}
void medusa_decap_init ()
{
float throwdist;
throwdist=self.health;
ThrowGib("models/medsnake.mdl",throwdist);
ThrowGib("models/medsnake.mdl",throwdist);
ThrowGib("models/medsnake.mdl",throwdist);
sound(self,CHAN_VOICE,"player/gib2.wav",1,ATTN_NORM);
MedusaThrowHead();
SpawnPuff (self.origin+'0 0 56', '0 0 35',5,self);
medusa_decap_loop();
}
void medusa_die (void) [++ $death01..$death20]
{
medusa_check_use_model("models/medusa2.mdl");
if(self.decap)
medusa_decap_init();
else if(self.health<=-80)
{
MedusaThrowHead();
chunk_death();
}
else
{
if(self.frame==$death20)
MakeSolidCorpse();
else if(self.frame==$death01)
sound(self,CHAN_VOICE,"medusa/death.wav",1,ATTN_NORM);
}
}
void medusa_pain_anim () [++ $pain1 .. $pain11]
{
//sound
medusa_check_use_model("models/medusa2.mdl");
if (cycle_wrapped)
{
thinktime self : 0;
self.think=self.th_run;
}
else if(self.frame==$pain1)
sound(self,CHAN_VOICE,"medusa/pain.wav",1,ATTN_NORM);
}
void medusa_pain (entity attacker,float total_damage)
{
if(random()<0.6&&total_damage<50&&attacker!=self)
return;
medusa_pain_anim();
}
void()medusa_look_left = [++ $looklf1 .. $looklf29]
{
medusa_check_use_model("models/medusa.mdl");
if(self.oldthink==self.th_run)
ai_run(self.speed);
else
{
if(self.oldthink==self.th_stand)
ai_stand();
else if(self.oldthink==self.th_walk)
ai_walk(5);
}
if(cycle_wrapped)
{
self.think=self.oldthink;
if(self.think!=self.th_run)
if(random()<0.2)
self.think=medusa_look_right;
thinktime self : 0;
}
};
void()medusa_look_right = [++ $lookrt1 .. $lookrt29]
{
medusa_check_use_model("models/medusa.mdl");
if(self.oldthink==self.th_run)
ai_run(self.speed);
else
{
if(self.oldthink==self.th_stand)
ai_stand();
else if(self.oldthink==self.th_walk)
ai_walk(5);
}
if(cycle_wrapped)
{
self.think=self.oldthink;
if(self.think!=self.th_run)
if(random()<0.2)
self.think=medusa_look_left;
thinktime self : 0;
}
};
void()medusa_rattle_left = [++ $ratlft1 .. $ratlft29]
{
//sound
medusa_check_use_model("models/medusa.mdl");
if(cycle_wrapped)
{
thinktime self : 0;
self.think=self.th_run;
}
};
void()medusa_rattle_right = [++ $ratrit1 .. $ratrit29]
{
//sound
medusa_check_use_model("models/medusa.mdl");
if(cycle_wrapped)
{
thinktime self : 0;
self.think=self.th_run;
}
};
void()medusa_rattle = [++ $ratatt1 .. $ratatt29]
{
//sound
medusa_check_use_model("models/medusa.mdl");
if(cycle_wrapped)
{
thinktime self : 0;
self.think=self.th_run;
}
};
void MedusaSelectDir (float action)
{
vector enemy_dir;
float dot;
medusa_check_use_model("models/medusa.mdl");
self.monster_stage=action;
if(action>=MEDUSA_HEADBUTT)
{
self.last_attack=time;
sound (self,CHAN_VOICE,"medusa/hiss.wav",1,ATTN_NORM);
medusa_check_use_model("models/medusa2.mdl");
}
else if(action==MEDUSA_RATTLE)
sound(self,CHAN_BODY,"medusa/rattle.wav",1,ATTN_NORM);
makevectors(self.angles);
enemy_dir=normalize(self.enemy.origin-self.origin);
dot=v_right*enemy_dir;
if(dot>0.3)
{
self.angle_ofs_y=-90;
if(action>=MEDUSA_HEADBUTT)
self.think=medusa_attack_right;
else if(action==MEDUSA_RATTLE)
self.think=medusa_rattle_right;
else
self.think=medusa_look_right;
}
else if(dot<-0.3)
{
self.angle_ofs_y=-90;
if(action>=MEDUSA_HEADBUTT)
self.think=medusa_attack_left;
else if(action==MEDUSA_RATTLE)
self.think=medusa_rattle_left;
else
self.think=medusa_look_left;
}
else
{
self.angle_ofs_y=0;
if(action>=MEDUSA_HEADBUTT)
self.think=medusa_attack;
else if(action==MEDUSA_RATTLE)
self.think=medusa_rattle;
else
return;
}
thinktime self : 0;
}
void medusa_hunt () [++ $medusa1 .. $medusa29]
{
medusa_check_use_model("models/medusa.mdl");
if(random()<0.1)
ai_run(0);
else
ai_run(self.speed);
if(!enemy_vis)
if(random()<0.1&&random()<0.5)
if(random()<0.5)
MedusaSelectDir(MEDUSA_RATTLE);
else
{
self.oldthink=self.th_run;
MedusaSelectDir(MEDUSA_LOOK);
}
}
void medusa_walk () [++ $medusa1 .. $medusa29]
{
medusa_check_use_model("models/medusa.mdl");
self.monster_awake=FALSE;
if(random()<0.1)
ai_walk(0);
else
ai_walk(5);
if(cycle_wrapped)
{
if(random()<0.3)
{
self.oldthink=self.th_walk;
if(random()<0.5)
{
thinktime self : 0;
self.think=medusa_look_left;
}
else
{
thinktime self : 0;
self.think=medusa_look_right;
}
}
}
// MedusaCheckAttack();
if(random()<0.1&&random()<0.5)
sound(self,CHAN_VOICE,"medusa/hiss.wav",1,ATTN_NORM);
}
void medusa_stand () [++$stand1..$stand29]
{
medusa_check_use_model("models/medusa.mdl");
self.monster_awake=FALSE;
ai_stand();
if(random()<0.1)
{
self.oldthink=self.th_stand;
if(random()<0.5)
{
thinktime self : 0;
self.think=medusa_look_left;
}
else
{
thinktime self : 0;
self.think=medusa_look_right;
}
}
if(random()<0.1&&random()<0.3)
sound(self,CHAN_VOICE,"medusa/hiss.wav",1,ATTN_NORM);
}
/*QUAKED monster_medusa_green (1 0.3 0) (-16 -16 0) (16 16 56) AMBUSH STUCK JUMP PLAY_DEAD DORMANT
The medusa monster with its nasty sharp pointy teeth
-------------------------FIELDS-------------------------
--------------------------------------------------------
*/
void monster_medusa_green (void)
{
if (deathmatch)
{
remove(self);
return;
}
precache_model2("models/medusa.mdl");
precache_model2("models/medusa2.mdl");
precache_model2("models/snakearr.mdl");
precache_model2("models/medhit.spr");
precache_model2("models/medhead.mdl");
precache_model2("models/medsnake.mdl");
precache_sound2("medusa/rattle.wav");
precache_sound2("medusa/hiss.wav");
precache_sound2("medusa/sight.wav");
precache_sound2("medusa/attack1.wav");
precache_sound2("medusa/attack2.wav");
precache_sound2("medusa/pain.wav");
precache_sound2("medusa/death.wav");
precache_sound2("medusa/stoned.wav");
precache_sound2("medusa/hitplayr.wav");
// if(random()<0.5)
// self.skin=1;
self.headmodel="models/medhead.mdl";
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
self.takedamage=DAMAGE_YES;
self.thingtype=THINGTYPE_FLESH;
self.monsterclass=CLASS_LEADER;
self.mintel = 20;//Very smart- excellent tracker
self.mass = 15;
self.view_ofs = '0 0 53';
self.speed=5;
self.yaw_speed = 5;
self.classname="monster_medusa";
self.health = 700;
self.experience_value = 500;
self.th_stand=medusa_stand;
self.th_run=medusa_hunt;
self.th_walk=medusa_walk;
self.th_die=medusa_die;
self.th_pain=medusa_pain;
self.th_missile=medusa_rattle;
self.th_melee=medusa_attack;
setmodel (self, "models/medusa.mdl");
setsize(self, '-28 -28 0', '28 28 56');
self.hull=HULL_PLAYER;
walkmonster_start();
}
void monster_medusa (void)
{
monster_medusa_green();
}
/*QUAKED monster_medusa_red (1 0.3 0) (-16 -16 0) (16 16 56) AMBUSH STUCK JUMP PLAY_DEAD DORMANT
The medusa monster with its nasty sharp pointy teeth
-------------------------FIELDS-------------------------
--------------------------------------------------------
*/
void monster_medusa_red (void)
{
// self.skin=1;
monster_medusa_green();
self.health = 250;
self.experience_value = 125;
}

0
medusa2.hc Normal file
View File

10
messages.hc Normal file
View File

@ -0,0 +1,10 @@
/*
* $Header: /HexenWorld/Siege/messages.hc 3 5/25/98 1:39p Mgummelt $
*/
void () message_init =
{
time = time;
};

451
meteor.hc Normal file
View File

@ -0,0 +1,451 @@
/*
* $Header: /HexenWorld/Siege/meteor.hc 34 5/25/98 1:39p Mgummelt $
*/
/*
==============================================================================
Q:\art\models\weapons\meteor\final\meteor.hc
==============================================================================
*/
// For building the model
$cd Q:\art\models\weapons\meteor\final
$origin 0 0 0
$base BASE skin
$skin skin
$flags 0
//
$frame idle
//
$frame Select1 Select2 Select3 Select4 Select5
$frame Select6 Select7 Select8 Select9 Select10
$frame Select11 Select12 Select13 Select14 Select15
$frame Select16 Select17 Select18
//
$frame fire1 fire2 fire3 fire4 fire5
$frame fire6 fire7 fire8 fire9
void MeteoriteFizzle (void)
{
CreateWhiteSmoke(self.origin,'0 0 8',HX_FRAME_TIME * 2);
remove(self);
}
void ByeByeMeteor(void)
{
remove(self);
}
void MeteorExplode(void)
{
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_METEORHIT);
WriteCoord (MSG_MULTICAST, self.origin_x - self.movedir_x * 8);
WriteCoord (MSG_MULTICAST, self.origin_y - self.movedir_y * 8);
WriteCoord (MSG_MULTICAST, self.origin_z - self.movedir_z * 8);
multicast(self.origin,MULTICAST_PHS_R);
T_RadiusDamage (self, self.owner, 80.0, world);
remove(self);
}
void MeteorTouch (void)
{
if(other.controller==self.owner)
return;
if(other.takedamage&&other.health)
{
T_Damage(other,self,self.owner,self.dmg);
if((other.flags&FL_CLIENT||other.flags&FL_MONSTER)&&other.mass<200)
{
vector hitdir;
hitdir=self.o_angle*300;
hitdir_z+=150;
if(hitdir_z<0)
hitdir_z=0;
other.velocity=hitdir;
other.flags(-)FL_ONGROUND;
}
}
self.dmg=90;
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_METEORHIT);
WriteCoord (MSG_MULTICAST, self.origin_x - self.movedir_x * 8);
WriteCoord (MSG_MULTICAST, self.origin_y - self.movedir_y * 8);
WriteCoord (MSG_MULTICAST, self.origin_z - self.movedir_z * 8);
multicast(self.origin,MULTICAST_PHS_R);
T_RadiusDamage (self, self.owner, self.dmg, other);
remove(self);
}
void MeteorThink(void)
{
self.movedir = normalize(self.velocity);
self.angles = vectoangles(self.movedir);
traceline(self.origin, self.origin + self.movedir * 300.0, FALSE, self);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_METEOR);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
WriteByte (MSG_MULTICAST, self.angles_y*256.0/360.0);
WriteByte (MSG_MULTICAST, self.angles_x*256.0/360.0);
WriteByte (MSG_MULTICAST, trace_fraction * 100);
multicast(self.origin,MULTICAST_PVS);
thinktime self : 0.3;
if (self.lifetime < time)
SUB_Remove();
}
void FireMeteor (string type)
{
vector org;
entity meteor;
meteor=spawn();
setmodel(meteor,"models/tempmetr.mdl");
meteor.th_die=MultiExplode;
meteor.takedamage = DAMAGE_NO;
meteor.health = 9999;
if(self.classname=="player")
{
self.greenmana-=8;
self.velocity+=normalize(v_forward)*-300;//include mass
self.flags(-)FL_ONGROUND;
}
meteor.classname="meteor";
self.punchangle_x = -6;
weapon_sound(self, "crusader/metfire.wav");
self.attack_finished=time + 0.7;
self.effects(+)EF_MUZZLEFLASH;
makevectors(self.v_angle);
meteor.speed=1000;
meteor.o_angle=normalize(v_forward);
meteor.velocity=meteor.o_angle*meteor.speed;
meteor.veer=30;
meteor.lifetime=time + 5;
meteor.dmg=65;
meteor.movetype=MOVETYPE_FLYMISSILE;
org=self.origin+self.proj_ofs+v_forward*12;
setsize(meteor,'0 0 0', '0 0 0');
meteor.movedir = normalize(meteor.velocity);
meteor.effects(+)EF_NODRAW;
meteor.drawflags(+)MLS_FIREFLICKER;//|MLS_ABSLIGHT;
if(self.classname=="tornato")
meteor.owner=self.controller;
else if(self.classname=="meteor")
meteor.owner=self.owner;
else
meteor.owner=self;
meteor.controller=self;
meteor.solid=SOLID_BBOX;
meteor.touch=MeteorTouch;
setorigin(meteor,org);
entity oldself;
oldself = self;
self = meteor;
meteor.think = MeteorThink;
meteor.think();
self = oldself;
}
void MegaMeteorIgnite(void)
{
float i;
vector startPos, endPos;
entity hurtGuy;
if(self.health == 6)
{ // must've timed out or been in-air ignited...
self.health = 5;
}
if(self.health == 5)
{
traceline(self.origin, self.origin + '0 0 -2000', FALSE, self);
// only make meteors on the first frame
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_METEOR_CRUSH);
WriteCoord (MSG_MULTICAST, self.origin_x - self.movedir_x * 8);
WriteCoord (MSG_MULTICAST, self.origin_y - self.movedir_y * 8);
WriteCoord (MSG_MULTICAST, self.origin_z - self.movedir_z * 8);
WriteLong (MSG_MULTICAST, 2000 * trace_fraction);
multicast(self.origin,MULTICAST_PHS_R);
self.effects (+) EF_NODRAW;
self.think = MegaMeteorIgnite;
self.velocity_x = 0;
self.velocity_y = 0;
self.velocity_z = 0;
}
i = 6;
while(i > 0)
{
startPos = self.origin;
startPos_x += random(-80, 80);
startPos_y += random(-80, 80);
endPos = startPos;
endPos_x += random(-90, 90)*4;
endPos_y += random(-90, 90)*4;
endPos_z += random(-1800, -1600)*4;
// simulate the meteor going through the air; simulate the meteor's width
traceline (startPos, endPos, FALSE, self.owner);
// if(trace_ent.takedamage)
// {
// T_Damage (trace_ent, self, self.owner, 40);
// }
hurtGuy=findradius(trace_endpos,90);
while(hurtGuy)
{
T_Damage(hurtGuy, self, self, 50 * (1.0 - (vlen(hurtGuy.origin - trace_endpos)/90)));
hurtGuy=hurtGuy.chain;
}
i-=1;
}
self.health -= 1;
if(self.health == 0)
{
remove(self);
}
else
{
self.nextthink = time + 0.05;
}
}
void MegaMeteorTouch(void)
{
if(other == self.owner)
{
return;
}
if((other != world)&&(self.health != 6))
{
return;
}
if(self.health == 6)
{
self.health = 5;
self.velocity_x = 0;
self.velocity_y = 0;
self.velocity_z = 1600;
self.lifetime = time + 0.5;
self.flags(-)FL_ONGROUND;
}
else
{
MegaMeteorIgnite();
}
}
void MegaMeteorThink(void)
{
if(self.lifetime < time)
{
self.health = 5;
MegaMeteorIgnite();
return;
//self.health = 5;
}
/* if((self.owner.button0)&&(self.lifetime - time < 4.7))
{ // if the owner tries firing again and the projectile's been around for at least .3 of a second...
self.health = 5;
}*/
if(self.health == 5)
{
self.velocity_x = 0;
self.velocity_y = 0;
self.velocity_z = 1600;
self.flags(-)FL_ONGROUND;
}
self.movedir = normalize(self.velocity);
self.angles = vectoangles(self.movedir);
traceline(self.origin, self.origin + self.velocity*.3, TRUE, self);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_MEGAMETEOR);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
WriteByte (MSG_MULTICAST, self.angles_y*256.0/360.0);
WriteByte (MSG_MULTICAST, self.angles_x*256.0/360.0);
WriteByte (MSG_MULTICAST, trace_fraction * 100);
multicast(self.origin,MULTICAST_PVS);
thinktime self : 0.3;
}
void FireMeteorTornado(void)
{
vector org;
entity meteor;
meteor=spawn();
setmodel(meteor,"models/tempmetr.mdl");
meteor.scale = 2.3;
if(self.classname=="player")
{
self.greenmana-=16;
self.velocity+=normalize(v_forward)*-100;//include mass
self.flags(-)FL_ONGROUND;
}
meteor.classname="meteor";
self.punchangle_x = -6;
weapon_sound(self, "crusader/metfire.wav");
self.attack_finished=time + 1.5;
self.effects(+)EF_MUZZLEFLASH;
makevectors(self.v_angle);
meteor.speed=1600;
meteor.o_angle=normalize(v_forward);
meteor.velocity=meteor.o_angle*meteor.speed;
meteor.lifetime=time + 5;
meteor.th_die=MegaMeteorIgnite;
meteor.nextthink = time + 0.1;
meteor.dmg=60;
meteor.movetype=MOVETYPE_FLYMISSILE;
meteor.health = 6;
setsize(meteor,'0 0 0', '0 0 0');
meteor.movedir = normalize(meteor.velocity);
// meteor.effects(+)EF_BRIGHTLIGHT|EF_TORNADO_EFFECT;
meteor.effects(+)EF_NODRAW;
meteor.drawflags(+)MLS_FIREFLICKER|DRF_TRANSLUCENT;//|MLS_ABSLIGHT;
meteor.owner=self;
//meteor.solid=SOLID_PHASE;
meteor.solid=SOLID_BBOX;
meteor.touch=MegaMeteorTouch;
org=self.origin+self.proj_ofs+v_forward*12;
setorigin(meteor,org);
entity oldself;
oldself = self;
self = meteor;
meteor.think = MegaMeteorThink;
meteor.think();
self = oldself;
}
void()meteor_ready_loop;
void() Cru_Met_Attack;
void meteor_power_fire (void)
{
self.wfs = advanceweaponframe($fire1,$fire9);
self.th_weapon=meteor_power_fire;
if(self.weaponframe==$fire2 && self.attack_finished<=time)
{
FireMeteorTornado();
}
if(self.wfs==WF_CYCLE_WRAPPED)
{
self.last_attack=time;
meteor_ready_loop();
}
}
void meteor_fire (void)
{
self.wfs = advanceweaponframe($fire1,$fire9);
self.th_weapon=meteor_fire;
if((!self.button0||self.attack_finished>time)&&self.wfs==WF_CYCLE_WRAPPED)
{
self.last_attack=time;
meteor_ready_loop();
}
else if(self.weaponframe==$fire1 &&self.attack_finished<=time)
FireMeteor("meteor");
}
void() Cru_Met_Attack =
{
if(self.artifact_active&ART_TOMEOFPOWER)
self.th_weapon=meteor_power_fire;
else
self.th_weapon=meteor_fire;
thinktime self : 0;
};
void meteor_ready_loop (void)
{
self.weaponframe = $idle;
self.th_weapon=meteor_ready_loop;
}
void meteor_select (void)
{
//go to ready loop, not relaxed?
self.wfs = advanceweaponframe($Select1,$Select16);
self.weaponmodel = "models/meteor.mdl";
self.th_weapon=meteor_select;
self.last_attack=time;
if(self.wfs==WF_CYCLE_WRAPPED)
{
self.attack_finished = time - 1;
meteor_ready_loop();
}
}
void meteor_deselect (void)
{
self.wfs = advanceweaponframe($Select16,$Select1);
self.th_weapon=meteor_deselect;
if(self.wfs==WF_CYCLE_WRAPPED)
W_SetCurrentAmmo();
}

1623
mezzoman.hc Normal file

File diff suppressed because it is too large Load Diff

253
mirage.hc Normal file
View File

@ -0,0 +1,253 @@
/*
* $Header: /HexenWorld/Siege/Mirage.hc 3 5/25/98 1:39p Mgummelt $
*/
/*
==============================================================================
MIRAGE
==============================================================================
*/
$cd id1/models/player_4
$origin 0 -6 24
$base base
$skin skin
$frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
/*
==============================================================================
MIRAGE FRAMES
==============================================================================
*/
void ai_mirage(float dist);
void() mirage_run1 =[ $axrun1, mirage_run2 ]
{
if(time > self.ltime)
{
self.owner.holo_engaged = 0;
remove(self);
return;
}
if(time + 3 > self.ltime)
self.model = string_null;
ai_mirage(11);
};
void() mirage_run2 =[ $axrun2, mirage_run3 ] {ai_mirage(8);};
void() mirage_run3 =[ $axrun3, mirage_run4 ]
{
if(time + 3 > self.ltime)
self.model = "models/player.mdl";
ai_mirage(10);
};
void() mirage_run4 =[ $axrun4, mirage_run5 ] {ai_mirage(10);};
void() mirage_run5 =[ $axrun5, mirage_run6 ] {ai_mirage(8);};
void() mirage_run6 =[ $axrun6, mirage_run1 ] {ai_mirage(15);};
/*
* ai_mirage() -- The so-called "intelligence" of the Mirage.
*/
void ai_mirage(float dist)
{
local vector delta;
local float axis;
local float direct, ang_rint, ang_floor, ang_ceil;
movedist = dist;
if(self.enemy.health <= 0)
{
self.enemy = world;
if(self.oldenemy.health > 0)
{
self.enemy = self.oldenemy;
HuntTarget();
}
else {
self.th_run();
return;
}
}
self.show_hostile = time + 1; // wake up monsters
enemy_vis = visible(self.enemy);
if(enemy_vis)
self.search_time = time + 5;
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(CheckAnyAttack())
// return; // beginning a fake attack
if(self.attack_state == AS_SLIDING)
{
ai_run_slide();
return;
}
movetogoal(dist);
}
/*
* remove_mirage() -- Removes the Mirage belonging to self from the world.
*/
void remove_mirage()
{
local entity mirage;
mirage = world;
while(mirage.owner != self)
{
mirage = find(mirage, classname, "mirage");
if(mirage == world)
{
bprint("Error: Mirage not found\n");
return;
}
}
remove(mirage);
bprint("Mirage disengaged\n");
if(time + 0.5 > mirage.ltime)
self.holo_engaged = 0;
else
self.holo_engaged = mirage.ltime - time;
}
/*
* init_mirage() -- Sets the Mirage entity fields after spawning.
*/
void init_mirage()
{
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_STEP;
setmodel(self, self.owner.model);
setsize(self, '-16 -16 -24', '16 16 40');
self.health = 666;
self.weapon = IT_SHOTGUN;
self.ltime = time + self.owner.holo_engaged;
self.th_stand = mirage_run1;
self.th_walk = mirage_run1;
self.th_run = mirage_run1;
self.classname = "mirage";
self.takedamage = DAMAGE_NO;
self.angles = self.owner.angles;
self.yaw_speed = 20;
self.proj_ofs=self.view_ofs = '0 0 25';
setorigin(self, self.owner.origin);
FindTarget();
self.pathentity = self.goalentity;
self.owner.holo_engaged += 100;
bprint("Mirage engaged\n");
mirage_run1();
}
/*
* Mirage() -- Handles requests to use the Mirage.
*/
void Mirage()
{
local entity mirage;
if(self.classname != "player")
return;
if(self.holo_engaged == 0) /* Mirage ran out */
bprint("Mirage not available\n");
else if(self.holo_engaged >= 100) /* Mirage is engaged */
remove_mirage();
else { /* Mirage isn't engaged */
mirage = spawn();
mirage.owner = self;
mirage.nextthink = time + 0.05;
mirage.think = init_mirage;
}
}
/*QUAK-ED item_mirage (0 0 0) (-8 -8 -8) (8 8 8) FLOATING
Gives a player ability to use a Mirage, similar to the "Holoduke" sprite.
Each item is worth 15 seconds.
-------------------------FIELDS-------------------------
--------------------------------------------------------
*/
/*
void item_mirage_touch()
{
local entity mirage;
if(other.classname != "player")
return;
if(other.health <= 0)
return;
remove(self);
sound(other, CHAN_VOICE, "items/artpkup.wav", 1, ATTN_NORM);
stuffcmd(other, "bf");
bprint("Got Mirage");
other.holo_engaged += 15;
if(other.holo_engaged >= 115)
{
while(mirage.owner != other)
{
mirage = find(mirage, classname, "mirage");
if(mirage == world)
return;
}
mirage.model = "models/player.mdl";
mirage.ltime += 15;
}
else if(other.holo_engaged > 100)
other.holo_engaged = 100;
}
void item_mirage()
{
precache_model("models/mirage.mdl");
setmodel(self, "models/mirage.mdl");
self.touch = item_mirage_touch;
StartItem();
}

Some files were not shown because too many files have changed in this diff Show More