This commit is contained in:
Charles 2001-01-22 22:24:53 +00:00
parent dd7ab2aee8
commit 598a1b7e33
9 changed files with 328 additions and 51 deletions

View File

@ -61,6 +61,7 @@ enemy_src := 2denemy \
nshrkman \
ngeneric \
nanemone \
neyeball \
enemy
projectl_src := projectl

47
source/enemy/neyeball.cpp Normal file
View File

@ -0,0 +1,47 @@
/*=========================================================================
neyeball.cpp
Author: CRB
Created:
Project: Spongebob
Purpose:
Copyright (c) 2000 Climax Development Ltd
===========================================================================*/
#ifndef __ENEMY_NPC_H__
#include "enemy\npc.h"
#endif
#ifndef __GAME_GAME_H__
#include "game\game.h"
#endif
#ifndef __PLAYER_PLAYER_H__
#include "player\player.h"
#endif
#ifndef __PROJECTL_PROJECTL_H__
#include "projectl\projectl.h"
#endif
void CNpc::processCloseEyeballAttack( int _frames )
{
if ( Next )
{
// already have child, ignore
}
else
{
// create child projectile which will be deleted when the projectile has returned
CProjectile *projectile;
projectile = new ( "test projectile" ) CProjectile;
projectile->init( Pos, m_fireHeading, CProjectile::PROJECTILE_USER_SEEK, CProjectile::PROJECTILE_INFINITE_LIFE );
addChild( projectile );
}
}

View File

@ -3,9 +3,9 @@
npc.cpp
Author: CRB
Created:
Created:
Project: Spongebob
Purpose:
Purpose:
Copyright (c) 2000 Climax Development Ltd
@ -277,10 +277,10 @@ CNpc::NPC_DATA CNpc::m_data[NPC_UNIT_TYPE_MAX] =
{ // NPC_EYEBALL
NPC_INIT_DEFAULT,
NPC_SENSOR_NONE,
NPC_SENSOR_EYEBALL_USER_CLOSE,
NPC_MOVEMENT_STATIC,
NPC_MOVEMENT_MODIFIER_NONE,
NPC_CLOSE_NONE,
NPC_CLOSE_EYEBALL_ATTACK,
NPC_TIMER_NONE,
false,
0,
@ -387,7 +387,7 @@ CNpc::NPC_DATA CNpc::m_data[NPC_UNIT_TYPE_MAX] =
void CNpc::init()
{
m_type = NPC_GHOST_PIRATE;
m_type = NPC_EYEBALL;
m_heading = m_fireHeading = 0;
m_movementTimer = 0;
@ -718,6 +718,20 @@ bool CNpc::processSensor()
}
}
case NPC_SENSOR_EYEBALL_USER_CLOSE:
{
if ( xDistSqr + yDistSqr < 40000 )
{
m_controlFunc = NPC_CONTROL_CLOSE;
return( true );
}
else
{
return( false );
}
}
default:
return( false );
}
@ -793,7 +807,7 @@ void CNpc::processMovement(int _frames)
m_heading += moveDist;
m_heading = m_heading % ONE;
s32 preShiftX = _frames * m_data[m_type].speed * rcos( m_heading );
s32 preShiftY = _frames * m_data[m_type].speed * rsin( m_heading );
@ -818,7 +832,7 @@ void CNpc::processMovement(int _frames)
case NPC_MOVEMENT_USER_SEEK:
{
CPlayer *player;
player = GameScene.getPlayer();
break;
@ -913,6 +927,11 @@ void CNpc::processClose(int _frames)
break;
case NPC_CLOSE_EYEBALL_ATTACK:
processCloseEyeballAttack( _frames );
break;
default:
break;
}
@ -959,27 +978,48 @@ void CNpc::render()
void CNpc::processEvent( GAME_EVENT evt, CThing *sourceThing )
{
if ( m_data[this->m_type].canTalk )
switch( evt )
{
DVECTOR sourcePos;
s32 xDiffSqr, yDiffSqr;
// check talk distance
sourcePos = sourceThing->getPos();
xDiffSqr = this->Pos.vx - sourcePos.vx;
xDiffSqr *= xDiffSqr;
yDiffSqr = this->Pos.vy - sourcePos.vy;
yDiffSqr *= yDiffSqr;
if ( xDiffSqr + yDiffSqr < 250 )
case USER_REQUEST_TALK_EVENT:
{
if( !CConversation::isActive() )
if ( m_data[this->m_type].canTalk )
{
CConversation::trigger( SCRIPTS_SPEECHTEST_DAT );
DVECTOR sourcePos;
s32 xDiffSqr, yDiffSqr;
// check talk distance
sourcePos = sourceThing->getPos();
xDiffSqr = this->Pos.vx - sourcePos.vx;
xDiffSqr *= xDiffSqr;
yDiffSqr = this->Pos.vy - sourcePos.vy;
yDiffSqr *= yDiffSqr;
if ( xDiffSqr + yDiffSqr < 250 )
{
if( !CConversation::isActive() )
{
CConversation::trigger( SCRIPTS_SPEECHTEST_DAT );
}
}
}
break;
}
case PROJECTILE_RETURNED_TO_SOURCE_EVENT:
{
m_controlFunc = NPC_CONTROL_MOVEMENT;
m_timerFunc = NPC_TIMER_ATTACK_DONE;
m_timerTimer = GameState::getOneSecondInFrames();
m_sensorFunc = NPC_SENSOR_NONE;
removeChild( sourceThing );
delete sourceThing;
break;
}
}
}
}

