/*========================================================================= thing.cpp Author: PKG Created: Project: Spongebob Purpose: Copyright (c) 2001 Climax Development Ltd ===========================================================================*/ /*---------------------------------------------------------------------- Includes -------- */ #include "thing\thing.h" /* Std Lib ------- */ /* Data ---- */ /*---------------------------------------------------------------------- Tyepdefs && Defines ------------------- */ /*---------------------------------------------------------------------- Structure defintions -------------------- */ /*---------------------------------------------------------------------- Function Prototypes ------------------- */ /*---------------------------------------------------------------------- Vars ---- */ CThing *CThingManager::s_thingLists[CThing::MAX_TYPE]={NULL,NULL}; int CThingManager::s_initialised=false; /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThingManager::init() { int i; ASSERT(!s_initialised); for(i=0;ishutdown(); delete thing; } } s_initialised=false; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThingManager::thinkAllThings(int _frames) { int i; CThing *thing; CThing *thing1,*thing2; for(i=0;ithink(_frames); thing->updateCollisionArea(); thing=thing->m_nextThing; } } // Player -> Pickup collision thing1=s_thingLists[CThing::TYPE_PICKUP]; thing2=s_thingLists[CThing::TYPE_PLAYER]; while(thing1&&thing2) { if(thing1->canCollide()&& thing1->checkCollisionAgainst(thing2)) { thing1->collidedWith(thing2); } thing1=thing1->m_nextThing; } // Player -> Enemy collision thing1=s_thingLists[CThing::TYPE_ENEMY]; thing2=s_thingLists[CThing::TYPE_PLAYER]; while(thing1&&thing2) { if(thing1->canCollide()&& thing1->checkCollisionAgainst(thing2)) { thing1->collidedWith(thing2); } thing1=thing1->m_nextThing; } // Player -> Enemy projectile collision thing1=s_thingLists[CThing::TYPE_ENEMYPROJECTILE]; thing2=s_thingLists[CThing::TYPE_PLAYER]; while(thing1&&thing2) { if(thing1->canCollide()&& thing1->checkCollisionAgainst(thing2)) { thing1->collidedWith(thing2); } thing1=thing1->m_nextThing; } } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThingManager::renderAllThings() { int i; CThing *thing; for(i=0;irender(); thing=thing->m_nextThing; } } } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThingManager::processEventAllThings(GAME_EVENT _event,CThing *_sourceThing) { int i; CThing *thing; for(i=0;iprocessEvent(_event,_sourceThing); thing=thing->m_nextThing; } } } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThingManager::addToThingList(CThing *_this) { _this->m_nextThing=s_thingLists[_this->getThingType()]; s_thingLists[_this->getThingType()]=_this; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThingManager::removeFromThingList(CThing *_this) { CThing *prevThing,*thing; prevThing=NULL; thing=s_thingLists[_this->getThingType()]; while(thing!=_this) { prevThing=thing; thing=thing->m_nextThing; ASSERT(thing); // Not in the list!?!? } if(prevThing) { prevThing->m_nextThing=_this->m_nextThing; } else { s_thingLists[_this->getThingType()]=_this->m_nextThing; } } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThing::init() { Parent=NULL; Next=NULL; Pos.vx=Pos.vy=10; // Add to thing list CThingManager::addToThingList(this); setCollisionSize(20,20); // Some temporary defaults.. (pkg) setCollisionCentreOffset(0,0); } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThing::shutdown() { if (Parent) { // Is child Parent->removeChild(this); } else { // Is Parent removeAllChild(); } // Remove from thing list CThingManager::removeFromThingList(this); } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThing::think(int _frames) { DVECTOR PosLast=Pos; PosDelta.vx=Pos.vx-PosLast.vx; PosDelta.vy=Pos.vy-PosLast.vy; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ #ifdef __USER_paul__ int showthings=true; #include "gfx\prim.h" #include "level\level.h" #endif void CThing::render() { #ifdef __USER_paul__ if(showthings) { DVECTOR ofs; CRECT area; int x1,y1,x2,y2; ofs=CLevel::getCameraPos(); area=getCollisionArea(); area.x1-=ofs.vx; area.y1-=ofs.vy; area.x2-=ofs.vx; area.y2-=ofs.vy; DrawLine(area.x1,area.y1,area.x1,area.y2,255,255,255,0); DrawLine(area.x1,area.y2,area.x2,area.y2,255,255,255,0); DrawLine(area.x2,area.y2,area.x2,area.y1,255,255,255,0); DrawLine(area.x2,area.y1,area.x1,area.y1,255,255,255,0); x1=Pos.vx-10-ofs.vx; y1=Pos.vy-10-ofs.vy; x2=Pos.vx+10-ofs.vx; y2=Pos.vy+10-ofs.vy; DrawLine(x1,y1,x2,y2,255,0,0,0); DrawLine(x2,y1,x1,y2,255,0,0,0); } #endif } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThing::addChild(CThing *Child) { CThing *List=Next; if ( List ) { // Find end of list while (List->Next) { List=List->Next; } List->Next=Child; Child->Parent=this; } else { // List does not exist, create Next = Child; Child->Parent=this; } } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThing::removeChild(CThing *Child) { CThing *List=Next; CThing *Last=NULL; // Find Child while ( List != Child && List->Next ) { Last = List; List = List->Next; } // 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 ) { Last->Next = List->Next; } else { this->Next = List->Next; } Child->Parent=NULL; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThing::removeAllChild() { CThing *List=Next; while (List) { CThing *Next=List->Next; List->Parent=NULL; List->Next=NULL; List=Next; } Next=NULL; } /*---------------------------------------------------------------------- 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: ---------------------------------------------------------------------- */ int CThing::checkCollisionAgainst(CThing *_thisThing) { DVECTOR pos,thisThingPos; int radius; int collided; pos=getCollisionCentre(); thisThingPos=_thisThing->getCollisionCentre(); radius=getCollisionRadius()+_thisThing->getCollisionRadius(); collided=false; if(abs(pos.vx-thisThingPos.vx)getCollisionArea(); 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))) { collided=true; } } return collided; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CThing::processEvent(GAME_EVENT _event,CThing *_sourceThing) { // do nothing by default - ignore event } /*=========================================================================== end */