// Copyright © 2016-2017 Graham Sanderson, all rights reserved. // vim: columns=110 #include "lith_player.h" #include "lith_monster.h" #include "lith_hudid.h" #include // 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