SBSPSS/source/player/player.cpp

3034 lines
76 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
-------- */
2001-06-21 21:19:15 +02:00
#include "system\vid.h"
2001-01-16 20:27:14 +01:00
#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-06-28 21:14:44 +02:00
#ifndef __PAD_VIBE_H__
#include "pad\vibe.h"
#endif
2001-07-04 18:27:35 +02:00
#ifndef __GAME_GAME_H__
#include "game\game.h"
#endif
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-07-03 22:49:30 +02:00
#ifndef __PLAYER_PMSWAL_H__
#include "player\pmswal.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-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-07-18 16:54:16 +02:00
#ifndef __GAME_CONVO_H__
#include "game\convo.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-08-04 21:16:11 +02:00
#ifdef __VERSION_DEBUG__
2001-02-09 18:01:04 +01:00
//#define _RECORD_DEMO_MODE_
2001-02-09 22:41:55 +01:00
#define _STATE_DEBUG_
2001-08-04 21:16:11 +02:00
#endif
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-07-03 22:49:30 +02:00
"SWALLOW",
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 m_cameraLookOffset;
2001-02-08 17:51:16 +01:00
2001-06-21 21:19:15 +02:00
int MAP2D_CENTRE_X=-(INGAME_SCREENW/2);
2001-07-12 17:44:51 +02:00
int MAP2D_CENTRE_Y=-(INGAME_SCREENH/2)-32;
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-07-03 22:49:30 +02:00
CPlayerModeSwallow PLAYERMODESWALLOW;
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-07-03 22:49:30 +02:00
&PLAYERMODESWALLOW, // PLAYER_MODE_SWALLOW
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;
2001-07-12 17:44:51 +02:00
pint lookmaxoffsetup=4*MAP2D_BLOCKSTEPSIZE;
pint lookmaxoffsetdown=4*MAP2D_BLOCKSTEPSIZE;
2001-04-18 18:35:26 +02:00
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-07-03 22:49:30 +02:00
NO_ADDON, // PLAYER_MODE_SWALLOW
2001-04-30 23:27:46 +02:00
};
2001-06-25 22:25:28 +02:00
s8 s_animMapNet[NUM_PLAYER_ADDONS][NUM_ANIM_SPONGEBOB]=
2001-04-30 23:27:46 +02:00
{
// 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_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,
-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,
2001-06-21 22:51:55 +02:00
ANIM_SPONGEBOB_NET_IDLEWEAPON, // ANIM_SPONGEBOB_IDLEWEAPON,
2001-04-30 23:27:46 +02:00
-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-19 17:23:50 +02:00
ANIM_SPONGEBOB_NET_LOOKUP, // ANIM_SPONGEBOB_LOOKUP
2001-07-27 16:43:39 +02:00
-1, // ANIM_SPONGEBOB_IDLEFACEUPSIDEDOWN
-1, // ANIM_SPONGEBOB_IDLEBANDAID,
2001-07-03 01:50:22 +02:00
//NOIDLE -1, // ANIM_SPONGEBOB_IDLEINHAT,
2001-07-27 16:43:39 +02:00
-1, // ANIM_SPONGEBOB_IDLEMATURE,
-1, // ANIM_SPONGEBOB_IDLEMOUSTACHE,
-1, // ANIM_SPONGEBOB_IDLENOFACE,
-1, // ANIM_SPONGEBOB_IDLEZORRO,
2001-07-24 00:55:50 +02:00
ANIM_SPONGEBOB_NET_CELEBRATE, // ANIM_SPONGEBOB_CELEBRATE,
2001-08-13 23:25:06 +02:00
ANIM_SPONGEBOB_NET_IDLEBLINK, // ANIM_SPONGEBOB_IDLEBLINK,
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,
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,
-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-19 17:23:50 +02:00
ANIM_SPONGEBOB_CORALBLOWER_LOOKUP, // ANIM_SPONGEBOB_LOOKUP
2001-07-27 16:43:39 +02:00
-1, // ANIM_SPONGEBOB_IDLEFACEUPSIDEDOWN
-1, // ANIM_SPONGEBOB_IDLEBANDAID,
2001-07-03 01:50:22 +02:00
//NOIDLE -1, // ANIM_SPONGEBOB_IDLEINHAT,
2001-07-27 16:43:39 +02:00
-1, // ANIM_SPONGEBOB_IDLEMATURE,
-1, // ANIM_SPONGEBOB_IDLEMOUSTACHE,
-1, // ANIM_SPONGEBOB_IDLENOFACE,
-1, // ANIM_SPONGEBOB_IDLEZORRO,
2001-07-24 00:55:50 +02:00
ANIM_SPONGEBOB_CORALBLOWER_CELEBRATE, // ANIM_SPONGEBOB_CELEBRATE,
2001-08-13 23:25:06 +02:00
ANIM_SPONGEBOB_CORALBLOWER_IDLEBLINK, // ANIM_SPONGEBOB_IDLEBLINK,
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_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,
-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,
2001-07-12 21:55:16 +02:00
ANIM_SPONGEBOB_JELLYLAUNCHER_IDLEWEAPON, // ANIM_SPONGEBOB_IDLEWEAPON,
2001-04-30 23:27:46 +02:00
-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-19 17:23:50 +02:00
ANIM_SPONGEBOB_JELLYLAUNCHER_LOOKUP, // ANIM_SPONGEBOB_LOOKUP
2001-07-27 16:43:39 +02:00
-1, // ANIM_SPONGEBOB_IDLEFACEUPSIDEDOWN
-1, // ANIM_SPONGEBOB_IDLEBANDAID,
2001-07-03 01:50:22 +02:00
//NOIDLE -1, // ANIM_SPONGEBOB_IDLEINHAT,
2001-07-27 16:43:39 +02:00
-1, // ANIM_SPONGEBOB_IDLEMATURE,
-1, // ANIM_SPONGEBOB_IDLEMOUSTACHE,
-1, // ANIM_SPONGEBOB_IDLENOFACE,
-1, // ANIM_SPONGEBOB_IDLEZORRO,
2001-07-24 00:55:50 +02:00
ANIM_SPONGEBOB_JELLYLAUNCHER_CELEBRATE, // ANIM_SPONGEBOB_CELEBRATE,
2001-08-13 23:25:06 +02:00
ANIM_SPONGEBOB_JELLYLAUNCHER_IDLEBLINK, // ANIM_SPONGEBOB_IDLEBLINK,
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,
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,
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,
2001-07-25 16:36:36 +02:00
ANIM_SPONGEBOB_WAND_IDLEWEAPON, // ANIM_SPONGEBOB_IDLEWEAPON,
2001-05-25 22:10:19 +02:00
-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-19 17:23:50 +02:00
ANIM_SPONGEBOB_WAND_LOOKUP, // ANIM_SPONGEBOB_LOOKUP
2001-07-27 16:43:39 +02:00
-1, // ANIM_SPONGEBOB_IDLEFACEUPSIDEDOWN
-1, // ANIM_SPONGEBOB_IDLEBANDAID,
2001-07-03 01:50:22 +02:00
//NOIDLE -1, // ANIM_SPONGEBOB_IDLEINHAT,
2001-07-27 16:43:39 +02:00
-1, // ANIM_SPONGEBOB_IDLEMATURE,
-1, // ANIM_SPONGEBOB_IDLEMOUSTACHE,
-1, // ANIM_SPONGEBOB_IDLENOFACE,
-1, // ANIM_SPONGEBOB_IDLEZORRO,
2001-07-24 00:55:50 +02:00
ANIM_SPONGEBOB_WAND_CELEBRATE, // ANIM_SPONGEBOB_CELEBRATE,
2001-08-13 23:25:06 +02:00
ANIM_SPONGEBOB_WAND_IDLEBLINK, // ANIM_SPONGEBOB_IDLEBLINK,
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_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,
-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,
2001-06-25 22:25:28 +02:00
ANIM_SPONGEBOB_JELLYFISH_IDLEWEAPON, // ANIM_SPONGEBOB_IDLEWEAPON,
2001-05-10 16:35:35 +02:00
-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-19 17:23:50 +02:00
ANIM_SPONGEBOB_JELLYFISH_LOOKUP, // ANIM_SPONGEBOB_LOOKUP
2001-07-27 16:43:39 +02:00
-1, // ANIM_SPONGEBOB_IDLEFACEUPSIDEDOWN
-1, // ANIM_SPONGEBOB_IDLEBANDAID,
2001-07-03 01:50:22 +02:00
//NOIDLE -1, // ANIM_SPONGEBOB_IDLEINHAT,
2001-07-27 16:43:39 +02:00
-1, // ANIM_SPONGEBOB_IDLEMATURE,
-1, // ANIM_SPONGEBOB_IDLEMOUSTACHE,
-1, // ANIM_SPONGEBOB_IDLENOFACE,
-1, // ANIM_SPONGEBOB_IDLEZORRO,
2001-07-24 00:55:50 +02:00
ANIM_SPONGEBOB_JELLYFISH_CELEBRATE, // ANIM_SPONGEBOB_CELEBRATE,
2001-08-13 23:25:06 +02:00
ANIM_SPONGEBOB_JELLYFISH_IDLEBLINK, // ANIM_SPONGEBOB_IDLEBLINK,
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_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,
-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
2001-07-27 16:43:39 +02:00
-1, // ANIM_SPONGEBOB_IDLEFACEUPSIDEDOWN
-1, // ANIM_SPONGEBOB_IDLEBANDAID,
2001-07-03 01:50:22 +02:00
//NOIDLE -1, // ANIM_SPONGEBOB_IDLEINHAT,
2001-07-27 16:43:39 +02:00
-1, // ANIM_SPONGEBOB_IDLEMATURE,
-1, // ANIM_SPONGEBOB_IDLEMOUSTACHE,
-1, // ANIM_SPONGEBOB_IDLENOFACE,
-1, // ANIM_SPONGEBOB_IDLEZORRO,
2001-07-02 22:15:14 +02:00
-1, // ANIM_SPONGEBOB_CELEBRATE,
2001-08-13 23:25:06 +02:00
-1, // ANIM_SPONGEBOB_IDLEBLINK,
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;
2001-07-17 23:04:20 +02:00
int CAMERA_SCROLLLIMIT=8; // SB is this many tiles off centre at most
int CAMERA_SCROLLTHRESHOLD=0; // (pkg 17/7) // If SB moves when more than this many tiles off-centre, the camera will *always* scroll
2001-07-18 00:05:23 +02:00
int CAMERA_STARTMOVETHRESHOLD=0; // (pkg 17/7) // If SB moves faster than this then the camera starts scrolling
2001-07-17 23:04:20 +02:00
int CAMERA_STOPMOVETHRESHOLD=0; // (pkg 17/7) // If SB moves slower than this then the camera stops scrolling
int CAMERA_SCROLLSPEED=1000; // Speed of the scroll
2001-05-13 21:28:48 +02:00
int CAMERA_ACCURACYSHIFT=8;
const int CAMERA_TILESIZE=16;
2001-07-17 23:04:20 +02:00
// Well, there goes any chance of refined camera control for the player! :( ( pkg 17/7 )
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;
2001-08-14 00:14:12 +02:00
int CAMERA_FALL_MAX_OFFSET=4*16;
2001-05-24 22:00:19 +02:00
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-07-20 21:36:18 +02:00
extern int checkx;
extern int checky;
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-06-22 18:22:03 +02:00
m_scalableFontBank=new ("PlayerFont") ScalableFontBank();
m_scalableFontBank->initialise(&standardFont);
m_scalableFontBank->setOt(POWERUPUI_OT);
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;
2001-06-27 21:50:35 +02:00
m_lastModeBeforeDeath=PLAYER_MODE_BASICUNARMED; // Player will then respawn into this mode
2001-07-10 20:15:12 +02:00
respawn();
2001-01-20 00:37:40 +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-07-21 20:39:43 +02:00
setCartCam(false);
2001-07-21 21:14:40 +02:00
setReverseCameraMovement(false);
2001-02-08 17:51:16 +01:00
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-16 18:47:29 +02:00
#ifdef __USER_paul__
2001-07-30 02:35:24 +02:00
/*
2001-07-03 23:51:16 +02:00
registerAddon(PLAYER_ADDON_GLOVE);
2001-05-16 18:47:29 +02:00
registerAddon(PLAYER_ADDON_NET);
registerAddon(PLAYER_ADDON_CORALBLOWER);
registerAddon(PLAYER_ADDON_JELLYLAUNCHER);
registerAddon(PLAYER_ADDON_BUBBLEWAND);
registerAddon(PLAYER_ADDON_JELLYFISHINNET);
2001-07-30 02:35:24 +02:00
*/
2001-05-16 18:47:29 +02:00
#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-06-22 18:22:03 +02:00
m_scalableFontBank->dump(); delete m_scalableFontBank;
m_fontBank->dump(); delete m_fontBank;
2001-03-31 20:22:38 +02:00
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-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-07-16 22:25:19 +02:00
if ( ( (CNpcPlatform *) platform )->isCart() )
2001-05-25 22:45:03 +02:00
{
2001-07-16 22:25:19 +02:00
if ( m_currentMode != PLAYER_MODE_CART && m_currentMode != PLAYER_MODE_DEAD )
2001-06-12 18:28:39 +02:00
{
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);
2001-08-10 17:39:05 +02:00
// Hmm.. this *almost* stops him elevating through walls :/
2001-06-12 01:12:58 +02:00
if ( platformOffset < height )
{
2001-08-10 17:39:05 +02:00
int goingToHitWall=false;
int i;
for(i=0;i<2;i++)
{
int x=Pos.vx+((i==0?-checkx:+checkx));
int y=Pos.vy-HEIGHT_FOR_HEAD_COLLISION;
if(getHeightFromGroundNoPlatform(x,y,16)>=0&&getHeightFromGroundNoPlatform(x,y+platformOffset,16)<=0&&((CGameScene::getCollision()->getCollisionBlock(x,y+platformOffset)&COLLISION_TYPE_MASK)!=COLLISION_TYPE_FLAG_NORMAL))
{
goingToHitWall=true;
break;
}
}
if(!goingToHitWall)
{
Pos.vy += platformOffset;
}
2001-06-12 01:12:58 +02:00
}
}
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-06-08 17:02:29 +02:00
m_xMove = Pos.vx;
2001-08-13 18:31:14 +02:00
m_moveLeftRight = 0;
2001-06-08 17:02:29 +02:00
2001-06-10 18:51:21 +02:00
///
#ifdef __USER_paul__
2001-07-27 17:19:36 +02:00
//if(PadGetDown(0)&PAD_TRIANGLE)
//{
// addLife();
//}
2001-06-10 18:51:21 +02:00
#endif
///
2001-07-21 21:14:40 +02:00
2001-08-08 18:54:00 +02:00
// Pending teleport?
if(m_teleportPending)
{
processTeleportToCommand();
}
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
2001-07-16 21:06:30 +02:00
// Only do the weapon change stuff on the first frame. As the buttons pressed do not
// change over these frames there is no point in doing it every frame
2001-07-16 21:46:48 +02:00
if(i==0&&m_currentPlayerModeClass->getState()!=STATE_CELEBRATE)
2001-05-29 20:22:49 +02:00
{
2001-07-16 21:46:48 +02:00
m_tryingToManuallyPickupWeapon=false;
m_tryingToAutomaticallyPickupWeapon=false;
2001-05-29 20:22:49 +02:00
2001-07-16 21:06:30 +02:00
// Weapon collect/drop/swap stuff..
if(m_currentMode==PLAYER_MODE_BASICUNARMED)
2001-05-29 18:12:06 +02:00
{
2001-07-16 21:06:30 +02:00
// Always trying to pick up weapon if unarmed... means that when SB walks
// over an item whilst unarmed, he automatically picks it up
m_tryingToAutomaticallyPickupWeapon=true;
}
2001-07-25 18:54:29 +02:00
if(m_currentMode!=PLAYER_MODE_CART && getPadInputDown()&PI_WEAPONCHANGE)
2001-07-16 21:06:30 +02:00
{
// If already armed then drop current weapon
if(m_currentMode!=PLAYER_MODE_BASICUNARMED&&
m_currentMode!=PLAYER_MODE_DEAD)
2001-05-29 18:12:06 +02:00
{
2001-07-16 21:06:30 +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
-1, // PLAYER_MODE_CART
-1, // PLAYER_MODE_SWALLOW
};
int pickupToDrop;
pickupToDrop=s_pickupsToDrop[m_currentMode];
if(pickupToDrop!=-1)
{
DVECTOR pickupPos;
CBasePickup *pickup;
pickupPos.vx=Pos.vx;
pickupPos.vy=Pos.vy-30;
pickup=createPickup((PICKUP_TYPE)pickupToDrop,&pickupPos);
pickup->setPos(&pickupPos);
2001-07-27 18:00:58 +02:00
((CBaseWeaponPickup*)pickup)->setHasBeenCollected();
2001-07-16 21:06:30 +02:00
}
setMode(PLAYER_MODE_BASICUNARMED);
2001-05-29 18:12:06 +02:00
}
2001-07-16 21:06:30 +02:00
// Now trying to pick up a weapon..
m_tryingToManuallyPickupWeapon=true;
2001-05-18 23:03:51 +02:00
}
}
2001-05-01 23:59:49 +02:00
2001-08-04 16:39:11 +02:00
int level=GameScene.getLevelNumber();
2001-07-17 22:13:07 +02:00
// Out of spats?
2001-08-04 16:39:11 +02:00
if(m_numSpatulasHeld==0 && level!=5)
2001-07-17 22:13:07 +02:00
{
2001-08-03 04:57:25 +02:00
int oldTimer=m_spatulaWarningTimer;
2001-07-17 22:13:07 +02:00
m_spatulaWarningTimer++;
2001-08-03 04:57:25 +02:00
if((m_spatulaWarningTimer&64)!=(oldTimer&64))
{
CSoundMediator::playSfx(CSoundMediator::SFX_BEEP10);
}
2001-07-17 22:13:07 +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&&
2001-07-10 21:56:51 +02:00
m_currentPlayerModeClass->canConverse()&&
2001-05-02 00:05:23 +02:00
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-06-15 23:24:14 +02:00
2001-01-25 23:19:47 +01:00
2001-06-04 16:41:56 +02:00
// Is player stood on any special collision?
2001-08-03 04:57:25 +02:00
for(int j=0;j<2;j++)
2001-05-30 21:21:32 +02:00
{
2001-08-03 04:57:25 +02:00
int x=Pos.vx+((j==0)?-checkx:+checkx);
if(getHeightFromGroundNoPlatform(x,Pos.vy,5)==0)
2001-05-30 21:21:32 +02:00
{
2001-08-03 04:57:25 +02:00
int block;
block=CGameScene::getCollision()->getCollisionBlock(x,Pos.vy)&COLLISION_TYPE_MASK;
2001-06-04 16:41:56 +02:00
2001-08-03 04:57:25 +02:00
// Conveyor belt movement
if(block==COLLISION_TYPE_FLAG_MOVE_LEFT)
{
moveHorizontal(-1);
break;
}
else if(block==COLLISION_TYPE_FLAG_MOVE_RIGHT)
{
moveHorizontal(+1);
break;
}
2001-06-15 23:24:14 +02:00
}
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..
2001-07-21 20:39:43 +02:00
if(m_cartCamActive)
{
// Just force the cam eo think we are running right so that the cam
// is always in the right place when in a cart
m_cameraXScrollDir=-1;
}
2001-05-13 21:28:48 +02:00
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
ASSERT(!(getIsInWater()==false&&isWearingDivingHelmet()==false));
2001-07-10 23:01:57 +02:00
if(isWearingDivingHelmet())
2001-05-16 16:41:50 +02:00
{
2001-07-10 23:01:57 +02:00
if(getIsInWater()==false&&m_currentMode!=PLAYER_MODE_DEAD&&m_currentMode!=PLAYER_MODE_FLY)
2001-05-16 16:41:50 +02:00
{
2001-07-10 23:01:57 +02:00
// Out of water and wearing helmet!
// Drain water/health
2001-08-03 04:57:25 +02:00
int oldLevel=m_healthWaterLevel/WATER_COUNTER_SECONDTIME;
2001-07-10 23:01:57 +02:00
m_healthWaterLevel-=waterDrainSpeed*_frames;
2001-08-03 04:57:25 +02:00
if(oldLevel<=6&&oldLevel>m_healthWaterLevel/WATER_COUNTER_SECONDTIME)
{
CSoundMediator::playSfx(CSoundMediator::SFX_BEEP5);
}
2001-07-10 23:01:57 +02:00
if(m_healthWaterLevel<=0)
{
dieYouPorousFreak(DEATHTYPE__DRYUP);
2001-08-03 04:57:25 +02:00
CSoundMediator::playSfx(CSoundMediator::SFX_BEEP5);
2001-07-10 23:01:57 +02:00
}
2001-06-01 20:59:33 +02:00
2001-07-10 23:01:57 +02:00
// Breath sound
m_helmetSoundTimer+=_frames;
if(m_helmetSoundTimer>150+(m_healthWaterLevel>>WATERLEVELSHIFT))
{
CSoundMediator::playSfx(CSoundMediator::SFX_SPONGEBOB_DIVING_HELMET);
m_helmetSoundTimer=0;
}
}
else if(getIsInWater())
2001-06-01 20:59:33 +02:00
{
2001-07-10 23:01:57 +02:00
// Back in water - fill up helmet! :)
m_healthWaterLevel+=waterSoakUpSpeed;
if(m_healthWaterLevel>WATERMAXHEALTH)
{
m_healthWaterLevel=WATERMAXHEALTH;
}
2001-06-01 20:59:33 +02:00
}
2001-05-16 16:41:50 +02:00
}
2001-04-17 22:09:33 +02:00
// Ledge look-ahead stuff
2001-07-26 22:00:55 +02:00
if(m_ledgeLookAhead)
2001-04-17 22:09:33 +02:00
{
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-07-26 22:00:55 +02:00
if(m_ledgeLookOffset<limit)
2001-04-17 22:09:33 +02:00
{
2001-07-26 22:00:55 +02:00
// Look down
m_ledgeLookOffset+=ledgeSpeedIn*_frames;
if(m_ledgeLookOffset>limit)
2001-04-17 22:09:33 +02:00
{
2001-07-26 22:00:55 +02:00
m_ledgeLookOffset=limit;
2001-04-17 22:45:02 +02:00
}
2001-07-26 22:00:55 +02:00
}
else if(m_ledgeLookOffset>limit)
{
// Look up
m_ledgeLookOffset-=ledgeSpeedIn*_frames;
if(m_ledgeLookOffset<limit)
2001-04-17 22:45:02 +02:00
{
2001-07-26 22:00:55 +02:00
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;
}
}
}
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-06-28 22:21:02 +02:00
CGameScene::shakeCamera(m_cameraPos);
2001-05-04 23:19:00 +02:00
}
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-06-20 21:32:03 +02:00
m_ignoreNewlyPressedButtonsOnPadThisThink=false;
2001-07-21 21:14:40 +02:00
// Restore flipped camera
setReverseCameraMovement(false);
2001-07-27 17:19:36 +02:00
// flashing pants..
if(m_pantFlashTimer)
{
m_pantFlashTimer-=_frames;
}
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-06-25 21:57:44 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::detectHazardousSurface()
{
2001-07-31 22:29:43 +02:00
// DOn't worry if on platform or already dead
if(!isOnPlatform()&&
m_currentMode!=PLAYER_MODE_DEAD)
2001-06-25 21:57:44 +02:00
{
2001-07-31 22:29:43 +02:00
int i;
DVECTOR const &pos=getPlayerPos();
for(i=0;i<2;i++)
2001-06-25 21:57:44 +02:00
{
2001-07-31 22:29:43 +02:00
int x,height;
2001-06-25 21:57:44 +02:00
2001-07-31 22:29:43 +02:00
x=pos.vx+(i==0?-checkx:checkx);
height=CGameScene::getCollision()->getHeightFromGround(x,pos.vy);
if(height<=0)
2001-06-25 21:57:44 +02:00
{
2001-07-31 22:29:43 +02:00
int block;
block=CGameScene::getCollision()->getCollisionBlock(x,pos.vy)&COLLISION_TYPE_MASK;
2001-06-25 21:57:44 +02:00
2001-07-31 22:29:43 +02:00
// Death?
if(block==COLLISION_TYPE_FLAG_DEATH_LIQUID)
{
dieYouPorousFreak(DEATHTYPE__LIQUID);
break;
}
else if(block==COLLISION_TYPE_FLAG_DEATH_INSTANT)
{
dieYouPorousFreak(DEATHTYPE__NORMAL);
break;
}
}
2001-06-25 21:57:44 +02: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;
2001-07-20 18:29:47 +02:00
int stateDebugY=180;
2001-05-02 17:31:30 +02:00
#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-07-20 18:29:47 +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-07-20 18:29:47 +02:00
drawlastpos=drawlastpos==true?false:true;
2001-05-10 16:35:35 +02:00
}
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-06-21 22:51:55 +02:00
if(m_animNo!=ANIM_SPONGEBOB_DONOTDRAW)
2001-01-22 23:58:12 +01:00
{
2001-06-21 22:51:55 +02:00
DVECTOR sbPos=
{
Pos.vx-m_cameraPos.vx,
2001-07-29 19:48:19 +02:00
Pos.vy-m_cameraPos.vy+1, // Odd.. source sprites were moved up by one pixel at some stage
2001-06-21 22:51:55 +02:00
};
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
2001-07-18 16:54:16 +02:00
// Don't draw it when the conversations are active - it's messy :/
if(!CConversation::isActive())
2001-07-04 18:27:35 +02:00
{
2001-07-18 16:54:16 +02:00
int count,warn;
sFrameHdr *fh;
char countBuf[5];
int x,y;
// Spat/token count
warn=false;
if(GameScene.getLevelNumber()!=5)
2001-07-17 22:13:07 +02:00
{
2001-07-18 16:54:16 +02:00
// Spat count
count=m_numSpatulasHeld;
fh=sb->getFrameHeader(FRM__SPATULA);
if(m_numSpatulasHeld==0)
{
warn=true;
}
2001-07-17 22:13:07 +02:00
}
2001-07-18 16:54:16 +02:00
else
{
// Token count
count=CGameSlotManager::getSlotData()->getKelpTokenCollectedCount(GameScene.getChapterNumber()-1,GameScene.getLevelNumber()-1);
fh=sb->getFrameHeader(FRM__TOKEN);
}
sprintf(countBuf,"x%d",count);
x=SB_UI_XBASE;
y=SB_UI_YBASE;
sb->printFT4(fh,x,y,0,0,POWERUPUI_OT);
x+=fh->W;
if(warn&&m_spatulaWarningTimer&32)
2001-06-22 18:22:03 +02:00
{
2001-07-18 16:54:16 +02:00
m_fontBank->setColour(255,0,0);
2001-06-22 18:22:03 +02:00
}
2001-07-18 16:54:16 +02:00
m_fontBank->print(x,y,countBuf);
m_fontBank->setColour(128,128,128);
x+=SB_UI_GAP_FROM_SPAT_COUNT_TO_PICKUPS;
2001-06-22 18:22:03 +02:00
2001-07-20 04:08:48 +02:00
if(isWearingBoots())
{
// Boots
int pickupX,pickupY;
sFrameHdr *fh=sb->getFrameHeader(FRM__SHOE);
if(m_squeakyBootsTimer>SQUEAKY_BOOTS_FLASH_TIME||m_squeakyBootsTimer&2)
{
sb->printFT4(fh,x,y,0,0,POWERUPUI_OT);
sb->printFT4(fh,x+4,y+4,0,0,POWERUPUI_OT);
}
x+=fh->W+SB_UI_GAP_BETWEEN_ITEMS+4;
}
// Mode specific ui
m_currentPlayerModeClass->renderModeUi();
// Fiving helmet.. now appears in same place as mode specific ui..
2001-07-18 16:54:16 +02:00
if(isWearingDivingHelmet())
{
// Helmet
POLY_FT4 *ft4;
2001-07-20 04:08:48 +02:00
int x,y;
2001-07-18 16:54:16 +02:00
int V,W,H,partH;
2001-07-20 04:08:48 +02:00
x=POWERUPUI_ICONX;
y=POWERUPUI_ICONY;
2001-07-18 16:54:16 +02:00
ft4=sb->printFT4(FRM__WATERHILIGHT,x,y,0,0,POWERUPUI_OT);
setSemiTrans(ft4,true);
fh=sb->getFrameHeader(FRM__WATER);
ft4=sb->printFT4(fh,0,0,0,0,POWERUPUI_OT);
setSemiTrans(ft4,true);
V=fh->V;
W=fh->W;
H=fh->H;
partH=(H*(255-(m_healthWaterLevel>>WATERLEVELSHIFT)))>>8;
if(partH>H)partH=H;
setXYWH(ft4,x,y+(partH),W,H-partH);
ft4->v0=V+(partH);
ft4->v1=V+(partH);
sb->printFT4(FRM__WATERMETER,x,y,0,0,POWERUPUI_OT);
if(!getIsInWater()&&m_healthWaterLevel<(WATER_COUNTER_SECONDTIME*6)&&m_currentPlayerModeClass->getState()!=STATE_SOAKUP)
{
int digit;
DVECTOR src={x+(W/2),y+(H/2)};
DVECTOR dst={INGAME_SCREENW/2,(INGAME_SCREENH/3)*1};
int frame;
int digitX,digitY,scale;
char buf[4];
int r,g,b;
digit=m_healthWaterLevel/WATER_COUNTER_SECONDTIME;
if(digit<0)digit=0;
frame=WATER_COUNTER_SECONDTIME-(m_healthWaterLevel%WATER_COUNTER_SECONDTIME);
if(frame>WATER_COUNTER_MOVINGTIME)frame=WATER_COUNTER_MOVINGTIME;
digitX=src.vx+(((dst.vx-src.vx)*frame)/WATER_COUNTER_MOVINGTIME);
digitY=src.vy+(((dst.vy-src.vy)*frame)/WATER_COUNTER_MOVINGTIME);
scale=WATER_COUNTER_STARTSCALE+(((WATER_COUNTER_ENDSCALE-WATER_COUNTER_STARTSCALE)*frame)/WATER_COUNTER_MOVINGTIME);
sprintf(buf,"%d",digit);
m_scalableFontBank->setJustification(FontBank::JUST_CENTRE);
m_scalableFontBank->setScale(scale);
r=WATER_COUNTER_R2-(((WATER_COUNTER_R2-WATER_COUNTER_R1)*(m_healthWaterLevel))/(WATER_COUNTER_SECONDTIME*6));
g=WATER_COUNTER_G2-(((WATER_COUNTER_G2-WATER_COUNTER_G1)*(m_healthWaterLevel))/(WATER_COUNTER_SECONDTIME*6));
b=WATER_COUNTER_B2-(((WATER_COUNTER_B2-WATER_COUNTER_B1)*(m_healthWaterLevel))/(WATER_COUNTER_SECONDTIME*6));
m_scalableFontBank->setColour(r,g,b);
m_scalableFontBank->print(digitX,digitY,buf);
}
x+=fh->W+SB_UI_GAP_BETWEEN_ITEMS;
}
2001-07-20 04:08:48 +02:00
2001-07-18 16:54:16 +02:00
}
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:
---------------------------------------------------------------------- */
2001-07-23 21:26:37 +02:00
void CPlayer::setRespawnPosAndRingTelephone(DVECTOR const &_respawn)
2001-06-11 17:27:05 +02:00
{
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-07-26 22:00:55 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::setLedgeLookAhead(int _lookAhead)
{
if(m_ledgeLookAhead!=_lookAhead)
{
m_ledgeLookAhead=_lookAhead;
m_ledgeLookTimer=0;
}
}
2001-03-01 21:30:25 +01:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::addLife()
{
2001-07-10 20:15:12 +02:00
CGameSlotManager::GameSlot *gameSlot;
gameSlot=CGameSlotManager::getSlotData();
if(gameSlot->m_lives<MAX_LIVES)
2001-03-01 21:30:25 +01:00
{
2001-07-10 20:15:12 +02:00
gameSlot->m_lives++;
2001-03-01 21:30:25 +01:00
}
2001-07-27 17:19:36 +02:00
m_pantFlashTimer=PANT_FLASH_TIME;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::addSpatula(int Count=1)
{
m_numSpatulasHeld+=Count;
if(!m_hasReceivedExtraLifeFor100Spats&&m_numSpatulasHeld==100)
{
addLife();
m_hasReceivedExtraLifeFor100Spats=true;
}
2001-03-01 21:30:25 +01:00
}
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-07-16 18:27:50 +02:00
m_currentPlayerModeClass->setInitialState(state);
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-07-16 21:06:30 +02:00
m_tryingToManuallyPickupWeapon=false;
m_tryingToAutomaticallyPickupWeapon=false;
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-08-04 00:46:16 +02:00
CSoundMediator::playSfx(CSoundMediator::SFX_BOUNCY_PLATFORM,false,true);
2001-05-01 20:39:41 +02:00
}
2001-06-15 23:24:14 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::setFloating()
{
m_currentPlayerModeClass->setFloating();
}
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-08-08 18:54:00 +02:00
m_teleportPendingPos=pos;
m_teleportPending=true;
}
void CPlayer::processTeleportToCommand()
{
ASSERT(m_teleportPending);
2001-05-04 03:35:52 +02:00
CameraBox releaseCamBox={0,0,29999,29999};
setCameraBox(releaseCamBox);
2001-08-08 18:54:00 +02:00
setPos(m_teleportPendingPos);
setRespawnPos(m_teleportPendingPos);
2001-05-02 20:11:29 +02:00
calcCameraFocusPointTarget();
m_currentCamFocusPoint=m_currentCamFocusPointTarget;
2001-08-08 18:54:00 +02:00
m_teleportPending=false;
2001-05-02 20:11:29 +02:00
}
2001-08-08 18:54:00 +02:00
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-07-17 22:13:07 +02:00
m_spatulaWarningTimer=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-07-26 22:00:55 +02:00
m_ledgeLookAhead=0;
2001-04-17 22:09:33 +02:00
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-07-27 18:00:58 +02:00
m_bubbleAmmo=0;
m_jellyAmmo=0;
2001-05-29 16:51:59 +02:00
m_jellyfishAmmoCount=0;
2001-07-27 17:19:36 +02:00
m_pantFlashTimer=0;
m_hasReceivedExtraLifeFor100Spats=false;
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
2001-06-20 21:32:03 +02:00
m_ignoreNewlyPressedButtonsOnPadThisThink=true;
2001-08-03 23:16:05 +02:00
m_canExitLevel=false;
2001-08-08 18:54:00 +02:00
m_teleportPending=false;
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
{
ft4=addonGfx->Render(*_pos,addonAnimNo,_animFrame,m_facing==FACING_RIGHT?0:1);
2001-07-30 23:24:53 +02:00
setShadeTex(ft4,0);
2001-07-12 18:47:11 +02:00
setRGB0(ft4,255,128,255);
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-06-15 23:24:14 +02:00
CThing *platform;
platform=isOnPlatform();
if(platform)
{
if ( ( (CNpcPlatform *) platform )->isCart() )
{
2001-08-13 20:52:43 +02:00
m_actorGfx->RotateScale( ft4, *_pos, ( (CNpcPlatform *) platform )->getCollisionAngle() , ONE, ONE );
2001-06-15 23:24:14 +02:00
}
}
2001-05-02 00:09:36 +02:00
setSemiTrans(ft4,trans);
2001-07-27 17:19:36 +02:00
// Pants?
if(m_pantFlashTimer>0)
{
SpriteBank *sb=CGameScene::getSpriteBank();
sFrameHdr *fh;
DVECTOR drawPos;
int size;
fh=sb->getFrameHeader(FRM__PANTS);
drawPos=*_pos;
drawPos.vy+=PANT_FLASH_Y_OFFSET;
size=m_pantFlashTimer&8?4096:8192;
ft4=sb->printRotatedScaledSprite(fh,drawPos.vx,drawPos.vy,size,size,0,0);
}
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
2001-06-20 21:32:03 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::ignoreNewlyPressedButtonsOnPadThisThink()
{
m_ignoreNewlyPressedButtonsOnPadThisThink=true;
}
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
2001-07-11 15:57:18 +02:00
m_currentPlayerModeClass->getState()!=STATE_CELEBRATE&& // Or celebrating
2001-07-03 22:49:30 +02:00
m_currentMode!=PLAYER_MODE_DEAD &&
m_currentMode!=PLAYER_MODE_SWALLOW) // Or already dead! :)
2001-02-06 22:09:45 +01:00
{
2001-07-13 23:45:29 +02:00
int ouchThatHurt=true;
int ouchThatHurtSoMuchThatImJustGoingToDieNow=false;
CSoundMediator::SFXID painSound=CSoundMediator::SFX_SPONGEBOB_OUCH;
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;
}
2001-07-13 23:45:29 +02:00
else
{
painSound=CSoundMediator::SFX_BOSS_JELLYFISH___SB_GETS_ELECTROCUTED;
}
2001-04-18 22:31:14 +02:00
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-07-10 20:28:13 +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-07-10 20:28:13 +02:00
// NET REMOVED FROM HIT SYSTEM (PKG)
/*
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-27 21:50:35 +02:00
setMode(PLAYER_MODE_BASICUNARMED);
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-07-10 20:28:13 +02:00
*/
2001-05-11 21:49:41 +02:00
{
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-07-17 22:13:07 +02:00
m_spatulaWarningTimer=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-06-28 21:14:44 +02:00
CPadVibrationManager::setVibration(0,CPadVibrationManager::VIBE_LONG_STROBEY);
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;
}
2001-07-13 23:45:29 +02:00
CSoundMediator::playSfx(painSound);
2001-05-11 21:49:41 +02:00
m_currentPlayerModeClass->setState(STATE_JUMPBACK);
}
2001-05-04 01:45:28 +02:00
m_invincibleFrameCount=INVINCIBLE_FRAMES__HIT;
2001-06-28 21:14:44 +02:00
CPadVibrationManager::setVibration(0,CPadVibrationManager::VIBE_SHORT);
2001-02-06 22:09:45 +01:00
}
}
}
2001-01-20 00:37:40 +01:00
}
2001-07-03 00:57:52 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayer::collectedQuestItem()
{
m_currentPlayerModeClass->setState(STATE_CELEBRATE);
}
2001-07-10 20:15:12 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int CPlayer::getLivesLeft()
{
return CGameSlotManager::getSlotData()->m_lives;
}
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-07-29 19:48:19 +02:00
m_lockCamera=true;
2001-05-04 01:45:28 +02:00
}
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-06-20 21:32:03 +02:00
if(!m_ignoreNewlyPressedButtonsOnPadThisThink)
{
m_padInputDown=(PLAYERINPUT)(m_padInput&(m_lastPadInput^-1));
}
else
{
m_padInputDown=PI_NONE;
}
2001-01-29 23:35:18 +01:00
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
2001-06-20 21:32:03 +02:00
typedef struct
{
CPadConfig::PAD_CFG m_input;
PLAYERINPUT m_output;
} PAD_CONVERSION;
static const PAD_CONVERSION s_padConversionTable[]=
{
{ CPadConfig::PAD_CFG_UP, PI_UP },
{ CPadConfig::PAD_CFG_DOWN, PI_DOWN },
{ CPadConfig::PAD_CFG_LEFT, PI_LEFT },
{ CPadConfig::PAD_CFG_RIGHT, PI_RIGHT },
{ CPadConfig::PAD_CFG_JUMP, PI_JUMP },
{ CPadConfig::PAD_CFG_FIRE, PI_FIRE },
{ CPadConfig::PAD_CFG_CATCH, PI_CATCH },
{ CPadConfig::PAD_CFG_WEAPONCHANGE, PI_WEAPONCHANGE },
};
static const int s_padConversionTableSize=sizeof(s_padConversionTable)/sizeof(PAD_CONVERSION);
2001-02-09 18:01:04 +01:00
PLAYERINPUT CPlayer::readPadInput()
2001-01-29 23:35:18 +01:00
{
2001-06-20 21:32:03 +02:00
PLAYERINPUT input;
int pad;
const PAD_CONVERSION *table;
int i;
2001-02-09 18:01:04 +01:00
input=PI_NONE;
pad=PadGetHeld(0);
2001-06-20 21:32:03 +02:00
table=s_padConversionTable;
for(i=0;i<s_padConversionTableSize;i++)
2001-02-09 18:01:04 +01:00
{
2001-06-20 21:32:03 +02:00
if(pad&CPadConfig::getButton(table->m_input))
{
input=(PLAYERINPUT)(input|table->m_output);
}
table++;
2001-05-18 23:03:51 +02:00
}
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
/*----------------------------------------------------------------------
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-07-23 21:26:37 +02:00
void CPlayer::shove( DVECTOR const &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
{
2001-07-21 21:14:40 +02:00
m_cameraXScrollDir=m_reverseCameraMovement==false?+1:-1;
2001-05-13 21:28:48 +02:00
}
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
{
2001-07-21 21:14:40 +02:00
m_cameraXScrollDir=m_reverseCameraMovement==false?-1:+1;
2001-05-13 21:28:48 +02:00
}
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-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;
2001-07-30 02:35:24 +02:00
int hitThisSuspectBlock;
2001-04-25 20:38:33 +02:00
pos=Pos;
hitGround=false;
2001-07-30 02:35:24 +02:00
hitThisSuspectBlock=0;
2001-04-25 20:38:33 +02:00
// Are we falling?
if(_moveDistance>0)
{
2001-07-31 18:03:19 +02:00
if ( isOnPlatform() )
{
// must also detect that we have landed on platform
return( true );
}
2001-07-30 02:35:24 +02:00
int colHeightBefore[2],colHeightAfter[2],blockAfter[2],moveRequired[2];
int i;
int move;
2001-07-29 19:48:19 +02:00
2001-07-30 02:35:24 +02:00
// Get heights of the two edges
for(i=0;i<+2;i++)
2001-07-20 22:56:30 +02:00
{
2001-07-30 02:35:24 +02:00
int x=pos.vx+((i==0?-checkx:+checkx));
2001-07-29 19:48:19 +02:00
colHeightBefore[i]=getHeightFromGround(x,pos.vy,16);
colHeightAfter[i]=getHeightFromGround(x,pos.vy+_moveDistance,16);
2001-07-30 02:35:24 +02:00
blockAfter[i]=CGameScene::getCollision()->getCollisionBlock(x,pos.vy+_moveDistance);
2001-07-20 22:56:30 +02:00
}
2001-07-27 16:43:39 +02:00
2001-07-30 02:35:24 +02:00
// See if either side is about to go through the ground
for(i=0;i<2;i++)
2001-07-29 19:48:19 +02:00
{
2001-07-30 02:35:24 +02:00
if(colHeightBefore[i]>=0&&colHeightAfter[i]<=0)
2001-07-20 22:56:30 +02:00
{
2001-07-30 17:08:29 +02:00
int goingIntoThisBlock=blockAfter[i]&COLLISION_TYPE_MASK;
if(goingIntoThisBlock!=COLLISION_TYPE_FLAG_DEATH_FALL)
{
moveRequired[i]=colHeightAfter[i];
hitGround=true;
}
else
{
moveRequired[i]=0;
}
if(!hitThisSuspectBlock)hitThisSuspectBlock=goingIntoThisBlock;
2001-07-30 02:35:24 +02:00
}
else
{
moveRequired[i]=0;
2001-07-20 21:36:18 +02:00
}
}
2001-07-30 02:35:24 +02:00
// Find the smallest move required to hit ground
move=0;
for(i=0;i<2;i++)
2001-05-10 16:35:35 +02:00
{
2001-07-29 19:48:19 +02:00
if(moveRequired[i]<move)
{
2001-07-30 02:35:24 +02:00
move=moveRequired[i];
2001-07-29 19:48:19 +02:00
}
2001-05-10 16:35:35 +02:00
}
2001-07-29 19:48:19 +02:00
_moveDistance+=move;
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
{
2001-07-30 02:35:24 +02:00
int colHeightBefore[2],colHeightAfter[2],blockAfter[2],moveRequired[2];
int i;
int move;
// -------------- Jumping - See if the feet have hit anything --------------
2001-07-29 19:48:19 +02:00
2001-07-30 02:35:24 +02:00
// Get heights of the two edges
for(i=0;i<+2;i++)
2001-04-25 20:38:33 +02:00
{
2001-07-30 02:35:24 +02:00
int x=pos.vx+((i==0?-checkx:+checkx));
colHeightBefore[i]=getHeightFromGround(x,pos.vy,16);
colHeightAfter[i]=getHeightFromGround(x,pos.vy+_moveDistance,16);
blockAfter[i]=CGameScene::getCollision()->getCollisionBlock(x,pos.vy+_moveDistance);
2001-04-25 20:38:33 +02:00
}
2001-07-30 02:35:24 +02:00
// See if either side is about to go through the ground
for(i=0;i<2;i++)
2001-06-07 21:40:41 +02:00
{
2001-07-30 02:35:24 +02:00
if(colHeightBefore[i]>=0&&colHeightAfter[i]<=0&&((blockAfter[i]&COLLISION_TYPE_MASK)!=COLLISION_TYPE_FLAG_NORMAL))
2001-06-14 23:12:48 +02:00
{
2001-07-30 02:35:24 +02:00
moveRequired[i]=colHeightAfter[i];
hitGround=true;
if(!hitThisSuspectBlock)hitThisSuspectBlock=blockAfter[i];
}
else
{
moveRequired[i]=0;
2001-06-14 23:12:48 +02:00
}
2001-06-07 21:40:41 +02:00
}
2001-06-15 23:24:14 +02:00
2001-07-30 02:35:24 +02:00
// Find the smallest move required to hit ground
move=0;
for(i=0;i<2;i++)
2001-05-14 19:04:13 +02:00
{
2001-07-30 02:35:24 +02:00
if(moveRequired[i]<move)
{
move=moveRequired[i];
}
2001-05-14 19:04:13 +02:00
}
2001-04-25 20:38:33 +02:00
2001-07-30 02:35:24 +02:00
_moveDistance-=move;
2001-07-20 22:56:30 +02:00
2001-07-30 02:35:24 +02:00
// -------------- Jumping - See if the head has hit anything --------------
// Get heights of the two edges
int y=pos.vy-HEIGHT_FOR_HEAD_COLLISION;
for(i=0;i<+2;i++)
2001-07-20 22:56:30 +02:00
{
2001-07-30 02:35:24 +02:00
int x=pos.vx+((i==0?-checkx:+checkx));
2001-07-31 00:00:31 +02:00
colHeightBefore[i]=getHeightFromGround(x,y,16);
colHeightAfter[i]=getHeightFromGround(x,y+_moveDistance,16);
2001-07-30 02:35:24 +02:00
blockAfter[i]=CGameScene::getCollision()->getCollisionBlock(x,y+_moveDistance);
2001-07-20 22:56:30 +02:00
}
2001-07-30 02:35:24 +02:00
// See if either side is about to go through the ground
for(i=0;i<2;i++)
2001-07-20 22:56:30 +02:00
{
2001-07-30 02:35:24 +02:00
if(colHeightBefore[i]>=0&&colHeightAfter[i]<=0&&((blockAfter[i]&COLLISION_TYPE_MASK)!=COLLISION_TYPE_FLAG_NORMAL))
2001-07-20 22:56:30 +02:00
{
2001-07-30 02:35:24 +02:00
moveRequired[i]=16+colHeightAfter[i];
2001-08-14 00:09:17 +02:00
// hitGround=true;
// do not call hitground code, because this will set it to STATE_IDLE for a frame
// instead, do the appropriate stuff for a fall
2001-07-30 02:35:24 +02:00
if(!hitThisSuspectBlock)hitThisSuspectBlock=blockAfter[i];
2001-08-14 00:09:17 +02:00
m_currentPlayerModeClass->setState(STATE_FALL);
DVECTOR moveVel;
moveVel=*getMoveVelocity();
moveVel.vy=0;
m_fallFrames=0;
setMoveVelocity(&moveVel);
2001-07-20 22:56:30 +02:00
}
else
{
2001-07-30 02:35:24 +02:00
moveRequired[i]=0;
2001-07-20 22:56:30 +02:00
}
}
2001-07-30 02:35:24 +02:00
// Find the smallest move required to hit ground
move=0;
for(i=0;i<2;i++)
2001-07-20 22:56:30 +02:00
{
2001-07-30 02:35:24 +02:00
if(moveRequired[i]<move)
2001-07-20 22:56:30 +02:00
{
2001-07-30 02:35:24 +02:00
move=moveRequired[i];
2001-07-20 22:56:30 +02:00
}
}
2001-07-30 02:35:24 +02:00
_moveDistance-=move;
2001-07-20 22:56:30 +02:00
}
else
{
// Stood on any important types of collision?
2001-07-30 02:35:24 +02:00
hitThisSuspectBlock=CGameScene::getCollision()->getCollisionBlock(pos.vx,pos.vy+_moveDistance);
}
2001-07-30 17:08:29 +02:00
2001-07-30 02:35:24 +02:00
pos.vy+=_moveDistance;
setPlayerPos(&pos);
2001-07-30 18:43:10 +02:00
if(m_currentMode!=PLAYER_MODE_DEAD)
2001-07-30 02:35:24 +02:00
{
switch(hitThisSuspectBlock&COLLISION_TYPE_MASK)
2001-07-20 22:56:30 +02:00
{
case COLLISION_TYPE_FLAG_DAMAGE:
takeDamage(DAMAGE__COLLISION_DAMAGE);
break;
case COLLISION_TYPE_FLAG_ELECTRIC:
if(!isWearingBoots())
{
takeDamage(DAMAGE__COLLISION_DAMAGE);
}
break;
2001-07-30 23:50:34 +02:00
/*
2001-07-30 02:35:24 +02:00
case COLLISION_TYPE_FLAG_DEATH_LIQUID:
dieYouPorousFreak(DEATHTYPE__LIQUID);
break;
case COLLISION_TYPE_FLAG_DEATH_INSTANT:
dieYouPorousFreak(DEATHTYPE__NORMAL);
break;
2001-07-31 16:32:19 +02:00
*/
2001-07-30 02:35:24 +02:00
case COLLISION_TYPE_FLAG_DEATH_FALL:
dieYouPorousFreak(DEATHTYPE__FALL_TO_DEATH);
break;
2001-07-20 22:56:30 +02:00
default:
break;
}
}
return hitGround;
}
2001-07-30 23:24:53 +02:00
2001-04-25 20:38:33 +02:00
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int CPlayer::moveHorizontal(int _moveDistance)
{
int hitWall;
hitWall=false;
if(_moveDistance)
{
DVECTOR pos;
2001-07-30 02:35:24 +02:00
int dirToMove;
int i;
int colHeightEdges[2];
2001-04-25 20:38:33 +02:00
int colHeight;
pos=getPlayerPos();
2001-07-30 02:35:24 +02:00
dirToMove=_moveDistance<0?-1:+1;
for(i=abs(_moveDistance);i&&!hitWall;i--)
{
2001-08-03 04:57:25 +02:00
int touchingGround,x,x2;
2001-07-30 02:35:24 +02:00
colHeightEdges[0]=getHeightFromGround(pos.vx-checkx,pos.vy,16);
colHeightEdges[1]=getHeightFromGround(pos.vx+checkx,pos.vy,16);
touchingGround=false;
2001-08-03 04:57:25 +02:00
x=x2=pos.vx+dirToMove;
2001-07-30 02:35:24 +02:00
if(dirToMove>0)
2001-04-25 20:38:33 +02:00
{
2001-07-30 02:35:24 +02:00
// Moving right
if(colHeightEdges[1]==0)
2001-04-25 20:38:33 +02:00
{
2001-07-30 02:35:24 +02:00
// Right side of SB touching ground
x+=checkx;
2001-08-03 04:57:25 +02:00
x2-=checkx;
2001-07-30 02:35:24 +02:00
touchingGround=true;
2001-04-25 20:38:33 +02:00
}
2001-07-30 02:35:24 +02:00
else if(colHeightEdges[0]==0)
2001-04-25 20:38:33 +02:00
{
2001-07-30 02:35:24 +02:00
// Left side of SB touching ground
x-=checkx;
2001-08-03 04:57:25 +02:00
x2+=checkx;
2001-07-30 02:35:24 +02:00
touchingGround=true;
2001-04-25 20:38:33 +02:00
}
}
2001-07-30 02:35:24 +02:00
else
2001-04-25 20:38:33 +02:00
{
2001-07-30 02:35:24 +02:00
// Moving left
if(colHeightEdges[0]==0)
2001-04-25 20:38:33 +02:00
{
2001-07-30 02:35:24 +02:00
// Left side of SB touching ground
x-=checkx;
2001-08-03 04:57:25 +02:00
x2+=checkx;
2001-07-30 02:35:24 +02:00
touchingGround=true;
2001-04-25 20:38:33 +02:00
}
2001-07-30 02:35:24 +02:00
else if(colHeightEdges[1]==0)
2001-04-25 20:38:33 +02:00
{
2001-07-30 02:35:24 +02:00
// Right side of SB touching ground
x+=checkx;
2001-08-03 04:57:25 +02:00
x2-=checkx;
2001-07-30 02:35:24 +02:00
touchingGround=true;
2001-04-25 20:38:33 +02:00
}
}
2001-07-20 22:56:30 +02:00
2001-07-30 02:35:24 +02:00
if(touchingGround)
2001-07-20 22:56:30 +02:00
{
2001-07-30 02:35:24 +02:00
// SB touching ground on at least one edge
colHeight=getHeightFromGround(x,pos.vy,16);
2001-08-03 04:57:25 +02:00
2001-08-11 00:32:15 +02:00
// Head collision ( a bit of a hack )
int oktomove=false;
switch ( CGameScene::getCollision()->getCollisionBlock( x, pos.vy-HEIGHT_FOR_HEAD_COLLISION ) & COLLISION_TYPE_MASK )
2001-07-20 22:56:30 +02:00
{
2001-08-11 00:32:15 +02:00
case COLLISION_TYPE_NORMAL:
oktomove=true;
break;
default:
break;
2001-07-20 22:56:30 +02:00
}
2001-08-11 00:32:15 +02:00
if(oktomove)
2001-07-20 22:56:30 +02:00
{
2001-08-11 00:32:15 +02:00
if(colHeight>=-2&&colHeight<=2)
{
// Move along the ground
pos.vx+=dirToMove;
pos.vy+=colHeight;
2001-08-03 04:57:25 +02:00
2001-08-11 00:32:15 +02:00
// Heh - these 4 lines stop SB going down a slope on the 'wrong edge' :)
colHeight=getHeightFromGround(x2,pos.vy,16);
if(colHeight<0)
{
pos.vy+=colHeight;
}
}
else if(colHeight<0)
{
// Hit wall
hitWall=true;
}
else
{
// Moved off edge of ledge
pos.vx+=dirToMove;
}
2001-07-20 22:56:30 +02:00
}
}
2001-07-30 02:35:24 +02:00
else
2001-07-20 22:56:30 +02:00
{
2001-07-30 02:35:24 +02:00
// SB not touching ground
if(dirToMove<0)
2001-07-20 22:56:30 +02:00
{
2001-07-30 02:35:24 +02:00
x-=checkx;
2001-07-20 22:56:30 +02:00
}
else
{
2001-07-30 02:35:24 +02:00
x+=checkx;
2001-07-20 22:56:30 +02:00
}
2001-08-03 04:57:25 +02:00
// Head collision ( cheers Charles! :)
colHeight = getHeightFromGround( x, pos.vy-HEIGHT_FOR_HEAD_COLLISION, 16 );
if ( colHeight < 0 )
2001-07-20 22:56:30 +02:00
{
2001-08-03 04:57:25 +02:00
switch ( CGameScene::getCollision()->getCollisionBlock( x, pos.vy-HEIGHT_FOR_HEAD_COLLISION ) & COLLISION_TYPE_MASK )
{
case COLLISION_TYPE_NORMAL:
break;
default:
hitWall=true;
break;
}
2001-07-30 02:35:24 +02:00
}
2001-08-03 04:57:25 +02:00
if ( !hitWall )
2001-07-30 02:35:24 +02:00
{
2001-08-03 04:57:25 +02:00
colHeight=getHeightFromGround(x,pos.vy,16);
if(colHeight>=0)
{
// Move in air
pos.vx+=dirToMove;
}
else
{
// Hit wall
hitWall=true;
}
2001-07-20 22:56:30 +02:00
}
}
}
setPlayerPos(&pos);
}
return hitWall;
}
2001-04-25 20:38:33 +02:00
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)
{
2001-07-23 21:26:37 +02:00
// DVECTOR offset,size;
2001-05-01 22:23:32 +02:00
2001-07-23 21:26:37 +02:00
DVECTOR const &offset=getCollisionCentreOffset();
DVECTOR const &size=getCollisionSize();
2001-05-01 22:23:32 +02:00
*_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 */