marrub
/
Lithia
Archived
1
0
Fork 0
This repository has been archived on 2023-06-17. You can view files and clone it, but cannot push or open issues/pull-requests.
Lithia/source/Main/p_weapons.c

383 lines
9.0 KiB
C

// Copyright © 2016-2017 Graham Sanderson, all rights reserved.
// vim: columns=110
#include "lith_player.h"
#include "lith_monster.h"
#include "lith_hudid.h"
#include <math.h>
// Static Functions ----------------------------------------------------------|
//
// GiveWeaponItem
//
static void GiveWeaponItem(int parm, int slot)
{
switch(parm)
{
case weapon_c_fist:
case weapon_fist: InvGive("Lith_Death", 1); break;
case weapon_c_spas: InvGive("Lith_ShellAmmo", 8); break;
case weapon_ssg: InvGive("Lith_ShellAmmo", 4); break;
case weapon_c_sniper: InvGive("Lith_RocketAmmo", 6); break;
case weapon_launcher: InvGive("Lith_RocketAmmo", 2); break;
case weapon_c_plasma:
case weapon_plasma: InvGive("Lith_PlasmaAmmo", 1500); break;
case weapon_c_shipgun: InvGive("Lith_CannonAmmo", 5); break;
case weapon_bfg: InvGive("Lith_CannonAmmo", 4); break;
case weapon_fd_jpcp_chainsaw:
InvGive("FDGotChainsaw", 1);
break;
}
if(parm > weapon_max_lith) switch(slot)
{
case 2: InvGive("Lith_BulletAmmo", 20); break;
case 3: InvGive("Lith_ShellAmmo", 10); break;
case 4: InvGive("Lith_BulletAmmo", 40); break;
case 5: InvGive("Lith_RocketAmmo", 5); break;
case 6: InvGive("Lith_PlasmaAmmo", 50); break;
case 7: InvGive("Lith_CannonAmmo", 2); break;
}
}
//
// WeaponGrab
//
static void WeaponGrab(struct player *p, weaponinfo_t const *info)
{
if(!p->getUpgrActive(UPGR_7777777)) ACS_LocalAmbientSound(info->pickupsound, 127);
else ACS_LocalAmbientSound("marathon/pickup", 127);
switch(info->slot)
{
default: Lith_FadeFlash(255, 255, 255, 0.5, 0.4); break;
case 3: Lith_FadeFlash(0, 255, 0, 0.5, 0.5); break;
case 4: Lith_FadeFlash(255, 255, 0, 0.5, 0.5); break;
case 5: Lith_FadeFlash(255, 64, 0, 0.5, 0.6); break;
case 6: Lith_FadeFlash(0, 0, 255, 0.5, 0.6); break;
case 7: Lith_FadeFlash(255, 0, 0, 0.5, 0.7); break;
}
}
//
// Lith_PickupScore
//
static void Lith_PickupScore(struct player *p, int parm)
{
weaponinfo_t const *info = &weaponinfo[parm];
i96 score = 4000 * info->slot;
GiveWeaponItem(parm, info->slot);
score = p->giveScore(score);
if(info->type < weapon_max_lith)
p->log("> Sold the %S for %lli\Cnscr\C-.", Language("LITH_TXT_INFO_SHORT_%S", info->name), score);
else
p->log("> Sold the slot %i weapon for %lli\Cnscr\C-.", info->slot, score);
}
// Extern Functions ----------------------------------------------------------|
//
// Lith_WeaponPickup
//
script acs bool Lith_WeaponPickup(int name)
{
extern void Lith_PickupMessage(struct player *p, weaponinfo_t const *info);
extern int Lith_WeaponFromName(struct player *p, int name);
struct player *p = LocalPlayer;
if(NoPlayer(p)) return false;
bool weaponstay = ACS_GetCVar("sv_weaponstay");
int parm = weapon_unknown;
parm = Lith_WeaponFromName(p, name);
if(parm >= weapon_max || parm < weapon_min)
return true;
weaponinfo_t const *info = &weaponinfo[parm];
if(HasWeapon(p, parm))
{
if(!weaponstay) {
WeaponGrab(p, info);
Lith_PickupScore(p, parm);
}
return !weaponstay;
}
else
{
WeaponGrab(p, info);
p->weaponsheld++;
p->bipUnlock(info->name);
GiveWeaponItem(parm, info->slot);
Lith_PickupMessage(p, info);
if(info->type != weapon_fd_jpcp_chainsaw) // fuck a bitch
InvGive(info->classname, 1);
return !weaponstay;
}
}
//
// Lith_CircleSpread
//
script acs fixed Lith_CircleSpread(fixed mdx, fixed mdy, bool getpitch)
{
static fixed A;
static fixed P;
if(!getpitch)
{
fixed dx = ACS_RandomFixed(mdx, 0.0);
fixed dy = ACS_RandomFixed(mdy, 0.0);
fixed a = ACS_RandomFixed(1.0, -1.0);
A = ACS_Sin(a) * dx;
P = ACS_Cos(a) * dy;
return A;
}
else
return P;
}
//
// Lith_ChargeFistDamage
//
script acs int Lith_ChargeFistDamage()
{
int amount = InvNum("Lith_FistCharge");
InvTake("Lith_FistCharge", 0x7FFFFFFF);
return amount * ACS_Random(1, 3);
}
//
// Lith_GSInit_Weapon
//
void Lith_GSInit_Weapon(void)
{
for(int i = 0; i < weapon_max; i++)
{
weaponinfo_t *info = (weaponinfo_t *)&weaponinfo[i];
info->type = i;
}
}
//
// Lith_PlayerPreWeapons
//
// Update information on what weapons we have.
//
script void Lith_PlayerPreWeapons(struct player *p)
{
weapondata_t *w = &p->weapon;
w->prev = w->cur;
// Reset data temporarily.
w->cur = null;
for(int i = 0; i < SLOT_MAX; i++)
w->slot[i] = 0;
// Iterate over each weapon setting information on it.
for(int i = weapon_min; i < weapon_max; i++)
{
weaponinfo_t const *info = &weaponinfo[i];
invweapon_t *wep = &w->inv[i];
if(!(p->pclass & info->pclass) || !(wep->owned = InvNum(info->classname)))
continue;
w->slot[info->slot] += wep->owned;
// Check for currently held weapon.
if(!w->cur && p->weaponclass == info->classname)
w->cur = wep;
wep->info = info;
wep->ammotype = info->defammotype;
wep->ammoclass = info->defammoclass;
// Special exceptions.
switch(i)
{
case weapon_shotgun:
if(p->getUpgrActive(UPGR_GaussShotty)) {
wep->ammotype = AT_NMag;
wep->ammoclass = "Lith_GaussShotsFired";
}
break;
case weapon_c_spas:
if(p->getUpgrActive(UPGR_SPAS_B))
wep->ammotype = AT_Ammo;
break;
case weapon_c_smg:
if(p->getUpgrActive(UPGR_SMG_A))
wep->ammoclass = "Lith_SMGShotsFired2";
break;
}
// Set magazine class if this weapon doesn't take ammo.
if(wep->ammotype & AT_NMag && !(wep->ammotype & AT_Ammo))
wep->magclass = wep->ammoclass;
// Check for currently held weapon.
if(!w->cur && ACS_StrICmp(p->weaponclass, info->classname) == 0)
w->cur = wep;
// Remove inactive magic weapons.
else if(info->flags & wf_magic && ++wep->magictake > 20)
{
InvTake(info->classname, 1);
wep->magictake = 0;
continue;
}
// Auto-reload anything else.
if(p->autoreload && wep->ammotype & AT_NMag && !(info->flags & wf_magic))
{
if(wep->autoreload >= 35 * 5)
ACS_TakeInventory(wep->magclass, 999);
if(w->cur != wep) wep->autoreload++;
else wep->autoreload = 0;
}
}
if(!w->cur) w->cur = &w->inv[weapon_unknown];
}
//
// Lith_PlayerUpdateWeapons
//
script void Lith_PlayerUpdateWeapons(struct player *p)
{
__with(int heat = ACS_CheckInventory("Lith_SMGHeat");) {
if(heat < 100) ACS_TakeInventory("Lith_SMGHeat", 5);
else if(heat < 200) ACS_TakeInventory("Lith_SMGHeat", 4);
else if(heat < 300) ACS_TakeInventory("Lith_SMGHeat", 3);
else if(heat < 400) ACS_TakeInventory("Lith_SMGHeat", 2);
else ACS_TakeInventory("Lith_SMGHeat", 1);
}
if(p->weapontype == weapon_c_delear)
ACS_GiveInventory("Lith_DelearSpriteDisplay", 1);
}
//
// Lith_AmmoRunOut
//
script acs fixed Lith_AmmoRunOut(bool ro, fixed mul)
{
withplayer(LocalPlayer)
{
__str cl = p->weapon.cur->magclass;
fixed inv = InvNum(cl) / (fixed)InvMax(cl);
mul = mul ? mul : 1.2;
if(ro) inv = inv * mul;
else inv = mul - inv * 0.35;
return minmax(inv, 0.0, 1.0);
}
return 0;
}
//
// Lith_GetFinalizerMaxHealth
//
script acs int Lith_GetFinalizerMaxHealth(void)
{
int sh = ACS_GetActorProperty(0, APROP_SpawnHealth);
ifauto(dmon_t *, m, DmonPtr())
return sh + (m->maxhealth - sh) * 0.5;
else
return sh;
}
//
// Lith_SwitchRifleMode
//
script acs void Lith_SwitchRifleFiremode(void)
{
withplayer(LocalPlayer)
{
int max = rifle_firemode_max;
if(!p->getUpgrActive(UPGR_RifleModes))
max--;
p->riflefiremode = ++p->riflefiremode % max;
ACS_LocalAmbientSound("weapons/rifle/firemode", 127);
}
}
//
// Lith_ResetRifleMode
//
script acs void Lith_ResetRifleMode()
{
withplayer(LocalPlayer)
if(p->getCVarI("lith_weapons_riflemodeclear"))
p->riflefiremode = rifle_firemode_auto;
}
//
// Lith_SurgeOfDestiny
//
script acs void Lith_SurgeOfDestiny(void)
{
for(int i = 0; i < (35 * 7) / 2; i++) {
InvGive("Lith_SurgeOfDestiny", 1);
ACS_Delay(2);
}
}
//
// Lith_GetWRF
//
script acs int Lith_GetWRF(void)
{
enum
{
WRF_NOBOB = 1,
WRF_NOSWITCH = 2,
WRF_NOPRIMARY = 4,
WRF_NOSECONDARY = 8,
WRF_NOFIRE = WRF_NOPRIMARY | WRF_NOSECONDARY,
WRF_ALLOWRELOAD = 16,
WRF_ALLOWZOOM = 32,
WRF_DISABLESWITCH = 64,
WRF_ALLOWUSER1 = 128,
WRF_ALLOWUSER2 = 256,
WRF_ALLOWUSER3 = 512,
WRF_ALLOWUSER4 = 1024
};
int flags = 0;
withplayer(LocalPlayer)
{
if(p->semifrozen)
flags |= WRF_NOFIRE;
if(p->pclass & (pcl_marine | pcl_darklord))
flags |= WRF_ALLOWUSER4;
}
return flags;
}
// EOF