/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "engines/stark/services/gameinterface.h" #include "engines/stark/movement/walk.h" #include "engines/stark/resources/knowledgeset.h" #include "engines/stark/resources/level.h" #include "engines/stark/resources/location.h" #include "engines/stark/resources/speech.h" #include "engines/stark/resources/floor.h" #include "engines/stark/resources/floorface.h" #include "engines/stark/resources/script.h" #include "engines/stark/resources/item.h" #include "engines/stark/services/global.h" #include "engines/stark/services/services.h" #include "engines/stark/visual/image.h" #include "engines/stark/scene.h" #include "engines/stark/services/userinterface.h" namespace Stark { GameInterface::GameInterface() { } GameInterface::~GameInterface() { } bool GameInterface::skipCurrentSpeeches() { Current *current = StarkGlobal->getCurrent(); if (!current) { return false; // No current location, nothing to do } // Get all speeches Common::Array speeches; speeches.push_back(StarkGlobal->getLevel()->listChildrenRecursive()); speeches.push_back(current->getLevel()->listChildrenRecursive()); speeches.push_back(current->getLocation()->listChildrenRecursive()); // Stop them bool skippedSpeeches = false; for (uint i = 0; i < speeches.size(); i++) { Resources::Speech *speech = speeches[i]; if (speech->isPlaying()) { speech->stop(); skippedSpeeches = true; } } return skippedSpeeches; } void GameInterface::walkTo(const Common::Point &mouse) { Resources::Floor *floor = StarkGlobal->getCurrent()->getFloor(); Resources::ModelItem *april = StarkGlobal->getCurrent()->getInteractive(); if (!floor || !april) { return; } Math::Ray mouseRay = StarkScene->makeRayFromMouse(mouse); // First look for a direct intersection with the floor Math::Vector3d destinationPosition; int32 destinationFloorFaceIndex = floor->findFaceHitByRay(mouseRay, destinationPosition); // Otherwise fall back to the floor face center closest to the ray if (destinationFloorFaceIndex < 0) { destinationFloorFaceIndex = floor->findFaceClosestToRay(mouseRay, destinationPosition); } if (destinationFloorFaceIndex < 0) { // No destination was found return; } Walk *walk = new Walk(april); walk->setDestination(destinationPosition); walk->start(); april->setMovement(walk); } VisualImageXMG *GameInterface::getActionImage(uint32 itemIndex, bool active) { // Lookup the action's item in the inventory Resources::KnowledgeSet *inventory = StarkGlobal->getLevel()->findChildWithSubtype(Resources::KnowledgeSet::kInventory, true); // Get the visual for the action Resources::InventoryItem *action = inventory->findChildWithIndex(itemIndex); Visual *visual = action->getActionVisual(active); return visual->get(); } VisualImageXMG *GameInterface::getCursorImage(uint32 itemIndex) { // Lookup the item's item in the inventory Resources::KnowledgeSet *inventory = StarkGlobal->getLevel()->findChildWithSubtype(Resources::KnowledgeSet::kInventory, true); // Get the visual for the item Resources::InventoryItem *item = inventory->findChildWithIndex(itemIndex); Visual *visual = item->getCursorVisual(); return visual->get(); } bool GameInterface::itemHasAction(Resources::ItemVisual *item, int32 action) { if (action != -1) { return item->canPerformAction(action, 0); } else { Resources::ActionArray actions = listActionsPossibleForObject(item); return !actions.empty(); } } bool GameInterface::itemHasActionAt(Resources::ItemVisual *item, const Common::Point &position, int32 action) { int32 hotspotIndex = item->getHotspotIndexForPoint(position); if (action != -1) { return item->canPerformAction(action, hotspotIndex); } else { Resources::ActionArray actions = listActionsPossibleForObjectAt(item, position); return !actions.empty(); } } int32 GameInterface::itemGetDefaultActionAt(Resources::ItemVisual *item, const Common::Point &position) { int32 hotspotIndex = item->getHotspotIndexForPoint(position); Resources::PATTable *table = item->findChildWithOrder(hotspotIndex); if (table) { return table->getDefaultAction(); } else { return -1; } } void GameInterface::itemDoAction(Resources::ItemVisual *item, uint32 action) { item->doAction(action, 0); } void GameInterface::itemDoActionAt(Resources::ItemVisual *item, uint32 action, const Common::Point &position) { int32 hotspotIndex = item->getHotspotIndexForPoint(position); item->doAction(action, hotspotIndex); } Common::String GameInterface::getItemTitle(Resources::ItemVisual *item) { return item->getHotspotTitle(0); } Common::String GameInterface::getItemTitleAt(Resources::ItemVisual *item, const Common::Point &pos) { int32 hotspotIndex = item->getHotspotIndexForPoint(pos); return item->getHotspotTitle(hotspotIndex); } Resources::ActionArray GameInterface::listActionsPossibleForObject(Resources::ItemVisual *item) { if (item == nullptr) { return Resources::ActionArray(); } Resources::PATTable *table = item->findChildWithOrder(0); if (table) { return table->listPossibleActions(); } else { return Resources::ActionArray(); } } Resources::ActionArray GameInterface::listActionsPossibleForObjectAt(Resources::ItemVisual *item, const Common::Point &pos) { if (item == nullptr) { return Resources::ActionArray(); } int index = item->getHotspotIndexForPoint(pos); if (index < 0) { return Resources::ActionArray(); } Resources::PATTable *table = item->findChildWithOrder(index); if (table) { return table->listPossibleActions(); } else { return Resources::ActionArray(); } } Resources::ActionArray GameInterface::listStockActionsPossibleForObject(Resources::ItemVisual *item) { Resources::ActionArray actions = listActionsPossibleForObject(item); Resources::ActionArray stockActions; for (uint i = 0; i < actions.size(); i++) { if (actions[i] < 4) { stockActions.push_back(actions[i]); } } return stockActions; } Resources::ActionArray GameInterface::listStockActionsPossibleForObjectAt(Resources::ItemVisual *item, const Common::Point &pos) { Resources::ActionArray actions = listActionsPossibleForObjectAt(item, pos); Resources::ActionArray stockActions; for (uint i = 0; i < actions.size(); i++) { if (actions[i] < 4) { stockActions.push_back(actions[i]); } } return stockActions; } bool GameInterface::isAprilWalking() const { Current *current = StarkGlobal->getCurrent(); if (!current) { return false; } Resources::ModelItem *april = current->getInteractive(); if (!april) { return false; } Movement *movement = april->getMovement(); if (!movement) { return false; } Walk *walk = dynamic_cast(movement); if (!walk) { return false; } return !walk->hasEnded(); } void GameInterface::setAprilRunning() { Current *current = StarkGlobal->getCurrent(); Resources::ModelItem *april = current->getInteractive(); Movement *movement = april->getMovement(); Walk *walk = dynamic_cast(movement); assert(walk); walk->setRunning(); } Common::Array GameInterface::listExitPositions() { return StarkGlobal->getCurrent()->getLocation()->listExitPositions(); } } // End of namespace Stark