This commit is contained in:
Charles 2001-03-08 20:12:47 +00:00
parent 11410feeb4
commit 7ad4ef60f4
11 changed files with 344 additions and 70 deletions

View File

@ -73,7 +73,8 @@ enemy_src := npc \
nocto \
nfskull \
nsklfish \
ngary
ngary \
nplatfrm
projectl_src := projectl

View File

@ -295,16 +295,6 @@ void CNpcEnemy::processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY
}
}
void CNpcEnemy::processGenericCircularPath( int _frames )
{
m_rotation += m_data[m_type].speed;
m_rotation %= 4096;
Pos.vx = m_base.vx + ( ( m_extension * rcos( m_rotation ) ) >> 12 );
Pos.vy = m_base.vy + ( ( m_extension * rsin( m_rotation ) ) >> 12 );
}
bool CNpcEnemy::isCollisionWithGround()
{
ASSERT(m_layerCollision);

View File

@ -209,7 +209,7 @@ void CNpcEnemy::init()
{
CEnemyThing::init();
m_type = NPC_LINEAR_PLATFORM;
m_type = NPC_CLAM_STATIC;
// sActorHdr *Hdr = m_skel.Load( m_data[m_type].skelType );
// m_skel.Init( Hdr );
@ -891,13 +891,6 @@ void CNpcEnemy::processMovement(int _frames)
break;
}
case NPC_MOVEMENT_FIXED_CIRCULAR:
{
processGenericCircularPath( _frames );
break;
}
case NPC_MOVEMENT_MOTHER_JELLYFISH:
{
processMotherJellyfishMovement( _frames );

View File

@ -116,8 +116,6 @@ public:
NPC_PENDULUM,
NPC_FIREBALL,
NPC_SAW_BLADE,
NPC_LINEAR_PLATFORM,
NPC_CIRCULAR_PLATFORM,
NPC_SMALL_JELLYFISH_1,
NPC_SMALL_JELLYFISH_2,
NPC_ANEMONE_1,
@ -246,7 +244,6 @@ protected:
NPC_MOVEMENT_STATIC = 0,
NPC_MOVEMENT_FIXED_PATH = 1,
NPC_MOVEMENT_FIXED_PATH_WALK,
NPC_MOVEMENT_FIXED_CIRCULAR,
NPC_MOVEMENT_MOTHER_JELLYFISH,
NPC_MOVEMENT_SUB_SHARK,
NPC_MOVEMENT_FLYING_DUTCHMAN,
@ -357,7 +354,6 @@ protected:
void processGenericGetUserDist( int _frames, s32 *distX, s32 *distY );
void processGenericFixedPathMove( int _frames, s32 *moveX, s32 *moveY, s32 *moveVel, s32 *moveDist );
void processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY );
void processGenericCircularPath( int _frames );
bool processGroundCollisionReverse( s32 *moveX, s32 *moveY );
// small jellyfish functions

View File

@ -15,6 +15,10 @@
#include "enemy\npc.h"
#endif
#ifndef __ENEMY_NPLATFRM_H__
#include "enemy\nplatfrm.h"
#endif
#ifndef __PLAYER_PLAYER_H__
#include "player\player.h"
#endif
@ -59,6 +63,32 @@ CNpcFriend::NPC_FRIEND_DATA CNpcFriend::m_data[NPC_FRIEND_UNIT_TYPE_MAX] =
},
};
CNpcPlatform::NPC_PLATFORM_DATA CNpcPlatform::m_data[NPC_PLATFORM_TYPE_MAX] =
{
{ // NPC_LINEAR_PLATFORM
ACTORS_CLAM_A3D,
ANIM_CLAM_CLAMSHUT,
NPC_PLATFORM_MOVEMENT_FIXED_PATH,
3,
//512,
2048,
true,
DAMAGE__NONE,
0,
},
{ // NPC_CIRCULAR_PLATFORM
ACTORS_CLAM_A3D,
ANIM_CLAM_CLAMSHUT,
NPC_PLATFORM_MOVEMENT_FIXED_CIRCULAR,
3,
128,
false,
DAMAGE__NONE,
0,
},
};
CNpcEnemy::NPC_DATA CNpcEnemy::m_data[NPC_UNIT_TYPE_MAX] =
{
{ // NPC_FALLING_ITEM
@ -163,41 +193,6 @@ CNpcEnemy::NPC_DATA CNpcEnemy::m_data[NPC_UNIT_TYPE_MAX] =
0,
},
{ // NPC_LINEAR_PLATFORM
ACTORS_CLAM_A3D,
ANIM_CLAM_CLAMSHUT,
NPC_INIT_DEFAULT,
NPC_SENSOR_NONE,
NPC_MOVEMENT_FIXED_PATH,
NPC_MOVEMENT_MODIFIER_NONE,
NPC_CLOSE_NONE,
NPC_TIMER_NONE,
false,
3,
//512,
2048,
true,
DAMAGE__NONE,
0,
},
{ // NPC_CIRCULAR_PLATFORM
ACTORS_CLAM_A3D,
ANIM_CLAM_CLAMSHUT,
NPC_INIT_CIRCULAR_PLATFORM,
NPC_SENSOR_NONE,
NPC_MOVEMENT_FIXED_CIRCULAR,
NPC_MOVEMENT_MODIFIER_NONE,
NPC_CLOSE_NONE,
NPC_TIMER_NONE,
false,
3,
128,
false,
DAMAGE__NONE,
0,
},
{ // NPC_SMALL_JELLYFISH_1
ACTORS_CLAM_A3D,
ANIM_CLAM_CLAMSHUT,

View File

@ -27,6 +27,10 @@
#include "enemy\npc.h"
#endif
#ifndef __ENEMY_NPLATFRM_H__
#include "enemy\nplatfrm.h"
#endif
#ifndef __PROJECTL_PROJECTL_H__
#include "projectl\projectl.h"
#endif
@ -230,8 +234,8 @@ void CGameScene::initLevel()
CConversation::registerConversationScript(SCRIPTS_SPEECHTEST_DAT); // Register one script for testing..
#ifdef __USER_charles__
CNpcEnemy *enemy;
enemy=new ("test enemy") CNpcEnemy;
CNpcPlatform *enemy;
enemy=new ("test enemy") CNpcPlatform;
enemy->init();
enemy->setLayerCollision( Level.getCollisionLayer() );
#endif

View File

@ -1336,15 +1336,19 @@ void CPlayer::setPlatform( CThing *newPlatform )
{
int colHeight;
int platformHeight;
DVECTOR newPos;
DVECTOR testPos;
m_platform = newPlatform;
m_onPlatform = true;
m_onPlatform = getCentreCollision();
if ( m_onPlatform )
{
newPos = getNewCollidedPos();
colHeight = m_layerCollision->getHeightFromGround( Pos.vx, Pos.vy, 16 );
platformHeight = m_platform->getPos().vy - Pos.vy;
platformHeight = newPos.vy - Pos.vy;
if ( platformHeight > colHeight )
{
@ -1361,7 +1365,7 @@ void CPlayer::setPlatform( CThing *newPlatform )
// have collided with a platform
m_moveVel.vy=0;
Pos.vy += colHeight;
Pos = newPos;
if ( !m_prevOnPlatform )
{
@ -1397,7 +1401,7 @@ void CPlayer::setPlatform( CThing *newPlatform )
}
else
{
Pos.vx += m_platform->getPos().vx - m_prevPlatformPos.vx;
//Pos.vx += m_platform->getPos().vx - m_prevPlatformPos.vx;
}
// Move the camera offset
@ -1441,6 +1445,33 @@ void CPlayer::setPlatform( CThing *newPlatform )
m_prevPlatformPos = m_platform->getPos();
}
else
{
newPlatform->removeChild( this );
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::shove( DVECTOR move )
{
int colHeight = m_layerCollision->getHeightFromGround( Pos.vx + move.vx, Pos.vy + move.vy, 1 );
if( colHeight < 0 )
{
// target position in within wall, abort
return;
}
else
{
Pos.vx += move.vx;
Pos.vy += move.vy;
}
}
/*===========================================================================

View File

@ -160,6 +160,7 @@ public:
virtual void shutdown();
virtual void think(int _frames);
virtual void render();
virtual void shove(DVECTOR move);
DVECTOR getCameraPos();

View File

@ -25,6 +25,8 @@
#include "game\game.h"
#endif
#include "utils\utils.h"
/* Std Lib
------- */
@ -123,6 +125,21 @@ void CThingManager::thinkAllThings(int _frames)
player->clearPlatform();
}
// Player -> Platform collision
thing1=s_thingLists[CThing::TYPE_PLATFORM];
thing2=s_thingLists[CThing::TYPE_PLAYER];
while(thing1&&thing2)
{
thing1->removeAllChild();
if(thing1->canCollide()&&
thing1->checkCollisionAgainst(thing2))
{
thing1->addChild( thing2 );
thing1->collidedWith(thing2);
}
thing1=thing1->m_nextThing;
}
// Player -> Pickup collision
thing1=s_thingLists[CThing::TYPE_PICKUP];
thing2=s_thingLists[CThing::TYPE_PLAYER];
@ -277,8 +294,11 @@ void CThing::init()
// Add to thing list
CThingManager::addToThingList(this);
setCollisionSize(20,20); // Some temporary defaults.. (pkg)
setCollisionSize(200,20); // Some temporary defaults.. (pkg)
setCollisionCentreOffset(0,0);
m_collisionAngle = 0;
m_collisionStickyBoundary = 0;
m_centreCollision = false;
}
/*----------------------------------------------------------------------
@ -313,6 +333,9 @@ void CThing::think(int _frames)
DVECTOR PosLast=Pos;
PosDelta.vx=Pos.vx-PosLast.vx;
PosDelta.vy=Pos.vy-PosLast.vy;
m_collisionAngle++;
m_collisionAngle %= 4096;
}
/*----------------------------------------------------------------------
@ -343,10 +366,54 @@ void CThing::render()
if(area.x1<=511&&area.x2>=0&&
area.y1<=255&&area.y2>=0)
{
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);
area=getCollisionArea();
SVECTOR points[4];
VECTOR vecPoints[4];
points[0].vx = area.x1 - Pos.vx;
points[0].vy = area.y1 - Pos.vy;
points[1].vx = area.x1 - Pos.vx;
points[1].vy = area.y2 - Pos.vy;
points[2].vx = area.x2 - Pos.vx;
points[2].vy = area.y2 - Pos.vy;
points[3].vx = area.x2 - Pos.vx;
points[3].vy = area.y1 - Pos.vy;
MATRIX mtx;
SetIdentNoTrans(&mtx );
RotMatrixZ( m_collisionAngle, &mtx );
ApplyMatrix( &mtx, &points[0], &vecPoints[0] );
ApplyMatrix( &mtx, &points[1], &vecPoints[1] );
ApplyMatrix( &mtx, &points[2], &vecPoints[2] );
ApplyMatrix( &mtx, &points[3], &vecPoints[3] );
vecPoints[0].vx += Pos.vx - ofs.vx;
vecPoints[0].vy += Pos.vy - ofs.vy;
vecPoints[1].vx += Pos.vx - ofs.vx;
vecPoints[1].vy += Pos.vy - ofs.vy;
vecPoints[2].vx += Pos.vx - ofs.vx;
vecPoints[2].vy += Pos.vy - ofs.vy;
vecPoints[3].vx += Pos.vx - ofs.vx;
vecPoints[3].vy += Pos.vy - 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);
DrawLine( vecPoints[0].vx, vecPoints[0].vy, vecPoints[1].vx, vecPoints[1].vy,255,255,255,0);
DrawLine( vecPoints[1].vx, vecPoints[1].vy, vecPoints[2].vx, vecPoints[2].vy,255,255,255,0);
DrawLine( vecPoints[2].vx, vecPoints[2].vy, vecPoints[3].vx, vecPoints[3].vy,255,255,255,0);
DrawLine( vecPoints[3].vx, vecPoints[3].vy, vecPoints[0].vx, vecPoints[0].vy,255,255,255,0);
area.x1=Pos.vx-10-ofs.vx;
area.y1=Pos.vy-10-ofs.vy;
@ -494,6 +561,8 @@ int CThing::checkCollisionAgainst(CThing *_thisThing)
int radius;
int collided;
MATRIX mtx;
pos=getCollisionCentre();
thisThingPos=_thisThing->getCollisionCentre();
@ -505,12 +574,174 @@ int CThing::checkCollisionAgainst(CThing *_thisThing)
CRECT thisRect,thatRect;
thisRect=getCollisionArea();
// ensure user 'sticks' to platform whilst it is moving along
thisRect.x1 -= m_collisionStickyBoundary;
thisRect.y1 -= m_collisionStickyBoundary;
thisRect.x2 += m_collisionStickyBoundary;
thisRect.y2 += m_collisionStickyBoundary;
thatRect=_thisThing->getCollisionArea();
// rotate thatPos opposite way to this CThing's collision angle, so that we can regard them both as being at 0 rotation
// get target thing's position
DVECTOR thatPos = _thisThing->getPos();
// get target thing's position relative to this thing's position
SVECTOR relativePos;
relativePos.vx = thatPos.vx - Pos.vx;
relativePos.vy = thatPos.vy - Pos.vy;
VECTOR newPos;
// get target thing's collision area relative to 0
thatRect.x1 -= thatPos.vx;
thatRect.y1 -= thatPos.vy;
thatRect.x2 -= thatPos.vx;
thatRect.y2 -= thatPos.vy;
SetIdentNoTrans(&mtx );
RotMatrixZ( -m_collisionAngle, &mtx );
// rotation target relative position back to 0 by this thing's collision angle
ApplyMatrix( &mtx, &relativePos, &newPos );
// add on this thing's position to get new target thing's position after rotation around this thing
newPos.vx += Pos.vx;
newPos.vy += Pos.vy;
// reposition target thing's collision area
thatRect.x1 += newPos.vx;
thatRect.y1 += newPos.vy;
thatRect.x2 += newPos.vx;
thatRect.y2 += newPos.vy;
// check to see if bounding boxes collide
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;
// check to see if centre point (i.e. where the object is standing) collides too
if ( ( newPos.vx >= thisRect.x1 && newPos.vx <= thisRect.x2 ) &&
( newPos.vy >= thisRect.y1 && newPos.vy <= thisRect.y2 ) )
{
thisRect=getCollisionArea();
_thisThing->setCentreCollision( true );
// 'render' collision box at correct angle
SVECTOR testPointsNonRel[4];
VECTOR testPoints[4];
testPointsNonRel[0].vx = thisRect.x1 - Pos.vx;
testPointsNonRel[0].vy = thisRect.y1 - Pos.vy;
testPointsNonRel[1].vx = thisRect.x2 - Pos.vx;
testPointsNonRel[1].vy = thisRect.y1 - Pos.vy;
testPointsNonRel[2].vx = thisRect.x2 - Pos.vx;
testPointsNonRel[2].vy = thisRect.y2 - Pos.vy;
testPointsNonRel[3].vx = thisRect.x1 - Pos.vx;
testPointsNonRel[3].vy = thisRect.y2 - Pos.vy;
SetIdentNoTrans(&mtx );
RotMatrixZ( m_collisionAngle, &mtx );
int i;
for ( i = 0 ; i < 4 ; i++ )
{
ApplyMatrix( &mtx, &testPointsNonRel[i], &testPoints[i] );
testPoints[i].vx += Pos.vx;
testPoints[i].vy += Pos.vy;
}
// now find the highest y pos
// first set highestY to lowest of the four points
s16 highestY = testPoints[0].vy;
for ( i = 1 ; i < 4 ; i++ )
{
if ( testPoints[i].vy > highestY ) // remember y is inverted
{
highestY = testPoints[i].vy;
}
}
for ( i = 0 ; i < 4 ; i++ )
{
int j = i + 1;
j %= 4;
VECTOR highestX, lowestX;
if ( testPoints[i].vx < testPoints[j].vx )
{
lowestX = testPoints[i];
highestX = testPoints[j];
}
else
{
lowestX = testPoints[j];
highestX = testPoints[i];
}
if ( highestX.vx == lowestX.vx )
{
// have to compare heights of both points to get highest
if ( lowestX.vy < highestY )
{
highestY = lowestX.vy;
}
if ( highestX.vy < highestY )
{
highestY = highestX.vy;
}
}
else
{
if ( thatPos.vx >= lowestX.vx && thatPos.vx <= highestX.vx )
{
// current position is above or below this line
s16 testY;
testY = lowestX.vy + ( ( thatPos.vx - lowestX.vx ) * ( highestX.vy - lowestX.vy ) ) /
( highestX.vx - lowestX.vx );
if ( testY < highestY )
{
highestY = testY;
}
}
}
}
thatPos.vy = highestY;
_thisThing->setNewCollidedPos( thatPos );
}
else
{
_thisThing->setCentreCollision( false );
}
}
}
@ -528,5 +759,17 @@ void CThing::processEvent(GAME_EVENT _event,CThing *_sourceThing)
// do nothing by default - ignore event
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CThing::shove( DVECTOR move )
{
Pos.vx += move.vx;
Pos.vy += move.vy;
}
/*===========================================================================
end */

View File

@ -68,12 +68,12 @@ public:
typedef enum
{
TYPE_PICKUP,
TYPE_PLATFORM,
TYPE_PLAYER,
TYPE_PLAYERPROJECTILE,
TYPE_NPC,
TYPE_ENEMY,
TYPE_ENEMYPROJECTILE,
TYPE_PLATFORM,
TYPE_TRIGGER,
MAX_TYPE,
@ -98,6 +98,8 @@ public:
DVECTOR getPos() {return Pos;}
virtual void shove(DVECTOR move);
CThing *getNext() {return Next;}
virtual void processEvent(GAME_EVENT _event,CThing *_sourceThing);
@ -135,15 +137,25 @@ protected:
void setCollisionSize(int _w,int _h);
void setCollisionCentreOffset(int _x,int _y) {m_collisionCentreOffset.vx=_x;m_collisionCentreOffset.vy=_y;}
void setCollisionCentreOffset(DVECTOR xy) {m_collisionCentreOffset=xy;}
void setCentreCollision(bool newCentreCollision) {m_centreCollision = newCentreCollision;}
void setNewCollidedPos(DVECTOR newPos) {m_newCollidedPos = newPos;}
void setCollisionStickyBoundary(int boundary) {m_collisionStickyBoundary = boundary;}
int getCollisionRadius() {return m_collisionRadius;}
CRECT getCollisionArea() {return m_collisionArea;}
DVECTOR getCollisionCentre() {return m_collisionCentre;}
s16 getCollisionAngle() {return m_collisionAngle;}
bool getCentreCollision() {return m_centreCollision;}
DVECTOR getNewCollidedPos() {return m_newCollidedPos;}
private:
DVECTOR m_collisionSize;
DVECTOR m_collisionCentreOffset;
int m_collisionRadius;
int m_collisionStickyBoundary; // for platforms
CRECT m_collisionArea;
DVECTOR m_collisionCentre;
s16 m_collisionAngle;
bool m_centreCollision;
DVECTOR m_newCollidedPos;
};

View File

@ -185,6 +185,14 @@ SOURCE=..\..\..\source\enemy\npcpath.h
# End Source File
# Begin Source File
SOURCE=..\..\..\source\enemy\nplatfrm.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\source\enemy\nplatfrm.h
# End Source File
# Begin Source File
SOURCE=..\..\..\source\enemy\nscrab.cpp
# End Source File
# Begin Source File