mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-24 19:45:07 +00:00
fixed some actor movement issues - fixed several scene changing issues - fixed memory bugs in LocalizeString and isVoicePlaying - fixed start_script called with LUA_T_NIL
This commit is contained in:
parent
c1eda63527
commit
f16975f426
7
README
7
README
@ -62,7 +62,7 @@ but many features are either missing or unstable. There is no abilitity
|
||||
to save/load, lighting, etc. Crashes are likely.
|
||||
|
||||
Game currently playable to:
|
||||
The Demon Beaver Dam (Petrified Forest)
|
||||
Meche leaves Manny again (Rubacava, Year 2)
|
||||
Caveats (in order of appearance):
|
||||
1) Sound track destruction doesn't do quite a good enough job when
|
||||
entering the spider web area (sp.set) in the Petrified Forest
|
||||
@ -70,9 +70,8 @@ Caveats (in order of appearance):
|
||||
the correct speed, this causes buffer overflows in the audio.
|
||||
While hardcoding the speed to the correct value used by the other
|
||||
movies works, it is not a good fix and so it is not implemented
|
||||
3) When you return from getting the shocks at the tree pump in the
|
||||
Petrified Forest the scene doesn't change correctly and the game
|
||||
stops allowing input
|
||||
3) Sometimes the Demon Beavers get stuck on obstacles - open the
|
||||
menu for a moment and they will correct themselves
|
||||
|
||||
What are the default keys?
|
||||
--------------------------
|
||||
|
1
TODO
1
TODO
@ -9,7 +9,6 @@ Assigned tasks:
|
||||
(Ender: May just need the blending of the lighting values (p2->r, ->g, ->b)
|
||||
to the result of pp[_a] in the non-24bpp PUT_PIXEL macro of
|
||||
ztriangle.cpp/ZB_FillTriangleMappingPerspective. Maybe. :)
|
||||
* Figure out problem changing scenes after getting shocks (compholio)
|
||||
* Improve actor colormap supprt (compholio)
|
||||
* Improve SMUSH looping support (compholio)
|
||||
* Improve menu support (compholio)
|
||||
|
28
actor.cpp
28
actor.cpp
@ -33,8 +33,11 @@
|
||||
|
||||
Actor::Actor(const char *name) :
|
||||
_name(name), _talkColor(255, 255, 255), _pos(0, 0, 0),
|
||||
_pitch(0), _yaw(0), _roll(0), _walkRate(0), _turnRate(0),
|
||||
_reflectionAngle(80), _setName(""), _setNameTmp(""),
|
||||
// Some actors don't set walk and turn rates, so we default the
|
||||
// _turnRate so Doug at the cat races can turn and we set the
|
||||
// _walkRate so Glottis at the demon beaver entrance can walk
|
||||
_pitch(0), _yaw(0), _roll(0), _walkRate(1.0f), _turnRate(100.0f),
|
||||
_reflectionAngle(80), _setName(""),
|
||||
_visible(true), _lipSynch(NULL), _turning(false), _walking(false),
|
||||
_restCostume(NULL), _restChore(-1),
|
||||
_walkCostume(NULL), _walkChore(-1), _walkedLast(false), _walkedCur(false),
|
||||
@ -369,9 +372,14 @@ bool Actor::talking() {
|
||||
}
|
||||
|
||||
void Actor::shutUp() {
|
||||
// Don't stop the sound, the call to stop the sound
|
||||
// is made by the game
|
||||
_talkSoundName = "";
|
||||
// While the call to stop the sound is usually made by the game,
|
||||
// we also need to handle when the user terminates the dialog.
|
||||
// Some warning messages will occur when the user terminates the
|
||||
// actor dialog but the game will continue alright.
|
||||
if (_talkSoundName != "") {
|
||||
g_imuse->stopSound(_talkSoundName.c_str());
|
||||
_talkSoundName = "";
|
||||
}
|
||||
if (_lipSynch != NULL) {
|
||||
if ((_talkAnim != -1) && (_talkChore[_talkAnim] >= 0))
|
||||
_talkCostume[_talkAnim]->stopChore(_talkChore[_talkAnim]);
|
||||
@ -467,7 +475,11 @@ void Actor::update() {
|
||||
dyaw -= 360;
|
||||
while (dyaw < -180)
|
||||
dyaw += 360;
|
||||
if (turnAmt >= std::abs(dyaw)) {
|
||||
// If the actor won't turn because the rate is set to zero then
|
||||
// have the actor turn all the way to the destination yaw.
|
||||
// Without this some actors will lock the interface on changing
|
||||
// scenes, this affects the Bone Wagon in particular.
|
||||
if (turnAmt == 0 || turnAmt >= std::abs(dyaw)) {
|
||||
setYaw(_destYaw);
|
||||
_turning = false;
|
||||
}
|
||||
@ -490,7 +502,9 @@ void Actor::update() {
|
||||
if (walkAmt >= dist) {
|
||||
_pos = _destPos;
|
||||
_walking = false;
|
||||
_turning = false;
|
||||
// It seems that we need to allow an already active turning motion to
|
||||
// continue or else turning actors away from barriers won't work right
|
||||
// _turning = false;
|
||||
} else
|
||||
_pos += dir * walkAmt;
|
||||
|
||||
|
22
actor.h
22
actor.h
@ -41,8 +41,17 @@ public:
|
||||
void setTalkColor(const Color& c) { _talkColor = c; }
|
||||
Color talkColor() const { return _talkColor; }
|
||||
void setPos(Vector3d pos) { _pos = pos; }
|
||||
Vector3d pos() const { return _pos; }
|
||||
// When the actor is walking report where the actor is going to and
|
||||
// not the actual current position, this fixes some scene change
|
||||
// change issues with the Bone Wagon (along with other fixes)
|
||||
Vector3d pos() const {
|
||||
if (_walking)
|
||||
return _destPos;
|
||||
else
|
||||
return _pos;
|
||||
}
|
||||
void walkTo(Vector3d p);
|
||||
void stopWalking() { _walking = false; }
|
||||
bool isWalking() const;
|
||||
void setRot(float pitch, float yaw, float roll);
|
||||
void turnTo(float pitch, float yaw, float roll);
|
||||
@ -52,13 +61,9 @@ public:
|
||||
float roll() const { return _roll; }
|
||||
void setVisibility(bool val) { _visible = val; }
|
||||
bool visible() const { return _visible; }
|
||||
// Don't actually change the set immediately, see engine.cpp for details
|
||||
void putInSet(const char *name) { _setNameTmp = name; }
|
||||
void putInSet() {
|
||||
if (_setName != _setNameTmp) {
|
||||
_setName = _setNameTmp;
|
||||
}
|
||||
}
|
||||
// The set should change immediately, otherwise a very rapid set change
|
||||
// for an actor will be recognized incorrectly and the actor will be lost.
|
||||
void putInSet(const char *name) { _setName = name; }
|
||||
void setTurnRate(float rate) { _turnRate = rate; }
|
||||
float turnRate() const { return _turnRate; }
|
||||
void setWalkRate(float rate) { _walkRate = rate; }
|
||||
@ -133,7 +138,6 @@ public:
|
||||
private:
|
||||
std::string _name;
|
||||
std::string _setName; // The actual current set
|
||||
std::string _setNameTmp; // The temporary name for the set
|
||||
Color _talkColor;
|
||||
Vector3d _pos;
|
||||
float _pitch, _yaw, _roll;
|
||||
|
@ -249,11 +249,6 @@ void Engine::mainLoop() {
|
||||
for (ActorListType::iterator i = _actors.begin(); i != _actors.end(); i++) {
|
||||
Actor *a = *i;
|
||||
|
||||
// Activate the new set
|
||||
// While this doesn't seem to affect anything this should be done here
|
||||
// instead of inside the lua_runtasks loop, otherwise certain functions
|
||||
// may request a set that was just deactivated
|
||||
a->putInSet();
|
||||
// Update the actor's costumes & chores
|
||||
g_currentUpdatedActor = *i;
|
||||
// Note that the actor need not be visible to update chores, for example:
|
||||
|
12
engine.h
12
engine.h
@ -102,14 +102,10 @@ public:
|
||||
unsigned frameStart() const { return _frameStart; }
|
||||
unsigned frameTime() const { return _frameTime; }
|
||||
|
||||
float perSecond(float rate) const {
|
||||
// The actor "Doug" at the Kitty races has no _turnRate set by default
|
||||
// so we need to return some sort of time that's non-zero for a rate
|
||||
// value of zero
|
||||
if (rate == 0.0)
|
||||
rate = 100.0;
|
||||
return rate * _frameTime / 1000;
|
||||
}
|
||||
// perSecond should allow rates of zero, some actors will accelerate
|
||||
// up to their normal speed (such as the bone wagon) so handling
|
||||
// a walking rate of zero should happen in the default actor creation
|
||||
float perSecond(float rate) const { return rate * _frameTime / 1000; }
|
||||
|
||||
int getTextSpeed() { return _textSpeed; }
|
||||
void setTextSpeed(int speed);
|
||||
|
@ -100,7 +100,10 @@ bool Imuse::isVoicePlaying() {
|
||||
StackLock lock(_mutex);
|
||||
for (int l = 0; l < MAX_IMUSE_TRACKS; l++) {
|
||||
Track *track = _track[l];
|
||||
if (track->volGroupId == IMUSE_VOLGRP_VOICE) {
|
||||
// Make sure the track is in use before checking the group ID,
|
||||
// otherwise volGroupId can be uninitialized or reference an
|
||||
// old track.
|
||||
if (track->used && track->volGroupId == IMUSE_VOLGRP_VOICE) {
|
||||
if (track->handle.isActive()) {
|
||||
return true;
|
||||
}
|
||||
|
160
lua.cpp
160
lua.cpp
@ -369,6 +369,19 @@ static void SetSelectedActor() {
|
||||
g_engine->setSelectedActor(act);
|
||||
}
|
||||
|
||||
/* Get the currently selected actor, this is used in
|
||||
* "Camera-Relative" mode to handle the appropriate
|
||||
* actor for movement
|
||||
*/
|
||||
static void GetCameraActor() {
|
||||
Actor *act;
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
stubWarning("VERIFY: GetCameraActor");
|
||||
act = g_engine->selectedActor();
|
||||
lua_pushusertag(act, MKID('ACTR'));
|
||||
}
|
||||
|
||||
static void SetSayLineDefaults() {
|
||||
char *key_text = NULL;
|
||||
lua_Object table_obj;
|
||||
@ -530,6 +543,8 @@ static void GetActorPos() {
|
||||
DEBUG_FUNCTION();
|
||||
act = check_actor(1);
|
||||
pos = act->pos();
|
||||
// It is important to process this request for all actors,
|
||||
// even for actors not within the active scene
|
||||
lua_pushnumber(pos.x());
|
||||
lua_pushnumber(pos.y());
|
||||
lua_pushnumber(pos.z());
|
||||
@ -548,10 +563,6 @@ static void SetActorRot() {
|
||||
act->turnTo(pitch, yaw, roll);
|
||||
else
|
||||
act->setRot(pitch, yaw, roll);
|
||||
// Naranja will cause the game to crash without this
|
||||
lua_pushnumber(pitch);
|
||||
lua_pushnumber(yaw);
|
||||
lua_pushnumber(roll);
|
||||
}
|
||||
|
||||
static void GetActorRot() {
|
||||
@ -605,19 +616,25 @@ static void GetActorYawToPoint() {
|
||||
lua_pushnumber(act->yawTo(yawVector));
|
||||
}
|
||||
|
||||
/* Changes the set that an actor is associated with,
|
||||
* by changing the set to "nil" an actor is disabled
|
||||
* but should still not be destroyed.
|
||||
*/
|
||||
static void PutActorInSet() {
|
||||
const char *set = "";
|
||||
Actor *act;
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
act = check_actor(1);
|
||||
if (!lua_isnil(lua_getparam(2))) {
|
||||
const char *set;
|
||||
|
||||
// If the set is "nil" then set to an empty string, we should not render
|
||||
// objects in the empty set or bad things will happen like the Bone
|
||||
// Wagon not changing scenes correctly.
|
||||
lua_Object param2 = lua_getparam(2);
|
||||
if (!lua_isnil(param2))
|
||||
set = luaL_check_string(2);
|
||||
// Make sure the actor isn't already in the set
|
||||
if (!act->inSet(set))
|
||||
act->putInSet(set);
|
||||
}
|
||||
// Make sure the actor isn't already in the set
|
||||
if (!act->inSet(set))
|
||||
act->putInSet(set);
|
||||
}
|
||||
|
||||
static void SetActorWalkRate() {
|
||||
@ -776,7 +793,6 @@ static void GetActorNodeLocation() {
|
||||
Actor *act;
|
||||
int node;
|
||||
|
||||
// Should this actually do anything?
|
||||
DEBUG_FUNCTION();
|
||||
act = check_actor(1);
|
||||
node = check_int(2);
|
||||
@ -802,11 +818,14 @@ static void GetActorNodeLocation() {
|
||||
lua_pushnumber(allNodes[node]._pos.z());
|
||||
}
|
||||
|
||||
/* This function is called to stop walking actions that
|
||||
* are in progress, it is unknown whether it should start
|
||||
* walking actions that are not in progress.
|
||||
*/
|
||||
static void SetActorWalkDominate() {
|
||||
lua_Object param2;
|
||||
Actor *act;
|
||||
|
||||
// Should this actually do anything?
|
||||
DEBUG_FUNCTION();
|
||||
act = check_actor(1);
|
||||
if (act == NULL) {
|
||||
@ -814,13 +833,26 @@ static void SetActorWalkDominate() {
|
||||
return;
|
||||
}
|
||||
param2 = lua_getparam(2);
|
||||
if (lua_isnil(param2))
|
||||
if (lua_isnil(param2)) {
|
||||
lua_pushnil();
|
||||
else if (lua_isnumber(param2))
|
||||
lua_pushnumber(lua_getnumber(param2));
|
||||
else
|
||||
} else if (lua_isnumber(param2)) {
|
||||
int walkcode = check_int(2);
|
||||
|
||||
if (walkcode != 1) {
|
||||
warning("Unknown SetActorWalkDominate 'walking code' value: %d", walkcode);
|
||||
lua_pushnil();
|
||||
return;
|
||||
}
|
||||
// When Manny is pursued out of the dam area by a demon
|
||||
// beaver he needs to stop his walk chore
|
||||
act->stopWalking();
|
||||
lua_pushnumber(walkcode);
|
||||
} else {
|
||||
warning("Unknown SetActorWalkDominate parameter!");
|
||||
lua_pushnil();
|
||||
}
|
||||
}
|
||||
|
||||
static void SetActorColormap() {
|
||||
char *mapname;
|
||||
CMap *_cmap;
|
||||
@ -876,7 +908,7 @@ static void GetActorCostume() {
|
||||
if (c == NULL) {
|
||||
lua_pushnil();
|
||||
if (debugLevel == DEBUG_NORMAL || debugLevel == DEBUG_ALL)
|
||||
printf("GetActorCostume() on '%s' when actor has no costume!", act->name());
|
||||
printf("GetActorCostume() on '%s' when actor has no costume!\n", act->name());
|
||||
return;
|
||||
}
|
||||
lua_pushstring(const_cast<char *>(c->filename()));
|
||||
@ -1129,16 +1161,10 @@ static void TurnActorTo() {
|
||||
// Find the vector pointing from the actor to the desired location
|
||||
Vector3d turnToVector(x, y, z);
|
||||
Vector3d lookVector = turnToVector - act->pos();
|
||||
lookVector.z() = 0;
|
||||
// must convert to use a unit vector
|
||||
lookVector /= lookVector.magnitude();
|
||||
// find the angle on the upper half of the unit circle
|
||||
yaw = std::acos(lookVector.x()) * (180 / M_PI);
|
||||
// adjust for the lower half of the unit circle
|
||||
if (lookVector.y() < 0)
|
||||
yaw = 360.0 - yaw;
|
||||
// find the angle the requested position is around the unit circle
|
||||
yaw = lookVector.unitCircleAngle();
|
||||
// yaw is offset from forward by 90 degrees
|
||||
yaw -= 90.0;
|
||||
yaw -= 90.0f;
|
||||
act->turnTo(0, yaw, 0);
|
||||
|
||||
// Game will lock in elevator if this doesn't return false
|
||||
@ -1152,6 +1178,50 @@ static void PointActorAt() {
|
||||
TurnActorTo();
|
||||
}
|
||||
|
||||
/* WalkActorVector handles the movement of the selected actor
|
||||
* when the game is in "Camera-Relative Movement Mode"
|
||||
*
|
||||
* NOTE: The usage for paramaters 1 and 5 are as-yet unknown.
|
||||
*/
|
||||
static void WalkActorVector() {
|
||||
float moveHoriz, moveVert, yaw;
|
||||
Actor *act;
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
stubWarning("VERIFY: WalkActorVector");
|
||||
// Second option is the actor returned by GetCameraActor
|
||||
act = check_actor(2);
|
||||
// Third option is the "left/right" movement
|
||||
moveHoriz = luaL_check_number(3);
|
||||
// Fourth Option is the "up/down" movement
|
||||
moveVert = luaL_check_number(4);
|
||||
|
||||
// Get the direction the camera is pointing
|
||||
Vector3d cameraVector = g_engine->currScene()->_currSetup->_interest - g_engine->currScene()->_currSetup->_pos;
|
||||
// find the angle the camera direction is around the unit circle
|
||||
float cameraYaw = cameraVector.unitCircleAngle();
|
||||
|
||||
// Handle the turning
|
||||
Vector3d adjustVector(moveHoriz, moveVert, 0);
|
||||
// find the angle the adjust vector is around the unit circle
|
||||
float adjustYaw = adjustVector.unitCircleAngle();
|
||||
|
||||
yaw = cameraYaw + adjustYaw;
|
||||
// yaw is offset from forward by 180 degrees
|
||||
yaw -= 180.0f;
|
||||
// set the yaw so it can be compared against the current
|
||||
// value for the actor yaw
|
||||
if (yaw < 0.0f)
|
||||
yaw += 360.0f;
|
||||
if (yaw >= 360.0f)
|
||||
yaw -= 360.0f;
|
||||
// set the new direction or walk forward
|
||||
if (act->yaw() != yaw)
|
||||
act->turnTo(0, yaw, 0);
|
||||
else
|
||||
act->walkForward();
|
||||
}
|
||||
|
||||
/* RotateVector takes a vector and rotates it around
|
||||
* the point (0,0,0) by the requested number of degrees.
|
||||
* This function is used to calculate the locations for
|
||||
@ -1306,7 +1376,8 @@ static void GetVisibleThings() {
|
||||
for (Engine::ActorListType::const_iterator i = g_engine->actorsBegin(); i != g_engine->actorsEnd(); i++) {
|
||||
if (!(*i)->inSet(g_engine->sceneName()))
|
||||
continue;
|
||||
if (sel->angleTo(*(*i)) < 90) {
|
||||
// Consider the active actor visible
|
||||
if (sel == (*i) || sel->angleTo(*(*i)) < 90) {
|
||||
lua_pushobject(result);
|
||||
lua_pushusertag(*i, MKID('ACTR'));
|
||||
lua_pushnumber(1);
|
||||
@ -1406,12 +1477,21 @@ static void TextFileGetLineCount() {
|
||||
|
||||
static void LocalizeString() {
|
||||
char msgId[32], buf[640], *str;
|
||||
char *result;
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
str = luaL_check_string(1);
|
||||
std::string msg = parseMsgText(str, msgId);
|
||||
sprintf(buf, "/%s/%s", msgId, msg.c_str());
|
||||
lua_pushstring(const_cast<char *>(buf));
|
||||
// If the string that we're passed isn't localized yet then
|
||||
// construct the localized string, otherwise spit back what
|
||||
// we've been given
|
||||
if (str[0] == '/' && str[strlen(str)-1] == '/') {
|
||||
std::string msg = parseMsgText(str, msgId);
|
||||
sprintf(buf, "/%s/%s", msgId, msg.c_str());
|
||||
result = buf;
|
||||
} else {
|
||||
result = str;
|
||||
}
|
||||
lua_pushstring(const_cast<char *>(result));
|
||||
}
|
||||
|
||||
static void SayLine() {
|
||||
@ -1664,18 +1744,26 @@ static void MakeCurrentSetup() {
|
||||
lua_endblock();
|
||||
}
|
||||
|
||||
/* Find the requested scene and return the current setup
|
||||
* id number. This function cannot just use the current
|
||||
* scene or else when Manny opens his inventory information
|
||||
* gets lost, such as the position for the demon beavors
|
||||
* in the Petrified Forest.
|
||||
*/
|
||||
static void GetCurrentSetup() {
|
||||
const char *name;
|
||||
Scene *scene;
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
name = luaL_check_string(1);
|
||||
if (std::strcmp(name, g_engine->sceneName()) == 0) {
|
||||
lua_pushnumber(g_engine->currScene()->setup());
|
||||
} else {
|
||||
scene = g_engine->findScene(name);
|
||||
if (scene == NULL) {
|
||||
if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL)
|
||||
warning("GetCurrentSetup() Requested scene (%s) is not the active scene (%s)", name, g_engine->sceneName());
|
||||
warning("GetCurrentSetup() Requested scene (%s) is not loaded!", name);
|
||||
lua_pushnil();
|
||||
return;
|
||||
}
|
||||
lua_pushnumber(scene->setup());
|
||||
}
|
||||
|
||||
// FIXME: Function only spits back what it's given
|
||||
@ -3197,9 +3285,7 @@ STUB_FUNC(WorldToScreen)
|
||||
STUB_FUNC(SetActorRoll)
|
||||
STUB_FUNC(IsPointInSector)
|
||||
STUB_FUNC(SetActorFrustrumCull)
|
||||
STUB_FUNC(GetCameraActor)
|
||||
STUB_FUNC(DriveActorTo)
|
||||
STUB_FUNC(WalkActorVector)
|
||||
STUB_FUNC(GetActorRect)
|
||||
STUB_FUNC(SetActorTimeScale)
|
||||
STUB_FUNC(SetActorScale)
|
||||
|
@ -32,6 +32,11 @@ void start_script (void) {
|
||||
f = L->stack.stack + L->Cstack.lua2C;
|
||||
if (ttype(f) == LUA_T_CLOSURE)
|
||||
f = &clvalue(f)->consts[0];
|
||||
// Start nothing? start_script gets called in this fashion
|
||||
// by the scene in the scrimshaw parlor, if we just return
|
||||
// immediately the game proceeds ok.
|
||||
if (ttype(f) == LUA_T_NIL)
|
||||
return;
|
||||
if (ttype(f) != LUA_T_PROTO)
|
||||
lua_error("can only start_script with a Lua function");
|
||||
|
||||
|
17
vector3d.h
17
vector3d.h
@ -82,6 +82,23 @@ public:
|
||||
return std::sqrt(x() * x() + y() * y() + z() * z());
|
||||
}
|
||||
|
||||
// Get the angle a vector is around the unit circle
|
||||
// (ignores z-component)
|
||||
float unitCircleAngle() const {
|
||||
float a = x() / magnitude();
|
||||
float b = y() / magnitude();
|
||||
float yaw;
|
||||
|
||||
// find the angle on the upper half of the unit circle
|
||||
yaw = std::acos(a) * (180.0f / M_PI);
|
||||
if (b < 0.0f)
|
||||
// adjust for the lower half of the unit circle
|
||||
return 360.0f - yaw;
|
||||
else
|
||||
// no adjustment, angle is on the upper half
|
||||
return yaw;
|
||||
}
|
||||
|
||||
float dotProduct( float sx, float sy, float sz ) {
|
||||
return x() * sx + y() * sy + z()*sz;
|
||||
}
|
||||
|
@ -96,8 +96,39 @@ bool Sector::isPointInSector(Vector3d point) const {
|
||||
// vertices are always given in counterclockwise order, and the
|
||||
// polygons are always convex.)
|
||||
//
|
||||
// (I don't know whether the box height actually has to be considered;
|
||||
// if not then this will be fine as is.)
|
||||
// Checking the box height on the first point fixes problems with Manny
|
||||
// changing sectors outside Velasco's storeroom. We make an exceptions
|
||||
// for heights of 0 and 9999 since these appear to have special meaning.
|
||||
// In order to have the entrance to the Blue Casket work we need to
|
||||
// handle the vertices having different z-coordinates.
|
||||
// TODO: Improve height checking for when vertices have different
|
||||
// z-coordinates so the railing in Cafe Calavera works properly.
|
||||
if (_height != 0.0f && _height != 9999.0f) {
|
||||
bool heightOK = false;
|
||||
|
||||
// Handle height above Z
|
||||
if ((point.z() >= _vertices[0].z()) && (point.z() <= _vertices[0].z() + _height))
|
||||
heightOK = true;
|
||||
// Handle height below Z
|
||||
if ((point.z() <= _vertices[0].z()) && (point.z() >= _vertices[0].z() - _height))
|
||||
heightOK = true;
|
||||
|
||||
for (int i = 0; i < _numVertices; i++) {
|
||||
if (_vertices[i + 1].z() != _vertices[i].z())
|
||||
heightOK = true;
|
||||
}
|
||||
if (!heightOK) {
|
||||
/* Use this for debugging problems at height interfaces
|
||||
if (debugLevel == DEBUG_NORMAL || debugLevel == DEBUG_ALL) {
|
||||
printf("Rejected trigger due to height: %s (%f)\n", _name.c_str(), _height);
|
||||
printf("Actor Z: %f\n", point.z());
|
||||
for (int i = 0; i < _numVertices; i++)
|
||||
printf("(%d) Z: %f\n", i, _vertices[i].z());
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < _numVertices; i++) {
|
||||
Vector3d edge = _vertices[i + 1] - _vertices[i];
|
||||
|
Loading…
x
Reference in New Issue
Block a user