thug/Code/Sk/Modules/Skate/Goal.cpp

3555 lines
115 KiB
C++
Raw Permalink Normal View History

2016-02-13 21:39:12 +00:00
// start autoduck documentation
// @DOC goal
// @module goal | None
// @subindex Scripting Database
// @index script | goal
#include <sk/modules/skate/goalmanager.h>
#include <sk/modules/skate/gamemode.h>
#include <core/string/stringutils.h>
#include <gel/scripting/script.h>
#include <gel/scripting/checksum.h>
#include <gel/scripting/struct.h>
#include <gel/scripting/string.h>
#include <gel/scripting/component.h>
#include <gel/scripting/array.h>
#include <gel/scripting/symboltable.h>
#include <gel/net/client/netclnt.h>
#include <gel/object/compositeobjectmanager.h>
#include <sk/gamenet/gamenet.h>
#include <sk/objects/skater.h>
#include <sk/objects/trickobject.h>
#include <sk/objects/skaterprofile.h>
#include <sk/objects/skatercareer.h>
#include <sk/objects/playerprofilemanager.h>
#include <sk/components/skatercorephysicscomponent.h>
#include <sk/components/skaterendruncomponent.h>
#include <sk/components/skaterscorecomponent.h>
#include <sk/modules/skate/score.h>
#include <sk/modules/skate/skate.h>
#include <sk/scripting/nodearray.h>
#include <sk/scripting/cfuncs.h>
#include <sk/scripting/skfuncs.h>
namespace Front
{
extern void HideTimeTHPS4();
}
namespace Game
{
/******************************************************************/
/* */
/* */
/******************************************************************/
CGoalLink::CGoalLink()
{
m_relative = 0;
mp_next = NULL;
m_beaten = false;
}
CGoalLink::~CGoalLink()
{
// nothing yet
}
/******************************************************************/
/* */
/* */
/******************************************************************/
CGoal::CGoal( Script::CStruct* pParams ) : Lst::Node<CGoal>( this )
{
mp_children = new Game::CGoalLink();
mp_parents = new Game::CGoalLink();
m_active = false;
m_hasSeen = false;
m_paused = false;
m_unlimitedTime = true;
m_isbeat = false;
m_netIsBeat = false;
m_beatenFlags = 0;
m_teamBeatenFlags = 0;
m_isselected = false;
m_isInitialized = false;
m_numTimesLost = 0;
m_numTimesWon = 0;
m_numTimesStarted = 0;
m_deactivateOnExpire = true;
m_timeLeft = 0;
m_chapter = m_stage = -1;
mp_params = new Script::CStruct;
mp_params->AppendStructure( pParams );
mp_goalPed = new Game::CGoalPed( mp_params );
mp_goalFlags = new Script::CStruct;
m_numflags = 0;
m_flagsSet = 0;
m_elapsedTime = 0;
m_elapsedTimeRecord = vINT32_MAX;
m_winScoreRecord = 0;
m_endRunType = vGOALENDOFRUN;
// set the level number
Mdl::Skate * skate_mod = Mdl::Skate::Instance();
Obj::CSkaterCareer* pCareer = skate_mod->GetCareer();
m_levelNum = pCareer->GetLevel();
CreateGoalFlags( pParams );
if ( pParams->ContainsFlag( CRCD( 0x4ab5f14, "single_timer" ) ) )
{
// Dbg_MsgAssert( mp_children->m_relative, ( "single_timer flag used on a goal without children" ) );
m_inherited_flags |= GOAL_INHERITED_FLAGS_ONE_TIMER;
}
if ( pParams->ContainsFlag( CRCD( 0xc6b4258f, "retry_stage" ) ) )
{
m_inherited_flags |= GOAL_INHERITED_FLAGS_RETRY_STAGE;
}
// TODO: make goal lock stuff work right
if ( pParams->ContainsFlag( vUNLOCKED_BY_ANOTHER ) )
{
m_isLocked = true;
}
else if ( pParams->ContainsFlag( vPRO_GOAL ) )
{
m_isLocked = true;
}
/* else if ( pParams->ContainsFlag( vPRO_CHALLENGE ) )
{
m_isLocked = true;
}
*/
else
{
m_isLocked = false;
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::Init()
{
Mem::Manager::sHandle().PushContext(Mem::Manager::sHandle().BottomUpHeap());
// overwrite any params with difficulty level params
AppendDifficultyLevelParams();
// make sure there's a goal description so that the intro cam anims can
// be killed and Gary will be happy
Dbg_MsgAssert( mp_params->ContainsComponentNamed( CRCD(0xc5d7e6b,"goal_description") ), ( "No goal description defined for %s\n", Script::FindChecksumName( GetGoalId() ) ) );
RunCallbackScript( vINIT );
ReplaceTrickText();
m_isInitialized = true;
// Dan, TT12965. If a server switched between time limit and capture limit ctf games, m_unlimitedTime was not being reset to true. Thus, ShouldExpire
// was returning true during the capture limit game, if the time on the previous time limit game had been allowed to run down.
int unlimited_time = 0;
mp_params->GetInteger( CRCD(0xf0e712d2,"unlimited_time"), &unlimited_time );
if ( unlimited_time )
{
m_unlimitedTime = true;
}
Mem::Manager::sHandle().PopContext();
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::AddParent( uint32 id )
{
// printf("adding parents\n");
if ( mp_parents->m_relative == 0 )
{
mp_parents->m_relative = id;
}
else
{
Game::CGoalLink* p_parent = new Game::CGoalLink();
p_parent->m_relative = id;
p_parent->mp_next = mp_parents;
mp_parents = p_parent;
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::CreateGoalFlags( Script::CStruct* pParams )
{
// set any goal flags specified in the params
Script::CArray *pTempArray;
mp_goalFlags->Clear();
m_numflags = 0;
if ( pParams->GetArray( CRCD(0xcc3c4cc4,"goal_flags"), &pTempArray ) )
{
for ( uint32 c = 0; c < pTempArray->GetSize(); c++)
{
mp_goalFlags->AddInteger( pTempArray->GetNameChecksum( c ), 0 );
m_numflags++;
}
}
mp_params->AddInteger( CRCD(0xb3790f33,"num_flags"), m_numflags );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetInheritableFlags( int recurse_level )
{
// printf("SetInheritableFlags called on %s\n", Script::FindChecksumName( GetGoalId() ) );
Dbg_MsgAssert( recurse_level < 100, ( "SetInheritableFlags recursed too much" ) );
CGoalManager* pGoalManager = GetGoalManager();
Dbg_Assert( pGoalManager );
CGoalLink* p_child = mp_children;
while ( p_child && p_child->m_relative != 0 )
{
CGoal *pGoal = pGoalManager->GetGoal( p_child->m_relative );
if ( pGoal )
{
pGoal->m_inherited_flags |= m_inherited_flags;
pGoal->SetInheritableFlags( recurse_level + 1 );
}
p_child = p_child->mp_next;
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::AddChild( uint32 id )
{
// printf("adding child\n");
// any current children?
if ( mp_children->m_relative == 0 )
{
mp_children->m_relative = id;
}
else
{
// make sure this child isn't already in the list
bool found = false;
Game::CGoalLink* p_test = mp_children;
while ( p_test && p_test->m_relative != 0 )
{
if ( p_test->m_relative == id )
{
found = true;
break;
}
p_test = p_test->mp_next;
}
if ( found )
{
Dbg_MsgAssert( 0, ( "AddChild failed. %s already a child of %s\n", Script::FindChecksumName( id ), Script::FindChecksumName( GetGoalId() ) ) );
}
else
{
// add new child to head of list
Game::CGoalLink* p_child = new Game::CGoalLink();
p_child->m_relative = id;
p_child->mp_next = mp_children;
mp_children = p_child;
}
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::ResetGoalLinks()
{
CGoalManager* pGoalManager = GetGoalManager();
Dbg_Assert( pGoalManager );
CGoalLink* p_link = mp_children;
while ( p_link && p_link->m_relative != 0 )
{
p_link->m_beaten = false;
CGoal* pGoal = pGoalManager->GetGoal( p_link->m_relative );
if ( pGoal )
{
// recurse!
pGoal->ResetGoalLinks();
}
p_link = p_link->mp_next;
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::DeleteLinks( CGoalLink* p_list )
{
CGoalLink *p_a, *p_b;
for ( p_a = p_list; p_a; p_a = p_b )
{
p_b = p_a->mp_next;
delete p_a;
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::Uninit( bool propogate, int recurse_level )
{
Dbg_MsgAssert( recurse_level < 20, ( "CGoal::Uninit recursed too deep" ) );
// uint32 trigger_obj_id = 0;
if ( IsActive() )
{
Deactivate( true );
}
RunCallbackScript( vUNINIT );
m_isInitialized = false;
/*
Script::RunScript( Script::GenerateCRC( "goal_kill_proset_geom" ), mp_params );
mp_params->GetChecksum( CRCD( 0x2d7e03d, "trigger_obj_id" ), &trigger_obj_id );
if ( trigger_obj_id )
{
Obj::CMovingObject* p_pos_obj = NULL;
// p_pos_obj = Obj::CMovingObject::m_hash_table.GetItem( trigger_obj_id );
p_pos_obj = (Obj::CMovingObject*) Obj::CCompositeObjectManager::Instance()->GetObjectByID( trigger_obj_id );
if ( p_pos_obj )
{
delete p_pos_obj;
}
}
*/
if ( propogate )
{
CGoalManager* pGoalManager = GetGoalManager();
Dbg_Assert( pGoalManager );
CGoalLink* pGoalLink = mp_children;
while ( pGoalLink && pGoalLink->m_relative != 0 )
{
CGoal* pChildGoal = pGoalManager->GetGoal( pGoalLink->m_relative );
Dbg_Assert( pChildGoal );
pChildGoal->Uninit( propogate, recurse_level + 1 );
pGoalLink = pGoalLink->mp_next;
}
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
CGoal::~CGoal()
{
// does this really need to be run?
// (you may not necessarily want to go through the
// same destructor logic if we're clearing out the
// goals at the end of the level)
RunCallbackScript( vDESTROY );
delete mp_goalPed;
Dbg_Assert( mp_params );
delete mp_params;
delete mp_goalFlags;
// delete all children and parent trees
DeleteLinks( mp_children );
DeleteLinks( mp_parents );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
Script::CStruct* CGoal::GetParams()
{
return mp_params;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetTimer()
{
int unlimited_time = 0;
mp_params->GetInteger( CRCD(0xf0e712d2,"unlimited_time"), &unlimited_time );
// check for unlimited time
if ( unlimited_time == 1 )
{
return;
}
// don't set default time for minigames.
if ( IsMinigame() )
{
if ( !mp_params->ContainsComponentNamed( CRCD(0x906b67ba,"time") ) )
return;
}
// default time limit of 2 minutes
m_timeLeft = 120;
int time;
if ( mp_params->GetInteger( CRCD(0x906b67ba,"time"), &time, Script::NO_ASSERT ) )
{
m_timeLeft = (Tmr::Time)time;
}
/* else
{
Script::CArray* pTimeLimits;
if ( mp_params->GetArray( CRCD(0x906b67ba,"time"), &pTimeLimits, Script::NO_ASSERT ) )
{
CGoalManager* pGoalManager = GetGoalManager();
Dbg_Assert( pGoalManager );
uint32 difficulty_level = pGoalManager->GetDifficultyLevel();
Dbg_Assert( difficulty_level > 0 && difficulty_level < pTimeLimits->GetSize() );
m_timeLeft = (Tmr::Time)( pTimeLimits->GetInteger( difficulty_level ) );
}
}
*/
// convert to milliseconds
m_timeLeft *= 1000;
// bump up timer so clock starts with expected amount of time left
m_timeLeft += 20;
// printf("timer set to %i\n", (int)m_timeLeft);
m_unlimitedTime = false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetTimer( int time )
{
m_timeLeft = (Tmr::Time)time * 1000;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
int CGoal::GetTimeLeft( void )
{
return m_timeLeft;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::AddTime( int time )
{
// bump up time by 20ms so that it displays right
m_timeLeft += ( (Tmr::Time)time * 1000 ) + 20;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::Activate()
{
if ( !IsActive() )
{
Mem::Manager::sHandle().PushContext(Mem::Manager::sHandle().BottomUpHeap());
// Warning! Make sure there are no 'return's between the above pushcontext and the
// popcontext below ...
m_elapsedTime = 0;
m_numTimesStarted++;
// printf("goal is not active - now activating\n");
GameNet::Manager * gamenet_man = GameNet::Manager::Instance();
GameNet::PlayerInfo* player;
Lst::Search< GameNet::PlayerInfo > sh;
// TODO: reset just this skater's score
for( player = gamenet_man->FirstPlayerInfo( sh ); player; player = gamenet_man->NextPlayerInfo( sh ) )
{
Obj::CSkater *p_Skater = player->m_Skater;
Dbg_Assert( p_Skater );
Obj::CSkaterScoreComponent* p_SkaterScoreComponent = GetSkaterScoreComponentFromObject(p_Skater);
Dbg_Assert( p_SkaterScoreComponent );
Mdl::Score * p_Score = ( p_SkaterScoreComponent->GetScore() );
Dbg_Assert( p_Score );
// don't reset the score when starting a minigame
if ( !IsMinigame() )
p_Score->Reset();
}
// Warning! Make sure there are no 'return's between the above pushcontext and the
// popcontext below ...
if ( mp_parents->m_relative != 0 )
{
CGoalManager* pGoalManager = GetGoalManager();
Dbg_Assert( pGoalManager );
CGoal* pParentGoal = NULL;
// get the root node and check the timer
CGoalLink* p_parent = mp_parents;
while ( p_parent && p_parent->m_relative != 0 )
{
pParentGoal = pGoalManager->GetGoal( p_parent->m_relative );
p_parent = pParentGoal->GetParents();
}
if ( pParentGoal )
{
if ( m_inherited_flags & GOAL_INHERITED_FLAGS_ONE_TIMER )
SetTimer( pParentGoal->GetTimeLeft() / 1000.0f );
else
SetTimer();
if ( pParentGoal->IsInitialized() )
{
pParentGoal->Uninit();
// reinitialize the goal in case uninitializing the parent
// screwed anything up.
if ( IsInitialized() )
{
Uninit();
Init();
}
}
}
else
{
// Dbg_Message( "Goal supposed to use a single timer but couldn't find parent" );
SetTimer();
}
}
else
{
SetTimer();
}
if ( !IsInitialized() )
{
Init();
}
m_endRunCalled = false;
// Warning! Make sure there are no 'return's between the above pushcontext and the
// popcontext below ...
mp_params->RemoveFlag( CRCD(0x7100155d,"combo_started") );
// activate script
RunCallbackScript( vACTIVATE );
if( gamenet_man->InNetGame() == false )
{
m_hasSeen = true;
}
//if ( !mp_params->ContainsFlag( "quick_start" ) )
//PauseGoal();
SetActive();
Mem::Manager::sHandle().PopContext();
return true;
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetActive()
{
m_active = true;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::Deactivate( bool force, bool affect_tree )
{
if ( IsActive() )
{
// special case for special trick goal...get rid of
// the temp key_combos array
if ( IsSpecialGoal() )
mp_params->RemoveComponent( CRCD(0x79704516,"key_combos") );
Front::HideTimeTHPS4();
SetInactive();
ResetGoalFlags();
ResetGoalLinks();
RunCallbackScript( vDEACTIVATE );
if (!mp_params->ContainsFlag( CRCD( 0x38221df4, "quick_start" ) ))
{
// If not retrying, then remove the testing_goal flag
// The presence of the testing_goal flag prevents the goal from being marked as
// beaten when it is beaten during testing.
mp_params->RemoveFlag(CRCD(0x54d3cac1,"testing_goal"));
}
if ( !mp_params->ContainsFlag( CRCD( 0xc309cad1, "just_won_goal" ) )
&& !mp_params->ContainsFlag( CRCD( 0x38221df4, "quick_start" ) ) )
{
Script::RunScript(CRCD(0x719ae783, "ready_skater_for_early_end_current_goal"), mp_params);
if ( affect_tree && mp_parents && mp_parents->m_relative )
{
Uninit();
// find parent node and reinitialize
CGoalManager* pGoalManager = GetGoalManager();
Dbg_Assert( pGoalManager );
CGoalLink* p_link = mp_parents;
CGoal* pParentGoal = NULL;
while ( p_link && p_link->m_relative )
{
pParentGoal = pGoalManager->GetGoal( p_link->m_relative );
Dbg_Assert( pParentGoal );
p_link = pParentGoal->GetParents();
}
if ( pParentGoal && !pParentGoal->HasWonGoal() )
{
// printf("initializing goal: %s\n", Script::FindChecksumName( pParentGoal->GetGoalId() ) );
pParentGoal->Init();
}
}
}
return true;
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetInactive()
{
m_active = false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::Win( void )
{
mp_params->AddInteger( CRCD(0xc22a2b72,"win_record"), 0 );
// see if it's a leaf node
if ( mp_children->m_relative == 0 )
{
mp_params->AddChecksum( NONAME, CRCD( 0xc309cad1, "just_won_goal" ) );
GameNet::Manager * gamenet_man = GameNet::Manager::Instance();
m_numTimesWon++;
// look for a new record if we're not in a net game
bool set_new_record = false;
uint32 record_type;
if ( !gamenet_man->InNetGame() && mp_params->GetChecksum( CRCD(0x96963902,"record_type"), &record_type, Script::NO_ASSERT ) )
{
// printf("record type is %s\n", Script::FindChecksumName( record_type ) );
if ( record_type == CRCD(0xcd66c8ae,"score") )
{
// check for custom score record
int custom_record;
if ( mp_params->GetInteger( CRCD(0xfc9630ab,"custom_score_record"), &custom_record, Script::NO_ASSERT ) )
{
if ( custom_record > m_winScoreRecord )
{
m_winScoreRecord = custom_record;
mp_params->AddInteger( CRCD(0xc22a2b72,"win_record"), m_winScoreRecord );
set_new_record = true;
}
}
else
{
// printf("found a score record type\n");
Mdl::Skate * skate_mod = Mdl::Skate::Instance();
Obj::CSkater *pSkater = skate_mod->GetLocalSkater();
Dbg_Assert( pSkater );
Obj::CSkaterScoreComponent* pSkaterScoreComponent = GetSkaterScoreComponentFromObject(pSkater);
Dbg_Assert( pSkaterScoreComponent );
Mdl::Score * pScore = ( pSkaterScoreComponent->GetScore() );
Dbg_Assert( pScore );
int total_score;
if ( mp_params->ContainsFlag( CRCD(0xc63432a7,"high_combo") ) )
total_score = pScore->GetLastScoreLanded();
else
total_score = pScore->GetTotalScore();
// printf("got a total_score of %i, had a previous record of %i\n", total_score, m_winScoreRecord );
if ( total_score > m_winScoreRecord )
{
m_winScoreRecord = total_score;
mp_params->AddInteger( CRCD(0xc22a2b72,"win_record"), m_winScoreRecord );
set_new_record = true;
}
}
}
else if ( record_type == CRCD(0x906b67ba,"time") )
{
// printf("got a time of %i, previous record was %i\n", (int)m_elapsedTime, (int)m_elapsedTimeRecord);
if ( m_elapsedTime < m_elapsedTimeRecord )
{
m_elapsedTimeRecord = m_elapsedTime;
mp_params->AddInteger( CRCD(0xc22a2b72,"win_record"), (int)m_elapsedTimeRecord );
set_new_record = true;
}
}
}
#ifdef __NOPT_ASSERT__
CGoalManager* pGoalManager = GetGoalManager();
Dbg_Assert( pGoalManager );
#endif // __NOPT_ASSERT__
if ( !HasWonGoal() && !gamenet_man->InNetGame() )
{
// printf("getting rewards struct\n");
Script::CStruct* p_reward_params = new Script::CStruct();
GetRewardsStructure( p_reward_params, true );
if ( set_new_record )
p_reward_params->AddChecksum( NONAME, CRCD(0xe7b8254f,"set_new_record") );
mp_params->AddStructurePointer( CRCD(0x128b3088,"reward_params"), p_reward_params );
UnlockRewardGoals();
}
else
mp_params->RemoveComponent( CRCD(0x128b3088,"reward_params") );
// update set_new_record flag
if ( set_new_record )
mp_params->AddChecksum( NONAME, CRCD(0xe7b8254f,"set_new_record") );
else
mp_params->RemoveFlag( CRCD(0xe7b8254f,"set_new_record") );
RunCallbackScript( vSUCCESS );
bool testing_goal=mp_params->ContainsFlag(CRCD(0x54d3cac1,"testing_goal"));
if ( IsActive() )
{
// add a flag so the deactivate script knows that we just beat the goal
Deactivate();
}
// The testing_goal flag is set when a created goal is being test played.
// Don't want it to be crossed off the view goals menu in that case. (TT3366)
if (!testing_goal)
{
MarkBeaten();
}
if ( gamenet_man->InNetGame() )
{
Uninit();
}
mp_params->RemoveFlag( CRCD( 0xc309cad1, "just_won_goal" ) );
return true;
}
else
{
// it's a link to another goal
// TODO: we need a way of deciding which child to pick
// for now, we'll just take the first child
Game::CGoalLink* p_link = mp_children;
CGoalManager* pGoalManager = GetGoalManager();
Dbg_Assert( pGoalManager );
Deactivate();
Uninit();
CGoal* pChildGoal = pGoalManager->GetGoal( p_link->m_relative );
pChildGoal->Init();
pGoalManager->ActivateGoal( p_link->m_relative, false );
// mark the link beaten
p_link->m_beaten = true;
return true;
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::Lose( void )
{
// Mdl::Skate * skate_mod = Mdl::Skate::Instance();
// Obj::CSkater *p_Skater = skate_mod->GetLocalSkater();
// Dbg_Assert( p_Skater );
// p_Skater->ClearAllExceptions();
if ( IsActive() )
{
m_numTimesLost++;
RunCallbackScript( vFAIL );
Deactivate( true );
return true;
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsExpired()
{
return IsExpired( false );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::ShouldExpire()
{
// returns true if the goal would expire if the skater was not in a combo
// Dan: this logic needs to mimic IsExpired()
Mdl::Skate * skate_mod = Mdl::Skate::Instance();
GameNet::Manager * gamenet_man = GameNet::Manager::Instance();
Obj::CSkater* p_skater;
p_skater = skate_mod->GetLocalSkater();
if ( p_skater == NULL )
{
return true;
}
#ifdef __NOPT_ASSERT__
Obj::CSkaterEndRunComponent* p_skater_endrun_component = GetSkaterEndRunComponentFromObject(p_skater);
Dbg_Assert(p_skater_endrun_component);
#endif // __NOPT_ASSERT__
// If no players are left, the goal should expire
if ( gamenet_man->GetNumPlayers() == 0 )
{
return true;
}
// If it's an unlimited game, don't expire the goal
if ( m_unlimitedTime )
{
return false;
}
if ( (int)m_timeLeft <= 0 )
{
// Dbg_Printf( "**** Already Expired\n" );
return true;
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsExpired( bool force_end )
{
Mdl::Skate * skate_mod = Mdl::Skate::Instance();
GameNet::Manager * gamenet_man = GameNet::Manager::Instance();
Obj::CSkater* p_skater;
p_skater = skate_mod->GetLocalSkater();
if ( p_skater == NULL )
{
return true;
}
Obj::CSkaterEndRunComponent* p_skater_endrun_component = GetSkaterEndRunComponentFromObject(p_skater);
Dbg_Assert(p_skater_endrun_component);
// If no players are left, the goal should expire
if ( gamenet_man->GetNumPlayers() == 0 )
{
return true;
}
// If it's an unlimited game, don't expire the goal
if ( m_unlimitedTime )
{
return false;
}
// check if the skaters have reached end of run BEFORE
// setting the exception, or you'll never catch it!
bool expired = false;
switch ( m_endRunType )
{
case vENDOFRUN:
expired = p_skater_endrun_component->RunHasEnded();
break;
case vGOALENDOFRUN:
expired = p_skater_endrun_component->GoalRunHasEnded();
break;
case vNONE:
// if we're not supposed to use end of run, we need only check
// the time
return ( (int)m_timeLeft <= 0 );
break;
default:
Dbg_Assert( 0 );
}
if ( expired && (int)m_timeLeft <= 0 )
{
// Dbg_Printf( "**** Already Expired\n" );
return true;
}
// if time is up, set the end of run exception
if ( (int)m_timeLeft <= 0 )
{
// Dbg_Printf( "EXPIRING GOAL: %d\n", GetGoalId());
// printf("&&&&&&&&&&&&&&&&& calling EndRun\n");
switch ( m_endRunType )
{
case vENDOFRUN:
m_endRunCalled = true;
// Dbg_Printf( "**** Calling End Run\n" );
p_skater_endrun_component->EndRun( force_end );
break;
case vGOALENDOFRUN:
// printf("reached goalendofrun\n");
m_endRunCalled = true;
p_skater_endrun_component->EndGoalRun( force_end );
break;
default:
Dbg_Assert( 0 );
}
}
// printf("AtEndOfRun returned %i\n", all_expired);
// return ( all_expired && ( (int)m_timeLeft <= 0 ) );
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::AllSkatersAtEndOfRun()
{
// check all the goals
GameNet::Manager * gamenet_man = GameNet::Manager::Instance();
Mdl::Skate* skate_mod = Mdl::Skate::Instance();
GameNet::PlayerInfo* player;
Lst::Search< GameNet::PlayerInfo > sh;
for( player = gamenet_man->FirstPlayerInfo( sh ); player; player = gamenet_man->NextPlayerInfo( sh ))
{
Obj::CSkater *p_Skater = player->m_Skater;
// int skater_num = p_Skater->GetSkaterNumber();
Dbg_Assert( p_Skater );
Obj::CSkaterEndRunComponent* p_skater_endrun_component = GetSkaterEndRunComponentFromObject(p_Skater);
Dbg_Assert( p_skater_endrun_component );
if( skate_mod->GetGameMode()->GetNameChecksum() == CRCD( 0x9d65d0e7, "horse" ))
{
if( p_Skater->IsPaused() || p_Skater->IsHidden())
{
continue;
}
}
switch ( m_endRunType )
{
case vENDOFRUN:
if ( !p_skater_endrun_component->RunHasEnded() )
{
return false;
}
break;
case vGOALENDOFRUN:
if ( !p_skater_endrun_component->GoalRunHasEnded() )
{
return false;
}
break;
default:
Dbg_Assert( 0 );
}
}
return true;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::EditParams( Script::CStruct* pParams )
{
mp_params->AppendStructure( pParams );
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::Update( void )
{
if ( IsActive() && !IsPaused() )
{
RunCallbackScript( vACTIVE );
}
// the active script may have deactivated the goal, so we check
// if it's active again...don't check mini games
if ( IsActive() && !IsPaused())
{
if( ShouldUseTimer() )
{
if ( ( (int)m_timeLeft >= 1 ) )
{
int old_time_left = (int)m_timeLeft;
m_timeLeft -= (Tmr::Time)( Tmr::FrameLength() * 1000 );
m_elapsedTime += (Tmr::Time)( Tmr::FrameLength() * 1000 );
if ( (int)m_timeLeft < 10000 && ( (int)( old_time_left / 1000 ) > (int)( (int)m_timeLeft / 1000 ) ) )
{
if (Mdl::Skate::Instance()->GetGameMode()->ShouldTimerBeep())
{
Script::RunScript( CRCD(0xcfc7c3ad,"timer_runout_beep") );
}
}
}
}
if ( ShouldRequireCombo() )
{
if ( !mp_params->ContainsFlag( CRCD( 0x7100155d, "combo_started" ) ) )
{
Mdl::Skate *skate_mod = Mdl::Skate::Instance();
Obj::CSkater* pSkater = skate_mod->GetLocalSkater();
if ( pSkater )
{
Mdl::Score* pScore = pSkater->GetScoreObject();
if ( pScore && pScore->GetScorePotValue() > 0 )
{
mp_params->AddChecksum( NONAME, CRCD(0x7100155d,"combo_started") );
}
}
}
}
// add the amount of time left
// mp_params->AddInteger( "time_left", m_timeLeft );
if ( IsExpired() )
{
Expire();
}
}
// haven't used the inactive yet
/* else
{
if ( !IsLocked() )
{
// runs its inactive script (if any)
RunCallbackScript( vINACTIVE );
}
}
*/
return true;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::Expire()
{
RunCallbackScript( vEXPIRED );
// TODO: fix after e3
// this was done to make the horse and combo letter goals work right
if ( m_deactivateOnExpire )
{
Deactivate();
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsActive( void )
{
return ( m_active == true );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::HasSeenGoal( void )
{
return m_hasSeen;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::PauseGoal( void )
{
m_paused = true;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::UnPauseGoal( void )
{
m_paused = false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
Tmr::Time CGoal::GetTime( void )
{
return m_timeLeft;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
/*void CGoal::CreateGoalFlag( uint32 flag )
{
mp_goalFlags->AddInteger( flag, 0 );
m_numflags++;
}*/
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::SetGoalFlag( uint32 flag, int value )
{
if ( !IsActive() )
{
return false;
}
if ( mp_goalFlags->ContainsComponentNamed( flag ) )
{
// remember the old value
int old_value;
mp_goalFlags->GetInteger( flag, &old_value, Script::ASSERT );
mp_goalFlags->AddInteger( flag, value );
if ( old_value != value )
{
if ( value == 0 )
m_flagsSet--;
else
{
m_flagsSet++;
if ( !mp_params->ContainsFlag( CRCD(0x524566e3,"no_midgoal_sound") ) )
Script::RunScript( CRCD(0x5ed34deb,"goal_got_flag_sound") );
}
if ( mp_params->ContainsFlag( CRCD(0xfd7ae1f4,"use_hud_counter") ) )
Script::RunScript( CRCD(0xf2e85a34,"goal_update_counter"), mp_params );
mp_params->AddInteger( CRCD(0xcf6cd3c1,"num_flags_set"), m_flagsSet );
}
// printf("setting goal flag %s, %i of %i set\n", Script::FindChecksumName( flag ), m_flagsSet, m_numflags );
return true;
}
Dbg_MsgAssert( 0, ("SetGoalFlag couldn't find flag\n" ) );
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::GetCreatedGoalGap(int gapIndex)
{
Script::CArray *p_required_gaps=NULL;
if (!mp_params->GetArray(CRCD(0x52d4489e,"required_gaps"),&p_required_gaps))
{
return false;
}
const char *p_required_trick_name="";
mp_params->GetString(CRCD(0x730844a3,"required_trick_name"),&p_required_trick_name);
if (p_required_trick_name[0])
{
Mdl::Skate *p_skate_mod = Mdl::Skate::Instance();
Obj::CSkater *p_skater = p_skate_mod->GetLocalSkater();
if (!p_skater)
{
return false;
}
Mdl::Score *p_score = p_skater->GetScoreObject();
uint32 trick_checksum=Script::GenerateCRC(p_required_trick_name);
// Also check for fs and bs versions (TT9784)
uint32 bs_trick_checksum=CRCD(0x7491335e,"bs ");
bs_trick_checksum=Crc::ExtendCRCWithString(bs_trick_checksum, p_required_trick_name);
uint32 fs_trick_checksum=CRCD(0x73989b82,"fs ");
fs_trick_checksum=Crc::ExtendCRCWithString(fs_trick_checksum, p_required_trick_name);
if (p_score->GetCurrentNumberOfOccurrencesByName(trick_checksum, 0, false) == 0 &&
p_score->GetCurrentNumberOfOccurrencesByName(bs_trick_checksum, 0, false) == 0 &&
p_score->GetCurrentNumberOfOccurrencesByName(fs_trick_checksum, 0, false) == 0)
{
return false;
}
}
for (uint i=0; i<p_required_gaps->GetSize(); ++i)
{
if (gapIndex==p_required_gaps->GetInteger(i))
{
char p_foo[20];
sprintf(p_foo,"got_%d",i+1);
SetGoalFlag(Script::GenerateCRC(p_foo),1);
return true;
}
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::GoalFlagEquals( uint32 flag, int value )
{
if ( mp_goalFlags->ContainsComponentNamed( flag ) )
{
int f;
mp_goalFlags->GetInteger( flag, &f, Script::ASSERT );
return ( value == f );
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::ResetGoalFlags()
{
// reset the goal flags
Script::CComponent* p_comp = mp_goalFlags->GetNextComponent( NULL );
while ( p_comp )
{
Script::CComponent* p_next = mp_goalFlags->GetNextComponent( p_comp );
p_comp->mIntegerValue = 0;
// SetGoalFlag( p_comp->mNameChecksum, 0 );
// printf("resetting goal flag %s\n", Script::FindChecksumName( flag_name ) );
p_comp = p_next;
}
m_flagsSet = 0;
mp_params->AddInteger( CRCD( 0xcf6cd3c1, "num_flags_set" ), 0 );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::AllFlagsSet()
{
// printf("%i flags, %i set\n", m_numflags, m_flagsSet);
int num_flags_to_win = m_numflags;
mp_params->GetInteger( CRCD(0x1171a555,"num_flags_to_win"), &num_flags_to_win, Script::NO_ASSERT );
// K: Fix to TT9785, where created gap goals would succeed straight away if no gaps were chosen,
// causing an assert.
if (num_flags_to_win == 0)
{
return false;
}
return ( m_flagsSet >= num_flags_to_win );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::GoalFlagSet( uint32 flag )
{
int flag_value;
mp_goalFlags->GetInteger( flag, &flag_value, Script::ASSERT );
return ( flag_value != 0 );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsLocked()
{
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::UnlockGoal()
{
if ( m_isLocked )
{
m_isLocked = false;
// don't initialize goals automatically in net games
GameNet::Manager * gamenet_man = GameNet::Manager::Instance();
if ( gamenet_man->InNetGame() )
return;
// initialize goal
Init();
// call the unlock script
RunCallbackScript( vUNLOCK );
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::NextTourSpot()
{
Script::CArray* p_waypoints;
// backward compatible with the horse_spots array naming convention
if ( !mp_params->GetArray( CRCD(0x160b3220,"tour_spots"), &p_waypoints, Script::NO_ASSERT ) )
mp_params->GetArray( CRCD(0x92c6e839,"horse_spots"), &p_waypoints, Script::ASSERT );
Script::CStruct* p_waypoint;
for ( uint32 i = 0; i < p_waypoints->GetSize(); i++ )
{
p_waypoint = p_waypoints->GetStructure( i );
// is this waypoint done?
uint32 flagId;
p_waypoint->GetChecksum( CRCD(0x2e0b1465,"flag"), &flagId, Script::ASSERT );
if ( GoalFlagEquals( flagId, 1 ) )
continue;
// pause the goal and set the time for this tour spot
PauseGoal();
int time;
p_waypoint->GetInteger( CRCD(0x906b67ba,"time"), &time, Script::ASSERT );
// add time if necessary
if ( mp_params->ContainsFlag( CRCD(0xfb11cb01,"cumulative_timer") ) )
{
AddTime( time );
}
else
{
mp_params->AddInteger( CRCD(0x906b67ba,"time"), time );
SetTimer();
}
// add the goalId and trigger id to the params
p_waypoint->AddChecksum( CRCD(0x9982e501,"goal_id"), GetGoalId() );
// send a flag if this is the first spot
if ( m_flagsSet == 0 )
p_waypoint->AddChecksum( NONAME, CRCD( 0xb13f3ab8, "first_spot" ) );
// send a flag if this is a restart
if ( mp_params->ContainsFlag( CRCD(0x38221df4,"quick_start") ) )
p_waypoint->AddChecksum( NONAME, CRCD(0x38221df4,"quick_start") );
else
p_waypoint->RemoveFlag( CRCD(0x38221df4,"quick_start") );
#ifdef __NOPT_ASSERT__
// backward compatible with horse goal
Script::CScript *p_script=NULL;
if ( mp_params->ContainsFlag( CRCD(0x9d65d0e7,"horse") ) )
p_script=Script::SpawnScript( CRCD(0x681bc776,"goal_horse_next_spot"), p_waypoint );
else
p_script=Script::SpawnScript( CRCD(0x4c938553,"goal_tour_next_spot"), p_waypoint );
p_script->SetCommentString("Spawned from CGoal::NextTourSpot()");
#else
// backward compatible with horse goal
if ( mp_params->ContainsFlag( CRCD(0x9d65d0e7,"horse") ) )
Script::SpawnScript( CRCD(0x681bc776,"goal_horse_next_spot"), p_waypoint );
else
Script::SpawnScript( CRCD(0x4c938553,"goal_tour_next_spot"), p_waypoint );
#endif
// remove restart flag
p_waypoint->RemoveFlag( CRCD(0x38221df4,"quick_start") );
/* // move the skater to the node
uint32 reset_checksum;
p_waypoint->GetChecksum( "id", &reset_checksum, Script::ASSERT );
Mdl::Skate * p_skate = Mdl::Skate::Instance();
p_skate->ResetSkaters( SkateScript::FindNamedNode( reset_checksum ) );
uint32 waypoint_script;
if ( p_waypoint->GetChecksum( "scr", &waypoint_script, Script::NO_ASSERT ) )
Script::SpawnScript( waypoint_script );
*/
return true;
}
return true;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::InitTrickObjects()
{
// get the object id's
Script::CArray* p_trickObjectArray = NULL;
mp_params->GetArray( CRCD(0x2eb84a54,"trick_objects"), &p_trickObjectArray, Script::ASSERT );
Mdl::Skate* skate_mod = Mdl::Skate::Instance();
Obj::CTrickObjectManager* p_TrickObjectManager = skate_mod->GetTrickObjectManager();
for ( uint32 i = 0; i < p_trickObjectArray->GetSize(); i++ )
{
// add the trick object
uint32 goal_object;
Script::CStruct* p_trickObject = p_trickObjectArray[i].GetStructure( i );
p_trickObject->GetChecksum( CRCD(0x40c698af,"id"), &goal_object, Script::ASSERT );
// p_TrickObjectManager->RequestLogTrick( 1,
p_TrickObjectManager->ModulateTrickObjectColor( goal_object, 0 );
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::GotTrickObject( uint32 clusterId )
{
// do we care?
if ( mp_params->ContainsFlag( CRCD( 0xf268c278, "SkateTheLine" ) ) )
{
// we do
uint32 current;
mp_params->GetChecksum( CRCD(0xb03713ee,"current_cluster"), &current, Script::ASSERT );
if ( current == clusterId )
Script::RunScript( CRCD( 0x62b12a8e, "Goal_SkateTheLine_got_node" ), mp_params );
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsGraffitiGoal()
{
return ( mp_params->ContainsFlag( CRCD(0xc8a82b5a,"graffiti") ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::ShouldLogTrickObject()
{
if ( mp_params->ContainsFlag( CRCD(0xc8a82b5a,"graffiti") ) || mp_params->ContainsFlag( CRCD(0xf268c278,"SkateTheLine") ) )
{
return true;
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::GotGraffitiCluster( uint32 clusterId, int score )
{
// find the cluster in our cluster array
Script::CArray* pClusterArray;
mp_params->GetArray( CRCD(0x191f66e9,"kill_clusters"), &pClusterArray, Script::ASSERT );
for ( uint32 i = 0; i < pClusterArray->GetSize(); i++ )
{
Script::CStruct* pCluster = pClusterArray->GetStructure( i );
Dbg_MsgAssert( pCluster, ( "got null cluster from kill_cluster array\n" ) );
uint32 id;
pCluster->GetChecksum( "id", &id, Script::ASSERT );
int minScore;
// get the score for this cluster, or the default score
if ( !pCluster->GetInteger( CRCD(0xcd66c8ae,"score"), &minScore, Script::NO_ASSERT ) )
mp_params->GetInteger( CRCD(0xcd66c8ae,"score"), &minScore, Script::ASSERT );
// printf("minScore: %i, score: %i\n", minScore, score);
if ( id == clusterId && score > minScore )
{
Mdl::Skate * skate_mod = Mdl::Skate::Instance();
Obj::CTrickObjectManager* p_trickObjectMan = skate_mod->GetTrickObjectManager();
// printf("modulating color\n");
if ( !p_trickObjectMan->ModulateTrickObjectColor( clusterId, 0 ) )
printf("ModulateTrickObjectColor didn't work\n");
uint32 flag;
pCluster->GetChecksum( CRCD(0x2e0b1465,"flag"), &flag, Script::ASSERT );
SetGoalFlag( flag, 1 );
return;
}
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsSpecialGoal()
{
return ( mp_params->ContainsFlag( CRCD(0xb394c01c,"special") ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::CheckSpecialGoal()
{
Mdl::Skate * skate_mod = Mdl::Skate::Instance();
Obj::CSkater *p_Skater = skate_mod->GetLocalSkater();
Dbg_Assert( p_Skater );
Obj::CSkaterScoreComponent* p_SkaterScoreComponent = GetSkaterScoreComponentFromObject(p_Skater);
Dbg_Assert( p_SkaterScoreComponent );
Mdl::Score * p_Score = ( p_SkaterScoreComponent->GetScore() );
Dbg_Assert( p_Score );
const char* trick_string;
mp_params->GetString( CRCD(0x3a54cc4b,"trick_string"), &trick_string, Script::ASSERT );
// if it's a grind, we need to check for the FS and BS version too
uint32 trick_type;
mp_params->GetChecksum( CRCD(0x3d929b66,"trick_type"), &trick_type, Script::ASSERT );
if ( trick_type == CRCD( 0x255ed86f, "grind" ) )
{
char test_trick[128];
// frontside
strcpy( test_trick, "FS " );
strcat( test_trick, trick_string );
// printf("testing FS version - %s\n", test_trick);
if ( p_Score->GetCurrentNumberOfOccurrencesByName( Script::GenerateCRC( test_trick ) ) )
{
// printf("got it\n");
return true;
}
// backside
strcpy( test_trick, "BS " );
strcat( test_trick, trick_string );
// printf("testing BS version - %s\n", test_trick);
if ( p_Score->GetCurrentNumberOfOccurrencesByName( Script::GenerateCRC( test_trick ) ) )
{
// printf("got it\n");
return true;
}
}
// check the bare trick string
if ( mp_params->ContainsFlag( CRCD(0x8e6014f6,"create_a_trick") ) )
{
// printf("testing cat version %s\n", new_string );
if ( p_Score->GetCurrentNumberOfOccurrencesByName( Script::GenerateCRC( trick_string ) ) > 0 )
{
return true;
}
}
else
{
// printf("testing normal version - %s\n", trick_string);
if ( p_Score->GetCurrentNumberOfOccurrencesByName( Script::GenerateCRC( trick_string ) ) > 0 )
{
return true;
}
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsTetrisGoal()
{
return ( mp_params->ContainsFlag( CRCD(0x4147922b,"tetris") ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
int CGoal::GetRandomIndexFromKeyCombos( Script::CArray* p_keyCombos )
{
Dbg_MsgAssert( p_keyCombos->GetType() == ESYMBOLTYPE_NAME ||
p_keyCombos->GetType() == ESYMBOLTYPE_STRUCTURE,
( "GetRandomIndexFromKeyCombos got array of the wrong type" ) );
// get the global trick mapping
Mdl::Skate* skate_mod = Mdl::Skate::Instance();
Obj::CSkaterProfile* p_SkaterProfile = skate_mod->GetCurrentProfile();
Script::CStruct* p_trickMappings = p_SkaterProfile->GetTrickMapping( CRCD(0xd544aa2d,"trick_mapping") );
// figure number of components in mapping
uint32 size = p_keyCombos->GetSize();
// safety first
int max_tries = 100;
uint32 trick_name_checksum = 0;
uint32 key_combo;
while ( !trick_name_checksum )
{
int i = Mth::Rnd( size );
if ( p_keyCombos->GetType() == ESYMBOLTYPE_NAME )
{
key_combo = p_keyCombos->GetChecksum( i );
}
else
p_keyCombos->GetStructure( i )->GetChecksum( CRCD(0xacfdb27a,"key_combo"), &key_combo, Script::ASSERT );
// see if this is a valid key_combo
int cat_index;
p_trickMappings->GetChecksum( key_combo, &trick_name_checksum, Script::NO_ASSERT );
if ( trick_name_checksum )
{
return i;
}
else if ( p_trickMappings->GetInteger( key_combo, &cat_index, Script::NO_ASSERT ) )
{
return i;
}
// reset it to 0
trick_name_checksum = 0;
max_tries--;
if ( max_tries == 0 )
{
// they've probably un-mapped all their keys. check all the tricks in order
// just to be safe
for ( uint32 j = 0; j < size; j++ )
{
if ( p_keyCombos->GetType() == ESYMBOLTYPE_NAME )
key_combo = p_keyCombos->GetChecksum( j );
else
p_keyCombos->GetStructure( j )->GetChecksum( CRCD(0xacfdb27a,"key_combo"), &key_combo, Script::ASSERT );
p_trickMappings->GetChecksum( key_combo, &trick_name_checksum, Script::NO_ASSERT );
if ( trick_name_checksum )
{
return i;
}
trick_name_checksum = 0;
}
// they did un-map all their keys. Fuck 'em
NoValidKeyCombos();
break;
}
}
return -1;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::NoValidKeyCombos()
{
Script::CStruct* p_temp_params = new Script::CStruct();
p_temp_params->AddChecksum( CRCD(0x9982e501,"goal_id"), GetGoalId() );
Script::RunScript( CRCD( 0xf3c20af5, "goal_no_valid_key_combos" ), p_temp_params );
delete p_temp_params;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
uint32 CGoal::GetRootGoalId()
{
CGoalManager* pGoalManager = GetGoalManager();
CGoal* pParentGoal = this;
Dbg_Assert( pGoalManager );
// get the root node
CGoalLink* p_parent = mp_parents;
while ( p_parent && p_parent->m_relative != 0 )
{
pParentGoal = pGoalManager->GetGoal( p_parent->m_relative );
p_parent = pParentGoal->GetParents();
}
return pParentGoal->GetGoalId();
}
/******************************************************************/
/* */
/* */
/******************************************************************/
uint32 CGoal::GetGoalId()
{
uint32 goalId = 0;
mp_params->GetChecksum( "goal_id", &goalId, Script::ASSERT );
return goalId;
}
bool CGoal::IsEditedGoal()
{
Dbg_MsgAssert(mp_params,("NULL mp_params"));
return mp_params->ContainsFlag(CRCD(0x981d3ad0,"edited_goal"));
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::HasWonGoal()
{
GameNet::Manager * gamenet_man = GameNet::Manager::Instance();
Mdl::Skate* skate_mod = Mdl::Skate::Instance();
if ( gamenet_man->InNetGame() &&
( skate_mod->GetGameMode()->GetNameChecksum() == CRCD( 0xec200eaa, "netgoalattack" )) ||
( skate_mod->GetGameMode()->GetNameChecksum() == CRCD(0x1c471c60,"netlobby")))
{
return m_netIsBeat;
}
return m_isbeat;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::HasWonStage()
{
if ( HasWonGoal() )
return true;
else
{
CGoalLink* pLink = mp_children;
while ( pLink )
{
if ( pLink->m_beaten )
return true;
else
pLink = pLink->mp_next;
}
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsSelected()
{
return m_isselected;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::GotCounterObject()
{
int number_collected = 0;
mp_params->GetInteger( CRCD(0x129daa10,"number_collected"), &number_collected, Script::NO_ASSERT );
// printf("alredy collected %i\n", number_collected);
number_collected++;
mp_params->AddInteger( CRCD(0x129daa10,"number_collected"), number_collected );
if ( mp_params->ContainsFlag( CRCD(0xfd7ae1f4,"use_hud_counter") ) )
Script::RunScript( CRCD(0xf2e85a34,"goal_update_counter"), mp_params );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::CounterGoalDone()
{
int number_collected = 0;
mp_params->GetInteger( CRCD(0x129daa10,"number_collected"), &number_collected, Script::NO_ASSERT );
int number;
mp_params->GetInteger( CRCD(0x696fe0ab,"number"), &number, Script::ASSERT );
return ( number_collected >= number );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::MarkInvalid()
{
m_invalid = true;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsInvalid()
{
return m_invalid;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::HasProset( const char* proset_prefix )
{
const char* p_local_proset;
if ( mp_params->GetString( CRCD(0x955c6305,"proset_prefix"), &p_local_proset, Script::NO_ASSERT ) )
{
if ( stricmp( p_local_proset, proset_prefix ) == 0 )
return true;
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetHasSeen()
{
m_hasSeen = true;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::MarkBeaten()
{
GameNet::Manager * gamenet_man = GameNet::Manager::Instance();
Mdl::Skate* skate_mod = Mdl::Skate::Instance();
if( gamenet_man->InNetGame() && skate_mod->GetGameMode()->GetNameChecksum() == CRCD( 0xec200eaa, "netgoalattack" ) )
{
m_netIsBeat = true;
}
else
{
m_isbeat = true;
}
// mark all goals in the tree beaten
CGoalManager* pGoalManager = GetGoalManager();
Dbg_Assert( pGoalManager );
Game::CGoalLink* p_link = mp_parents;
while ( p_link && p_link->m_relative != 0 )
{
CGoal* pGoal = pGoalManager->GetGoal( p_link->m_relative );
pGoal->MarkBeaten();
p_link = p_link->mp_next;
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::MarkBeatenBy( int id )
{
Dbg_Printf( "**** Marking goal 0x%x as beaten\n", GetGoalId());
m_beatenFlags.Set( id );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::MarkBeatenByTeam( int team_id )
{
m_teamBeatenFlags.Set( team_id );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::HasWonGoal( int id )
{
return m_beatenFlags.Test( id );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::HasTeamWonGoal( int team_id )
{
return m_teamBeatenFlags.Test( team_id );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::Select()
{
m_isselected = true;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::Deselect()
{
m_isselected = false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetUnlocked()
{
m_isLocked = false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetLevelNum( int levelNum )
{
m_levelNum = levelNum;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
int CGoal::GetLevelNum()
{
return m_levelNum;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::CheckMinigameRecord( int value )
{
int record = 0;
mp_params->GetInteger( CRCD(0x78ffb85c,"minigame_record"), &record, Script::NO_ASSERT );
mp_params->AddInteger( CRCD(0x819fc1d1,"last_attempt"), value );
if ( value > record )
{
mp_params->AddInteger( CRCD(0x78ffb85c,"minigame_record"), value );
return true;
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
int CGoal::GetMinigameRecord()
{
int minigame_record = -1;
mp_params->GetInteger( CRCD(0x78ffb85c,"minigame_record"), &minigame_record, Script::NO_ASSERT );
return minigame_record;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::CanRetry()
{
return ( !mp_params->ContainsFlag( CRCD(0xa612f12c,"no_restart") ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsMinigame()
{
return ( mp_params->ContainsFlag( CRCD(0x6bae094c,"minigame") ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetStartTime()
{
mp_params->AddInteger( CRCD(0x5fd80edc,"current_time"), 0 );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::UpdateComboTimer()
{
if ( !IsPaused() )
{
Tmr::Time current_time = 0;
int time;
mp_params->GetInteger( CRCD(0x5fd80edc,"current_time"), &time, Script::NO_ASSERT );
current_time = (Tmr::Time)time;
current_time += (Tmr::Time)( Tmr::FrameLength() * 1000 );
mp_params->AddInteger( CRCD(0x5fd80edc,"current_time"), (int)current_time );
// add normal units for display
mp_params->AddInteger( CRCD(0x7b1fe9a4,"current_time_seconds"), (int)( current_time / 1000 ) );
mp_params->AddInteger( CRCD(0xb4db9cb7,"current_time_fraction"), (int)( ( current_time / 10 ) % 100 ) );
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetStartHeight()
{
Mdl::Skate * skate_mod = Mdl::Skate::Instance();
Obj::CSkater *p_skater = skate_mod->GetLocalSkater();
Dbg_Assert( p_skater );
int start_height = static_cast< int >(GetSkaterStateComponentFromObject(p_skater)->GetHeight());
mp_params->AddInteger( CRCD(0xc07d8d60,"start_height"), start_height );
// printf("setting start height to %i\n", start_height);
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::CheckHeightRecord()
{
if ( !IsPaused() )
{
int record = 0;
mp_params->GetInteger( CRCD(0x78ffb85c,"minigame_record"), &record, Script::NO_ASSERT );
Mdl::Skate * skate_mod = Mdl::Skate::Instance();
Obj::CSkater *p_skater = skate_mod->GetLocalSkater();
Dbg_Assert( p_skater );
int start_height = 10000;
mp_params->GetInteger( CRCD(0xc07d8d60,"start_height"), &start_height, Script::NO_ASSERT );
int current_height = static_cast< int >(GetSkaterStateComponentFromObject(p_skater)->GetHeight()) - start_height;
//printf("current_height: %i\n", current_height);
if ( current_height < 0 )
current_height = 0;
int feet = (int)( current_height / 12 );
int inches = current_height % 12;
mp_params->AddInteger( CRCD(0x50815d42,"current_height_feet"), feet );
mp_params->AddInteger( CRCD(0xb0c26927,"current_height_inches"), inches );
if ( current_height > record )
{
mp_params->AddInteger( CRCD(0x78ffb85c,"minigame_record"), current_height );
mp_params->AddInteger( CRCD(0x24bf3ae4,"record_feet"), feet );
mp_params->AddInteger( CRCD(0x9b49f28d,"record_inches"), inches );
return true;
}
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::CheckDistanceRecord()
{
// find the object in question
uint32 objId;
mp_params->GetChecksum( CRCD(0x8e18f3b3,"distance_record_object"), &objId, Script::ASSERT );
// grab the object
Obj::CMovingObject* pObj = NULL;
// pObj = Obj::CMovingObject::m_hash_table.GetItem( objId );
pObj = (Obj::CMovingObject*) Obj::CCompositeObjectManager::Instance()->GetObjectByID( objId);
// grab the skater
Obj::CSkater* pSkater = Mdl::Skate::Instance()->GetLocalSkater();
if ( pSkater && pObj )
{
float distSquared = Mth::DistanceSqr( pObj->m_pos, pSkater->m_pos );
// get the height of the two
float objHeight = pObj->m_pos.GetY();
float skaterHeight = pSkater->m_pos.GetY();
// get the base of the right triangle formed by the three points
float distance = sqrtf( distSquared - ( Mth::Sqr( skaterHeight - objHeight ) ) );
// printf("distance = %f\n", distance);
int feet = (int)( distance / 12 );
int inches = (int)distance % 12;
mp_params->AddInteger( CRCD(0xcb48c8e8,"current_distance_feet"), feet );
mp_params->AddInteger( CRCD(0x644fc146,"current_distance_inches"), inches );
int record = 0;
mp_params->GetInteger( CRCD(0x78ffb85c,"minigame_record"), &record, Script::NO_ASSERT );
if ( distance > record )
{
mp_params->AddInteger( CRCD(0x78ffb85c,"minigame_record"), distance );
mp_params->AddInteger( CRCD(0x24bf3ae4,"record_feet"), feet );
mp_params->AddInteger( CRCD(0x9b49f28d,"record_inches"), inches );
return true;
}
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetQuickStartFlag()
{
mp_params->AddChecksum( NONAME, CRCD( 0x38221df4, "quick_start" ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::UnsetQuickStartFlag()
{
mp_params->RemoveFlag( CRCD(0x38221df4,"quick_start") );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsProGoal()
{
return ( mp_params->ContainsComponentNamed( CRCD(0xd303a1a3,"pro_goal") ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsNetGoal()
{
return ( mp_params->ContainsComponentNamed( CRCD(0xd15ea00,"net") ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsCompetition()
{
return ( mp_params->ContainsFlag( CRCD(0x4af5d34e,"competition") ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsPaused()
{
return m_paused;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::UnBeatGoal()
{
GameNet::Manager * gamenet_man = GameNet::Manager::Instance();
if( gamenet_man->InNetGame() )
{
m_beatenFlags = 0;
m_teamBeatenFlags = 0;
if( m_netIsBeat )
{
m_netIsBeat = false;
return true;
}
}
else
{
if ( m_isbeat )
{
m_isbeat = false;
return true;
}
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::GetViewGoalsText( const char** p_view_goals_text )
{
mp_params->GetText( "view_goals_text", p_view_goals_text, Script::NO_ASSERT );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsBettingGame()
{
return ( mp_params->ContainsFlag( CRCD(0x8add4306,"betting_game") ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsBettingGuy()
{
return ( mp_params->ContainsFlag( CRCD(0x8cfee956,"betting_guy") ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::EndRunCalled()
{
return m_endRunCalled;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::ClearEndRun( Script::CScript* pScript )
{
// printf("CGoal::ClearEndRun called\n");
m_endRunCalled = false;
// TODO: this should pick the right skater somehow
Mdl::Skate * skate_mod = Mdl::Skate::Instance();
Obj::CSkater* p_skater = skate_mod->GetLocalSkater();
Obj::CSkaterEndRunComponent* p_skater_endrun_component = GetSkaterEndRunComponentFromObject(p_skater);
Dbg_Assert(p_skater_endrun_component);
switch ( m_endRunType )
{
case vENDOFRUN:
// Mick: the way these type of exception is handled has changed
// I'm not sure if it still needs to be cleared here any more
// as it should have been executed immediately
// I'm removing this line for now, as the ExceptionComponent has gone
// GetExceptionComponentFromObject(p_skater)->ClearException( CRCD( 0x822e13a9, "RunHasEnded" ));
p_skater->CallMemberFunction( CRCD( 0x4c58771e, "EndOfRunDone" ), NULL, pScript );
p_skater_endrun_component->ClearStartedEndOfRunFlag();
break;
case vGOALENDOFRUN:
// GetExceptionComponentFromObject(p_skater)->ClearException( CRCD( 0xab676175, "GoalHasEnded" ) );
p_skater->CallMemberFunction( CRCD( 0x69a9e37f, "Goal_EndOfRunDone" ), NULL, pScript );
p_skater_endrun_component->ClearStartedGoalEndOfRunFlag();
break;
default:
Dbg_Assert( 0 );
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::FinishedEndOfRun()
{
// TODO: make this pick the right skater
Mdl::Skate * skate_mod = Mdl::Skate::Instance();
Obj::CSkater* p_skater = skate_mod->GetLocalSkater();
Obj::CSkaterEndRunComponent* p_skater_endrun_component = GetSkaterEndRunComponentFromObject(p_skater);
Dbg_Assert(p_skater_endrun_component);
switch ( m_endRunType )
{
case vENDOFRUN:
return p_skater_endrun_component->RunHasEnded();
break;
case vGOALENDOFRUN:
return p_skater_endrun_component->GoalRunHasEnded();
break;
default:
Dbg_Assert( 0 );
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::StartedEndOfRun()
{
// TODO: make this choose the right skater
Mdl::Skate * skate_mod = Mdl::Skate::Instance();
Obj::CSkater* p_skater = skate_mod->GetLocalSkater();
Obj::CSkaterEndRunComponent* p_skater_endrun_component = GetSkaterEndRunComponentFromObject(p_skater);
Dbg_Assert(p_skater_endrun_component);
switch ( m_endRunType )
{
case vENDOFRUN:
return p_skater_endrun_component->StartedEndOfRun();
break;
case vGOALENDOFRUN:
// return p_skater->StartedGoalEndOfRun();
return m_endRunCalled;
break;
default:
Dbg_Assert( 0 );
}
return false;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
// void CGoal::DisableEndOfRun()
// {
// m_shouldEndRun = false;
// }
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::AddTempSpecialTrick()
{
// get the new special trick name and type
uint32 trickType;
bool is_cat = mp_params->ContainsFlag( CRCD(0x8e6014f6,"create_a_trick") );
mp_params->GetChecksum( "trick_type", &trickType, Script::ASSERT );
uint32 trickName;
if ( is_cat )
{
int tempTrickName;
mp_params->GetInteger( CRCD(0xb502200,"premade_cat_index"), &tempTrickName, Script::ASSERT );
trickName = (uint32)tempTrickName;
}
else
mp_params->GetChecksum( "trick_name", &trickName, Script::ASSERT );
// get the local string version of the trick and store it
if ( is_cat )
{
Script::CArray* pPremadeCatArray = Script::GetArray( CRCD(0xffd7913f,"Premade_CATS"), Script::ASSERT );
Script::CStruct* pPremadeCat = pPremadeCatArray->GetStructure( trickName );
const char* pPremadeCatName;
pPremadeCat->GetString( CRCD(0xa1dc81f9,"name"), &pPremadeCatName, Script::ASSERT );
mp_params->AddString( CRCD(0x3a54cc4b,"trick_string"), pPremadeCatName );
}
else
{
const char* trickName_string;
Script::CStruct* p_trick = Script::GetStructure( trickName, Script::ASSERT );
Script::CStruct* p_trick_params;
p_trick->GetStructure( "Params", &p_trick_params, Script::ASSERT );
p_trick_params->GetLocalString( "Name", &trickName_string, Script::ASSERT );
mp_params->AddString( "trick_string", trickName_string );
}
// get the list of valid key bindings for this trick type
Script::CStruct* p_keyBindings = NULL;
switch ( trickType )
{
case CRCC( 0x61a1bc57, "cat" ):
case CRCC( 0x439f4704, "air" ):
p_keyBindings = Script::GetStructure( CRCD( 0x4764231d, "goal_special_tricks_air" ), Script::ASSERT );
break;
case CRCC( 0xa549b57b, "lip" ):
p_keyBindings = Script::GetStructure( CRCD( 0xa1b2d162, "goal_special_tricks_lip" ), Script::ASSERT );
break;
case CRCC( 0x255ed86f, "grind" ):
p_keyBindings = Script::GetStructure( CRCD( 0xf481d0cd, "goal_special_tricks_grind" ), Script::ASSERT );
break;
case CRCC( 0xef24413b, "manual" ):
p_keyBindings = Script::GetStructure( CRCD( 0xd72d5cf7, "goal_special_tricks_manual" ), Script::ASSERT );
break;
default:
Dbg_MsgAssert( p_keyBindings, ( "AddTempSpecialTrick got weird trick type\n" ) );
}
Obj::CPlayerProfileManager* pPlayerProfileManager = Mdl::Skate::Instance()->GetPlayerProfileManager();
Obj::CSkaterProfile* pSkaterProfile = pPlayerProfileManager->GetCurrentProfile();
// Script::CStruct* p_trickMapping = p_SkaterProfile->GetTrickMapping( CRCD(0xd544aa2d,"trick_mapping") );
int numTricks = pSkaterProfile->GetNumSpecialTrickSlots();
// we need to remember the key combo
uint32 key_combo = 0;
// search through current special tricks
bool found_trick = false;
for ( int i = 0; i < numTricks; i++ )
{
Obj::SSpecialTrickInfo trick_info = pSkaterProfile->GetSpecialTrickInfo( i );
if ( !is_cat && trick_info.m_TrickName == trickName )
{
// printf("the special trick is already bound!\n");
found_trick = true;
key_combo = trick_info.m_TrickSlot;
break;
}
p_keyBindings->RemoveFlag( trick_info.m_TrickSlot );
}
// if we didn't find the trick, grab the first available, unused key combo
if ( !found_trick )
{
// printf("binding special trick\n");
Script::CComponent* p_comp = p_keyBindings->GetNextComponent();
Dbg_MsgAssert( p_comp, ( "Could not find an open key binding\n" ) );
uint32 trickSlot = p_comp->mChecksum;
Dbg_MsgAssert( trickSlot, ( "Could not find key binding in structure" ) );
// give everyone a new slot
/*int num_profiles = pPlayerProfileManager->GetNumProfileTemplates();
for ( int i = 0; i < num_profiles; i++ )
{
Obj::CSkaterProfile* pTempProfile = pPlayerProfileManager->GetProfileTemplateByIndex( i );
pTempProfile->AwardSpecialTrickSlot();
}*/
pSkaterProfile->AwardSpecialTrickSlot();
key_combo = trickSlot;
if ( is_cat )
{
// assign cat to trickslot
Script::CStruct* pScriptParams = new Script::CStruct();
pScriptParams->AddChecksum( CRCD(0xa92a2280,"trickSlot"), trickSlot );
pScriptParams->AddInteger( CRCD(0x7f8c98fe,"index"), trickName );
pScriptParams->AddInteger( CRCD(0x7f264be9,"special_trick_index"), numTricks );
Script::RunScript( CRCD(0x466576c8,"load_premade_cat"), pScriptParams );
delete pScriptParams;
}
else
{
// add new trick to new slot
Obj::SSpecialTrickInfo trickInfo;
trickInfo.m_TrickSlot = trickSlot;
trickInfo.m_TrickName = trickName;
pSkaterProfile->SetSpecialTrickInfo( numTricks, trickInfo );
}
// make a note of this so we can remove it later
mp_params->AddInteger( CRCD( 0xbc678826, "should_remove_trick" ), 1 );
}
// testing
// Script::PrintContents( p_SkaterProfile->GetSpecialTricksStructure() );
// replace the key combo array
mp_params->RemoveComponent( "key_combos" );
Script::CArray* p_key_combos = new Script::CArray();
p_key_combos->SetSizeAndType( 1, ESYMBOLTYPE_NAME );
p_key_combos->SetChecksum( 0, key_combo );
mp_params->AddArrayPointer( "key_combos", p_key_combos );
// printf("added special trick\n");
// Script::PrintContents( mp_params );
ReplaceTrickText();
return !found_trick;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::RemoveTempSpecialTrick()
{
Mdl::Skate* skate_mod = Mdl::Skate::Instance();
Obj::CPlayerProfileManager* pPlayerProfileManager = skate_mod->GetPlayerProfileManager();
Obj::CSkaterProfile* pSkaterProfile = pPlayerProfileManager->GetCurrentProfile();
// do we need to take out the trick we added?
int should_remove;
mp_params->GetInteger( "should_remove_trick", &should_remove, Script::ASSERT );
if ( should_remove == 1 )
{
// printf("removing special trick\n");
// find it and take it out
uint32 trickName;
if ( mp_params->ContainsFlag( CRCD(0x8e6014f6,"create_a_trick") ) )
{
// int premade_cat_index;
// mp_params->GetInteger( CRCD(0xb502200,"premade_cat_index"), &premade_cat_index, Script::ASSERT );
// trickName = (uint32)premade_cat_index;
// temp cat tricks are always on 0
trickName = 0;
}
else
mp_params->GetChecksum( CRCD( 0xef6fb249, "trick_name" ), &trickName, Script::ASSERT );
// int numTricks = p_SkaterProfile->GetNumSpecialTrickSlots();
// just look through all tricks
for ( int i = 0; i < Obj::CSkaterProfile::vMAXSPECIALTRICKSLOTS; i++ )
{
Obj::SSpecialTrickInfo trick_info = pSkaterProfile->GetSpecialTrickInfo( i );
// printf("m_TrickName: %x, trickName: %x\n", trick_info.m_TrickName, trickName );
if ( trick_info.m_TrickName == trickName )
{
// printf("Removing special trick\n");
Obj::SSpecialTrickInfo new_info;
new_info.m_TrickName = CRCD( 0xf60c9090, "unassigned" );
new_info.m_TrickSlot = CRCD( 0xf60c9090, "unassigned" );
pSkaterProfile->SetSpecialTrickInfo( i, new_info );
mp_params->AddInteger( CRCD( 0xbc678826, "should_remove_trick" ), 0 );
break;
}
}
// take a slot away from everyone
/*int num_profiles = pPlayerProfileManager->GetNumProfileTemplates();
for ( int i = 0; i < num_profiles; i++ )
{
Obj::CSkaterProfile* pTempProfile = pPlayerProfileManager->GetProfileTemplateByIndex( i );
pTempProfile->AwardSpecialTrickSlot( -1 );
}*/
pSkaterProfile->AwardSpecialTrickSlot( -1 );
}
mp_params->RemoveComponent( CRCD(0x79704516,"key_combos") );
Dbg_MsgAssert( (int)pSkaterProfile->GetNumSpecialTrickSlots() <= Script::GetInteger( CRCD(0x20297d6f,"max_number_of_special_trickslots") ), ( "You have too many trickslots!" ) );
// Script::CStruct* pTest = pSkaterProfile->GetSpecialTricksStructure();
// printf("done removing\n");
// Script::PrintContents( pTest );
// remove the display string just in case
mp_params->RemoveComponent( "key_combo_string" );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::ShouldUseTimer()
{
int unlimited_time = 0;
mp_params->GetInteger( CRCD(0xf0e712d2,"unlimited_time"), &unlimited_time );
return ( unlimited_time == 0 );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::CountAsActive()
{
return IsActive();
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::LoadSaveData( Script::CStruct *pFlags )
{
int hasBeaten = 0;
pFlags->GetInteger( "hasBeaten", &hasBeaten, Script::ASSERT );
if ( hasBeaten != 0 )
MarkBeaten();
int isLocked = 1;
pFlags->GetInteger( "isLocked", &isLocked, Script::ASSERT );
if ( isLocked == 0 )
{
// special case for pro challenges
/* if ( mp_params->ContainsFlag( "pro_specific_challenge" ) && hasBeaten == 0 )
{
if ( mp_goalPed->ProIsCurrentSkater() )
SetUnlocked();
}
else
*/
SetUnlocked();
}
int hasSeen = 0;
pFlags->GetInteger( "hasSeen", &hasSeen, Script::ASSERT );
if ( hasSeen != 0 )
SetHasSeen();
// check for a completion record
int record = 0;
pFlags->GetInteger( CRCD( 0xc22a2b72, "win_record" ), &record, Script::ASSERT );
mp_params->AddInteger( "win_record", record );
uint32 record_type;
if ( mp_params->GetChecksum( "record_type", &record_type, Script::NO_ASSERT ) )
{
if ( record_type == Script::GenerateCRC( "time" ) )
m_elapsedTimeRecord = record;
else if ( record_type == Script::GenerateCRC( "score" ) )
m_winScoreRecord = record;
}
pFlags->GetInteger( "timesLost", &m_numTimesLost, Script::ASSERT );
pFlags->GetInteger( "timesWon", &m_numTimesWon, Script::ASSERT );
pFlags->GetInteger( "timesStarted", &m_numTimesStarted, Script::ASSERT );
uint32 team_pro;
pFlags->GetChecksum( CRCD(0xced8a3a4,"team_pro"), &team_pro, Script::ASSERT );
if ( team_pro != 0 )
{
mp_params->AddChecksum( CRCD(0xced8a3a4,"team_pro"), team_pro );
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::GetSaveData( Script::CStruct* pFlags )
{
pFlags->AddInteger( "levelNum", GetLevelNum() );
int isLocked = IsLocked();
pFlags->AddInteger( "isLocked", isLocked );
int hasSeen = HasSeenGoal();
pFlags->AddInteger( "hasSeen", hasSeen );
int hasBeaten = HasWonGoal();
pFlags->AddInteger( "hasBeaten", hasBeaten );
/* int isProSpecificChallenge = 0;
if ( mp_params->ContainsFlag( "pro_specific_challenge" ) )
isProSpecificChallenge = 1;
pFlags->AddInteger( "isProSpecificChallenge", isProSpecificChallenge );
*/
int record = 0;
uint32 record_type;
if ( mp_params->GetChecksum( "record_type", &record_type, Script::NO_ASSERT ) )
{
if ( record_type == Script::GenerateCRC( "time" ) )
record = (int)m_elapsedTimeRecord;
else if ( record_type == Script::GenerateCRC( "score" ) )
record = m_winScoreRecord;
}
pFlags->AddInteger( "win_record", record );
// TODO: should this be removed for the release?
pFlags->AddInteger( "timesLost", m_numTimesLost );
pFlags->AddInteger( "timesWon", m_numTimesWon );
pFlags->AddInteger( "timesStarted", m_numTimesStarted );
uint32 team_pro = 0;
mp_params->GetChecksum( CRCD(0xced8a3a4,"team_pro"), &team_pro, Script::NO_ASSERT );
pFlags->AddChecksum( CRCD(0xced8a3a4,"team_pro"), team_pro );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
// utility used by ReplaceTrickText
bool fill_trick_and_key_combo_arrays( Script::CArray* p_key_combos, Script::CArray* p_key_combo_strings, Script::CArray* p_trick_names, int premade_cat_index )
{
// make sure the arrays are the right size and type
Dbg_MsgAssert( p_key_combos->GetSize() == p_key_combo_strings->GetSize(), ( "key combo string array wrong size" ) );
Dbg_MsgAssert( p_key_combos->GetSize() == p_trick_names->GetSize(), ( "trick name array wrong size" ) );
Dbg_MsgAssert( p_key_combo_strings->GetType() == ESYMBOLTYPE_STRING, ( "array is the wrong type" ) );
Dbg_MsgAssert( p_trick_names->GetType() == ESYMBOLTYPE_STRING, ( "array is the wrong type" ) );
Script::CStruct* p_key_combo_map = Script::GetStructure( CRCD(0x8856c817,"goal_tetris_trick_text"), Script::ASSERT );
Mdl::Skate * pSkate = Mdl::Skate::Instance();
Obj::CSkaterProfile* pSkaterProfile = pSkate->GetCurrentProfile();
Script::CStruct* pTricks = pSkaterProfile->GetTrickMapping( CRCD(0xd544aa2d,"trick_mapping") );
// Script::PrintContents( pTricks );
int size = p_key_combos->GetSize();
for ( int i = 0; i < size; i++ )
{
uint32 key_combo = p_key_combos->GetChecksum( i );
// printf("checking for key combo %s\n", Script::FindChecksumName( key_combo ) );
uint32 trick_checksum = 0;
bool found_a_match = false;
int cat_trick_index = 0;
bool found_cat = false;
if ( pTricks->GetInteger( key_combo, &cat_trick_index, Script::NO_ASSERT ) )
{
// load cat info
printf("found a cat trick - cat_trick_index = %i\n", cat_trick_index);
found_cat = true;
found_a_match = true;
}
else if ( pTricks->GetChecksum( key_combo, &trick_checksum, Script::NO_ASSERT ) )
{
found_a_match = true;
}
else
{
// look for a special key combo
int numSpecials = pSkaterProfile->GetNumSpecialTrickSlots();
// printf("checking special trick slots\n");
for ( int j = 0; j < numSpecials; j++ )
{
Obj::SSpecialTrickInfo trick_info = pSkaterProfile->GetSpecialTrickInfo( j );
// printf("trickslot: %s\n", Script::FindChecksumName( trick_info.m_TrickSlot ) );
if ( trick_info.m_TrickSlot == key_combo )
{
// printf("found a match\n");
trick_checksum = trick_info.m_TrickName;
found_a_match = true;
break;
}
}
}
if ( !found_a_match )
{
// Script::PrintContents( pTricks );
// this key combo isn't assigned! bail out...
Dbg_MsgAssert( 0, ( "key combo %s not assigned!\n", Script::FindChecksumName( key_combo ) ) );
return false;
}
const char* p_key_combo_string;
p_key_combo_map->GetString( key_combo, &p_key_combo_string, Script::ASSERT );
const char* p_trick_name;
if ( found_cat )
{
// printf("getting cat params\n");
Obj::CSkater* pSkater = pSkate->GetLocalSkater();
if ( pSkater )
{
// printf("got skater\n");
Game::CCreateATrick* pCreatedTrick = pSkater->m_created_trick[cat_trick_index];
Dbg_Assert( pCreatedTrick );
// Script::PrintContents( pCreatedTrick->mp_other_params );
pCreatedTrick->mp_other_params->GetString( CRCD( 0xa1dc81f9, "name" ), &p_trick_name, Script::ASSERT );
}
}
else
{
if ( premade_cat_index > -1 )
{
Script::CArray* pPremadeCats = Script::GetArray( CRCD(0xffd7913f,"Premade_CATS"), Script::ASSERT );
Script::CStruct* pPremadeCat = pPremadeCats->GetStructure( premade_cat_index );
pPremadeCat->GetString( CRCD(0xa1dc81f9,"name"), &p_trick_name, Script::ASSERT );
}
else
{
Script::CStruct* p_trick_struct = Script::GetStructure( trick_checksum, Script::ASSERT );
Script::CStruct* p_trick_params;
p_trick_struct->GetStructure( CRCD(0x7031f10c,"Params"), &p_trick_params, Script::ASSERT );
p_trick_params->GetLocalString( CRCD(0xa1dc81f9,"Name"), &p_trick_name, Script::ASSERT );
}
}
// printf("setting strings: %s\n%s\n", p_key_combo_string, p_trick_name );
p_key_combo_strings->SetString( i, Script::CreateString( p_key_combo_string ) );
p_trick_names->SetString( i, Script::CreateString( p_trick_name ) );
}
return true;
}
// utility used by CGoal::ReplaceTrickText...finds and replaces \t and \k with
// the trick name and key combo, respectively
void find_and_replace_trick_string( const char* p_old, char* p_out, Script::CArray* p_key, Script::CArray* p_trick, uint out_buffer_size )
{
#ifdef __NOPT_ASSERT__
const char *p_out_start = p_out;
#endif
const char *p_in = p_old;
while( *p_in )
{
int tag_num;
if ( *p_in == '\\' && *(p_in+1) == 't' && ( *(p_in+2) <= '9' && *(p_in+2) >= '0' ) )
{
// printf("found the trick tag\n");
// get the index
tag_num = *(p_in+2) - 48;
if ( *(p_in+3) <= '9' && *(p_in+3) >= '0' )
{
tag_num *= 10;
tag_num += *(p_in+3) - 48;
// move ahead an extra char
p_in++;
}
// printf( "found a tag num of %i\n", tag_num );
Dbg_MsgAssert( ( tag_num > 0 ) && tag_num <= (int)p_trick->GetSize(), ( "Tag value too large" ) );
const char* p_trick_string = p_trick->GetString( tag_num - 1 );
Dbg_MsgAssert( p_trick_string, ( "ReplaceTrickText found a \\t tag but no key combo." ) );
sprintf( p_out, p_trick_string );
int length = strlen( p_trick_string );
for ( int i = 0; i < length; i++ )
p_out++;
// move past the tag
p_in++;
p_in++;
p_in++;
}
else if ( *p_in == '\\' && *(p_in+1) == 'k' && ( *(p_in+2) <= '9' && *(p_in+2) >= '0' ) )
{
// printf("found the key tag\n");
// get the index
tag_num = *(p_in+2) - 48;
if ( *(p_in+3) <= '9' && *(p_in+3) >= '0' )
{
tag_num *= 10;
tag_num += *(p_in+3) - 48;
// move ahead an extra char
p_in++;
}
// printf( "found a tag num of %i\n", tag_num );
Dbg_MsgAssert( ( tag_num > 0 ) && tag_num <= (int)p_key->GetSize(), ( "Tag value too large" ) );
const char* p_key_string = p_key->GetString( tag_num - 1 );
Dbg_MsgAssert( p_key_string, ( "ReplaceTrickText found a \\k tag but no key combo." ) );
sprintf( p_out, p_key_string );
int length = strlen( p_key_string );
for ( int i = 0; i < length; i++ )
p_out++;
// move past the tag
p_in++;
p_in++;
p_in++;
}
else
{
*p_out++ = *p_in++;
}
}
*p_out++ = '\0';
Dbg_MsgAssert(strlen(p_out_start) < out_buffer_size,("String overflow with\n\n%s\n\nMake it shorter than %d chars, or get a bigger buffer",p_out_start, out_buffer_size));
}
bool CGoal::ReplaceTrickText()
{
// printf("ReplaceTrickText %s\n", Script::FindChecksumName( GetGoalId() ) );
// see if there's a key_combo associated with this goal
Script::CArray* p_key_combo = NULL;
if ( !mp_params->GetArray( "key_combos", &p_key_combo, Script::NO_ASSERT ) )
{
// printf("no key combos\n");
return false;
}
// Make sure we have copies of the original text. We want
// to update properly if they change their trick bindings.
if ( !mp_params->ContainsComponentNamed( "original_goal_description" ) )
{
const char* p_ogd;
Script::CArray* p_ogd_array;
if ( mp_params->GetString( "goal_description", &p_ogd, Script::NO_ASSERT ) )
mp_params->AddString( "original_goal_description", p_ogd );
else if ( mp_params->GetArray( "goal_description", &p_ogd_array, Script::ASSERT ) )
mp_params->AddArray( "original_goal_description", p_ogd_array );
}
if ( !mp_params->ContainsComponentNamed( "original_view_goals_text" ) )
{
const char* p_ovgt;
if ( mp_params->GetString( "view_goals_text", &p_ovgt, Script::NO_ASSERT ) )
mp_params->AddString( "original_view_goals_text", p_ovgt );
}
if ( !mp_params->ContainsComponentNamed( "original_goal_text" ) )
{
const char* p_ogt;
if ( mp_params->GetString( "goal_text", &p_ogt, Script::NO_ASSERT ) )
mp_params->AddString( "original_goal_text", p_ogt );
}
if ( !mp_params->ContainsComponentNamed( "original_key_combo_text" ) )
{
const char* p_okct;
if ( mp_params->GetString( "key_combo_text", &p_okct, Script::NO_ASSERT ) )
mp_params->AddString( "original_key_combo_text", p_okct );
}
// special case for cat goal
int premade_cat_index = -1;
if ( mp_params->ContainsFlag( CRCD(0x8e6014f6,"create_a_trick") ) )
{
mp_params->GetInteger( CRCD(0xb502200,"premade_cat_index"), &premade_cat_index, Script::ASSERT );
}
// get the new string arrays
Script::CArray* p_key = new Script::CArray();
Script::CArray* p_trick = new Script::CArray();
int size = p_key_combo->GetSize();
p_key->SetSizeAndType( size, ESYMBOLTYPE_STRING );
p_trick->SetSizeAndType( size, ESYMBOLTYPE_STRING );
if ( !fill_trick_and_key_combo_arrays( p_key_combo, p_key, p_trick, premade_cat_index ) )
{
Script::CleanUpArray( p_key );
Script::CleanUpArray( p_trick );
delete p_key;
delete p_trick;
return false;
}
const char* p_string;
Script::CArray* p_string_array = NULL;
char new_string[Game::NEW_STRING_LENGTH];
// replace the goal description
if ( mp_params->GetString( "original_goal_description", &p_string, Script::NO_ASSERT ) )
{
find_and_replace_trick_string( p_string, new_string, p_key, p_trick, Game::NEW_STRING_LENGTH );
mp_params->AddString( "goal_description", p_string );
}
else if ( mp_params->GetArray( "original_goal_description", &p_string_array, Script::ASSERT ) )
{
int size = p_string_array->GetSize();
Script::CArray* p_new_string_array = new Script::CArray();
p_new_string_array->SetSizeAndType( size, ESYMBOLTYPE_STRING );
for ( int i = 0; i < size; i++ )
{
p_string = p_string_array->GetString( i );
find_and_replace_trick_string( p_string, new_string, p_key, p_trick, Game::NEW_STRING_LENGTH );
p_new_string_array->SetString( i, Script::CreateString( new_string ) );
}
mp_params->AddArray( "goal_description", p_new_string_array );
Script::CleanUpArray( p_new_string_array );
delete p_new_string_array;
}
// replace the view goals text
if ( mp_params->GetString( "original_view_goals_text", &p_string, Script::NO_ASSERT ) )
{
find_and_replace_trick_string( p_string, new_string, p_key, p_trick, Game::NEW_STRING_LENGTH );
mp_params->AddString( "view_goals_text", new_string );
}
// replace the goal text
if ( mp_params->GetString( "original_goal_text", &p_string, Script::NO_ASSERT ) )
{
find_and_replace_trick_string( p_string, new_string, p_key, p_trick, Game::NEW_STRING_LENGTH );
mp_params->AddString( "goal_text", new_string );
}
// replace the key combo text
if ( mp_params->GetString( "original_key_combo_text", &p_string, Script::NO_ASSERT ) )
{
find_and_replace_trick_string( p_string, new_string, p_key, p_trick, Game::NEW_STRING_LENGTH );
mp_params->AddString( "key_combo_text", new_string );
}
// cleanup!
Script::CleanUpArray( p_key );
Script::CleanUpArray( p_trick );
delete p_key;
delete p_trick;
return true;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
int CGoal::GetNumberCollected()
{
int number_collected = 0;
// check for special counter goal num
if ( mp_params->GetInteger( CRCD(0x129daa10,"number_collected"), &number_collected, Script::NO_ASSERT ) )
return number_collected;
// return the number of flags set
return m_flagsSet;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
int CGoal::GetNumberOfFlags()
{
int num_flags_to_win = m_numflags;
mp_params->GetInteger( CRCD(0x1171a555,"num_flags_to_win"), &num_flags_to_win, Script::NO_ASSERT );
if ( num_flags_to_win != 0 )
return num_flags_to_win;
return -1;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::ColorTrickObjects( int seqIndex, bool clear )
{
Mdl::Skate * skate_mod = Mdl::Skate::Instance();
Obj::CTrickObjectManager* p_trickObjMan = skate_mod->GetTrickObjectManager();
Script::CArray* p_clusters = NULL;
if ( !mp_params->GetArray( "kill_clusters", &p_clusters, Script::NO_ASSERT ) )
return;
int numClusters = p_clusters->GetSize();
for ( int i = 0; i < numClusters; i++ )
{
Script::CStruct* p_temp = p_clusters->GetStructure( i );
uint32 cluster_id;
p_temp->GetChecksum( "id", &cluster_id, Script::ASSERT );
Obj::CTrickCluster* p_trickCluster = p_trickObjMan->GetTrickCluster( cluster_id );
if ( p_trickCluster )
{
if ( clear )
{
// printf("clearing cluster %s\n", Script::FindChecksumName( cluster_id ) );
Obj::CTrickCluster* p_trickCluster = p_trickObjMan->GetTrickCluster( cluster_id );
if ( p_trickCluster )
p_trickCluster->ClearCluster( seqIndex );
}
else
p_trickObjMan->GetTrickCluster( cluster_id )->ModulateTrickObjectColor( seqIndex );
}
else
Dbg_Message( "WARNING: cluster %s not found\n", Script::FindChecksumName( cluster_id ) );
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
int CGoal::GetNumberOfTimesGoalStarted()
{
return m_numTimesStarted;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::GetRewardsStructure( Script::CStruct *p_structure, bool give_cash )
{
CGoalManager* pGoalManager = GetGoalManager();
Dbg_Assert( pGoalManager );
GameNet::Manager * gamenet_man = GameNet::Manager::Instance();
if ( !mp_params->ContainsFlag( CRCD(0x981d3ad0,"edited_goal") ) )
pGoalManager->AddGoalPoint();
p_structure->AddChecksum( NONAME, CRCD( 0xc7fef529, "awarded_goal_point" ) );
// No rewards in net games, only fanfare
if( gamenet_man->InNetGame() == false )
{
// special case for special trick goal
if ( mp_params->ContainsFlag( "reward_trickslot" ) && !mp_params->ContainsFlag( CRCD( 0x8e6014f6, "create_a_trick" ) ) )
{
// printf("found trickslot flag\n");
Mdl::Skate* skate_mod = Mdl::Skate::Instance();
Obj::CSkaterProfile* p_SkaterProfile = skate_mod->GetCurrentProfile();
int num_slots = p_SkaterProfile->GetNumSpecialTrickSlots();
if ( num_slots <= Script::GetInteger( CRCD(0x20297d6f,"max_number_of_special_trickslots") ) )
{
// printf("has less than the max number of slots\n");
int should_remove = 0;
mp_params->GetInteger( "should_remove_trick", &should_remove, Script::NO_ASSERT );
if ( should_remove == 1 )
{
// printf("was going to remove the special trick, but don't!\n");
mp_params->AddInteger( "should_remove_trick", 0 );
// p_reward_params->AddChecksum( NONAME, CRCD( 0x65ca5ffc, "already_added_trickslot" ) );
mp_params->AddChecksum( NONAME, CRCD( 0x65ca5ffc, "already_added_trickslot" ) );
mp_params->AddInteger( CRCD(0xb45fd352,"just_added_trickslot"), 1 );
}
}
}
// ************************
// new global reward stuff
// ************************
// grab the list of rewards
Script::CStruct* p_all_rewards = Script::GetStructure( "goal_rewards", Script::ASSERT );
Script::CStruct* p_rewards = NULL;
p_all_rewards->GetStructure( GetGoalId(), &p_rewards, Script::NO_ASSERT );
if ( p_rewards )
{
// map the reward_stat flag to an int
if ( p_rewards->ContainsFlag( "reward_stat" ) )
{
p_rewards->RemoveComponent( "reward_stat" );
p_rewards->AddInteger( "reward_stat", 1 );
}
p_structure->AppendStructure( p_rewards );
if ( give_cash )
{
int reward_cash;
if ( p_rewards->GetInteger( "reward_cash", &reward_cash, Script::NO_ASSERT ) )
p_structure->AddInteger( "cash", reward_cash );
}
}
// **************************
// old reward stuff
// **************************
else
{
if ( give_cash )
{
int reward_cash;
// give 'em cash
if ( mp_params->GetInteger( "reward_cash", &reward_cash, Script::NO_ASSERT ) )
p_structure->AddInteger( "cash", reward_cash );
}
// stat points
int stat_points;
if ( mp_params->ContainsFlag( "reward_stat" ) )
p_structure->AddInteger( "reward_stat", 1 );
else if ( mp_params->GetInteger( "reward_stat", &stat_points, Script::NO_ASSERT ) )
p_structure->AddInteger( "reward_stat", stat_points );
}
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::UnlockRewardGoals()
{
CGoalManager* pGoalManager = GetGoalManager();
// unlock a new goal
Script::CArray* p_new_goal_array = NULL;
uint32 new_goal_checksum = 0;
if ( mp_params->GetChecksum( "reward_goal", &new_goal_checksum, Script::NO_ASSERT ) )
pGoalManager->UnlockGoal( new_goal_checksum );
// check for an array of goals to unlock
else if ( mp_params->GetArray( "reward_goal", &p_new_goal_array, Script::NO_ASSERT ) )
{
int num_goals_to_unlock = p_new_goal_array->GetSize();
for ( int i = 0; i < num_goals_to_unlock; i++ )
{
new_goal_checksum = p_new_goal_array->GetChecksum( i );
if ( new_goal_checksum )
pGoalManager->UnlockGoal( new_goal_checksum );
}
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetEndRunType( EndRunType newEndRunType )
{
m_endRunType = newEndRunType;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::SetShouldDeactivateOnExpire( bool should_deactivate )
{
m_deactivateOnExpire = should_deactivate;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsHorseGoal()
{
return mp_params->ContainsFlag( CRCD(0x9d65d0e7,"horse") );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::IsFindGapsGoal()
{
return ( mp_params->ContainsFlag( CRCD( 0xc5ec08e6, "findGaps" ) ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::ShouldRequireCombo()
{
return mp_params->ContainsFlag( CRCD(0xf8e31760,"require_combo") );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CGoal::AppendDifficultyLevelParams()
{
Script::CArray* pLevelParams;
if ( mp_params->GetArray( CRCD( 0x85104ab3, "difficulty_level_params" ), &pLevelParams, Script::NO_ASSERT ) )
{
CGoalManager* pGoalManager = GetGoalManager();
Dbg_Assert( pGoalManager );
Game::GOAL_MANAGER_DIFFICULTY_LEVEL difficulty_level = pGoalManager->GetDifficultyLevel();
Dbg_MsgAssert( difficulty_level < (int)pLevelParams->GetSize(), ( "Difficulty params array has wrong size in goal %s", Script::FindChecksumName( GetGoalId() ) ) );
mp_params->AppendStructure( pLevelParams->GetStructure( difficulty_level ) );
CreateGoalFlags( mp_params );
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
bool CGoal::RunCallbackScript( uint32 script_name )
{
#if 1
uint32 checksum;
if ( mp_params->GetChecksum( script_name, &checksum, Script::NO_ASSERT ) )
{
Script::RunScript( checksum, mp_params );
return true;
}
#else
Script::CStruct* pStruct;
if ( mp_params->GetStructure( script_name, &pStruct, Script::NO_ASSERT ) )
{
// target script name is required
uint32 checksum;
pStruct->GetChecksum( CRCD(0xb990d003,"target"), &checksum, Script::ASSERT );
// but not the params...
Script::CStruct* pSubStruct = NULL;
pStruct->GetStructure( CRCD(0x7031f10c,"params"), &pSubStruct, Script::NO_ASSERT );
if ( pParams )
pSubStruct->AppendStructure( pParams );
Script::RunScript( checksum, pSubStruct );
return true;
}
#endif
else
{
return false;
}
}
} // namespace Game