mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
289 lines
7.8 KiB
C++
289 lines
7.8 KiB
C++
/* 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.
|
|
*
|
|
* Additional copyright for this file:
|
|
* Copyright (C) 1995-1997 Presto Studios, Inc.
|
|
*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "common/stream.h"
|
|
|
|
#include "pegasus/energymonitor.h"
|
|
#include "pegasus/gamestate.h"
|
|
#include "pegasus/pegasus.h"
|
|
#include "pegasus/ai/ai_condition.h"
|
|
#include "pegasus/items/itemlist.h"
|
|
#include "pegasus/items/biochips/biochipitem.h"
|
|
#include "pegasus/items/inventory/inventoryitem.h"
|
|
|
|
namespace Pegasus {
|
|
|
|
AIOneChildCondition::AIOneChildCondition(AICondition *child) {
|
|
_child = child;
|
|
}
|
|
|
|
AIOneChildCondition::~AIOneChildCondition() {
|
|
delete _child;
|
|
}
|
|
|
|
void AIOneChildCondition::writeAICondition(Common::WriteStream *stream) {
|
|
if (_child)
|
|
_child->writeAICondition(stream);
|
|
}
|
|
|
|
void AIOneChildCondition::readAICondition(Common::ReadStream *stream) {
|
|
if (_child)
|
|
_child->readAICondition(stream);
|
|
}
|
|
|
|
AITwoChildrenCondition::AITwoChildrenCondition(AICondition *leftChild, AICondition *rightChild) {
|
|
_leftChild = leftChild;
|
|
_rightChild = rightChild;
|
|
}
|
|
|
|
AITwoChildrenCondition::~AITwoChildrenCondition() {
|
|
delete _leftChild;
|
|
delete _rightChild;
|
|
}
|
|
|
|
void AITwoChildrenCondition::writeAICondition(Common::WriteStream *stream) {
|
|
if (_leftChild)
|
|
_leftChild->writeAICondition(stream);
|
|
|
|
if (_rightChild)
|
|
_rightChild->writeAICondition(stream);
|
|
}
|
|
|
|
void AITwoChildrenCondition::readAICondition(Common::ReadStream *stream) {
|
|
if (_leftChild)
|
|
_leftChild->readAICondition(stream);
|
|
|
|
if (_rightChild)
|
|
_rightChild->readAICondition(stream);
|
|
}
|
|
|
|
AINotCondition::AINotCondition(AICondition* child) : AIOneChildCondition(child) {
|
|
}
|
|
|
|
bool AINotCondition::fireCondition() {
|
|
return _child && !_child->fireCondition();
|
|
}
|
|
|
|
AIAndCondition::AIAndCondition(AICondition *leftChild, AICondition *rightChild) : AITwoChildrenCondition(leftChild, rightChild) {
|
|
}
|
|
|
|
bool AIAndCondition::fireCondition() {
|
|
return _leftChild && _leftChild->fireCondition() && _rightChild && _rightChild->fireCondition();
|
|
}
|
|
|
|
AIOrCondition::AIOrCondition(AICondition *leftChild, AICondition *rightChild) : AITwoChildrenCondition(leftChild, rightChild) {
|
|
}
|
|
|
|
bool AIOrCondition::fireCondition() {
|
|
return (_leftChild && _leftChild->fireCondition()) || (_rightChild && _rightChild->fireCondition());
|
|
}
|
|
|
|
AITimerCondition::AITimerCondition(const TimeValue time, const TimeScale scale, const bool shouldStartTimer) {
|
|
_timerFuse.primeFuse(time, scale);
|
|
_timerFuse.setFunctor(new Common::Functor0Mem<void, AITimerCondition>(this, &AITimerCondition::fire));
|
|
_fired = false;
|
|
|
|
if (shouldStartTimer)
|
|
startTimer();
|
|
}
|
|
|
|
void AITimerCondition::startTimer() {
|
|
_fired = false;
|
|
_timerFuse.lightFuse();
|
|
}
|
|
|
|
void AITimerCondition::stopTimer() {
|
|
_timerFuse.stopFuse();
|
|
}
|
|
|
|
void AITimerCondition::writeAICondition(Common::WriteStream *stream) {
|
|
stream->writeByte(_timerFuse.isFuseLit());
|
|
stream->writeByte(_fired);
|
|
stream->writeUint32BE(_timerFuse.getTimeRemaining());
|
|
stream->writeUint32BE(_timerFuse.getFuseScale());
|
|
}
|
|
|
|
void AITimerCondition::readAICondition(Common::ReadStream *stream) {
|
|
bool running = stream->readByte();
|
|
_fired = stream->readByte();
|
|
TimeValue time = stream->readUint32BE();
|
|
TimeScale scale = stream->readUint32BE();
|
|
|
|
_timerFuse.stopFuse();
|
|
_timerFuse.primeFuse(time, scale);
|
|
|
|
if (running)
|
|
_timerFuse.lightFuse();
|
|
}
|
|
|
|
bool AITimerCondition::fireCondition() {
|
|
return _fired;
|
|
}
|
|
|
|
void AITimerCondition::fire() {
|
|
_fired = true;
|
|
}
|
|
|
|
AILocationCondition::AILocationCondition(uint32 maxLocations) {
|
|
_numLocations = 0;
|
|
_maxLocations = maxLocations;
|
|
_locations = new RoomViewID[maxLocations];
|
|
}
|
|
|
|
AILocationCondition::~AILocationCondition() {
|
|
delete[] _locations;
|
|
}
|
|
|
|
void AILocationCondition::addLocation(const RoomViewID location) {
|
|
if (_numLocations < _maxLocations)
|
|
_locations[_numLocations++] = location;
|
|
}
|
|
|
|
bool AILocationCondition::fireCondition() {
|
|
RoomViewID test = GameState.getCurrentRoomAndView(), *p;
|
|
uint32 i;
|
|
|
|
for (i = 0, p = _locations; i < _numLocations; i++, p++) {
|
|
if (test == *p) {
|
|
*p = MakeRoomView(kNoRoomID, kNoDirection);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void AILocationCondition::writeAICondition(Common::WriteStream *stream) {
|
|
stream->writeUint32BE(_maxLocations);
|
|
stream->writeUint32BE(_numLocations);
|
|
|
|
uint32 i;
|
|
RoomViewID *p;
|
|
for (i = 0, p = _locations; i < _numLocations; i++, p++)
|
|
stream->writeUint32BE(*p);
|
|
}
|
|
|
|
void AILocationCondition::readAICondition(Common::ReadStream *stream) {
|
|
uint32 maxLocations = stream->readUint32BE();
|
|
|
|
if (_maxLocations != maxLocations) {
|
|
delete[] _locations;
|
|
_locations = new RoomViewID[maxLocations];
|
|
_maxLocations = maxLocations;
|
|
}
|
|
|
|
_numLocations = stream->readUint32BE();
|
|
|
|
uint32 i;
|
|
RoomViewID *p;
|
|
for (i = 0, p = _locations; i < _numLocations; i++, p++)
|
|
*p = stream->readUint32BE();
|
|
}
|
|
|
|
AIDoorOpenedCondition::AIDoorOpenedCondition(RoomViewID doorLocation) {
|
|
_doorLocation = doorLocation;
|
|
}
|
|
|
|
bool AIDoorOpenedCondition::fireCondition() {
|
|
return GameState.getCurrentRoomAndView() == _doorLocation && GameState.isCurrentDoorOpen();
|
|
}
|
|
|
|
AIHasItemCondition::AIHasItemCondition(const ItemID item) {
|
|
_item = item;
|
|
}
|
|
|
|
bool AIHasItemCondition::fireCondition() {
|
|
return _item == kNoItemID || GameState.isTakenItemID(_item);
|
|
}
|
|
|
|
AIDoesntHaveItemCondition::AIDoesntHaveItemCondition(const ItemID item) {
|
|
_item = item;
|
|
}
|
|
|
|
bool AIDoesntHaveItemCondition::fireCondition() {
|
|
return _item == kNoItemID || !GameState.isTakenItemID(_item);
|
|
}
|
|
|
|
AICurrentItemCondition::AICurrentItemCondition(const ItemID item) {
|
|
_item = item;
|
|
}
|
|
|
|
bool AICurrentItemCondition::fireCondition() {
|
|
InventoryItem *item = g_vm->getCurrentInventoryItem();
|
|
|
|
if (_item == kNoItemID)
|
|
return item == nullptr;
|
|
|
|
return item != nullptr && item->getObjectID() == _item;
|
|
}
|
|
|
|
AICurrentBiochipCondition::AICurrentBiochipCondition(const ItemID biochip) {
|
|
_biochip = biochip;
|
|
}
|
|
|
|
bool AICurrentBiochipCondition::fireCondition() {
|
|
BiochipItem *biochip = g_vm->getCurrentBiochip();
|
|
|
|
if (_biochip == kNoItemID)
|
|
return biochip == nullptr;
|
|
|
|
return biochip != nullptr && biochip->getObjectID() == _biochip;
|
|
}
|
|
|
|
AIItemStateCondition::AIItemStateCondition(const ItemID item, const ItemState state) {
|
|
_item = item;
|
|
_state = state;
|
|
}
|
|
|
|
bool AIItemStateCondition::fireCondition() {
|
|
Item *item = g_allItems.findItemByID(_item);
|
|
return item != nullptr && item->getItemState() == _state;
|
|
}
|
|
|
|
AIEnergyMonitorCondition::AIEnergyMonitorCondition(const int32 energyThreshold) {
|
|
_energyThreshold = energyThreshold;
|
|
}
|
|
|
|
bool AIEnergyMonitorCondition::fireCondition() {
|
|
return g_energyMonitor != nullptr && g_energyMonitor->getCurrentEnergy() < _energyThreshold;
|
|
}
|
|
|
|
AILastExtraCondition::AILastExtraCondition(const ExtraID lastExtra) {
|
|
_lastExtra = lastExtra;
|
|
}
|
|
|
|
bool AILastExtraCondition::fireCondition() {
|
|
return g_neighborhood && (ExtraID)g_neighborhood->getLastExtra() == _lastExtra;
|
|
}
|
|
|
|
AICondition *makeLocationAndDoesntHaveItemCondition(const RoomID room, const DirectionConstant direction, const ItemID item) {
|
|
AILocationCondition *location = new AILocationCondition(1);
|
|
location->addLocation(MakeRoomView(room, direction));
|
|
|
|
AIDoesntHaveItemCondition *doesntHaveItem = new AIDoesntHaveItemCondition(item);
|
|
|
|
return new AIAndCondition(location, doesntHaveItem);
|
|
}
|
|
|
|
} // End of namespace Pegasus
|