working on Disney Rave "Magic Dance" battle mode

This commit is contained in:
Chris Danford
2003-04-07 03:25:44 +00:00
parent d821c4f1b5
commit 9eac2856a0
29 changed files with 848 additions and 285 deletions
@@ -0,0 +1 @@
_menu in
@@ -0,0 +1 @@
_menu out
Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

@@ -0,0 +1 @@
ScreenSelectGroup change
@@ -0,0 +1 @@
_common menu music.ogg
+49 -11
View File
@@ -122,7 +122,7 @@ NextScreen=ScreenSelectGroup
HelpText=
[ScreenSelectDifficulty]
Choices=arcade-beginner,arcade-easy,arcade-medium,arcade-hard,nonstop,oni,endless
Choices=arcade-beginner,arcade-easy,arcade-medium,arcade-hard,nonstop,oni,endless,battle
NumChoicesOnPage1=4
HelpText=Use &LEFT; &RIGHT; to select, then press START
TimerSeconds=40
@@ -133,6 +133,7 @@ NextScreen4=ScreenSelectGroup
NextScreen5=ScreenInstructions
NextScreen6=ScreenInstructions
NextScreen7=ScreenInstructions
NextScreen8=ScreenInstructions
LockInputSeconds=0.8
SleepAfterChoiceSeconds=0.3
SleepAfterTweenOffSeconds=0.8
@@ -144,7 +145,7 @@ ExplanationPage1OnCommand=x,170;y,70;xoffset,-400;bounceend,0.5;xoffset,400;
ExplanationPage1OffCommand=bouncebegin,0.5;xoffset,-400
ExplanationPage2OnCommand=x,1100;y,70
ExplanationPage2OffCommand=bouncebegin,0.5;xoffset,400
InfoPage1Choice1OnCommand=vertalign,bottom;x,90;y,180;xoffset,-800;sleep,0.0;decelerate,0.4;xoffset,800
InfoPage1Choice1OnCommand=vertalign,bottom;x,98;y,180;xoffset,-800;sleep,0.0;decelerate,0.4;xoffset,800
InfoPage1Choice1OffCommand=sleep,0.3;accelerate,0.4;xoffset,-800
InfoPage1Choice2OnCommand=vertalign,bottom;x,246;y,220;xoffset,-800;sleep,0.2;decelerate,0.4;xoffset,800
InfoPage1Choice2OffCommand=sleep,0.5;accelerate,0.4;xoffset,-800
@@ -152,13 +153,15 @@ InfoPage1Choice3OnCommand=vertalign,bottom;x,394;y,180;xoffset,-800;sleep,0.4;de
InfoPage1Choice3OffCommand=sleep,0.7;accelerate,0.4;xoffset,-800
InfoPage1Choice4OnCommand=vertalign,bottom;x,542;y,220;xoffset,-800;sleep,0.6;decelerate,0.4;xoffset,800
InfoPage1Choice4OffCommand=sleep,0.9;accelerate,0.4;xoffset,-800
InfoPage2Choice1OnCommand=vertalign,bottom;x,760;y,200
InfoPage2Choice1OnCommand=vertalign,bottom;x,738;y,220
InfoPage2Choice1OffCommand=sleep,0.3;accelerate,0.4;xoffset,-800
InfoPage2Choice2OnCommand=vertalign,bottom;x,960;y,200
InfoPage2Choice2OnCommand=vertalign,bottom;x,886;y,180
InfoPage2Choice2OffCommand=sleep,0.5;accelerate,0.4;xoffset,-800
InfoPage2Choice3OnCommand=vertalign,bottom;x,1160;y,200
InfoPage2Choice3OnCommand=vertalign,bottom;x,1034;y,220
InfoPage2Choice3OffCommand=sleep,0.7;accelerate,0.4;xoffset,-800
PicturePage1Choice1OnCommand=vertalign,top;x,90;y,180;zoomy,0.0;sleep,0.4;bounceend,0.3;zoomy,1
InfoPage2Choice4OnCommand=vertalign,bottom;x,1182;y,180
InfoPage2Choice4OffCommand=sleep,0.9;accelerate,0.4;xoffset,-800
PicturePage1Choice1OnCommand=vertalign,top;x,98;y,180;zoomy,0.0;sleep,0.4;bounceend,0.3;zoomy,1
PicturePage1Choice1OffCommand=sleep,0.0;bouncebegin,0.3;zoomy,0
PicturePage1Choice2OnCommand=vertalign,top;x,246;y,220;zoomy,0.0;sleep,0.6;bounceend,0.3;zoomy,1
PicturePage1Choice2OffCommand=sleep,0.2;bouncebegin,0.3;zoomy,0
@@ -166,12 +169,14 @@ PicturePage1Choice3OnCommand=vertalign,top;x,394;y,180;zoomy,0.0;sleep,0.8;bounc
PicturePage1Choice3OffCommand=sleep,0.4;bouncebegin,0.3;zoomy,0
PicturePage1Choice4OnCommand=vertalign,top;x,542;y,220;zoomy,0.0;sleep,1.0;bounceend,0.3;zoomy,1
PicturePage1Choice4OffCommand=sleep,0.6;bouncebegin,0.3;zoomy,0
PicturePage2Choice1OnCommand=vertalign,top;x,760;y,200;
PicturePage2Choice1OnCommand=vertalign,top;x,738;y,220;
PicturePage2Choice1OffCommand=sleep,0.0;bouncebegin,0.3;zoomy,0
PicturePage2Choice2OnCommand=vertalign,top;x,960;y,200
PicturePage2Choice2OnCommand=vertalign,top;x,886;y,180
PicturePage2Choice2OffCommand=sleep,0.2;bouncebegin,0.3;zoomy,0
PicturePage2Choice3OnCommand=vertalign,top;x,1160;y,200
PicturePage2Choice3OnCommand=vertalign,top;x,1034;y,220
PicturePage2Choice3OffCommand=sleep,0.4;bouncebegin,0.3;zoomy,0
PicturePage2Choice4OnCommand=vertalign,top;x,1182;y,180
PicturePage2Choice4OffCommand=sleep,0.6;bouncebegin,0.3;zoomy,0
CursorOnCommand=diffuse,1,1,1,0;rotationz,340;zoom,4;linear,0.3;diffuse,1,1,1,1;rotationz,0;zoom,1;glowshift;effectperiod,0.5
CursorChooseCommand=sleep,0.2;linear,0.2;xoffset,10;yoffset,10
CursorOffCommand=sleep,0.2;linear,0.3;zoom,0
@@ -247,7 +252,7 @@ InitCommand=horizalign,left;vertalign,top;shadowlength,2;zoom,0.5;
[ScreenInstructions]
NextScreenArcade=ScreenSelectMusic
NextScreenOni=ScreenSelectCourse
NextScreenBattle=ScreenSelectMusic
NextScreenBattle=ScreenSelectCharacter
HelpText=Press START to continue
TimerSeconds=15
@@ -1274,4 +1279,37 @@ TextsZoom=0.5
NextScreen=ScreenRanking
[ScreenGameOver]
NextScreen=ScreenCompany
NextScreen=ScreenCompany
[ScreenSelectCharacter]
TitleP1OnCommand=x,140;y,80;xoffset,-400;bounceend,0.5;xoffset,400
TitleP1OffCommand=sleep,0.6;bouncebegin,0.5;xoffset,-400
TitleP2OnCommand=x,500;y,80;xoffset,400;bounceend,0.5;xoffset,-400
TitleP2OffCommand=sleep,0.6;bouncebegin,0.5;xoffset,400
CharacterP1OnCommand=x,140;y,200;xoffset,-400;bounceend,0.5;xoffset,400
CharacterP1OffCommand=sleep,0.6;bouncebegin,0.5;xoffset,-400
CharacterP2OnCommand=x,500;y,200;xoffset,400;bounceend,0.5;xoffset,-400
CharacterP2OffCommand=sleep,0.6;bouncebegin,0.5;xoffset,400
CharacterArrowsP1OnCommand=x,140;y,180
CharacterArrowsP1OffCommand=
CharacterArrowsP2OnCommand=x,500;y,180
CharacterArrowsP2OffCommand=
ExplanationOnCommand=x,320;y,140;diffusealpha,0;linear,0.3;diffusealpha,1
ExplanationOffCommand=linear,0.3;diffusealpha,0
AttackFrameP1OnCommand=x,140;y,360
AttackFrameP1OffCommand=
AttackFrameP2OnCommand=x,500;y,360
AttackFrameP2OffCommand=
IconsP1StartX=128
IconsP1StartY=336
IconsP2StartX=488
IconsP2StartY=336
IconsSpacingX=42
IconsSpacingY=32
HelpText=Use &LEFT; &RIGHT; to select, then press START
TimerSeconds=40
NextScreen=ScreenSelectMusic
[Inventory]
AttackDurationSeconds=10
ComboPerAttackLevel=50
+16 -24
View File
@@ -25,8 +25,6 @@
ActiveItemList::ActiveItemList()
{
m_pInventory = NULL;
for( int i=0; i<MAX_ACTIVE_ITEMS_LINES; i++ )
{
m_text[i].LoadFromFont( THEME->GetPathTo("Fonts","Common normal") );
@@ -36,10 +34,9 @@ ActiveItemList::ActiveItemList()
}
}
void ActiveItemList::Init( PlayerNumber pn, Inventory* pInventory )
void ActiveItemList::Init( PlayerNumber pn )
{
m_PlayerNumber = pn;
m_pInventory = pInventory;
for( int i=0; i<MAX_ACTIVE_ITEMS_LINES; i++ )
{
@@ -58,29 +55,24 @@ void ActiveItemList::Update( float fDelta )
ActorFrame::Update( fDelta );
if( m_pInventory )
// refresh text only once every second
float fNowSeconds = RageTimer::GetTimeSinceStart();
float fLastSeconds = RageTimer::GetTimeSinceStart() - fDelta;
if( (int)fNowSeconds != (int)fLastSeconds )
{
// refresh text only once every second
float fNowSeconds = RageTimer::GetTimeSinceStart();
float fLastSeconds = RageTimer::GetTimeSinceStart() - fDelta;
if( (int)fNowSeconds != (int)fLastSeconds )
GameState::ActiveAttack* sActiveAttacks = GAMESTATE->m_sActiveAttacks[m_PlayerNumber]; // NUM_INVENTORY_SLOTS
for( int s=0; s<NUM_INVENTORY_SLOTS; s++ )
{
int iNumActiveItems = m_pInventory->m_ActiveItems[m_PlayerNumber].size();
for( int i=0; i<MAX_ACTIVE_ITEMS_LINES; i++ )
{
if( i<iNumActiveItems )
{
const Inventory::ActiveItem& active_item = m_pInventory->m_ActiveItems[m_PlayerNumber][i];
const Inventory::ItemDef& item_def = m_pInventory->m_ItemDefs[ active_item.iItemDefIndex ];
GameState::ActiveAttack& aa = sActiveAttacks[s];
int iDisplaySecondsLeft = (int)(active_item.fSecondsLeft+1);
m_text[i].SetText( ssprintf("%s %02d:%02d", item_def.effect.GetString(), iDisplaySecondsLeft/60, iDisplaySecondsLeft%60) );
}
else
{
m_text[i].SetText( "" );
}
CString sDisplayText = aa.sModifier;
if( sDisplayText == "" )
m_text[s].SetText( "" );
else
{
int iDisplaySecondsLeft = (int)(aa.fSecsRemaining+1);
m_text[s].SetText( ssprintf("%s %02d:%02d", sDisplayText.GetString(), iDisplaySecondsLeft/60, iDisplaySecondsLeft%60) );
}
}
}
+1 -2
View File
@@ -26,7 +26,7 @@ class ActiveItemList : public ActorFrame
public:
ActiveItemList();
void Init( PlayerNumber pn, Inventory* pInventory );
void Init( PlayerNumber pn );
virtual void Update( float fDelta );
@@ -34,7 +34,6 @@ protected:
BitmapText m_text[MAX_ACTIVE_ITEMS_LINES];
PlayerNumber m_PlayerNumber;
Inventory* m_pInventory;
};
#endif
+32
View File
@@ -0,0 +1,32 @@
#include "global.h"
/*
-----------------------------------------------------------------------------
Class: Character
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "Character.h"
#include "IniFile.h"
#include "RageUtil.h"
void Character::Load( CString sCharIniPath )
{
IniFile ini;
ini.SetPath( sCharIniPath );
ini.ReadFile();
// save file name
CString sThrowAway;
splitrelpath( sCharIniPath, sThrowAway, m_sFileName, sThrowAway );
// load attacks
for( int i=0; i<NUM_ATTACK_LEVELS; i++ )
for( int j=0; j<NUM_ATTACKS_PER_LEVEL; j++ )
ini.GetValue( "Character", ssprintf("Level%dAttack%d",i+1,j+1), m_sAttacks[i][j] );
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef Character_H
#define Character_H
/*
-----------------------------------------------------------------------------
Class: Character
Desc: An persona that defines attacks for use in battle
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "GameConstantsAndTypes.h"
class Character
{
public:
// Character();
void Load( CString sCharIniPath );
CString m_sFileName;
CString m_sAttacks[NUM_ATTACK_LEVELS][NUM_ATTACKS_PER_LEVEL];
};
#endif
+10 -4
View File
@@ -182,10 +182,16 @@ const CString GROUP_ALL_MUSIC = "";
//
// Battle stuff
//
const int ITEM_NONE = -1;
const int NUM_ITEM_SLOTS = 3;
const int NUM_INVENTORY_SLOTS = 3;
enum AttackLevel
{
ATTACK_LEVEL_1,
ATTACK_LEVEL_2,
ATTACK_LEVEL_3,
NUM_ATTACK_LEVELS
};
const int NUM_ATTACKS_PER_LEVEL = 3;
const int ITEM_NONE = -1;
const CString BG_ANIMS_DIR = "BGAnimations/";
+69 -11
View File
@@ -94,14 +94,32 @@ void GameState::Reset()
void GameState::Update( float fDelta )
{
int p;
for( p=0; p<NUM_PLAYERS; p++ )
for( int p=0; p<NUM_PLAYERS; p++ )
{
m_CurrentPlayerOptions[p].Approach( m_PlayerOptions[p], fDelta );
for( p=0; p<NUM_PLAYERS; p++ )
if(m_Position[p]) m_Position[p]->Update(fDelta);
}
m_bActiveAttackEndedThisUpdate[p] = false;
for( unsigned s=0; s<NUM_INVENTORY_SLOTS; s++ )
{
if( m_sActiveAttacks[p][s].fSecsRemaining > 0 )
{
m_sActiveAttacks[p][s].fSecsRemaining -= fDelta;
if( m_sActiveAttacks[p][s].fSecsRemaining <= 0 )
{
m_sActiveAttacks[p][s].fSecsRemaining = 0;
m_sActiveAttacks[p][s].sModifier = "";
m_bActiveAttackEndedThisUpdate[p] = true;
}
}
}
if( m_bActiveAttackEndedThisUpdate[p] )
RebuildPlayerOptionsFromActiveAttacks( (PlayerNumber)p );
}
}
void GameState::ResetLastRanking()
{
@@ -121,10 +139,6 @@ void GameState::ResetMusicStatistics()
m_fCurBPS = 10;
m_bFreeze = false;
m_bPastHereWeGo = false;
for( int p=0; p<NUM_PLAYERS; p++ )
for( int s=0; s<NUM_ITEM_SLOTS; s++ )
m_iItems[p][s] = ITEM_NONE;
}
void GameState::UpdateSongPosition(float fPositionSeconds)
@@ -229,10 +243,15 @@ bool GameState::IsPlayable( const ModeChoice& mc )
bool GameState::IsPlayerEnabled( PlayerNumber pn )
{
// no longer necessary
// if( GAMESTATE->m_bIsOnSystemMenu ) // if no style set (we're in TitleMenu, ConfigInstruments or something)
// return true; // allow input from both sides
// In battle, all players are present. Non-human players are CPU controlled.
if( m_PlayMode == PLAY_MODE_BATTLE )
return true;
return IsHumanPlayer( pn );
}
bool GameState::IsHumanPlayer( PlayerNumber pn )
{
if( m_CurStyle == STYLE_INVALID ) // no style chosen
if( this->m_bPlayersCanJoin )
return m_bSideIsJoined[pn]; // only allow input from sides that have already joined
@@ -252,6 +271,12 @@ bool GameState::IsPlayerEnabled( PlayerNumber pn )
}
}
bool GameState::IsCpuPlayer( PlayerNumber pn )
{
return IsPlayerEnabled(pn) && !IsHumanPlayer(pn);
}
bool GameState::IsCourseMode() const
{
switch(m_PlayMode)
@@ -345,3 +370,36 @@ void GameState::RestoreSelectedOptions()
GAMESTATE->m_PlayerOptions[p] = GAMESTATE->m_StoredPlayerOptions[p];
m_SongOptions = m_StoredSongOptions;
}
void GameState::ActivateAttack( PlayerNumber target, ActiveAttack aa )
{
// search for an open slot
for( unsigned s=0; s<NUM_INVENTORY_SLOTS; s++ )
if( m_sActiveAttacks[target][s].fSecsRemaining <= 0 )
{
m_sActiveAttacks[target][s] = aa;
return;
}
}
void GameState::RemoveAllActiveAttacks()
{
for( int p=0; p<NUM_PLAYERS; p++ )
for( unsigned s=0; s<NUM_INVENTORY_SLOTS; s++ )
{
m_sActiveAttacks[p][s].fSecsRemaining = 0;
m_sActiveAttacks[p][s].sModifier = "";
}
}
void GameState::RebuildPlayerOptionsFromActiveAttacks( PlayerNumber pn )
{
// rebuild player options
PlayerOptions po = GAMESTATE->m_StoredPlayerOptions[pn];
for( int s=0; s<NUM_INVENTORY_SLOTS; s++ )
{
po.FromString( m_sActiveAttacks[pn][s].sModifier );
}
GAMESTATE->m_PlayerOptions[pn] = po;
}
+27 -2
View File
@@ -65,8 +65,20 @@ public:
void ApplyModeChoice( const ModeChoice& mc, PlayerNumber pn );
bool IsPlayable( const ModeChoice& mc );
void GetPlayerInfo( PlayerNumber pn, bool& bIsEnabledOut, bool& bIsHumanOut );
bool IsPlayerEnabled( PlayerNumber pn );
bool IsPlayerEnabled( int p ) { return IsPlayerEnabled( (PlayerNumber)p ); }; // for those too lasy to cast all those p's to a PlayerNumber
bool IsPlayerEnabled( int p ) { return IsPlayerEnabled( (PlayerNumber)p ); };
bool IsHumanPlayer( PlayerNumber pn );
bool IsHumanPlayer( int p ) { return IsHumanPlayer( (PlayerNumber)p ); };
bool IsCpuPlayer( PlayerNumber pn );
bool IsCpuPlayer( int p ) { return IsCpuPlayer( (PlayerNumber)p ); };
bool AnyPlayersAreCpu()
{
for( int p=0; p<NUM_PLAYERS; p++ )
if( IsCpuPlayer(p) )
return true;
return false;
}
bool IsCourseMode() const;
CString m_sLoadingMessage; // used in loading screen
@@ -136,7 +148,20 @@ public:
void RestoreSelectedOptions();
int m_iItems[NUM_PLAYERS][NUM_ITEM_SLOTS];
CString m_sCharacterName[NUM_PLAYERS];
AttackLevel m_MaxAttackLevel[NUM_PLAYERS];
CString m_sAttacks[NUM_PLAYERS][NUM_ATTACK_LEVELS][NUM_ATTACKS_PER_LEVEL];
CString m_sInventory[NUM_PLAYERS][NUM_INVENTORY_SLOTS];
struct ActiveAttack
{
float fSecsRemaining;
CString sModifier;
};
ActiveAttack m_sActiveAttacks[NUM_PLAYERS][NUM_INVENTORY_SLOTS];
bool m_bActiveAttackEndedThisUpdate[NUM_PLAYERS]; // flag so we can play sounds
void ActivateAttack( PlayerNumber target, ActiveAttack aa );
void RebuildPlayerOptionsFromActiveAttacks( PlayerNumber pn );
void RemoveAllActiveAttacks(); // called on end of song
bool HasEarnedExtraStage();
bool m_bAllow2ndExtraStage; //only used when "Allow Selection of Extra Stage is on"
+70 -124
View File
@@ -15,167 +15,113 @@
#include "RageUtil.h"
#include "GameState.h"
CachedThemeMetricF ATTACK_DURATION_SECONDS ("Inventory","AttackDurationSeconds");
CachedThemeMetricI COMBO_PER_ATTACK_LEVEL ("Inventory","ComboPerAttackLevel");
#define NUM_ITEM_TYPES THEME->GetMetricF("Inventory","NumItemTypes")
#define ITEM_DURATION_SECONDS THEME->GetMetricF("Inventory","ItemDurationSeconds")
#define ITEM_COMBO( i ) THEME->GetMetricI("Inventory",ssprintf("Item%dCombo",i+1))
#define ITEM_EFFECT( i ) THEME->GetMetric ("Inventory",ssprintf("Item%dEffect",i+1))
const PlayerNumber OPPOSITE_PLAYER[NUM_PLAYERS] = { PLAYER_2, PLAYER_1 };
Inventory::Inventory()
{
RefreshPossibleItems();
ATTACK_DURATION_SECONDS.Refresh();
COMBO_PER_ATTACK_LEVEL.Refresh();
}
void Inventory::Load( PlayerNumber pn )
{
m_PlayerNumber = pn;
m_iLastSeenCombo = 0;
// don't load battle sounds if they're not going to be used
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_BATTLE:
m_soundAcquireItem.Load( THEME->GetPathTo("Sounds","gameplay battle aquire item") );
m_soundUseItem.Load( THEME->GetPathTo("Sounds","gameplay battle use item") );
m_soundItemEnding.Load( THEME->GetPathTo("Sounds","gameplay battle item ending") );
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
m_soundAcquireItem.Load( THEME->GetPathTo("Sounds",ssprintf("Inventory aquire p%d",p+1)) );
m_soundUseItem.Load( THEME->GetPathTo("Sounds",ssprintf("Inventory use p%d",p+1)) );
m_soundItemEnding.Load( THEME->GetPathTo("Sounds",ssprintf("Inventory finished p%d",p+1)) );
}
}
break;
}
}
void Inventory::RefreshPossibleItems()
{
m_ItemDefs.clear();
for( int i=0; i<NUM_ITEM_TYPES; i++ )
{
ItemDef def;
def.comboLevel = ITEM_COMBO(i);
def.effect = ITEM_EFFECT(i);
m_ItemDefs.push_back( def );
}
}
void Inventory::Update( float fDelta )
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
bool bActiveItemsChanged = false;
for( int i=m_ActiveItems[p].size()-1; i>=0; i-- )
{
ActiveItem& active_item = m_ActiveItems[p][i];
active_item.fSecondsLeft -= fDelta;
if( active_item.fSecondsLeft < 0 )
{
m_ActiveItems[p].erase( m_ActiveItems[p].begin()+i );
bActiveItemsChanged = true;
}
}
if( GAMESTATE->m_bActiveAttackEndedThisUpdate[m_PlayerNumber] )
m_soundItemEnding.Play();
if( bActiveItemsChanged )
PlayerNumber pn = m_PlayerNumber;
// check to see if they deserve a new item
if( GAMESTATE->m_CurStageStats.iCurCombo[pn] != m_iLastSeenCombo )
{
int iOldCombo = m_iLastSeenCombo;
m_iLastSeenCombo = GAMESTATE->m_CurStageStats.iCurCombo[pn];
int iNewCombo = m_iLastSeenCombo;
int iLevelOfOldCombo = (iOldCombo/COMBO_PER_ATTACK_LEVEL) - 1;
int iLevelOfNewCombo = (iNewCombo/COMBO_PER_ATTACK_LEVEL) - 1;
if( iLevelOfOldCombo < iLevelOfNewCombo && // combo increasing
iLevelOfNewCombo >= ATTACK_LEVEL_1 ) // attack level not negative
{
RebuildPlayerOptions( (PlayerNumber)p );
m_soundItemEnding.Play();
// they deserve a new item
CLAMP( iLevelOfNewCombo, 0, GAMESTATE->m_MaxAttackLevel[pn] );
AttackLevel al = (AttackLevel)iLevelOfNewCombo;
AwardItem( al );
}
}
}
bool Inventory::OnComboBroken( PlayerNumber pn, int iCombo )
void Inventory::AwardItem( AttackLevel al )
{
int* iItems = GAMESTATE->m_iItems[pn];
// search for the first open slot
int iOpenSlot = -1;
// search for the item acquired
int item;
for( item=0; item<(int)m_ItemDefs.size(); item++ )
if( m_ItemDefs[item].comboLevel > iCombo )
break;
CString* asInventory = GAMESTATE->m_sInventory[m_PlayerNumber]; //[NUM_INVENTORY_SLOTS]
CString* asAttacks = GAMESTATE->m_sAttacks[m_PlayerNumber][al]; //[NUM_ATTACKS_PER_LEVEL]
item--; // back up because we went one too far
if( item == -1 ) // no item acquired
return false;
if( asInventory[NUM_INVENTORY_SLOTS/2] == "" )
iOpenSlot = NUM_INVENTORY_SLOTS/2;
else
{
// give them an item
// search for the first open slot
int iOpenSlot = -1;
if( iItems[NUM_ITEM_SLOTS/2] == ITEM_NONE )
iOpenSlot = NUM_ITEM_SLOTS/2;
else
{
for( int s=0; s<NUM_ITEM_SLOTS; s++ )
if( iItems[s] == ITEM_NONE )
{
iOpenSlot = s;
break;
}
}
if( iOpenSlot != -1 )
{
iItems[iOpenSlot] = item;
m_soundAcquireItem.Play();
}
// else not enough room to insert item
for( int s=0; s<NUM_INVENTORY_SLOTS; s++ )
if( asInventory[s] == "" )
{
iOpenSlot = s;
break;
}
}
return true;
if( iOpenSlot != -1 )
{
CString sAttackToGive = asAttacks[ rand()%NUM_ATTACKS_PER_LEVEL ];
asInventory[iOpenSlot] = sAttackToGive;
m_soundAcquireItem.Play();
}
// else not enough room to insert item
}
void Inventory::UseItem( PlayerNumber pn, int iSlot )
void Inventory::UseAttack( int iSlot )
{
int* iItems = GAMESTATE->m_iItems[pn];
CString* asInventory = GAMESTATE->m_sInventory[m_PlayerNumber]; //[NUM_INVENTORY_SLOTS]
if( iItems[iSlot] == ITEM_NONE )
if( asInventory[iSlot] == "" )
return;
int iItemIndex = iItems[iSlot];
PlayerNumber pnToAttack = OPPOSITE_PLAYER[m_PlayerNumber];
PlayerNumber pnToAttack;
switch( pn )
{
case PLAYER_1: pnToAttack = PLAYER_2; break;
case PLAYER_2: pnToAttack = PLAYER_1; break;
default: ASSERT(0); pnToAttack = PLAYER_1; break;
}
GameState::ActiveAttack aa;
aa.fSecsRemaining = ATTACK_DURATION_SECONDS;
aa.sModifier = asInventory[iSlot];
// see if there is already an active instance of this item index
bool bAddedToExisting = false;
for( unsigned i=0; i<m_ActiveItems[pnToAttack].size(); i++ )
{
if( m_ActiveItems[pnToAttack][i].iItemDefIndex == iItemIndex )
{
m_ActiveItems[pnToAttack][i].fSecondsLeft += ITEM_DURATION_SECONDS;
bAddedToExisting = true;
}
}
if( !bAddedToExisting )
{
ActiveItem ai = { ITEM_DURATION_SECONDS, iItemIndex };
m_ActiveItems[pnToAttack].push_back( ai );
}
RebuildPlayerOptions( pnToAttack );
GAMESTATE->ActivateAttack( pnToAttack, aa );
GAMESTATE->RebuildPlayerOptionsFromActiveAttacks( pnToAttack );
// remove the item
iItems[iSlot] = ITEM_NONE;
asInventory[iSlot] = "";
m_soundUseItem.Play();
}
void Inventory::RebuildPlayerOptions( PlayerNumber pn )
{
// rebuild player options
PlayerOptions po = GAMESTATE->m_StoredPlayerOptions[pn];
for( int i=0; i<(int)m_ActiveItems[pn].size(); i++ )
{
int iItemDefIndex = m_ActiveItems[pn][i].iItemDefIndex;
po.FromString( m_ItemDefs[iItemDefIndex].effect );
}
GAMESTATE->m_PlayerOptions[pn] = po;
}
void Inventory::RemoveAllActiveItems()
{
for( int p=0; p<NUM_PLAYERS; p++ )
m_ActiveItems[p].clear();
}
+7 -23
View File
@@ -14,41 +14,25 @@
#include "Actor.h"
#include "PlayerNumber.h"
#include "RageSound.h"
#include "GameConstantsAndTypes.h"
class Inventory : public Actor
{
public:
Inventory();
void Reset();
void RefreshPossibleItems();
void Load( PlayerNumber pn );
virtual void Update( float fDelta );
virtual void DrawPrimitives() {};
bool OnComboBroken( PlayerNumber pn, int iCombo );
void UseItem( PlayerNumber pn, int iSlot );
void RemoveAllActiveItems(); // called on end of song
struct ItemDef
{
int comboLevel;
CString effect;
bool operator<( const ItemDef& other ) const { return comboLevel < other.comboLevel; }
void Sort( vector<ItemDef>& items ) { sort( items.begin(), items.end() ); }
};
vector<ItemDef> m_ItemDefs;
struct ActiveItem
{
float fSecondsLeft;
int iItemDefIndex;
};
vector<ActiveItem> m_ActiveItems[NUM_PLAYERS];
void UseAttack( int iSlot );
protected:
void RebuildPlayerOptions( PlayerNumber pn );
void AwardItem( AttackLevel al );
PlayerNumber m_PlayerNumber;
int m_iLastSeenCombo;
RageSound m_soundAcquireItem;
RageSound m_soundUseItem;
+28 -60
View File
@@ -18,85 +18,53 @@
#include "GameState.h"
#include "ThemeManager.h"
ScoreDisplayBattle::ScoreDisplayBattle()
{
LOG->Trace( "ScoreDisplayBattle::ScoreDisplayBattle()" );
for( int i=0; i<NUM_ITEM_SLOTS; i++ )
for( int i=0; i<NUM_INVENTORY_SLOTS; i++ )
{
float fX = (float)SCALE(i,0.f,2.f,-60.f,60.f);
m_sprFrames[i].Load( THEME->GetPathTo("Graphics","gameplay battle item frames 3x1") );
m_sprFrames[i].SetX( fX );
m_sprFrames[i].StopAnimating();
m_sprFrames[i].SetState( i );
this->AddChild( &m_sprFrames[i] );
m_sprItems[i].SetX( fX );
m_sprItems[i].Load( THEME->GetPathTo("Graphics","gameplay battle item icons") );
m_sprItems[i].StopAnimating();
m_sprItems[i].SetZoom( 0 );
this->AddChild( &m_sprItems[i] );
m_iLastSeenItems[i] = ITEM_NONE;
m_Inventory[i].SetX( fX );
this->AddChild( &m_Inventory[i] );
}
}
void ScoreDisplayBattle::Init( PlayerNumber pn )
{
ScoreDisplay::Init( pn );
for( int i=0; i<NUM_INVENTORY_SLOTS; i++ )
m_Inventory[i].Load( m_PlayerNumber, "" );
}
void ScoreDisplayBattle::Update( float fDelta )
{
ScoreDisplay::Update( fDelta );
for( int s=0; s<NUM_ITEM_SLOTS; s++ )
for( int s=0; s<NUM_INVENTORY_SLOTS; s++ )
{
int iNewItem = GAMESTATE->m_iItems[m_PlayerNumber][s];
int iOldItem = m_iLastSeenItems[s];
CString sNewItem = GAMESTATE->m_sInventory[m_PlayerNumber][s];
m_iLastSeenItems[s] = iNewItem;
if( iNewItem != iOldItem ) // there was a change of items
if( sNewItem != m_iLastSeenInventory[s] )
{
if( iNewItem == ITEM_NONE )
{
m_sprItems[s].StopTweening();
m_sprItems[s].BeginTweening( 0.25f, Actor::TWEEN_BOUNCE_BEGIN );
m_sprItems[s].SetTweenZoom( 0 );
}
m_iLastSeenInventory[s] = sNewItem;
m_Inventory[s].Load( m_PlayerNumber, sNewItem );
if( sNewItem == "" )
m_Inventory[s].Command( "linear,0.25;zoom,0" );
else
{
m_sprItems[s].SetDiffuse( RageColor(1,1,1,1) );
m_sprItems[s].SetState( iNewItem );
m_sprItems[s].SetZoom( 1 );
// blink
m_sprItems[s].StopTweening();
m_sprItems[s].BeginTweening( 0.1f ); // sleep
m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,1) );
m_sprItems[s].BeginTweening( 0.1f ); // sleep
m_sprItems[s].BeginTweening( 0.001f ); // snap
m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,0) );
m_sprItems[s].BeginTweening( 0.1f ); // sleep
m_sprItems[s].BeginTweening( 0.001f ); // snap
m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,1) );
m_sprItems[s].BeginTweening( 0.1f ); // sleep
m_sprItems[s].BeginTweening( 0.001f ); // snap
m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,0) );
m_sprItems[s].BeginTweening( 0.1f ); // sleep
m_sprItems[s].BeginTweening( 0.001f ); // snap
m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,1) );
m_sprItems[s].BeginTweening( 0.1f ); // sleep
m_sprItems[s].BeginTweening( 0.001f ); // snap
m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,0) );
m_sprItems[s].BeginTweening( 0.1f ); // sleep
m_sprItems[s].BeginTweening( 0.001f ); // snap
m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,1) );
m_sprItems[s].BeginTweening( 0.1f ); // sleep
m_sprItems[s].BeginTweening( 0.001f ); // snap
m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,0) );
m_sprItems[s].BeginTweening( 0.1f ); // sleep
m_sprItems[s].BeginTweening( 0.001f ); // snap
m_sprItems[s].SetTweenDiffuse( RageColor(1,1,1,1) );
m_Inventory[s].StopTweening();
m_Inventory[s].Command( "diffuse,1,1,1,1;zoom,1;"
"sleep,0.1;linear,0;diffusealpha,0;"
"sleep,0.1;linear,0;diffusealpha,1;"
"sleep,0.1;linear,0;diffusealpha,0;"
"sleep,0.1;linear,0;diffusealpha,1;"
"sleep,0.1;linear,0;diffusealpha,0;"
"sleep,0.1;linear,0;diffusealpha,1;" );
}
}
}
+4 -5
View File
@@ -12,23 +12,22 @@
*/
#include "ScoreDisplay.h"
#include "Sprite.h"
#include "GameConstantsAndTypes.h"
#include "OptionIcon.h"
class ScoreDisplayBattle : public ScoreDisplay
{
public:
ScoreDisplayBattle();
virtual void Init( PlayerNumber pn );
virtual void Update( float fDelta );
protected:
Sprite m_sprFrames[NUM_ITEM_SLOTS];
Sprite m_sprItems[NUM_ITEM_SLOTS];
OptionIcon m_Inventory[NUM_INVENTORY_SLOTS];
int m_iLastSeenItems[NUM_ITEM_SLOTS];
CString m_iLastSeenInventory[NUM_INVENTORY_SLOTS];
};
#endif
+2 -10
View File
@@ -308,16 +308,8 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa
case TNS_GOOD:
case TNS_BOO:
case TNS_MISS:
// don't play "combo stopped" in battle
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_BATTLE:
if( pInventory )
pInventory->OnComboBroken( m_PlayerNumber, iCurCombo );
default:
if( iCurCombo>50 )
SCREENMAN->PostMessageToTopScreen( SM_ComboStopped, 0 );
}
if( iCurCombo>50 )
SCREENMAN->PostMessageToTopScreen( SM_ComboStopped, 0 );
iCurCombo = 0;
break;
+2
View File
@@ -273,6 +273,7 @@ void Screen::ClearMessageQueue( const ScreenMessage SM )
#include "ScreenStyleSplash.h"
#include "ScreenAutogenOptions.h"
#include "ScreenCredits.h"
#include "ScreenSelectCharacter.h"
Screen* Screen::Create( CString sClassName )
{
@@ -334,6 +335,7 @@ Screen* Screen::Create( CString sClassName )
else if( 0==stricmp(sClassName, "ScreenStyleSplash") ) ret = new ScreenStyleSplash;
else if( 0==stricmp(sClassName, "ScreenAutogenOptions") ) ret = new ScreenAutogenOptions;
else if( 0==stricmp(sClassName, "ScreenCredits") ) ret = new ScreenCredits;
else if( 0==stricmp(sClassName, "ScreenSelectCharacter") ) ret = new ScreenSelectCharacter;
else
RageException::Throw( "Invalid Screen class name '%s'", sClassName.GetString() );
return ret;
+10 -7
View File
@@ -222,7 +222,7 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
m_TimingAssist.Load((PlayerNumber)p, &m_Player[p]);
m_ActiveItemList[p].Init( (PlayerNumber)p, &m_Inventory );
m_ActiveItemList[p].Init( (PlayerNumber)p );
/* Position it in LoadNextSong. */
this->AddChild( &m_ActiveItemList[p] );
@@ -398,8 +398,11 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
m_BPMDisplay.SetZoom( BPM_ZOOM );
this->AddChild( &m_BPMDisplay );
m_Inventory.RefreshPossibleItems();
this->AddChild( &m_Inventory );
for( p=0; p<NUM_PLAYERS; p++ )
{
m_Inventory[p].Load( (PlayerNumber)p );
this->AddChild( &m_Inventory[p] );
}
if( !bDemonstration ) // only load if we're going to use it
@@ -573,7 +576,7 @@ void ScreenGameplay::LoadNextSong()
NoteData pNewNoteData;
pStyleDef->GetTransformedNoteDataForStyle( (PlayerNumber)p, &pOriginalNoteData, &pNewNoteData );
m_Player[p].Load( (PlayerNumber)p, &pNewNoteData, m_pLifeMeter[p], m_pScoreDisplay[p], &m_Inventory, m_pScoreKeeper[p] );
m_Player[p].Load( (PlayerNumber)p, &pNewNoteData, m_pLifeMeter[p], m_pScoreDisplay[p], &m_Inventory[p], m_pScoreKeeper[p] );
m_TimingAssist.Reset();
}
@@ -1074,7 +1077,7 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
}
if( iItemSlot != -1 )
m_Inventory.UseItem( MenuI.player, iItemSlot );
m_Inventory[MenuI.player].UseAttack( iItemSlot );
}
}
@@ -1110,7 +1113,7 @@ void SaveChanges()
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
{
// FIXME
// FIXME!!!
//for( int i=0; i<m_apSongsQueue.size(); i++ )
// m_apSongsQueue[i]->Save();
}
@@ -1214,7 +1217,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
}
}
m_Inventory.RemoveAllActiveItems();
GAMESTATE->RemoveAllActiveAttacks();
for( p=0; p<NUM_PLAYERS; p++ )
{
+1 -1
View File
@@ -134,7 +134,7 @@ protected:
Player m_Player[NUM_PLAYERS];
Inventory m_Inventory;
Inventory m_Inventory[NUM_PLAYERS];
ActiveItemList m_ActiveItemList[NUM_PLAYERS];
DifficultyIcon m_DifficultyIcon[NUM_PLAYERS];
+1 -1
View File
@@ -219,7 +219,7 @@ void ScreenSelect::HandleScreenMessage( const ScreenMessage SM )
case SM_AllDoneChoosing:
{
for( int p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled((PlayerNumber)p) )
if( GAMESTATE->IsHumanPlayer(p) )
GAMESTATE->ApplyModeChoice( m_aModeChoices[this->GetSelectionIndex((PlayerNumber)p)], (PlayerNumber)p );
GAMESTATE->m_bPlayersCanJoin = false;
+379
View File
@@ -0,0 +1,379 @@
#include "global.h"
/*
-----------------------------------------------------------------------------
Class: ScreenSelectCharacter
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "ScreenSelectCharacter.h"
#include "ScreenManager.h"
#include "RageUtil.h"
#include "RageLog.h"
#include "ThemeManager.h"
#include "AnnouncerManager.h"
#include "GameState.h"
#define TITLE_ON_COMMAND( p ) THEME->GetMetric ("ScreenSelectCharacter",ssprintf("TitleP%dOnCommand",p+1))
#define TITLE_OFF_COMMAND( p ) THEME->GetMetric ("ScreenSelectCharacter",ssprintf("TitleP%dOffCommand",p+1))
#define CHARACTER_ON_COMMAND( p ) THEME->GetMetric ("ScreenSelectCharacter",ssprintf("CharacterP%dOnCommand",p+1))
#define CHARACTER_OFF_COMMAND( p ) THEME->GetMetric ("ScreenSelectCharacter",ssprintf("CharacterP%dOffCommand",p+1))
#define CHARACTER_ARROWS_ON_COMMAND( p ) THEME->GetMetric ("ScreenSelectCharacter",ssprintf("CharacterArrowsP%dOnCommand",p+1))
#define CHARACTER_ARROWS_OFF_COMMAND( p ) THEME->GetMetric ("ScreenSelectCharacter",ssprintf("CharacterArrowsP%dOffCommand",p+1))
#define EXPLANATION_ON_COMMAND THEME->GetMetric ("ScreenSelectCharacter","ExplanationOnCommand")
#define EXPLANATION_OFF_COMMAND THEME->GetMetric ("ScreenSelectCharacter","ExplanationOffCommand")
#define ATTACK_FRAME_ON_COMMAND( p ) THEME->GetMetric ("ScreenSelectCharacter",ssprintf("AttackFrameP%dOnCommand",p+1))
#define ATTACK_FRAME_OFF_COMMAND( p ) THEME->GetMetric ("ScreenSelectCharacter",ssprintf("AttackFrameP%dOffCommand",p+1))
#define ICONS_START_X( p ) THEME->GetMetricF("ScreenSelectCharacter",ssprintf("IconsP%dStartX",p+1))
#define ICONS_START_Y( p ) THEME->GetMetricF("ScreenSelectCharacter",ssprintf("IconsP%dStartY",p+1))
#define ICONS_SPACING_X THEME->GetMetricF("ScreenSelectCharacter","IconsSpacingX")
#define ICONS_SPACING_Y THEME->GetMetricF("ScreenSelectCharacter","IconsSpacingY")
#define HELP_TEXT THEME->GetMetric ("ScreenSelectCharacter","HelpText")
#define TIMER_SECONDS THEME->GetMetricI("ScreenSelectCharacter","TimerSeconds")
#define NEXT_SCREEN THEME->GetMetric ("ScreenSelectCharacter","NextScreen")
#define LEVEL_CURSOR_X( p, l ) ( ICONS_START_X(p)+ICONS_SPACING_X*((NUM_ATTACKS_PER_LEVEL-1)/2.f) )
#define LEVEL_CURSOR_Y( p, l ) ( ICONS_START_Y(p)+ICONS_SPACING_Y*l )
const PlayerNumber CPU_PLAYER[NUM_PLAYERS] = { PLAYER_2, PLAYER_1 };
ScreenSelectCharacter::ScreenSelectCharacter()
{
LOG->Trace( "ScreenSelectCharacter::ScreenSelectCharacter()" );
m_Menu.Load( "ScreenSelectCharacter" );
this->AddChild( &m_Menu );
int p;
for( p=0; p<NUM_PLAYERS; p++ )
{
m_iSelectedCharacter[p] = 0;
m_iSelectedLevelIndex[p] = 0;
if( GAMESTATE->IsPlayerEnabled(p) )
m_SelectionRow[p] = CHOOSING_HUMAN_CHARACTER;
}
CStringArray asCharacterPaths;
GetDirListing( "Characters/*.ini", asCharacterPaths, false, true );
for( int i=0; i<asCharacterPaths.size(); i++ )
{
m_vCharacters.resize( m_vCharacters.size()+1 );
m_vCharacters[i].Load( asCharacterPaths[i] );
}
for( p=0; p<NUM_PLAYERS; p++ )
{
m_sprTitle[p].Load( THEME->GetPathTo("Graphics","ScreenSelectCharacter title 2x2") );
m_sprTitle[p].SetState( GAMESTATE->IsHumanPlayer(p) ? p : 2+p );
m_sprTitle[p].StopAnimating();
m_sprTitle[p].Command( TITLE_ON_COMMAND(p) );
this->AddChild( &m_sprTitle[p] );
m_sprCharacter[p].Command( CHARACTER_ON_COMMAND(p) );
this->AddChild( &m_sprCharacter[p] );
m_sprCharacterArrows[p].Load( THEME->GetPathTo("Graphics","ScreenSelectCharacter character arrows") );
m_sprCharacterArrows[p].Command( CHARACTER_ARROWS_ON_COMMAND(p) );
this->AddChild( &m_sprCharacterArrows[p] );
m_sprAttackFrame[p].Load( THEME->GetPathTo("Graphics","ScreenSelectCharacter attack frame 1x2") );
m_sprAttackFrame[p].StopAnimating();
m_sprAttackFrame[p].SetState( p );
m_sprAttackFrame[p].Command( ATTACK_FRAME_ON_COMMAND(p) );
this->AddChild( &m_sprAttackFrame[p] );
for( int i=0; i<NUM_ATTACK_LEVELS; i++ )
for( int j=0; j<NUM_ATTACKS_PER_LEVEL; j++ )
{
float fX = ICONS_START_X(p) + ICONS_SPACING_X*j;
float fY = ICONS_START_Y(p) + ICONS_SPACING_Y*i;
m_AttackIcons[p][i][j].SetXY( fX, fY );
this->AddChild( &m_AttackIcons[p][i][j] );
}
m_sprLevelCursor[p].Load( THEME->GetPathTo("Graphics","ScreenSelectCharacter level cursor") );
int iLevelIndex = m_iSelectedLevelIndex[p];
m_sprLevelCursor[p].SetXY( LEVEL_CURSOR_X(p,iLevelIndex), LEVEL_CURSOR_Y(p,iLevelIndex) );
m_sprLevelCursor[p].Load( THEME->GetPathTo("Graphics","ScreenSelectCharacter level cursor") );
this->AddChild( &m_sprLevelCursor[p] );
}
m_sprExplanation.Load( THEME->GetPathTo("Graphics","ScreenSelectCharacter explanation") );
m_sprExplanation.Command( EXPLANATION_ON_COMMAND );
this->AddChild( &m_sprExplanation );
m_soundChange.Load( THEME->GetPathTo("Sounds","ScreenSelectCharacter change") );
m_soundSelect.Load( THEME->GetPathTo("Sounds","Common start") );
SOUNDMAN->PlayOnceFromDir( ANNOUNCER->GetPathTo("select group intro") );
SOUNDMAN->PlayMusic( THEME->GetPathTo("Sounds","ScreenSelectCharacter music") );
for( p=0; p<NUM_PLAYERS; p++ )
{
if( GAMESTATE->IsHumanPlayer(p) )
{
AfterRowChange( (PlayerNumber)p );
AfterValueChange( (PlayerNumber)p );
}
}
TweenOnScreen();
}
ScreenSelectCharacter::~ScreenSelectCharacter()
{
LOG->Trace( "ScreenSelectCharacter::~ScreenSelectCharacter()" );
}
void ScreenSelectCharacter::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI )
{
LOG->Trace( "ScreenSelectCharacter::Input()" );
if( m_Menu.IsTransitioning() )
return;
Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); // default input handler
}
void ScreenSelectCharacter::DrawPrimitives()
{
m_Menu.DrawBottomLayer();
Screen::DrawPrimitives();
m_Menu.DrawTopLayer();
}
void ScreenSelectCharacter::HandleScreenMessage( const ScreenMessage SM )
{
switch( SM )
{
case SM_BeginFadingOut:
m_Menu.StartTransitioning( SM_GoToNextScreen );
break;
case SM_MenuTimer:
MenuStart(PLAYER_1);
break;
case SM_GoToPrevScreen:
SCREENMAN->SetNewScreen( "ScreenTitleMenu" );
break;
case SM_GoToNextScreen:
SCREENMAN->SetNewScreen( NEXT_SCREEN );
break;
}
}
PlayerNumber ScreenSelectCharacter::GetAffectedPlayerNumber( PlayerNumber pn )
{
switch( m_SelectionRow[pn] )
{
case CHOOSING_HUMAN_CHARACTER:
case CHOOSING_HUMAN_LEVEL:
return pn;
break;
case CHOOSING_CPU_CHARACTER:
case CHOOSING_CPU_LEVEL:
return CPU_PLAYER[pn];
break;
default:
ASSERT(0);
case FINISHED_CHOOSING:
return pn;
}
}
void ScreenSelectCharacter::BeforeRowChange( PlayerNumber pn )
{
PlayerNumber pnAffected = GetAffectedPlayerNumber(pn);
switch( m_SelectionRow[pn] )
{
case CHOOSING_CPU_CHARACTER:
case CHOOSING_HUMAN_CHARACTER:
m_sprCharacterArrows[pnAffected].SetEffectNone();
break;
case CHOOSING_CPU_LEVEL:
case CHOOSING_HUMAN_LEVEL:
m_sprLevelCursor[pnAffected].SetEffectNone();
break;
}
}
void ScreenSelectCharacter::AfterRowChange( PlayerNumber pn )
{
PlayerNumber pnAffected = GetAffectedPlayerNumber(pn);
switch( m_SelectionRow[pn] )
{
case CHOOSING_CPU_CHARACTER:
case CHOOSING_HUMAN_CHARACTER:
m_sprCharacterArrows[pnAffected].SetEffectGlowShift();
break;
case CHOOSING_CPU_LEVEL:
case CHOOSING_HUMAN_LEVEL:
m_sprLevelCursor[pnAffected].SetEffectGlowShift();
break;
}
}
void ScreenSelectCharacter::AfterValueChange( PlayerNumber pn )
{
PlayerNumber pnAffected = GetAffectedPlayerNumber(pn);
switch( m_SelectionRow[pn] )
{
case CHOOSING_CPU_CHARACTER:
case CHOOSING_HUMAN_CHARACTER:
{
Character& character = m_vCharacters[ m_iSelectedCharacter[pnAffected] ];
CStringArray asGraphicPaths;
GetDirListing( "Characters/" + character.m_sFileName + ".png", asGraphicPaths, false, true );
GetDirListing( "Characters/" + character.m_sFileName + ".jpg", asGraphicPaths, false, true );
GetDirListing( "Characters/" + character.m_sFileName + ".gif", asGraphicPaths, false, true );
GetDirListing( "Characters/" + character.m_sFileName + ".bmp", asGraphicPaths, false, true );
if( asGraphicPaths.empty() )
m_sprCharacter[pnAffected].UnloadTexture();
else
m_sprCharacter[pnAffected].Load( asGraphicPaths[0] );
for( int i=0; i<NUM_ATTACK_LEVELS; i++ )
for( int j=0; j<NUM_ATTACKS_PER_LEVEL; j++ )
m_AttackIcons[pnAffected][i][j].Load( pnAffected, character.m_sAttacks[i][j] );
}
break;
case CHOOSING_CPU_LEVEL:
case CHOOSING_HUMAN_LEVEL:
{
int iLevelIndex = m_iSelectedLevelIndex[pnAffected];
m_sprLevelCursor[pnAffected].SetXY( LEVEL_CURSOR_X(pnAffected,iLevelIndex), LEVEL_CURSOR_Y(pnAffected,iLevelIndex) );
}
break;
case FINISHED_CHOOSING:
; // do nothing
break;
default:
ASSERT(0);
}
}
void ScreenSelectCharacter::MenuLeft( PlayerNumber pn )
{
MenuUp( pn );
}
void ScreenSelectCharacter::MenuRight( PlayerNumber pn )
{
MenuDown( pn );
}
void ScreenSelectCharacter::MenuUp( PlayerNumber pn )
{
Move( pn, -1 );
}
void ScreenSelectCharacter::MenuDown( PlayerNumber pn )
{
Move( pn, +1 );
}
void ScreenSelectCharacter::Move( PlayerNumber pn, int deltaValue )
{
PlayerNumber pnAffected = GetAffectedPlayerNumber(pn);
switch( m_SelectionRow[pn] )
{
case CHOOSING_CPU_CHARACTER:
case CHOOSING_HUMAN_CHARACTER:
m_iSelectedCharacter[pnAffected] = (m_iSelectedCharacter[pnAffected]+deltaValue)+m_vCharacters.size();
m_iSelectedCharacter[pnAffected] %= m_vCharacters.size();
AfterValueChange(pn);
m_soundChange.PlayRandom();
break;
case CHOOSING_CPU_LEVEL:
case CHOOSING_HUMAN_LEVEL:
m_iSelectedLevelIndex[pnAffected] += deltaValue;
CLAMP( m_iSelectedLevelIndex[pnAffected], 0, NUM_ATTACK_LEVELS-1 );
AfterValueChange(pn);
m_soundChange.PlayRandom();
break;
}
}
void ScreenSelectCharacter::MenuStart( PlayerNumber pn )
{
if( m_SelectionRow[pn] == FINISHED_CHOOSING )
return;
// change row
BeforeRowChange(pn);
switch( m_SelectionRow[pn] )
{
case CHOOSING_HUMAN_CHARACTER:
m_SelectionRow[pn] = CHOOSING_HUMAN_LEVEL;
break;
case CHOOSING_HUMAN_LEVEL:
m_SelectionRow[pn] = GAMESTATE->AnyPlayersAreCpu() ? CHOOSING_CPU_CHARACTER : FINISHED_CHOOSING;
break;
case CHOOSING_CPU_CHARACTER:
m_SelectionRow[pn] = CHOOSING_CPU_LEVEL;
break;
case CHOOSING_CPU_LEVEL:
m_SelectionRow[pn] = FINISHED_CHOOSING;
break;
}
AfterRowChange(pn);
AfterValueChange(pn);
m_soundSelect.PlayRandom();
bool bAllAreFinished = true;
for( int p=0; p<NUM_PLAYERS; p++ )
bAllAreFinished &= (m_SelectionRow[p] == FINISHED_CHOOSING);
if( bAllAreFinished )
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
Character& character = m_vCharacters[ m_iSelectedCharacter[p] ];
GAMESTATE->m_sCharacterName[p] = character.m_sFileName;
for( int i=0; i<NUM_ATTACK_LEVELS; i++ )
for( int j=0; j<NUM_ATTACKS_PER_LEVEL; j++ )
GAMESTATE->m_sAttacks[p][i][j] = character.m_sAttacks[i][j];
GAMESTATE->m_MaxAttackLevel[p] = (AttackLevel)m_iSelectedLevelIndex[p];
}
m_Menu.m_MenuTimer.Stop();
TweenOffScreen();
this->PostScreenMessage( SM_BeginFadingOut, 0 );
}
}
void ScreenSelectCharacter::MenuBack( PlayerNumber pn )
{
m_Menu.Back( SM_GoToPrevScreen );
}
void ScreenSelectCharacter::TweenOffScreen()
{
for( int p=0; p<NUM_PLAYERS; p++ )
m_sprCharacter[p].Command( CHARACTER_OFF_COMMAND(p) );
m_sprExplanation.Command( EXPLANATION_OFF_COMMAND );
}
void ScreenSelectCharacter::TweenOnScreen()
{
}
+79
View File
@@ -0,0 +1,79 @@
/*
-----------------------------------------------------------------------------
File: ScreenSelectCharacter.h
Desc: Set the current song group by selecting from a list.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "Screen.h"
#include "Sprite.h"
#include "RandomSample.h"
#include "MenuElements.h"
#include "Character.h"
#include "OptionIcon.h"
class ScreenSelectCharacter : public Screen
{
public:
ScreenSelectCharacter();
virtual ~ScreenSelectCharacter();
virtual void DrawPrimitives();
virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI );
virtual void HandleScreenMessage( const ScreenMessage SM );
void MenuLeft( PlayerNumber pn );
void MenuRight( PlayerNumber pn );
void MenuUp( PlayerNumber pn );
void MenuDown( PlayerNumber pn );
void MenuStart( PlayerNumber pn );
void MenuBack( PlayerNumber pn );
void TweenOffScreen();
void TweenOnScreen();
private:
// These functions take the PlayerNumber of the player making the selections,
// which is not necessarily the same as the PlayerNumber that the options are being
// chosen for. If only one player is joined, they will pick their choices, then
// the CPU's choices.
void BeforeRowChange( PlayerNumber pn );
void AfterRowChange( PlayerNumber pn );
void AfterValueChange( PlayerNumber pn );
void Move( PlayerNumber pn, int deltaValue );
vector<Character> m_vCharacters;
int m_iSelectedCharacter[NUM_PLAYERS];
int m_iSelectedLevelIndex[NUM_PLAYERS];
enum {
CHOOSING_HUMAN_CHARACTER,
CHOOSING_HUMAN_LEVEL,
CHOOSING_CPU_CHARACTER,
CHOOSING_CPU_LEVEL,
FINISHED_CHOOSING
} m_SelectionRow[NUM_PLAYERS];
PlayerNumber GetAffectedPlayerNumber( PlayerNumber pn ); // returns the number of the player that pn is selecting for
MenuElements m_Menu;
Sprite m_sprTitle[NUM_PLAYERS];
Sprite m_sprCharacter[NUM_PLAYERS];
Sprite m_sprCharacterArrows[NUM_PLAYERS];
Sprite m_sprAttackFrame[NUM_PLAYERS];
OptionIcon m_AttackIcons[NUM_PLAYERS][NUM_ATTACK_LEVELS][NUM_ATTACKS_PER_LEVEL];
Sprite m_sprLevelCursor[NUM_PLAYERS];
Sprite m_sprExplanation;
RandomSample m_soundChange;
RandomSample m_soundSelect;
};
+16
View File
@@ -295,6 +295,14 @@ SOURCE=.\RageUtil.h
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Character.cpp
# End Source File
# Begin Source File
SOURCE=.\Character.h
# End Source File
# Begin Source File
SOURCE=.\CodeDetector.cpp
# End Source File
# Begin Source File
@@ -1797,6 +1805,14 @@ SOURCE=.\ScreenSelect.h
# End Source File
# Begin Source File
SOURCE=.\ScreenSelectCharacter.cpp
# End Source File
# Begin Source File
SOURCE=.\ScreenSelectCharacter.h
# End Source File
# Begin Source File
SOURCE=.\ScreenSelectCourse.cpp
# End Source File
# Begin Source File
+12
View File
@@ -391,6 +391,12 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
<File
RelativePath="ScreenSelect.h">
</File>
<File
RelativePath="ScreenSelectCharacter.cpp">
</File>
<File
RelativePath="ScreenSelectCharacter.h">
</File>
<File
RelativePath="ScreenSelectCourse.cpp">
</File>
@@ -509,6 +515,12 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
<Filter
Name="Data Structures"
Filter="">
<File
RelativePath="Character.cpp">
</File>
<File
RelativePath="Character.h">
</File>
<File
RelativePath="CodeDetector.cpp">
</File>