Esempio n. 1
0
void SceneGame::pressKey(int k) {
	// delete
	if(k == GameAlphabetDEL) {
		IGLog("SceneGame touched DEL");
		inverseAnswerKey[selectedChar-'A'] = '_';
		updatePhrase();
		removeKeyboard();
	}
	// escape
	else if(k == GameAlphabetESC) {
		IGLog("SceneGame touched ESC");
		removeKeyboard();
	}
	// a letter
	else {
		char buffer[200];
		sprintf(buffer, "SceneGame touched letter %c", 'A'+k);
		IGLog(buffer);
		
		// if there's a duplicate, get rid of it
		for(int i=0; i<26; i++) {
			if(inverseAnswerKey[i] == k+'A')
				inverseAnswerKey[i] = '_';
		}
		
		inverseAnswerKey[selectedChar-'A'] = k+'A';
		updatePhrase();
		removeKeyboard();
	}
}
// method used to initialise a new phrase
void CSabrinaPhraseInstance::beginPhrase(const ISabrinaPhraseModel* thePhrase)
{
	#ifdef NL_DEBUG
		nlassert(_ThePhrase==NULL);
		nlassert(_State==Inactive);
		nlassert(_Target==NULL);
	#endif

	// setup basic data
	_ThePhrase=const_cast<ISabrinaPhraseModel*>(thePhrase);
	_NextEventTime=0;

	// setup the target
	_Target= _ThePhrase->requiresTarget()? _Actor->getTarget(): NULL;
	if (_Target!=NULL)
		_Target->addTargeter(this);

	// call the actor's init() callback
	_Actor->cbSabrinaActionBegin(this);

	// ask the model whether the phrase is valid (target's accessible, etc)
	// if the validation fails then close the phrase down and exit cleanly
	SABRINA::TEventCode validationResult=_ThePhrase->validate(this);
	if (!SABRINA::isSuccess(validationResult))
	{
		abortPhrase(validationResult);
		return;
	}

	// ask the phrase model to calculate the pre-execution delay
	uint32 ticks= _ThePhrase->calculatePreExecutionDelay(this);

	// setup the state information
	_State= PreActionDelay;
	_NextEventTime= CTickEventHandler::getGameCycle()+ticks;

	// check whether the action time is '0' - requiring immediate action
	if (ticks==0)
	{
		updatePhrase();
	}
	else
	{
		CSabrinaPhraseManager::setNextPhraseEvent(this,_NextEventTime);
	}
}
Esempio n. 3
0
void SceneGame::hint() {
	IGLog("pressed hint");
	
	unsigned int i;
	int rnd, index;
	bool found = false;
	std::vector<int> notAnswered;
	std::vector<int> incorrectAnswers;
	std::vector<int> correctAnswers;
	
	// count how many answers, and how many of them are correct
	for(i=0; i<26; i++) {
		if(inverseAnswerKey[i] != '_') {
			if(inverseAnswerKey[i] == inverseKey[i])
				correctAnswers.push_back(i);
			else
				incorrectAnswers.push_back(i);
		} else {
			notAnswered.push_back(i);
		}
	}

	// if there are no answers, supply a random one
	if(incorrectAnswers.size() + correctAnswers.size() == 0) {
		while(!found) {
			index = rand()%26;
			if(frequency[index] > 0)
				found = true;
		}
	}
	
	// if there are answers but some are wrong, fix one of the wrong answers
	else if(incorrectAnswers.size() > 0) {
		while(!found) {
			rnd = rand()%incorrectAnswers.size();
			index = incorrectAnswers[rnd];
			if(frequency[index] > 0)
				found = true;
		}
	}

	// otherwise supply a random answer that hasn't been answered
	else {
		while(!found) {
			rnd = rand()%notAnswered.size();
			index = notAnswered[rnd];
			if(frequency[index] > 0)
				found = true;
		}
	}

	// if there's a duplicate, get rid of it
	for(int i=0; i<26; i++) {
		if(inverseAnswerKey[i] == inverseKey[index])
			inverseAnswerKey[i] = '_';
	}
	
	// give the hint and update the phrase
	inverseAnswerKey[index] = inverseKey[index];
	updatePhrase();
}
Esempio n. 4
0
// game scene
SceneGame::SceneGame() {
	IGScene::IGScene();
	IGLog("SceneGame init");
	unsigned int i, j;

	// load the game
	phraseId = 0;
	savedGameDB = new SQLite3Wrapper("savedGame.db");
	loadGame();

	// init physical keyboard array
	s3eKeys[0]=s3eKeyA; s3eKeys[1]=s3eKeyB; s3eKeys[2]=s3eKeyC; s3eKeys[3]=s3eKeyD; s3eKeys[4]=s3eKeyE; 
	s3eKeys[5]=s3eKeyF; s3eKeys[6]=s3eKeyG; s3eKeys[7]=s3eKeyH; s3eKeys[8]=s3eKeyI; s3eKeys[9]=s3eKeyJ;
	s3eKeys[10]=s3eKeyK; s3eKeys[11]=s3eKeyL; s3eKeys[12]=s3eKeyM; s3eKeys[13]=s3eKeyN; s3eKeys[14]=s3eKeyO;
	s3eKeys[15]=s3eKeyP; s3eKeys[16]=s3eKeyQ; s3eKeys[17]=s3eKeyR; s3eKeys[18]=s3eKeyS; s3eKeys[19]=s3eKeyT;
	s3eKeys[20]=s3eKeyU; s3eKeys[21]=s3eKeyV; s3eKeys[22]=s3eKeyW; s3eKeys[23]=s3eKeyX; s3eKeys[24]=s3eKeyY;
	s3eKeys[25]=s3eKeyZ;

	// load resources, background image
	IGSprite* spriteBackground = NULL;
	switch(Settings::getInstance()->theme) {
		case SettingsThemeHacker:
			IwGetResManager()->LoadGroup("game_hacker.group");
			spriteBackground = new IGSprite("GameHackerBackground", IGPoint(240,160), 0);
			break;
		case SettingsThemeDetective:
			IwGetResManager()->LoadGroup("game_detective.group");
			spriteBackground = new IGSprite("GameDetectiveBackground", IGPoint(240,160), 0);
			break;
		case SettingsThemeEspionage:
			IwGetResManager()->LoadGroup("game_espionage.group");
			spriteBackground = new IGSprite("GameEspionageBackground", IGPoint(240,160), 0);
			break;
	}
	this->addChild(spriteBackground);
	
	// buttons
	GameButtonNewPuzzle* buttonNewPuzzle = new GameButtonNewPuzzle();
	GameButtonHint* buttonHint = new GameButtonHint();
	GameButtonMenu* buttonMenu = new GameButtonMenu();
	this->addChild(buttonNewPuzzle);
	this->addChild(buttonHint);
	this->addChild(buttonMenu);

	// time
	int sec = (int)(time%60);
	int min = (int)(time/60);
	GameTimeLabel* timeLabel = new GameTimeLabel(min,sec);
	this->addChild(timeLabel);
	
	// draw the phrase
	const unsigned int maxCols = 18; // used to be 21
	const unsigned int maxRows = 4;
	int columnCount[4] = {0,0,0,0}; // count number of columns per row
	unsigned int col = 0;
	unsigned int row = 0;
	for(i=0; i<strlen(ciphertext); i++) {
		// if it's a space in the first column, skip this one
		while(col == 0 && ciphertext[i] == ' ')
			i++;
		
		// if it's a word, see if there's enough space in this line
		if(ciphertext[i] != ' ') {
			for(j=i+1; j<strlen(ciphertext); j++) {
				if(ciphertext[j] == ' ' || ciphertext[j] == '\0')
					break;
			}
			if(col + (j-i) >= maxCols) {
				col = 0;
				row++;
			}
		}

		// if it's a letter, draw empty box and an empty plaintext label
		if(ciphertext[i] >= 'A' && ciphertext[i] <= 'Z') {
			GameSlot* slot = new GameSlot(row, col, SceneGameTagSlots+i);
			GamePlaintextLabel* plaintextLabel = new GamePlaintextLabel(' ', row, col, SceneGameTagPlaintextLabels+i);
			this->addChild(slot);
			this->addChild(plaintextLabel);
		}
		// otherwise draw the character
		else {
			if(ciphertext[i] != ' ') {
				GamePlaintextLabel* plaintextLabel = new GamePlaintextLabel(ciphertext[i], row, col, SceneGameTagPlaintextLabels+i);
				this->addChild(plaintextLabel);
			}
		}
		
		// draw the ciphertext
		if(ciphertext[i] != ' ') {
			GameCiphertextLabel* ciphertextLabel = new GameCiphertextLabel(ciphertext[i], row, col, SceneGameTagCiphertextLabels+i);
			this->addChild(ciphertextLabel);
		}

		// count the columns
		columnCount[row]++;
		
		// increment the column
		col++;
		if(col == maxCols) {
			col = 0;
			row++;
		}
	}
	
	// center the text, total width=468, letter width=26
	for(i=0; i<4; i++) {
		int width = columnCount[i];
		int index = -1;
		for(j=0; j<=i; j++) index += columnCount[j];
		if(ciphertext[index] == ' ') width--;
		centerOffset[i] = (468 - (width*26)) / 2;
	}
	row = 0;
	for(i=0; i<strlen(ciphertext); i++) {
		GameSlot* slot = (GameSlot*)this->getChildByTag(SceneGameTagSlots+i);
		if(slot != NULL) {
			row = slot->row;
			slot->position.x += centerOffset[row];
		}

		GamePlaintextLabel* plaintextLabel = (GamePlaintextLabel*)this->getChildByTag(SceneGameTagPlaintextLabels+i);
		if(plaintextLabel != NULL)
			plaintextLabel->position.x += centerOffset[row];

		GameCiphertextLabel* ciphertextLabel = (GameCiphertextLabel*)this->getChildByTag(SceneGameTagCiphertextLabels+i);
		if(ciphertextLabel != NULL)
			ciphertextLabel->position.x += centerOffset[row];
	}
	
	// draw the key
	IGLabel* labelAlphabet = new IGLabel("FontFixedSys14",  "alphabet: ", IGPoint(123,230), IGRect(90,20), 2, SceneGameTagLabelAlphabet);
	IGLabel* labelAnswerKey = new IGLabel("FontFixedSys14", "     key: ", IGPoint(123,250), IGRect(90,20), 2, SceneGameTagLabelAnswerKey);
	IGLabel* labelAlphabetLetter = new IGLabel("FontFixedSys14", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", IGPoint(294,230), IGRect(234,20), 2, SceneGameTagLabelAlphabetLetters);
	IGLabel* labelAnswerKeyLetter = new IGLabel("FontFixedSys14", "__________________________", IGPoint(294,250), IGRect(234,20), 2, SceneGameTagLabelAnswerKeyLetters);
	switch(Settings::getInstance()->theme) {
		case SettingsThemeHacker:
			labelAnswerKey->setColor(140,140,140,255);
			labelAlphabet->setColor(140,140,140,255);
			labelAnswerKeyLetter->setColor(210,220,210,255);
			labelAlphabetLetter->setColor(210,220,210,255);
			break;
		case SettingsThemeDetective:
		case SettingsThemeEspionage:
			labelAnswerKey->setColor(80,80,80,255);
			labelAlphabet->setColor(80,80,80,255);
			labelAnswerKeyLetter->setColor(20,20,20,255);
			labelAlphabetLetter->setColor(20,20,20,255);
			break;
			break;
	}
	this->addChild(labelAnswerKey);
	this->addChild(labelAlphabet);
	this->addChild(labelAnswerKeyLetter);
	this->addChild(labelAlphabetLetter);

	// keyboard
	keyboardUp = false;

	// update the phrase
	updatePhrase();
}
// update routine called on event triggers
// returns true if _NextEventTime == current time (otherwise false)
bool CSabrinaPhraseInstance::updatePhrase()
{
	// if the phrase' timer's been changed then this event is not valid so ignore it...
	NLMISC::TGameCycle curTime=CTickEventHandler::getGameCycle();
	if (_NextEventTime != curTime)
		return false;

	// change the value of '_NextEventTime' to avoid multiple executions of the action phrase
	// when the phrase end date is set to the same time more than once...
	--_NextEventTime;

	// depending on state do something...
	switch (_State)
	{
	case PreActionDelay:
		{
			// ask the model whether the phrase is valid (target's accessible, etc)
			// if the validation fails then close the phrase down and exit cleanly
			SABRINA::TEventCode validationResult=_ThePhrase->validate(this);
			if (!SABRINA::isSuccess(validationResult))
			{
				_Actor->cbSabrinaActionFailure(this,validationResult);
				terminate();
				break;
			}

			// ask the model to execute the phrase action and apply results to whoever necessary
			// if execution failed then exit cleanly
			SABRINA::TEventCode executionResult= _ThePhrase->executeAndApplyResults(this);
			if (SABRINA::isSuccess(executionResult))
			{
				_Actor->cbSabrinaActionSuccess(this,executionResult);
			}
			else
			{
				_Actor->cbSabrinaActionFailure(this,executionResult);
				terminate();
				break;
			}

			// ask the phrase model to calculate the post-execution delay
			uint32 ticks=_ThePhrase->calculatePostExecutionDelay(this);

			// setup the state information
			_State= PostActionDelay;
			_NextEventTime= CTickEventHandler::getGameCycle()+ticks;

			// check whether the action time is '0' - requiring immediate action
			if (ticks==0)
			{
				updatePhrase();
			}
			else
			{
				CSabrinaPhraseManager::setNextPhraseEvent(this,_NextEventTime);
			}

			break;
		}

	case PostActionDelay:
		terminate();
		break;

	case Inactive:
		break;
	}
	return true;
}