diff --git a/engines/twine/renderer/redraw.cpp b/engines/twine/renderer/redraw.cpp index df4d4f227a67..3a99789a3162 100644 --- a/engines/twine/renderer/redraw.cpp +++ b/engines/twine/renderer/redraw.cpp @@ -241,19 +241,19 @@ int32 Redraw::fillActorDrawingList(DrawListStruct *drawList, bool bgRedraw) { // if use shadows if (_engine->_cfgfile.ShadowMode != 0 && !(actor->_staticFlags.bDoesntCastShadow)) { if (actor->_carryBy != -1) { - _engine->_actor->_shadowCoord.x = actor->_pos.x; - _engine->_actor->_shadowCoord.y = actor->_pos.y - 1; - _engine->_actor->_shadowCoord.z = actor->_pos.z; + drawList[drawListPos].x = actor->_pos.x; + drawList[drawListPos].y = actor->_pos.y - 1; + drawList[drawListPos].z = actor->_pos.z; } else { - _engine->_movements->getShadowPosition(actor->pos()); + const IVec3 shadowCoord = _engine->_movements->getShadowPosition(actor->pos()); + drawList[drawListPos].x = shadowCoord.x; + drawList[drawListPos].y = shadowCoord.y; + drawList[drawListPos].z = shadowCoord.z; } drawList[drawListPos].posValue = tmpVal - 1; // save the shadow entry in the _drawList drawList[drawListPos].type = DrawListType::DrawShadows; drawList[drawListPos].actorIdx = 0; - drawList[drawListPos].x = _engine->_actor->_shadowCoord.x; - drawList[drawListPos].y = _engine->_actor->_shadowCoord.y; - drawList[drawListPos].z = _engine->_actor->_shadowCoord.z; drawList[drawListPos].offset = 1; drawListPos++; } @@ -291,14 +291,14 @@ int32 Redraw::fillExtraDrawingList(DrawListStruct *drawList, int32 drawListPos) drawListPos++; if (_engine->_cfgfile.ShadowMode == 2 && !(extra->info0 & EXTRA_SPECIAL_MASK)) { - _engine->_movements->getShadowPosition(extra->pos); + const IVec3 &shadowCoord = _engine->_movements->getShadowPosition(extra->pos); drawList[drawListPos].posValue = tmpVal - 1; drawList[drawListPos].actorIdx = 0; drawList[drawListPos].type = DrawListType::DrawShadows; - drawList[drawListPos].x = _engine->_actor->_shadowCoord.x; - drawList[drawListPos].y = _engine->_actor->_shadowCoord.y; - drawList[drawListPos].z = _engine->_actor->_shadowCoord.z; + drawList[drawListPos].x = shadowCoord.x; + drawList[drawListPos].y = shadowCoord.y; + drawList[drawListPos].z = shadowCoord.z; drawList[drawListPos].offset = 0; drawListPos++; } diff --git a/engines/twine/scene/actor.cpp b/engines/twine/scene/actor.cpp index 5ed220e2630b..c4e824db6cbf 100644 --- a/engines/twine/scene/actor.cpp +++ b/engines/twine/scene/actor.cpp @@ -266,6 +266,9 @@ void Actor::resetActor(int16 actorIdx) { actor->_anim = AnimationTypes::kStanding; actor->_pos = IVec3(0, -1, 0); actor->_spriteActorRotation = 0; + actor->_processActor = IVec3(0, 0, 0); + actor->_lastPos = IVec3(0, 0, 0); + actor->_collisionPos = IVec3(0, 0, 0); actor->_boudingBox = BoundingBox(); diff --git a/engines/twine/scene/actor.h b/engines/twine/scene/actor.h index ebc4fc669edf..54908de5ab37 100644 --- a/engines/twine/scene/actor.h +++ b/engines/twine/scene/actor.h @@ -181,7 +181,7 @@ class ActorStruct { int32 _hitBy = 0; BonusParameter _bonusParameter; int32 _angle = 0; // facing angle of actor. Minumum is 0 (SW). Going counter clock wise - int32 _speed = 0; + int32 _speed = 0; // speed of movement ControlMode _controlMode = ControlMode::kNoMove; int32 _delayInMillis = 0; int32 _cropLeft = 0; @@ -194,6 +194,10 @@ class ActorStruct { int32 _armor = 0; int32 _life = 0; + /** Process actor coordinate */ + IVec3 _processActor; + /** Previous process actor coordinate */ + IVec3 _previousActor; IVec3 _collisionPos; int32 _positionInMoveScript = 0; @@ -280,9 +284,6 @@ class Actor { ActorStruct *_processActorPtr = nullptr; - /** Actor shadow coordinate */ - IVec3 _shadowCoord; - HeroBehaviourType _heroBehaviour = HeroBehaviourType::kNormal; /** Hero auto aggressive mode */ bool _autoAggressive = true; diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp index 87957d26b1da..375b2d0125b6 100644 --- a/engines/twine/scene/animations.cpp +++ b/engines/twine/scene/animations.cpp @@ -466,10 +466,10 @@ void Animations::processActorAnimations(int32 actorIdx) { return; } - IVec3 &previousActor = _engine->_movements->_previousActor; + IVec3 &previousActor = actor->_previousActor; previousActor = actor->_collisionPos; - IVec3 &processActor = _engine->_movements->_processActor; + IVec3 &processActor = actor->_processActor; if (actor->_staticFlags.bIsSpriteActor) { if (actor->_strengthOfHit) { actor->_dynamicFlags.bIsHitting = 1; @@ -488,11 +488,11 @@ void Animations::processActorAnimations(int32 actorIdx) { } } - IVec3 destPos = _engine->_movements->rotateActor(xAxisRotation, 0, actor->_spriteActorRotation); + const IVec3 xRotPos = _engine->_movements->rotateActor(xAxisRotation, 0, actor->_spriteActorRotation); - processActor.y = actor->_pos.y - destPos.z; + processActor.y = actor->_pos.y - xRotPos.z; - destPos = _engine->_movements->rotateActor(0, destPos.x, actor->_angle); + const IVec3 destPos = _engine->_movements->rotateActor(0, xRotPos.x, actor->_angle); processActor.x = actor->_pos.x + destPos.x; processActor.z = actor->_pos.z + destPos.z; @@ -655,7 +655,7 @@ void Animations::processActorAnimations(int32 actorIdx) { if (brickShape == ShapeType::kSolid) { actor->_pos.y = processActor.y = (processActor.y / BRICK_HEIGHT) * BRICK_HEIGHT + BRICK_HEIGHT; // go upper } else { - _engine->_collision->reajustActorPosition(brickShape); + _engine->_collision->reajustActorPosition(processActor, brickShape); } } @@ -673,16 +673,16 @@ void Animations::processActorAnimations(int32 actorIdx) { if (IS_HERO(actorIdx) && !actor->_staticFlags.bComputeLowCollision) { // check hero collisions with bricks - _engine->_collision->checkHeroCollisionWithBricks(actor->_boudingBox.mins.x, actor->_boudingBox.mins.y, actor->_boudingBox.mins.z, 1); - _engine->_collision->checkHeroCollisionWithBricks(actor->_boudingBox.maxs.x, actor->_boudingBox.mins.y, actor->_boudingBox.mins.z, 2); - _engine->_collision->checkHeroCollisionWithBricks(actor->_boudingBox.maxs.x, actor->_boudingBox.mins.y, actor->_boudingBox.maxs.z, 4); - _engine->_collision->checkHeroCollisionWithBricks(actor->_boudingBox.mins.x, actor->_boudingBox.mins.y, actor->_boudingBox.maxs.z, 8); + _engine->_collision->checkHeroCollisionWithBricks(actor, actor->_boudingBox.mins.x, actor->_boudingBox.mins.y, actor->_boudingBox.mins.z, 1); + _engine->_collision->checkHeroCollisionWithBricks(actor, actor->_boudingBox.maxs.x, actor->_boudingBox.mins.y, actor->_boudingBox.mins.z, 2); + _engine->_collision->checkHeroCollisionWithBricks(actor, actor->_boudingBox.maxs.x, actor->_boudingBox.mins.y, actor->_boudingBox.maxs.z, 4); + _engine->_collision->checkHeroCollisionWithBricks(actor, actor->_boudingBox.mins.x, actor->_boudingBox.mins.y, actor->_boudingBox.maxs.z, 8); } else { // check other actors collisions with bricks - _engine->_collision->checkActorCollisionWithBricks(actor->_boudingBox.mins.x, actor->_boudingBox.mins.y, actor->_boudingBox.mins.z, 1); - _engine->_collision->checkActorCollisionWithBricks(actor->_boudingBox.maxs.x, actor->_boudingBox.mins.y, actor->_boudingBox.mins.z, 2); - _engine->_collision->checkActorCollisionWithBricks(actor->_boudingBox.maxs.x, actor->_boudingBox.mins.y, actor->_boudingBox.maxs.z, 4); - _engine->_collision->checkActorCollisionWithBricks(actor->_boudingBox.mins.x, actor->_boudingBox.mins.y, actor->_boudingBox.maxs.z, 8); + _engine->_collision->checkActorCollisionWithBricks(actor, actor->_boudingBox.mins.x, actor->_boudingBox.mins.y, actor->_boudingBox.mins.z, 1); + _engine->_collision->checkActorCollisionWithBricks(actor, actor->_boudingBox.maxs.x, actor->_boudingBox.mins.y, actor->_boudingBox.mins.z, 2); + _engine->_collision->checkActorCollisionWithBricks(actor, actor->_boudingBox.maxs.x, actor->_boudingBox.mins.y, actor->_boudingBox.maxs.z, 4); + _engine->_collision->checkActorCollisionWithBricks(actor, actor->_boudingBox.mins.x, actor->_boudingBox.mins.y, actor->_boudingBox.maxs.z, 8); } processActor = processActorSave; @@ -739,7 +739,7 @@ void Animations::processActorAnimations(int32 actorIdx) { _engine->_collision->stopFalling(); } - _engine->_collision->reajustActorPosition(brickShape); + _engine->_collision->reajustActorPosition(processActor, brickShape); } actor->_dynamicFlags.bIsFalling = 0; @@ -752,7 +752,7 @@ void Animations::processActorAnimations(int32 actorIdx) { _engine->_collision->stopFalling(); } - _engine->_collision->reajustActorPosition(brickShape); + _engine->_collision->reajustActorPosition(processActor, brickShape); } else { if (!actor->_dynamicFlags.bIsRotationByAnim) { actor->_dynamicFlags.bIsFalling = 1; diff --git a/engines/twine/scene/collision.cpp b/engines/twine/scene/collision.cpp index 4d64615a989b..af684945614b 100644 --- a/engines/twine/scene/collision.cpp +++ b/engines/twine/scene/collision.cpp @@ -44,7 +44,7 @@ bool Collision::standingOnActor(int32 actorIdx1, int32 actorIdx2) const { const ActorStruct *actor1 = _engine->_scene->getActor(actorIdx1); const ActorStruct *actor2 = _engine->_scene->getActor(actorIdx2); - const IVec3 &processActor = _engine->_movements->_processActor; + const IVec3 &processActor = actor1->_processActor; const IVec3 &mins1 = processActor + actor1->_boudingBox.mins; const IVec3 &maxs1 = processActor + actor1->_boudingBox.maxs; @@ -94,7 +94,7 @@ int32 Collision::getAverageValue(int32 start, int32 end, int32 maxDelay, int32 d return (((end - start) * delay) / maxDelay) + start; } -void Collision::reajustActorPosition(ShapeType brickShape) { +void Collision::reajustActorPosition(IVec3 &processActor, ShapeType brickShape) const { if (brickShape == ShapeType::kNone) { return; } @@ -103,8 +103,6 @@ void Collision::reajustActorPosition(ShapeType brickShape) { const int32 brkY = _collision.y * BRICK_HEIGHT; const int32 brkZ = (_collision.z * BRICK_SIZE) - BRICK_HEIGHT; - IVec3 &processActor = _engine->_movements->_processActor; - // double-side stairs switch (brickShape) { case ShapeType::kDoubleSideStairsTop1: @@ -185,9 +183,9 @@ void Collision::reajustActorPosition(ShapeType brickShape) { } } -void Collision::handlePushing(const IVec3 &minsTest, const IVec3 &maxsTest, const ActorStruct *actor, ActorStruct *actorTest) { - IVec3 &processActor = _engine->_movements->_processActor; - const IVec3 &previousActor = _engine->_movements->_previousActor; +void Collision::handlePushing(const IVec3 &minsTest, const IVec3 &maxsTest, ActorStruct *actor, ActorStruct *actorTest) { + IVec3 &processActor = actor->_processActor; + const IVec3 &previousActor = actor->_previousActor; const int32 newAngle = _engine->_movements->getAngleAndSetTargetActorDistance(processActor, actorTest->pos()); @@ -235,7 +233,7 @@ void Collision::handlePushing(const IVec3 &minsTest, const IVec3 &maxsTest, cons int32 Collision::checkCollisionWithActors(int32 actorIdx) { ActorStruct *actor = _engine->_scene->getActor(actorIdx); - IVec3 &processActor = _engine->_movements->_processActor; + IVec3 &processActor = actor->_processActor; IVec3 mins = processActor + actor->_boudingBox.mins; IVec3 maxs = processActor + actor->_boudingBox.maxs; @@ -294,9 +292,9 @@ int32 Collision::checkCollisionWithActors(int32 actorIdx) { return actor->_collision; } -void Collision::checkHeroCollisionWithBricks(int32 x, int32 y, int32 z, int32 damageMask) { - IVec3 &processActor = _engine->_movements->_processActor; - IVec3 &previousActor = _engine->_movements->_previousActor; +void Collision::checkHeroCollisionWithBricks(ActorStruct *actor, int32 x, int32 y, int32 z, int32 damageMask) { + IVec3 &processActor = actor->_processActor; + IVec3 &previousActor = actor->_previousActor; ShapeType brickShape = _engine->_grid->getBrickShape(processActor); processActor.x += x; @@ -305,7 +303,7 @@ void Collision::checkHeroCollisionWithBricks(int32 x, int32 y, int32 z, int32 da if (processActor.x >= 0 && processActor.z >= 0 && processActor.x <= SCENE_SIZE_MAX && processActor.z <= SCENE_SIZE_MAX) { const BoundingBox &bbox = _engine->_actor->_processActorPtr->_boudingBox; - reajustActorPosition(brickShape); + reajustActorPosition(processActor, brickShape); brickShape = _engine->_grid->getBrickShapeFull(processActor, bbox.maxs.y); if (brickShape == ShapeType::kSolid) { @@ -327,9 +325,9 @@ void Collision::checkHeroCollisionWithBricks(int32 x, int32 y, int32 z, int32 da processActor = _processCollision; } -void Collision::checkActorCollisionWithBricks(int32 x, int32 y, int32 z, int32 damageMask) { - IVec3 &processActor = _engine->_movements->_processActor; - IVec3 &previousActor = _engine->_movements->_previousActor; +void Collision::checkActorCollisionWithBricks(ActorStruct *actor, int32 x, int32 y, int32 z, int32 damageMask) { + IVec3 &processActor = actor->_processActor; + IVec3 &previousActor = actor->_previousActor; ShapeType brickShape = _engine->_grid->getBrickShape(processActor); processActor.x += x; @@ -337,7 +335,7 @@ void Collision::checkActorCollisionWithBricks(int32 x, int32 y, int32 z, int32 d processActor.z += z; if (processActor.x >= 0 && processActor.z >= 0 && processActor.x <= SCENE_SIZE_MAX && processActor.z <= SCENE_SIZE_MAX) { - reajustActorPosition(brickShape); + reajustActorPosition(processActor, brickShape); brickShape = _engine->_grid->getBrickShape(processActor); if (brickShape == ShapeType::kSolid) { @@ -361,7 +359,7 @@ void Collision::checkActorCollisionWithBricks(int32 x, int32 y, int32 z, int32 d void Collision::stopFalling() { // ReceptionObj() if (IS_HERO(_engine->_animations->_currentlyProcessedActorIdx)) { - const IVec3 &processActor = _engine->_movements->_processActor; + const IVec3 &processActor = _engine->_actor->_processActorPtr->_processActor; const int32 fall = _engine->_scene->_startYFalling - processActor.y; if (fall >= BRICK_HEIGHT * 8) { diff --git a/engines/twine/scene/collision.h b/engines/twine/scene/collision.h index 0c15ca494b37..206d27f35681 100644 --- a/engines/twine/scene/collision.h +++ b/engines/twine/scene/collision.h @@ -35,7 +35,7 @@ class Collision { private: TwinEEngine *_engine; - void handlePushing(const IVec3 &minsTest, const IVec3 &maxsTest, const ActorStruct *actor, ActorStruct *actorTest); + void handlePushing(const IVec3 &minsTest, const IVec3 &maxsTest, ActorStruct *actor, ActorStruct *actorTest); public: Collision(TwinEEngine *engine); /** Actor collision coordinate */ @@ -60,7 +60,7 @@ class Collision { * Reajust actor position in scene according with brick shape bellow actor * @param brickShape Shape of brick bellow the actor */ - void reajustActorPosition(ShapeType brickShape); + void reajustActorPosition(IVec3 &processActor, ShapeType brickShape) const; /** * Check collision with actors @@ -75,7 +75,7 @@ class Collision { * @param z Hero Z coordinate * @param damageMask Cause damage mask */ - void checkHeroCollisionWithBricks(int32 x, int32 y, int32 z, int32 damageMask); + void checkHeroCollisionWithBricks(ActorStruct *actor, int32 x, int32 y, int32 z, int32 damageMask); /** * Check other actor collision with bricks @@ -84,7 +84,7 @@ class Collision { * @param z Actor Z coordinate * @param damageMask Cause damage mask */ - void checkActorCollisionWithBricks(int32 x, int32 y, int32 z, int32 damageMask); + void checkActorCollisionWithBricks(ActorStruct *actor, int32 x, int32 y, int32 z, int32 damageMask); /** Make actor to stop falling */ void stopFalling(); diff --git a/engines/twine/scene/movements.cpp b/engines/twine/scene/movements.cpp index acf9d3982261..ef4eb9837405 100644 --- a/engines/twine/scene/movements.cpp +++ b/engines/twine/scene/movements.cpp @@ -37,10 +37,11 @@ namespace TwinE { Movements::Movements(TwinEEngine *engine) : _engine(engine) {} -void Movements::getShadowPosition(const IVec3 &pos) { - const uint8 *ptr = _engine->_grid->getBlockBufferGround(pos, _processActor.y); - _processActor.x = pos.x; - _processActor.z = pos.z; +IVec3 Movements::getShadowPosition(const IVec3 &pos) { + IVec3 shadowCoord; + const uint8 *ptr = _engine->_grid->getBlockBufferGround(pos, shadowCoord.y); + shadowCoord.x = pos.x; + shadowCoord.z = pos.z; ShapeType shadowCollisionType; const int32 blockIdx = *ptr; @@ -51,9 +52,8 @@ void Movements::getShadowPosition(const IVec3 &pos) { } else { shadowCollisionType = ShapeType::kNone; } - _engine->_collision->reajustActorPosition(shadowCollisionType); - - _engine->_actor->_shadowCoord = _processActor; + _engine->_collision->reajustActorPosition(shadowCoord, shadowCollisionType); + return shadowCoord; } void Movements::setActorAngleSafe(int16 startAngle, int16 endAngle, int16 stepAngle, ActorMoveStruct *movePtr) { diff --git a/engines/twine/scene/movements.h b/engines/twine/scene/movements.h index 5b56280bb7d8..363c21c94979 100644 --- a/engines/twine/scene/movements.h +++ b/engines/twine/scene/movements.h @@ -127,19 +127,13 @@ class Movements { bool _lastJoyFlag = false; - /** Process actor coordinate */ - IVec3 _processActor; - - /** Previous process actor coordinate */ - IVec3 _previousActor; - int32 _targetActorDistance = 0; /** * Get shadow position * @param pos Shadow coordinates */ - void getShadowPosition(const IVec3 &pos); + IVec3 getShadowPosition(const IVec3 &pos); /** * Set actor safe angle diff --git a/engines/twine/scene/scene.cpp b/engines/twine/scene/scene.cpp index a4b0857b2d31..890e1182940b 100644 --- a/engines/twine/scene/scene.cpp +++ b/engines/twine/scene/scene.cpp @@ -770,8 +770,8 @@ void Scene::processActorZones(int32 actorIdx) { case ZoneType::kLadder: if (IS_HERO(actorIdx) && _engine->_actor->_heroBehaviour != HeroBehaviourType::kProtoPack && (actor->_anim == AnimationTypes::kForward || actor->_anim == AnimationTypes::kTopLadder || actor->_anim == AnimationTypes::kClimbLadder)) { IVec3 destPos = _engine->_movements->rotateActor(actor->_boudingBox.mins.x, actor->_boudingBox.mins.z, actor->_angle + ANGLE_360 + ANGLE_135); - destPos.x += _engine->_movements->_processActor.x; - destPos.z += _engine->_movements->_processActor.z; + destPos.x += actor->_processActor.x; + destPos.z += actor->_processActor.z; if (destPos.x >= 0 && destPos.z >= 0 && destPos.x <= SCENE_SIZE_MAX && destPos.z <= SCENE_SIZE_MAX) { if (_engine->_grid->getBrickShape(destPos.x, actor->_pos.y + BRICK_HEIGHT, destPos.z) != ShapeType::kNone) {