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_data.c

390 lines
10 KiB
C

// Copyright © 2016-2017 Graham Sanderson, all rights reserved.
#include "lith_common.h"
#include "lith_player.h"
#include "lith_version.h"
#include "lith_world.h"
#include "lith_monster.h"
#include <math.h>
// Static Functions ----------------------------------------------------------|
//
// SetupAttributes
//
static void SetupAttributes(struct player *p)
{
p->attr.names[at_acc] = "ACC";
p->attr.names[at_def] = "DEF";
p->attr.names[at_str] = "STR";
p->attr.names[at_vit] = "VIT";
p->attr.names[at_stm] = "STM";
p->attr.names[at_luk] = "LUK";
p->attr.names[at_rge] = "RGE";
if(p->pclass & pcl_robot) {
p->attr.names[at_vit] = "POT";
p->attr.names[at_stm] = "REP";
} else if(p->pclass & pcl_nonhuman) {
p->attr.names[at_vit] = "POT";
p->attr.names[at_stm] = "REG";
}
p->attr.expnext = 500;
p->attr.level = 1;
}
//
// SetPClass
//
static void SetPClass(struct player *p)
{
__with(__str cl = p->pcstr = ACS_GetActorClass(0);) {
if(cl == "Lith_MarinePlayer" ) p->pclass = pcl_marine;
else if(cl == "Lith_CyberMagePlayer") p->pclass = pcl_cybermage;
else if(cl == "Lith_InformantPlayer") p->pclass = pcl_informant;
else if(cl == "Lith_WandererPlayer" ) p->pclass = pcl_wanderer;
else if(cl == "Lith_AssassinPlayer" ) p->pclass = pcl_assassin;
else if(cl == "Lith_DarkLordPlayer" ) p->pclass = pcl_darklord;
else if(cl == "Lith_ThothPlayer" ) p->pclass = pcl_thoth;
else if(cl == "FDPlutPlayer" || cl == "FDTNTPlayer" ||
cl == "FDDoom2Player" || cl == "FDAliensPlayer" ||
cl == "FDJPCPPlayer" || cl == "FDBTSXPlayer")
p->pclass = pcl_fdoomer;
else if(cl == "DoomRLMarine" || cl == "DoomRLScout" ||
cl == "DoomRLTechnician" || cl == "DoomRLRenegade" ||
cl == "DoomRLDemolitionist" || cl == "DoomRLCommando")
p->pclass = pcl_drla;
else for(;;)
{
Log("Invalid player class detected, everything is going to explode!");
ACS_Delay(1);
}
}
}
// Extern Functions ----------------------------------------------------------|
//
// Lith_PlayerCurWeaponType
//
stkcall int Lith_PlayerCurWeaponType(struct player *p)
{
return p->weapon.cur->info->type;
}
//
// Lith_ButtonPressed
//
stkcall bool Lith_ButtonPressed(struct player *p, int bt)
{
return p->buttons & bt && !(p->old.buttons & bt);
}
//
// Lith_SetPlayerVelocity
//
stkcall bool Lith_SetPlayerVelocity(struct player *p, fixed velx, fixed vely, fixed velz, bool add)
{
if(add)
p->velx += velx, p->vely += vely, p->velz += velz;
else
p->velx = velx, p->vely = vely, p->velz = velz;
return ACS_SetActorVelocity(p->tid, velx, vely, velz, add, true);
}
//
// Lith_ValidatePlayerTID
//
void Lith_ValidatePlayerTID(struct player *p)
{
if(ACS_ActivatorTID() == 0) {
ACS_Thing_ChangeTID(0, p->tid = ACS_UniqueTID());
LogDebug(log_dev, "set ptid from 0 to %i", p->tid);
} else if(p->tid != ACS_ActivatorTID()) {
LogDebug(log_dev, "set ptid from %i to %i", p->tid, ACS_ActivatorTID());
p->tid = ACS_ActivatorTID();
}
}
//
// Lith_PlayerUpdateData
//
// Update all of the player's data.
//
script void Lith_PlayerUpdateData(struct player *p)
{
static int const warpflags = WARPF_NOCHECKPOSITION | WARPF_MOVEPTR |
WARPF_WARPINTERPOLATION | WARPF_COPYINTERPOLATION | WARPF_COPYPITCH;
ACS_Warp(p->cameratid, 4, 0, ACS_GetActorViewHeight(0), 0, warpflags);
ACS_Warp(p->weathertid, 4, 0, ACS_GetActorViewHeight(0), 0, warpflags);
p->x = ACS_GetActorX(0);
p->y = ACS_GetActorY(0);
p->z = ACS_GetActorZ(0);
p->floorz = ACS_GetActorFloorZ(0);
p->velx = ACS_GetActorVelX(0);
p->vely = ACS_GetActorVelY(0);
p->velz = ACS_GetActorVelZ(0);
p->pitch = ACS_GetActorPitch(0) - p->addpitch;
p->yaw = ACS_GetActorAngle(0) - p->addyaw;
p->roll = ACS_GetActorRoll (0) - p->addroll;
p->pitchf = ((-p->pitch + 0.25) * 2) * pi;
p->yawf = p->yaw * tau - pi;
p->pitchv = ACS_GetPlayerInputFixed(-1, INPUT_PITCH);
p->yawv = ACS_GetPlayerInputFixed(-1, INPUT_YAW);
p->forwardv = ACS_GetPlayerInputFixed(-1, INPUT_FORWARDMOVE);
p->sidev = ACS_GetPlayerInputFixed(-1, INPUT_SIDEMOVE);
p->upv = ACS_GetPlayerInputFixed(-1, INPUT_UPMOVE);
p->buttons = ACS_GetPlayerInput(-1, INPUT_BUTTONS);
p->name = StrParam("%tS", p->num);
p->weaponclass = ACS_GetWeapon();
p->scopetoken = InvNum("Lith_WeaponScopedToken");
p->keys.rc = InvNum("RedCard") ||
InvNum("KeyGreen");
p->keys.yc = InvNum("YellowCard") ||
InvNum("KeyYellow");
p->keys.bc = InvNum("BlueCard") ||
InvNum("KeyBlue");
p->keys.rs = InvNum("RedSkull");
p->keys.ys = InvNum("YellowSkull");
p->keys.bs = InvNum("BlueSkull");
DebugStat("attr points: %u\nexp: lv.%u %lu/%lu\n",
p->attr.points, p->attr.level, p->attr.exp, p->attr.expnext);
DebugStat("x: %k\ny: %k\nz: %k\n", p->x, p->y, p->z);
DebugStat("vx: %k\nvy: %k\nvz: %k\nvel: %k\n", p->velx, p->vely, p->velz, p->getVel());
DebugStat("a.y: %k\na.p: %k\n", p->yaw * 360, p->pitch * 360);
}
//
// Lith_GiveMail
//
script acs void Lith_GiveMail(int num)
{
static __str const names[] = {
"Intro",
"Cluster1",
"Cluster2",
"Cluster3",
"Phantom",
"JamesDefeated",
"MakarovDefeated",
"IsaacDefeated"
};
num %= countof(names);
withplayer(LocalPlayer)
p->deliverMail(names[num]);
}
//
// Lith_ClearTextBuf
//
stkcall void Lith_ClearTextBuf(struct player *p)
{
memset(p->txtbuf, 0, sizeof(p->txtbuf));
p->tbptr = 0;
}
//
// Lith_KeyDown
//
script acs void Lith_KeyDown(int pnum, int ch)
{
withplayer(&players[pnum])
if(p->tbptr + 1 < countof(p->txtbuf))
p->txtbuf[p->tbptr++] = ch;
}
//
// Lith_GiveEXP
//
stkcall void Lith_GiveEXP(struct player *p, u64 amt)
{
#pragma GDCC FIXED_LITERAL OFF
struct player_attributes *a = &p->attr;
while(a->exp + amt >= a->expnext) {
a->level++;
a->points += 5;
a->expnext = 500 + (a->level * pow(1.385, a->level * 0.2) * 340);
p->attr.sup = p->attr.cur;
}
a->exp += amt;
}
//
// Lith_ResetPlayer
//
// Reset some things on the player when they spawn.
//
script void Lith_ResetPlayer(struct player *p)
{
//
// Zero-init
if(!p->wasinit) {
*p = (struct player){};
p->wasinit = true;
}
//
// Constant data
p->active = true;
p->reinit = p->dead = false;
p->num = ACS_PlayerNumber();
p->bipptr = &p->bip;
//
// Static data (pre-init)
if(!p->staticinit)
{
SetPClass(p);
SetupAttributes(p);
// i cri tears of pain for APROP_SpawnHealth
p->viewheight = ACS_GetActorViewHeight(0);
p->jumpheight = ACS_GetActorPropertyFixed(0, APROP_JumpZ);
p->spawnhealth = ACS_GetActorProperty(0, APROP_Health);
p->spawndfactor = ACS_GetActorPropertyFixed(0, APROP_DamageFactor);
p->maxhealth = p->spawnhealth;
p->discount = 1.0;
p->stepnoise = StrParam("player/%S/step", p->classname);
switch(ACS_GetPlayerInfo(p->num, PLAYERINFO_GENDER))
{
case 0: p->pronoun = pro_male; break;
case 1: p->pronoun = pro_female; break;
case 2: p->pronoun = pro_object; break;
}
}
//
// Map-static data
p->old = (struct player_delta){};
// If the map sets the TID on the first tic, it could already be set here.
p->tid = 0;
p->validateTID();
// This keeps spawning more camera actors when you die, but that should be
// OK as long as you don't die 2 billion times.
ACS_SpawnForced("Lith_CameraHax", 0, 0, 0, p->cameratid = ACS_UniqueTID());
ACS_SpawnForced("Lith_CameraHax", 0, 0, 0, p->weathertid = ACS_UniqueTID());
if(world.dbgScore)
p->score = 0xFFFFFFFFFFFFFFFFll;
//
// Reset data
// Any linked lists on the player need to be initialized here.
p->loginfo.hud.free();
p->hudstrlist.free(true);
if(!p->loginfo.full.next) p->loginfo.full.construct();
if(!p->loginfo.maps.next) p->loginfo.maps.construct();
// pls not exit map with murder thingies out
// is bad practice
ACS_SetPlayerProperty(0, false, PROP_INSTANTWEAPONSWITCH);
ACS_SetActorPropertyFixed(0, APROP_ViewHeight, p->viewheight);
InvTake("Lith_WeaponScopedToken", 999);
Lith_PlayerResetCBIGUI(p);
p->frozen = 0;
p->semifrozen = 0;
p->addpitch = 0.0f;
p->addyaw = 0.0f;
p->addroll = 0.0f;
p->bobpitch = 0.0f;
p->bobyaw = 0.0f;
p->extrpitch = 0.0f;
p->extryaw = 0.0f;
p->scoreaccum = 0;
p->scoreaccumtime = 0;
p->scoremul = 1.3;
p->alpha = 1;
//
// Re-init data
if(!p->bip.init)
Lith_PlayerInitBIP(p);
if(!p->upgrinit)
Lith_PlayerInitUpgrades(p);
else
Lith_PlayerReinitUpgrades(p);
//
// Static data
if(!p->staticinit)
{
p->log("> Lithia " Lith_Version " :: Compiled %S", __DATE__);
if(world.dbgLevel) {
p->logH("> player is %u bytes long!", sizeof(struct player) * 4);
p->logH("> strnull is \"%S\"", strnull);
PrintDmonAllocSize(p);
} else {
p->logH("> Press \"%jS\" to open the menu.", "lith_k_opencbi");
}
p->deliverMail("Intro");
p->staticinit = true;
}
if(world.dbgItems)
{
for(int i = weapon_min; i < weapon_max; i++) {
weaponinfo_t const *info = &weaponinfo[i];
if(info->classname != null && info->pclass & p->pclass && !(info->flags & wf_magic))
InvGive(info->classname, 1);
}
}
}
//
// Lith_PlayerUpdateStats
//
stkcall void Lith_PlayerUpdateStats(struct player *p)
{
fixed boost = 1 + p->jumpboost;
if(p->frozen != p->old.frozen)
ACS_SetPlayerProperty(0, p->frozen > 0, PROP_TOTALLYFROZEN);
if(p->speedmul != p->old.speedmul)
ACS_SetActorPropertyFixed(0, APROP_Speed, 0.7 + p->speedmul);
if(p->jumpboost != p->old.jumpboost)
ACS_SetActorPropertyFixed(0, APROP_JumpZ, p->jumpheight * boost);
}
// EOF