SBSPSS/source/player/player.cpp

2569 lines
64 KiB
C++
Raw Normal View History

2001-01-16 20:27:14 +01:00
/*=========================================================================
2001-01-09 21:38:20 +01:00
2001-01-16 20:27:14 +01:00
player.cpp
Author: PKG
2001-05-21 16:22:26 +02:00
Created:
2001-01-16 20:27:14 +01:00
Project: Spongebob
2001-05-21 16:22:26 +02:00
Purpose:
2001-01-16 20:27:14 +01:00
Copyright (c) 2001 Climax Development Ltd
===========================================================================*/
/*----------------------------------------------------------------------
Includes
-------- */
#include "player\player.h"
#ifndef __PAD_PADS_H__
2001-01-15 23:09:47 +01:00
#include "pad\pads.h"
2001-01-16 20:27:14 +01:00
#endif
2001-01-15 23:09:47 +01:00
2001-01-22 23:58:12 +01:00
#ifndef __GAME_GAMESLOT_H__
#include "game\gameslot.h"
#endif
2001-01-16 20:27:14 +01:00
2001-02-06 18:15:28 +01:00
#ifndef __LAYER_COLLISION_H__
2001-03-23 21:09:14 +01:00
#include "level\layercollision.h"
2001-02-06 18:15:28 +01:00
#endif
2001-03-05 21:43:32 +01:00
#ifndef __PLAYER_PMODES_H__
#include "player\pmodes.h"
#endif
2001-03-30 19:47:00 +02:00
#ifndef __PLAYER_PMBLOON_H__
#include "player\pmbloon.h"
#endif
#ifndef __PLAYER_PMBUBBLE_H__
#include "player\pmbubble.h"
#endif
2001-03-31 20:22:38 +02:00
#ifndef __PLAYER_PMNET_H__
#include "player\pmnet.h"
#endif
2001-03-25 23:33:20 +02:00
#ifndef __PLAYER_PMCHOP_H__
#include "player\pmchop.h"
2001-03-23 21:09:14 +01:00
#endif
2001-03-30 19:47:00 +02:00
#ifndef __PLAYER_PMCORAL_H__
#include "player\pmcoral.h"
2001-03-25 22:36:28 +02:00
#endif
2001-03-25 23:33:20 +02:00
#ifndef __PLAYER_PMDEAD_H__
#include "player\pmdead.h"
#endif
#ifndef __PLAYER_PMFLY_H__
#include "player\pmfly.h"
#endif
2001-04-03 23:36:35 +02:00
#ifndef __PLAYER_PMJELLY_H__
#include "player\pmjelly.h"
#endif
2001-06-12 18:28:39 +02:00
#ifndef __PLAYER_PMCART_H__
#include "player\pmcart.h"
#endif
2001-03-31 20:22:38 +02:00
#ifndef __GFX_FONT_H__
#include "gfx\font.h"
#endif
#ifndef __GFX_SPRBANK_H__
#include "gfx\sprbank.h"
#endif
2001-04-27 04:05:05 +02:00
#ifndef __PLATFORM_PLATFORM_H__
#include "platform\platform.h"
#endif
2001-05-04 21:34:09 +02:00
#ifndef __GAME_GAME_H__
#include "game\game.h"
#endif
2001-01-16 20:27:14 +01:00
2001-05-29 20:22:49 +02:00
#ifndef __PICKUPS_PICKUP_H__
#include "pickups\pickup.h"
#endif
2001-06-14 17:19:57 +02:00
#ifndef __MATHTABLE_HEADER__
#include "utils\mathtab.h"
#endif
2001-01-12 23:40:39 +01:00
2001-01-16 20:27:14 +01:00
/* Std Lib
------- */
2001-01-15 23:09:47 +01:00
2001-01-16 20:27:14 +01:00
/* Data
---- */
2001-04-20 16:53:35 +02:00
#ifndef __SPR_SPRITES_H__
#include <sprites.h>
2001-04-05 16:40:50 +02:00
#endif
2001-04-30 23:27:46 +02:00
#ifndef __ANIM_SPONGEBOB_HEADER__
#include <ACTOR_SPONGEBOB_Anim.h>
#endif
#ifndef __ANIM_SPONGEBOB_NET_HEADER__
#include <ACTOR_SPONGEBOB_NET_Anim.h>
#endif
#ifndef __ANIM_SPONGEBOB_CORALBLOWER_HEADER__
#include <ACTOR_SPONGEBOB_CORALBLOWER_Anim.h>
#endif
#ifndef __ANIM_SPONGEBOB_JELLYLAUNCHER_HEADER__
#include <ACTOR_SPONGEBOB_JELLYLAUNCHER_Anim.h>
#endif
2001-05-25 22:10:19 +02:00
#ifndef __ANIM_SPONGEBOB_WAND_HEADER__
#include <ACTOR_SPONGEBOB_WAND_Anim.h>
#endif
2001-04-30 23:27:46 +02:00
2001-05-10 16:35:35 +02:00
#ifndef __ANIM_SPONGEBOB_JELLYFISH_HEADER__
#include <ACTOR_SPONGEBOB_JELLYFISH_Anim.h>
#endif
2001-04-30 23:27:46 +02:00
2001-05-10 23:32:18 +02:00
#ifndef __ANIM_SPONGEBOB_GLOVE_HEADER__
#include <ACTOR_SPONGEBOB_GLOVE_Anim.h>
#endif
2001-05-22 17:11:52 +02:00
#include "fx\fx.h"
2001-01-16 20:27:14 +01:00
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
2001-02-09 18:01:04 +01:00
//#define _RECORD_DEMO_MODE_
2001-02-09 22:41:55 +01:00
#define _STATE_DEBUG_
2001-02-09 18:01:04 +01:00
2001-01-16 20:27:14 +01:00
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
2001-01-15 23:09:47 +01:00
2001-02-28 20:37:01 +01:00
// Two dice. One says 'Re' on every face, the other says 'boot',
// 'install', 'try', 'tire', 'sume' and 'number'
2001-01-16 20:27:14 +01:00
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
/*----------------------------------------------------------------------
Vars
---- */
2001-01-15 23:09:47 +01:00
2001-02-09 18:01:04 +01:00
#ifdef _RECORD_DEMO_MODE_
#include "player\demoplay.h"
#define MAX_DEMO_SIZE 512 // So max size of a demo is 1k
2001-02-12 16:26:00 +01:00
#define MAX_DEMO_TIME_IN_FRAMES 30*60 // Recorded demo will last 30 seconds
2001-02-09 18:01:04 +01:00
static CDemoPlayer::demoPlayerControl s_demoControls[MAX_DEMO_SIZE]={{PI_NONE,0}};
static int s_demoSize=0;
static int s_demoFrameCount=0;
static void writeDemoControls()
{
char filename[32];
int fh;
int fc=MAX_DEMO_TIME_IN_FRAMES;
sprintf(filename,"demo____.dmo");
fh=PCcreat((char *)filename,0);
ASSERT(fh!=-1);
PCwrite(fh,(char*)&fc,sizeof(fc)); // frame count
PCwrite(fh,(char*)&s_demoSize,sizeof(s_demoSize)); // demo size
for(int i=0;i<s_demoSize;i++)
PCwrite(fh,(char*)&s_demoControls[i],sizeof(CDemoPlayer::demoPlayerControl)); // control data
PCclose(fh);
SYSTEM_DBGMSG("Written demo file %s with %d frames",filename,s_demoSize);
}
#endif
2001-02-09 22:41:55 +01:00
#ifdef _STATE_DEBUG_
static const char *s_modeText[NUM_PLAYERMODES]=
{
"BASICUNARMED",
2001-03-25 23:33:20 +02:00
"FULLUNARMED",
2001-03-25 22:36:28 +02:00
"BALLOON",
2001-03-30 19:47:00 +02:00
"BUBBLE MIXTURE",
2001-03-31 20:22:38 +02:00
"NET",
2001-03-30 19:47:00 +02:00
"CORALBLOWER",
2001-04-03 23:36:35 +02:00
"JELLY LAUNCHER",
2001-03-30 19:47:00 +02:00
"DEAD",
2001-03-23 21:09:14 +01:00
"FLY",
2001-06-12 18:28:39 +02:00
"CART",
2001-02-09 22:41:55 +01:00
};
#endif
2001-02-09 18:01:04 +01:00
2001-04-17 22:45:02 +02:00
int s_screenPos;
int m_cameraLookOffset;
2001-02-08 17:51:16 +01:00
int MAP2D_CENTRE_X=-256;
2001-04-13 00:14:49 +02:00
int MAP2D_CENTRE_Y=-170;
2001-02-08 17:51:16 +01:00
int MAP2D_BLOCKSTEPSIZE=16;
2001-03-30 19:47:00 +02:00
CPlayerModeBase PLAYERMODE;
CPlayerModeChop PLAYERMODECHOP;
CPlayerModeBalloon PLAYERMODEBALLOON;
CPlayerModeBubbleMixture PLAYERMODEBUBBLEMIXTURE;
2001-03-31 20:22:38 +02:00
CPlayerModeNet PLAYERMODENET;
2001-03-30 19:47:00 +02:00
CPlayerModeCoralBlower PLAYERMODECORALBLOWER;
2001-04-03 23:36:35 +02:00
CPlayerModeJellyLauncher PLAYERMODEJELLYLAUNCHER;
2001-03-30 19:47:00 +02:00
CPlayerModeDead PLAYERMODEDEAD;
CPlayerModeFly PLAYERMODEFLY;
2001-06-12 18:28:39 +02:00
CPlayerModeCart PLAYERMODECART;
2001-03-23 21:09:14 +01:00
CPlayerMode *CPlayer::s_playerModes[NUM_PLAYERMODES]=
{
2001-03-25 22:36:28 +02:00
&PLAYERMODE, // PLAYER_MODE_BASICUNARMED
2001-03-25 23:33:20 +02:00
&PLAYERMODECHOP, // PLAYER_MODE_FULLUNARMED
2001-03-25 22:36:28 +02:00
&PLAYERMODEBALLOON, // PLAYER_MODE_BALLOON
2001-03-30 19:47:00 +02:00
&PLAYERMODEBUBBLEMIXTURE, // PLAYER_MODE_BUBBLE_MIXTURE
2001-03-31 20:22:38 +02:00
&PLAYERMODENET, // PLAYER_MODE_NET
2001-03-30 19:47:00 +02:00
&PLAYERMODECORALBLOWER, // PLAYER_MODE_CORALBLOWER
2001-04-03 23:36:35 +02:00
&PLAYERMODEJELLYLAUNCHER, // PLAYER_MODE_JELLY_LAUNCHER
2001-03-25 23:33:20 +02:00
&PLAYERMODEDEAD, // PLAYER_MODE_DEAD
2001-03-25 22:36:28 +02:00
&PLAYERMODEFLY, // PLAYER_MODE_FLY
2001-06-12 18:28:39 +02:00
&PLAYERMODECART, // PLAYER_MODE_CART
2001-03-23 21:09:14 +01:00
};
2001-02-09 18:01:04 +01:00
2001-04-18 18:35:26 +02:00
// A big bunch of 'temporary' variables for tweaking things
// This #def makes them static under a release build..
2001-04-18 18:54:22 +02:00
#ifdef __VERSION_DEBUG__
2001-04-18 18:35:26 +02:00
#define pint int
#else
#define pint static const int
#endif
pint sbanimspeed=0;
pint looktimeout=20;
pint lookmaxoffsetup=3*MAP2D_BLOCKSTEPSIZE;
pint lookmaxoffsetdown=6*MAP2D_BLOCKSTEPSIZE;
pint lookspeed=2;
pint lookreturnspeed=5;
pint ledgeTimer=50;
pint ledgeSpeedIn=1;
pint ledgeSpeedOut=3;
pint ledgeShift=1;
pint cammove=2;
2001-04-02 17:48:02 +02:00
2001-05-04 01:45:28 +02:00
pint waterDrainSpeed=4;
2001-05-10 23:32:18 +02:00
pint waterSoakUpSpeed=40;
2001-05-04 01:45:28 +02:00
2001-02-06 22:09:45 +01:00
2001-04-30 23:27:46 +02:00
// --------------------------------- Addon stuff ---------------------------------
CActorGfx *s_addonActorGfx[NUM_PLAYER_ADDONS]=
{
NULL, // PLAYER_ADDON_NET
NULL, // PLAYER_ADDON_CORALBLOWER
NULL, // PLAYER_ADDON_JELLYLAUNCHER
NULL, // PLAYER_ADDON_BUBBLEWAND
2001-05-10 16:35:35 +02:00
NULL, // PLAYER_ADDON_JELLYFISHINNET
2001-05-10 23:32:18 +02:00
NULL, // PLAYER_ADDON_GLOVE
2001-04-30 23:27:46 +02:00
};
FileEquate s_addonActorPoolNames[NUM_PLAYER_ADDONS]=
{
ACTORS_SPONGEBOB_NET_SBK, // PLAYER_ADDON_NET
ACTORS_SPONGEBOB_CORALBLOWER_SBK, // PLAYER_ADDON_CORALBLOWER
ACTORS_SPONGEBOB_JELLYLAUNCHER_SBK, // PLAYER_ADDON_JELLYLAUNCHER
2001-05-25 22:10:19 +02:00
ACTORS_SPONGEBOB_WAND_SBK, // PLAYER_ADDON_BUBBLEWAND
2001-05-10 16:35:35 +02:00
ACTORS_SPONGEBOB_JELLYFISH_SBK, // PLAYER_ADDON_JELLYFISHINNET
2001-05-10 23:32:18 +02:00
ACTORS_SPONGEBOB_GLOVE_SBK, // PLAYER_ADDON_GLOVE
2001-04-30 23:27:46 +02:00
};
PLAYER_ADDONS s_addonNumbers[NUM_PLAYERMODES]=
{
NO_ADDON, // PLAYER_MODE_BASICUNARMED
NO_ADDON, // PLAYER_MODE_FULLUNARMED
NO_ADDON, // PLAYER_MODE_BALLOON
PLAYER_ADDON_BUBBLEWAND, // PLAYER_MODE_BUBBLE_MIXTURE
PLAYER_ADDON_NET, // PLAYER_MODE_NET
PLAYER_ADDON_CORALBLOWER, // PLAYER_MODE_CORALBLOWER
PLAYER_ADDON_JELLYLAUNCHER, // PLAYER_MODE_JELLY_LAUNCHER
NO_ADDON, // PLAYER_MODE_DEAD
NO_ADDON, // PLAYER_MODE_FLY
2001-06-12 18:28:39 +02:00
NO_ADDON, // PLAYER_MODE_CART
2001-04-30 23:27:46 +02:00
};
static s8 s_animMapNet[NUM_PLAYER_ADDONS][NUM_ANIM_SPONGEBOB]=
{
// PLAYER_ADDON_NET,
{
ANIM_SPONGEBOB_NET_BUTTBOUNCEEND, // ANIM_SPONGEBOB_BUTTBOUNCEEND,
ANIM_SPONGEBOB_NET_BUTTBOUNCESTART, // ANIM_SPONGEBOB_BUTTBOUNCESTART,
ANIM_SPONGEBOB_NET_FALL, // ANIM_SPONGEBOB_FALL,
ANIM_SPONGEBOB_NET_GETUP, // ANIM_SPONGEBOB_GETUP,
ANIM_SPONGEBOB_NET_HITGROUND, // ANIM_SPONGEBOB_HITGROUND,
ANIM_SPONGEBOB_NET_IDLEBREATH, // ANIM_SPONGEBOB_IDLEBREATH,
ANIM_SPONGEBOB_NET_JUMPEND, // ANIM_SPONGEBOB_JUMPEND,
ANIM_SPONGEBOB_NET_JUMP, // ANIM_SPONGEBOB_JUMP,
ANIM_SPONGEBOB_NET_RUN, // ANIM_SPONGEBOB_RUN,
ANIM_SPONGEBOB_NET_RUNSTOP, // ANIM_SPONGEBOB_RUNSTOP,
ANIM_SPONGEBOB_NET_RUNSTART, // ANIM_SPONGEBOB_RUNSTART,
ANIM_SPONGEBOB_NET_SOAKUP, // ANIM_SPONGEBOB_SOAKUP,
ANIM_SPONGEBOB_NET_TEETERBACK, // ANIM_SPONGEBOB_TEETERBACK,
ANIM_SPONGEBOB_NET_TEETERFRONT, // ANIM_SPONGEBOB_TEETERFRONT,
ANIM_SPONGEBOB_NET_SWIPE, // ANIM_SPONGEBOB_SWIPE,
2001-05-17 20:42:59 +02:00
ANIM_SPONGEBOB_NET_DEATHFORWARDS, // ANIM_SPONGEBOB_DEATHFORWARDS,
ANIM_SPONGEBOB_NET_DEATHSQUASH, // ANIM_SPONGEBOB_DEATHSQUASH,
2001-04-30 23:27:46 +02:00
ANIM_SPONGEBOB_NET_DEATHSPIN, // ANIM_SPONGEBOB_DEATHSPIN,
2001-05-17 20:42:59 +02:00
-1, // ANIM_SPONGEBOB_DEATHDRY
2001-04-30 23:27:46 +02:00
-1, // ANIM_SPONGEBOB_BALLOONJUMP,
-1, // ANIM_SPONGEBOB_BLOWBUBBLE,
-1, // ANIM_SPONGEBOB_FIREEND,
-1, // ANIM_SPONGEBOB_FIRESTART,
-1, // ANIM_SPONGEBOB_IDLEWEAPON,
-1, // ANIM_SPONGEBOB_WALK,
-1, // ANIM_SPONGEBOB_KARATE,
2001-05-11 21:49:41 +02:00
ANIM_SPONGEBOB_NET_GETHIT, // ANIM_SPONGEBOB_GETHIT
2001-05-14 18:43:48 +02:00
ANIM_SPONGEBOB_NET_CROUCHDOWN, // ANIM_SPONGEBOB_CROUCHDOWN
2001-05-15 21:31:26 +02:00
ANIM_SPONGEBOB_NET_CROUCHUP, // ANIM_SPONGEBOB_CROUCHUP
2001-06-11 21:46:09 +02:00
-1, // ANIM_SPONGEBOB_LOOKUP
-1, // ANIM_SPONGEBOB_IDLEBIGEYE
-1, // ANIM_SPONGEBOB_IDLEFACEUPSIDEDOWN
2001-04-30 23:27:46 +02:00
},
// PLAYER_ADDON_CORALBLOWER,
{
-1, // ANIM_SPONGEBOB_BUTTBOUNCEEND,
-1, // ANIM_SPONGEBOB_BUTTBOUNCESTART,
ANIM_SPONGEBOB_CORALBLOWER_FALL, // ANIM_SPONGEBOB_FALL,
ANIM_SPONGEBOB_CORALBLOWER_GETUP, // ANIM_SPONGEBOB_GETUP,
ANIM_SPONGEBOB_CORALBLOWER_HITGROUND, // ANIM_SPONGEBOB_HITGROUND,
ANIM_SPONGEBOB_CORALBLOWER_IDLEBREATH, // ANIM_SPONGEBOB_IDLEBREATH,
ANIM_SPONGEBOB_CORALBLOWER_JUMPEND, // ANIM_SPONGEBOB_JUMPEND,
ANIM_SPONGEBOB_CORALBLOWER_JUMP, // ANIM_SPONGEBOB_JUMP,
-1, // ANIM_SPONGEBOB_RUN,
-1, // ANIM_SPONGEBOB_RUNSTOP,
-1, // ANIM_SPONGEBOB_RUNSTART,
2001-05-10 16:35:35 +02:00
-1, // ANIM_SPONGEBOB_SOAKUP,
2001-04-30 23:27:46 +02:00
ANIM_SPONGEBOB_CORALBLOWER_TEETERBACK, // ANIM_SPONGEBOB_TEETERBACK,
ANIM_SPONGEBOB_CORALBLOWER_TEETERFRONT, // ANIM_SPONGEBOB_TEETERFRONT,
-1, // ANIM_SPONGEBOB_SWIPE,
2001-05-17 20:42:59 +02:00
ANIM_SPONGEBOB_CORALBLOWER_DEATHFORWARDS, // ANIM_SPONGEBOB_DEATHFORWARDS,
ANIM_SPONGEBOB_CORALBLOWER_DEATHSQUASH, // ANIM_SPONGEBOB_DEATHSQUASH,
2001-04-30 23:27:46 +02:00
ANIM_SPONGEBOB_CORALBLOWER_DEATHSPIN, // ANIM_SPONGEBOB_DEATHSPIN,
2001-05-17 20:42:59 +02:00
-1, // ANIM_SPONGEBOB_DEATHDRY
2001-04-30 23:27:46 +02:00
-1, // ANIM_SPONGEBOB_BALLOONJUMP,
-1, // ANIM_SPONGEBOB_BLOWBUBBLE,
ANIM_SPONGEBOB_CORALBLOWER_FIREEND, // ANIM_SPONGEBOB_FIREEND,
ANIM_SPONGEBOB_CORALBLOWER_FIRESTART, // ANIM_SPONGEBOB_FIRESTART,
2001-05-10 16:35:35 +02:00
ANIM_SPONGEBOB_CORALBLOWER_IDLEWEAPON, // ANIM_SPONGEBOB_IDLEWEAPON,
2001-04-30 23:27:46 +02:00
ANIM_SPONGEBOB_CORALBLOWER_WALK, // ANIM_SPONGEBOB_WALK,
-1, // ANIM_SPONGEBOB_KARATE,
2001-05-11 21:49:41 +02:00
ANIM_SPONGEBOB_CORALBLOWER_GETHIT, // ANIM_SPONGEBOB_GETHIT
2001-05-14 18:43:48 +02:00
ANIM_SPONGEBOB_CORALBLOWER_CROUCHDOWN, // ANIM_SPONGEBOB_CROUCHDOWN
ANIM_SPONGEBOB_CORALBLOWER_CROUCHUP, // ANIM_SPONGEBOB_CROUCHUP
2001-06-11 21:46:09 +02:00
-1, // ANIM_SPONGEBOB_LOOKUP
-1, // ANIM_SPONGEBOB_IDLEBIGEYE
-1, // ANIM_SPONGEBOB_IDLEFACEUPSIDEDOWN
2001-04-30 23:27:46 +02:00
},
// PLAYER_ADDON_JELLYLAUNCHER,
{
ANIM_SPONGEBOB_JELLYLAUNCHER_BUTTBOUNCEEND, // ANIM_SPONGEBOB_BUTTBOUNCEEND,
ANIM_SPONGEBOB_JELLYLAUNCHER_BUTTBOUNCESTART, // ANIM_SPONGEBOB_BUTTBOUNCESTART,
ANIM_SPONGEBOB_JELLYLAUNCHER_FALL, // ANIM_SPONGEBOB_FALL,
ANIM_SPONGEBOB_JELLYLAUNCHER_GETUP, // ANIM_SPONGEBOB_GETUP,
ANIM_SPONGEBOB_JELLYLAUNCHER_HITGROUND, // ANIM_SPONGEBOB_HITGROUND,
ANIM_SPONGEBOB_JELLYLAUNCHER_IDLEBREATH, // ANIM_SPONGEBOB_IDLEBREATH,
ANIM_SPONGEBOB_JELLYLAUNCHER_JUMPEND, // ANIM_SPONGEBOB_JUMPEND,
ANIM_SPONGEBOB_JELLYLAUNCHER_JUMP, // ANIM_SPONGEBOB_JUMP,
ANIM_SPONGEBOB_JELLYLAUNCHER_RUN, // ANIM_SPONGEBOB_RUN,
ANIM_SPONGEBOB_JELLYLAUNCHER_RUNSTOP, // ANIM_SPONGEBOB_RUNSTOP,
ANIM_SPONGEBOB_JELLYLAUNCHER_RUNSTART, // ANIM_SPONGEBOB_RUNSTART,
ANIM_SPONGEBOB_JELLYLAUNCHER_SOAKUP, // ANIM_SPONGEBOB_SOAKUP,
ANIM_SPONGEBOB_JELLYLAUNCHER_TEETERBACK, // ANIM_SPONGEBOB_TEETERBACK,
ANIM_SPONGEBOB_JELLYLAUNCHER_TEETERFRONT, // ANIM_SPONGEBOB_TEETERFRONT,
-1, // ANIM_SPONGEBOB_SWIPE,
2001-05-17 20:42:59 +02:00
ANIM_SPONGEBOB_JELLYLAUNCHER_DEATHFORWARDS, // ANIM_SPONGEBOB_DEATHFORWARDS,
ANIM_SPONGEBOB_JELLYLAUNCHER_DEATHSQUASH, // ANIM_SPONGEBOB_DEATHSQUASH,
2001-04-30 23:27:46 +02:00
ANIM_SPONGEBOB_JELLYLAUNCHER_DEATHSPIN, // ANIM_SPONGEBOB_DEATHSPIN,
2001-05-17 20:42:59 +02:00
-1, // ANIM_SPONGEBOB_DEATHDRY
2001-04-30 23:27:46 +02:00
-1, // ANIM_SPONGEBOB_BALLOONJUMP,
-1, // ANIM_SPONGEBOB_BLOWBUBBLE,
ANIM_SPONGEBOB_JELLYLAUNCHER_FIREEND, // ANIM_SPONGEBOB_FIREEND,
ANIM_SPONGEBOB_JELLYLAUNCHER_FIRESTART, // ANIM_SPONGEBOB_FIRESTART,
-1, // ANIM_SPONGEBOB_IDLEWEAPON,
-1, // ANIM_SPONGEBOB_WALK,
-1, // ANIM_SPONGEBOB_KARATE,
2001-05-11 21:49:41 +02:00
ANIM_SPONGEBOB_JELLYLAUNCHER_GETHIT, // ANIM_SPONGEBOB_GETHIT
2001-05-14 18:43:48 +02:00
ANIM_SPONGEBOB_JELLYLAUNCHER_CROUCHDOWN, // ANIM_SPONGEBOB_CROUCHDOWN
ANIM_SPONGEBOB_JELLYLAUNCHER_CROUCHUP, // ANIM_SPONGEBOB_CROUCHUP
2001-06-11 21:46:09 +02:00
-1, // ANIM_SPONGEBOB_LOOKUP
-1, // ANIM_SPONGEBOB_IDLEBIGEYE
-1, // ANIM_SPONGEBOB_IDLEFACEUPSIDEDOWN
2001-04-30 23:27:46 +02:00
},
// PLAYER_ADDON_BUBBLEWAND,
{
2001-05-25 22:10:19 +02:00
ANIM_SPONGEBOB_WAND_BUTTBOUNCEEND, // ANIM_SPONGEBOB_BUTTBOUNCEEND,
ANIM_SPONGEBOB_WAND_BUTTBOUNCESTART, // ANIM_SPONGEBOB_BUTTBOUNCESTART,
ANIM_SPONGEBOB_WAND_FALL, // ANIM_SPONGEBOB_FALL,
ANIM_SPONGEBOB_WAND_GETUP, // ANIM_SPONGEBOB_GETUP,
ANIM_SPONGEBOB_WAND_HITGROUND, // ANIM_SPONGEBOB_HITGROUND,
ANIM_SPONGEBOB_WAND_IDLEBREATH, // ANIM_SPONGEBOB_IDLEBREATH,
ANIM_SPONGEBOB_WAND_JUMPEND, // ANIM_SPONGEBOB_JUMPEND,
ANIM_SPONGEBOB_WAND_JUMP, // ANIM_SPONGEBOB_JUMP,
ANIM_SPONGEBOB_WAND_RUN, // ANIM_SPONGEBOB_RUN,
ANIM_SPONGEBOB_WAND_RUNSTOP, // ANIM_SPONGEBOB_RUNSTOP,
ANIM_SPONGEBOB_WAND_RUNSTART, // ANIM_SPONGEBOB_RUNSTART,
-1, // ANIM_SPONGEBOB_SOAKUP,
ANIM_SPONGEBOB_WAND_TEETERBACK, // ANIM_SPONGEBOB_TEETERBACK,
ANIM_SPONGEBOB_WAND_TEETERFRONT, // ANIM_SPONGEBOB_TEETERFRONT,
-1, // ANIM_SPONGEBOB_SWIPE,
ANIM_SPONGEBOB_WAND_DEATHFORWARDS, // ANIM_SPONGEBOB_DEATHFORWARDS,
ANIM_SPONGEBOB_WAND_DEATHSQUASH, // ANIM_SPONGEBOB_DEATHSQUASH,
ANIM_SPONGEBOB_WAND_DEATHSPIN, // ANIM_SPONGEBOB_DEATHSPIN,
2001-05-17 20:42:59 +02:00
-1, // ANIM_SPONGEBOB_DEATHDRY
2001-05-25 22:10:19 +02:00
-1, // ANIM_SPONGEBOB_BALLOONJUMP,
ANIM_SPONGEBOB_WAND_BLOWBUBBLE, // ANIM_SPONGEBOB_BLOWBUBBLE,
-1, // ANIM_SPONGEBOB_FIREEND,
-1, // ANIM_SPONGEBOB_FIRESTART,
-1, // ANIM_SPONGEBOB_IDLEWEAPON,
-1, // ANIM_SPONGEBOB_WALK,
-1, // ANIM_SPONGEBOB_KARATE,
ANIM_SPONGEBOB_WAND_GETHIT, // ANIM_SPONGEBOB_GETHIT
ANIM_SPONGEBOB_WAND_CROUCHDOWN, // ANIM_SPONGEBOB_CROUCHDOWN
ANIM_SPONGEBOB_WAND_CROUCHUP, // ANIM_SPONGEBOB_CROUCHUP
2001-06-11 21:46:09 +02:00
-1, // ANIM_SPONGEBOB_LOOKUP
-1, // ANIM_SPONGEBOB_IDLEBIGEYE
-1, // ANIM_SPONGEBOB_IDLEFACEUPSIDEDOWN
2001-04-30 23:27:46 +02:00
},
2001-05-10 16:35:35 +02:00
// PLAYER_ADDON_JELLYFISHINNET
{
ANIM_SPONGEBOB_JELLYFISH_BUTTBOUNCEEND, // ANIM_SPONGEBOB_BUTTBOUNCEEND,
ANIM_SPONGEBOB_JELLYFISH_BUTTBOUNCESTART, // ANIM_SPONGEBOB_BUTTBOUNCESTART,
ANIM_SPONGEBOB_JELLYFISH_FALL, // ANIM_SPONGEBOB_FALL,
ANIM_SPONGEBOB_JELLYFISH_GETUP, // ANIM_SPONGEBOB_GETUP,
ANIM_SPONGEBOB_JELLYFISH_HITGROUND, // ANIM_SPONGEBOB_HITGROUND,
ANIM_SPONGEBOB_JELLYFISH_IDLEBREATH, // ANIM_SPONGEBOB_IDLEBREATH,
ANIM_SPONGEBOB_JELLYFISH_JUMPEND, // ANIM_SPONGEBOB_JUMPEND,
ANIM_SPONGEBOB_JELLYFISH_JUMP, // ANIM_SPONGEBOB_JUMP,
ANIM_SPONGEBOB_JELLYFISH_RUN, // ANIM_SPONGEBOB_RUN,
ANIM_SPONGEBOB_JELLYFISH_RUNSTOP, // ANIM_SPONGEBOB_RUNSTOP,
ANIM_SPONGEBOB_JELLYFISH_RUNSTART, // ANIM_SPONGEBOB_RUNSTART,
ANIM_SPONGEBOB_JELLYFISH_SOAKUP, // ANIM_SPONGEBOB_SOAKUP,
ANIM_SPONGEBOB_JELLYFISH_TEETERBACK, // ANIM_SPONGEBOB_TEETERBACK,
ANIM_SPONGEBOB_JELLYFISH_TEETERFRONT, // ANIM_SPONGEBOB_TEETERFRONT,
2001-05-15 21:31:26 +02:00
ANIM_SPONGEBOB_JELLYFISH_SWIPE, // ANIM_SPONGEBOB_SWIPE,
2001-05-17 20:42:59 +02:00
ANIM_SPONGEBOB_JELLYFISH_DEATHFORWARDS, // ANIM_SPONGEBOB_DEATHFORWARDS,
ANIM_SPONGEBOB_JELLYFISH_DEATHSQUASH, // ANIM_SPONGEBOB_DEATHSQUASH,
2001-05-10 16:35:35 +02:00
ANIM_SPONGEBOB_JELLYFISH_DEATHSPIN, // ANIM_SPONGEBOB_DEATHSPIN,
2001-05-17 20:42:59 +02:00
-1, // ANIM_SPONGEBOB_DEATHDRY
2001-05-10 16:35:35 +02:00
-1, // ANIM_SPONGEBOB_BALLOONJUMP,
-1, // ANIM_SPONGEBOB_BLOWBUBBLE,
-1, // ANIM_SPONGEBOB_FIREEND,
-1, // ANIM_SPONGEBOB_FIRESTART,
-1, // ANIM_SPONGEBOB_IDLEWEAPON,
-1, // ANIM_SPONGEBOB_WALK,
-1, // ANIM_SPONGEBOB_KARATE,
2001-05-11 21:49:41 +02:00
ANIM_SPONGEBOB_JELLYFISH_GETHIT, // ANIM_SPONGEBOB_GETHIT
2001-05-14 18:43:48 +02:00
ANIM_SPONGEBOB_JELLYFISH_CROUCHDOWN, // ANIM_SPONGEBOB_CROUCHDOWN
ANIM_SPONGEBOB_JELLYFISH_CROUCHUP, // ANIM_SPONGEBOB_CROUCHUP
2001-06-11 21:46:09 +02:00
-1, // ANIM_SPONGEBOB_LOOKUP
-1, // ANIM_SPONGEBOB_IDLEBIGEYE
-1, // ANIM_SPONGEBOB_IDLEFACEUPSIDEDOWN
2001-05-10 16:35:35 +02:00
},
2001-05-10 23:32:18 +02:00
// PLAYER_ADDON_GLOVE
{
-1, // ANIM_SPONGEBOB_BUTTBOUNCEEND,
-1, // ANIM_SPONGEBOB_BUTTBOUNCESTART,
-1, // ANIM_SPONGEBOB_FALL,
-1, // ANIM_SPONGEBOB_GETUP,
-1, // ANIM_SPONGEBOB_HITGROUND,
-1, // ANIM_SPONGEBOB_IDLEBREATH,
-1, // ANIM_SPONGEBOB_JUMPEND,
-1, // ANIM_SPONGEBOB_JUMP,
-1, // ANIM_SPONGEBOB_RUN,
-1, // ANIM_SPONGEBOB_RUNSTOP,
-1, // ANIM_SPONGEBOB_RUNSTART,
-1, // ANIM_SPONGEBOB_SOAKUP,
-1, // ANIM_SPONGEBOB_TEETERBACK,
-1, // ANIM_SPONGEBOB_TEETERFRONT,
-1, // ANIM_SPONGEBOB_SWIPE,
2001-05-17 20:42:59 +02:00
-1, // ANIM_SPONGEBOB_DEATHFORWARDS,
-1, // ANIM_SPONGEBOB_DEATHSQUASH,
2001-05-10 23:32:18 +02:00
-1, // ANIM_SPONGEBOB_DEATHSPIN,
2001-05-17 20:42:59 +02:00
-1, // ANIM_SPONGEBOB_DEATHDRY
2001-05-10 23:32:18 +02:00
-1, // ANIM_SPONGEBOB_BALLOONJUMP,
-1, // ANIM_SPONGEBOB_BLOWBUBBLE,
-1, // ANIM_SPONGEBOB_FIREEND,
-1, // ANIM_SPONGEBOB_FIRESTART,
-1, // ANIM_SPONGEBOB_IDLEWEAPON,
-1, // ANIM_SPONGEBOB_WALK,
ANIM_SPONGEBOB_GLOVE_KARATE, // ANIM_SPONGEBOB_KARATE,
2001-05-11 21:49:41 +02:00
-1, // ANIM_SPONGEBOB_GETHIT
2001-05-14 18:43:48 +02:00
-1, // ANIM_SPONGEBOB_CROUCHDOWN
-1, // ANIM_SPONGEBOB_CROUCHUP
2001-06-11 21:46:09 +02:00
-1, // ANIM_SPONGEBOB_LOOKUP
-1, // ANIM_SPONGEBOB_IDLEBIGEYE
-1, // ANIM_SPONGEBOB_IDLEFACEUPSIDEDOWN
2001-05-10 23:32:18 +02:00
},
2001-04-30 23:27:46 +02:00
};
// -------------------------------------------------------------------------------
2001-05-13 21:28:48 +02:00
int m_cameraXScrollDir;
int m_cameraXScrollPos;
int CAMERA_SCROLLLIMIT=8; // SB is this many tiles off centre at most
2001-05-14 17:15:20 +02:00
int CAMERA_SCROLLTHRESHOLD=6; // If SB moves when more than this many tiles off-centre, the camera will *always* scroll
int CAMERA_STARTMOVETHRESHOLD=90; // If SB moves faster than this then the camera starts scrolling
2001-05-13 21:28:48 +02:00
int CAMERA_STOPMOVETHRESHOLD=10; // If SB moves slower than this then the camera stops scrolling
int CAMERA_SCROLLSPEED=1000; // Speed of the scroll
int CAMERA_ACCURACYSHIFT=8;
const int CAMERA_TILESIZE=16;
2001-05-24 22:00:19 +02:00
int m_isFalling;
int m_fallFrames;
int m_cameraFallYScrollPos;
int m_cameraFallYScrollSpeed;
int CAMERA_FALL_DROP_SPEED=6;
int CAMERA_FALL_MAX_OFFSET=5*16;
int CAMERA_FALL_FRAME_THRESHOLD=20;
int CAMERA_FALL_RETURN_SPEED=1;
2001-05-18 18:33:05 +02:00
#ifdef CAM_X_AUTO_CENTERING
2001-05-16 16:41:50 +02:00
int returnspeed=1500;
2001-05-18 18:33:05 +02:00
int returntimeout=25;
int returntimeoutcount=0;
2001-05-16 16:41:50 +02:00
int returnsafespace=4*16;
2001-05-18 18:33:05 +02:00
#endif
2001-04-28 00:25:49 +02:00
2001-01-22 23:58:12 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-01-12 23:40:39 +01:00
void CPlayer::init()
2001-01-09 21:38:20 +01:00
{
2001-04-30 23:27:46 +02:00
int i;
2001-02-27 17:59:50 +01:00
CPlayerThing::init();
2001-02-06 18:15:28 +01:00
2001-03-31 20:22:38 +02:00
m_fontBank=new ("PlayerFont") FontBank();
m_fontBank->initialise(&standardFont);
2001-06-14 18:25:58 +02:00
m_fontBank->setOt(POWERUPUI_OT);
2001-03-31 20:22:38 +02:00
2001-03-06 21:13:16 +01:00
2001-04-01 22:22:49 +02:00
m_actorGfx=CActorPool::GetActor(ACTORS_SPONGEBOB_SBK);
2001-01-16 17:20:45 +01:00
2001-04-30 23:27:46 +02:00
for(i=0;i<NUM_PLAYERMODES;i++)
2001-03-23 21:09:14 +01:00
{
s_playerModes[i]->initialise(this);
}
2001-01-20 00:37:40 +01:00
m_animNo=0;
m_animFrame=0;
2001-01-16 20:27:14 +01:00
setFacing(FACING_RIGHT);
2001-05-15 18:48:29 +02:00
m_currentPlayerModeClass=NULL;
m_lastModeBeforeDeath=PLAYER_MODE_FULLUNARMED; // Player will then respawn into this mode
2001-05-11 23:35:08 +02:00
m_lives++;respawn();
2001-06-12 23:45:33 +02:00
m_canExitLevel=false;
2001-01-20 00:37:40 +01:00
2001-05-09 22:15:01 +02:00
m_lives=CGameSlotManager::getSlotData()->m_lives;
2001-01-22 23:58:12 +01:00
2001-02-09 18:01:04 +01:00
m_lastPadInput=m_padInput=PI_NONE;
2001-02-06 22:09:45 +01:00
2001-02-08 17:51:16 +01:00
s_screenPos=128;
2001-04-18 18:35:26 +02:00
resetPlayerCollisionSizeToBase();
2001-03-02 17:02:30 +01:00
2001-03-29 23:30:34 +02:00
m_divingHelmet=false;
2001-05-08 18:58:07 +02:00
setIsInWater(true);
2001-04-30 23:27:46 +02:00
2001-05-10 23:32:18 +02:00
// Always ( cept for one level ) need this
registerAddon(PLAYER_ADDON_GLOVE);
2001-05-16 18:47:29 +02:00
#ifdef __USER_paul__
registerAddon(PLAYER_ADDON_NET);
registerAddon(PLAYER_ADDON_CORALBLOWER);
registerAddon(PLAYER_ADDON_JELLYLAUNCHER);
registerAddon(PLAYER_ADDON_BUBBLEWAND);
registerAddon(PLAYER_ADDON_JELLYFISHINNET);
#endif
2001-01-09 21:38:20 +01:00
}
2001-01-16 20:27:14 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-01-12 23:40:39 +01:00
void CPlayer::shutdown()
2001-01-09 21:38:20 +01:00
{
2001-04-30 23:27:46 +02:00
int i;
for(i=0;i<NUM_PLAYERMODES;i++)
2001-03-27 22:01:22 +02:00
{
s_playerModes[i]->shutdown();
}
2001-04-30 23:27:46 +02:00
for(i=0;i<NUM_PLAYER_ADDONS;i++)
{
if(s_addonActorGfx[i])
{
delete s_addonActorGfx[i];
s_addonActorGfx[i]=NULL;
}
}
2001-04-10 01:28:27 +02:00
delete m_actorGfx;
2001-03-31 20:22:38 +02:00
m_fontBank->dump(); delete m_fontBank;
2001-02-27 17:59:50 +01:00
CPlayerThing::shutdown();
2001-01-09 21:38:20 +01:00
}
2001-01-16 20:27:14 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-04-25 21:18:28 +02:00
static int oldmode=-1;
2001-02-06 18:15:28 +01:00
int newmode=-1;
2001-03-02 19:00:19 +01:00
2001-06-01 20:59:33 +02:00
2001-01-15 23:09:47 +01:00
void CPlayer::think(int _frames)
{
2001-01-25 16:25:46 +01:00
int i;
2001-01-16 17:20:45 +01:00
2001-05-22 17:11:52 +02:00
#ifdef __USER_daveo__
if(PadGetDown(0)&PAD_R1)
{
2001-06-12 02:00:48 +02:00
TestFX(getPos(),this);
2001-05-22 17:11:52 +02:00
}
#endif
2001-01-29 23:35:18 +01:00
2001-05-18 18:35:11 +02:00
if(PadGetDown(0)&PAD_L1&&m_currentMode!=PLAYER_MODE_DEAD)
2001-04-25 21:18:28 +02:00
{
oldmode=m_currentMode;
newmode=PLAYER_MODE_FLY;
}
else if(oldmode!=-1&&!(PadGetHeld(0)&PAD_L1))
{
newmode=oldmode;
oldmode=-1;
}
2001-01-29 23:35:18 +01:00
if(newmode!=-1)
{
setMode((PLAYER_MODE)newmode);
newmode=-1;
}
2001-01-20 00:37:40 +01:00
2001-04-27 04:05:05 +02:00
CThing *platform;
platform=isOnPlatform();
if(platform)
2001-04-11 22:59:16 +02:00
{
2001-06-12 01:12:58 +02:00
if ( ( (CNpcPlatform *) platform )->isCart() )
2001-05-25 22:45:03 +02:00
{
2001-06-12 18:28:39 +02:00
if ( m_currentMode != PLAYER_MODE_CART )
{
setMode( PLAYER_MODE_CART );
}
2001-05-25 22:45:03 +02:00
}
2001-06-12 01:12:58 +02:00
else
{
DVECTOR posDelta;
posDelta=platform->getPosDelta();
posDelta.vy = 0;
shove(posDelta);
int platformOffset = ( ( CNpcPlatform* ) platform )->getHeightFromPlatformAtPosition( Pos.vx, Pos.vy );
int height=CGameScene::getCollision()->getHeightFromGround(Pos.vx,Pos.vy,16);
if ( platformOffset < height )
{
Pos.vy += platformOffset;
}
}
2001-04-11 22:59:16 +02:00
}
2001-04-27 04:05:05 +02:00
2001-05-02 00:05:23 +02:00
m_allowConversation=false;
2001-05-21 16:22:26 +02:00
2001-05-29 20:22:49 +02:00
m_tryingToManuallyPickupWeapon=false;
m_tryingToAutomaticallyPickupWeapon=false;
2001-06-08 17:02:29 +02:00
m_xMove = Pos.vx;
2001-06-10 18:51:21 +02:00
///
#ifdef __USER_paul__
2001-06-14 20:14:36 +02:00
/*
2001-06-10 18:51:21 +02:00
if(PadGetDown(0)&PAD_TRIANGLE)
{
2001-06-14 17:19:57 +02:00
DVECTOR spawnBasePos;
int angle,angleInc;
int i;
spawnBasePos=Pos;
spawnBasePos.vy-=50;
angle=-1024;
angleInc=512;
for(i=0;i<5;i++)
{
DVECTOR offset,spawnPos;
CBaseBouncingPickup *pickup;
angle&=4095;
offset.vx=((msin(angle)*25)>>12);
offset.vy=-((mcos(angle)*25)>>12);
spawnPos.vx=spawnBasePos.vx+offset.vx;
spawnPos.vy=spawnBasePos.vy+offset.vy;
pickup=(CBaseBouncingPickup*)createPickup(PICKUP__BOUNCING_SPATULA,&spawnPos);
angle+=angleInc;
}
2001-06-10 18:51:21 +02:00
}
2001-06-14 20:14:36 +02:00
*/
2001-06-10 18:51:21 +02:00
#endif
///
2001-01-25 16:25:46 +01:00
for(i=0;i<_frames;i++)
2001-01-15 23:09:47 +01:00
{
2001-01-29 23:35:18 +01:00
updatePadInput();
2001-05-29 20:22:49 +02:00
// Weapon collect/drop/swap stuff..
if(m_currentMode==PLAYER_MODE_BASICUNARMED||
m_currentMode==PLAYER_MODE_FULLUNARMED)
2001-05-18 23:03:51 +02:00
{
2001-05-29 20:22:49 +02:00
// Always trying to pickup weapon if unarmed... means that when SB walks
// over an item whilst unarmed, he automatically picks it up
m_tryingToAutomaticallyPickupWeapon=true;
}
if(getPadInputDown()&PI_WEAPONCHANGE)
{
// Trying to pick up a weapon
m_tryingToManuallyPickupWeapon=true;
// If already armed then drop current weapon
if(m_currentMode!=PLAYER_MODE_BASICUNARMED&&
m_currentMode!=PLAYER_MODE_FULLUNARMED&&
m_currentMode!=PLAYER_MODE_DEAD)
2001-05-29 18:12:06 +02:00
{
2001-05-29 20:22:49 +02:00
static const int s_pickupsToDrop[NUM_PLAYERMODES]=
{
-1, // PLAYER_MODE_BASICUNARMED,
-1, // PLAYER_MODE_FULLUNARMED,
-1, // PLAYER_MODE_BALLOON,
PICKUP__BUBBLE_WAND, // PLAYER_MODE_BUBBLE_MIXTURE,
PICKUP__NET, // PLAYER_MODE_NET,
PICKUP__CORAL_BLOWER, // PLAYER_MODE_CORALBLOWER,
PICKUP__JELLY_LAUNCHER, // PLAYER_MODE_JELLY_LAUNCHER,
-1, // PLAYER_MODE_DEAD,
-1, // PLAYER_MODE_FLY,
2001-06-12 18:28:39 +02:00
-1, // PLAYER_MODE_CART,
2001-05-29 20:22:49 +02:00
};
int pickupToDrop;
pickupToDrop=s_pickupsToDrop[m_currentMode];
if(pickupToDrop!=-1)
2001-05-29 18:12:06 +02:00
{
2001-05-29 20:22:49 +02:00
DVECTOR pickupPos;
CBasePickup *pickup;
pickupPos.vx=Pos.vx;
pickupPos.vy=Pos.vy-30;
pickup=createPickup((PICKUP_TYPE)pickupToDrop,&pickupPos);
pickup->setPos(&pickupPos);
2001-05-29 18:12:06 +02:00
}
2001-05-29 20:22:49 +02:00
setMode(PLAYER_MODE_FULLUNARMED);
2001-05-18 23:03:51 +02:00
}
}
2001-05-01 23:59:49 +02:00
// Trying to converate?
2001-05-02 00:05:23 +02:00
if(m_allowConversation==false&&
getPadInputDown()&PI_UP)
2001-05-01 23:59:49 +02:00
{
m_allowConversation=true;
}
2001-05-30 21:21:32 +02:00
// Think for the current player mode
2001-06-11 23:07:35 +02:00
int oldBlock;
DVECTOR oldPos;
oldBlock=CGameScene::getCollision()->getCollisionBlock(Pos.vx,Pos.vy)&COLLISION_TYPE_MASK;
oldPos=Pos;
2001-03-27 22:01:22 +02:00
m_currentPlayerModeClass->think();
2001-06-11 23:07:35 +02:00
if(oldBlock==COLLISION_TYPE_FLAG_DESTRUCTABLE_FLOOR&&
(Pos.vx>>4!=oldPos.vx>>4||Pos.vy>>4!=oldPos.vy>>4))
{
GameScene.GetLevel().destroyMapTile(oldPos);
}
2001-01-25 23:19:47 +01:00
2001-06-04 16:41:56 +02:00
// Is player stood on any special collision?
2001-05-30 21:21:32 +02:00
if(getHeightFromGroundNoPlatform(Pos.vx,Pos.vy,5)==0)
{
int block;
block=CGameScene::getCollision()->getCollisionBlock(Pos.vx,Pos.vy)&COLLISION_TYPE_MASK;
2001-06-04 16:41:56 +02:00
// Conveyor belt movement
2001-05-30 21:21:32 +02:00
if(block==COLLISION_TYPE_FLAG_MOVE_LEFT)
{
moveHorizontal(-1);
}
else if(block==COLLISION_TYPE_FLAG_MOVE_RIGHT)
{
moveHorizontal(+1);
}
2001-06-04 16:41:56 +02:00
// Death?
else if(m_currentMode!=PLAYER_MODE_DEAD&&
block==COLLISION_TYPE_FLAG_DEATH_LIQUID)
{
dieYouPorousFreak(DEATHTYPE__LIQUID);
}
else if(m_currentMode!=PLAYER_MODE_DEAD&&
block==COLLISION_TYPE_FLAG_DEATH_INSTANT)
{
dieYouPorousFreak(DEATHTYPE__NORMAL);
}
2001-05-30 21:21:32 +02:00
}
2001-03-02 17:02:30 +01:00
// Powerups
if(m_squeakyBootsTimer)
{
m_squeakyBootsTimer--;
}
2001-04-25 20:38:33 +02:00
if(m_invincibilityRingTimer)
2001-03-02 17:02:30 +01:00
{
2001-04-25 20:38:33 +02:00
m_invincibilityRingTimer--;
2001-03-02 17:02:30 +01:00
}
// Flashing..
if(m_invincibleFrameCount)
{
m_invincibleFrameCount--;
}
2001-05-13 21:28:48 +02:00
// Camera scroll..
if(m_cameraXScrollDir==-1)
{
if(m_cameraXScrollPos>-(CAMERA_SCROLLLIMIT*CAMERA_TILESIZE)<<CAMERA_ACCURACYSHIFT)
{
m_cameraXScrollPos-=CAMERA_SCROLLSPEED;
if(m_cameraXScrollPos<-(CAMERA_SCROLLLIMIT*CAMERA_TILESIZE)<<CAMERA_ACCURACYSHIFT)
{
m_cameraXScrollPos=-(CAMERA_SCROLLLIMIT*CAMERA_TILESIZE)<<CAMERA_ACCURACYSHIFT;
m_cameraXScrollDir=0;
}
}
2001-05-18 18:33:05 +02:00
#ifdef CAM_X_AUTO_CENTERING
2001-05-16 00:12:23 +02:00
returntimeoutcount=0;
2001-05-18 18:33:05 +02:00
#endif
2001-05-13 21:28:48 +02:00
}
else if(m_cameraXScrollDir==+1)
{
if(m_cameraXScrollPos<((CAMERA_SCROLLLIMIT*CAMERA_TILESIZE)<<CAMERA_ACCURACYSHIFT))
{
m_cameraXScrollPos+=CAMERA_SCROLLSPEED;
if(m_cameraXScrollPos>(CAMERA_SCROLLLIMIT*CAMERA_TILESIZE)<<CAMERA_ACCURACYSHIFT)
{
m_cameraXScrollPos=(CAMERA_SCROLLLIMIT*CAMERA_TILESIZE)<<CAMERA_ACCURACYSHIFT;
m_cameraXScrollDir=0;
}
}
2001-05-18 18:33:05 +02:00
#ifdef CAM_X_AUTO_CENTERING
2001-05-16 00:12:23 +02:00
returntimeoutcount=0;
2001-05-18 18:33:05 +02:00
#endif
2001-05-16 00:12:23 +02:00
}
2001-05-16 15:52:29 +02:00
2001-05-18 18:33:05 +02:00
#ifdef CAM_X_AUTO_CENTERING
2001-05-16 00:12:23 +02:00
if(m_moveVelocity.vx==0)
{
m_cameraXScrollDir=0;
if(m_cameraXScrollPos<-returnsafespace||m_cameraXScrollPos>returnsafespace)
{
if(returntimeoutcount<returntimeout)
{
returntimeoutcount++;
}
else
{
if(m_cameraXScrollPos<0)
{
m_cameraXScrollPos+=returnspeed;
if(m_cameraXScrollPos>0)
{
m_cameraXScrollPos=0;
}
}
else if(m_cameraXScrollPos>0)
{
m_cameraXScrollPos-=returnspeed;
if(m_cameraXScrollPos<0)
{
m_cameraXScrollPos=0;
}
}
}
}
2001-05-13 21:28:48 +02:00
}
2001-05-18 18:33:05 +02:00
#endif
2001-05-13 21:28:48 +02:00
2001-05-03 20:42:56 +02:00
// Stop the player vanishing off the edge of the telly..
2001-05-15 23:41:39 +02:00
if(!m_lockCamera)
{
if(Pos.vx<m_playerPosLimitBox.x1) Pos.vx=m_playerPosLimitBox.x1;
else if(Pos.vx>m_playerPosLimitBox.x2) Pos.vx=m_playerPosLimitBox.x2;
if(Pos.vy<m_playerPosLimitBox.y1) Pos.vy=m_playerPosLimitBox.y1;
else if(Pos.vy>m_playerPosLimitBox.y2) Pos.vy=m_playerPosLimitBox.y2;
}
2001-02-09 18:01:04 +01:00
2001-05-24 22:00:19 +02:00
// Falling camera lag
if(m_isFalling)
{
if(m_fallFrames>CAMERA_FALL_FRAME_THRESHOLD)
{
if(m_cameraFallYScrollSpeed<CAMERA_FALL_DROP_SPEED)
{
m_cameraFallYScrollSpeed++;
}
m_cameraFallYScrollPos-=m_cameraFallYScrollSpeed;
if(m_cameraFallYScrollPos<-CAMERA_FALL_MAX_OFFSET)
{
m_cameraFallYScrollPos=-CAMERA_FALL_MAX_OFFSET;
}
}
else
{
m_fallFrames++;
}
m_isFalling=false;
}
else
{
if(m_cameraFallYScrollPos)
{
m_cameraFallYScrollPos+=CAMERA_FALL_RETURN_SPEED;
if(m_cameraFallYScrollPos>0)
{
m_cameraFallYScrollPos=0;
}
}
m_fallFrames=0;
m_cameraFallYScrollSpeed=0;
}
2001-01-31 22:05:12 +01:00
// Look around
int pad=getPadInputHeld();
2001-04-18 18:35:26 +02:00
if(pad&PI_UP&&canDoLookAround())
2001-04-11 17:48:16 +02:00
{
2001-04-12 00:37:57 +02:00
if(m_padLookAroundTimer>0)
2001-04-11 17:48:16 +02:00
{
2001-04-12 00:37:57 +02:00
m_padLookAroundTimer=0;
2001-04-11 17:48:16 +02:00
}
2001-04-12 00:37:57 +02:00
else if(m_padLookAroundTimer>-looktimeout)
2001-04-11 17:48:16 +02:00
{
2001-04-12 00:37:57 +02:00
m_padLookAroundTimer--;
2001-04-11 17:48:16 +02:00
}
else if(m_cameraLookOffset>-lookmaxoffsetup)
{
m_cameraLookOffset-=lookspeed;
if(m_cameraLookOffset<-lookmaxoffsetup)
{
m_cameraLookOffset=-lookmaxoffsetup;
}
}
}
2001-04-18 18:35:26 +02:00
else if(pad&PI_DOWN&&canDoLookAround())
2001-04-11 17:48:16 +02:00
{
2001-04-12 00:37:57 +02:00
if(m_padLookAroundTimer<0)
2001-04-11 17:48:16 +02:00
{
2001-04-12 00:37:57 +02:00
m_padLookAroundTimer=0;
2001-04-11 17:48:16 +02:00
}
2001-04-12 00:37:57 +02:00
else if(m_padLookAroundTimer<looktimeout)
2001-04-11 17:48:16 +02:00
{
2001-04-12 00:37:57 +02:00
m_padLookAroundTimer++;
2001-04-11 17:48:16 +02:00
}
else if(m_cameraLookOffset<lookmaxoffsetdown)
{
m_cameraLookOffset+=lookspeed;
if(m_cameraLookOffset>lookmaxoffsetdown)
{
m_cameraLookOffset=lookmaxoffsetdown;
}
}
}
else
{
2001-04-12 00:37:57 +02:00
m_padLookAroundTimer=0;
2001-04-11 17:48:16 +02:00
}
// Return to centre
2001-04-17 22:45:02 +02:00
if(m_padLookAroundTimer==0&&m_cameraLookOffset<0)
2001-04-11 17:48:16 +02:00
{
m_cameraLookOffset+=lookreturnspeed;
if(m_cameraLookOffset>0)
{
m_cameraLookOffset=0;
}
}
2001-04-17 22:45:02 +02:00
if(m_padLookAroundTimer==0&&m_cameraLookOffset>0)
2001-04-11 17:48:16 +02:00
{
m_cameraLookOffset-=lookreturnspeed;
if(m_cameraLookOffset<0)
{
m_cameraLookOffset=0;
}
}
2001-04-19 01:37:52 +02:00
// Automatic anim sfx
playAnimFrameSfx(m_animNo,m_animFrame);
2001-01-15 23:09:47 +01:00
}
2001-01-25 16:25:46 +01:00
2001-06-08 17:02:29 +02:00
m_xMove = Pos.vx - m_xMove;
2001-05-16 16:41:50 +02:00
// Out of water and wearing helmet..?
ASSERT(!(getIsInWater()==false&&isWearingDivingHelmet()==false));
if(isWearingDivingHelmet()&&getIsInWater()==false&&
m_currentMode!=PLAYER_MODE_DEAD&&m_currentMode!=PLAYER_MODE_FLY)
{
2001-06-01 20:59:33 +02:00
// Drain water/health
2001-05-16 16:41:50 +02:00
m_healthWaterLevel-=waterDrainSpeed*_frames;
if(m_healthWaterLevel<=0)
{
2001-05-17 20:42:59 +02:00
dieYouPorousFreak(DEATHTYPE__DRYUP);
2001-05-16 16:41:50 +02:00
}
2001-06-01 20:59:33 +02:00
// Breath sound
m_helmetSoundTimer+=_frames;
if(m_helmetSoundTimer>150+(m_healthWaterLevel>>WATERLEVELSHIFT))
{
CSoundMediator::playSfx(CSoundMediator::SFX_SPONGEBOB_DIVING_HELMET);
m_helmetSoundTimer=0;
}
2001-05-16 16:41:50 +02:00
}
2001-04-17 22:09:33 +02:00
// Ledge look-ahead stuff
if(m_ledgeLookAhead&&m_ledgeLookAhead==m_lastLedgeLookAhead)
{
if(m_ledgeLookTimer<ledgeTimer)
{
2001-04-17 22:45:02 +02:00
m_ledgeLookTimer+=_frames;
2001-04-17 22:09:33 +02:00
}
else
{
int limit;
limit=(m_ledgeLookAhead*MAP2D_BLOCKSTEPSIZE)<<ledgeShift;
2001-04-17 22:45:02 +02:00
if(m_ledgeLookAhead>0)
2001-04-17 22:09:33 +02:00
{
2001-04-17 22:45:02 +02:00
if(m_ledgeLookOffset<limit)
2001-04-17 22:09:33 +02:00
{
2001-04-17 22:45:02 +02:00
// Look down
m_ledgeLookOffset+=ledgeSpeedIn*_frames;
if(m_ledgeLookOffset>limit)
{
m_ledgeLookOffset=limit;
}
}
else if(m_ledgeLookOffset>limit)
{
// Look up
m_ledgeLookOffset-=ledgeSpeedIn*_frames;
if(m_ledgeLookOffset<limit)
{
m_ledgeLookOffset=limit;
}
2001-04-17 22:09:33 +02:00
}
}
}
}
else
{
if(m_ledgeLookOffset>0)
{
2001-04-17 22:45:02 +02:00
// Relax from look down
2001-04-17 22:09:33 +02:00
m_ledgeLookOffset-=ledgeSpeedOut*_frames;
if(m_ledgeLookOffset<=0)
{
m_ledgeLookOffset=0;
m_ledgeLookTimer=0;
}
}
else if(m_ledgeLookOffset<0)
{
2001-04-17 22:45:02 +02:00
// Relax from look up
2001-04-17 22:09:33 +02:00
m_ledgeLookOffset+=ledgeSpeedOut*_frames;
if(m_ledgeLookOffset>=0)
{
m_ledgeLookOffset=0;
m_ledgeLookTimer=0;
}
}
}
m_lastLedgeLookAhead=m_ledgeLookAhead;
m_ledgeLookAhead=0;
2001-04-13 00:14:49 +02:00
// Camera focus point stuff
2001-05-02 20:11:29 +02:00
calcCameraFocusPointTarget();
2001-04-17 22:09:33 +02:00
for(i=0;i<_frames;i++)
{
m_currentCamFocusPoint.vx+=(m_currentCamFocusPointTarget.vx-m_currentCamFocusPoint.vx)>>cammove;
m_currentCamFocusPoint.vy+=(m_currentCamFocusPointTarget.vy-m_currentCamFocusPoint.vy)>>cammove;
}
2001-04-17 22:45:02 +02:00
// Final camera position
int yoff;
yoff=m_cameraLookOffset+(m_ledgeLookOffset>>ledgeShift);
if(yoff<-lookmaxoffsetup)yoff=-lookmaxoffsetup;
else if(yoff>lookmaxoffsetdown)yoff=lookmaxoffsetdown;
2001-05-04 23:19:00 +02:00
if(!m_lockCamera)
{
m_cameraPos.vx=m_currentCamFocusPoint.vx;
m_cameraPos.vy=m_currentCamFocusPoint.vy+yoff;
}
2001-02-09 18:01:04 +01:00
2001-02-12 16:26:00 +01:00
// Limit camera scroll to the edges of the map
2001-05-03 20:42:56 +02:00
if(m_cameraPos.vx<m_cameraPosLimitBox.x1) m_cameraPos.vx=m_cameraPosLimitBox.x1;
else if(m_cameraPos.vx>m_cameraPosLimitBox.x2) m_cameraPos.vx=m_cameraPosLimitBox.x2;
if(m_cameraPos.vy<m_cameraPosLimitBox.y1) m_cameraPos.vy=m_cameraPosLimitBox.y1;
else if(m_cameraPos.vy>m_cameraPosLimitBox.y2) m_cameraPos.vy=m_cameraPosLimitBox.y2;
2001-05-21 16:22:26 +02:00
2001-04-01 23:40:52 +02:00
CPlayerThing::think(_frames);
2001-01-15 23:09:47 +01:00
}
2001-02-16 21:25:02 +01:00
2001-01-16 20:27:14 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-01-20 00:37:40 +01:00
int panim=-1;
2001-03-01 18:01:37 +01:00
#include "gfx\prim.h" // (pkg)
2001-03-02 19:00:19 +01:00
2001-05-02 17:31:30 +02:00
#ifdef _STATE_DEBUG_
int stateDebugX=280;
int stateDebugY=60;
#endif
2001-04-25 20:38:33 +02:00
#ifdef __USER_paul__
2001-05-17 20:42:59 +02:00
#define NUM_LASTPOS 100
typedef struct
{
int vx,vy;
int h;
int onp;
}POSMEM;
static POSMEM lastpos[NUM_LASTPOS];
2001-04-25 20:38:33 +02:00
static int lastposnum=0;
2001-05-30 21:21:32 +02:00
int drawlastpos=false;
2001-04-25 20:38:33 +02:00
#endif
2001-02-02 18:48:40 +01:00
#ifdef __USER_paul__
int mouth=-1,eyes=-1;
#endif
2001-05-01 18:26:31 +02:00
2001-05-03 03:59:46 +02:00
#include "gui\gui.h"
2001-01-15 23:09:47 +01:00
void CPlayer::render()
{
2001-05-03 03:59:46 +02:00
CPlayerThing::render();
2001-02-20 18:37:25 +01:00
#ifdef _STATE_DEBUG_
2001-05-02 17:31:30 +02:00
char buf[100];
#ifdef __USER_paul__
sprintf(buf,"%04d (%02d) ,%04d (%02d)\ndfg:%+02d\nMode:%s",Pos.vx,Pos.vx&0x0f,Pos.vy,Pos.vy&0x0f,getHeightFromGround(Pos.vx,Pos.vy),s_modeText[m_currentMode]);
#else
sprintf(buf,"Pos: %04d,%04d",Pos.vx,Pos.vy);
#endif
m_fontBank->print(stateDebugX,stateDebugY,buf);
2001-02-20 18:37:25 +01:00
#endif
2001-04-25 20:38:33 +02:00
#ifdef __USER_paul__
2001-05-10 16:35:35 +02:00
if(PadGetDown(0)&PAD_R1)
{
2001-05-17 20:42:59 +02:00
POSMEM clear={0,0,0,false};
2001-05-10 16:35:35 +02:00
for(int i=0;i<NUM_LASTPOS;i++)
{
lastpos[i]=clear;
}
}
2001-04-25 20:38:33 +02:00
if(Pos.vx!=lastpos[lastposnum].vx||Pos.vy!=lastpos[lastposnum].vy)
{
lastposnum=(lastposnum+1)%NUM_LASTPOS;
2001-05-17 20:42:59 +02:00
POSMEM *p=&lastpos[lastposnum];
p->vx=Pos.vx;
p->vy=Pos.vy;
p->onp=isOnPlatform()!=NULL;
if(p->onp)
{
p->h=getHeightFromPlatformNoGround(Pos.vx,Pos.vy,150);
}
else
{
p->h=getHeightFromGround(Pos.vx,Pos.vy,150);
}
2001-04-25 20:38:33 +02:00
}
2001-05-30 21:21:32 +02:00
if(drawlastpos)
2001-04-25 20:38:33 +02:00
{
2001-05-30 21:21:32 +02:00
POSMEM *p=lastpos;
for(int i=0;i<NUM_LASTPOS;i++)
2001-05-17 20:42:59 +02:00
{
2001-05-30 21:21:32 +02:00
int x,y;
x=p->vx-m_cameraPos.vx;
y=p->vy-m_cameraPos.vy;
DrawLine(x-4,y-4,x+4,y+4,0,0,255,0);
DrawLine(x-4,y+4,x+4,y-4,0,0,255,0);
y=y+p->h;
if(p->onp)
{
DrawLine(x-6,y,x+6,y,255,0,255,0);
}
else
{
DrawLine(x-6,y,x+6,y,128,0,255,0);
}
2001-05-17 20:42:59 +02:00
2001-05-30 21:21:32 +02:00
p++;
}
2001-04-25 20:38:33 +02:00
}
#endif
2001-06-14 17:19:57 +02:00
SpriteBank *sb=CGameScene::getSpriteBank();
// Render player
2001-05-01 23:59:49 +02:00
DVECTOR sbPos=
2001-01-22 23:58:12 +01:00
{
2001-05-01 23:59:49 +02:00
Pos.vx-m_cameraPos.vx,
Pos.vy-m_cameraPos.vy,
};
renderSb(&sbPos,m_animNo,m_animFrame>>sbanimspeed);
m_currentPlayerModeClass->render(&sbPos);
2001-02-09 22:41:55 +01:00
2001-06-14 17:19:57 +02:00
// UI
char spatCount[20];
int x,y;
sFrameHdr *fh;
2001-04-05 16:40:50 +02:00
2001-06-14 17:19:57 +02:00
// Spat count
sprintf(spatCount,"x%d",m_numSpatulasHeld);
x=SB_UI_XBASE;
y=SB_UI_YBASE;
fh=sb->getFrameHeader(FRM__SPATULA);
2001-06-14 18:25:58 +02:00
sb->printFT4(fh,x,y,0,0,POWERUPUI_OT);
2001-06-14 17:19:57 +02:00
x+=fh->W;
m_fontBank->print(x,y,spatCount);
x+=SB_UI_GAP_FROM_SPAT_COUNT_TO_PICKUPS;
2001-03-01 21:30:25 +01:00
2001-06-14 17:19:57 +02:00
if(isWearingDivingHelmet())
2001-05-04 01:45:28 +02:00
{
2001-06-14 17:19:57 +02:00
// Helmet
2001-05-04 01:45:28 +02:00
POLY_FT4 *ft4;
int V,W,H,partH;
2001-05-21 16:22:26 +02:00
2001-06-14 18:25:58 +02:00
ft4=sb->printFT4(FRM__WATERHILIGHT,x,y,0,0,POWERUPUI_OT);
2001-05-04 01:45:28 +02:00
setSemiTrans(ft4,true);
2001-06-14 17:19:57 +02:00
fh=sb->getFrameHeader(FRM__WATER);
2001-06-14 18:25:58 +02:00
ft4=sb->printFT4(fh,0,0,0,0,POWERUPUI_OT);
2001-05-04 01:45:28 +02:00
setSemiTrans(ft4,true);
V=fh->V;
W=fh->W;
H=fh->H;
partH=(H*(255-(m_healthWaterLevel>>WATERLEVELSHIFT)))>>8;
if(partH>H)partH=H;
2001-06-14 17:19:57 +02:00
setXYWH(ft4,x,y+(partH),W,H-partH);
2001-05-04 01:45:28 +02:00
ft4->v0=V+(partH);
ft4->v1=V+(partH);
2001-05-14 21:38:11 +02:00
2001-06-14 18:25:58 +02:00
sb->printFT4(FRM__WATERMETER,x,y,0,0,POWERUPUI_OT);
2001-05-02 22:27:49 +02:00
2001-06-14 17:19:57 +02:00
x+=fh->W+SB_UI_GAP_BETWEEN_ITEMS;
}
2001-05-02 22:27:49 +02:00
if(isWearingBoots())
{
2001-06-14 17:19:57 +02:00
// Boots
int pickupX,pickupY;
sFrameHdr *fh=sb->getFrameHeader(FRM__SHOE);
2001-06-14 18:25:58 +02:00
sb->printFT4(fh,x,y,0,0,POWERUPUI_OT);
sb->printFT4(fh,x+4,y+4,0,0,POWERUPUI_OT);
2001-06-14 17:19:57 +02:00
x+=fh->W+SB_UI_GAP_BETWEEN_ITEMS+4;
2001-05-02 22:27:49 +02:00
}
2001-06-14 17:19:57 +02:00
// Mode specific ui
m_currentPlayerModeClass->renderModeUi();
2001-01-15 23:09:47 +01:00
}
2001-01-20 00:37:40 +01:00
2001-02-12 16:26:00 +01:00
/*----------------------------------------------------------------------
Function:
Purpose: Pre-calcs the visible edges of the map ( ie: the hard limits
for the camera pos )
2001-05-03 20:42:56 +02:00
Params: camera box ( in tiles )
2001-02-12 16:26:00 +01:00
Returns:
---------------------------------------------------------------------- */
2001-05-03 20:42:56 +02:00
void CPlayer::setCameraBox(CameraBox _cameraBox)
2001-02-12 16:26:00 +01:00
{
2001-05-03 20:42:56 +02:00
m_cameraPosLimitBox.x1=_cameraBox.x1;
m_cameraPosLimitBox.y1=_cameraBox.y1;
m_cameraPosLimitBox.x2=_cameraBox.x2-(32*MAP2D_BLOCKSTEPSIZE); // Made up numbers! :) (pkg);
m_cameraPosLimitBox.y2=_cameraBox.y2-(16*MAP2D_BLOCKSTEPSIZE);
m_playerPosLimitBox.x1=_cameraBox.x1+64;
m_playerPosLimitBox.y1=_cameraBox.y1+64;
m_playerPosLimitBox.x2=_cameraBox.x2-64;
m_playerPosLimitBox.y2=_cameraBox.y2-64;
2001-01-25 16:25:46 +01:00
}
2001-03-29 21:19:33 +02:00
2001-06-11 17:27:05 +02:00
/*----------------------------------------------------------------------
Function:
Purpose: Like the normal setRespawnPos() but plays the telephone ring sound if
this is not the current respawn point. To be used from the respawn triggers
so that they make the ring sound
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::setRespawnPosAndRingTelephone(DVECTOR _respawn)
{
2001-06-11 23:07:35 +02:00
if(m_respawnPos.vx!=_respawn.vx||
2001-06-11 17:27:05 +02:00
m_respawnPos.vy!=_respawn.vy)
{
CSoundMediator::playSfx(CSoundMediator::SFX_TELEPHONE_BOX);
setRespawnPos(_respawn);
}
}
2001-03-29 21:19:33 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int CPlayer::getHeightFromGround(int _x,int _y,int _maxHeight)
{
int height;
2001-03-31 00:43:35 +02:00
2001-05-25 20:43:47 +02:00
height=CGameScene::getCollision()->getHeightFromGround(_x,_y,_maxHeight);
2001-05-01 18:26:31 +02:00
if(height>=_maxHeight)
2001-04-27 04:05:05 +02:00
{
2001-05-01 18:26:31 +02:00
CThing *platform;
2001-05-01 01:02:50 +02:00
platform=isOnPlatform();
if(platform)
2001-04-06 22:53:48 +02:00
{
2001-05-25 22:45:03 +02:00
int platformHeight=((CNpcPlatform*)platform)->getHeightFromPlatformAtPosition(_x,_y);
if ( platformHeight < height )
{
height = platformHeight;
if(height>_maxHeight)height=_maxHeight;
else if(height<-_maxHeight)height=-_maxHeight;
}
2001-04-06 22:53:48 +02:00
}
2001-03-29 21:19:33 +02:00
}
2001-04-27 04:05:05 +02:00
2001-03-29 21:19:33 +02:00
return height;
}
2001-05-10 16:35:35 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int CPlayer::getHeightFromPlatformNoGround(int _x,int _y,int _maxHeight)
{
CThing *platform;
int height;
platform=isOnPlatform();
ASSERT(platform);
height=((CNpcPlatform*)platform)->getHeightFromPlatformAtPosition(_x,_y);
if(height>_maxHeight)height=_maxHeight;
else if(height<-_maxHeight)height=-_maxHeight;
return height;
}
2001-04-07 21:52:45 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int CPlayer::getHeightFromGroundNoPlatform(int _x,int _y,int _maxHeight=32)
{
2001-05-25 20:43:47 +02:00
return( CGameScene::getCollision()->getHeightFromGround(_x,_y,_maxHeight) );
2001-04-07 21:52:45 +02:00
}
2001-03-01 21:30:25 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::addLife()
{
m_lives++;
if(m_lives>MAX_LIVES)
{
m_lives=MAX_LIVES;
}
}
2001-01-20 00:37:40 +01:00
2001-04-12 20:48:33 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
ATTACK_STATE CPlayer::getAttackState()
{
return m_currentPlayerModeClass->getAttackState();
}
2001-01-26 19:20:41 +01:00
2001-04-30 23:27:46 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::registerAddon(PLAYER_ADDONS _addon)
{
if(!s_addonActorGfx[_addon])
{
FileEquate sbk;
sbk=s_addonActorPoolNames[_addon];
2001-05-25 22:10:19 +02:00
s_addonActorGfx[_addon]=CActorPool::GetActor(sbk);
2001-04-30 23:27:46 +02:00
}
}
2001-01-26 19:20:41 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-01-31 23:50:59 +01:00
void CPlayer::setMode(PLAYER_MODE _mode)
2001-01-26 19:20:41 +01:00
{
2001-05-17 20:42:59 +02:00
int state;
2001-05-15 18:48:29 +02:00
if(_mode==PLAYER_MODE_DEAD)
{
ASSERT(m_currentMode!=PLAYER_MODE_DEAD);
m_lastModeBeforeDeath=m_currentMode;
}
2001-04-18 18:35:26 +02:00
resetPlayerCollisionSizeToBase();
2001-05-17 20:42:59 +02:00
if(m_currentPlayerModeClass)
{
state=m_currentPlayerModeClass->getState();
}
else
{
state=STATE_IDLE;
}
2001-01-26 19:20:41 +01:00
m_currentMode=_mode;
2001-03-23 21:09:14 +01:00
m_currentPlayerModeClass=s_playerModes[_mode];
2001-05-17 20:42:59 +02:00
if(!m_currentPlayerModeClass->setState(state))
{
m_currentPlayerModeClass->setState(STATE_IDLE);
m_moveVelocity.vx=m_moveVelocity.vy=0;
}
2001-03-23 21:09:14 +01:00
m_currentPlayerModeClass->enter();
2001-01-16 20:27:14 +01:00
}
2001-01-15 23:09:47 +01:00
2001-01-20 00:37:40 +01:00
2001-01-16 20:27:14 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-01-20 00:37:40 +01:00
int CPlayer::getFacing()
{
return m_facing;
}
void CPlayer::setFacing(int _facing)
2001-01-15 23:09:47 +01:00
{
2001-04-02 17:48:02 +02:00
m_facing=_facing;
2001-01-12 23:40:39 +01:00
}
2001-02-01 18:01:12 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-01-20 00:37:40 +01:00
int CPlayer::getAnimFrame()
{
return m_animFrame;
}
void CPlayer::setAnimFrame(int _animFrame)
{
m_animFrame=_animFrame;
2001-04-19 01:37:52 +02:00
}
int CPlayer::getAnimFrameCount()
{
return m_actorGfx->getFrameCount(m_animNo)<<sbanimspeed;
}
int CPlayer::getAnimNo()
{
return m_animNo;
}
void CPlayer::setAnimNo(int _animNo)
{
m_animNo=_animNo;
setAnimFrame(0);
}
2001-05-01 20:39:41 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-06-14 23:22:40 +02:00
void CPlayer::springPlayerUp(int _springHeight)
2001-05-01 20:39:41 +02:00
{
2001-06-14 23:22:40 +02:00
m_currentPlayerModeClass->springPlayerUp(_springHeight);
2001-05-01 20:39:41 +02:00
}
2001-06-07 21:40:41 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int haha=25;
void CPlayer::floatPlayerUp()
{
m_moveVelocity.vy-=haha;
}
2001-05-02 20:11:29 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::teleportTo(int _x,int _y)
{
DVECTOR pos={_x,_y};
2001-05-04 03:35:52 +02:00
CameraBox releaseCamBox={0,0,29999,29999};
setCameraBox(releaseCamBox);
2001-05-02 20:11:29 +02:00
setPos(pos);
setRespawnPos(pos);
calcCameraFocusPointTarget();
m_currentCamFocusPoint=m_currentCamFocusPointTarget;
}
2001-04-19 01:37:52 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::playAnimFrameSfx(int _animNo,int _animFrame)
{
static int lastAnimNo=-1;
static const AnimSfx *sfx;
2001-02-01 18:01:12 +01:00
2001-04-19 01:37:52 +02:00
if(_animNo!=lastAnimNo)
{
// Lookup the new anim number and cache it for next time :)
int i;
sfx=s_animSfx;
for(i=0;i<s_numAnimSfx;i++)
{
if(sfx->m_animNumber==_animNo)
{
break;
}
sfx++;
}
if(i==s_numAnimSfx)
{
// No sfx for this anim
sfx=NULL;
}
lastAnimNo=_animNo;
}
// Are there any sounds for this anim at this frame?
if(sfx)
2001-02-01 18:01:12 +01:00
{
2001-02-01 18:32:16 +01:00
const AnimFrameSfx *frameSfx;
int i;
2001-02-01 18:01:12 +01:00
2001-04-19 01:37:52 +02:00
ASSERT(sfx->m_numAnimFrameSfx);
2001-02-01 18:01:12 +01:00
frameSfx=sfx->m_animFrameSfx;
for(i=0;i<sfx->m_numAnimFrameSfx;i++)
{
if(m_animFrame==frameSfx->m_frame)
{
2001-02-08 17:51:16 +01:00
CSoundMediator::SFXID sfxId=frameSfx->m_sfxId;
2001-06-01 22:16:23 +02:00
if(isWearingBoots())
2001-02-08 17:51:16 +01:00
{
// Ugh.. horrible way to change the sfx when wearing squeaky boots (pkg)
if(sfxId==CSoundMediator::SFX_SPONGEBOB_WALK_1)sfxId=CSoundMediator::SFX_SPONGEBOB_SQUEAKY_SHOES_1;
else if(sfxId==CSoundMediator::SFX_SPONGEBOB_WALK_2)sfxId=CSoundMediator::SFX_SPONGEBOB_SQUEAKY_SHOES_2;
}
CSoundMediator::playSfx(sfxId);
2001-03-02 17:02:30 +01:00
break;
2001-02-01 18:01:12 +01:00
}
if(m_animFrame<frameSfx->m_frame)
{
break;
}
frameSfx++;
}
}
2001-01-20 00:37:40 +01:00
}
2001-02-01 18:01:12 +01:00
2001-05-02 20:11:29 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::calcCameraFocusPointTarget()
{
2001-05-13 21:28:48 +02:00
m_currentCamFocusPointTarget.vx=Pos.vx+MAP2D_CENTRE_X-(m_cameraXScrollPos>>CAMERA_ACCURACYSHIFT);
2001-05-24 22:00:19 +02:00
m_currentCamFocusPointTarget.vy=Pos.vy+MAP2D_CENTRE_Y-m_cameraFallYScrollPos;
2001-05-02 20:11:29 +02:00
}
2001-02-01 18:01:12 +01:00
2001-02-12 18:55:01 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::respawn()
{
2001-05-15 18:48:29 +02:00
setMode(m_lastModeBeforeDeath);
2001-02-12 18:55:01 +01:00
2001-05-01 23:43:14 +02:00
m_allowConversation=false;
2001-06-14 17:19:57 +02:00
m_numSpatulasHeld=0;
2001-05-04 01:45:28 +02:00
m_healthWaterLevel=WATERMAXHEALTH;
2001-03-27 22:01:22 +02:00
m_invincibleFrameCount=INVINCIBLE_FRAMES__START;
2001-06-01 20:59:33 +02:00
m_helmetSoundTimer=0;
2001-02-12 18:55:01 +01:00
Pos=m_respawnPos;
2001-04-12 00:37:57 +02:00
m_cameraLookOffset=0;
2001-05-02 20:11:29 +02:00
2001-05-04 23:19:00 +02:00
m_lockCamera=false;
2001-05-13 21:28:48 +02:00
m_cameraXScrollDir=0;
m_cameraXScrollPos=0;
2001-05-24 22:00:19 +02:00
m_cameraFallYScrollPos=0;
m_isFalling=false;
m_fallFrames=false;
m_cameraFallYScrollSpeed=0;
2001-05-02 20:11:29 +02:00
calcCameraFocusPointTarget();
m_currentCamFocusPoint=m_currentCamFocusPointTarget;
2001-05-10 23:07:25 +02:00
m_cameraPos.vx=m_currentCamFocusPoint.vx;
m_cameraPos.vy=m_currentCamFocusPoint.vy;
2001-05-02 20:11:29 +02:00
2001-04-12 00:37:57 +02:00
m_padLookAroundTimer=0;
2001-04-17 22:09:33 +02:00
m_ledgeLookAhead=m_lastLedgeLookAhead=0;
m_ledgeLookOffset=0;
m_ledgeLookTimer=0;
2001-05-29 20:22:49 +02:00
m_tryingToManuallyPickupWeapon=false;
m_tryingToAutomaticallyPickupWeapon=false;
2001-03-29 21:19:33 +02:00
2001-03-31 04:05:24 +02:00
m_squeakyBootsTimer=0;
2001-04-25 20:38:33 +02:00
m_invincibilityRingTimer=0;
2001-03-31 04:05:24 +02:00
m_bubbleAmmo=0;
2001-04-08 20:57:16 +02:00
m_jellyAmmo=0;
2001-05-29 16:51:59 +02:00
m_jellyfishAmmoCount=0;
2001-03-31 04:05:24 +02:00
2001-05-01 18:26:31 +02:00
m_moveVelocity.vx=m_moveVelocity.vy=0;
2001-05-21 16:22:26 +02:00
2001-03-29 21:19:33 +02:00
clearPlatform();
2001-05-04 21:34:09 +02:00
2001-05-10 23:08:40 +02:00
updateCollisionArea();
2001-05-11 23:35:08 +02:00
m_lives--;
2001-02-12 18:55:01 +01:00
}
2001-04-05 18:26:17 +02:00
/*----------------------------------------------------------------------
Function:
2001-05-11 02:36:17 +02:00
Purpose: Yes - This function is fat! It can be tidied up when all of the anims
are finalised. Etracting the repeated code to a function will probly not
improve things cos of the amount of data that would need to be passed about.
2001-04-05 18:26:17 +02:00
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::renderSb(DVECTOR *_pos,int _animNo,int _animFrame)
{
2001-05-16 18:47:29 +02:00
int playerMode;
2001-05-02 00:09:36 +02:00
int trans;
2001-05-01 23:59:49 +02:00
int addon;
2001-05-16 18:47:29 +02:00
POLY_FT4 *ft4;
2001-05-01 23:59:49 +02:00
2001-05-16 18:47:29 +02:00
if(m_currentMode==PLAYER_MODE_DEAD)
{
playerMode=m_lastModeBeforeDeath;
}
else
{
playerMode=m_currentMode;
}
2001-05-02 00:09:36 +02:00
trans=m_invincibleFrameCount||m_invincibilityRingTimer;
2001-04-30 23:27:46 +02:00
// Render an addon?
2001-05-16 18:47:29 +02:00
addon=s_addonNumbers[playerMode];
2001-04-30 23:27:46 +02:00
if(addon!=NO_ADDON)
{
2001-05-10 16:35:35 +02:00
s8 addonAnimNo=s_animMapNet[addon][_animNo];
if(addonAnimNo!=-1)
2001-04-30 23:27:46 +02:00
{
CActorGfx *addonGfx=s_addonActorGfx[addon];
2001-05-10 23:32:18 +02:00
if(addonGfx)
2001-04-30 23:27:46 +02:00
{
2001-05-10 23:32:18 +02:00
if(_animFrame>=addonGfx->getFrameCount(addonAnimNo))
{
PAUL_DBGMSG("FRAME OVERRUN ON SPONGEBOB ADDON! ( %d vs %d )",m_actorGfx->getFrameCount(_animNo),addonGfx->getFrameCount(addonAnimNo));
}
else
{
ft4=addonGfx->Render(*_pos,addonAnimNo,_animFrame,m_facing==FACING_RIGHT?0:1);
setSemiTrans(ft4,trans);
}
2001-04-30 23:27:46 +02:00
}
}
}
2001-05-11 02:36:17 +02:00
// Render JFish in a net?
2001-05-16 18:47:29 +02:00
if(playerMode==PLAYER_MODE_NET&&getJellyFishAmmo())
2001-05-11 02:36:17 +02:00
{
s8 addonAnimNo=s_animMapNet[PLAYER_ADDON_JELLYFISHINNET][_animNo];
if(addonAnimNo!=-1)
{
CActorGfx *addonGfx=s_addonActorGfx[PLAYER_ADDON_JELLYFISHINNET];
if(addonGfx)
{
if(_animFrame>=addonGfx->getFrameCount(addonAnimNo))
{
PAUL_DBGMSG("FRAME OVERRUN ON SPONGEBOB JELLYFISH ADDON! ( %d vs %d )",m_actorGfx->getFrameCount(_animNo),addonGfx->getFrameCount(addonAnimNo));
}
else
{
2001-05-29 16:51:59 +02:00
u32 colour;
colour=getColourOfNextJellyfishAmmo();
2001-05-11 02:36:17 +02:00
ft4=addonGfx->Render(*_pos,addonAnimNo,_animFrame,m_facing==FACING_RIGHT?0:1);
2001-05-29 16:51:59 +02:00
setRGB0(ft4,(colour)&0xff,(colour>>8)&0x0ff,(colour>>16)&0xff);
2001-05-11 02:36:17 +02:00
setSemiTrans(ft4,trans);
}
}
}
}
2001-05-16 18:47:29 +02:00
2001-05-10 23:32:18 +02:00
// Render glove addon?
if(m_currentMode==PLAYER_MODE_FULLUNARMED)
{
s8 addonAnimNo=s_animMapNet[PLAYER_ADDON_GLOVE][_animNo];
if(addonAnimNo!=-1)
{
CActorGfx *addonGfx=s_addonActorGfx[PLAYER_ADDON_GLOVE];
if(addonGfx)
2001-05-10 16:35:35 +02:00
{
2001-05-10 23:32:18 +02:00
if(_animFrame>=addonGfx->getFrameCount(addonAnimNo))
{
2001-05-11 02:36:17 +02:00
PAUL_DBGMSG("FRAME OVERRUN ON SPONGEBOB GLOVE ADDON! ( %d vs %d )",m_actorGfx->getFrameCount(_animNo),addonGfx->getFrameCount(addonAnimNo));
2001-05-10 23:32:18 +02:00
}
else
{
ft4=addonGfx->Render(*_pos,addonAnimNo,_animFrame,m_facing==FACING_RIGHT?0:1);
setSemiTrans(ft4,trans);
}
2001-04-28 00:25:49 +02:00
}
}
}
2001-04-30 23:27:46 +02:00
// Render SB
2001-05-02 00:05:23 +02:00
ft4=m_actorGfx->Render(*_pos,_animNo,_animFrame,m_facing==FACING_RIGHT?0:1);
2001-05-02 00:09:36 +02:00
setSemiTrans(ft4,trans);
2001-04-05 18:26:17 +02:00
}
2001-04-18 18:35:26 +02:00
/*----------------------------------------------------------------------
Function:
Purpose: Says whether SB can do the look up/down thing
Params:
Returns:
---------------------------------------------------------------------- */
int CPlayer::canDoLookAround()
{
return m_currentPlayerModeClass->canDoLookAround();
}
2001-05-04 01:45:28 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::inSoakUpState()
{
2001-05-08 18:58:07 +02:00
if(isWearingDivingHelmet()&&
2001-06-04 16:41:56 +02:00
(CGameScene::getCollision()->getCollisionBlock(Pos.vx,Pos.vy)&COLLISION_TYPE_MASK)==COLLISION_TYPE_FLAG_SOAKUP)
2001-05-04 01:45:28 +02:00
{
m_healthWaterLevel+=waterSoakUpSpeed;
if(m_healthWaterLevel>WATERMAXHEALTH)
{
m_healthWaterLevel=WATERMAXHEALTH;
}
}
}
2001-02-06 22:09:45 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
2001-05-11 21:49:41 +02:00
Params: When _reactDirection is REACT__GET_DIRECTION_FROM_THING then
_thing must point to the thing that caused the damage
2001-02-06 22:09:45 +01:00
Returns:
---------------------------------------------------------------------- */
2001-05-29 20:22:49 +02:00
#if defined(__USER_daveo__) || defined(__USER_paul__)
2001-05-09 19:30:40 +02:00
int invincibleSponge=true; // NB: This is for debugging purposes only so don't try and use it for a permenant cheat mode..
#else
2001-02-12 18:55:01 +01:00
int invincibleSponge=false; // NB: This is for debugging purposes only so don't try and use it for a permenant cheat mode..
2001-05-09 19:30:40 +02:00
#endif
2001-05-11 21:49:41 +02:00
void CPlayer::takeDamage(DAMAGE_TYPE _damage,REACT_DIRECTION _reactDirection,CThing *_thing)
2001-02-06 22:09:45 +01:00
{
2001-05-15 00:08:19 +02:00
if(m_invincibleFrameCount==0&& // Don't take damage if still recovering from the last hit
m_invincibilityRingTimer==0&& // Or if we have the invincibility ring on
m_currentPlayerModeClass->getState()!=STATE_SOAKUP&& // Or soaking up
m_currentMode!=PLAYER_MODE_DEAD) // Or already dead! :)
2001-02-06 22:09:45 +01:00
{
int ouchThatHurt=true;
2001-05-10 21:54:07 +02:00
int ouchThatHurtSoMuchThatImJustGoingToDieNow=false;
2001-02-06 22:09:45 +01:00
// Check if we are currently immune to this damage type
switch(_damage)
{
2001-03-05 22:11:51 +01:00
case DAMAGE__NONE:
2001-05-10 22:27:33 +02:00
ouchThatHurt=false;
2001-03-05 22:11:51 +01:00
break;
2001-04-18 22:31:14 +02:00
case DAMAGE__ELECTROCUTION:
case DAMAGE__SHOCK_ENEMY:
2001-06-07 22:55:45 +02:00
if(isWearingBoots())
2001-04-18 22:31:14 +02:00
{
ouchThatHurt=false;
}
break;
2001-02-06 22:09:45 +01:00
case DAMAGE__FALL:
case DAMAGE__LAVA:
2001-02-27 17:59:50 +01:00
case DAMAGE__HIT_ENEMY:
2001-03-05 22:11:51 +01:00
case DAMAGE__GAS_ENEMY:
case DAMAGE__POISON_ENEMY:
case DAMAGE__SWALLOW_ENEMY:
case DAMAGE__PINCH_ENEMY:
case DAMAGE__SQUASH_ENEMY:
case DAMAGE__BURN_ENEMY:
case DAMAGE__BITE_ENEMY:
2001-05-14 19:04:13 +02:00
case DAMAGE__COLLISION_DAMAGE:
2001-02-06 22:09:45 +01:00
break;
2001-05-10 21:54:07 +02:00
case DAMAGE__KILL_OUTRIGHT:
ouchThatHurt=ouchThatHurtSoMuchThatImJustGoingToDieNow=true;
break;
2001-02-06 22:09:45 +01:00
}
if(ouchThatHurt)
{
2001-05-04 01:45:28 +02:00
int died=false;
2001-05-11 21:49:41 +02:00
if(invincibleSponge)
2001-02-06 22:09:45 +01:00
{
2001-05-11 21:49:41 +02:00
m_invincibleFrameCount=INVINCIBLE_FRAMES__HIT;
2001-05-04 01:45:28 +02:00
}
else
{
2001-06-14 17:19:57 +02:00
if(ouchThatHurtSoMuchThatImJustGoingToDieNow||(getSpatulasHeld()==0&&m_currentMode!=PLAYER_MODE_NET))
2001-05-10 21:54:07 +02:00
{
2001-06-14 17:19:57 +02:00
died=true;
2001-05-10 21:54:07 +02:00
}
else
{
2001-06-14 17:19:57 +02:00
if(m_currentMode==PLAYER_MODE_NET)
2001-05-11 21:49:41 +02:00
{
2001-06-14 17:19:57 +02:00
// Launch net pickup
2001-06-14 20:14:36 +02:00
setMode(PLAYER_MODE_FULLUNARMED);
2001-06-15 20:05:56 +02:00
DVECTOR pickupPos;
CBasePickup *pickup;
pickupPos.vx=Pos.vx;
pickupPos.vy=Pos.vy-30;
pickup=createPickup(PICKUP__NET,&pickupPos);
pickup->setPos(&pickupPos);
2001-05-11 21:49:41 +02:00
}
else
{
2001-06-14 17:19:57 +02:00
// Launch all spatulas!
2001-06-15 00:03:03 +02:00
GameScene.dropHealth(Pos,m_numSpatulasHeld,1);
2001-06-14 17:19:57 +02:00
m_numSpatulasHeld=0;
2001-05-11 21:49:41 +02:00
}
2001-05-04 01:45:28 +02:00
}
}
if(died)
{
2001-05-17 23:18:35 +02:00
DEATH_TYPE deathType;
switch(_damage)
{
case DAMAGE__SQUASH_ENEMY:
deathType=DEATHTYPE__SQUASH;
break;
default:
deathType=DEATHTYPE__NORMAL;
break;
}
dieYouPorousFreak(deathType);
2001-02-06 22:09:45 +01:00
}
else
{
2001-06-12 15:59:32 +02:00
CThing *platform;
platform=isOnPlatform();
if(platform)
{
if ( ( (CNpcPlatform *) platform )->isCart() )
{
m_invincibleFrameCount=INVINCIBLE_FRAMES__HIT;
return;
}
}
2001-05-11 21:49:41 +02:00
if(_reactDirection!=REACT__NO_REACTION)
{
if(_reactDirection==REACT__GET_DIRECTION_FROM_THING)
{
ASSERT(_thing);
if(Pos.vx<_thing->getPos().vx)
{
_reactDirection=REACT__LEFT;
}
else
{
_reactDirection=REACT__RIGHT;
}
}
m_moveVelocity.vx=((int)_reactDirection);
switch(_reactDirection)
{
case REACT__LEFT:
setFacing(FACING_RIGHT);
break;
case REACT__RIGHT:
setFacing(FACING_LEFT);
break;
case REACT__UP:
case REACT__GET_DIRECTION_FROM_THING:
case REACT__NO_REACTION:
break;
}
m_currentPlayerModeClass->setState(STATE_JUMPBACK);
}
2001-05-04 01:45:28 +02:00
m_invincibleFrameCount=INVINCIBLE_FRAMES__HIT;
2001-02-06 22:09:45 +01:00
}
}
}
2001-01-20 00:37:40 +01:00
}
2001-05-04 01:45:28 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-05-17 20:42:59 +02:00
void CPlayer::dieYouPorousFreak(DEATH_TYPE _deathType)
2001-05-04 01:45:28 +02:00
{
ASSERT(m_currentMode!=PLAYER_MODE_DEAD);
2001-05-17 20:42:59 +02:00
m_deathType=_deathType;
2001-05-04 01:45:28 +02:00
CSoundMediator::playSfx(CSoundMediator::SFX_SPONGEBOB_DEFEATED_JINGLE);
setMode(PLAYER_MODE_DEAD);
}
2001-01-15 23:09:47 +01:00
2001-01-29 23:35:18 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::updatePadInput()
{
m_lastPadInput=m_padInput;
m_padInput=readPadInput();
2001-02-09 18:01:04 +01:00
m_padInputDown=(PLAYERINPUT)(m_padInput&(m_lastPadInput^-1));
2001-01-29 23:35:18 +01:00
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-02-09 18:01:04 +01:00
PLAYERINPUT CPlayer::readPadInput()
2001-01-29 23:35:18 +01:00
{
2001-02-09 18:01:04 +01:00
PLAYERINPUT input;
int pad;
input=PI_NONE;
pad=PadGetHeld(0);
2001-05-21 16:22:26 +02:00
2001-02-09 18:01:04 +01:00
if(pad&CPadConfig::getButton(CPadConfig::PAD_CFG_UP))
{
input=(PLAYERINPUT)(input|PI_UP);
}
if(pad&CPadConfig::getButton(CPadConfig::PAD_CFG_DOWN))
{
input=(PLAYERINPUT)(input|PI_DOWN);
}
if(pad&CPadConfig::getButton(CPadConfig::PAD_CFG_LEFT))
{
input=(PLAYERINPUT)(input|PI_LEFT);
}
if(pad&CPadConfig::getButton(CPadConfig::PAD_CFG_RIGHT))
{
input=(PLAYERINPUT)(input|PI_RIGHT);
}
if(pad&CPadConfig::getButton(CPadConfig::PAD_CFG_JUMP))
{
input=(PLAYERINPUT)(input|PI_JUMP);
}
2001-05-10 00:12:00 +02:00
if(pad&CPadConfig::getButton(CPadConfig::PAD_CFG_FIRE))
2001-02-09 18:01:04 +01:00
{
2001-05-10 00:12:00 +02:00
input=(PLAYERINPUT)(input|PI_FIRE);
}
if(pad&CPadConfig::getButton(CPadConfig::PAD_CFG_CATCH))
{
input=(PLAYERINPUT)(input|PI_CATCH);
2001-02-09 18:01:04 +01:00
}
2001-05-18 23:03:51 +02:00
if(pad&CPadConfig::getButton(CPadConfig::PAD_CFG_WEAPONCHANGE))
{
input=(PLAYERINPUT)(input|PI_WEAPONCHANGE);
}
2001-02-09 18:01:04 +01:00
#ifdef _RECORD_DEMO_MODE_
CDemoPlayer::demoPlayerControl *crnt;
PLAYERINPUT lastInput;
crnt=&s_demoControls[s_demoSize];
if(s_demoFrameCount==0)
{
crnt->m_inputValue=input;
}
lastInput=(PLAYERINPUT)crnt->m_inputValue;
if(crnt->m_length==255)
{
lastInput=(PLAYERINPUT)(input-1);
}
if(lastInput==input)
{
crnt->m_length++;
}
else
{
s_demoSize++;
ASSERT(s_demoSize<MAX_DEMO_SIZE);
crnt++;
crnt->m_inputValue=input;
crnt->m_length=1;
}
s_demoFrameCount++;
2001-03-05 16:08:50 +01:00
if(s_demoFrameCount==MAX_DEMO_TIME_IN_FRAMES)
2001-02-09 18:01:04 +01:00
{
writeDemoControls();
ASSERT(!"DEMO ENDED");
}
#endif
return input;
2001-01-29 23:35:18 +01:00
}
2001-05-11 22:56:43 +02:00
2001-05-29 16:51:59 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::giveJellyFishAmmo(u32 _colour)
{
ASSERT(!isJellyFishAmmoFull());
m_jellyfishAmmoColours[m_jellyfishAmmoCount]=_colour;
m_jellyfishAmmoCount++;
}
void CPlayer::useOneJellyFishAmmo()
{
ASSERT(m_jellyfishAmmoCount!=0);
int i;
m_jellyfishAmmoCount--;
for(i=0;i<m_jellyfishAmmoCount;i++)
{
m_jellyfishAmmoColours[i]=m_jellyfishAmmoColours[i+1];
}
}
int CPlayer::isJellyFishAmmoFull()
{
return m_jellyfishAmmoCount==MAX_JELLFISH_IN_NET;
}
int CPlayer::getJellyFishAmmo()
{
return m_jellyfishAmmoCount;
}
u32 CPlayer::getColourOfNextJellyfishAmmo()
{
ASSERT(m_jellyfishAmmoCount!=0);
return m_jellyfishAmmoColours[0];
}
2001-05-11 22:56:43 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::justButtBouncedABadGuy()
{
2001-06-01 20:59:33 +02:00
CSoundMediator::playSfx(CSoundMediator::SFX_SPONGEBOB_BUTTBOUNCE);
2001-05-11 22:56:43 +02:00
m_currentPlayerModeClass->setState(STATE_BUTTBOUNCEUP);
}
2001-03-08 21:12:47 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-04-11 22:59:16 +02:00
void CPlayer::shove( DVECTOR move )
2001-03-08 21:12:47 +01:00
{
2001-03-29 21:19:33 +02:00
int colHeight;
// X movement
2001-05-25 20:43:47 +02:00
colHeight=CGameScene::getCollision()->getHeightFromGround(Pos.vx+move.vx,Pos.vy,5);
2001-03-29 21:19:33 +02:00
if(colHeight<0)
{
// Stop at the edge of the obstruction
int dir,vx,cx,i;
if(move.vx<0)
{
dir=-1;
vx=move.vx;
}
else
{
dir=+1;
vx=move.vx;
}
cx=Pos.vx;
for(i=0;i<vx;i++)
{
2001-05-25 20:43:47 +02:00
if(CGameScene::getCollision()->getHeightFromGround(cx,Pos.vy)<0)
2001-03-29 21:19:33 +02:00
{
break;
}
cx+=dir;
}
2001-04-03 22:26:21 +02:00
if(i)
Pos.vx=cx-dir;
2001-03-29 21:19:33 +02:00
}
else
{
// No obstruction
Pos.vx+=move.vx;
}
// Y movement
2001-05-25 20:43:47 +02:00
colHeight=CGameScene::getCollision()->getHeightFromGround(Pos.vx,Pos.vy+move.vy,5);
2001-03-29 21:19:33 +02:00
if(colHeight<0)
{
// Stop at the edge of the obstruction
int dir,vy,cy,i;
if(move.vy<0)
{
dir=-1;
vy=move.vy;
}
else
{
dir=+1;
vy=move.vy;
}
cy=Pos.vy;
for(i=0;i<vy;i++)
{
2001-05-25 20:43:47 +02:00
if(CGameScene::getCollision()->getHeightFromGround(Pos.vx,cy)<0)
2001-03-29 21:19:33 +02:00
{
break;
}
cy+=dir;
}
2001-04-03 22:26:21 +02:00
if(i)
Pos.vy=cy-dir;
2001-03-29 21:19:33 +02:00
}
else
{
// No obstruction
Pos.vy+=move.vy;
}
2001-04-11 22:59:16 +02:00
}
2001-03-29 21:19:33 +02:00
2001-05-13 21:28:48 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::moveLeft()
{
2001-05-14 17:15:20 +02:00
if(m_moveVelocity.vx<-CAMERA_STARTMOVETHRESHOLD||m_cameraXScrollPos<-(CAMERA_SCROLLTHRESHOLD*CAMERA_TILESIZE)<<CAMERA_ACCURACYSHIFT)
2001-05-13 21:28:48 +02:00
{
m_cameraXScrollDir=+1;
}
else if(m_moveVelocity.vx>-CAMERA_STOPMOVETHRESHOLD)
{
m_cameraXScrollDir=0;
}
}
void CPlayer::moveRight()
{
2001-05-14 17:15:20 +02:00
if(m_moveVelocity.vx>CAMERA_STARTMOVETHRESHOLD||m_cameraXScrollPos>(CAMERA_SCROLLTHRESHOLD*CAMERA_TILESIZE)<<CAMERA_ACCURACYSHIFT)
2001-05-13 21:28:48 +02:00
{
m_cameraXScrollDir=-1;
}
else if(m_moveVelocity.vx<CAMERA_STOPMOVETHRESHOLD)
{
m_cameraXScrollDir=0;
}
}
2001-05-24 22:00:19 +02:00
void CPlayer::fall()
{
m_isFalling=true;
}
void CPlayer::buttFall()
{
m_cameraFallYScrollSpeed=CAMERA_FALL_DROP_SPEED;
m_isFalling=true;
}
2001-05-13 21:28:48 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-03-29 21:19:33 +02:00
void CPlayer::setPlatform(CThing *_newPlatform)
{
m_platform=_newPlatform;
}
void CPlayer::clearPlatform()
{
m_platform=NULL;
}
2001-03-31 00:43:35 +02:00
void CPlayer::setHasPlatformCollided( bool newVal )
{
m_hasPlatformCollided = newVal;
}
bool CPlayer::getHasPlatformCollided()
{
return( m_hasPlatformCollided );
}
2001-03-29 21:19:33 +02:00
2001-03-06 21:13:16 +01:00
2001-04-25 20:38:33 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int CPlayer::moveVertical(int _moveDistance)
{
DVECTOR pos;
int hitGround;
pos=Pos;
hitGround=false;
// Are we falling?
if(_moveDistance>0)
{
int colHeightBefore,colHeightAfter;
2001-05-10 16:35:35 +02:00
// Yes.. Check to see if we're about to hit/go through the ground/platform
2001-05-10 21:22:34 +02:00
colHeightBefore=getHeightFromGround(pos.vx,pos.vy,16);
colHeightAfter=getHeightFromGround(pos.vx,pos.vy+_moveDistance,16);
if(isOnPlatform()&&
!(colHeightBefore>=0&&colHeightAfter<=0))
2001-05-10 16:35:35 +02:00
{
colHeightBefore=getHeightFromPlatformNoGround(pos.vx,pos.vy,16);
colHeightAfter=getHeightFromPlatformNoGround(pos.vx,pos.vy+_moveDistance,16);
}
2001-04-25 20:38:33 +02:00
if(colHeightBefore>=0&&colHeightAfter<=0)
{
2001-05-04 23:19:00 +02:00
// About to hit a 'fall to death' block?
2001-05-30 19:07:26 +02:00
if((CGameScene::getCollision()->getCollisionBlock(pos.vx,pos.vy+_moveDistance)&COLLISION_TYPE_MASK)!=COLLISION_TYPE_FLAG_DEATH_FALL)
2001-05-04 23:19:00 +02:00
{
2001-05-10 16:35:35 +02:00
// No
2001-05-04 23:19:00 +02:00
// Stick at ground level
pos.vy+=colHeightAfter+_moveDistance;
_moveDistance=0;
hitGround=true;
}
else
{
2001-05-10 16:35:35 +02:00
// Yeah!
2001-05-04 23:19:00 +02:00
if(m_currentMode!=PLAYER_MODE_DEAD)
{
// Lock the camera, kill the player and let him fall to his death..
setMode(PLAYER_MODE_DEAD);
m_lockCamera=true;
}
}
2001-04-25 20:38:33 +02:00
}
}
2001-05-14 19:04:13 +02:00
else if(_moveDistance<0)
2001-04-25 20:38:33 +02:00
{
// Are we jumping into an impassable block?
2001-05-25 20:43:47 +02:00
if((CGameScene::getCollision()->getCollisionBlock(pos.vx,pos.vy+_moveDistance)&COLLISION_TYPE_MASK)!=COLLISION_TYPE_FLAG_NORMAL&&
2001-04-27 04:05:05 +02:00
getHeightFromGround(pos.vx,pos.vy+_moveDistance)<=0)
2001-04-25 20:38:33 +02:00
{
pos.vy=(pos.vy&0xfff0);
_moveDistance=0;
hitGround=true;
}
2001-06-07 21:40:41 +02:00
else if((CGameScene::getCollision()->getCollisionBlock(pos.vx,pos.vy+_moveDistance-HEIGHT_FOR_HEAD_COLLISION)&COLLISION_TYPE_MASK)!=COLLISION_TYPE_FLAG_NORMAL&&
getHeightFromGround(pos.vx,pos.vy+_moveDistance-HEIGHT_FOR_HEAD_COLLISION)<=0)
{
2001-06-14 23:12:48 +02:00
switch(CGameScene::getCollision()->getCollisionBlock(pos.vx,pos.vy+_moveDistance-HEIGHT_FOR_HEAD_COLLISION)&COLLISION_TYPE_MASK)
{
case COLLISION_TYPE_FLAG_DAMAGE:
takeDamage(DAMAGE__COLLISION_DAMAGE);
break;
case COLLISION_TYPE_FLAG_ELECTRIC:
if(!isWearingBoots())
{
takeDamage(DAMAGE__COLLISION_DAMAGE);
}
break;
default:
break;
}
2001-06-07 21:40:41 +02:00
pos.vy=((pos.vy+_moveDistance)&0xfff0);
_moveDistance=0;
hitGround=true;
}
2001-04-25 20:38:33 +02:00
}
2001-05-14 19:04:13 +02:00
else
{
// Stood on any important types of collision?
2001-05-25 20:43:47 +02:00
switch(CGameScene::getCollision()->getCollisionBlock(pos.vx,pos.vy+_moveDistance)&COLLISION_TYPE_MASK)
2001-05-14 19:04:13 +02:00
{
2001-05-15 00:08:19 +02:00
case COLLISION_TYPE_FLAG_DAMAGE:
takeDamage(DAMAGE__COLLISION_DAMAGE);
break;
2001-06-01 22:16:23 +02:00
case COLLISION_TYPE_FLAG_ELECTRIC:
if(!isWearingBoots())
{
takeDamage(DAMAGE__COLLISION_DAMAGE);
}
break;
2001-05-15 00:08:19 +02:00
default:
break;
2001-05-14 19:04:13 +02:00
}
}
2001-04-25 20:38:33 +02:00
pos.vy+=_moveDistance;
setPlayerPos(&pos);
return hitGround;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int CPlayer::moveHorizontal(int _moveDistance)
{
int hitWall;
hitWall=false;
if(_moveDistance)
{
2001-05-25 20:43:47 +02:00
CLayerCollision *collision=CGameScene::getCollision();
2001-04-25 20:38:33 +02:00
DVECTOR pos;
int colHeight;
pos=getPlayerPos();
colHeight=getHeightFromGround(pos.vx,pos.vy,5);
if(colHeight==0)
{
// Ok.. we're on the ground. What happens if we move left/right
colHeight=getHeightFromGround(pos.vx+_moveDistance,pos.vy);
if(colHeight<-8)
{
// Big step up. Stop at the edge of the obstruction
int dir,vx,cx,i;
if(_moveDistance<0)
{
dir=-1;
vx=-_moveDistance;
}
else
{
dir=+1;
vx=_moveDistance;
}
cx=pos.vx;
for(i=0;i<vx;i++)
{
if(getHeightFromGround(cx,pos.vy)<-8)
{
break;
}
cx+=dir;
}
if(i)
pos.vx=cx-dir;
hitWall=true;
_moveDistance=0;
2001-05-21 16:22:26 +02:00
2001-04-25 20:38:33 +02:00
// Get the height at this new position and then try the step-up code below.
// Without this, there are problems when you run up a slope and hit a wall at the same time
colHeight=getHeightFromGround(pos.vx,pos.vy);
}
if(colHeight&&colHeight>=-8&&colHeight<=8)
{
// Small step up/down. Follow the contour of the level
pos.vy+=colHeight;
}
}
2001-04-27 04:05:05 +02:00
else if(colHeight>0) // Lets you jump through platforms from below
2001-04-25 20:38:33 +02:00
{
2001-05-25 20:43:47 +02:00
if((CGameScene::getCollision()->getCollisionBlock(pos.vx+_moveDistance,pos.vy)&COLLISION_TYPE_MASK)!=COLLISION_TYPE_FLAG_NORMAL&&
2001-04-27 04:05:05 +02:00
getHeightFromGround(pos.vx+_moveDistance,pos.vy,5)<0)
2001-04-25 20:38:33 +02:00
{
2001-04-27 04:05:05 +02:00
// Stop at the edge of the obstruction
int dir,vx,cx,i;
if(_moveDistance<0)
{
dir=-1;
vx=-_moveDistance;
}
else
2001-04-25 20:38:33 +02:00
{
2001-04-27 04:05:05 +02:00
dir=+1;
vx=_moveDistance;
2001-04-25 20:38:33 +02:00
}
2001-04-27 04:05:05 +02:00
cx=pos.vx;
for(i=0;i<vx;i++)
2001-04-25 20:38:33 +02:00
{
2001-04-27 04:05:05 +02:00
if(getHeightFromGround(cx,pos.vy)<0)
2001-04-25 20:38:33 +02:00
{
2001-04-27 04:05:05 +02:00
break;
2001-04-25 20:38:33 +02:00
}
2001-04-27 04:05:05 +02:00
cx+=dir;
2001-04-25 20:38:33 +02:00
}
2001-04-27 04:05:05 +02:00
if(i)
cx-=dir;
pos.vx=cx;
_moveDistance=0;
2001-04-25 20:38:33 +02:00
}
}
pos.vx+=_moveDistance;
setPlayerPos(&pos);
}
2001-05-21 16:22:26 +02:00
2001-04-25 20:38:33 +02:00
return hitWall;
}
2001-04-18 18:35:26 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::resetPlayerCollisionSizeToBase()
{
setPlayerCollisionSize(0,-COLSIZE_BASE_HEIGHT/2,COLSIZE_BASE_WIDTH,COLSIZE_BASE_HEIGHT);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::setPlayerCollisionSize(int _x,int _y,int _w,int _h)
{
setCollisionSize(_w,_h);
setCollisionCentreOffset(_x,_y);
}
2001-05-01 22:23:32 +02:00
void CPlayer::getPlayerCollisionSize(int *_x,int *_y,int *_w,int *_h)
{
DVECTOR offset,size;
offset=getCollisionCentreOffset();
size=getCollisionSize();
*_x=offset.vx;
*_y=offset.vy;
*_w=size.vx;
*_h=size.vy;
}
2001-04-18 18:35:26 +02:00
2001-01-16 20:27:14 +01:00
/*===========================================================================
2001-05-21 16:22:26 +02:00
end */