mirror of
https://github.com/yquake2/rogue.git
synced 2024-11-22 20:31:50 +00:00
Mkay, nun startet er wieder
This commit is contained in:
parent
8be94c74b6
commit
4cd96d7fb4
3 changed files with 401 additions and 24 deletions
252
src/m_flyer.c
252
src/m_flyer.c
|
@ -29,6 +29,11 @@ void flyer_setstart (edict_t *self);
|
|||
void flyer_stand (edict_t *self);
|
||||
void flyer_nextmove (edict_t *self);
|
||||
|
||||
// ROGUE - kamikaze stuff
|
||||
void flyer_kamikaze (edict_t *self);
|
||||
void flyer_kamikaze_check (edict_t *self);
|
||||
void flyer_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
|
||||
|
||||
|
||||
void flyer_sight (edict_t *self, edict_t *other)
|
||||
{
|
||||
|
@ -197,24 +202,93 @@ mframe_t flyer_frames_run [] =
|
|||
};
|
||||
mmove_t flyer_move_run = {FRAME_stand01, FRAME_stand45, flyer_frames_run, NULL};
|
||||
|
||||
mframe_t flyer_frames_kamizake [] =
|
||||
{
|
||||
{ai_charge, 40, flyer_kamikaze_check},
|
||||
{ai_charge, 40, flyer_kamikaze_check},
|
||||
{ai_charge, 40, flyer_kamikaze_check},
|
||||
{ai_charge, 40, flyer_kamikaze_check},
|
||||
{ai_charge, 40, flyer_kamikaze_check}
|
||||
};
|
||||
mmove_t flyer_move_kamikaze = {FRAME_rollr02, FRAME_rollr06, flyer_frames_kamizake, flyer_kamikaze};
|
||||
|
||||
void flyer_run (edict_t *self)
|
||||
{
|
||||
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
|
||||
self->monsterinfo.currentmove = &flyer_move_stand;
|
||||
if (self->mass > 50)
|
||||
self->monsterinfo.currentmove = &flyer_move_kamikaze;
|
||||
else
|
||||
self->monsterinfo.currentmove = &flyer_move_run;
|
||||
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
|
||||
self->monsterinfo.currentmove = &flyer_move_stand;
|
||||
else
|
||||
self->monsterinfo.currentmove = &flyer_move_run;
|
||||
}
|
||||
|
||||
void flyer_walk (edict_t *self)
|
||||
{
|
||||
self->monsterinfo.currentmove = &flyer_move_walk;
|
||||
if (self->mass > 50)
|
||||
flyer_run (self);
|
||||
else
|
||||
self->monsterinfo.currentmove = &flyer_move_walk;
|
||||
}
|
||||
|
||||
void flyer_stand (edict_t *self)
|
||||
{
|
||||
if (self->mass > 50)
|
||||
flyer_run (self);
|
||||
else
|
||||
self->monsterinfo.currentmove = &flyer_move_stand;
|
||||
}
|
||||
|
||||
// ROGUE - kamikaze stuff
|
||||
|
||||
void flyer_kamikaze_explode (edict_t *self)
|
||||
{
|
||||
vec3_t dir;
|
||||
|
||||
if (self->monsterinfo.commander && self->monsterinfo.commander->inuse &&
|
||||
!strcmp(self->monsterinfo.commander->classname, "monster_carrier"))
|
||||
{
|
||||
self->monsterinfo.commander->monsterinfo.monster_slots++;
|
||||
}
|
||||
|
||||
if (self->enemy)
|
||||
{
|
||||
VectorSubtract (self->enemy->s.origin, self->s.origin, dir);
|
||||
T_Damage (self->enemy, self, self, dir, self->s.origin, vec3_origin, (int)50, (int)50, DAMAGE_RADIUS, MOD_UNKNOWN);
|
||||
}
|
||||
|
||||
flyer_die (self, NULL, NULL, 0, dir);
|
||||
}
|
||||
|
||||
void flyer_kamikaze (edict_t *self)
|
||||
{
|
||||
self->monsterinfo.currentmove = &flyer_move_kamikaze;
|
||||
}
|
||||
|
||||
void flyer_kamikaze_check (edict_t *self)
|
||||
{
|
||||
float dist;
|
||||
|
||||
// PMM - this needed because we could have gone away before we get here (blocked code)
|
||||
if (!self->inuse)
|
||||
return;
|
||||
|
||||
if ((!self->enemy) || (!self->enemy->inuse))
|
||||
{
|
||||
flyer_kamikaze_explode (self);
|
||||
return;
|
||||
}
|
||||
|
||||
self->goalentity = self->enemy;
|
||||
|
||||
dist = realrange (self, self->enemy);
|
||||
|
||||
if (dist < 90)
|
||||
flyer_kamikaze_explode (self);
|
||||
}
|
||||
|
||||
// rogue - kamikaze
|
||||
|
||||
mframe_t flyer_frames_start [] =
|
||||
{
|
||||
{ai_move, 0, NULL},
|
||||
|
@ -353,6 +427,9 @@ void flyer_fire (edict_t *self, int flash_number)
|
|||
vec3_t dir;
|
||||
int effect;
|
||||
|
||||
if(!self->enemy || !self->enemy->inuse) //PGM
|
||||
return; //PGM
|
||||
|
||||
if ((self->s.frame == FRAME_attak204) || (self->s.frame == FRAME_attak207) || (self->s.frame == FRAME_attak210))
|
||||
effect = EF_HYPERBLASTER;
|
||||
else
|
||||
|
@ -400,6 +477,31 @@ mframe_t flyer_frames_attack2 [] =
|
|||
};
|
||||
mmove_t flyer_move_attack2 = {FRAME_attak201, FRAME_attak217, flyer_frames_attack2, flyer_run};
|
||||
|
||||
// PMM
|
||||
// circle strafe frames
|
||||
|
||||
mframe_t flyer_frames_attack3 [] =
|
||||
{
|
||||
{ai_charge, 10, NULL},
|
||||
{ai_charge, 10, NULL},
|
||||
{ai_charge, 10, NULL},
|
||||
{ai_charge, 10, flyer_fireleft}, // left gun
|
||||
{ai_charge, 10, flyer_fireright}, // right gun
|
||||
{ai_charge, 10, flyer_fireleft}, // left gun
|
||||
{ai_charge, 10, flyer_fireright}, // right gun
|
||||
{ai_charge, 10, flyer_fireleft}, // left gun
|
||||
{ai_charge, 10, flyer_fireright}, // right gun
|
||||
{ai_charge, 10, flyer_fireleft}, // left gun
|
||||
{ai_charge, 10, flyer_fireright}, // right gun
|
||||
{ai_charge, 10, NULL},
|
||||
{ai_charge, 10, NULL},
|
||||
{ai_charge, 10, NULL},
|
||||
{ai_charge, 10, NULL},
|
||||
{ai_charge, 10, NULL},
|
||||
{ai_charge, 10, NULL}
|
||||
};
|
||||
mmove_t flyer_move_attack3 = {FRAME_attak201, FRAME_attak217, flyer_frames_attack3, flyer_run};
|
||||
// pmm
|
||||
|
||||
void flyer_slash_left (edict_t *self)
|
||||
{
|
||||
|
@ -466,7 +568,38 @@ void flyer_loop_melee (edict_t *self)
|
|||
|
||||
void flyer_attack (edict_t *self)
|
||||
{
|
||||
self->monsterinfo.currentmove = &flyer_move_attack2;
|
||||
float chance;
|
||||
/* if (random() <= 0.5)
|
||||
self->monsterinfo.currentmove = &flyer_move_attack1;
|
||||
else */
|
||||
// 0% chance of circle in easy
|
||||
// 50% chance in normal
|
||||
// 75% chance in hard
|
||||
// 86.67% chance in nightmare
|
||||
|
||||
if (self->mass > 50)
|
||||
{
|
||||
flyer_run (self);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!skill->value)
|
||||
chance = 0;
|
||||
else
|
||||
chance = 1.0 - (0.5/(float)(skill->value));
|
||||
|
||||
if (random() > chance)
|
||||
{
|
||||
self->monsterinfo.attack_state = AS_STRAIGHT;
|
||||
self->monsterinfo.currentmove = &flyer_move_attack2;
|
||||
}
|
||||
else // circle strafe
|
||||
{
|
||||
if (random () <= 0.5) // switch directions
|
||||
self->monsterinfo.lefty = 1 - self->monsterinfo.lefty;
|
||||
self->monsterinfo.attack_state = AS_SLIDING;
|
||||
self->monsterinfo.currentmove = &flyer_move_attack3;
|
||||
}
|
||||
}
|
||||
|
||||
void flyer_setstart (edict_t *self)
|
||||
|
@ -487,7 +620,12 @@ void flyer_nextmove (edict_t *self)
|
|||
|
||||
void flyer_melee (edict_t *self)
|
||||
{
|
||||
self->monsterinfo.currentmove = &flyer_move_start_melee;
|
||||
// flyer.nextmove = ACTION_attack1;
|
||||
// self->monsterinfo.currentmove = &flyer_move_stop;
|
||||
if (self->mass > 50)
|
||||
flyer_run (self);
|
||||
else
|
||||
self->monsterinfo.currentmove = &flyer_move_start_melee;
|
||||
}
|
||||
|
||||
void flyer_check_melee(edict_t *self)
|
||||
|
@ -505,6 +643,11 @@ void flyer_pain (edict_t *self, edict_t *other, float kick, int damage)
|
|||
{
|
||||
int n;
|
||||
|
||||
// pmm - kamikaze's don't feel pain
|
||||
if (self->mass != 50)
|
||||
return;
|
||||
// pmm
|
||||
|
||||
if (self->health < (self->max_health / 2))
|
||||
self->s.skinnum = 1;
|
||||
|
||||
|
@ -539,7 +682,44 @@ void flyer_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage,
|
|||
gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
|
||||
BecomeExplosion1(self);
|
||||
}
|
||||
|
||||
|
||||
// PMM - kamikaze code .. blow up if blocked
|
||||
int flyer_blocked (edict_t *self, float dist)
|
||||
{
|
||||
vec3_t origin;
|
||||
|
||||
// kamikaze = 100, normal = 50
|
||||
if (self->mass == 100)
|
||||
{
|
||||
flyer_kamikaze_check(self);
|
||||
|
||||
// if the above didn't blow us up (i.e. I got blocked by the player)
|
||||
if (self->inuse)
|
||||
{
|
||||
if (self->monsterinfo.commander && self->monsterinfo.commander->inuse &&
|
||||
!strcmp(self->monsterinfo.commander->classname, "monster_carrier"))
|
||||
{
|
||||
self->monsterinfo.commander->monsterinfo.monster_slots++;
|
||||
// if ((g_showlogic) && (g_showlogic->value))
|
||||
// gi.dprintf ("suicide blocked, exploding. %d slots left\n", self->monsterinfo.commander->monsterinfo.monster_slots);
|
||||
}
|
||||
|
||||
VectorMA (self->s.origin, -0.02, self->velocity, origin);
|
||||
gi.WriteByte (svc_temp_entity);
|
||||
gi.WriteByte (TE_ROCKET_EXPLOSION);
|
||||
gi.WritePosition (origin);
|
||||
gi.multicast (self->s.origin, MULTICAST_PHS);
|
||||
|
||||
G_FreeEdict (self);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// we're a normal flyer
|
||||
if(blocked_checkshot (self, 0.25 + (0.05 * skill->value) ))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*QUAKED monster_flyer (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
|
||||
*/
|
||||
|
@ -570,7 +750,8 @@ void SP_monster_flyer (edict_t *self)
|
|||
|
||||
self->s.modelindex = gi.modelindex ("models/monsters/flyer/tris.md2");
|
||||
VectorSet (self->mins, -16, -16, -24);
|
||||
VectorSet (self->maxs, 16, 16, 32);
|
||||
// PMM - shortened to 16 from 32
|
||||
VectorSet (self->maxs, 16, 16, 16);
|
||||
self->movetype = MOVETYPE_STEP;
|
||||
self->solid = SOLID_BBOX;
|
||||
|
||||
|
@ -589,6 +770,7 @@ void SP_monster_flyer (edict_t *self)
|
|||
self->monsterinfo.melee = flyer_melee;
|
||||
self->monsterinfo.sight = flyer_sight;
|
||||
self->monsterinfo.idle = flyer_idle;
|
||||
self->monsterinfo.blocked = flyer_blocked;
|
||||
|
||||
gi.linkentity (self);
|
||||
|
||||
|
@ -598,3 +780,57 @@ void SP_monster_flyer (edict_t *self)
|
|||
flymonster_start (self);
|
||||
}
|
||||
|
||||
// PMM - suicide fliers
|
||||
void SP_monster_kamikaze (edict_t *self)
|
||||
{
|
||||
if (deathmatch->value)
|
||||
{
|
||||
G_FreeEdict (self);
|
||||
return;
|
||||
}
|
||||
|
||||
sound_sight = gi.soundindex ("flyer/flysght1.wav");
|
||||
sound_idle = gi.soundindex ("flyer/flysrch1.wav");
|
||||
sound_pain1 = gi.soundindex ("flyer/flypain1.wav");
|
||||
sound_pain2 = gi.soundindex ("flyer/flypain2.wav");
|
||||
sound_slash = gi.soundindex ("flyer/flyatck2.wav");
|
||||
sound_sproing = gi.soundindex ("flyer/flyatck1.wav");
|
||||
sound_die = gi.soundindex ("flyer/flydeth1.wav");
|
||||
|
||||
gi.soundindex ("flyer/flyatck3.wav");
|
||||
|
||||
self->s.modelindex = gi.modelindex ("models/monsters/flyer/tris.md2");
|
||||
VectorSet (self->mins, -16, -16, -24);
|
||||
// used to be 32 tall .. was WAY too big
|
||||
VectorSet (self->maxs, 16, 16, 16);
|
||||
self->movetype = MOVETYPE_STEP;
|
||||
self->solid = SOLID_BBOX;
|
||||
|
||||
self->s.sound = gi.soundindex ("flyer/flyidle1.wav");
|
||||
|
||||
self->s.effects |= EF_ROCKET;
|
||||
|
||||
self->health = 50;
|
||||
// PMM - normal flyer has mass of 50
|
||||
self->mass = 100;
|
||||
|
||||
self->pain = flyer_pain;
|
||||
self->die = flyer_die;
|
||||
|
||||
self->monsterinfo.stand = flyer_stand;
|
||||
self->monsterinfo.walk = flyer_walk;
|
||||
self->monsterinfo.run = flyer_run;
|
||||
self->monsterinfo.attack = flyer_attack;
|
||||
self->monsterinfo.melee = flyer_melee;
|
||||
self->monsterinfo.sight = flyer_sight;
|
||||
self->monsterinfo.idle = flyer_idle;
|
||||
|
||||
self->monsterinfo.blocked = flyer_blocked;
|
||||
|
||||
gi.linkentity (self);
|
||||
|
||||
self->monsterinfo.currentmove = &flyer_move_stand;
|
||||
self->monsterinfo.scale = MODEL_SCALE;
|
||||
|
||||
flymonster_start (self);
|
||||
}
|
||||
|
|
143
src/m_parasite.c
143
src/m_parasite.c
|
@ -275,7 +275,8 @@ void parasite_pain (edict_t *self, edict_t *other, float kick, int damage)
|
|||
}
|
||||
|
||||
|
||||
static qboolean parasite_drain_attack_ok (vec3_t start, vec3_t end)
|
||||
//static qboolean parasite_drain_attack_ok (vec3_t start, vec3_t end)
|
||||
qboolean parasite_drain_attack_ok (vec3_t start, vec3_t end)
|
||||
{
|
||||
vec3_t dir, angles;
|
||||
|
||||
|
@ -417,6 +418,144 @@ void parasite_attack (edict_t *self)
|
|||
}
|
||||
|
||||
|
||||
//================
|
||||
//ROGUE
|
||||
void parasite_jump_down (edict_t *self)
|
||||
{
|
||||
vec3_t forward,up;
|
||||
|
||||
monster_jump_start (self);
|
||||
|
||||
AngleVectors (self->s.angles, forward, NULL, up);
|
||||
VectorMA(self->velocity, 100, forward, self->velocity);
|
||||
VectorMA(self->velocity, 300, up, self->velocity);
|
||||
}
|
||||
|
||||
void parasite_jump_up (edict_t *self)
|
||||
{
|
||||
vec3_t forward,up;
|
||||
|
||||
monster_jump_start (self);
|
||||
|
||||
AngleVectors (self->s.angles, forward, NULL, up);
|
||||
VectorMA(self->velocity, 200, forward, self->velocity);
|
||||
VectorMA(self->velocity, 450, up, self->velocity);
|
||||
}
|
||||
|
||||
void parasite_jump_wait_land (edict_t *self)
|
||||
{
|
||||
if(self->groundentity == NULL)
|
||||
{
|
||||
self->monsterinfo.nextframe = self->s.frame;
|
||||
|
||||
if(monster_jump_finished (self))
|
||||
self->monsterinfo.nextframe = self->s.frame + 1;
|
||||
}
|
||||
else
|
||||
self->monsterinfo.nextframe = self->s.frame + 1;
|
||||
}
|
||||
|
||||
mframe_t parasite_frames_jump_up [] =
|
||||
{
|
||||
ai_move, -8, NULL,
|
||||
ai_move, -8, NULL,
|
||||
ai_move, -8, NULL,
|
||||
ai_move, -8, parasite_jump_up,
|
||||
ai_move, 0, NULL,
|
||||
ai_move, 0, NULL,
|
||||
ai_move, 0, parasite_jump_wait_land,
|
||||
ai_move, 0, NULL
|
||||
};
|
||||
mmove_t parasite_move_jump_up = { FRAME_jump01, FRAME_jump08, parasite_frames_jump_up, parasite_run };
|
||||
|
||||
mframe_t parasite_frames_jump_down [] =
|
||||
{
|
||||
ai_move, 0, NULL,
|
||||
ai_move, 0, NULL,
|
||||
ai_move, 0, NULL,
|
||||
ai_move, 0, parasite_jump_down,
|
||||
ai_move, 0, NULL,
|
||||
ai_move, 0, NULL,
|
||||
ai_move, 0, parasite_jump_wait_land,
|
||||
ai_move, 0, NULL
|
||||
};
|
||||
mmove_t parasite_move_jump_down = { FRAME_jump01, FRAME_jump08, parasite_frames_jump_down, parasite_run };
|
||||
|
||||
void parasite_jump (edict_t *self)
|
||||
{
|
||||
if(!self->enemy)
|
||||
return;
|
||||
|
||||
if(self->enemy->s.origin[2] > self->s.origin[2])
|
||||
self->monsterinfo.currentmove = ¶site_move_jump_up;
|
||||
else
|
||||
self->monsterinfo.currentmove = ¶site_move_jump_down;
|
||||
}
|
||||
|
||||
/*
|
||||
===
|
||||
Blocked
|
||||
===
|
||||
*/
|
||||
qboolean parasite_blocked (edict_t *self, float dist)
|
||||
{
|
||||
if(blocked_checkshot (self, 0.25 + (0.05 * skill->value) ))
|
||||
return true;
|
||||
|
||||
if(blocked_checkjump (self, dist, 256, 68))
|
||||
{
|
||||
parasite_jump (self);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(blocked_checkplat (self, dist))
|
||||
return true;
|
||||
}
|
||||
//ROGUE
|
||||
//================
|
||||
|
||||
|
||||
qboolean parasite_checkattack (edict_t *self)
|
||||
{
|
||||
vec3_t f, r, offset, start, end;
|
||||
trace_t tr;
|
||||
qboolean retval;
|
||||
|
||||
retval = M_CheckAttack (self);
|
||||
|
||||
if (!retval)
|
||||
return false;
|
||||
|
||||
AngleVectors (self->s.angles, f, r, NULL);
|
||||
VectorSet (offset, 24, 0, 6);
|
||||
G_ProjectSource (self->s.origin, offset, f, r, start);
|
||||
|
||||
VectorCopy (self->enemy->s.origin, end);
|
||||
if (!parasite_drain_attack_ok(start, end))
|
||||
{
|
||||
end[2] = self->enemy->s.origin[2] + self->enemy->maxs[2] - 8;
|
||||
if (!parasite_drain_attack_ok(start, end))
|
||||
{
|
||||
end[2] = self->enemy->s.origin[2] + self->enemy->mins[2] + 8;
|
||||
if (!parasite_drain_attack_ok(start, end))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
VectorCopy (self->enemy->s.origin, end);
|
||||
|
||||
tr = gi.trace (start, NULL, NULL, end, self, MASK_SHOT);
|
||||
if (tr.ent != self->enemy)
|
||||
{
|
||||
self->monsterinfo.aiflags |= AI_BLOCKED;
|
||||
|
||||
if(self->monsterinfo.attack)
|
||||
self->monsterinfo.attack(self);
|
||||
|
||||
self->monsterinfo.aiflags &= ~AI_BLOCKED;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===
|
||||
|
@ -520,6 +659,8 @@ void SP_monster_parasite (edict_t *self)
|
|||
self->monsterinfo.attack = parasite_attack;
|
||||
self->monsterinfo.sight = parasite_sight;
|
||||
self->monsterinfo.idle = parasite_idle;
|
||||
self->monsterinfo.blocked = parasite_blocked; // PGM
|
||||
self->monsterinfo.checkattack = parasite_checkattack;
|
||||
|
||||
gi.linkentity (self);
|
||||
|
||||
|
|
|
@ -692,7 +692,7 @@ mframe_t soldier_frames_attack3 [] =
|
|||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, soldier_attack3_refire},
|
||||
{ai_charge, 0, soldier_duck_up},
|
||||
{ai_charge, 0, monster_duck_up},
|
||||
{ai_charge, 0, NULL},
|
||||
{ai_charge, 0, NULL}
|
||||
};
|
||||
|
@ -744,20 +744,20 @@ void soldier_attack6_refire (edict_t *self)
|
|||
|
||||
mframe_t soldier_frames_attack6 [] =
|
||||
{
|
||||
{ai_charge, 10, NULL},
|
||||
{ai_charge, 4, NULL},
|
||||
{ai_charge, 12, NULL},
|
||||
{ai_charge, 11, soldier_fire8},
|
||||
{ai_charge, 13, NULL},
|
||||
{ai_charge, 18, NULL},
|
||||
{ai_charge, 15, NULL},
|
||||
{ai_charge, 14, NULL},
|
||||
{ai_charge, 11, NULL},
|
||||
{ai_charge, 8, NULL},
|
||||
{ai_charge, 11, NULL},
|
||||
{ai_charge, 12, NULL},
|
||||
{ai_charge, 12, NULL},
|
||||
{ai_charge, 17, soldier_attack6_refire}
|
||||
{ai_run, 10, soldier_start_charge},
|
||||
{ai_run, 4, NULL},
|
||||
{ai_run, 12, soldier_fire8},
|
||||
{ai_run, 11, NULL},
|
||||
{ai_run, 13, monster_done_dodge},
|
||||
{ai_run, 18, NULL},
|
||||
{ai_run, 15, NULL},
|
||||
{ai_run, 14, NULL},
|
||||
{ai_run, 11, NULL},
|
||||
{ai_run, 8, NULL},
|
||||
{ai_run, 11, NULL},
|
||||
{ai_run, 12, NULL},
|
||||
{ai_run, 12, NULL},
|
||||
{ai_run, 17, soldier_attack6_refire}
|
||||
};
|
||||
mmove_t soldier_move_attack6 = {FRAME_runs01, FRAME_runs14, soldier_frames_attack6, soldier_run};
|
||||
|
||||
|
|
Loading…
Reference in a new issue