SBSPSS/source/thing/thing.cpp

1495 lines
35 KiB
C++
Raw Normal View History

2001-02-26 21:27:20 +01:00
/*=========================================================================
thing.cpp
Author: PKG
2001-05-25 21:08:35 +02:00
Created:
2001-02-26 21:27:20 +01:00
Project: Spongebob
2001-05-25 21:08:35 +02:00
Purpose:
2001-02-26 21:27:20 +01:00
Copyright (c) 2001 Climax Development Ltd
===========================================================================*/
2001-05-29 18:38:09 +02:00
#define USE_FREE_LIST
2001-02-26 21:27:20 +01:00
/*----------------------------------------------------------------------
Includes
-------- */
2001-06-21 21:19:15 +02:00
#include "system\vid.h"
2001-02-26 21:27:20 +01:00
#include "thing\thing.h"
2001-03-06 21:13:16 +01:00
#ifndef __PLAYER_PLAYER_H__
#include "player\player.h"
#endif
#ifndef __GAME_GAME_H__
#include "game\game.h"
#endif
2001-02-26 21:27:20 +01:00
2001-04-11 18:49:07 +02:00
#ifndef __UTILS_HEADER__
2001-03-08 21:12:47 +01:00
#include "utils\utils.h"
2001-04-11 18:49:07 +02:00
#endif
2001-05-10 18:16:57 +02:00
#include "level\level.h"
2001-05-25 20:43:47 +02:00
// Needed for freelist table :o(
#include "pickups\pickup.h"
#include "platform\platform.h"
#include "projectl\projectl.h"
#include "enemy\npc.h"
#include "friend\friend.h"
2001-05-29 22:31:02 +02:00
#include "triggers\trigger.h"
2001-05-25 20:43:47 +02:00
#include "fx\fx.h"
2001-05-23 20:45:27 +02:00
2001-05-25 21:08:35 +02:00
#ifndef __FRIEND_FRIEND_H__
#include "friend\friend.h"
#endif
2001-05-30 22:24:02 +02:00
#ifndef __FRIEND_FGARY_H__
#include "friend\fgary.h"
#endif
2001-05-23 20:45:27 +02:00
#ifndef __HAZARD_HRWEIGHT_H__
#include "hazard\hrweight.h"
#endif
2001-05-24 01:16:43 +02:00
#ifndef __HAZARD_HPSWITCH_H__
#include "hazard\hpswitch.h"
#endif
2001-05-30 22:24:02 +02:00
#ifndef __TRIGGERS_TGARYGO_H__
#include "triggers\tgarygo.h"
#endif
2001-07-05 23:50:02 +02:00
#ifndef __PLATFORM_PFBLOCK_H__
#include "platform\pfblock.h"
#endif
2001-02-26 21:27:20 +01:00
/* Std Lib
------- */
/* Data
---- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
/*----------------------------------------------------------------------
Vars
---- */
2001-08-04 19:23:30 +02:00
static const int s_RenderBBoxX0=-32;
static const int s_RenderBBoxX1=INGAME_SCREENW+32;
static const int s_RenderBBoxY0=-16;
static const int s_RenderBBoxY1=INGAME_SCREENH+16;
2001-06-21 21:19:15 +02:00
static const int s_ThinkBBoxX0=0-(INGAME_SCREENW/2);
static const int s_ThinkBBoxX1=INGAME_SCREENW+(INGAME_SCREENW/2);
2001-08-04 19:23:30 +02:00
static const int s_ThinkBBoxY0=0-(INGAME_SCREENH/2);
static const int s_ThinkBBoxY1=INGAME_SCREENW+(INGAME_SCREENH/2);
2001-05-10 23:09:23 +02:00
2001-05-15 18:48:29 +02:00
CThing *CThingManager::s_thingLists[CThing::MAX_TYPE];
2001-05-10 18:16:57 +02:00
CThing *CThingManager::s_CollisionLists[CThing::MAX_TYPE];
2001-02-26 21:42:25 +01:00
int CThingManager::s_initialised=false;
2001-05-10 18:16:57 +02:00
sBBox CThingManager::m_RenderBBox;
sBBox CThingManager::m_ThinkBBox;
2001-08-15 18:12:20 +02:00
DVECTOR CThingManager::MapWH,CThingManager::MapWH16;
2001-05-10 18:16:57 +02:00
2001-05-25 20:43:47 +02:00
#ifdef USE_FREE_LIST
CThing **CThingManager::s_FreeList[CThing::MAX_TYPE];
2001-05-29 18:38:09 +02:00
int FreeListCount=0;
2001-05-10 23:09:23 +02:00
2001-05-25 20:43:47 +02:00
struct sFreeListTable
{
u16 Type;
u16 Count;
};
static const sFreeListTable FreeListTable[]=
{
/* 0*/ {CThing::TYPE_PICKUP ,CBasePickup::MAX_SUBTYPE},
/* 1*/ {CThing::TYPE_PLATFORM ,CNpcPlatform::MAX_SUBTYPE},
/* 2*/ {CThing::TYPE_PLAYER ,CPlayerThing::MAX_SUBTYPE},
/* 3*/ {CThing::TYPE_PLAYERPROJECTILE ,CPlayerProjectile::MAX_SUBTYPE},
/* 4*/ {CThing::TYPE_NPC ,CNpcFriend::MAX_SUBTYPE},
/* 5*/ {CThing::TYPE_ENEMY ,CNpcEnemy::MAX_SUBTYPE},
/* 6*/ {CThing::TYPE_ENEMYPROJECTILE ,CProjectile::MAX_SUBTYPE},
2001-05-29 22:31:02 +02:00
/* 7*/ {CThing::TYPE_TRIGGER ,CTrigger::MAX_SUBTYPE},
2001-05-25 20:43:47 +02:00
/* 8*/ {CThing::TYPE_HAZARD ,CNpcHazard::MAX_SUBTYPE},
/* 9*/ {CThing::TYPE_FX ,CFX::MAX_SUBTYPE},
};
static const int FreeListTableSize=sizeof(FreeListTable)/sizeof(sFreeListTable);
#endif
2001-02-26 21:27:20 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThingManager::init()
{
2001-02-26 21:42:25 +01:00
ASSERT(!s_initialised);
2001-05-10 18:16:57 +02:00
initList(s_thingLists);
initList(s_CollisionLists);
2001-05-25 20:43:47 +02:00
initFreeList();
2001-02-26 21:42:25 +01:00
s_initialised=true;
2001-02-26 21:27:20 +01:00
}
2001-08-15 18:12:20 +02:00
/************************************************************************/
void CThingManager::setMapWH(DVECTOR const &WH)
{
MapWH=WH;
MapWH16.vx=MapWH.vx*16;
MapWH16.vy=MapWH.vy*16;
}
2001-02-26 21:27:20 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThingManager::shutdown()
{
int i;
CThing *thing;
2001-02-26 21:44:45 +01:00
ASSERT(s_initialised);
2001-02-26 21:27:20 +01:00
for(i=0;i<CThing::MAX_TYPE;i++)
{
while(s_thingLists[i])
{
thing=s_thingLists[i];
thing->shutdown();
2001-05-25 20:43:47 +02:00
DeleteThing(thing);
2001-02-26 21:27:20 +01:00
}
}
2001-02-26 21:42:25 +01:00
s_initialised=false;
2001-05-25 20:43:47 +02:00
shutdownFreeList();
2001-02-26 21:27:20 +01:00
}
2001-05-10 18:16:57 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThingManager::initList(CThing **List)
{
int i;
for(i=0 ;i<CThing::MAX_TYPE; i++)
{
List[i]=NULL;
}
}
2001-05-04 21:34:09 +02:00
/*----------------------------------------------------------------------
Function:
2001-05-25 21:08:35 +02:00
Purpose:
2001-05-04 21:34:09 +02:00
Params:
Returns:
---------------------------------------------------------------------- */
void CThingManager::killAllThingsForRespawn()
{
int i;
ASSERT(s_initialised);
for(i=0;i<CThing::MAX_TYPE;i++)
{
2001-05-15 18:48:29 +02:00
// Hey - it's not optimal in speed, but it's vaguely funny :)
// ( and anyway.. it probly *is* optimal in size.. )
CThing *thing;
thing=s_thingLists[i];
while(thing)
2001-05-04 21:34:09 +02:00
{
2001-05-15 18:48:29 +02:00
if(thing->dontKillDuringLevelRespawn())
{
thing=thing->m_nextListThing;
}
else
2001-05-04 21:34:09 +02:00
{
thing->shutdown();
2001-05-25 20:43:47 +02:00
DeleteThing(thing);
2001-05-15 18:48:29 +02:00
thing=s_thingLists[i];
2001-05-04 21:34:09 +02:00
}
}
}
}
2001-05-11 01:51:14 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThingManager::initAllThings()
{
for(int i=0; i<CThing::MAX_TYPE; i++)
{
CThing *thing=s_thingLists[i];
while(thing)
{
thing->updateCollisionArea();
thing=thing->m_nextListThing;
}
}
}
2001-05-24 01:16:43 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThingManager::matchPressureSwitches()
{
CNpcHazard *hazard;
hazard = (CNpcHazard *) s_thingLists[CThing::TYPE_HAZARD];
while( hazard )
{
2001-05-29 20:40:38 +02:00
if ( hazard->getThingSubType() == CNpcHazard::NPC_PRESSURE_SWITCH_HAZARD )
2001-05-24 01:16:43 +02:00
{
CNpcPressureSwitchHazard *switchHazard = (CNpcPressureSwitchHazard *) hazard;
DVECTOR triggerPos = switchHazard->getTriggerPos();
CNpcPlatform *platform;
platform = (CNpcPlatform *) s_thingLists[CThing::TYPE_PLATFORM];
while( platform )
{
2001-05-29 20:40:38 +02:00
if ( platform->getThingSubType() == CNpcPlatform::NPC_TRAPDOOR_PLATFORM )
2001-05-24 01:16:43 +02:00
{
CNpcTrapdoorPlatform *trapdoor = (CNpcTrapdoorPlatform *) platform;
DVECTOR testPos = trapdoor->getTriggerPos();
if ( testPos.vx == triggerPos.vx && testPos.vy == triggerPos.vy )
{
switchHazard->linkToPlatform( trapdoor );
}
}
platform = (CNpcPlatform *) platform->m_nextListThing;
}
}
hazard = (CNpcHazard *) hazard->m_nextListThing;
}
}
2001-05-23 20:45:27 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThingManager::matchWheelsAndWeights()
{
CNpcHazard *hazard1;
CNpcHazard *hazard2;
hazard1 = (CNpcHazard *) s_thingLists[CThing::TYPE_HAZARD];
while( hazard1 )
{
2001-05-29 20:40:38 +02:00
if ( hazard1->getThingSubType() == CNpcHazard::NPC_RISING_WEIGHT_HAZARD )
2001-05-23 20:45:27 +02:00
{
CNpcRisingWeightHazard *weight = (CNpcRisingWeightHazard *) hazard1;
DVECTOR wheelPos = weight->getWheelPos();
hazard2 = (CNpcHazard *) s_thingLists[CThing::TYPE_HAZARD];
while( hazard2 )
{
2001-05-29 20:40:38 +02:00
if ( hazard2->getThingSubType() == CNpcHazard::NPC_RISING_WEIGHT_WHEEL_HAZARD )
2001-05-23 20:45:27 +02:00
{
CNpcRisingWeightWheelHazard *wheel = (CNpcRisingWeightWheelHazard *) hazard2;
DVECTOR testPos = wheel->getWheelPos();
if ( testPos.vx == wheelPos.vx && testPos.vy == wheelPos.vy )
{
wheel->linkToWeight( weight );
2001-08-08 17:43:07 +02:00
weight->linkToWheel( wheel );
2001-05-23 20:45:27 +02:00
}
}
hazard2 = (CNpcHazard *) hazard2->m_nextListThing;
}
}
hazard1 = (CNpcHazard *) hazard1->m_nextListThing;
}
}
2001-02-26 21:27:20 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-05-30 22:24:02 +02:00
void CThingManager::matchGaryTriggers()
{
CNpcFriend *friendNpc;
friendNpc = (CNpcFriend *) s_thingLists[CThing::TYPE_NPC];
while( friendNpc )
{
if ( friendNpc->getThingSubType() == CNpcFriend::NPC_FRIEND_GARY )
{
CNpcGaryFriend *gary = (CNpcGaryFriend *) friendNpc;
DVECTOR triggerPos = gary->getTriggerPos();
CTrigger *trigger;
trigger = (CTrigger *) s_thingLists[CThing::TYPE_TRIGGER];
while( trigger )
{
2001-06-05 16:38:11 +02:00
if ( trigger->getThingSubType() == CTrigger::TRIGGER_GARY_START )
2001-05-30 22:24:02 +02:00
{
CGaryStartTrigger *garyTrigger = (CGaryStartTrigger *) trigger;
DVECTOR testPos = garyTrigger->getPos();
testPos.vx >>= 4;
testPos.vy >>= 4;
if ( testPos.vx == triggerPos.vx && testPos.vy == triggerPos.vy )
{
garyTrigger->setGary( gary );
}
}
trigger = (CTrigger *) trigger->m_nextListThing;
}
}
friendNpc = (CNpcFriend *) friendNpc->m_nextListThing;
}
}
2001-07-05 23:50:02 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThingManager::shakePlatformLoose()
{
CNpcPlatform *platform;
int platformCount = getRnd() % 30;
int platformTest = 0;
while( platformCount )
{
platform = (CNpcPlatform *) s_thingLists[CThing::TYPE_PLATFORM];
while( platform )
{
if ( platform->getThingSubType() == CNpcPlatform::NPC_FALLING_BLOCK_PLATFORM )
{
platformCount--;
platformTest++;
if ( !platformCount )
{
CNpcFallingBlockPlatform *block = (CNpcFallingBlockPlatform *) platform;
block->trigger();
return;
}
}
platform = (CNpcPlatform *) platform->m_nextListThing;
}
if ( !platformTest )
{
return;
}
}
}
2001-05-30 22:24:02 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-05-10 23:48:04 +02:00
2001-02-26 21:27:20 +01:00
void CThingManager::thinkAllThings(int _frames)
{
2001-05-10 23:09:23 +02:00
// Setup Screen BBox's
DVECTOR const &CamPos=CLevel::getCameraPos();
m_ThinkBBox.XMin=s_ThinkBBoxX0+CamPos.vx;
m_ThinkBBox.XMax=s_ThinkBBoxX1+CamPos.vx;
m_ThinkBBox.YMin=s_ThinkBBoxY0+CamPos.vy;
m_ThinkBBox.YMax=s_ThinkBBoxY1+CamPos.vy;
2001-08-15 18:12:20 +02:00
//CLevel &Lvl=GameScene.GetLevel();
//DVECTOR const &MapSize=Lvl.getMapSize16();
2001-05-10 23:09:23 +02:00
2001-02-26 21:27:20 +01:00
int i;
CThing *thing;
2001-05-10 23:48:04 +02:00
CThing *thing1,*thing2,*playerThing;
2001-05-11 01:51:14 +02:00
2001-05-10 23:48:04 +02:00
initList(s_CollisionLists);
2001-02-26 21:27:20 +01:00
2001-05-11 01:51:14 +02:00
for(i=0; i<CThing::MAX_TYPE; i++)
2001-02-26 21:27:20 +01:00
{
thing=s_thingLists[i];
while(thing)
{
2001-05-10 23:09:23 +02:00
// Check If in Thinkable range
2001-05-14 18:33:39 +02:00
CRECT const *ThingRect= thing->getThinkBBox();
2001-05-29 18:38:09 +02:00
int lastFlag=thing->getThinkFlag()<<1;
int Flag=1;
2001-08-15 16:14:13 +02:00
DVECTOR const &ThingPos=thing->getPos();
2001-08-15 16:21:27 +02:00
// Will speed this up - doubt it, not now!!
2001-08-15 18:12:20 +02:00
if (!thing->allowOffMap() && (ThingPos.vx<0 || ThingPos.vx>=MapWH16.vx || ThingPos.vy<0 || ThingPos.vy>=MapWH16.vy))
2001-05-15 00:12:09 +02:00
{
2001-08-15 16:14:13 +02:00
thing->setToShutdown();
2001-08-15 20:26:51 +02:00
// SYSTEM_DBGMSG("ThingOffMap: T:%i S:%i TXY%i %i, MWH%i %i\n",(int)thing->getThingType(),(int)thing->getThingSubType(),ThingPos.vx,ThingPos.vy,MapWH16.vx,MapWH16.vy);
2001-05-15 00:12:09 +02:00
}
2001-08-15 16:14:13 +02:00
else
2001-05-10 23:09:23 +02:00
{
2001-08-15 16:14:13 +02:00
if (!thing->alwaysThink())
2001-05-10 23:48:04 +02:00
{
2001-08-15 16:14:13 +02:00
if (ThingRect->x2<m_ThinkBBox.XMin || ThingRect->x1>m_ThinkBBox.XMax) Flag=0;
if (ThingRect->y2<m_ThinkBBox.YMin || ThingRect->y1>m_ThinkBBox.YMax) Flag=0;
2001-05-10 23:48:04 +02:00
}
2001-08-15 16:14:13 +02:00
thing->setThinkFlag(Flag);
// Is in think zone
if (Flag)
{
thing->think(_frames);
// thing->updateCollisionArea();
if (thing->canCollide())
{
CThingManager::addToCollisionList(thing);
}
}
Flag|=lastFlag;
2001-06-14 23:17:10 +02:00
// Handle enter/leave states (not sure of viabilty now)
2001-08-15 16:14:13 +02:00
switch (Flag)
{ // Last This
case 0: // 0 0
break;
case 1: // 0 1
// thing->enterThinkZone(_frames);
break;
case 2: // 1 0
thing->leftThinkZone(_frames);
break;
case 3: // 1 1
break;
default:
ASSERT("Invalid Think State");
}
2001-05-11 00:39:23 +02:00
/* THIS WILL NOT STAY HERE, THINGS MUST BE INITIALISED CORRECTLY */
2001-08-15 16:14:13 +02:00
thing->updateCollisionArea();
}
2001-05-10 18:16:57 +02:00
thing=thing->m_nextListThing;
2001-02-26 21:27:20 +01:00
}
}
2001-03-06 21:13:16 +01:00
CPlayer *player = GameScene.getPlayer();
2001-05-10 23:48:04 +02:00
playerThing=s_CollisionLists[CThing::TYPE_PLAYER];
2001-03-31 00:43:35 +02:00
2001-05-11 01:51:14 +02:00
if (player && playerThing)
2001-03-08 21:12:47 +01:00
{
2001-08-16 21:32:24 +02:00
int playerIsAlive=!player->isDead();
2001-05-10 23:48:04 +02:00
// Player -> Platform collision
2001-08-16 21:32:24 +02:00
if(playerIsAlive)
2001-02-26 21:27:20 +01:00
{
2001-08-16 21:32:24 +02:00
player->clearPlatform();
thing1=s_CollisionLists[CThing::TYPE_PLATFORM];
while(thing1)
2001-05-10 23:48:04 +02:00
{
2001-08-16 21:32:24 +02:00
if(thing1->checkCollisionAgainst(playerThing, _frames))
{
thing1->collidedWith(playerThing);
}
thing1=thing1->m_nextCollisionThing;
2001-05-10 23:48:04 +02:00
}
2001-02-27 18:39:25 +01:00
2001-08-16 21:32:24 +02:00
// Player -> Pickup collision
thing1=s_CollisionLists[CThing::TYPE_PICKUP];
while(thing1)
2001-05-10 23:48:04 +02:00
{
2001-08-16 21:32:24 +02:00
if(thing1->checkCollisionAgainst(playerThing, _frames))
{
thing1->collidedWith(playerThing);
}
thing1=thing1->m_nextCollisionThing;
2001-05-10 23:48:04 +02:00
}
2001-04-24 17:01:42 +02:00
}
2001-06-06 21:07:19 +02:00
// Friend -> Pickup collision
2001-08-13 23:29:12 +02:00
thing1=s_CollisionLists[CThing::TYPE_NPC];
2001-06-06 21:07:19 +02:00
while(thing1)
{
2001-08-13 23:29:12 +02:00
thing2=s_CollisionLists[CThing::TYPE_PICKUP];
2001-06-06 21:07:19 +02:00
while(thing2)
{
2001-08-13 23:29:12 +02:00
if(thing2->checkCollisionAgainst(thing1, _frames))
2001-06-06 21:07:19 +02:00
{
2001-08-13 23:29:12 +02:00
thing2->collidedWith(thing1);
2001-06-06 21:07:19 +02:00
}
thing2=thing2->m_nextCollisionThing;
}
thing1=thing1->m_nextCollisionThing;
}
2001-05-10 23:48:04 +02:00
// Player -> Enemy collision
2001-08-16 21:32:24 +02:00
if(playerIsAlive)
2001-05-02 00:06:59 +02:00
{
2001-08-16 21:32:24 +02:00
thing1=s_CollisionLists[CThing::TYPE_ENEMY];
while(thing1)
2001-05-10 23:48:04 +02:00
{
2001-08-16 21:32:24 +02:00
if(thing1->checkCollisionAgainst(playerThing, _frames))
{
thing1->collidedWith(playerThing);
}
thing1=thing1->m_nextCollisionThing;
2001-05-10 23:48:04 +02:00
}
2001-05-02 00:06:59 +02:00
2001-08-16 21:32:24 +02:00
// Player -> Effect collision
thing1=s_CollisionLists[CThing::TYPE_FX];
while(thing1)
2001-06-07 18:33:19 +02:00
{
2001-08-16 21:32:24 +02:00
if(thing1->checkCollisionAgainst(playerThing, _frames))
{
thing1->collidedWith(playerThing);
}
thing1=thing1->m_nextCollisionThing;
2001-06-07 18:33:19 +02:00
}
2001-08-16 21:32:24 +02:00
// Player -> Friend collision
thing1=s_CollisionLists[CThing::TYPE_NPC];
while(thing1)
2001-05-10 23:48:04 +02:00
{
2001-08-16 21:32:24 +02:00
if(thing1->checkCollisionAgainst(playerThing, _frames))
{
thing1->collidedWith(playerThing);
}
thing1=thing1->m_nextCollisionThing;
2001-05-10 23:48:04 +02:00
}
2001-02-27 18:39:25 +01:00
2001-08-16 21:32:24 +02:00
// Player -> Hazard collision
thing1=s_CollisionLists[CThing::TYPE_HAZARD];
while(thing1)
2001-05-10 23:48:04 +02:00
{
2001-08-16 21:32:24 +02:00
if(thing1->checkCollisionAgainst(playerThing, _frames))
{
thing1->collidedWith(playerThing);
}
thing1=thing1->m_nextCollisionThing;
2001-05-10 23:48:04 +02:00
}
2001-02-27 18:39:25 +01:00
2001-08-16 21:32:24 +02:00
// Player -> Enemy projectile collision
thing1=s_CollisionLists[CThing::TYPE_ENEMYPROJECTILE];
while(thing1)
2001-05-10 23:48:04 +02:00
{
2001-08-16 21:32:24 +02:00
if(thing1->checkCollisionAgainst(playerThing, _frames))
{
thing1->collidedWith(playerThing);
}
thing1=thing1->m_nextCollisionThing;
2001-05-10 23:48:04 +02:00
}
2001-03-05 21:01:25 +01:00
2001-08-16 21:32:24 +02:00
// Player -> Trigger collision
thing1=s_CollisionLists[CThing::TYPE_TRIGGER];
while(thing1)
2001-04-12 18:33:48 +02:00
{
2001-08-16 21:32:24 +02:00
if(thing1->checkCollisionAgainst(playerThing, _frames))
{
thing1->collidedWith(playerThing);
}
thing1=thing1->m_nextCollisionThing;
2001-04-12 18:33:48 +02:00
}
}
2001-04-24 21:03:06 +02:00
2001-06-04 14:54:44 +02:00
// Friend -> Trigger collision
thing1=s_CollisionLists[CThing::TYPE_TRIGGER];
while(thing1)
{
thing2=s_CollisionLists[CThing::TYPE_NPC];
while(thing2)
{
if(thing1->checkCollisionAgainst(thing2, _frames))
{
thing1->collidedWith(thing2);
}
thing2=thing2->m_nextCollisionThing;
}
thing1=thing1->m_nextCollisionThing;
}
2001-06-06 15:27:46 +02:00
// Enemy -> Trigger collision
thing1=s_CollisionLists[CThing::TYPE_TRIGGER];
while(thing1)
{
thing2=s_CollisionLists[CThing::TYPE_ENEMY];
while(thing2)
{
if(thing1->checkCollisionAgainst(thing2, _frames))
{
thing1->collidedWith(thing2);
}
thing2=thing2->m_nextCollisionThing;
}
thing1=thing1->m_nextCollisionThing;
}
2001-05-10 23:48:04 +02:00
// Enemy -> Player projectile collision
thing1=s_CollisionLists[CThing::TYPE_PLAYERPROJECTILE];
while(thing1)
2001-04-24 21:03:06 +02:00
{
2001-06-04 14:54:44 +02:00
thing2=s_CollisionLists[CThing::TYPE_ENEMY];
2001-05-10 23:48:04 +02:00
while(thing2)
2001-04-24 21:03:06 +02:00
{
2001-05-10 23:48:04 +02:00
if(thing1->checkCollisionAgainst(thing2, _frames))
2001-04-24 21:03:06 +02:00
{
2001-05-10 23:48:04 +02:00
thing1->collidedWith(thing2);
2001-04-24 21:03:06 +02:00
}
2001-05-10 23:48:04 +02:00
thing2=thing2->m_nextCollisionThing;
2001-04-24 21:03:06 +02:00
}
2001-05-10 23:48:04 +02:00
thing1=thing1->m_nextCollisionThing;
2001-04-24 21:03:06 +02:00
}
2001-05-10 23:48:04 +02:00
// Enemy -> Enemy collision
thing1=s_CollisionLists[CThing::TYPE_ENEMY];
while(thing1)
{
thing2=thing1->m_nextCollisionThing;//s_CollisionLists[CThing::TYPE_ENEMY];
2001-04-24 21:03:06 +02:00
2001-05-10 23:48:04 +02:00
while(thing2)
{
ASSERT(thing1 != thing2 );
// if ( thing1 != thing2 )
{
if (thing1->checkCollisionAgainst( thing2, _frames ) )
{
thing1->collidedWith( thing2 );
//thing2->collidedWith( thing1 );
}
}
thing2 = thing2->m_nextCollisionThing;
}
thing1 = thing1->m_nextCollisionThing;
}
2001-05-05 21:08:02 +02:00
2001-05-10 23:48:04 +02:00
// Hazard -> Platform collision
thing1=s_CollisionLists[CThing::TYPE_PLATFORM];
while(thing1)
2001-05-05 21:08:02 +02:00
{
2001-05-10 23:48:04 +02:00
thing2=s_CollisionLists[CThing::TYPE_HAZARD];
while(thing2)
2001-05-05 21:08:02 +02:00
{
2001-05-10 23:48:04 +02:00
if ( thing1 != thing2 )
2001-05-05 21:08:02 +02:00
{
2001-05-10 23:48:04 +02:00
if (thing1->checkCollisionAgainst( thing2, _frames ) )
{
thing1->collidedWith( thing2 );
//thing2->collidedWith( thing1 );
}
2001-05-05 21:08:02 +02:00
}
2001-05-10 23:48:04 +02:00
thing2 = thing2->m_nextCollisionThing;
2001-05-05 21:08:02 +02:00
}
2001-05-10 23:48:04 +02:00
thing1 = thing1->m_nextCollisionThing;
2001-05-05 21:08:02 +02:00
}
2001-05-23 23:27:29 +02:00
// Platform -> Player projectile collision
thing1=s_CollisionLists[CThing::TYPE_PLATFORM];
while(thing1)
{
thing2=s_CollisionLists[CThing::TYPE_PLAYERPROJECTILE];
while(thing2)
{
if(thing1->checkCollisionAgainst(thing2, _frames))
{
thing1->collidedWith(thing2);
}
thing2=thing2->m_nextCollisionThing;
}
thing1=thing1->m_nextCollisionThing;
}
2001-05-25 21:08:35 +02:00
2001-07-30 21:43:39 +02:00
// Trigger -> Player projectile collision
thing1=s_CollisionLists[CThing::TYPE_PLAYERPROJECTILE];
while(thing1)
{
thing2=s_CollisionLists[CThing::TYPE_TRIGGER];
while(thing2)
{
if(thing1->checkCollisionAgainst(thing2, _frames))
{
thing2->collidedWith(thing1);
}
thing2=thing2->m_nextCollisionThing;
}
thing1=thing1->m_nextCollisionThing;
}
// Hazard -> Player projectile collision
thing1=s_CollisionLists[CThing::TYPE_PLAYERPROJECTILE];
while(thing1)
{
thing2=s_CollisionLists[CThing::TYPE_HAZARD];
while(thing2)
{
if(thing1->checkCollisionAgainst(thing2, _frames))
{
thing2->collidedWith(thing1);
}
thing2=thing2->m_nextCollisionThing;
}
thing1=thing1->m_nextCollisionThing;
}
2001-05-25 21:08:35 +02:00
// Friendly npc -> Platform projectile collision - first clear platforms
CNpcFriend *friendNpc = (CNpcFriend *) s_CollisionLists[CThing::TYPE_NPC];
while( friendNpc )
{
friendNpc->clearPlatform();
friendNpc = (CNpcFriend *) friendNpc->m_nextCollisionThing;
}
// now detect new platform
thing1=s_CollisionLists[CThing::TYPE_PLATFORM];
while(thing1)
{
thing2=s_CollisionLists[CThing::TYPE_NPC];
while(thing2)
{
if(thing1->checkCollisionAgainst(thing2, _frames))
{
thing1->collidedWith(thing2);
}
thing2=thing2->m_nextCollisionThing;
}
thing1=thing1->m_nextCollisionThing;
}
2001-06-25 21:57:44 +02:00
2001-07-09 21:38:58 +02:00
// gary collision with hazards
thing2=s_CollisionLists[CThing::TYPE_NPC];
while(thing2)
{
if ( thing2->getThingSubType() == CNpcFriend::NPC_FRIEND_GARY )
{
thing1=s_CollisionLists[CThing::TYPE_HAZARD];
while(thing1)
{
if(thing1->checkCollisionAgainst(thing2, _frames))
{
thing1->collidedWith(thing2);
}
thing1=thing1->m_nextCollisionThing;
}
}
thing2=thing2->m_nextCollisionThing;
}
2001-06-25 21:57:44 +02:00
player->detectHazardousSurface();
2001-05-05 21:08:02 +02:00
}
2001-05-10 23:09:23 +02:00
// Shut emm down, sh sh shut em down, we shutem down
2001-04-25 21:52:35 +02:00
for(i=0;i<CThing::MAX_TYPE;i++)
{
2001-05-11 02:54:52 +02:00
thing=s_thingLists[i];
2001-04-25 21:52:35 +02:00
CThing *nextThing = thing;
while(thing)
{
2001-05-10 18:16:57 +02:00
nextThing=thing->m_nextListThing;
2001-04-25 21:52:35 +02:00
if ( thing->isSetToShutdown() )
{
thing->shutdown();
2001-05-25 20:43:47 +02:00
DeleteThing(thing);
2001-04-25 21:52:35 +02:00
}
thing = nextThing;
}
}
2001-02-26 21:27:20 +01:00
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThingManager::renderAllThings()
{
2001-05-10 18:16:57 +02:00
// Setup Screen BBox's
DVECTOR const &CamPos=CLevel::getCameraPos();
m_RenderBBox.XMin=s_RenderBBoxX0+CamPos.vx;
m_RenderBBox.XMax=s_RenderBBoxX1+CamPos.vx;
m_RenderBBox.YMin=s_RenderBBoxY0+CamPos.vy;
m_RenderBBox.YMax=s_RenderBBoxY1+CamPos.vy;
2001-02-26 21:27:20 +01:00
2001-05-10 23:09:23 +02:00
for(int i=0;i<CThing::MAX_TYPE;i++)
2001-02-26 21:27:20 +01:00
{
2001-05-10 23:09:23 +02:00
CThing *thing=s_thingLists[i];
2001-02-26 21:27:20 +01:00
while(thing)
{
thing->render();
2001-05-10 18:16:57 +02:00
thing=thing->m_nextListThing;
2001-02-26 21:27:20 +01:00
}
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThingManager::processEventAllThings(GAME_EVENT _event,CThing *_sourceThing)
{
int i;
CThing *thing;
for(i=0;i<CThing::MAX_TYPE;i++)
{
thing=s_thingLists[i];
while(thing)
{
thing->processEvent(_event,_sourceThing);
2001-05-10 18:16:57 +02:00
thing=thing->m_nextListThing;
2001-02-26 21:27:20 +01:00
}
}
}
2001-04-06 23:25:18 +02:00
/*----------------------------------------------------------------------
Function:
Purpose: Searches through a list of things to check for collision against an area.
The first time this is called, _continue should be false. If no colliding things are found then
NULL will be returned. If a colliding thing is found then it's address gets returned. To continue
searching through the list for the next colliding thing, call the function again with _continue set
to true.
NB: This function could probly cause weird bugs if not used properly! BE AWARE!
Params: *_area Area to check against
_type Type of thing to search for
_continue If false then the list is searched from the start, if true then the search continues
from the last thing that was found ( um.. see above )
Returns:
---------------------------------------------------------------------- */
CThing *CThingManager::checkCollisionAreaAgainstThings(CRECT *_area,int _type,int _continue)
{
static CThing *thing=NULL;
ASSERT(_type<CThing::MAX_TYPE);
if(_continue)
{
ASSERT(thing);
2001-05-10 18:16:57 +02:00
thing=thing->m_nextListThing;
2001-04-06 23:25:18 +02:00
}
else
{
thing=s_thingLists[_type];
}
while(thing)
{
2001-05-10 23:48:04 +02:00
if(thing->canCollide() && thing->checkCollisionAgainstArea(_area))
2001-04-06 23:25:18 +02:00
{
return thing;
}
2001-05-10 18:16:57 +02:00
thing=thing->m_nextListThing;
2001-04-06 23:25:18 +02:00
}
return NULL;
}
2001-02-26 21:27:20 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-05-10 23:48:04 +02:00
void CThingManager::addToThingList(CThing *_this)
2001-02-26 21:27:20 +01:00
{
2001-05-10 23:48:04 +02:00
int Type=_this->getThingType();
2001-05-25 20:43:47 +02:00
2001-05-10 23:48:04 +02:00
_this->m_nextListThing=s_thingLists[Type];
s_thingLists[Type]=_this;
2001-02-26 21:27:20 +01:00
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-05-10 23:48:04 +02:00
void CThingManager::removeFromThingList(CThing *_this)
2001-02-26 21:27:20 +01:00
{
CThing *prevThing,*thing;
prevThing=NULL;
thing=s_thingLists[_this->getThingType()];
while(thing!=_this)
{
prevThing=thing;
2001-05-10 18:16:57 +02:00
thing=thing->m_nextListThing;
2001-02-26 21:27:20 +01:00
ASSERT(thing); // Not in the list!?!?
}
if(prevThing)
{
2001-05-10 18:16:57 +02:00
prevThing->m_nextListThing=_this->m_nextListThing;
2001-02-26 21:27:20 +01:00
}
else
{
2001-05-10 18:16:57 +02:00
s_thingLists[_this->getThingType()]=_this->m_nextListThing;
2001-02-26 21:27:20 +01:00
}
}
2001-05-10 23:48:04 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-05-11 01:51:14 +02:00
void CThingManager::addToCollisionList(CThing *thing)
2001-05-10 23:48:04 +02:00
{
2001-05-11 01:51:14 +02:00
int Type=thing->getThingType();
2001-05-10 23:48:04 +02:00
2001-05-11 01:51:14 +02:00
thing->m_nextCollisionThing=s_CollisionLists[Type];
s_CollisionLists[Type]=thing;
2001-05-10 23:48:04 +02:00
}
2001-05-25 20:43:47 +02:00
/********************************************************************/
/********************************************************************/
/*** Free List Stuff ************************************************/
/********************************************************************/
/********************************************************************/
void CThingManager::initFreeList()
{
#ifdef USE_FREE_LIST
// Make sure no-one is being naughty
ASSERT(FreeListTableSize==CThing::MAX_TYPE)
for (int i=0; i<FreeListTableSize; i++)
{
sFreeListTable const &ThisType=FreeListTable[i];
int Count=ThisType.Count;
CThing **List=(CThing**)MemAlloc(Count*sizeof(CThing**),"ThingCache");
for (int t=0; t<Count; t++)
{
List[t]=0;
}
s_FreeList[ThisType.Type]=List;
}
#endif
}
/********************************************************************/
void CThingManager::resetFreeList()
{
#ifdef USE_FREE_LIST
for (int i=0; i<FreeListTableSize; i++)
{
sFreeListTable const &ThisType=FreeListTable[i];
int Count=ThisType.Count;
CThing **List=s_FreeList[i];
for (int t=0; t<Count; t++)
{
CThing *ThisThing=List[t];
while (ThisThing)
{
CThing *Next=ThisThing->NextFreeThing;
2001-07-04 20:19:13 +02:00
// ThisThing->destroy();
2001-05-25 20:43:47 +02:00
delete ThisThing;
2001-05-29 18:38:09 +02:00
FreeListCount--;
2001-05-25 20:43:47 +02:00
ThisThing=Next;
}
List[t]=0;
}
2001-05-29 15:32:17 +02:00
}
2001-05-25 20:43:47 +02:00
#endif
}
/********************************************************************/
void CThingManager::shutdownFreeList()
{
#ifdef USE_FREE_LIST
resetFreeList();
for (int i=0; i<FreeListTableSize; i++)
{
sFreeListTable const &ThisType=FreeListTable[i];
MemFree(s_FreeList[ThisType.Type]);
}
#endif
}
/********************************************************************/
CThing *CThingManager::GetThing(int Type,int SubType)
{
#ifdef USE_FREE_LIST
CThing **List=s_FreeList[Type];
CThing *Thing=List[SubType];
2001-05-29 22:31:02 +02:00
ASSERT(Type<CThing::MAX_TYPE);
ASSERT(SubType<FreeListTable[Type].Count);
2001-05-25 20:43:47 +02:00
if (Thing)
{
List[SubType]=Thing->NextFreeThing;
Thing->initDef();
Thing->NextFreeThing=0;
2001-05-29 18:38:09 +02:00
FreeListCount--;
2001-05-25 20:43:47 +02:00
}
return(Thing);
#else
return(0);
#endif
}
/********************************************************************/
void CThingManager::DeleteThing(CThing *Thing)
{
#ifdef USE_FREE_LIST
int Type=Thing->getThingType();
int SubType=Thing->getThingSubType();
CThing **List=s_FreeList[Type];
2001-05-25 21:08:35 +02:00
2001-05-25 20:43:47 +02:00
// Check its been aquired/set correctly
2001-06-14 23:17:10 +02:00
2001-07-04 20:19:13 +02:00
ASSERT(SubType!=255);
2001-06-14 23:17:10 +02:00
Thing->NextFreeThing=List[SubType];
List[SubType]=Thing;
FreeListCount++;
2001-05-25 20:43:47 +02:00
#else
delete Thing;
#endif
}
/********************************************************************/
/********************************************************************/
/********************************************************************/
/********************************************************************/
/********************************************************************/
/********************************************************************/
2001-02-26 21:27:20 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThing::init()
{
2001-05-21 17:19:18 +02:00
ParentThing=NULL;
NextThing=NULL;
2001-05-29 22:31:02 +02:00
NextFreeThing=0;
2001-04-19 01:12:24 +02:00
m_numChildren = 0;
2001-02-26 21:27:20 +01:00
Pos.vx=Pos.vy=10;
2001-05-11 01:51:14 +02:00
// These need to stay for init
2001-03-08 22:04:11 +01:00
setCollisionSize(20,20); // Some temporary defaults.. (pkg)
2001-02-26 21:27:20 +01:00
setCollisionCentreOffset(0,0);
2001-05-11 01:51:14 +02:00
// Add to thing list
CThingManager::addToThingList(this);
2001-02-26 21:27:20 +01:00
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThing::shutdown()
{
2001-05-29 18:38:09 +02:00
2001-05-25 21:08:35 +02:00
if (ParentThing)
2001-02-26 21:27:20 +01:00
{ // Is child
2001-05-21 17:19:18 +02:00
ParentThing->removeChild(this);
2001-02-26 21:27:20 +01:00
}
else
{ // Is Parent
removeAllChild();
}
// Remove from thing list
CThingManager::removeFromThingList(this);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThing::think(int _frames)
{
2001-05-25 21:08:35 +02:00
PosDelta.vx=Pos.vx-PosLast.vx;
2001-02-26 21:27:20 +01:00
PosDelta.vy=Pos.vy-PosLast.vy;
2001-04-01 23:40:52 +02:00
PosLast=Pos;
2001-02-26 21:27:20 +01:00
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-05-10 18:16:57 +02:00
#if defined (__USER_paul__) || defined (__USER_charles__)
#define SHOW_BBOX 1
int showthings=true;
#endif
2001-05-05 18:28:40 +02:00
2001-05-10 18:16:57 +02:00
#if defined (__USER_daveo__)
#define SHOW_BBOX 1
int showthings=false;
#endif
2001-05-05 18:28:40 +02:00
2001-02-26 21:27:20 +01:00
void CThing::render()
2001-05-10 18:16:57 +02:00
{
// Check Is Onscreen
2001-05-14 18:33:39 +02:00
CRECT const *ThingRect= getRenderBBox();
2001-05-10 18:16:57 +02:00
sBBox &ScrBBox=CThingManager::getRenderBBox();
DVECTOR const &CamPos=CLevel::getCameraPos();
m_RenderPos.vx = Pos.vx - CamPos.vx;
m_RenderPos.vy = Pos.vy - CamPos.vy;
// Will speed this up
m_renderFlag=true;
2001-05-14 18:33:39 +02:00
if (ThingRect->x2<ScrBBox.XMin || ThingRect->x1>ScrBBox.XMax) m_renderFlag=false;
if (ThingRect->y2<ScrBBox.YMin || ThingRect->y1>ScrBBox.YMax) m_renderFlag=false;
2001-05-10 18:16:57 +02:00
/***/
#ifdef SHOW_BBOX
if(showthings) ShowBBox();
#endif
}
2001-06-18 21:31:50 +02:00
2001-08-04 23:06:19 +02:00
/****************************************************************************************/
bool CThing::isOnScreen(DVECTOR Pos)
{
// Check Is Onscreen
sBBox &ScrBBox=CThingManager::getRenderBBox();
DVECTOR const &CamPos=CLevel::getCameraPos();
2001-08-04 23:21:25 +02:00
// Pos.vx-=CamPos.vx;
// Pos.vy-=CamPos.vy;
2001-08-04 23:06:19 +02:00
if (Pos.vx<ScrBBox.XMin) return(false);
if (Pos.vx>ScrBBox.XMax) return(false);
if (Pos.vy<ScrBBox.YMin) return(false);
if (Pos.vy>ScrBBox.YMax) return(false);
return(true);
}
2001-06-18 21:31:50 +02:00
/****************************************************************************************/
void CThing::calcRenderPos(DVECTOR const &Pos,DVECTOR &renderPos)
{
DVECTOR const &CamPos=CLevel::getCameraPos();
renderPos.vx = Pos.vx - CamPos.vx;
renderPos.vy = Pos.vy - CamPos.vy;
}
2001-05-10 18:16:57 +02:00
/****************************************************************************************/
#ifdef SHOW_BBOX
#include "gfx\prim.h"
void CThing::ShowBBox()
2001-02-26 21:27:20 +01:00
{
if(showthings)
{
2001-05-10 18:16:57 +02:00
DVECTOR const &ofs=CLevel::getCameraPos();
2001-02-26 21:27:20 +01:00
CRECT area;
2001-04-27 21:57:12 +02:00
area=getCollisionArea();
area.x1-=ofs.vx;
area.y1-=ofs.vy;
area.x2-=ofs.vx;
area.y2-=ofs.vy;
2001-05-05 18:28:40 +02:00
if(area.x1<=511&&area.x2>=0 && area.y1<=255&&area.y2>=0)
2001-04-27 21:57:12 +02:00
{
DrawLine(area.x1,area.y1,area.x2,area.y1,255,255,255,0);
DrawLine(area.x2,area.y1,area.x2,area.y2,255,255,255,0);
DrawLine(area.x2,area.y2,area.x1,area.y2,255,255,255,0);
DrawLine(area.x1,area.y2,area.x1,area.y1,255,255,255,0);
area.x1=Pos.vx-10-ofs.vx;
area.y1=Pos.vy-10-ofs.vy;
area.x2=Pos.vx+10-ofs.vx;
area.y2=Pos.vy+10-ofs.vy;
DrawLine(area.x1,area.y1,area.x2,area.y2,255,0,0,0);
DrawLine(area.x2,area.y1,area.x1,area.y2,255,0,0,0);
}
2001-02-26 21:27:20 +01:00
}
}
2001-03-01 23:33:18 +01:00
#endif
2001-02-26 21:27:20 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThing::addChild(CThing *Child)
{
2001-05-21 17:19:18 +02:00
CThing *List=NextThing;
2001-02-26 21:27:20 +01:00
if ( List )
{
// Find end of list
2001-05-25 21:08:35 +02:00
while (List->NextThing)
2001-02-26 21:27:20 +01:00
{
2001-05-21 17:19:18 +02:00
List=List->NextThing;
2001-02-26 21:27:20 +01:00
}
2001-05-21 17:19:18 +02:00
List->NextThing=Child;
Child->ParentThing=this;
2001-04-19 01:12:24 +02:00
m_numChildren++;
2001-02-26 21:27:20 +01:00
}
else
{
// List does not exist, create
2001-05-21 17:19:18 +02:00
NextThing = Child;
Child->ParentThing=this;
2001-04-19 01:12:24 +02:00
m_numChildren++;
2001-02-26 21:27:20 +01:00
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThing::removeChild(CThing *Child)
{
2001-05-21 17:19:18 +02:00
CThing *List=NextThing;
2001-02-26 21:27:20 +01:00
CThing *Last=NULL;
// Find Child
2001-05-21 17:19:18 +02:00
while ( List != Child && List->NextThing )
2001-02-26 21:27:20 +01:00
{
Last = List;
2001-05-21 17:19:18 +02:00
List = List->NextThing;
2001-02-26 21:27:20 +01:00
}
// if there are no more links to continue down, the current 'List' must either be the correct item, or the item does not
// exist in the list at all
ASSERT( List == Child );
if ( Last )
{
2001-05-21 17:19:18 +02:00
Last->NextThing = List->NextThing;
2001-02-26 21:27:20 +01:00
}
else
{
2001-05-21 17:19:18 +02:00
this->NextThing = List->NextThing;
2001-02-26 21:27:20 +01:00
}
2001-04-19 01:12:24 +02:00
m_numChildren--;
2001-05-21 17:19:18 +02:00
Child->ParentThing=NULL;
2001-02-26 21:27:20 +01:00
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThing::removeAllChild()
{
2001-05-21 17:19:18 +02:00
CThing *List=NextThing;
2001-02-26 21:27:20 +01:00
while (List)
{
2001-05-21 17:19:18 +02:00
CThing *NextThing=List->NextThing;
List->ParentThing=NULL;
List->NextThing=NULL;
List=NextThing;
2001-02-26 21:27:20 +01:00
}
2001-05-21 17:19:18 +02:00
NextThing=NULL;
2001-04-19 01:12:24 +02:00
m_numChildren = 0;
}
2001-04-23 17:12:44 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThing::deleteAllChild()
{
2001-05-21 17:19:18 +02:00
CThing *List=NextThing;
2001-04-23 17:12:44 +02:00
while (List)
{
2001-05-21 17:19:18 +02:00
CThing *NextThing=List->NextThing;
List->ParentThing=NULL;
List->NextThing=NULL;
2001-04-23 17:12:44 +02:00
List->shutdown();
2001-05-25 20:43:47 +02:00
CThingManager::DeleteThing(List);
2001-05-21 17:19:18 +02:00
List=NextThing;
2001-04-23 17:12:44 +02:00
}
2001-05-21 17:19:18 +02:00
NextThing=NULL;
2001-04-23 17:12:44 +02:00
m_numChildren = 0;
}
2001-02-26 21:27:20 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThing::setCollisionSize(int _w,int _h)
{
m_collisionSize.vx=_w;
m_collisionSize.vy=_h;
if(m_collisionSize.vx>m_collisionSize.vy)
{
m_collisionRadius=m_collisionSize.vx;
}
else
{
m_collisionRadius=m_collisionSize.vy;
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThing::updateCollisionArea()
{
m_collisionCentre.vx=Pos.vx+m_collisionCentreOffset.vx;
m_collisionCentre.vy=Pos.vy+m_collisionCentreOffset.vy;
m_collisionArea.x1=m_collisionCentre.vx-(m_collisionSize.vx/2);
m_collisionArea.x2=m_collisionArea.x1+m_collisionSize.vx;
m_collisionArea.y1=m_collisionCentre.vy-(m_collisionSize.vy/2);
m_collisionArea.y2=m_collisionArea.y1+m_collisionSize.vy;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-04-01 23:40:52 +02:00
int CThing::checkCollisionAgainst(CThing *_thisThing, int _frames)
2001-02-26 21:27:20 +01:00
{
2001-07-23 21:26:37 +02:00
// DVECTOR pos,thisThingPos;
2001-02-26 21:27:20 +01:00
int radius;
int collided;
2001-07-23 21:26:37 +02:00
DVECTOR const &pos=getCollisionCentre();
DVECTOR const &thisThingPos=_thisThing->getCollisionCentre();
2001-02-26 21:27:20 +01:00
radius=getCollisionRadius()+_thisThing->getCollisionRadius();
collided=false;
2001-08-13 23:29:12 +02:00
if(abs(pos.vx-thisThingPos.vx)<radius && abs(pos.vy-thisThingPos.vy)<radius)
2001-02-26 21:27:20 +01:00
{
2001-07-23 21:26:37 +02:00
// CRECT thisRect,thatRect;
2001-03-08 21:12:47 +01:00
2001-07-23 21:26:37 +02:00
CRECT const &thisRect=getCollisionArea();
CRECT const &thatRect=_thisThing->getCollisionArea();
2001-02-26 21:27:20 +01:00
2001-08-13 23:29:12 +02:00
// if(((thisRect.x1>=thatRect.x1&&thisRect.x1<=thatRect.x2)||(thisRect.x2>=thatRect.x1&&thisRect.x2<=thatRect.x2)||(thisRect.x1<=thatRect.x1&&thisRect.x2>=thatRect.x2))&&
// ((thisRect.y1>=thatRect.y1&&thisRect.y1<=thatRect.y2)||(thisRect.y2>=thatRect.y1&&thisRect.y2<=thatRect.y2)||(thisRect.y1<=thatRect.y1&&thisRect.y2>=thatRect.y2)))
if (thisRect.x2<thatRect.x1 || thisRect.x1>thatRect.x2) return(false);
if (thisRect.y2<thatRect.y1 || thisRect.y1>thatRect.y2) return(false);
2001-02-26 21:27:20 +01:00
{
collided=true;
}
}
return collided;
}
2001-04-06 23:25:18 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int CThing::checkCollisionAgainstArea(CRECT *_rect)
{
2001-07-23 21:26:37 +02:00
// CRECT thisRect;
2001-04-06 23:25:18 +02:00
int ret;
2001-07-23 21:26:37 +02:00
CRECT const &thisRect=getCollisionArea();
2001-04-06 23:25:18 +02:00
ret=false;
if(((thisRect.x1>=_rect->x1&&thisRect.x1<=_rect->x2)||(thisRect.x2>=_rect->x1&&thisRect.x2<=_rect->x2)||(thisRect.x1<=_rect->x1&&thisRect.x2>=_rect->x2))&&
((thisRect.y1>=_rect->y1&&thisRect.y1<=_rect->y2)||(thisRect.y2>=_rect->y1&&thisRect.y2<=_rect->y2)||(thisRect.y1<=_rect->y1&&thisRect.y2>=_rect->y2)))
{
ret=true;
}
return ret;
}
2001-02-26 21:27:20 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThing::processEvent(GAME_EVENT _event,CThing *_sourceThing)
{
// do nothing by default - ignore event
}
2001-04-17 22:09:33 +02:00
2001-03-08 21:12:47 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */