Пример #1
0
// reset things to prepare for entry to the next stage
bool Game::initlevel()
{
	Carets::DestroyAll();	// delete smoke clouds, ZZzz's etc...
	ScreenEffects::Stop();	// prevents white flash after island scene when ballos defeated
	
	game.frozen = false;
	game.bossbar.object = NULL;
	nOnscreenObjects = 0;
	
	if (statusbar_init()) return 1;					// reset his displayed health value
	InitPlayer();
	initmap();
	
	game.stageboss.SetType(stages[game.curmap].bossNo);
	game.stageboss.OnMapEntry();
	
	map_scroll_jump(player->CenterX(), player->CenterY());
	
	if (game.switchstage.eventonentry)
	{
		// this prevents a glitch otherwise caused by entry script to Last Cave.
		// i.e. the script immediately <PRI's then fades in while the game is still
		// frozen, thus the player code never has a chance to set the initial frame.
		PHandleAttributes();
		PSelectFrame();
		
		stat("-- Starting on-entry script %d", game.switchstage.eventonentry);
		StartScript(game.switchstage.eventonentry);
		game.switchstage.eventonentry = 0;
	}
	
	return 0;
}
Пример #2
0
/**
 * Initializes instance of GameSetup
 */
void SpringApp::Startup()
{
	// bash input
	const std::string inputFile = cmdline->GetInputFile();
	const std::string extension = FileSystem::GetExtension(inputFile);

	// note: avoid any .get() leaks between here and GameServer!
	clientSetup.reset(new ClientSetup());

	// create base client-setup
	if (cmdline->IsSet("server")) {
		clientSetup->hostIP = cmdline->GetString("server");
		clientSetup->isHost = true;
	}

	clientSetup->myPlayerName = configHandler->GetString("name");
	clientSetup->SanityCheck();

	// no argument (either game is given or show selectmenu)
	if (inputFile.empty()) {
		clientSetup->isHost = true;
		if (cmdline->IsSet("game") && cmdline->IsSet("map")) {
			// --game and --map directly specified, try to run them
			activeController = RunScript(StartScriptGen::CreateMinimalSetup(cmdline->GetString("game"), cmdline->GetString("map")));
			return;
		}
		LoadSpringMenu();
		return;
	}

	// process given argument
	if (inputFile.find("spring://") == 0) {
		// url (syntax: spring://username:password@host:port)
		if (!ParseSpringUri(inputFile, clientSetup->myPlayerName, clientSetup->myPasswd, clientSetup->hostIP, clientSetup->hostPort))
			throw content_error("invalid url specified: " + inputFile);

		clientSetup->isHost = false;
		pregame = new CPreGame(clientSetup);
	} else if (extension == "sdf") {
		// demo
		clientSetup->isHost        = true;
		clientSetup->myPlayerName += " (spec)";

		pregame = new CPreGame(clientSetup);
		pregame->LoadDemo(inputFile);
	} else if (extension == "ssf") {
		// savegame
		clientSetup->isHost = true;

		pregame = new CPreGame(clientSetup);
		pregame->LoadSavefile(inputFile);
	} else {
		StartScript(inputFile);
	}
}
TInt CTestDataCallCallBack::Start()
/**
 * This method is defined as a pure virtual function that must be implemented.
 * This method is currently not used by the Etel regression test harness.
 * Instead of using this method to start the scripts, the CTestTxMess::Start()
 * method is used to start the scripts.  The CTestTxMess::Start() is called by
 * the responder thread of the scripting engine to start the execution of the script.
 *
 * @return KErrNone.
 */
	{
	StartScript(iScript);
	return KErrNone;
	}
Пример #4
0
void GameJoined(void)
{
	if(!Vars.bUseProfileScript)
	{
		const char* starter = GetStarterScriptName();
		if(starter != NULL)
		{
			Print("ÿc2D2BSÿc0 :: Starting %s", starter);
			if(StartScript(starter, GetStarterScriptState()))
				Print("ÿc2D2BSÿc0 :: %s running.", starter);
			else
				Print("ÿc2D2BSÿc0 :: Failed to start %s!", starter);
		}
	}
}
Пример #5
0
void MenuEntered(bool beginStarter)
{
	if(beginStarter && !Vars.bUseProfileScript)
	{
		const char* starter = GetStarterScriptName();
		if(starter != NULL)
		{
			Print("ÿc2D2BSÿc0 :: Starting %s", starter);
			if(StartScript(starter, GetStarterScriptState()))
				Print("ÿc2D2BSÿc0 :: %s running.", starter);
			else
				Print("ÿc2D2BSÿc0 :: Failed to start %s!", starter);
		}
	}
}
Пример #6
0
void SpringApp::LoadSpringMenu()
{
	const std::string defaultscript = configHandler->GetString("DefaultStartScript");

	if (cmdline->IsSet("oldmenu") || defaultscript.empty()) {
		// old menu
	#ifdef HEADLESS
		handleerror(NULL,
			"The headless version of the engine can not be run in interactive mode.\n"
			"Please supply a start-script, save- or demo-file.", "ERROR", MBF_OK|MBF_EXCL);
	#endif
		// not a memory-leak: SelectMenu deletes itself on start
		activeController = new SelectMenu(clientSetup);
	} else { // run custom menu from game and map
		StartScript(defaultscript);
	}
}
Пример #7
0
void QueueScriptCoordinator::CheckQueue()
{
	DownloadQueue* pDownloadQueue = DownloadQueue::Lock();
	m_mutexQueue.Lock();

	delete m_pCurItem;

	m_pCurItem = NULL;
	NZBInfo* pCurNZBInfo = NULL;
	Queue::iterator itCurItem = m_Queue.end();

	for (Queue::iterator it = m_Queue.begin(); it != m_Queue.end(); )
	{
		QueueItem* pQueueItem = *it;

		NZBInfo* pNZBInfo = pDownloadQueue->GetQueue()->Find(pQueueItem->GetNZBID());

		// in a case this nzb must not be processed further - delete queue script from queue
		if (!pNZBInfo || pNZBInfo->GetDeleteStatus() != NZBInfo::dsNone ||
			pNZBInfo->GetMarkStatus() == NZBInfo::ksBad)
		{
			delete pQueueItem;
			it = m_Queue.erase(it);
			continue;
		}

		if (!m_pCurItem || pQueueItem->GetEvent() > m_pCurItem->GetEvent())
		{
			m_pCurItem = pQueueItem;
			itCurItem = it;
			pCurNZBInfo = pNZBInfo;
		}

		it++;
	}

	if (m_pCurItem)
	{
		m_Queue.erase(itCurItem);
		StartScript(pCurNZBInfo, m_pCurItem);
	}

	m_mutexQueue.Unlock();
	DownloadQueue::Unlock();
}
Пример #8
0
void Reload(void)
{
	if(ScriptEngine::GetCount() > 0)
		Print("ÿc2D2BSÿc0 :: Stopping all scripts");
	ScriptEngine::StopAll();

	if(Vars.bDisableCache != TRUE)
		Print("ÿc2D2BSÿc0 :: Flushing the script cache");
	ScriptEngine::FlushCache();

	// wait for things to catch up
	Sleep(500);

	if(!Vars.bUseProfileScript)
	{
		const char* script = GetStarterScriptName();
		if(StartScript(script, GetStarterScriptState()))
			Print("ÿc2D2BSÿc0 :: Started %s", script);
		else
			Print("ÿc2D2BSÿc0 :: Failed to start %s", script);
	}
}
Пример #9
0
bool ProcessCommand(const char* command, bool unprocessedIsCommand)
{
	bool result = false;
	char* buf = _strdup(command);
	char* next_token1;
	char* argv = strtok_s(buf, " ", &next_token1);

	// no command?
	if(argv == NULL)
		return false;

	if(_strcmpi(argv, "start") == 0)
	{
		const char* script = GetStarterScriptName();
		if(StartScript(script, GetStarterScriptState()))
			Print("ÿc2D2BSÿc0 :: Started %s", script);
		else
			Print("ÿc2D2BSÿc0 :: Failed to start %s", script);
		result = true;
	}
	else if(_strcmpi(argv, "stop") == 0)
	{
		if(ScriptEngine::GetCount() > 0)
			Print("ÿc2D2BSÿc0 :: Stopping all scripts");
		ScriptEngine::StopAll();
		result = true;
	}
	else if(_strcmpi(argv, "flush") == 0)
	{
		if(Vars.bDisableCache != TRUE)
			Print("ÿc2D2BSÿc0 :: Flushing the script cache");
		ScriptEngine::FlushCache();
		result = true;
	}
	else if(_strcmpi(argv, "load") == 0)
	{
		const char* script = command+5;
		if(StartScript(script, GetStarterScriptState()))
			Print("ÿc2D2BSÿc0 :: Started %s", script);
		else
			Print("ÿc2D2BSÿc0 :: Failed to start %s", script);
		result = true;
	}
	else if(_strcmpi(argv, "reload") == 0)
	{
		Reload();
		result = true;
	}
#if DEBUG
	else if(_strcmpi(argv, "crash") == 0)
	{
		DWORD zero = 0;
		double value = 1/zero;
		Print("%d", value);
	}
	else if(_strcmpi(argv, "profile") == 0)
	{
		const char* profile = command+8;
		if(SwitchToProfile(profile))
			Print("ÿc2D2BSÿc0 :: Switched to profile %s", profile);
		else
			Print("ÿc2D2BSÿc0 :: Profile %s not found", profile);
		result = true;
	}
#endif
	else if(_strcmpi(argv, "exec") == 0 && !unprocessedIsCommand)
	{
		ExecCommand(command+5);
		result = true;
	}
	else if(unprocessedIsCommand)
	{
		ExecCommand(command);
		result = true;
	}
	return result;
}
TInt CTestTwoFaxRx::Start()
	{
	StartScript(iScript);
	return KErrNone;
	}