View File

@ -27,16 +27,6 @@
class CNpc : public CThing
{
public:
void init();
void shutdown();
void think(int _frames);
virtual void render();
void processEvent( GAME_EVENT evt, CThing *sourceThing );
protected:
// NPC data structure definitions //
enum NPC_UNIT_TYPE
{
NPC_TEST_TYPE = 0,
@ -70,6 +60,16 @@ protected:
NPC_UNIT_TYPE_MAX,
};
void init();
void shutdown();
void think(int _frames);
virtual void render();
void processEvent( GAME_EVENT evt, CThing *sourceThing );
protected:
// NPC data structure definitions //
enum NPC_INIT_FUNC
{
NPC_INIT_DEFAULT = 0,
@ -97,6 +97,7 @@ protected:
NPC_SENSOR_SHARK_MAN_USER_VISIBLE,
NPC_SENSOR_OIL_BLOB_USER_CLOSE,
NPC_SENSOR_ANEMONE_USER_CLOSE,
NPC_SENSOR_EYEBALL_USER_CLOSE,
};
enum NPC_CLOSE_FUNC
@ -110,6 +111,7 @@ protected:
NPC_CLOSE_GENERIC_USER_SEEK,
NPC_CLOSE_ANEMONE_1_ATTACK,
NPC_CLOSE_ANEMONE_2_ATTACK,
NPC_CLOSE_EYEBALL_ATTACK,
};
enum NPC_MOVEMENT_FUNC
@ -197,6 +199,10 @@ protected:
void processCloseAnemone1Attack( int _frames );
void processCloseAnemone2Attack( int _frames );
// eyeball functions
void processCloseEyeballAttack( int _frames );
// data
static NPC_DATA m_data[NPC_UNIT_TYPE_MAX];
@ -210,9 +216,9 @@ protected:
CNpcPath m_npcPath;
s32 m_heading;
s32 m_fireHeading;
s32 m_movementTimer;
s32 m_velocity;
bool m_evadeClockwise;
s32 m_movementTimer;
s32 m_timerTimer;
s32 m_extension;
bool m_extendDir;

View File

@ -8,6 +8,7 @@
enum GAME_EVENT
{
USER_REQUEST_TALK_EVENT,
PROJECTILE_RETURNED_TO_SOURCE_EVENT,
};
#endif

View File

@ -75,10 +75,6 @@ void CGameScene::init()
enemy=new ("test enemy") C2dEnemy;
enemy->init();
CProjectile *testProjectile;
testProjectile = new( "test projectile" ) CProjectile;
testProjectile->init();
m_player=new ("player") CPlayer();
m_player->init();

View File

