scummvm/engines/saga2/property.cpp

273 lines
7.7 KiB
C++
Raw Normal View History

2021-05-17 20:47:39 +02:00
/* 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.
2021-05-17 20:47:39 +02:00
*
* 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
* aint32 with this program; if not, write to the Free Software
*
*
* Based on the original sources
* Faery Tale II -- The Halls of the Dead
* (c) 1993-1996 The Wyrmkeep Entertainment Co.
*/
2021-06-23 14:41:01 +02:00
#include "saga2/saga2.h"
2021-05-17 20:47:39 +02:00
#include "saga2/player.h"
#include "saga2/tile.h"
#include "saga2/pclass.r"
2021-05-17 20:47:39 +02:00
namespace Saga2 {
// Determine if this object is just an object
bool objIsObject(GameObject *obj) {
2021-05-17 20:47:39 +02:00
return isObject(obj);
}
// Determine if this object is an actor
bool objIsActor(GameObject *obj) {
2021-05-17 20:47:39 +02:00
return isActor(obj);
}
// Determine if this object is a world
bool objIsWorld(GameObject *obj) {
2021-05-17 20:47:39 +02:00
return isWorld(obj);
}
// Determine if this object is locked
bool objIsLocked(GameObject *obj) {
2021-05-17 20:47:39 +02:00
return obj->isLocked();
}
// Determine if this object is unlocked
bool objIsUnlocked(GameObject *obj) {
2021-05-17 20:47:39 +02:00
return !obj->isLocked();
}
// Determine if this object is a key
bool objIsKey(GameObject *obj) {
2021-05-17 20:47:39 +02:00
return obj->proto()->classType == protoClassKey;
}
// Determine if this object is a player actor
bool objIsPlayerActor(GameObject *obj) {
2021-05-17 20:47:39 +02:00
return isActor(obj)
&& isPlayerActor((Actor *)obj);
}
// Determine if this object is an enemy of the protaganists
bool objIsEnemy(GameObject *obj) {
2021-05-17 20:47:39 +02:00
return isActor(obj)
&& isEnemy((Actor *)obj);
}
/* ===================================================================== *
Actor properties
* ===================================================================== */
// Determine if this actor is dead
bool actorIsDead(Actor *a) {
2021-05-17 20:47:39 +02:00
return a->isDead();
}
// Determine if this actor is the center actor
bool actorIsCenterActor(Actor *a) {
2021-05-17 20:47:39 +02:00
return a == getCenterActor();
}
// Determine if this actor is a player actor
bool actorIsPlayerActor(Actor *a) {
2021-05-17 20:47:39 +02:00
return isPlayerActor(a);
}
// Determine if this actor is an enemy of the protaganists
bool actorIsEnemy(Actor *a) {
2021-05-17 20:47:39 +02:00
return isEnemy(a);
}
/* ===================================================================== *
Tile properties
* ===================================================================== */
// Determine if this tile has water
bool tileHasWater(TileInfo *ti) {
2022-10-29 22:28:04 +02:00
return (ti->combinedTerrainMask() & kTerrainWater) ? true : false;
2021-05-17 20:47:39 +02:00
}
/* ===================================================================== *
MetaTile properties
* ===================================================================== */
/* ===================================================================== *
SimpleMetaTileProperty class member functions
* ===================================================================== */
bool SimpleMetaTileProperty::operator()(
MetaTile *mt,
int16 mapNum,
const TilePoint &tp) const {
// Simply pass this call to the property evaluation function
return (*_propertyFunc)(mt, mapNum, tp);
2021-05-17 20:47:39 +02:00
}
/* ===================================================================== *
CompoundMetaTileProperty class member functions
* ===================================================================== */
CompoundMetaTileProperty::CompoundMetaTileProperty(
MetaTileProperty **array,
uint16 size) {
// Calculate the number of bytes required to copy the array
uint16 arrayBytes = sizeof(MetaTileProperty *) * size;
// Allocate memory for a copy of the array
_propertyArray = (MetaTileProperty **)malloc(arrayBytes);
2021-05-17 20:47:39 +02:00
#if DEBUG
assert(_propertyArray);
2021-05-17 20:47:39 +02:00
#endif
// Copy the array
memcpy(_propertyArray, array, arrayBytes);
_arraySize = size;
2021-05-17 20:47:39 +02:00
}
2021-09-11 12:13:35 +03:00
CompoundMetaTileProperty::~CompoundMetaTileProperty() {
2021-05-17 20:47:39 +02:00
// Free the memory for the copy of the array
free(_propertyArray);
2021-05-17 20:47:39 +02:00
}
/* ===================================================================== *
MetaTilePropertyAnd class member functions
* ===================================================================== */
bool MetaTilePropertyAnd::operator()(
MetaTile *mt,
int16 mapNum,
const TilePoint &tp) const {
uint16 i;
// Iterate through each element in the array and if any evaluate to
2021-06-13 16:56:52 +02:00
// false, return false immediately.
for (i = 0; i < _arraySize; i++)
if ((*_propertyArray[i])(mt, mapNum, tp) == false) return false;
2021-05-17 20:47:39 +02:00
2021-06-13 16:56:52 +02:00
return true;
2021-05-17 20:47:39 +02:00
}
/* ===================================================================== *
MetaTilePropertyOr class member functions
* ===================================================================== */
bool MetaTilePropertyOr::operator()(
MetaTile *mt,
int16 mapNum,
const TilePoint &tp) const {
uint16 i;
// Iterate through each element in the array and if any evaluate to
2021-06-13 16:56:52 +02:00
// true, return true immediately.
for (i = 0; i < _arraySize; i++)
if ((*_propertyArray[i])(mt, mapNum, tp)) return true;
2021-05-17 20:47:39 +02:00
2021-06-13 16:56:52 +02:00
return false;
2021-05-17 20:47:39 +02:00
}
// Determine if this MetaTile has water
bool metaTileHasWater(
2021-05-17 20:47:39 +02:00
MetaTile *mt,
int16 mapNum,
const TilePoint &mCoords) {
TilePoint origin = mCoords << kPlatShift,
2021-05-17 20:47:39 +02:00
tCoords;
tCoords.z = 0;
2022-10-29 22:28:04 +02:00
for (int i = 0; i < kMaxPlatforms; i++) {
2021-05-17 20:47:39 +02:00
Platform *p = mt->fetchPlatform(mapNum, i);
if (p) {
for (tCoords.u = 0; tCoords.u < kPlatformWidth; tCoords.u++) {
for (tCoords.v = 0; tCoords.v < kPlatformWidth; tCoords.v++) {
2021-05-17 20:47:39 +02:00
TileInfo *ti;
int16 height;
int16 trFlags;
ti = p->fetchTile(
mapNum,
tCoords,
origin,
height,
trFlags);
2022-10-29 22:28:04 +02:00
if (ti->combinedTerrainMask() & kTerrainWater)
2021-06-13 16:56:52 +02:00
return true;
2021-05-17 20:47:39 +02:00
}
}
}
}
2021-06-13 16:56:52 +02:00
return false;
2021-05-17 20:47:39 +02:00
}
Properties::Properties() {
_objPropArray.push_back(new SimpleObjectProperty(objIsObject));
_objPropArray.push_back(new SimpleObjectProperty(objIsActor));
_objPropArray.push_back(new SimpleObjectProperty(objIsWorld));
_objPropArray.push_back(new SimpleObjectProperty(objIsLocked));
_objPropArray.push_back(new SimpleObjectProperty(objIsUnlocked));
_objPropArray.push_back(new SimpleObjectProperty(objIsKey));
_objPropArray.push_back(new SimpleObjectProperty(objIsPlayerActor));
_objPropArray.push_back(new SimpleObjectProperty(objIsEnemy));
_actorPropArray.push_back(new SimpleActorProperty(actorIsDead));
_actorPropArray.push_back(new SimpleActorProperty(actorIsCenterActor));
_actorPropArray.push_back(new SimpleActorProperty(actorIsPlayerActor));
_actorPropArray.push_back(new SimpleActorProperty(actorIsEnemy));
_tilePropArray.push_back(new SimpleTileProperty(tileHasWater));
_metaTilePropArray.push_back(new SimpleMetaTileProperty(metaTileHasWater));
}
Properties::~Properties() {
for (uint i = 0; i < _objPropArray.size(); ++i) {
if (_objPropArray[i])
delete _objPropArray[i];
}
_objPropArray.clear();
for (uint i = 0; i < _actorPropArray.size(); ++i) {
if (_actorPropArray[i])
delete _actorPropArray[i];
}
_actorPropArray.clear();
2021-05-17 20:47:39 +02:00
for (uint i = 0; i < _tilePropArray.size(); ++i) {
if (_tilePropArray[i])
delete _tilePropArray[i];
}
_tilePropArray.clear();
for (uint i = 0; i < _metaTilePropArray.size(); ++i) {
if (_metaTilePropArray[i])
delete _metaTilePropArray[i];
}
_metaTilePropArray.clear();
}
2021-05-17 20:47:39 +02:00
} // end of namespace Saga2