Пример #11
0
void QueueScriptCoordinator::EnqueueScript(NZBInfo* pNZBInfo, EEvent eEvent)
{
	if (!m_bHasQueueScripts)
	{
		return;
	}

	m_mutexQueue.Lock();

	if (eEvent == qeNzbDownloaded)
	{
		// delete all other queued scripts for this nzb
		for (Queue::iterator it = m_Queue.begin(); it != m_Queue.end(); )
		{
			QueueItem* pQueueItem = *it;
			if (pQueueItem->GetNZBID() == pNZBInfo->GetID())
			{
				delete pQueueItem;
				it = m_Queue.erase(it);
				continue;
			}
			it++;
		}
	}

	// respect option "EventInterval"
	time_t tCurTime = time(NULL);
	if (eEvent == qeFileDownloaded &&
		(g_pOptions->GetEventInterval() == -1 ||
		 (g_pOptions->GetEventInterval() > 0 && tCurTime - pNZBInfo->GetQueueScriptTime() > 0 &&
		 (int)(tCurTime - pNZBInfo->GetQueueScriptTime()) < g_pOptions->GetEventInterval())))
	{
		m_mutexQueue.Unlock();
		return;
	}

	for (ScriptConfig::Scripts::iterator it = g_pScriptConfig->GetScripts()->begin(); it != g_pScriptConfig->GetScripts()->end(); it++)
	{
		ScriptConfig::Script* pScript = *it;

		if (!pScript->GetQueueScript())
		{
			continue;
		}

		bool bUseScript = false;

		// check queue-scripts
		const char* szQueueScript = g_pOptions->GetQueueScript();
		if (!Util::EmptyStr(szQueueScript))
		{
			// split szQueueScript into tokens
			Tokenizer tok(szQueueScript, ",;");
			while (const char* szScriptName = tok.Next())
			{
				if (Util::SameFilename(szScriptName, pScript->GetName()))
				{
					bUseScript = true;
					break;
				}
			}
		}

		// check post-processing-scripts
		if (!bUseScript)
		{
			for (NZBParameterList::iterator it = pNZBInfo->GetParameters()->begin(); it != pNZBInfo->GetParameters()->end(); it++)
			{
				NZBParameter* pParameter = *it;
				const char* szVarname = pParameter->GetName();
				if (strlen(szVarname) > 0 && szVarname[0] != '*' && szVarname[strlen(szVarname)-1] == ':' &&
					(!strcasecmp(pParameter->GetValue(), "yes") ||
					 !strcasecmp(pParameter->GetValue(), "on") ||
					 !strcasecmp(pParameter->GetValue(), "1")))
				{
					char szScriptName[1024];
					strncpy(szScriptName, szVarname, 1024);
					szScriptName[1024-1] = '\0';
					szScriptName[strlen(szScriptName)-1] = '\0'; // remove trailing ':'
					if (Util::SameFilename(szScriptName, pScript->GetName()))
					{
						bUseScript = true;
						break;
					}
				}
			}
		}

		bUseScript &= Util::EmptyStr(pScript->GetQueueEvents()) || strstr(pScript->GetQueueEvents(), QUEUE_EVENT_NAMES[eEvent]);

		if (bUseScript)
		{
			bool bAlreadyQueued = false;
			if (eEvent == qeFileDownloaded)
			{
				// check if this script is already queued for this nzb
				for (Queue::iterator it2 = m_Queue.begin(); it2 != m_Queue.end(); it2++)
				{
					QueueItem* pQueueItem = *it2;
					if (pQueueItem->GetNZBID() == pNZBInfo->GetID() && pQueueItem->GetScript() == pScript)
					{
						bAlreadyQueued = true;
						break;
					}
				}
			}

			if (!bAlreadyQueued)
			{
				QueueItem* pQueueItem = new QueueItem(pNZBInfo->GetID(), pScript, eEvent);
				if (m_pCurItem)
				{
					m_Queue.push_back(pQueueItem);
				}
				else
				{
					StartScript(pNZBInfo, pQueueItem);
				}
			}

			pNZBInfo->SetQueueScriptTime(time(NULL));
		}
	}

	m_mutexQueue.Unlock();
}
Пример #12
0
TInt CTestSSData::Start()
	{
	StartScript(iScript);
	return KErrNone;
	}
