From ec05aa5368209da123fdb06a44a9b4e4569a9896 Mon Sep 17 00:00:00 2001 From: Aaron Dean <8dino2@gmail.com> Date: Wed, 6 Sep 2023 16:59:30 -0400 Subject: [PATCH] Well, it compiles again.. --- actionlite/action/a_game.cpp | 24 +-- actionlite/g_local.h | 21 +- actionlite/g_weapon.cpp | 382 +++++++++++++++++++++++++++++++++++ actionlite/p_weapon.cpp | 36 +++- 4 files changed, 442 insertions(+), 21 deletions(-) diff --git a/actionlite/action/a_game.cpp b/actionlite/action/a_game.cpp index 25aac4f..f8a1eae 100644 --- a/actionlite/action/a_game.cpp +++ b/actionlite/action/a_game.cpp @@ -719,20 +719,20 @@ void PlaceHolder( edict_t * ent ); // p_weapon.c FindEdictByClassnum ================== */ -// edict_t *FindEdictByClassnum(char *classname, int classnum) -// { -// int i; -// edict_t *it; -// for (i = 0; i < globals.num_edicts; i++) -// { -// it = &g_edicts[i]; -// if (it->classname && (it->classnum == classnum) && (strcmp(it->classname, classname) == 0)) -// return it; -// } +edict_t *FindEdictByClassnum(const char *classname, int classnum) +{ + int i; + edict_t *it; + for (i = 0; i < globals.num_edicts; i++) + { + it = &g_edicts[i]; + if (it->classname && (it->classnum == classnum) && (strcmp(it->classname, classname) == 0)) + return it; + } -// return NULL; + return NULL; -// } +} // /********* Bulletholes/wall stuff ***********/ diff --git a/actionlite/g_local.h b/actionlite/g_local.h index 8ded776..8f35416 100644 --- a/actionlite/g_local.h +++ b/actionlite/g_local.h @@ -2127,9 +2127,6 @@ struct gunStats_t int damage; //Damage dealt }; -// C++ External symbol linker fixes? -bool team_round_going = false; // is an actual round of a team game going right now? - //====================================================================== // Action Add End //====================================================================== @@ -2483,9 +2480,8 @@ void kick_attack(edict_t *ent); void punch_attack(edict_t *ent); int knife_attack(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick); void knife_throw(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed); -void knife_touch(edict_t* ent, edict_t* other, cplane_t* plane, csurface_t* surf); -void fire_bullet_sparks(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int mod); -void fire_bullet_sniper(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int mod); +void fire_bullet_sparks(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, mod_id_t mod); +void fire_bullet_sniper(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, mod_id_t mod); void setFFState(edict_t* ent); // ACTION @@ -2794,8 +2790,14 @@ void PrintDeathMessage(char *msg, edict_t * gibee); // ACTION void CL_FixUpGender(edict_t *ent, const char *userinfo); void ClientFixLegs(edict_t *ent); +void PrintDeathMessage(char *msg, edict_t * gibee); +bool Pickup_Special (edict_t * ent, edict_t * other); +edict_t *FindEdictByClassnum (const char *classname, int classnum); +void DropSpecialWeapon (edict_t * ent); +void ReadySpecialWeapon (edict_t * ent); +void DropSpecialItem (edict_t * ent); -// ACTION +// ACTION END constexpr spawnflags_t SPAWNFLAG_LANDMARK_KEEP_Z = 1_spawnflag; @@ -3309,6 +3311,7 @@ struct gclient_t edict_t *chase_target; int32_t chase_mode; bool team_force; // are we forcing a team change + int jumping; // ammo capacities int32_t ammo_index; int32_t max_pistolmags; @@ -3618,6 +3621,10 @@ struct edict_t // Action int32_t light_level; + // action + bool splatted; + int32_t classnum; + int32_t typeNum; }; //============= diff --git a/actionlite/g_weapon.cpp b/actionlite/g_weapon.cpp index db1405b..e5e08ef 100644 --- a/actionlite/g_weapon.cpp +++ b/actionlite/g_weapon.cpp @@ -1278,6 +1278,388 @@ void fire_disintegrator(edict_t *self, const vec3_t &start, const vec3_t &forwar gi.linkentity(bfg); } +void kick_attack (edict_t *ent) +{ + vec3_t start; + vec3_t forward, right; + vec3_t offset; + int damage = 20, kick = 400, friendlyFire = 0; + trace_t tr; + vec3_t end; + char *genderstr; + + + AngleVectors(ent->client->v_angle, forward, right, NULL); + + VectorScale(forward, 0, ent->client->kick_origin); + + VectorSet(offset, 0, 0, ent->viewheight - 20); + P_ProjectSource(ent, ent->client->v_angle, offset, start, forward); + + VectorMA(start, 25, forward, end); + + PRETRACE(); + tr = gi.trace(ent->s.origin, vec3_origin, vec3_origin, end, ent, MASK_SHOT); + POSTTRACE(); + + // don't need to check for water + if (tr.surface && (tr.surface->flags & SURF_SKY)) + return; + + if (tr.fraction >= 1.0) + return; + + if (tr.ent->takedamage || KickDoor(&tr, ent, forward)) + { + ent->client->jumping = 0; // only 1 jumpkick per jump + + if (tr.ent->health <= 0) + return; + + if (tr.ent->client) + { + if (tr.ent->client->uvTime) + return; + + if (tr.ent != ent && ent->client && OnSameTeam( tr.ent, ent )) + friendlyFire = 1; + + if (friendlyFire/* && DMFLAGS(DF_NO_FRIENDLY_FIRE)*/){ + if (!teamplay->value || team_round_going || !ff_afterround->value) + return; + } + } + // zucc stop powerful upwards kicking + //forward[2] = 0; + // glass fx + // if (strcmp(tr.ent->classname, "func_explosive") == 0) + // CGF_SFX_ShootBreakableGlass(tr.ent, ent, &tr, MOD_KICK); + // else + T_Damage(tr.ent, ent, ent, forward, tr.endpos, tr.plane.normal, damage, kick, DAMAGE_NONE, MOD_KICK); + + // Stat add + //Stats_AddHit(ent, MOD_KICK, LOC_NO); + // Stat end + gi.sound(ent, CHAN_WEAPON, level.snd_kick, 1, ATTN_NORM, 0); + PlayerNoise (ent, ent->s.origin, PNOISE_SELF); + if (tr.ent->client && (tr.ent->client->pers.weapon->id == IT_WEAPON_M4 + || tr.ent->client->pers.weapon->id == IT_WEAPON_MP5 + || tr.ent->client->pers.weapon->id == IT_WEAPON_M3 + || tr.ent->client->pers.weapon->id == IT_WEAPON_SNIPER + || tr.ent->client->pers.weapon->id == IT_WEAPON_HANDCANNON)) // crandom() > .8 ) + { + // zucc fix this so reloading won't happen on the new gun! + tr.ent->client->reload_attempts = 0; + DropSpecialWeapon(tr.ent); + + gi.LocClient_Print(ent, PRINT_HIGH, "You kick %s's %s from their hands!\n", + tr.ent->client->pers.netname,tr.ent->client->pers.weapon->pickup_name); + + gi.LocClient_Print(tr.ent, PRINT_HIGH, "%s kicked your weapon from your hands!\n", ent->client->pers.netname); + + } else if(tr.ent->client && tr.ent->client->ctf_grapple && tr.ent->client->ctf_grapplestate == CTF_GRAPPLE_STATE_FLY) { + // hifi: if the player is shooting a grapple, lose it's focus + CTFPlayerResetGrapple(tr.ent); + } + } +} + +#include "m_player.h" +void punch_attack(edict_t * ent) +{ + vec3_t start, forward, right, offset, end; + int damage = 7, kick = 100, friendlyFire = 0; + int randmodify; + trace_t tr; + char *genderstr; + + AngleVectors(ent->client->v_angle, forward, right, NULL); + VectorScale(forward, 0, ent->client->kick_origin); + VectorSet(offset, 0, 0, ent->viewheight - 20); + P_ProjectSource(ent, ent->client->v_angle, offset, start, forward); + VectorMA(start, 50, forward, end); + PRETRACE(); + tr = gi.trace(ent->s.origin, vec3_origin, vec3_origin, end, ent, MASK_SHOT); + POSTTRACE(); + + if (!((tr.surface) && (tr.surface->flags & SURF_SKY))) + { + if (tr.fraction < 1.0 && tr.ent->takedamage) + { + if (tr.ent->health <= 0) + return; + + if (tr.ent->client) + { + if (tr.ent->client->uvTime) + return; + + if (tr.ent != ent && ent->client && OnSameTeam(tr.ent, ent)) + friendlyFire = 1; + + if (friendlyFire && !g_friendly_fire->integer){ + if (!teamplay->value || team_round_going || !ff_afterround->value) + return; + } + } + + // add some random damage, damage range from 8 to 20. + randmodify = rand() % 13 + 1; + damage += randmodify; + // modify kick by damage + kick += (randmodify * 10); + + // reduce damage, if he tries to punch within or out of water + if (ent->waterlevel) + damage -= rand() % 10 + 1; + // reduce kick, if victim is in water + if (tr.ent->waterlevel) + kick /= 2; + + T_Damage(tr.ent, ent, ent, forward, tr.endpos, tr.plane.normal, + damage, kick, DAMAGE_NONE, MOD_PUNCH); + // Stat add + //Stats_AddHit(ent, MOD_PUNCH, LOC_NO); + // Stat end + gi.sound(ent, CHAN_WEAPON, level.snd_kick, 1, ATTN_NORM, 0); + PlayerNoise(ent, ent->s.origin, PNOISE_SELF); + + //only hit weapon out of hand if damage >= 15 + if (tr.ent->client && (tr.ent->client->pers.weapon->id == IT_WEAPON_M4 + || tr.ent->client->pers.weapon->id == IT_WEAPON_MP5 + || tr.ent->client->pers.weapon->id == IT_WEAPON_M3 + || tr.ent->client->pers.weapon->id == IT_WEAPON_SNIPER + || tr.ent->client->pers.weapon->id == IT_WEAPON_HANDCANNON) && damage >= 15) + { + DropSpecialWeapon(tr.ent); + + gi.LocClient_Print(ent, PRINT_HIGH, "You hit %s's %s from their hands!\n", + tr.ent->client->pers.netname, tr.ent->client->pers.weapon->pickup_name); + + gi.LocClient_Print(tr.ent, PRINT_HIGH, "%s hit your weapon from your hands!\n", + ent->client->pers.netname); + } + return; + } + } + gi.sound(ent, CHAN_WEAPON, gi.soundindex("weapons/swish.wav"), 1, ATTN_NORM, 0); + + // animate the punch + // can't animate a punch when ducked + if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) + return; + if (ent->client->anim_priority >= ANIM_WAVE) + return; + + ent->s.frame = FRAME_flip01 - 1; + ent->client->anim_end = FRAME_attack8; + ent->client->anim_time = 0_ms; +} + +// zucc +// return values +// 0 - missed +// 1 - hit player +// 2 - hit wall + +int knife_attack (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick) +{ + trace_t tr; + vec3_t end; + + VectorMA (start, 45, aimdir, end); + + PRETRACE(); + tr = gi.trace(self->s.origin, vec3_origin, vec3_origin, end, self, MASK_SHOT); + POSTTRACE(); + + // don't need to check for water + if (tr.surface && (tr.surface->flags & SURF_SKY)) + return 0; // we hit the sky, call it a miss + + if (tr.fraction < 1.0) + { + //glass fx + // if (0 == strcmp(tr.ent->classname, "func_explosive")) + // { + // CGF_SFX_ShootBreakableGlass(tr.ent, self, &tr, MOD_KNIFE); + // } + // else + if (tr.ent->takedamage) + { + setFFState(self); + T_Damage(tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, DAMAGE_NONE, MOD_KNIFE); + return -2; + } + else + { + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_SPARKS); + gi.WritePosition (tr.endpos); + gi.WriteDir(tr.plane.normal); + gi.multicast(tr.endpos, MULTICAST_PVS, false); + return -1; + } + } + return 0; +} + +static int knives = 0; + +TOUCH(knife_touch) (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) -> void +{ + vec3_t origin; + edict_t *dropped, *knife; + vec3_t move_angles; + gitem_t *item; + + + if (other == ent->owner) + return; + + if (surf && (surf->flags & SURF_SKY)) { + G_FreeEdict (ent); + return; + } + + if (ent->owner->client) + { + gi.positioned_sound(ent->s.origin, ent, CHAN_WEAPON, gi.soundindex("weapons/clank.wav"), 1, ATTN_NORM, 0); + PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT); + } + + // calculate position for the explosion entity + VectorMA(ent->s.origin, -0.02, ent->velocity, origin); + + //glass fx + // if (0 == strcmp(other->classname, "func_explosive")) + // return; // ignore it, so it can bounce + + + if (other->takedamage) + { + // Players hit by throwing knives add it to their inventory. + if( other->client && (INV_AMMO(other,KNIFE_NUM) < other->client->knife_max) ) + INV_AMMO(other,KNIFE_NUM) ++; + + T_Damage(other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, 0, DAMAGE_NONE, MOD_KNIFE_THROWN); + } + else + { + // code to manage excess knives in the game, guarantees that + // no more than knifelimit knives will be stuck in walls. + // if knifelimit == 0 then it won't be in effect and it can + // start removing knives even when less than the limit are + // out there. + if (knifelimit->value != 0) + { + knives++; + + if (knives > knifelimit->value) + knives = 1; + + knife = FindEdictByClassnum("weapon_Knife", knives); + if (knife) + knife->nextthink = level.time + gtime_t::from_ms(4); + } + + dropped = G_Spawn(); + item = GET_ITEM(KNIFE_NUM); + + dropped->classname = item->classname; + dropped->item = item; + dropped->spawnflags = SPAWNFLAG_ITEM_DROPPED; + dropped->s.effects = item->world_model_flags; + dropped->s.renderfx = RF_GLOW; + VectorSet(dropped->mins, -15, -15, -15); + VectorSet(dropped->maxs, 15, 15, 15); + gi.setmodel(dropped, dropped->item->world_model); + dropped->solid = SOLID_TRIGGER; + dropped->movetype = MOVETYPE_TOSS; + dropped->touch = Touch_Item; + dropped->owner = ent; + dropped->gravity = 0; + //dropped->classnum = knives; + + move_angles = vectoangles(ent->velocity); + //AngleVectors (ent->s.angles, forward, right, up); + VectorCopy(ent->s.origin, dropped->s.origin); + //VectorCopy(dropped->s.origin, dropped->old_origin); + VectorCopy(move_angles, dropped->s.angles); + + dropped->nextthink = level.time + gtime_t::from_hz(120); + dropped->think = G_FreeEdict; + + // Stick to moving doors, platforms, etc. + if( CanBeAttachedTo(other) ) + AttachToEntity( dropped, other ); + + gi.linkentity(dropped); + + if (!(ent->waterlevel)) + { + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_SPARKS); + gi.WritePosition(origin); + gi.WriteDir(plane->normal); + gi.multicast(ent->s.origin, MULTICAST_PVS, false); + } + } + G_FreeEdict(ent); +} + + +void knife_throw(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed) +{ + edict_t *knife; + trace_t tr; + vec3_t angles; + + knife = G_Spawn(); + + VectorNormalize(dir); + VectorCopy(start, knife->s.origin); + //vectoangles(knife->s.angles); + angles = vectoangles(dir); + VectorCopy(angles, knife->s.angles); + + VectorScale(dir, speed, knife->velocity); + knife->movetype = MOVETYPE_TOSS; + + VectorSet(knife->avelocity, 1200, 0, 0); + + knife->movetype = MOVETYPE_TOSS; + knife->clipmask = MASK_SHOT; + knife->solid = SOLID_BBOX; + knife->s.effects = EF_NONE; //EF_ROTATE? + VectorClear(knife->mins); + VectorClear(knife->maxs); + knife->s.modelindex = gi.modelindex ("models/objects/knife/tris.md2"); + knife->owner = self; + knife->touch = knife_touch; + knife->nextthink = level.time + gtime_t::from_ms((8000 * 10) / speed); + knife->think = G_FreeEdict; + knife->dmg = damage; + knife->s.sound = level.snd_knifethrow; + knife->classname = "thrown_knife"; + //knife->typeNum = KNIFE_NUM; + + PRETRACE(); + tr = gi.trace(self->s.origin, vec3_origin, vec3_origin, knife->s.origin, knife, MASK_SHOT); + POSTTRACE(); + if (tr.fraction < 1.0) + { + VectorMA(knife->s.origin, -10, dir, knife->s.origin); + knife->touch(knife, tr.ent, tr, false); + } + + if (knife->inuse) { + VectorCopy(knife->s.origin, knife->s.old_origin); + //VectorCopy(knife->s.origin, knife->old_origin); + gi.linkentity(knife); + } +} + /* ===================================================================== setFFState: Save team wound count & warning state before an attack diff --git a/actionlite/p_weapon.cpp b/actionlite/p_weapon.cpp index 413ec37..02e4ee0 100644 --- a/actionlite/p_weapon.cpp +++ b/actionlite/p_weapon.cpp @@ -978,6 +978,29 @@ void Weapon_Repeating(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST } } +void DropSpecialWeapon(edict_t* ent) +{ + int itemNum = ent->client->pers.weapon->id ? : 0; + + // first check if their current weapon is a special weapon, if so, drop it. + if (itemNum >= MP5_NUM && itemNum <= SNIPER_NUM) + Drop_Weapon(ent, ent->client->pers.weapon); + else if (INV_AMMO(ent, SNIPER_NUM) > 0) + Drop_Weapon(ent, GET_ITEM(SNIPER_NUM)); + else if (INV_AMMO(ent, HC_NUM) > 0) + Drop_Weapon(ent, GET_ITEM(HC_NUM)); + else if (INV_AMMO(ent, M3_NUM) > 0) + Drop_Weapon(ent, GET_ITEM(M3_NUM)); + else if (INV_AMMO(ent, MP5_NUM) > 0) + Drop_Weapon(ent, GET_ITEM(MP5_NUM)); + else if (INV_AMMO(ent, M4_NUM) > 0) + Drop_Weapon(ent, GET_ITEM(M4_NUM)); + // special case, aq does this, guess I can support it + else if (itemNum == DUAL_NUM) + ent->client->newweapon = GET_ITEM(MK23_NUM); + +} + /* ====================================================================== @@ -2459,11 +2482,20 @@ static void fire_lead_ap(edict_t *self, vec3_t start, vec3_t aimdir, int damage, } +// zucc - for the M4 void fire_bullet_sparks (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, mod_id_t mod) { + setFFState(self); fire_lead_ap(self, start, aimdir, damage, kick, TE_BULLET_SPARKS, hspread, vspread, mod); } +// zucc - for sniper +void fire_bullet_sniper (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, mod_id_t mod) +{ + setFFState (self); + fire_lead_ap (self, start, aimdir, damage, kick, TE_GUNSHOT, hspread, vspread, mod); +} + void M4_Fire(edict_t* ent) { int i; @@ -2570,7 +2602,7 @@ void M4_Fire(edict_t* ent) damage *= 1.5f; G_LagCompensate(ent, start, dir); - fire_bullet_sparks(ent, start, forward, damage, kick, spread, spread, IT_WEAPON_M4); + fire_bullet_sparks(ent, start, forward, damage, kick, spread, spread, MOD_M4); G_UnLagCompensate(); //Stats_AddShot(ent, MOD_M4); @@ -2878,7 +2910,7 @@ void Sniper_Fire(edict_t* ent) P_ProjectSource(ent, ent->client->v_angle, forward, start, dir); G_LagCompensate(ent, start, dir); //If no reload, fire normally. - fire_bullet_sniper(ent, start, forward, damage, kick, spread, spread, IT_WEAPON_SNIPER); + fire_bullet_sniper(ent, start, forward, damage, kick, spread, spread, MOD_SNIPER); //Stats_AddShot(ent, MOD_SNIPER); G_UnLagCompensate();