Git Repos / fte_dogmode / qc / monsters / fish.qc
Last update to this file was on 2024-06-15 at 19:50.
Show fish.qc
//==============================================================================
// FISHIES
//==============================================================================
//======================================================================
// constants
//======================================================================
const float FISH_HEALTH = 25; // id1 25
const float FISH_HEALTH_CORPSE = 20;
const vector FISH_CORPSE_Z_MINS = '-16 -16 -24'; // thin 32x32 box on ground
const vector FISH_CORPSE_Z_MAXS = '16 16 -8';
//======================================================================
// forward declarations
//======================================================================
// monster_fish
void() monster_fish_attack_melee; // AI, attacks, animation, thinking
void() fish_stand1; void() fish_stand2; void() fish_stand3; void() fish_stand4;
void() fish_stand5; void() fish_stand6; void() fish_stand7; void() fish_stand8;
void() fish_stand9; void() fish_stand10; void() fish_stand11;
void() fish_stand12; void() fish_stand13; void() fish_stand14;
void() fish_stand15; void() fish_stand16; void() fish_stand17;
void() fish_stand18;
void() fish_walk1; void() fish_walk2; void() fish_walk3; void() fish_walk4;
void() fish_walk5; void() fish_walk6; void() fish_walk7; void() fish_walk8;
void() fish_walk9; void() fish_walk10; void() fish_walk11; void() fish_walk12;
void() fish_walk13; void() fish_walk14; void() fish_walk15; void() fish_walk16;
void() fish_walk17; void() fish_walk18;
void() fish_run1; void() fish_run2; void() fish_run3; void() fish_run4;
void() fish_run5; void() fish_run6; void() fish_run7; void() fish_run8;
void() fish_run9;
void() fish_atk1; void() fish_atk2; void() fish_atk3; void() fish_atk4;
void() fish_atk5; void() fish_atk6; void() fish_atk7; void() fish_atk8;
void() fish_atk9; void() fish_atk10; void() fish_atk11; void() fish_atk12;
void() fish_atk13; void() fish_atk14; void() fish_atk15; void() fish_atk16;
void() fish_atk17; void() fish_atk18;
void() fish_pain1; void() fish_pain2; void() fish_pain3; void() fish_pain4;
void() fish_pain5; void() fish_pain6; void() fish_pain7; void() fish_pain8;
void() fish_pain9;
void() fish_death1; void() fish_death2; void() fish_death3; void() fish_death4;
void() fish_death5; void() fish_death6; void() fish_death7; void() fish_death8;
void() fish_death9; void() fish_death10; void() fish_death11;
void() fish_death12; void() fish_death13; void() fish_death14;
void() fish_death15; void() fish_death16; void() fish_death17;
void() fish_death18; void() fish_death19; void() fish_death20;
void() fish_death21;
void(entity attacker, float damage) monster_fish_pain; // interaction
void(vector dir) monster_fish_destroy;
entity(vector org, vector ang, float sflags, float yaw, float angry)
spawn_monster_fish; // initialization
void(entity e) monster_fish_init;
void() monster_fish;
//======================================================================
// frame macros
//======================================================================
$cd id1/models/fish
$origin 0 0 24
$base base
$skin skin
$frame attack1 attack2 attack3 attack4 attack5 attack6
$frame attack7 attack8 attack9 attack10 attack11 attack12 attack13
$frame attack14 attack15 attack16 attack17 attack18
$frame death1 death2 death3 death4 death5 death6 death7
$frame death8 death9 death10 death11 death12 death13 death14 death15
$frame death16 death17 death18 death19 death20 death21
$frame swim1 swim2 swim3 swim4 swim5 swim6 swim7 swim8
$frame swim9 swim10 swim11 swim12 swim13 swim14 swim15 swim16 swim17
$frame swim18
$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8
$frame pain9
//------------------------------------------------------------------------------
/*QUAKED monster_fish (1 0 0) (-16 -16 -24) (16 16 24) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/fish.mdl");
}
Rotfish.
Default health = 25"
snd_death(string) : "Path to custom death sound (BUBBLES)"
snd_attack(string) : "Path to custom attack sound (CRUNCHY BITE)"
snd_idle(string) : "Path to custom idle sound"
mdl_body(string) : "Path to custom body model"
mdl_gib1(string) : "Path to custom 1st gib model"
mdl_gib2(string) : "Path to custom 2nd gib model"
mdl_gib3(string) : "Path to custom 3rd gib model"
effects(choices) : "Add a visual effect to an entity"
0 : "None (Default)"
1 : "Brightfield (yellow particles)"
4 : "Bright light"
8 : "Dim light"
berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
0 : "Off (Default)"
1 : "Berserk (skip pain animations)"
delay(float) : "Delay spawn in for this amount of time"
wait(choices) : "Play an effect when trigger spawned?"
0 : "Teleport Effects (Default)"
1 : "Spawn Silently"
spawn_angry(Choices)
0 : "Only when trigger spawned, default behavior - not angry"
1 : "Only when trigger spawned, set to 1 to spawn angry at player"
infight_mode(Choices)
0 : "Default behavior, only with different classnames"
1 : "Infight with monsters with the same classname but a different mdl_body"
2 : "Infight with monsters with the same classname and model but a different skin"
3 : "Infight no matter what"
health(integer) : "Set this to a custom health amount"
pain_target(string) : "Fire this target when pain_threshold is reached"
pain_threshold(integer) : "Fire pain_target when health drops below this amount"
sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
*/
//----------------------------------------------------------------------
// class monster_fish: base_swimmonster
// {
//--------------------------------------------------------------
void() monster_fish_attack_melee =
{
local vector delta;
local float ldmg;
if (!self.enemy)
// removed before stroke
return;
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 60)
return;
sound_attack (self, CHAN_VOICE, "fish/bite.wav",
VOL_HIGH, ATTN_NORM);
ldmg = (random() + random()) * 3;
t_damage2 (self.enemy, self, self, ldmg);
};
//--------------------------------------------------------------
// Fish stand (resting?) functions
//--------------------------------------------------------------
void() fish_stand1 = [$swim1, fish_stand2] { ai_stand (); };
void() fish_stand2 = [$swim2, fish_stand3] { ai_stand (); };
void() fish_stand3 = [$swim3, fish_stand4] { ai_stand (); };
void() fish_stand4 = [$swim4, fish_stand5] { ai_stand (); };
void() fish_stand5 = [$swim5, fish_stand6] { ai_stand (); };
void() fish_stand6 = [$swim6, fish_stand7] { ai_stand (); };
void() fish_stand7 = [$swim7, fish_stand8] { ai_stand (); };
void() fish_stand8 = [$swim8, fish_stand9] { ai_stand (); };
void() fish_stand9 = [$swim9, fish_stand10 ] { ai_stand (); };
void() fish_stand10 = [$swim10, fish_stand11] { ai_stand (); };
void() fish_stand11 = [$swim11, fish_stand12] { ai_stand (); };
void() fish_stand12 = [$swim12, fish_stand13] { ai_stand (); };
void() fish_stand13 = [$swim13, fish_stand14] { ai_stand (); };
void() fish_stand14 = [$swim14, fish_stand15] { ai_stand (); };
void() fish_stand15 = [$swim15, fish_stand16] { ai_stand (); };
void() fish_stand16 = [$swim16, fish_stand17] { ai_stand (); };
void() fish_stand17 = [$swim17, fish_stand18] { ai_stand (); };
void() fish_stand18 = [$swim18, fish_stand1] { ai_stand (); };
//--------------------------------------------------------------
// Fish walking functions (ever seen a fish walk?)
//--------------------------------------------------------------
void() fish_walk1 = [$swim1, fish_walk2] { ai_walk (8); };
void() fish_walk2 = [$swim2, fish_walk3] { ai_walk (8); };
void() fish_walk3 = [$swim3, fish_walk4] { ai_walk (8); };
void() fish_walk4 = [$swim4, fish_walk5] { ai_walk (8); };
void() fish_walk5 = [$swim5, fish_walk6] { ai_walk (8); };
void() fish_walk6 = [$swim6, fish_walk7] { ai_walk (8); };
void() fish_walk7 = [$swim7, fish_walk8] { ai_walk (8); };
void() fish_walk8 = [$swim8, fish_walk9] { ai_walk (8); };
void() fish_walk9 = [$swim9, fish_walk10] { ai_walk (8); };
void() fish_walk10 = [$swim10, fish_walk11] { ai_walk (8); };
void() fish_walk11 = [$swim11, fish_walk12] { ai_walk (8); };
void() fish_walk12 = [$swim12, fish_walk13] { ai_walk (8); };
void() fish_walk13 = [$swim13, fish_walk14] { ai_walk (8); };
void() fish_walk14 = [$swim14, fish_walk15] { ai_walk (8); };
void() fish_walk15 = [$swim15, fish_walk16] { ai_walk (8); };
void() fish_walk16 = [$swim16, fish_walk17] { ai_walk (8); };
void() fish_walk17 = [$swim17, fish_walk18] { ai_walk (8); };
void() fish_walk18 = [$swim18, fish_walk1] { ai_walk (8); };
//--------------------------------------------------------------
// Fish run functions
//--------------------------------------------------------------
void() fish_run1 = [$swim1, fish_run2]
{
ai_run (12);
if (random() < 0.5)
sound_idle (self, CHAN_VOICE, "fish/idle.wav",
VOL_HIGH, ATTN_NORM);
};
void() fish_run2 = [$swim3, fish_run3] { ai_run (12); };
void() fish_run3 = [$swim5, fish_run4] { ai_run (12); };
void() fish_run4 = [$swim7, fish_run5] { ai_run (12); };
void() fish_run5 = [$swim9, fish_run6] { ai_run (12); };
void() fish_run6 = [$swim11, fish_run7] { ai_run (12); };
void() fish_run7 = [$swim13, fish_run8] { ai_run (12); };
void() fish_run8 = [$swim15, fish_run9] { ai_run (12); };
void() fish_run9 = [$swim17, fish_run1] { ai_run (12); };
//--------------------------------------------------------------
// Fish attack functions
//--------------------------------------------------------------
void() fish_atk1 = [$attack1, fish_atk2] { ai_charge (10); };
void() fish_atk2 = [$attack2, fish_atk3] { ai_charge (10); };
void() fish_atk3 = [$attack3, fish_atk4]
{
monster_fish_attack_melee ();
};
void() fish_atk4 = [$attack4, fish_atk5] { ai_charge (10); };
void() fish_atk5 = [$attack5, fish_atk6] { ai_charge (10); };
void() fish_atk6 = [$attack6, fish_atk7] { ai_charge (10); };
void() fish_atk7 = [$attack7, fish_atk8] { ai_charge (10); };
void() fish_atk8 = [$attack8, fish_atk9] { ai_charge (10); };
void() fish_atk9 = [$attack9, fish_atk10]
{
monster_fish_attack_melee ();
};
void() fish_atk10 = [$attack10, fish_atk11] { ai_charge (10); };
void() fish_atk11 = [$attack11, fish_atk12] { ai_charge (10); };
void() fish_atk12 = [$attack12, fish_atk13] { ai_charge (10); };
void() fish_atk13 = [$attack13, fish_atk14] { ai_charge (10); };
void() fish_atk14 = [$attack14, fish_atk15] { ai_charge (10); };
void() fish_atk15 = [$attack15, fish_atk16]
{
monster_fish_attack_melee ();
};
void() fish_atk16 = [$attack16, fish_atk17] { ai_charge (10); };
void() fish_atk17 = [$attack17, fish_atk18] { ai_charge (10); };
void() fish_atk18 = [$attack18, fish_run1] { ai_charge (10); };
//--------------------------------------------------------------
// Fish pain states (please don't hurt the fish)
//--------------------------------------------------------------
void() fish_pain1 = [$pain1, fish_pain2] { };
void() fish_pain2 = [$pain2, fish_pain3] { ai_pain (6); };
void() fish_pain3 = [$pain3, fish_pain4] { ai_pain (6); };
void() fish_pain4 = [$pain4, fish_pain5] { ai_pain (6); };
void() fish_pain5 = [$pain5, fish_pain6] { ai_pain (6); };
void() fish_pain6 = [$pain6, fish_pain7] { ai_pain (6); };
void() fish_pain7 = [$pain7, fish_pain8] { ai_pain (6); };
void() fish_pain8 = [$pain8, fish_pain9] { ai_pain (6); };
void() fish_pain9 = [$pain9, fish_run1] { ai_pain (6); };
//--------------------------------------------------------------
// Fish death states (RIP fish)
//--------------------------------------------------------------
void() fish_death1 = [$death1, fish_death2] { };
void() fish_death2 = [$death2, fish_death3] { };
void() fish_death3 = [$death3, fish_death4] { };
void() fish_death4 = [$death4, fish_death5] { };
void() fish_death5 = [$death5, fish_death6] { };
void() fish_death6 = [$death6, fish_death7] { };
void() fish_death7 = [$death7, fish_death8] { };
void() fish_death8 = [$death8, fish_death9] { };
void() fish_death9 = [$death9, fish_death10] { };
void() fish_death10 = [$death10, fish_death11] { };
void() fish_death11 = [$death11, fish_death12] { };
void() fish_death12 = [$death12, fish_death13] { };
void() fish_death13 = [$death13, fish_death14] { };
void() fish_death14 = [$death14, fish_death15] { };
void() fish_death15 = [$death15, fish_death16] { };
void() fish_death16 = [$death16, fish_death17] { };
void() fish_death17 = [$death17, fish_death18] { };
void() fish_death18 = [$death18, fish_death19] { };
void() fish_death19 = [$death19, fish_death20] { };
void() fish_death20 = [$death20, fish_death21]
{
become_base_corpse (self, FISH_HEALTH_CORPSE);
setsize (self, FISH_CORPSE_Z_MINS, FISH_CORPSE_Z_MAXS);
};
void() fish_death21 = [$death21, fish_death21] { };
//==============================================================
// Interaction
//==============================================================
//--------------------------------------------------------------
// fish_pain
//--------------------------------------------------------------
void(entity attacker, float damage) monster_fish_pain =
{
// fish always do pain frames
fish_pain1 ();
};
//--------------------------------------------------------------
// fish_die
//--------------------------------------------------------------
void(vector dir) monster_fish_destroy =
{
// check if we're dead already
if (self.classgroup & CG_CORPSE)
{
// fish gibs -- dumptruck_ds
sound (self, CHAN_VOICE, "player/udeath.wav",
VOL_HIGH, ATTN_NORM);
// custom models -- dumptruck_ds
if (self.mdl_gib1 != "")
throw_gib_1 (self, dir, self.health);
else
throw_gib_3 (self, dir, self.health);
if (self.mdl_gib2 != "")
throw_gib_2 (self, dir, self.health);
else
throw_gib_3 (self, dir, self.health);
if (self.mdl_gib3 != "")
throw_gib_3 (self, dir, self.health);
else
throw_gib_3 (self, dir, self.health);
// no fish heads -- CEV
remove (self);
return;
}
// check for gib
if (self.health < -35)
{
// fish gibs -- dumptruck_ds
sound (self, CHAN_VOICE, "player/udeath.wav",
VOL_HIGH, ATTN_NORM);
// custom models -- dumptruck_ds
if (self.mdl_gib1 != "")
throw_gib_1 (self, dir, self.health);
else
throw_gib_3 (self, dir, self.health);
if (self.mdl_gib2 != "")
throw_gib_2 (self, dir, self.health);
else
throw_gib_3 (self, dir, self.health);
if (self.mdl_gib3 != "")
throw_gib_3 (self, dir, self.health);
else
throw_gib_3 (self, dir, self.health);
base_item_drop_stuff (self);
// no fish heads -- CEV
remove (self);
return;
}
// regular death
self.solid = SOLID_NOT;
base_item_drop_stuff (self);
sound_death (self, CHAN_VOICE, "fish/death.wav",
VOL_HIGH, ATTN_NORM);
fish_death1 ();
};
//==============================================================
// Initialization
//==============================================================
//--------------------------------------------------------------
entity(vector org, vector ang, float sflags, float yaw, float angry)
spawn_monster_fish =
{
return spawn_base_monster (org, ang, sflags, yaw, angry,
monster_fish_init);
};
//--------------------------------------------------------------
void(entity e) monster_fish_init =
{
if (e.spawnflags & I_AM_TURRET)
objerror ("Incompatible spawnflag: TURRET_MODE\n");
if (deathmatch)
{
remove (e);
return;
}
e.classname = "monster_fish";
e.classtype = CT_MONSTER_FISH;
precache_body_model2 (e, "progs/fish.mdl");
// precache_model2 ("progs/fish.mdl");
precache_sound2_death (e, "fish/death.wav");
precache_sound2_attack (e, "fish/bite.wav");
precache_sound2_idle (e, "fish/idle.wav");
precache_gib1 (e, "progs/gib1.mdl");
precache_gib2 (e, "progs/gib2.mdl");
precache_gib3 (e, "progs/gib3.mdl");
e.solid = SOLID_SLIDEBOX;
e.movetype = MOVETYPE_STEP;
body_model (e, "progs/fish.mdl");
// setmodel (e, "progs/fish.mdl");
setsize (e, '-16 -16 -24', '16 16 24');
if (!e.health)
// thanks RennyC -- dumptruck_ds
e.health = FISH_HEALTH;
e.th_stand = fish_stand1;
e.th_walk = fish_walk1;
e.th_run = fish_run1;
e.destroy = monster_fish_destroy;
// Berserk from
// http://celephais.net/board/view_thread.php?id=4&start=3465
// -- dumptruck_ds
if !(e.berserk)
e.th_pain = monster_fish_pain;
else
e.th_pain = sub_nullpain;
e.th_melee = fish_atk1;
// swimmonster_start
base_swimmonster_init (e);
};
//--------------------------------------------------------------
void() monster_fish =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;
monster_fish_init (self);
};
// };
Return to the top of this page or return to the overview of this repo.
Log fish.qc
Date | Commit Message | Author | + | - |
---|---|---|---|---|
2024-06-15 | Major update, committing as-is, will have bugs | cev | +68 | -28 |
2024-04-12 | Moveable gibs, heads, some bugfixes | cev | +20 | -15 |
2024-04-08 | Registered monsters, projectile bugfixes | cev | +221 | -171 |
2024-02-18 | Client/player, projectiles, entrypoints refactor | cev | +1 | -1 |
2024-01-31 | Class based monster refactor & start projectiles | cev | +283 | -228 |
2024-01-13 | Refactored items into classes, fix teleporttrain | cev | +2 | -2 |
2024-01-09 | Continue OO / Class-based refactor | cev | +2 | -2 |
2023-10-13 | New movement code based on SV_RunClientCommand | cev | +306 | -306 |
2023-10-13 | Rename "qc-server" dir to "qc" | cev | +306 |
Return to the top of this page or return to the overview of this repo.