Пример #13
0
TInt CTestSsFax::Start()
	{
	StartScript(iScript);
	return KErrNone;
	}
Пример #14
0
void ondeath_ironhead(Object *o)
{
	StartScript(1000);
}
Пример #15
0
static void RunSelector(stSelector *selector)
{
int nrows;
int currow, curcol;
char toggle = 0;

	if (inv.lockinput)
	{
		if (GetCurrentScript()==-1) inv.lockinput = 0;
		else return;
	}
	
	if (selector->nitems)
	{
		nrows = (selector->nitems - 1) / selector->rowlen;
		currow = (selector->cursel / selector->rowlen);
		curcol = (selector->cursel % selector->rowlen);
	}
	else
	{
		nrows = currow = curcol = 0;
	}
	
	if (justpushed(LEFTKEY))
	{
		sound(selector->sound);
		
		// at beginning of row?
		if (curcol == 0)
		{	// wrap to end of row
			if (currow < nrows)
				selector->cursel += (selector->rowlen - 1);
			else if (selector->nitems > 0)
				selector->cursel = selector->nitems - 1;
		}
		else selector->cursel--;
	}
	
	if (justpushed(RIGHTKEY))
	{
		sound(selector->sound);
		
		// at end of row?
		if (curcol==selector->rowlen-1 || selector->cursel+1 >= selector->nitems)
		{	// wrap to beginning of row
			selector->cursel = (currow * selector->rowlen);
		}
		else selector->cursel++;
	}
	
	if (justpushed(DOWNKEY))
	{
		// on last row?
		if (currow >= nrows) toggle = 1;
		else
		{
			selector->cursel += selector->rowlen;
			
			// don't go past last item
			if (selector->cursel >= selector->nitems)
				selector->cursel = (selector->nitems - 1);
				
			sound(selector->sound);
		}
	}
	
	if (justpushed(UPKEY))
	{
		// on top row?
		if (currow == 0) toggle = 1;
		else
		{
			selector->cursel -= selector->rowlen;
			sound(selector->sound);
		}
	}
	
	// switch to other selector
	if (toggle)
	{
		if (selector == &inv.itemsel)
		{
			selector = &inv.armssel;
		}
		else
		{
			selector = &inv.itemsel;
		}
		
		inv.curselector = selector;
		
		sound(selector->sound);
		selector->lastsel = -9999;
	}
	
	// bring up scripts
	if (selector->cursel != selector->lastsel)
	{
		selector->lastsel = selector->cursel;
		
		StartScript(selector->items[selector->cursel] + selector->scriptbase, SP_ARMSITEM);
	}
	
	
	if (selector == &inv.armssel)		// selecting a weapon
	{
		if (buttonjustpushed())
		{	// select the new weapon
			weapon_slide(LEFT, selector->items[selector->cursel]);
			ExitInventory();
		}
	}
	else									// selecting an item
	{
		if (justpushed(JUMPKEY))
		{	// bring up "more info" or "equip" script for this item
			StartScript(selector->items[selector->cursel] + selector->scriptbase + 1000, SP_ARMSITEM);
			inv.lockinput = 1;
		}
		
		if (justpushed(FIREKEY))
			ExitInventory();
	}

   if (justpushed(INVENTORYKEY))
			ExitInventory();
}
TInt CTestShutdown::Start()
{
    StartScript(iScript);
    return KErrNone;
}
Пример #17
0
void XBoss::Run()
{
Object *o = mainobject;
int i;

	if (!mainobject) return;
	if (o->state == 0 || (!X.initilized && o->state != STATE_X_APPEAR))
	{
		o->hp = 1;
		o->x = -(Graphics::SCREEN_WIDTH << CSF);
		return;
	}
	
	switch(o->state)
	{
		// script triggered us to initilize/appear
		// (there is a hvtrigger, right before player first walks by us
		// and sees us inactive, which sends us this ANP).
		case STATE_X_APPEAR:
		{
			if (!X.initilized)
			{
				Init();
				X.initilized = true;
			}
		}
		break;
		
		// script has triggered the fight to begin
		case STATE_X_FIGHT_BEGIN:
		{
			o->timer = 0;
			o->state++;
		}
		case STATE_X_FIGHT_BEGIN+1:
		{
			if (++o->timer > 100)
			{
				FACEPLAYER;
				o->timer = 0;
				o->state = STATE_X_TRAVEL;
			}
		}
		break;
		
		// starts the treads and moves us in the currently-facing direction
		case STATE_X_TRAVEL:
		{
			// count number of times we've traveled, we brake
			// and attack every third time.
			o->timer2++;
			
			o->timer = 0;
			o->state++;
		}
		case STATE_X_TRAVEL+1:
		{
			o->timer++;
			
			// trigger the treads to start moving,
			// and put them slightly out of sync with each-other.
			for(int i=0;i<4;i++)
			{
				if (o->timer == tread_turnon_times[i])
				{
					treads[i]->state = STATE_TREAD_RUN;
					treads[i]->dir = o->dir;
				}
			}
			
			if (o->timer > 120)
			{
				// time to attack? we attack every 3rd travel
				// if so skid to a stop, that's the first step.
				if (o->timer2 >= 3)
				{
					o->timer2 = 0;
					
					o->dir ^= 1;
					o->state = STATE_X_BRAKE;
					o->timer = 0;
				}
				else
				{
					// passed player? skid and turn around.
					if ((o->dir == RIGHT && o->x > player->x) || \
					 	(o->dir == LEFT  && o->x < player->x))
					{
						o->dir ^= 1;
						o->state = STATE_X_TRAVEL;
					}
				}
			}
		}
		break;
		
		// skidding to a stop in preparation to attack
		case STATE_X_BRAKE:
		{
			o->timer = 0;
			o->state++;
		}
		case STATE_X_BRAKE+1:
		{
			o->timer++;
			
			// trigger the treads to start braking,
			// and put them slightly out of sync with each-other.
			for(int i=0;i<4;i++)
			{
				if (o->timer == tread_turnon_times[i])
				{
					treads[i]->state = STATE_TREAD_BRAKE;
					treads[i]->dir = o->dir;
				}
			}
			
			if (o->timer > 50)
			{
				o->state = STATE_X_OPEN_DOORS;
				o->timer = 0;
			}
		}
		break;
		
		// doors opening to attack
		case STATE_X_OPEN_DOORS:
		{
			o->timer = 0;
			o->savedhp = o->hp;
			
			// select type of attack depending on where we are in the battle
			if (!AllTargetsDestroyed())
			{
				SetStates(doors, 2, STATE_DOOR_OPENING);
				o->state = STATE_X_FIRE_TARGETS;
			}
			else
			{
				SetStates(doors, 2, STATE_DOOR_OPENING_PARTIAL);
				o->state = STATE_X_FIRE_FISHIES;
			}
		}
		break;
		
		// firing targets (early battle)
		case STATE_X_FIRE_TARGETS:
		{
			if (doors[0]->state == STATE_DOOR_FINISHED)
			{
				doors[0]->state = 0;
				SetStates(targets, 4, STATE_TARGET_FIRE);
			}
			
			if (++o->timer > 300 || AllTargetsDestroyed())
			{
				o->state = STATE_X_CLOSE_DOORS;
				o->timer = 0;
			}
		}
		break;
		
		// firing fishy missiles (late battle)
		case STATE_X_FIRE_FISHIES:
		{
			if (doors[0]->state == STATE_DOOR_FINISHED)
			{
				doors[0]->state = 0;
				
				SetStates(fishspawners, 4, STATE_FISHSPAWNER_FIRE);
				internals->flags |= FLAG_SHOOTABLE;
			}
			
			if (++o->timer > 300 || (o->savedhp - o->hp) > 200)
			{
				o->state = STATE_X_CLOSE_DOORS;
				o->timer = 0;
			}
		}
		break;
		
		// doors closing after attack
		case STATE_X_CLOSE_DOORS:
		{
			o->timer = 0;
			o->state++;
			
			SetStates(doors, 2, STATE_DOOR_CLOSING);
		}
		case STATE_X_CLOSE_DOORS+1:
		{
			if (doors[0]->state == STATE_DOOR_FINISHED)
			{
				doors[0]->state = 0;
				
				// just turn off everything for both types of attacks;
				// turning off the attack type that wasn't enabled isn't harmful.
				SetStates(targets, 4, 0);
				SetStates(fishspawners, 4, 0);
				internals->flags &= ~FLAG_SHOOTABLE;
			}
			
			if (++o->timer > 50)
			{
				FACEPLAYER;
				o->state = STATE_X_TRAVEL;
				o->timer = 0;
			}
		}
		break;
		
		// exploding
		case STATE_X_EXPLODING:
		{
			SetStates(fishspawners, 4, 0);
			KillObjectsOfType(OBJ_X_FISHY_MISSILE);
			
			StartScript(1000);
			o->timer = 0;
			o->state++;
		}
		case STATE_X_EXPLODING+1:
		{
			game.quaketime = 2;
			o->timer++;
			
			if ((o->timer % 8) == 0)
				sound(SND_ENEMY_HURT_BIG);
			
			SmokePuff(o->CenterX() + (random(-72, 72) << CSF),
					  o->CenterY() + (random(-64, 64) << CSF));
			
			if (o->timer > 100)
			{
				starflash.Start(o->CenterX(), o->CenterY());
				sound(SND_EXPLOSION1);
				o->timer = 0;
				o->state++;
			}
		}
		break;
		case STATE_X_EXPLODING+2:
		{
			game.quaketime = 40;
			if (++o->timer > 50)
			{
				CreateObject(o->x, o->y - (24 << CSF), OBJ_X_DEFEATED);
				DeleteMonster();
				return;
			}
		}
		break;
	}
	
	// call AI for all tread pieces
	for(i=0;i<4;i++)
	{
		run_tread(i);
		run_fishy_spawner(i);
	}
}
Пример #18
0
void OmegaBoss::Run(void)
{
	Object *&o = game.stageboss.object;
	
	if (omg.defeated)
		return;
	
	switch(o->state)
	{
		case 0:	break;	// waiting for trigger by script
		
		case OMG_WAIT:	// waits for a moment then go to omg.nextstate
		{
			o->state++;
			omg.timer = 0;
		}
		case OMG_WAIT+1:
		{
			if (++omg.timer >= OMEGA_WAIT_TIME)
			{
				omg.timer = 0;
				o->state = omg.nextstate;
			}
		}
		break;
		
		case OMG_APPEAR:
		{
			omg.timer = 0;
			o->frame = 0;
			o->state = OMG_MOVE;
			omg.movedir = -OMEGA_SPEED;
			o->flags |= FLAG_SOLID_MUSHY;
		}
		case OMG_MOVE:	// rising up/going back into ground
		{
			o->frame = 0;
			o->y += omg.movedir;
			
			game.quaketime = 2;
			
			omg.timer++;
			if ((omg.timer & 3) == 0) sound(SND_QUAKE);
			
			if (omg.timer >= omg.movetime)
			{
				if (omg.movedir < 0)
				{	// was rising out of ground
					omg.nextstate = OMG_JAWS_OPEN;
					o->state = OMG_WAIT;
				}
				else
				{	// was going back into ground
					omg.timer = 0;
					o->state = OMG_UNDERGROUND;
					o->flags &= ~(FLAG_SOLID_MUSHY | FLAG_SOLID_BRICK);
				}
			}
		}
		break;
		
		case OMG_JAWS_OPEN:			// jaws opening
		{
			o->state++;
			omg.animtimer = 0;
			sound(SND_JAWS);
			o->sprite = SPR_OMG_OPENED;			// select "open" bounding box
		}
		case OMG_JAWS_OPEN+1:
		{
			omg.animtimer++;
			if (omg.animtimer > 2)
			{
				omg.animtimer = 0;
				o->frame++;
				if (o->frame==3)
				{
					o->state = OMG_FIRE;
					omg.firecounter = 0;
					o->flags |= FLAG_SHOOTABLE;
				}
			}
		}
		break;
		
		case OMG_FIRE:	// throwing out red stuff
		{
			omg.firecounter++;
			
			if (omg.firecounter > omg.startfiring && omg.firecounter < omg.stopfiring)
			{
				if ((omg.firecounter % omg.firefreq)==0)
				{
					Object *shot;
					
					sound(SND_EM_FIRE);
					
					shot = SpawnObjectAtActionPoint(o, OBJ_OMEGA_SHOT);
					shot->xinertia = random(-omg.shotxspd, omg.shotxspd);
					shot->yinertia = -0x333;
					if (omg.form==2 || random(0, 9) < 8)
					{
						shot->sprite = SPR_OMG_BULLET_NORMAL;
						shot->flags = FLAG_SHOOTABLE;
					}
					else
					{
						shot->sprite = SPR_OMG_BULLET_HARD;
						shot->flags = (FLAG_SHOOTABLE | FLAG_INVULNERABLE);
					}
					
					shot->timer = (random(0, 7) >= 4) ? random(300, 400):0;
					shot->damage = 4;
				}
			}
			else if (omg.firecounter >= omg.endfirestate || sound_is_playing(SND_MISSILE_HIT))
			{	// snap jaws shut
				omg.animtimer = 0;
				o->state = OMG_JAWS_CLOSE;
				sound(SND_JAWS);
			}
		}
		break;
		
		case OMG_JAWS_CLOSE:	// jaws closing
		{
			omg.animtimer++;
			if (omg.animtimer > 2)
			{
				omg.animtimer = 0;
				
				o->frame--;
				if (o->frame == 0)
				{
					sound_stop(SND_JAWS);
					sound(SND_BLOCK_DESTROY);
					
					o->sprite = SPR_OMG_CLOSED;		// select "closed" bounding box
					
					o->flags &= ~FLAG_SHOOTABLE;
					o->damage = 0;
					
					if (omg.form == 1)
					{	// form 1: return to sand
						o->state = OMG_WAIT;
						omg.nextstate = OMG_MOVE;
						omg.movedir = OMEGA_SPEED;
						omg.movetime = OMEGA_SINK_DEPTH;
					}
					else
					{	// form 2: jump
						sound(SND_FUNNY_EXPLODE);
						if (o->x < player->x) o->xinertia = 0xC0;
										 else o->xinertia = -0xC0;
						o->state = OMG_JUMP;
						o->yinertia = -0x5FF;
						omg.orgy = o->y;
					}
				}
			}
			
			// hurt player if he was standing in the middle when the jaws shut
			if (player->riding == o)
			{
				hurtplayer(OMEGA_DAMAGE);
			}
		}
		break;
		
		case OMG_UNDERGROUND:		// underground waiting to reappear
		{
			if (++omg.timer >= 120)
			{
				omg.timer = 0;
				o->state = OMG_APPEAR;
				
				o->x = omg.orgx + (random(-64, 64) << CSF);
				o->y = omg.orgy;
				omg.movetime = OMEGA_RISE_HEIGHT;
				
				// switch to jumping out of ground when we get low on life
				if (omg.form==1 && o->hp <= HP_TRIGGER_POINT)
				{
					o->flags |= FLAG_SOLID_MUSHY;
					
					omg.form = 2;
					omg.firefreq = 5;
					omg.shotxspd = 0x155;
					omg.startfiring = 0;
					omg.stopfiring = 30;
					omg.endfirestate = 50;
					omg.movetime = OMEGA_RISE_HEIGHT+3;
				}
			}
		}
		break;
		
		case OMG_JUMP:	// init for jump
		{
			omg.orgy = o->y;
			o->state++;
			omg.timer = 0;
		}
		case OMG_JUMP+1:	// jumping
		{
			o->yinertia += 0x24;
			if (o->yinertia > 0x5ff) o->yinertia = 0x5ff;
			
			if (o->yinertia > 0)
			{	// coming down
				
				pieces[LEFTLEG]->sprite = pieces[RIGHTLEG]->sprite = SPR_OMG_LEG_ONGROUND;
				
				// retract legs a little when we hit the ground
				if (pieces[LEFTLEG]->blockd || pieces[RIGHTLEG]->blockd)
				{
					o->xinertia = 0;
					omg.leg_descend -= o->yinertia;
					if (++omg.timer >= 3)
					{
						o->yinertia = 0;
						o->state = OMG_JAWS_OPEN;
					}
				}
				
				// --- squash player if we land on him -------------
				// if top of player is higher than bottom of our bounding box
				// but bottom of player's bounding box is not...
				if (player->blockd)
				{
					int omg_bottom = o->y + (sprites[o->sprite].solidbox.y2 << CSF);
					if (player->y <= omg_bottom)
					{
						if (player->y + (sprites[player->sprite].solidbox.y2 << CSF) >= omg_bottom)
						{
							if (hitdetect(o, player))	// easy way to verify the X's are lined up
							{	// SQUISH!
								hurtplayer(OMEGA_DAMAGE);
							}
						}
					}
				}
			}
			else
			{	// jumping up; extend legs
				omg.leg_descend = (omg.orgy - o->y) + LEGD_MIN;
				if (omg.leg_descend > LEGD_MAX) omg.leg_descend = LEGD_MAX;
				pieces[LEFTLEG]->sprite = pieces[RIGHTLEG]->sprite = SPR_OMG_LEG_INAIR;
			}
		}
		break;
		
		/// victory
		case OMG_EXPLODING:
		{
			omg.timer = 0;
			o->state++;
		}
		case OMG_EXPLODING+1:
		{
			int x, y;
			
			o->xinertia = o->yinertia = 0;
			
			x = o->CenterX() + (random(-48, 48)<<CSF);
			y = o->CenterY() + (random(-48, 24)<<CSF);
			SmokePuff(x, y);
			effect(x, y, EFFECT_BOOMFLASH);
			
			game.quaketime = 2;
			
			if ((omg.timer % 12)==0) sound(SND_ENEMY_HURT_BIG);
			
			if (++omg.timer > 100)
			{
				omg.timer = 0;
				starflash.Start(o->CenterX(), o->CenterY());
				o->state = OMG_EXPLODED;
			}
			else if (omg.timer==24)
			{
				StartScript(210);
			}
		}
		break;
		
		case OMG_EXPLODED:
		{
			game.quaketime = 40;
			
			if (++omg.timer > 50)
			{
				o->Delete();
				for(int i=0;i<NUM_PIECES;i++)
					pieces[i]->Delete();
				
				omg.defeated = true;
				return;
			}
		}
		break;
	}
	
	// implement shaking when shot
	// we do it manually instead of used the usual shared code
	// because we want all the pieces to shake at once
	if (o->hp != omg.lasthp && !omg.shaketimer)
	{
		omg.shaketimer = 3;
		// why did I write this? anyway, I'm sure it's important
		if (o->x > player->x) o->display_xoff = -1;
						 else o->display_xoff = 1;
		
		omg.lasthp = o->hp;
	}
	if (omg.shaketimer)
	{
		int xoff = -o->display_xoff;
		
		if (!--omg.shaketimer) xoff = 0;
		
		o->display_xoff = xoff;
		pieces[LEFTLEG]->display_xoff = xoff;
		pieces[RIGHTLEG]->display_xoff = xoff;
		pieces[LEFTSTRUT]->display_xoff = xoff;
		pieces[RIGHTSTRUT]->display_xoff = xoff;
	}
	
	if (o->state)
	{
		o->blockl |= pieces[LEFTLEG]->blockl;
		o->blockr |= pieces[RIGHTLEG]->blockr;
		
		pieces[LEFTLEG]->x = o->x - (4 << CSF); pieces[LEFTLEG]->y = o->y + omg.leg_descend;
		pieces[RIGHTLEG]->x = o->x + (38 << CSF); pieces[RIGHTLEG]->y = o->y + omg.leg_descend;
		pieces[LEFTSTRUT]->x = o->x + (9 << CSF); pieces[LEFTSTRUT]->y = o->y + (27 << CSF);
		pieces[RIGHTSTRUT]->x = o->x + (43 << CSF); pieces[RIGHTSTRUT]->y = o->y + (27 << CSF);
	}
}
TInt CTestOOMVoiceCall::Start()
	{
	StartScript(iScript);
	return KErrNone;
	}