Exemplo n.º 1
0
bool AdEntity::setSprite(const char *filename) {
	if (_currentSprite == _sprite) {
		_currentSprite = nullptr;
	}

	delete _sprite;
	_sprite = nullptr;
	BaseSprite *spr = new BaseSprite(_gameRef, this);
	if (!spr || DID_FAIL(spr->loadFile(filename))) {
		delete _sprite;
		_sprite = nullptr;
		return STATUS_FAILED;
	} else {
		_sprite = spr;
		_currentSprite = _sprite;
		return STATUS_OK;
	}
}
Exemplo n.º 2
0
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool AdTalkHolder::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
	//////////////////////////////////////////////////////////////////////////
	// SetSprite
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(name, "SetSprite") == 0) {
		stack->correctParams(1);

		ScValue *val = stack->pop();

		bool setCurrent = false;
		if (_currentSprite && _currentSprite == _sprite) {
			setCurrent = true;
		}

		delete _sprite;
		_sprite = nullptr;

		if (val->isNULL()) {
			_sprite = nullptr;
			if (setCurrent) {
				_currentSprite = nullptr;
			}
			stack->pushBool(true);
		} else {
			const char *filename = val->getString();
			BaseSprite *spr = new BaseSprite(_gameRef, this);
			if (!spr || DID_FAIL(spr->loadFile(filename))) {
				script->runtimeError("SetSprite method failed for file '%s'", filename);
				stack->pushBool(false);
			} else {
				_sprite = spr;
				if (setCurrent) {
					_currentSprite = _sprite;
				}
				stack->pushBool(true);
			}
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetSprite
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetSprite") == 0) {
		stack->correctParams(0);

		if (!_sprite || !_sprite->getFilename()) {
			stack->pushNULL();
		} else {
			stack->pushString(_sprite->getFilename());
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetSpriteObject
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetSpriteObject") == 0) {
		stack->correctParams(0);

		if (!_sprite) {
			stack->pushNULL();
		} else {
			stack->pushNative(_sprite, true);
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// AddTalkSprite
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "AddTalkSprite") == 0) {
		stack->correctParams(2);

		const char *filename = stack->pop()->getString();
		bool ex = stack->pop()->getBool();

		BaseSprite *spr = new BaseSprite(_gameRef, this);
		if (!spr || DID_FAIL(spr->loadFile(filename))) {
			stack->pushBool(false);
			script->runtimeError("AddTalkSprite method failed for file '%s'", filename);
		} else {
			if (ex) {
				_talkSpritesEx.add(spr);
			} else {
				_talkSprites.add(spr);
			}
			stack->pushBool(true);
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// RemoveTalkSprite
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "RemoveTalkSprite") == 0) {
		stack->correctParams(2);

		const char *filename = stack->pop()->getString();
		bool ex = stack->pop()->getBool();

		bool setCurrent = false;
		bool setTemp2 = false;

		if (ex) {
			for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
				if (scumm_stricmp(_talkSpritesEx[i]->getFilename(), filename) == 0) {
					if (_currentSprite == _talkSpritesEx[i]) {
						setCurrent = true;
					}
					if (_tempSprite2 == _talkSpritesEx[i]) {
						setTemp2 = true;
					}
					delete _talkSpritesEx[i];
					_talkSpritesEx.remove_at(i);
					break;
				}
			}
		} else {
			for (uint32 i = 0; i < _talkSprites.size(); i++) {
				if (scumm_stricmp(_talkSprites[i]->getFilename(), filename) == 0) {
					if (_currentSprite == _talkSprites[i]) {
						setCurrent = true;
					}
					if (_tempSprite2 == _talkSprites[i]) {
						setTemp2 = true;
					}
					delete _talkSprites[i];
					_talkSprites.remove_at(i);
					break;
				}
			}

		}

		stack->pushBool(true);
		if (setCurrent) {
			_currentSprite = _sprite;
		}
		if (setTemp2) {
			_tempSprite2 = _sprite;
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetTalkSprite
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "SetTalkSprite") == 0) {
		stack->correctParams(2);

		const char *filename = stack->pop()->getString();
		bool ex = stack->pop()->getBool();
		bool setCurrent = false;
		bool setTemp2 = false;

		BaseSprite *spr = new BaseSprite(_gameRef, this);
		if (!spr || DID_FAIL(spr->loadFile(filename))) {
			stack->pushBool(false);
			script->runtimeError("SetTalkSprite method failed for file '%s'", filename);
		} else {

			// delete current
			if (ex) {
				for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
					if (_talkSpritesEx[i] == _currentSprite) {
						setCurrent = true;
					}
					if (_talkSpritesEx[i] == _tempSprite2) {
						setTemp2 = true;
					}
					delete _talkSpritesEx[i];
				}
				_talkSpritesEx.clear();
			} else {
				for (uint32 i = 0; i < _talkSprites.size(); i++) {
					if (_talkSprites[i] == _currentSprite) {
						setCurrent = true;
					}
					if (_talkSprites[i] == _tempSprite2) {
						setTemp2 = true;
					}
					delete _talkSprites[i];
				}
				_talkSprites.clear();
			}

			// set new
			if (ex) {
				_talkSpritesEx.add(spr);
			} else {
				_talkSprites.add(spr);
			}
			stack->pushBool(true);

			if (setCurrent) {
				_currentSprite = spr;
			}
			if (setTemp2) {
				_tempSprite2 = spr;
			}
		}
		return STATUS_OK;
	} else {
		return AdObject::scCallMethod(script, stack, thisStack, name);
	}
}
Exemplo n.º 3
0
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdEntity::loadBuffer(byte *buffer, bool complete) {
	TOKEN_TABLE_START(commands)
	TOKEN_TABLE(ENTITY)
	TOKEN_TABLE(SPRITE)
	TOKEN_TABLE(X)
	TOKEN_TABLE(Y)
	TOKEN_TABLE(TEMPLATE)
	TOKEN_TABLE(NAME)
	TOKEN_TABLE(SCALABLE)
	TOKEN_TABLE(REGISTRABLE)
	TOKEN_TABLE(INTERACTIVE)
	TOKEN_TABLE(SHADOWABLE)
	TOKEN_TABLE(COLORABLE)
	TOKEN_TABLE(ACTIVE)
	TOKEN_TABLE(EVENTS)
	TOKEN_TABLE(FONT)
	TOKEN_TABLE(TALK_SPECIAL)
	TOKEN_TABLE(TALK)
	TOKEN_TABLE(CURSOR)
	TOKEN_TABLE(REGION)
	TOKEN_TABLE(BLOCKED_REGION)
	TOKEN_TABLE(EDITOR_SELECTED)
	TOKEN_TABLE(SCRIPT)
	TOKEN_TABLE(SOUND_START_TIME)
	TOKEN_TABLE(SOUND_VOLUME)
	TOKEN_TABLE(SOUND_PANNING)
	TOKEN_TABLE(SOUND)
	TOKEN_TABLE(SUBTYPE)
	TOKEN_TABLE(CAPTION)
	TOKEN_TABLE(PROPERTY)
	TOKEN_TABLE(WAYPOINTS)
	TOKEN_TABLE(IGNORE_ITEMS)
	TOKEN_TABLE(ROTABLE)
	TOKEN_TABLE(ROTATABLE)
	TOKEN_TABLE(ALPHA_COLOR)
	TOKEN_TABLE(SCALE)
	TOKEN_TABLE(RELATIVE_SCALE)
	TOKEN_TABLE(ALPHA)
	TOKEN_TABLE(EDITOR_PROPERTY)
	TOKEN_TABLE(ITEM)
	TOKEN_TABLE(WALK_TO_X)
	TOKEN_TABLE(WALK_TO_Y)
	TOKEN_TABLE(WALK_TO_DIR)
	TOKEN_TABLE(SAVE_STATE)
	TOKEN_TABLE_END

	byte *params;
	int cmd;
	BaseParser parser;

	if (complete) {
		if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ENTITY) {
			_gameRef->LOG(0, "'ENTITY' keyword expected.");
			return STATUS_FAILED;
		}
		buffer = params;
	}

	AdGame *adGame = (AdGame *)_gameRef;
	BaseSprite *spr = nullptr;
	int ar = 0, ag = 0, ab = 0, alpha = 0;
	while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
		switch (cmd) {
		case TOKEN_TEMPLATE:
			if (DID_FAIL(loadFile((char *)params))) {
				cmd = PARSERR_GENERIC;
			}
			break;

		case TOKEN_X:
			parser.scanStr((char *)params, "%d", &_posX);
			break;

		case TOKEN_Y:
			parser.scanStr((char *)params, "%d", &_posY);
			break;

		case TOKEN_SPRITE: {
			delete _sprite;
			_sprite = nullptr;
			spr = new BaseSprite(_gameRef, this);
			if (!spr || DID_FAIL(spr->loadFile((char *)params))) {
				cmd = PARSERR_GENERIC;
			} else {
				_sprite = spr;
			}
		}
		break;

		case TOKEN_TALK: {
			spr = new BaseSprite(_gameRef, this);
			if (!spr || DID_FAIL(spr->loadFile((char *)params, adGame->_texTalkLifeTime))) {
				cmd = PARSERR_GENERIC;
			} else {
				_talkSprites.add(spr);
			}
		}
		break;

		case TOKEN_TALK_SPECIAL: {
			spr = new BaseSprite(_gameRef, this);
			if (!spr || DID_FAIL(spr->loadFile((char *)params, adGame->_texTalkLifeTime))) {
				cmd = PARSERR_GENERIC;
			} else {
				_talkSpritesEx.add(spr);
			}
		}
		break;

		case TOKEN_NAME:
			setName((char *)params);
			break;

		case TOKEN_ITEM:
			setItem((char *)params);
			break;

		case TOKEN_CAPTION:
			setCaption((char *)params);
			break;

		case TOKEN_FONT:
			setFont((char *)params);
			break;

		case TOKEN_SCALABLE:
			parser.scanStr((char *)params, "%b", &_zoomable);
			break;

		case TOKEN_SCALE: {
			int s;
			parser.scanStr((char *)params, "%d", &s);
			_scale = (float)s;

		}
		break;

		case TOKEN_RELATIVE_SCALE: {
			int s;
			parser.scanStr((char *)params, "%d", &s);
			_relativeScale = (float)s;

		}
		break;

		case TOKEN_ROTABLE:
		case TOKEN_ROTATABLE:
			parser.scanStr((char *)params, "%b", &_rotatable);
			break;

		case TOKEN_REGISTRABLE:
		case TOKEN_INTERACTIVE:
			parser.scanStr((char *)params, "%b", &_registrable);
			break;

		case TOKEN_SHADOWABLE:
		case TOKEN_COLORABLE:
			parser.scanStr((char *)params, "%b", &_shadowable);
			break;

		case TOKEN_ACTIVE:
			parser.scanStr((char *)params, "%b", &_active);
			break;

		case TOKEN_CURSOR:
			delete _cursor;
			_cursor = new BaseSprite(_gameRef);
			if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
				delete _cursor;
				_cursor = nullptr;
				cmd = PARSERR_GENERIC;
			}
			break;

		case TOKEN_EDITOR_SELECTED:
			parser.scanStr((char *)params, "%b", &_editorSelected);
			break;

		case TOKEN_REGION: {
			if (_region) {
				_gameRef->unregisterObject(_region);
			}
			_region = nullptr;
			BaseRegion *rgn = new BaseRegion(_gameRef);
			if (!rgn || DID_FAIL(rgn->loadBuffer(params, false))) {
				cmd = PARSERR_GENERIC;
			} else {
				_region = rgn;
				_gameRef->registerObject(_region);
			}
		}
		break;

		case TOKEN_BLOCKED_REGION: {
			delete _blockRegion;
			_blockRegion = nullptr;
			delete _currentBlockRegion;
			_currentBlockRegion = nullptr;
			BaseRegion *rgn = new BaseRegion(_gameRef);
			BaseRegion *crgn = new BaseRegion(_gameRef);
			if (!rgn || !crgn || DID_FAIL(rgn->loadBuffer(params, false))) {
				delete _blockRegion;
				_blockRegion = nullptr;
				delete _currentBlockRegion;
				_currentBlockRegion = nullptr;
				cmd = PARSERR_GENERIC;
			} else {
				_blockRegion = rgn;
				_currentBlockRegion = crgn;
				_currentBlockRegion->mimic(_blockRegion);
			}
		}
		break;

		case TOKEN_WAYPOINTS: {
			delete _wptGroup;
			_wptGroup = nullptr;
			delete _currentWptGroup;
			_currentWptGroup = nullptr;
			AdWaypointGroup *wpt = new AdWaypointGroup(_gameRef);
			AdWaypointGroup *cwpt = new AdWaypointGroup(_gameRef);
			if (!wpt || !cwpt || DID_FAIL(wpt->loadBuffer(params, false))) {
				delete _wptGroup;
				_wptGroup = nullptr;
				delete _currentWptGroup;
				_currentWptGroup = nullptr;
				cmd = PARSERR_GENERIC;
			} else {
				_wptGroup = wpt;
				_currentWptGroup = cwpt;
				_currentWptGroup->mimic(_wptGroup);
			}
		}
		break;

		case TOKEN_SCRIPT:
			addScript((char *)params);
			break;

		case TOKEN_SUBTYPE: {
			if (scumm_stricmp((char *)params, "sound") == 0) {
				delete _sprite;
				_sprite = nullptr;
				if (_gameRef->_editorMode) {
					spr = new BaseSprite(_gameRef, this);
					if (!spr || DID_FAIL(spr->loadFile("entity_sound.sprite"))) {
						cmd = PARSERR_GENERIC;
					} else {
						_sprite = spr;
					}
				}
				if (_gameRef->_editorMode) {
					_editorOnly = true;
				}
				_zoomable = false;
				_rotatable = false;
				_registrable = _gameRef->_editorMode;
				_shadowable = false;
				_subtype = ENTITY_SOUND;
			}
		}
		break;

		case TOKEN_SOUND:
			playSFX((char *)params, false, false);
			break;

		case TOKEN_SOUND_START_TIME:
			parser.scanStr((char *)params, "%d", &_sFXStart);
			break;

		case TOKEN_SOUND_VOLUME:
			parser.scanStr((char *)params, "%d", &_sFXVolume);
			break;

		case TOKEN_SOUND_PANNING:
			parser.scanStr((char *)params, "%b", &_autoSoundPanning);
			break;

		case TOKEN_SAVE_STATE:
			parser.scanStr((char *)params, "%b", &_saveState);
			break;

		case TOKEN_PROPERTY:
			parseProperty(params, false);
			break;

		case TOKEN_IGNORE_ITEMS:
			parser.scanStr((char *)params, "%b", &_ignoreItems);
			break;

		case TOKEN_ALPHA_COLOR:
			parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
			break;

		case TOKEN_ALPHA:
			parser.scanStr((char *)params, "%d", &alpha);
			break;

		case TOKEN_EDITOR_PROPERTY:
			parseEditorProperty(params, false);
			break;

		case TOKEN_WALK_TO_X:
			parser.scanStr((char *)params, "%d", &_walkToX);
			break;

		case TOKEN_WALK_TO_Y:
			parser.scanStr((char *)params, "%d", &_walkToY);
			break;

		case TOKEN_WALK_TO_DIR: {
			int i;
			parser.scanStr((char *)params, "%d", &i);
			if (i < 0) {
				i = 0;
			}
			if (i >= NUM_DIRECTIONS) {
				i = DI_NONE;
			}
			_walkToDir = (TDirection)i;
		}
		break;
		}
	}
	if (cmd == PARSERR_TOKENNOTFOUND) {
		_gameRef->LOG(0, "Syntax error in ENTITY definition");
		return STATUS_FAILED;
	}
	if (cmd == PARSERR_GENERIC) {
		_gameRef->LOG(0, "Error loading ENTITY definition");
		if (spr) {
			delete spr;
		}
		return STATUS_FAILED;
	}

	if (_region && _sprite) {
		_gameRef->LOG(0, "Warning: Entity '%s' has both sprite and region.", getName());
	}

	updatePosition();

	if (alpha != 0 && ar == 0 && ag == 0 && ab == 0) {
		ar = ag = ab = 255;
	}
	_alphaColor = BYTETORGBA(ar, ag, ab, alpha);
	_state = STATE_READY;

	if (_item && ((AdGame *)_gameRef)->isItemTaken(_item)) {
		_active = false;
	}

	return STATUS_OK;
}