Esempio n. 1
0
void Script::moveCharacterToPlayer(uint16 characterId, uint16 v2, uint16 v3) {
	Resources &res = Resources::getReference();
	Hotspot *playerHotspot = res.getActiveHotspot(PLAYER_ID);
	Hotspot *charHotspot = res.getActiveHotspot(characterId);
	assert(charHotspot);

	// If character in same room as player, then no need to do anything
	if (!charHotspot->currentActions().isEmpty() &&
		(charHotspot->currentActions().top().roomNumber() == playerHotspot->roomNumber()))
		return;

	uint16 destRoom = playerHotspot->roomNumber();
	const RoomTranslationRecord *rec;
	for (rec = &roomTranslations[0]; rec->srcRoom != 0; ++rec) {
		if (rec->srcRoom == destRoom) {
			destRoom = rec->destRoom;
			break;
		}
	}

	if (charHotspot->currentActions().isEmpty())
		charHotspot->currentActions().addFront(DISPATCH_ACTION,  destRoom);
	else
		charHotspot->currentActions().top().setRoomNumber(destRoom);
}
Esempio n. 2
0
void Script::makeGoewinFollow(uint16 v1, uint16 v2, uint16 v3) {
	Resources &res = Resources::getReference();
	Hotspot *hotspot = res.getActiveHotspot(GOEWIN_ID);
	hotspot->setTickProc(FOLLOWER_TICK_PROC_2);
	hotspot->currentActions().clear();
	CharacterScheduleEntry *entry = res.charSchedules().getEntry(GOEWIN_CAVE_SUPPORT_ID);
	hotspot->currentActions().addFront(DISPATCH_ACTION, entry, ROOMNUM_CAVE);

	hotspot->setActions(hotspot->resource()->actions | (1 << (TELL - 1)));
	hotspot->setActionCtr(0);
	hotspot->setDelayCtr(0);
	hotspot->setCharacterMode(CHARMODE_NONE);
}
Esempio n. 3
0
void Script::ratpouchPushBricks(uint16 v1, uint16 v2, uint16 v3) {
	Resources &res = Resources::getReference();

	// Mark the bricks exit as now open
	RoomExitJoinData *joinRec = res.getExitJoin(BRICKS_ID);
	joinRec->blocked = 0;

	// Set Ratpouch moving through the new exit to room #7
	Hotspot *ratpouchHotspot = res.getActiveHotspot(RATPOUCH_ID);
	ratpouchHotspot->setActions(0); // Make sure he can't be interrupted
	ratpouchHotspot->currentActions().clear();
	ratpouchHotspot->currentActions().addBack(DISPATCH_ACTION, 7);
}
Esempio n. 4
0
void Script::normalGoewin(uint16 v1, uint16 v2, uint16 v3) {
	Resources &res = Resources::getReference();
	Hotspot *hotspot = res.getActiveHotspot(GOEWIN_ID);
	assert(hotspot);

	if (!hotspot->currentActions().isEmpty())
		hotspot->currentActions().top().setAction(DISPATCH_ACTION);
	hotspot->setCharacterMode(CHARMODE_NONE);
	hotspot->setDirection(UP);
	hotspot->setTickProc(STANDARD_CHARACTER_TICK_PROC);

	// Clear walk to position for Goewin so player must walk up to her when interacting
	hotspot->resource()->walkX = 0;
	hotspot->resource()->walkY = 0;
}
Esempio n. 5
0
void Script::fixGoewin(uint16 v1, uint16 v2, uint16 v3) {
	Resources &res = Resources::getReference();
	Hotspot *hotspot = res.getActiveHotspot(GOEWIN_ID);
	assert(hotspot);
	hotspot->setTickProc(STANDARD_CHARACTER_TICK_PROC);

	CharacterScheduleEntry *entry = res.charSchedules().getEntry(GOEWIN_STANDARD_SUPPORT_ID);
	assert(entry);
	hotspot->currentActions().clear();
	hotspot->currentActions().addFront(DISPATCH_ACTION, entry, hotspot->roomNumber());

	hotspot->setActions(hotspot->resource()->actions & ~(1 << (TELL - 1)));
	hotspot->setActionCtr(0);
	hotspot->setDelayCtr(0);
	hotspot->setCharacterMode(CHARMODE_NONE);
}
Esempio n. 6
0
void Script::setSupportData(uint16 hotspotId, uint16 index, uint16 v3) {
	Resources &res = Resources::getReference();

	// WORKAROUND: In room #45, the script for the Skorl noticing you gets
	// the parameters back to front. If this the case, just ignore it
	if (index == CASTLE_SKORL_ID) return;

	uint16 dataId = res.getCharOffset(index);
	CharacterScheduleEntry *entry = res.charSchedules().getEntry(dataId);
	assert(entry != NULL);

	Hotspot *h = res.getActiveHotspot(hotspotId);
	assert(h);
	assert(!h->currentActions().isEmpty());
	h->currentActions().pop();
	h->currentActions().addFront(DISPATCH_ACTION, entry, h->roomNumber());
}
Esempio n. 7
0
void Script::setNewSupportData(uint16 index, uint16 hotspotId, uint16 v3) {
	Resources &res = Resources::getReference();
	uint16 dataId = res.getCharOffset(index);
	CharacterScheduleEntry *entry = res.charSchedules().getEntry(dataId);

	Hotspot *h = res.getActiveHotspot(hotspotId);
	h->setBlockedFlag(false);
	h->currentActions().addFront(DISPATCH_ACTION, entry, h->roomNumber());
	h->setActionCtr(0);
}
Esempio n. 8
0
void Script::setBlockingHotspotScript(uint16 charId, uint16 scriptIndex, uint16 v3) {
	Resources &r = Resources::getReference();
	uint16 offset = r.getHotspotScript(scriptIndex);

	if (charId == PLAYER_ID)
		Room::getReference().setCursorState(CS_SEQUENCE);

	Hotspot *hs = r.getActiveHotspot(charId);
	hs->setHotspotScript(offset);
	hs->currentActions().top().setAction(EXEC_HOTSPOT_SCRIPT);
	hs->setOccupied(true);
}
Esempio n. 9
0
void Script::makeGoewinWork(uint16 v1, uint16 v2, uint16 v3) {
	Resources &res = Resources::getReference();
	Hotspot *goewin = res.getActiveHotspot(GOEWIN_ID);
	assert(goewin);
	goewin->updateMovement();
	goewin->currentActions().addBack(EXEC_HOTSPOT_SCRIPT, 34);
	goewin->setHotspotScript(0x616);
	goewin->setDelayCtr(1500);
	goewin->setTickProc(GOEWIN_SHOP_TICK_PROC);

	// Set walk to position for Goewin whilst she's working
	goewin->resource()->walkX = 179;
	goewin->resource()->walkY = 138;
}
Esempio n. 10
0
Hotspot *Resources::activateHotspot(uint16 hotspotId) {
	Resources &resources = Resources::getReference();
	HotspotData *res = getHotspot(hotspotId);
	if (!res) return NULL;
	res->roomNumber &= 0x7fff; // clear any suppression bit in room #

	// Make sure that the hotspot isn't already active
	Hotspot *h = getActiveHotspot(hotspotId);
	if (h != NULL)
		return h;

	// If it's NPC with a schedule, then activate the schedule
	if ((res->npcScheduleId != 0) && (res->npcSchedule.isEmpty())) {
		CharacterScheduleEntry *entry = resources.charSchedules().getEntry(res->npcScheduleId);
		res->npcSchedule.addFront(DISPATCH_ACTION, entry, res->roomNumber);
	}

	// Check the script load flag
	if (res->scriptLoadFlag) {
		// Execute a script rather than doing a standard load
		Script::execute(res->loadOffset);
	} else {
		// Standard load
		bool loadFlag = true;
		uint16 talkIndex;

		switch (res->loadOffset) {
		case 1:
			// Copy protection check - since the game is freeware now, ignore it
			loadFlag = false;
			break;

		case 2:
			// Empty handler used to prevent loading hotspots that
			// are yet to be active (such as the straw fire)
			loadFlag = false;
			break;

		case 3:
		case 4:
			// Standard animation load
			break;

		case 5:
			// Custom loader used by the notice hotspot 42ah in room #20
			talkIndex = _fieldList.getField(TALK_INDEX);
			if ((talkIndex < 8) || (talkIndex >= 14))
				// Don't load hotspot
				loadFlag = false;
			else
				// Make the notice be on-screen
				res->startY = 85;
			break;

		case 6:
			// Torch in room #1
			loadFlag = _fieldList.getField(TORCH_HIDE) == 0;
			break;

		default:
			// All others simply activate the hotspot
			warning("Hotspot %d uses unknown load offset index %d",
				res->hotspotId, res->loadOffset);
		}

		if (loadFlag) {
			Hotspot *hotspot = addHotspot(hotspotId);
			assert(hotspot);

			// Special post-load handling
			if (res->loadOffset == 3) hotspot->setPersistant(true);
			if (res->loadOffset == 5) hotspot->handleTalkDialog();
			if (hotspotId == CASTLE_SKORL_ID) {
				// The Castle skorl has a default room #99, so it needs to be adjusted dynamically
				res->npcSchedule.clear();
				CharacterScheduleEntry *entry = resources.charSchedules().getEntry(res->npcScheduleId);
				res->npcSchedule.addFront(DISPATCH_ACTION, entry, res->roomNumber);
			}
			if ((hotspotId == GOEWIN_ID) && (hotspot->roomNumber() == 39)) {
				// WORKAROUND: When you re-join Goewin in the caves, clear her schedule. This may prevent a
				// situation where you could close the left door, and she'd be permanently stuck trying to go
				// the next room on the left, since her old schedule still had her following your old path
				hotspot->currentActions().clear();

				// Since she's no longer a follower, clear her start room field
				hotspot->setStartRoomNumber(0);
			}

			// TODO: Figure out why there's a room set in the animation decode for a range of characters,
			// particularly since it doesn't seem to match what happens in-game
			/*
			if ((hotspot->hotspotId() >= RATPOUCH_ID) &&
				(hotspot->hotspotId() < FIRST_NONCHARACTER_ID) &&
				(hotspot->roomNumber() < 42)) {
				// Start wandering characters off in room 24
				hotspot->setRoomNumber(24);
				hotspot->setPosition(64, 116);
				_fieldList.wanderingCharsLoaded() = true;
			}
			*/

			return hotspot;
		}
	}

	return NULL;
}