Beispiel #1
0
void EMICostume::playChoreLooping(int num, uint msecs) {
	// FIXME: Original EMI can play multiple instances of a chore at the same time.
	EMIChore *chore = static_cast<EMIChore *>(_chores[num]);
	if (chore->isWearChore()) {
		setWearChore(chore);
	}
	Costume::playChoreLooping(num, msecs);
}
Beispiel #2
0
void EMICostume::saveState(SaveGame *state) const {
	Costume::saveState(state);

	for (int i = 0; i < _numChores; ++i) {
		EMIChore *chore = (EMIChore *)_chores[i];
		state->writeLESint32(chore->getId());
	}

	state->writeLESint32(_wearChore ? _wearChore->getChoreId() : -1);
}
Beispiel #3
0
EMIModel *EMICostume::getEMIModel(int num) const {
	if (num >= _numChores) {
		return nullptr;
	}
	EMIChore *chore = static_cast<EMIChore *>(_chores[num]);
	if (chore == nullptr) {
		return nullptr;
	}
	EMIMeshComponent *mesh = chore->getMesh();
	if (mesh == nullptr) {
		return nullptr;
	}
	return mesh->_obj;
}
Beispiel #4
0
bool EMICostume::restoreState(SaveGame *state) {
	bool ret = Costume::restoreState(state);
	if (ret) {
		if (state->saveMinorVersion() >= 11) {
			EMIChore::Pool &pool = EMIChore::getPool();
			for (int i = 0; i < _numChores; ++i) {
				EMIChore *chore = (EMIChore *)_chores[i];
				int id = state->readLESint32();
				pool.removeObject(chore->getId());
				EMIChore* oldChore = pool.getObject(id);
				if (oldChore) {
					pool.removeObject(id);
					oldChore->setId(chore->getId());
					pool.addObject(oldChore);
				}
				chore->setId(id);
				pool.addObject(chore);
			}
		}

		if (state->saveMinorVersion() < 13) {
			// Used to be active texture IDs for materials. Materials are now
			// managed by the owner Actor of this Costume.
			for (uint i = 0; i < _materials.size(); ++i) {
				state->readLESint32();
			}
		}

		int id = state->readLESint32();
		if (id >= 0) {
			EMIChore *chore = static_cast<EMIChore *>(_chores[id]);
			setWearChore(chore);
		}
	}
	return ret;
}
Beispiel #5
0
void EMICostume::load(Common::SeekableReadStream *data) {
	Common::Array<Component *> components;

	_numChores = data->readUint32LE();
	_chores = new Chore *[_numChores];
	for (int i = 0; i < _numChores; i++) {
		uint32 nameLength;
		Component *prevComponent = nullptr;
		nameLength = data->readUint32LE();
		assert(nameLength < 32);

		char name[32];
		data->read(name, nameLength);
		char f[4];
		data->read(f, 4);
		float length = get_float(f);
		int numTracks = data->readUint32LE();

		if (length == 1000)
			length = -1.0f;
		else
			length *= 1000;

		EMIChore *chore = new EMIChore(name, i, this, (int)length, numTracks);
		_chores[i] = chore;

		for (int k = 0; k < numTracks; k++) {
			int componentNameLength = data->readUint32LE();

			char *componentName = new char[componentNameLength];
			data->read(componentName, componentNameLength);

			data->readUint32LE();
			int parentID = data->readUint32LE();
			if (parentID == -1 && _prevCostume) {
				// However, only the first item can actually share the
				// node hierarchy with the previous costume, so flag
				// that component so it knows what to do
				if (i == 0)
					parentID = -2;
				prevComponent = _prevCostume->getComponent(0);
				// Make sure that the component is valid
				if (!prevComponent->isComponentType('M', 'M', 'D', 'L'))
					prevComponent = nullptr;
			}
			// Actually load the appropriate component
			Component *component = loadEMIComponent(parentID < 0 ? nullptr : components[parentID], parentID, componentName, prevComponent);
			if (component) {
				component->setCostume(this);
				component->init();
				chore->addComponent(component);
			}

			components.push_back(component);

			ChoreTrack &track = chore->_tracks[k];
			track.numKeys = data->readUint32LE();
			track.keys = new TrackKey[track.numKeys];
			track.component = component;
			track.compID = -1; // -1 means "look at .component"

			for (int j = 0; j < track.numKeys; j++) {
				float time, value;
				char v[8];
				data->read(v, 8);
				time = get_float(v);
				value = get_float(v + 4);
				track.keys[j].time = (int)(time * 1000);
				length = MAX(length, time * 1000);
				track.keys[j].value = (int)value;
			}
			delete[] componentName;
		}
	}

	_numComponents = components.size();
	_components = new Component *[_numComponents];
	for (int i = 0; i < _numComponents; ++i) {
		_components[i] = components[i];
	}

	// The wearChore is active by default
	_isWearChoreActive = true;

	_head = new EMIHead(this);
}
// TODO: Implement, verify, and rename unknown 5th parameter
void Lua_V2::PlayActorChore() {
	lua_Object actorObj = lua_getparam(1);
	lua_Object choreObj = lua_getparam(2);
	lua_Object costumeObj = lua_getparam(3);
	lua_Object modeObj = lua_getparam(4);
	/* lua_Object paramObj = */ lua_getparam(5);

	if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
		return;

	Actor *actor = getactor(actorObj);

	if (!lua_isstring(choreObj) || !lua_isstring(costumeObj))
		lua_pushnil();

	bool mode = false;
	// float param = 0.0;

	if (!lua_isnil(modeObj)) {
		if (lua_getnumber(modeObj) != 0.0)
			mode = true;
		//if (!lua_isnil(paramObj))
		//	if (lua_isnumber(paramObj))
		//		param = lua_getnumber(paramObj);
	}

	const char *choreName = lua_getstring(choreObj);

	const char *costumeName = lua_getstring(costumeObj);
	Costume *costume;
	// If a new wear chore is set and it uses a different costume than the
	// current one and neither of them is the shadow costume stop all active
	// chores and remove the old costume before setting the new one.
	//
	// This is necessary, because always the last costume on the stack, even
	// if it is not active, is returned by getCurrentCostume(). This would
	// cause an issue if the costumes would have different joints and the lua
	// code would consider a different costume active than the C code.
	if (0 == strncmp("wear_", choreName, 5)) {
		if (0 != strncmp("fx/dumbshadow.cos", costumeName, 17)) {
			if (actor->getCurrentCostume() != NULL &&
			    actor->getCurrentCostume()->getFilename() != "fx/dumbshadow.cos" &&
			    actor->getCurrentCostume()->getFilename().compareToIgnoreCase(costumeName) != 0) {
				actor->stopAllChores();
				actor->setRestChore(-1, NULL);
				actor->setWalkChore(-1, NULL);
				actor->setTurnChores(-1, -1, NULL);
				actor->setMumbleChore(-1, NULL);
				actor->popCostume();
			}
		}
	}
	if (!findCostume(costumeObj, actor, &costume))
		return;

	EMIChore *chore = (EMIChore *)costume->getChore(choreName);
	if (0 == strncmp("wear_", choreName, 5)) {
		actor->setLastWearChore(costume->getChoreId(choreName), costume);
	}

	if (mode) {
		costume->playChoreLooping(choreName);
	} else {
		costume->playChore(choreName);
	}
	if (chore) {
		lua_pushusertag(chore->getId(), MKTAG('C','H','O','R'));
	} else {
		lua_pushnil();
	}

}