@ -39,6 +39,10 @@
#include "game\game.h"
#endif
#ifndef __PLAYER_PLAYER_H__
#include "player\player.h"
#endif
/*****************************************************************************/
@ -49,6 +53,10 @@ void CProjectile::init()
m_heading = 0;
m_lifetime = GameState::getOneSecondInFrames() * 2;
m_movementType = PROJECTILE_DUMBFIRE;
m_lifetimeType = PROJECTILE_FINITE_LIFE;
m_state = PROJECTILE_ATTACK;
m_turnSpeed = 256;
}
void CProjectile::init( DVECTOR initPos, s16 initHeading )
@ -59,22 +67,172 @@ void CProjectile::init( DVECTOR initPos, s16 initHeading )
Pos = initPos;
}
void CProjectile::init( DVECTOR initPos, s16 initHeading, PROJECTILE_MOVEMENT_TYPE initMoveType, PROJECTILE_LIFETIME_TYPE initLifeType )
{
init( initPos, initHeading );
m_movementType = initMoveType;
m_lifetimeType = initLifeType;
}
void CProjectile::shutdown()
{
m_spriteBank->dump(); delete m_spriteBank;
}
bool CProjectile::processTargetSeek( int _frames, DVECTOR targetPos )
{
s32 moveX = 0, moveY = 0;
s16 moveDist = 0;
s32 moveVel = 0;
s32 xDist, yDist;
s32 xDistSqr, yDistSqr;
xDist = targetPos.vx - this->Pos.vx;
xDistSqr = xDist * xDist;
yDist = targetPos.vy - this->Pos.vy;
yDistSqr = yDist * yDist;
//if ( xDistSqr + yDistSqr > 22500 )
//{
//this->m_controlFunc = NPC_CONTROL_MOVEMENT;
//}
//else
{
s16 headingToTarget = ratan2( yDist, xDist );
s16 maxTurnRate = m_turnSpeed;
s16 decDir, incDir;
decDir = m_heading - headingToTarget;
if ( decDir < 0 )
{
decDir += ONE;
}
incDir = headingToTarget - m_heading;
if ( incDir < 0 )
{
incDir += ONE;
}
if ( decDir < incDir )
{
moveDist = -decDir;
}
else
{
moveDist = incDir;
}
if ( moveDist < -maxTurnRate )
{
moveDist = -maxTurnRate;
}
else if ( moveDist > maxTurnRate )
{
moveDist = maxTurnRate;
}
m_heading += moveDist;
m_heading = m_heading % ONE;
s32 preShiftX = _frames * 3 * rcos( m_heading );
s32 preShiftY = _frames * 3 * rsin( m_heading );
moveX = preShiftX >> 12;
if ( !moveX && preShiftX )
{
moveX = preShiftX / abs( preShiftX );
}
moveY = preShiftY >> 12;
if ( !moveY && preShiftY )
{
moveY = preShiftY / abs( preShiftY );
}
Pos.vx += moveX;
Pos.vy += moveY;
}
xDist = targetPos.vx - this->Pos.vx;
xDistSqr = xDist * xDist;
yDist = targetPos.vy - this->Pos.vy;
yDistSqr = yDist * yDist;
if ( xDistSqr + yDistSqr < 100 )
{
return( true );
}
else
{
return( false );
}
}
void CProjectile::think(int _frames)
{
Pos.vx += ( _frames * 3 * rcos( m_heading ) ) >> 12;
Pos.vy += ( _frames * 3 * rsin( m_heading ) ) >> 12;
m_lifetime -= _frames;
if ( m_lifetime <= 0 )
switch( m_movementType )
{
shutdown();
delete this;
case PROJECTILE_USER_SEEK:
{
switch( m_state )
{
case PROJECTILE_RETURN:
{
if ( processTargetSeek( _frames, Parent->getPos() ) )
{
Parent->processEvent( PROJECTILE_RETURNED_TO_SOURCE_EVENT, this );
}
break;
}
case PROJECTILE_ATTACK:
default:
{
CPlayer *player = GameScene.getPlayer();
DVECTOR playerPos = player->getPos();
if ( processTargetSeek( _frames, playerPos ) )
{
m_state = PROJECTILE_RETURN;
}
break;
}
}
break;
}
case PROJECTILE_DUMBFIRE:
default:
{
Pos.vx += ( _frames * 3 * rcos( m_heading ) ) >> 12;
Pos.vy += ( _frames * 3 * rsin( m_heading ) ) >> 12;
break;
}
}
if ( m_lifetimeType == PROJECTILE_FINITE_LIFE )
{
m_lifetime -= _frames;
if ( m_lifetime <= 0 )
{
shutdown();
delete this;
}
}
}

View File

@ -22,8 +22,27 @@
class CProjectile : public CThing
{
public:
enum PROJECTILE_MOVEMENT_TYPE
{
PROJECTILE_DUMBFIRE = 0,
PROJECTILE_USER_SEEK = 1,
};
enum PROJECTILE_LIFETIME_TYPE
{
PROJECTILE_FINITE_LIFE = 0,
PROJECTILE_INFINITE_LIFE = 1,
};
enum PROJECTILE_STATE
{
PROJECTILE_ATTACK = 0,
PROJECTILE_RETURN = 1,
};
void init();
void init( DVECTOR initPos, s16 initHeading );
void init( DVECTOR initPos, s16 initHeading, PROJECTILE_MOVEMENT_TYPE initMoveType, PROJECTILE_LIFETIME_TYPE initLifeType );
void shutdown();
void think(int _frames);
virtual void render();
@ -31,10 +50,15 @@ public:
protected:
DVECTOR getScreenOffset();
bool processTargetSeek( int _frames, DVECTOR targetPos );
class SpriteBank *m_spriteBank;
s16 m_heading;
s32 m_lifetime;
class SpriteBank *m_spriteBank;
s16 m_heading;
s32 m_lifetime;
PROJECTILE_MOVEMENT_TYPE m_movementType;
PROJECTILE_LIFETIME_TYPE m_lifetimeType;
PROJECTILE_STATE m_state;
u16 m_turnSpeed;
};

View File

@ -133,6 +133,10 @@ SOURCE=..\..\..\source\enemy\nclam.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\source\enemy\neyeball.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\source\enemy\ngeneric.cpp
# End Source File
# Begin Source File