Files
quakemapping/mod_xj19/my_progs/mon_gargoyle.qc
2020-01-01 23:35:17 +01:00

578 lines
24 KiB
Plaintext

/*==============================================================================
GARGOYLE / IMP (Hexen2 Model)
==============================================================================*/
// Fall on back to ground
$frame death1 death2 death3 death4 death5 death6 death7 death8
$frame death9 death10 death11 death12 death13 death14
// Single attack routine, fling fireball
$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15 attack16
$frame attack17 attack18 attack19 attack20 attack21
// Classic idle
$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8
$frame fly9 fly10 fly11 fly12 fly13 fly14 fly15 fly16
$frame fly17 fly18 fly19 fly20
// Special minion grow animation
// Removed excessive frames (0.05 timing)
$frame grow1 grow2 grow3 grow4 grow5 grow6 grow7 grow8 grow9 grow10
// Move from perch to flying (can be reversed)
$frame flyup1 flyup2 flyup3 flyup4 flyup5 flyup6 flyup7 flyup8
$frame flyup9 flyup10 flyup11 flyup12 flyup13 flyup14 flyup15 flyup16
$frame flyup17 flyup18 flyup19 flyup20 flyup21 flyup22 flyup23
// Idle animation for perching (sitting down)
$frame perch1 perch2 perch3 perch4 perch5 perch6 perch7 perch8
$frame perch9 perch10 perch11 perch12 perch13 perch14 perch15 perch16
$frame perch17 perch18 perch19 perch20 perch21 perch22 perch23 perch24
// Going into a nosedive
$frame swoop1 swoop2 swoop3 swoop4 swoop5 swoop6 swoop7 swoop8
$frame swoop9 swoop10 swoop11 swoop12 swoop13 swoop14 swoop15 swoop16
$frame swoop17 swoop18 swoop19 swoop20
// Swooshing through the air!
$frame swooploop1 swooploop2 swooploop3 swooploop4
// Nose up, back to fly idling
$frame swoopend1 swoopend2 swoopend3 swoopend4 swoopend5 swoopend6 swoopend7 swoopend8
$frame swoopend9 swoopend10 swoopend11 swoopend12 swoopend13 swoopend14 swoopend15
// Alternative to stop swooping
$frame swoopout1 swoopout2 swoopout3 swoopout4 swoopout5 swoopout6 swoopout7 swoopout8
$frame swoopout9 swoopout10 swoopout11 swoopout12 swoopout13 swoopout14 swoopout15
void() gargoylewings =
{ sound(self, CHAN_ITEM, "gargoyle/wings1.wav", 1, ATTN_IDLE); };
void() garg_fbfinish;
//======================================================================
void() garg_idle1 =[ $fly2, garg_idle2 ] {monster_idle_sound();ai_stand();};
void() garg_idle2 =[ $fly4, garg_idle3 ] {ai_stand();};
void() garg_idle3 =[ $fly6, garg_idle4 ] {gargoylewings();ai_stand();};
void() garg_idle4 =[ $fly8, garg_idle5 ] {ai_stand();};
void() garg_idle5 =[ $fly10, garg_idle6 ] {ai_stand();};
void() garg_idle6 =[ $fly12, garg_idle7 ] {ai_stand();};
void() garg_idle7 =[ $fly14, garg_idle8 ] {ai_stand();};
void() garg_idle8 =[ $fly16, garg_idle9 ] {ai_stand();};
void() garg_idle9 =[ $fly18, garg_idle10 ] {ai_stand();};
void() garg_idle10 =[ $fly20, garg_idle1 ] {ai_stand();};
//======================================================================
void() garg_walk1 =[ $fly1, garg_walk2 ] {monster_idle_sound();ai_walk(8);};
void() garg_walk2 =[ $fly3, garg_walk3 ] {ai_walk(8);};
void() garg_walk3 =[ $fly5, garg_walk4 ] {gargoylewings();ai_walk(8);};
void() garg_walk4 =[ $fly7, garg_walk5 ] {ai_walk(8);};
void() garg_walk5 =[ $fly9, garg_walk6 ] {ai_walk(8);};
void() garg_walk6 =[ $fly11, garg_walk7 ] {ai_walk(8);};
void() garg_walk7 =[ $fly13, garg_walk8 ] {ai_walk(8);};
void() garg_walk8 =[ $fly15, garg_walk9 ] {ai_walk(8);};
void() garg_walk9 =[ $fly17, garg_walk10 ] {ai_walk(8);};
void() garg_walk10 =[ $fly19, garg_walk1 ] {ai_walk(8);};
//======================================================================
void() garg_run1 =[ $fly1, garg_run2 ] {monster_idle_sound();
if (self.attachment && self.attachment.state == STATE_ON) garg_fbfinish();
// Switch direction of strafing (random duration)
if (self.meleeattack < time) {
self.meleeattack = time + 4 + (random() + random() + random() * 4);
self.lefty = rint(1 - self.lefty);
}
ai_run(4);
};
void() garg_run2 =[ $fly3, garg_run3 ] {ai_run(5);};
void() garg_run3 =[ $fly5, garg_run4 ] {gargoylewings(); ai_run(6);};
void() garg_run4 =[ $fly7, garg_run5 ] {ai_run(7);};
void() garg_run5 =[ $fly9, garg_run6 ] {ai_run(8);};
void() garg_run6 =[ $fly11, garg_run7 ] {ai_run(4);};
void() garg_run7 =[ $fly13, garg_run8 ] {ai_run(5);};
void() garg_run8 =[ $fly15, garg_run9 ] {ai_run(6);};
void() garg_run9 =[ $fly17, garg_run10 ] {ai_run(7);};
void() garg_run10 =[ $fly19, garg_run1 ] {ai_run(8);};
//============================================================================
// Range attack
//============================================================================
void() garg_fbthrow =
{
local vector org, dir;
makevectors (self.angles);
org = self.origin + attack_vector(self.attack_offset);
dir = normalize(SUB_orgEnemyTarget() - org);
self.attack_speed = SPEED_GARGMISSILE + (skill * SPEED_GARGSKILL);
Launch_Missile (org, dir, '0 0 0', CT_PROJ_GARG, self.attack_speed);
};
//----------------------------------------------------------------------
void() garg_fbfinish =
{
setmodel(self.attachment, "");
self.attachment.state = STATE_OFF;
};
//----------------------------------------------------------------------
void(float fbframe, vector fbofs) garg_fbupdate =
{
if (self.health < 1) return;
if (!self.attachment) {
self.attachment = spawn();
self.attachment.owner = self;
self.attachment.classtype = CT_ATTACHMENT;
if (self.poisonous) self.attachment.mdl = MODEL_PROJ_GARGBALLGRN;
else self.attachment.mdl = MODEL_PROJ_GARGBALL;
self.attachment.alpha = 0.85;
}
if (fbframe == 0) {
self.attachment.state = STATE_ON;
self.pain_finished = time + 1.5; //don't go into pain whilst firing
setorigin(self.attachment, self.origin);
setmodel(self.attachment, self.attachment.mdl);
setsize (self.attachment, VEC_ORIGIN, VEC_ORIGIN);
self.attachment.movetype = MOVETYPE_NONE;
self.attachment.solid = SOLID_NOT;
sound (self, CHAN_WEAPON, "gargoyle/attack1.wav", 1, ATTN_NORM);
}
ai_face(); // Turn towards enemy
makevectors(self.angles);
self.attachment.origin = self.origin + v_forward*fbofs_x + v_right*fbofs_y;
self.attachment.origin_z = self.attachment.origin_z + fbofs_z;
setorigin(self.attachment, self.attachment.origin);
self.attachment.angles = self.angles;
self.attachment.frame = fbframe;
};
//----------------------------------------------------------------------
// Original offset position for gargoyle fireball (designed for a sprite)
// 10 16 0, 4 24 2, -7 28 15, -25 26 28, -38 12 45, -38 9 45, -17 36 30, 24 16 10
// Changed the offset to match the new model instead
// Positioned the fireball to match the hand orientation
//----------------------------------------------------------------------
void() garg_fire1 =[ $attack2, garg_fire2 ] {garg_fbupdate(0,'10 16 -2');};
void() garg_fire2 =[ $attack4, garg_fire3 ] {garg_fbupdate(2,'0 20 -2');};
void() garg_fire3 =[ $attack6, garg_fire4 ] {garg_fbupdate(3,'-6 23 6');gargoylewings();};
void() garg_fire4 =[ $attack8, garg_fire5 ] {garg_fbupdate(4,'-16 26 18');};
void() garg_fire5 =[ $attack10, garg_fire6 ] {garg_fbupdate(5,'-29 18 38');};
void() garg_fire6 =[ $attack12, garg_fire7 ] {garg_fbupdate(4,'-34 9 45');};
void() garg_fire7 =[ $attack14, garg_fire8 ] {garg_fbupdate(3,'-32 22 38');};
void() garg_fire8 =[ $attack16, garg_fire9 ] {garg_fbfinish();garg_fbthrow();};
void() garg_fire9 =[ $attack18, garg_fire10 ] {ai_face();monster_idle_sound();};
void() garg_fire10 =[ $attack20, garg_run1 ] {ai_face();
// If enemy really close, goto into a frenzy of fireball attacks
self.enemydist = range_distance(SUB_entEnemyTarget(), FALSE);
if (SUB_healthEnemyTarget() > 0 && self.enemydist < MON_RANGE_CLOSE) self.think = garg_fire1;
else self.attack_state = AS_STRAIGHT;
};
//============================================================================
// PERCH + WAKEUP
//============================================================================
void() garg_perch1 =[ $perch2, garg_perch2 ] {monster_idle_sound();ai_stand();};
void() garg_perch2 =[ $perch4, garg_perch3 ] {ai_stand();};
void() garg_perch3 =[ $perch6, garg_perch4 ] {ai_stand();};
void() garg_perch4 =[ $perch8, garg_perch5 ] {ai_stand();};
void() garg_perch5 =[ $perch10, garg_perch6 ] {ai_stand();};
void() garg_perch6 =[ $perch12, garg_perch7 ] {ai_stand();};
void() garg_perch7 =[ $perch14, garg_perch8 ] {ai_stand();};
void() garg_perch8 =[ $perch16, garg_perch9 ] {ai_stand();};
void() garg_perch9 =[ $perch18, garg_perch10 ] {ai_stand();};
void() garg_perch10=[ $perch20, garg_perch11 ] {ai_stand();};
void() garg_perch11=[ $perch22, garg_perch12 ] {ai_stand();};
void() garg_perch12=[ $perch24, garg_perch1 ] {ai_stand();};
//----------------------------------------------------------------------
// Sightsound and very quick animation while moving forward
void() garg_wakeup1 =[ $flyup2, garg_wakeup2 ] {ai_forward(1);};
void() garg_wakeup2 =[ $flyup4, garg_wakeup3 ] {ai_forward(4);};
void() garg_wakeup3 =[ $flyup6, garg_wakeup4 ] {ai_forward(8);};
void() garg_wakeup4 =[ $flyup14, garg_wakeup5 ] {ai_forward(8);gargoylewings();};
void() garg_wakeup5 =[ $flyup16, garg_wakeup6 ] {ai_forward(4);};
void() garg_wakeup6 =[ $flyup20, garg_run1 ] {
monster_targets(); // Find target (angry/path_corner)
self.nextthink = time + 0.1;// Next frame
};
//----------------------------------------------------------------------
void() gargoyle_wakeup =
{
// Dead already?
if (self.health < 1) return;
// No longer perched on the ground
self.spawnflags = self.spawnflags - (self.spawnflags & MON_GARGOYLE_PERCH);
self.spawnflags = self.spawnflags - (self.spawnflags & MON_STATUE);
self.spawnstatue = FALSE; // No longer stationary
self.takedamage = DAMAGE_AIM; // Can receive damage
self.use = SUB_Null; // no re-trigger
// Restore all think state functions
self.th_stand = garg_idle1;
self.th_walk = garg_walk1;
self.th_run = garg_run1;
self.th_missile = garg_fire1;
// Allow gargoyle to fly up, no more ground checks
self.flags = self.flags | FL_FLY;
self.movetype = MOVETYPE_STEP;
self.pain_finished = time + 1.5; // No pain
self.attack_finished = 1.5 + random(); // No skill adjustment
garg_wakeup1();
};
//----------------------------------------------------------------------
void() gargoyle_statue =
{
if (random() < MON_IDLE_SOUND) sound (self, CHAN_VOICE, self.idle_sound, 1, ATTN_NORM);
self.think = gargoyle_statue;
self.nextthink = time + 5 + random()*5;
};
//======================================================================
// MINION - Grow and spin up from nothing
//======================================================================
void() gargoyle_growangle = {self.angles_y = self.angles_y + self.lefty;};
void() gargoyle_grow1 = [ $grow1, gargoyle_grow2 ] {};
void() gargoyle_grow2 = [ $grow2, gargoyle_grow3 ] {gargoyle_growangle();};
void() gargoyle_grow3 = [ $grow3, gargoyle_grow4 ] {gargoyle_growangle();};
void() gargoyle_grow4 = [ $grow4, gargoyle_grow5 ] {gargoyle_growangle();};
void() gargoyle_grow5 = [ $grow5, gargoyle_grow6 ] {gargoyle_growangle();};
void() gargoyle_grow6 = [ $grow6, gargoyle_grow7 ] {gargoyle_growangle();};
void() gargoyle_grow7 = [ $grow7, gargoyle_grow8 ] {gargoyle_growangle();};
void() gargoyle_grow8 = [ $grow8, gargoyle_grow9 ] {gargoyle_growangle();};
void() gargoyle_grow9 = [ $grow9, gargoyle_grow10] {gargoyle_growangle();};
void() gargoyle_grow10= [ $grow10, garg_run1 ] {
// Is the gargoyle stuck? cannot move?
if (pointcontents(self.origin) == CONTENT_SOLID) {
// Time to die!
self.health = self.gibhealth;
Killed(self, self);
}
else {
// Finally spin back to original position
self.angles_y = self.angles_y + self.lefty;
// Setup goals and warn other monsters
FoundHuntTarget(TRUE);
// Restore all think state functions
self.th_stand = garg_idle1;
self.th_walk = garg_walk1;
self.th_run = garg_run1;
self.th_missile = garg_fire1;
}
};
//----------------------------------------------------------------------------
void() gargoyle_grow =
{
// Only call wakeup function once
self.th_stand = self.th_walk = self.th_run = SUB_Null;
if (random() < 0.5) self.lefty = 36;
else self.lefty = -36;
monster_sightsound();
gargoyle_grow1();
};
//============================================================================
// The gargoyle does not have a specific pain animation
// - Kinn created one from the death animation (Marcher progs)
void() garg_pain1 =[ $death3, garg_pain2 ] {};
void() garg_pain2 =[ $death4, garg_pain3 ] {};
void() garg_pain3 =[ $death3, garg_pain4 ] {};
void() garg_pain4 =[ $death2, garg_pain5 ] {};
void() garg_pain5 =[ $death1, garg_run1 ] {};
//----------------------------------------------------------------------
void(entity inflictor, entity attacker, float damage) garg_pain =
{
// Check for perching gargoyles, need special wakeup
if (self.spawnflags & MON_GARGOYLE_PERCH) gargoyle_wakeup();
// Statues don't feel pain!
else if (self.spawnflags & MON_STATUE) return;
else {
// Check all pain conditions and set up what to do next
monster_pain_check(attacker, damage);
// make sure any fireball is hidden
if (self.attachment) garg_fbfinish();
// Any pain animation/sound required?
if (self.pain_check > 0) {
if (random() < 0.5) sound (self, CHAN_VOICE, self.pain_sound, 1, ATTN_NORM);
else sound (self, CHAN_VOICE, self.pain_sound2, 1, ATTN_NORM);
if (self.pain_check == 1 || self.pain_check == 2) {
garg_pain1 ();
}
}
}
};
//============================================================================
void() garg_death1 =[ $death1, garg_death2 ] {};
void() garg_death2 =[ $death3, garg_death3 ] {monster_check_gib();};
void() garg_death3 =[ $death5, garg_death4 ] {monster_check_gib();
self.solid = SOLID_NOT;};
void() garg_death4 =[ $death7, garg_death5 ] {};
void() garg_death5 =[ $death9, garg_death6 ] {};
void() garg_death6 =[ $death11, garg_death7 ] {};
void() garg_death7 =[ $death13, garg_death8 ] {monster_death_postcheck();};
void() garg_death8 =[ $death14, garg_death8 ] {monster_deadbody_check();};
//----------------------------------------------------------------------
void() garg_die =
{
// Statues don't die!
if (self.spawnflags & MON_STATUE) return;
// Make sure any wings sound is silenced
sound (self, CHAN_ITEM, SOUND_EMPTY, 1, ATTN_NORM);
// Check for perching gargoyles, need to blow up in gibs
// In an awkward pose that does not go well into death animations
if (self.spawnflags & MON_GARGOYLE_PERCH) self.gibondeath = TRUE;
// If creating a Fireball, make it explode!
if (self.attachment) {
if (self.attachment.state == STATE_ON) {
self.gibondeath = TRUE;
SpawnProjectileSmoke(self.origin, 200, 50, 150);
SpawnProjectileSmoke(self.origin, 200, 50, 150);
if (self.poisonous) self.lip = PARTICLE_BURST_GREEN;
else self.lip = PARTICLE_BURST_FIRE;
particle_explode(self.origin-'0 0 16', 50+random()*50, 2, self.lip, PARTICLE_BURST_UPWARD);
makevectors(self.angles);
self.oldorigin = self.origin + v_forward*8;
if (self.poisonous) self.lip = EXPLODE_POISON_BIG;
else self.lip = EXPLODE_BIG;
SpawnExplosion(self.lip, self.oldorigin, SOUND_REXP3);
}
// make sure any fireball is hidden
garg_fbfinish();
}
// Pre-check routine to tidy up extra entities
monster_death_precheck();
// If not gibbed, then drop to ground
if (!self.gibbed) {
sound (self, CHAN_VOICE, "gargoyle/death1.wav", 1, ATTN_NORM);
self.flags = FL_MONSTER; // reset all flag conditions
self.movetype = MOVETYPE_TOSS; // Affected by gravity
self.velocity_x = -200 + 400*random();
self.velocity_y = -200 + 400*random();
self.velocity_z = 100 + 100*random();
garg_death1 ();
}
};
/*======================================================================
QUAKED monster_gargoyle (0.8 0 0.2) (-16 -16 -24) (16 16 40) AMBUSH STATUE PERCH NOSIGHT NOIDLE NOGFX STARTOFF ANGRY Not_Easy Not_Normal Not_Hard Not_DM
{ model(":progs/mon_gargoyle.mdl"); }
Gargoyle, 120 health points.
-------- KEYS --------
-------- SPAWNFLAGS --------
STATUE : Stone statue until triggered (always starts in a perched position)
PERCH : Start in a sitting down, place 44 units out from perching edge, 4 units higher
======================================================================*/
void() setup_gargoyle;
void() monster_gargoyle =
{
if (deathmatch) { remove(self); return; }
self.mdl = "progs/mon_gargoyle.mdl";
self.headmdl = "progs/h_gargoyle.mdl";
self.gib1mdl = "progs/gib_gargwing1.mdl"; // Left wing
self.gib2mdl = "progs/gib_gargwing2.mdl"; // Right wing
precache_model (self.mdl);
precache_model (self.headmdl);
precache_model (MODEL_PROJ_GARGBALL); // FB growing 8 frames
precache_model (MODEL_PROJ_GARGOYLE); // red/smoke wiz projectile
precache_model (self.gib1mdl);
precache_model (self.gib2mdl);
self.idle_sound = "gargoyle/idle1.wav";
self.idle_soundcom = "gargoyle/perch1.wav";
self.idle_soundcom2 = "gargoyle/perch2.wav";
precache_sound (self.idle_sound);
precache_sound (self.idle_soundcom);
precache_sound (self.idle_soundcom2);
precache_sound ("gargoyle/attack1.wav"); // Doom imp fireball!
precache_sound ("gargoyle/swoop1.wav");
precache_sound ("gargoyle/swoop2.wav");
precache_sound ("gargoyle/swoop1hit.wav");
precache_sound ("gargoyle/wings1.wav");
self.pain_sound = "gargoyle/pain75.wav";
self.pain_sound2 = "gargoyle/pain100.wav";
precache_sound (self.pain_sound);
precache_sound (self.pain_sound2);
precache_sound ("gargoyle/death1.wav");
self.sight_sound = "gargoyle/sight1.wav";
precache_sound (self.sight_sound);
// Check for poisonous entity flag
if (self.poisonous) {
precache_poisongibs(); // precache gibs
self.gibtype = GIBTYPE_POISON; // Poisonous blood trails
precache_model (MODEL_PROJ_GARGBALLGRN); // Ball growing 8 frames
precache_model (MODEL_PROJ_GARGOYLEGRN); // acid/smoke wiz projectile
}
// Cache gargoyle is a special class used for precache only
if (self.classtype != CT_CACHEGARGOYLE) setup_gargoyle();
};
//----------------------------------------------------------------------------
void() monster_minotaurminion = {
self.classtype = CT_CACHEGARGOYLE;
self.poisonous = TRUE; // Cache poison stuff for minotaur spawns
monster_gargoyle();
};
//----------------------------------------------------------------------------
void() setup_gargoyle =
{
// Randomize gib parts
if (random() < 0.5) self.gib1mdl = string_null;
else if (random() < 0.5) self.gib2mdl = string_null;
self.solid = SOLID_NOT; // No interaction with world
self.movetype = MOVETYPE_NONE; // Static item, no movement
if (self.bboxtype < 1) self.bboxtype = BBOX_TALL;
if (self.health < 1) self.health = 120;
self.gibhealth = -70; // Need a powerful weapon to GIB
self.gibbed = FALSE; // no falling apart
self.pain_flinch = 70; // High pain threshold
self.blockudeath = TRUE; // no humanoid death sound
if (self.height < 1) self.height = MONAI_ABOVEDIST; // Custom height
self.attack_offset = '16 28 22'; // fireball start location
self.deathstring = " was burned by a Gargoyle\n";
// Always reset Ammo Resistance to be consistent
self.resist_shells = self.resist_nails = 0;
self.resist_rockets = self.resist_cells = 0;
self.th_checkattack = GargoyleCheckAttack;
self.th_pain = garg_pain;
self.th_die = garg_die;
if(!self.classtype) self.classtype = CT_MONGARGOYLE;
if (!self.classgroup) self.classgroup = CG_WIZARD;
self.classmove = MON_MOVEFLY;
// Fix double spawnflags problem - default to statue
if (self.spawnflags & MON_STATUE && self.spawnflags & MON_GARGOYLE_PERCH) {
dprint("\b[GARGOYLE]\b Cannot be perch and statue!\n");
self.spawnflags = self.spawnflags - MON_GARGOYLE_PERCH;
}
//----------------------------------------------------------------------
// Perched Gargoyles have special idle animation + idle sounds
// The AI needs to be setup 40 units forward and 24 units up
// to be positioned feet flat on perch surface
if (self.spawnflags & MON_GARGOYLE_PERCH) {
self.th_stand = self.th_walk = garg_perch1;
self.th_run = self.th_missile = gargoyle_wakeup;
}
//----------------------------------------------------------------------
// Statue Gargoyles setup in perch position with statue idle sounds
// Randomly picks a frame position from perch animation set
else if (self.spawnflags & MON_STATUE) {
// Setup stone idle sounds
self.idle_sound = "statue/idle1.wav";
self.idle_sound2 = "statue/idle2.wav";
precache_sound (self.idle_sound);
precache_sound (self.idle_sound2);
self.spawnstatue = TRUE; // Start as a statue
self.poisonous = FALSE; // Cannot be status + poison
self.th_stand = gargoyle_statue; // Stone idle pose
self.think1 = gargoyle_wakeup; // Wakeup statue angry at player
self.skin = 1; // Stone like skin
self.gib1skin = self.gib2skin = 1;
//self.resist_nails = 0.5; // Stone resistance
// Work out random starting pose
self.pos1_x = $perch1;
self.pos1_y = $perch24;
self.pos1_z = fabs(self.pos1_y - self.pos1_x);
self.frame = rint(self.pos1_x + random() * self.pos1_z);
}
//----------------------------------------------------------------------
// Special spawning minion need to start spinning
else if (self.classtype == CT_MINIONGARGOYLE) {
self.th_stand = self.th_walk = self.th_run = gargoyle_grow;
self.th_missile = SUB_Null;
}
//----------------------------------------------------------------------
// Default gargoyle setup
else {
self.th_stand = garg_idle1;
self.th_walk = garg_walk1;
self.th_run = garg_run1;
self.th_missile = garg_fire1;
}
monster_start();
};
//----------------------------------------------------------------------------
// A code way to spawn gargoyles (requires monster_minotaurminion entity)
//----------------------------------------------------------------------------
void(vector minion_org, entity minion_targ) minion_gargoyle =
{
local entity minion;
// Check if there is space to spawn entity
if (entity_pcontent(minion_org)) return;
// Self = minotaur, there is no egg
update_minioncount(self, 1); // Update spawn counters
minion = spawn();
minion.classname = "monster_gargoyle"; // For function searching
setorigin(minion, minion_org); // Move to new location
minion.owner = self; // Spawner Parent Link
minion.effects = minion.flags = 0; // make sure are blank
minion.gibondeath = 1; // Always gib on death
minion.classtype = CT_MINIONGARGOYLE; // Special minion class
minion.enemy = minion_targ; // Target to attack
minion.spawnflags = 0;
minion.classgroup = CG_DEMON; // Don't turn on master
minion.minion_active = TRUE; // Minion flag
minion.bodyfadeaway = TRUE; // Get rid of body
// Check for poison gibs being cached first
if (gibpoison && self.poisonous == TRUE) {
minion.poisonous = self.poisonous; // carry over from host spawner
minion.gibtype = GIBTYPE_POISON; // Poisonous blood trails
}
// Adopt parameters from host spawner
minion.infightextra = self.infightextra;
minion.mdl = "progs/mon_gargoyle.mdl";
minion.headmdl = "progs/h_gargoyle.mdl";
minion.gib1mdl = "progs/gib_gargwing1.mdl"; // Left wing
minion.gib2mdl = "progs/gib_gargwing2.mdl"; // Right wing
minion.pain_sound = "gargoyle/pain75.wav";
minion.pain_sound2 = "gargoyle/pain100.wav";
minion.idle_sound = "gargoyle/idle1.wav";
minion.idle_soundcom = "gargoyle/perch1.wav";
minion.idle_soundcom2 = "gargoyle/perch2.wav";
minion.sight_sound = "gargoyle/sight1.wav";
minion.nextthink = time + 0.01;
minion.think = setup_gargoyle;
};