nuclide/Source/shared/valve/w_tripmine.c

289 lines
5.9 KiB
C

/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
enum
{
TRIPMINE_IDLE1,
TRIPMINE_IDLE2,
TRIPMINE_FIRE1,
TRIPMINE_FIRE2,
TRIPMINE_FIDGET,
TRIPMINE_HOLSTER,
TRIPMINE_DRAW,
TRIPMINE_WORLD,
TRIPMINE_GROUND,
};
void w_tripmine_precache(void)
{
precache_model("models/v_tripmine.mdl");
precache_model("models/p_tripmine.mdl");
precache_sound("weapons/mine_deploy.wav");
precache_sound("weapons/mine_charge.wav");
precache_sound("weapons/mine_activate.wav");
}
string w_tripmine_vmodel(void)
{
return "models/v_tripmine.mdl";
}
string w_tripmine_wmodel(void)
{
return "models/v_tripmine.mdl";
}
string w_tripmine_pmodel(void)
{
return "models/p_tripmine.mdl";
}
string w_tripmine_deathmsg(void)
{
return "";
}
void w_tripmine_pickup(void)
{
#ifdef SSQC
player pl = (player)self;
pl.ammo_tripmine = bound(0, pl.ammo_tripmine + 1, 10);
#endif
}
void w_tripmine_draw(void)
{
#ifdef CSQC
Weapons_ViewAnimation(TRIPMINE_DRAW);
#else
player pl = (player)self;
Weapons_UpdateAmmo(pl, __NULL__, pl.ammo_tripmine, __NULL__);
#endif
}
void w_tripmine_holster(void)
{
}
#ifdef SSQC
void w_tripmine_trip(int unused)
{
/* This is to prevent infinite loops in Damage_Radius */
self.vDeath =
self.vPain = __NULL__;
self.takedamage = DAMAGE_NO;
Effect_CreateExplosion(self.origin);
Damage_Radius(self.origin, self.owner, 150, 150 * 2.5f, TRUE);
sound(self, CHAN_WEAPON, sprintf( "weapons/explode%d.wav", floor( random() * 2 ) + 3 ), 1, ATTN_NORM);
remove(self);
}
void w_tripmine_ready(void)
{
makevectors(self.angles);
traceline(self.origin, self.origin + v_forward * 2048, FALSE, self);
if (!self.health) {
self.SendFlags = 1;
self.health = 1;
self.vDeath =
self.vPain = w_tripmine_trip;
self.takedamage = DAMAGE_YES;
self.solid = SOLID_BBOX;
setsize(self, [-8,-8,-8], [8,8,8]);
self.armor = trace_plane_dist;
sound(self, CHAN_WEAPON, "weapons/mine_activate.wav", 1, ATTN_NORM);
}
if (trace_plane_dist != self.armor) {
w_tripmine_trip(0);
}
self.nextthink = time;
}
#endif
#ifdef SSQC
float w_tripmine_sendentity(entity pvsent, float flags)
{
WriteByte(MSG_ENTITY, ENT_TRIPMINE);
WriteCoord(MSG_ENTITY, self.origin[0]);
WriteCoord(MSG_ENTITY, self.origin[1]);
WriteCoord(MSG_ENTITY, self.origin[2]);
WriteCoord(MSG_ENTITY, self.angles[0]);
WriteCoord(MSG_ENTITY, self.angles[1]);
WriteCoord(MSG_ENTITY, self.angles[2]);
WriteFloat(MSG_ENTITY, self.armor);
WriteByte(MSG_ENTITY, self.health);
WriteShort(MSG_ENTITY, self.modelindex);
return TRUE;
}
#else
.float health;
.float armor;
float w_tripmine_predraw(void)
{
if (self.health) {
makevectors(self.angles);
traceline(self.origin, self.origin + v_forward * 8196, FALSE, self);
trailparticles(BEAM_TRIPMINE, self, self.origin, trace_endpos);
}
addentity(self);
return PREDRAW_NEXT;
}
void w_tripmine_parse(void)
{
self.origin[0] = readcoord();
self.origin[1] = readcoord();
self.origin[2] = readcoord();
self.angles[0] = readcoord();
self.angles[1] = readcoord();
self.angles[2] = readcoord();
self.armor = readfloat();
self.health = readbyte();
self.modelindex = readshort();
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_NONE;
self.predraw = w_tripmine_predraw;
self.drawmask = MASK_ENGINE;
self.frame = TRIPMINE_WORLD;
setcustomskin(self, "", "geomset 0 2\ngeomset 1 2\n");
setorigin(self, self.origin);
}
#endif
void w_tripmine_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
#ifdef CSQC
if (pl.a_ammo1 <= 0) {
return;
}
#else
if (pl.ammo_tripmine <= 0) {
return;
}
#endif
Weapons_MakeVectors();
traceline(Weapons_GetCameraPos(), Weapons_GetCameraPos() + v_forward * 64, FALSE, pl);
if (trace_fraction == 1.0f) {
return;
}
#ifdef CSQC
Weapons_ViewAnimation(TRIPMINE_FIRE2);
#else
entity mine = spawn();
setmodel(mine, "models/v_tripmine.mdl");
setorigin(mine, trace_endpos);
mine.angles = vectoangles( trace_plane_normal );
setorigin(mine, trace_endpos - (v_forward * 8));
mine.think = w_tripmine_ready;
mine.nextthink = time + 4.0f;
mine.SendEntity = w_tripmine_sendentity;
mine.SendFlags = 1;
//mine.owner = pl;
sound(mine, CHAN_WEAPON, "weapons/mine_charge.wav", 1, ATTN_NORM);
sound(self, CHAN_WEAPON, "weapons/mine_deploy.wav", 1, ATTN_NORM);
pl.ammo_tripmine--;
if (pl.ammo_tripmine <= 0) {
Weapons_RemoveItem(pl, WEAPON_TRIPMINE);
} else {
Weapons_UpdateAmmo(pl, __NULL__, pl.ammo_tripmine, __NULL__);
}
#endif
pl.w_attack_next = 0.5f;
pl.w_idle_next = 2.5f;
}
void w_tripmine_secondary(void)
{
}
void w_tripmine_reload(void)
{
}
void w_tripmine_release(void)
{
int r;
player pl = (player)self;
if (pl.w_idle_next > 0.0) {
return;
}
r = floor(random(0,3));
switch (r) {
case 0:
Weapons_ViewAnimation(TRIPMINE_IDLE1);
pl.w_idle_next = 3.0f;
break;
case 1:
Weapons_ViewAnimation(TRIPMINE_IDLE2);
pl.w_idle_next = 2.0f;
break;
default:
Weapons_ViewAnimation(TRIPMINE_FIDGET);
pl.w_idle_next = 3.333333f;
break;
}
}
float w_tripmine_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CR_AIMTRIPMINE : ANIM_AIMTRIPMINE;
}
void w_tripmine_hud(void)
{
#ifdef CSQC
HUD_DrawAmmo2();
#endif
}
void w_tripmine_hudpic(int s, vector pos)
{
#ifdef CSQC
if (s) {
drawsubpic(pos, [170,45], "sprites/640hud6.spr_0.tga", [0,90/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE);
} else {
drawsubpic(pos, [170,45], "sprites/640hud3.spr_0.tga", [0,90/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE);
}
#endif
}
weapon_t w_tripmine =
{
ITEM_TRIPMINE,
4,
2,
w_tripmine_draw,
w_tripmine_holster,
w_tripmine_primary,
w_tripmine_secondary,
w_tripmine_reload,
w_tripmine_release,
w_tripmine_hud,
w_tripmine_precache,
w_tripmine_pickup,
w_tripmine_vmodel,
w_tripmine_wmodel,
w_tripmine_pmodel,
w_tripmine_deathmsg,
w_tripmine_aimanim,
w_tripmine_hudpic
};
#ifdef SSQC
void weapon_tripmine(void) {
Weapons_InitItem(WEAPON_TRIPMINE);
}
#endif