SBSPSS/source/game/healthman.cpp

272 lines
6.3 KiB
C++
Raw Normal View History

2001-06-14 23:08:42 +02:00
/******************************/
/*** Health throw out stuff ***/
/******************************/
#include "system\global.h"
#include "mem\memory.h"
#include "gfx\sprbank.h"
#include "utils\utils.h"
#include "gfx\prim.h"
//#include "gfx\actor.h"
#include "game\game.h"
#include "player\player.h"
#include "gfx\otpos.h"
2001-08-16 22:05:31 +02:00
#include "system\vid.h"
2001-06-14 23:08:42 +02:00
#include "game\healthman.h"
2001-08-02 18:31:56 +02:00
#ifndef __SAVE_SAVE_H__
#include "save\save.h"
#endif
2001-06-14 23:08:42 +02:00
#include <sprites.h>
CHealthManager::sItemTable CHealthManager::ItemTable[]=
{
2001-08-16 22:05:31 +02:00
{CHealthManager::SPAT_CLUMP, 255,255,0},
{1, 127,127,127},
2001-06-14 23:08:42 +02:00
};
2001-06-14 17:28:07 +02:00
2001-06-14 23:08:42 +02:00
const int CHealthManager::ItemTableSize=sizeof(CHealthManager::ItemTable)/sizeof(CHealthManager::sItemTable);
2001-06-14 17:28:07 +02:00
2001-08-16 22:05:31 +02:00
const int HealthManGrav=128;
const int HealthManShift=9;
const int HealthManPickUpDelay=32;
2001-06-14 17:28:07 +02:00
2001-06-14 23:08:42 +02:00
/*****************************************************************************/
void CHealthManager::init()
{
2001-07-25 23:30:13 +02:00
sItem *list=ItemList;
2001-06-14 23:08:42 +02:00
FrameHdr=CGameScene::getSpriteBank()->getFrameHeader(FRM__SPATULA);
2001-08-16 22:05:31 +02:00
for (int i=0; i<SPAT_MAX; i++)
2001-06-14 23:08:42 +02:00
{
2001-07-25 23:30:13 +02:00
list->Life=0;
2001-08-16 22:05:31 +02:00
for (int s=0; s<2; s++)
{
TSPRT *Spr=&list->Sprite[s];
setTSprt(Spr);
setTSprtTPage(Spr,FrameHdr->TPage);
Spr->clut=FrameHdr->Clut;
Spr->u0=FrameHdr->U-1;
Spr->v0=FrameHdr->V-1;
Spr->w=FrameHdr->W;
Spr->h=FrameHdr->H;
}
2001-07-25 23:30:13 +02:00
list++;
2001-06-14 23:08:42 +02:00
}
2001-08-16 22:05:31 +02:00
Frame=0;
2001-06-14 23:08:42 +02:00
}
2001-06-14 17:28:07 +02:00
2001-06-14 23:08:42 +02:00
/*****************************************************************************/
void CHealthManager::shutdown()
{
}
2001-06-14 17:28:07 +02:00
2001-06-14 23:08:42 +02:00
/*****************************************************************************/
const int AngleS=2048+1024+512;
2001-07-23 21:26:37 +02:00
void CHealthManager::drop(DVECTOR const &Pos,int Amount,int Vel)
2001-06-14 23:08:42 +02:00
{
int Count=0;
int Am=Amount;
// Count em for Arc
for (int i=0; i<ItemTableSize; i++)
{
sItemTable &T=ItemTable[i];
while (Amount>=T.Count)
{
Amount-=T.Count;
Count++;
}
}
int Angle=AngleS;
int AngleInc=1024/Count;
// Split Em
Amount=Am;
for (int i=0; i<ItemTableSize; i++)
{
sItemTable &T=ItemTable[i];
while (Amount>=T.Count)
{
Amount-=T.Count;
addItem(Pos,i,Angle,Vel);
Angle+=AngleInc;
Angle&=4095;
}
}
2001-07-23 23:35:55 +02:00
think(1);
2001-06-14 23:08:42 +02:00
}
2001-06-14 17:28:07 +02:00
2001-06-14 23:08:42 +02:00
/*****************************************************************************/
2001-07-23 21:26:37 +02:00
void CHealthManager::addItem(DVECTOR const &Pos,int TableIdx,int Angle,int Vel)
2001-06-14 23:08:42 +02:00
{
int Idx=0;
2001-07-25 23:30:13 +02:00
sItem *item;
2001-06-14 17:28:07 +02:00
2001-06-14 23:08:42 +02:00
while (ItemList[Idx].Life) Idx++;
2001-08-16 22:05:31 +02:00
ASSERT(Idx<SPAT_MAX);
2001-07-25 23:30:13 +02:00
item=&ItemList[Idx];
2001-08-16 22:05:31 +02:00
item->Life=SPAT_LIFE;
setRGB0(&item->Sprite[0],ItemTable[TableIdx].R,ItemTable[TableIdx].G,ItemTable[TableIdx].B);
setRGB0(&item->Sprite[1],ItemTable[TableIdx].R,ItemTable[TableIdx].G,ItemTable[TableIdx].B);
2001-07-25 23:30:13 +02:00
item->Pos.vx=Pos.vx<<HealthManShift;
item->Pos.vy=Pos.vy<<HealthManShift;
2001-06-14 17:28:07 +02:00
2001-07-25 23:30:13 +02:00
item->Vel.vx=-(msin(Angle)*Vel);//>>1;
item->Vel.vy=-(mcos(Angle)*Vel);
2001-07-03 00:18:18 +02:00
2001-07-25 23:30:13 +02:00
// item->Pos.vx+=item->Vel.vx;
// item->Pos.vy+=item->Vel.vy;
2001-07-03 00:18:18 +02:00
2001-07-25 23:30:13 +02:00
item->Count=ItemTable[TableIdx].Count;
2001-06-14 23:08:42 +02:00
}
2001-06-14 17:28:07 +02:00
2001-06-14 23:08:42 +02:00
/*****************************************************************************/
void CHealthManager::checkPlayerCol(CPlayer *Player)
{
2001-07-25 23:30:13 +02:00
CRECT PRect=Player->getCollisionArea();
sItem *item=ItemList;
PRect.x1+=8;
PRect.x2+=8;
PRect.y1+=16;
PRect.y2+=16;
2001-06-14 23:08:42 +02:00
2001-08-16 22:05:31 +02:00
for (int i=0; i<SPAT_MAX; i++)
2001-06-14 23:08:42 +02:00
{
2001-07-25 23:30:13 +02:00
if (item->Life && item->Life<256-HealthManPickUpDelay)
2001-06-14 23:08:42 +02:00
{
2001-07-25 23:30:13 +02:00
if (PRect.x2<item->ScrPos.vx || PRect.x1>item->ScrPos.vx+16 ||
PRect.y2<item->ScrPos.vy || PRect.y1>item->ScrPos.vy+32)
2001-06-14 23:08:42 +02:00
{
}
else
{
2001-07-25 23:30:13 +02:00
item->Life=0;
Player->addSpatula(item->Count);
2001-08-02 18:31:56 +02:00
CSoundMediator::playSfx(CSoundMediator::SFX_ITEM__ANY_OTHER_ITEM);
2001-06-14 23:08:42 +02:00
}
}
2001-06-14 17:28:07 +02:00
2001-07-25 23:30:13 +02:00
item++;
2001-06-14 23:08:42 +02:00
}
}
2001-06-14 17:28:07 +02:00
2001-06-14 23:08:42 +02:00
/*****************************************************************************/
/*** think *******************************************************************/
/*****************************************************************************/
2001-08-16 22:05:31 +02:00
const int YO=32;
const int CO=1;
2001-06-14 23:08:42 +02:00
void CHealthManager::think(int frames)
2001-06-14 17:28:07 +02:00
{
2001-07-25 23:30:13 +02:00
sItem *item=ItemList;
2001-08-16 22:05:31 +02:00
int Dist;
CLayerCollision *ColLayer=CGameScene::getCollision();
2001-06-14 23:08:42 +02:00
2001-08-16 22:05:31 +02:00
for (int i=0; i<SPAT_MAX; i++)
2001-06-14 23:08:42 +02:00
{
for (int f=0; f<frames; f++)
{
2001-07-25 23:30:13 +02:00
if (item->Life>1)
2001-06-14 23:08:42 +02:00
{
2001-08-16 22:05:31 +02:00
int CheckOfs=16;
int YOfs=0;
int ColEx=COLLISION_TYPE_FLAG_DEATH_FALL;
int XS=1;
int XYO=0;
2001-07-25 23:30:13 +02:00
item->Life--;
item->Pos.vx+=item->Vel.vx;
item->Pos.vy+=item->Vel.vy;
item->ScrPos.vx=item->Pos.vx>>HealthManShift;
item->ScrPos.vy=item->Pos.vy>>HealthManShift;
item->Vel.vy+=HealthManGrav;
2001-08-16 22:05:31 +02:00
if (item->Vel.vy)
{
if (item->Vel.vy<0)
{ // Going Up
YOfs=-YO;//+(item->Vel.vy>>HealthManShift);
CheckOfs=CO;
ColEx=0; // Dont exclude any types when going up
XS=0; // dont reduce x on head col
}
Dist = ColLayer->getHeightFromGround( item->ScrPos.vx, item->ScrPos.vy+YOfs, CheckOfs );
if ((item->Vel.vy>0 && Dist<=0) || (item->Vel.vy<0 && Dist!=CheckOfs))
2001-06-14 23:08:42 +02:00
{
2001-08-16 22:05:31 +02:00
int newBlock=ColLayer->getCollisionBlock(item->ScrPos.vx,item->ScrPos.vy) & COLLISION_TYPE_MASK;
if (!(ColEx && newBlock==ColEx))
2001-07-23 23:35:55 +02:00
{
2001-08-16 22:05:31 +02:00
item->Pos.vy+=Dist<<HealthManShift; // align to ground
item->ScrPos.vy=item->Pos.vy>>HealthManShift;
item->Vel.vy-=HealthManGrav;
item->Vel.vy=-item->Vel.vy>>1;
item->Vel.vx>>=XS;
XYO=-4; // to stop spat coming back on hitting ground
2001-07-23 23:35:55 +02:00
}
2001-08-13 20:43:39 +02:00
}
2001-06-14 23:08:42 +02:00
}
2001-08-16 22:05:31 +02:00
if(item->ScrPos.vy>GameScene.GetLevel().getMapHeight16()) item->Life=0;
2001-06-14 23:08:42 +02:00
int XOfs;
2001-07-25 23:30:13 +02:00
if (item->Vel.vx>0)
2001-06-14 23:08:42 +02:00
{
XOfs=+16;
}
else
{
XOfs=-16;
}
// Check X collision
2001-08-16 22:05:31 +02:00
Dist = ColLayer->getHeightFromGround( item->ScrPos.vx+XOfs, item->ScrPos.vy+XYO, 16);
if (Dist<=0)
2001-06-14 23:08:42 +02:00
{
2001-07-25 23:30:13 +02:00
item->Vel.vx=-item->Vel.vx>>1;
2001-08-16 22:05:31 +02:00
item->Vel.vy>>=1;
2001-06-14 23:08:42 +02:00
}
2001-08-16 22:05:31 +02:00
2001-06-14 23:08:42 +02:00
}
2001-07-25 23:30:13 +02:00
else
{
item->Life=0;
}
2001-06-14 23:08:42 +02:00
}
2001-07-25 23:30:13 +02:00
item++;
2001-06-14 17:28:07 +02:00
}
2001-06-14 23:08:42 +02:00
}
2001-06-14 17:28:07 +02:00
2001-06-14 23:08:42 +02:00
/*****************************************************************************/
/*** render ******************************************************************/
/*****************************************************************************/
void CHealthManager::render()
2001-06-14 17:28:07 +02:00
{
2001-07-25 23:30:13 +02:00
sItem *list=ItemList;
2001-08-16 22:05:31 +02:00
sOT *ThisOT=OtPtr+OTPOS__PICKUP_POS;
2001-06-14 23:08:42 +02:00
DVECTOR const &CamPos=CLevel::getCameraPos();
2001-08-16 22:05:31 +02:00
for (int i=0; i<SPAT_MAX; i++)
2001-06-14 23:08:42 +02:00
{
2001-08-16 22:05:31 +02:00
int Life=list->Life;
if (Life<64 && Frame) Life=0;
if (Life)
2001-06-14 23:08:42 +02:00
{
2001-08-16 22:05:31 +02:00
TSPRT *Spr=&list->Sprite[Frame];
2001-06-14 23:08:42 +02:00
// Calc render pos (dont worry about clipping yet)
2001-08-16 22:05:31 +02:00
Spr->x0 = list->ScrPos.vx - CamPos.vx;
Spr->y0 = (list->ScrPos.vy - CamPos.vy)-32;
2001-06-14 17:28:07 +02:00
2001-08-16 22:05:31 +02:00
addPrim(ThisOT,Spr);
2001-06-14 23:08:42 +02:00
}
2001-07-25 23:30:13 +02:00
list++;
2001-06-14 23:08:42 +02:00
}
2001-08-16 22:05:31 +02:00
Frame^=1;
2001-06-14 17:28:07 +02:00
}