[Scummvm-git-logs] scummvm master -> ad01f082649137f755b287854764556410f98b50
mduggan
mgithub at guarana.org
Fri Jan 8 09:20:06 UTC 2021
This automated email contains information about 9 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
fedc73f9f2 ULTIMA8: Add more anims to crusdaer table. Fix z-values for Crusader anims
27c35abb44 ULTIMA8: Fix many small Cruader movement issues
ac6c4add3a ULTIMA8: Avoid wait/wake-up tight loops in attack process
7542d278a6 ULTIMA8: Call hit usecode multiple times in Crusader
b4e50e21ef ULTIMA8: Hold last Crusader target reticle frame
ff910b0d91 ULTIMA8: Tone down Crusader splash damage
5d7b662538 ULTIMA8: Don't update fast area when getting item location
bd00ab28a0 ULTIMA8: Avoid corner-case of Crusader mover failing
ad01f08264 ULTIMA8: More tweaks for Crusader mover to bring closer to original
Commit: fedc73f9f27531bb1ab71ac9e9a9c8757781796d
https://github.com/scummvm/scummvm/commit/fedc73f9f27531bb1ab71ac9e9a9c8757781796d
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-01-08T18:18:37+09:00
Commit Message:
ULTIMA8: Add more anims to crusdaer table. Fix z-values for Crusader anims
Changed paths:
engines/ultima/ultima8/graphics/anim_dat.cpp
diff --git a/engines/ultima/ultima8/graphics/anim_dat.cpp b/engines/ultima/ultima8/graphics/anim_dat.cpp
index d05e5be74b..57bc81fb68 100644
--- a/engines/ultima/ultima8/graphics/anim_dat.cpp
+++ b/engines/ultima/ultima8/graphics/anim_dat.cpp
@@ -137,6 +137,10 @@ uint32 AnimDat::getActionNumberForSequence(Animation::Sequence action, const Act
return 0;
case Animation::lookRight:
return 0;
+ case Animation::jump:
+ return 58; // 58 is a shorter jump?
+ case Animation::startRunWithLargeWeapon:
+ return (smallwpn ? 34 : 35);
default:
return action_int;
}
@@ -238,7 +242,7 @@ void AnimDat::load(Common::SeekableReadStream *rs) {
const uint8 x = rs->readByte();
f._frame += (x & 0xF) << 8;
// byte 2: delta z
- f._deltaZ = rs->readByte();
+ f._deltaZ = rs->readSByte();
// byte 3: sfx
f._sfx = rs->readByte();
// byte 4: deltadir (signed) - convert to pixels
Commit: 27c35abb4442a73ada2c7248167394e84b92b604
https://github.com/scummvm/scummvm/commit/27c35abb4442a73ada2c7248167394e84b92b604
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-01-08T18:18:37+09:00
Commit Message:
ULTIMA8: Fix many small Cruader movement issues
Changed paths:
engines/ultima/ultima8/world/actors/actor.cpp
engines/ultima/ultima8/world/actors/actor.h
engines/ultima/ultima8/world/actors/animation.cpp
engines/ultima/ultima8/world/actors/animation.h
engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
engines/ultima/ultima8/world/actors/main_actor.cpp
engines/ultima/ultima8/world/current_map.cpp
engines/ultima/ultima8/world/item.cpp
engines/ultima/ultima8/world/item.h
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index 33025ed4b3..63a5c81ae3 100644
--- a/engines/ultima/ultima8/world/actors/actor.cpp
+++ b/engines/ultima/ultima8/world/actors/actor.cpp
@@ -487,15 +487,20 @@ uint16 Actor::doAnim(Animation::Sequence anim, Direction dir, unsigned int steps
// Small hack: When switching from 16-dir to 8-dir, fix the direction
if (animDirMode(anim) == dirmode_8dirs)
dir = static_cast<Direction>(dir - (static_cast<uint32>(dir) % 2));
- else if (anim == Animation::readyWeapon)
+
+ if (anim == Animation::readyWeapon || anim == Animation::stopRunningAndDrawWeapon ||
+ anim == Animation::combatStand || anim == Animation::attack || anim == Animation::kneel ||
+ anim == Animation::kneelAndFire)
setActorFlag(ACT_WEAPONREADY);
- else if (anim == Animation::unreadyWeapon)
+ else
clearActorFlag(ACT_WEAPONREADY);
- else if (anim == Animation::startKneeling || anim == Animation::kneelAndFire ||
- anim == Animation::kneelAndFireSmallWeapon ||
- anim == Animation::kneelAndFireLargeWeapon)
+
+ if (anim == Animation::startKneeling || anim == Animation::kneelAndFire ||
+ anim == Animation::kneelAndFireSmallWeapon ||
+ anim == Animation::kneelAndFireLargeWeapon ||
+ anim == Animation::kneel)
setActorFlag(ACT_KNEELING);
- else if (anim == Animation::stopKneeling)
+ else
clearActorFlag(ACT_KNEELING);
}
@@ -2387,7 +2392,7 @@ uint32 Actor::I_isKneeling(const uint8 *args, unsigned int /*argsize*/) {
ARG_ACTOR_FROM_PTR(actor);
if (!actor) return 0;
- return actor->hasFlags(ACT_KNEELING) ? 1 : 0;
+ return actor->isKneeling() ? 1 : 0;
}
} // End of namespace Ultima8
diff --git a/engines/ultima/ultima8/world/actors/actor.h b/engines/ultima/ultima8/world/actors/actor.h
index 7358e69c34..868c20e65d 100644
--- a/engines/ultima/ultima8/world/actors/actor.h
+++ b/engines/ultima/ultima8/world/actors/actor.h
@@ -84,6 +84,10 @@ public:
return (_actorFlags & ACT_INCOMBAT) != 0;
}
+ bool isKneeling() const {
+ return (_actorFlags & ACT_KNEELING) != 0;
+ }
+
CombatProcess *getCombatProcess(); // in U8
AttackProcess *getAttackProcess(); // in Crusader
virtual void setInCombat(int activity);
diff --git a/engines/ultima/ultima8/world/actors/animation.cpp b/engines/ultima/ultima8/world/actors/animation.cpp
index bb26236237..e7b0da2a2a 100644
--- a/engines/ultima/ultima8/world/actors/animation.cpp
+++ b/engines/ultima/ultima8/world/actors/animation.cpp
@@ -60,12 +60,18 @@ bool isCombatAnimCru(const Sequence anim) {
case attack:
case kick:
case kneel:
- case kneelStart:
+ case startKneeling:
+ case stopKneeling:
+ case kneelAndFire:
case fire2:
case combatRollLeft:
case combatRollRight:
case slideLeft:
case slideRight:
+ case startRun:
+ case startRunWithLargeWeapon:
+ case run:
+ case stopRunningAndDrawWeapon:
return true;
default:
return false;
diff --git a/engines/ultima/ultima8/world/actors/animation.h b/engines/ultima/ultima8/world/actors/animation.h
index 84c6d3ab36..dea6764120 100644
--- a/engines/ultima/ultima8/world/actors/animation.h
+++ b/engines/ultima/ultima8/world/actors/animation.h
@@ -112,8 +112,8 @@ enum Sequence {
halfStep = 37,
startRun = 38,
stopRunningAndDrawWeapon = 39,
- kneelStart = 40,
- kneelEnd = 41,
+ kneelStartCru = 40,
+ kneelEndCru = 41,
kneelAndFireSmallWeapon = 42,
kneelAndFireLargeWeapon = 43,
advanceWithLargeWeapon = 44,
diff --git a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
index a9c8aecaa2..c4117e71d9 100644
--- a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
+++ b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
@@ -106,23 +106,26 @@ void CruAvatarMoverProcess::handleCombatMode() {
} else if (hasMovementFlags(MOVE_FORWARD)) {
Animation::Sequence nextanim;
if (hasMovementFlags(MOVE_STEP)) {
- nextanim = avatar->hasActorFlags(Actor::ACT_KNEELING) ?
+ nextanim = avatar->isKneeling() ?
Animation::kneelingAdvance : Animation::advance;
} else if (hasMovementFlags(MOVE_RUN)) {
// Take a step before running
- avatar->toggleInCombat();
- if (lastanim != Animation::startRun)
- nextanim = Animation::startRun;
+ if (lastanim != Animation::startRunWithLargeWeapon && lastanim != Animation::run)
+ nextanim = Animation::startRunWithLargeWeapon;
else
nextanim = Animation::run;
} else if (hasMovementFlags(MOVE_JUMP)) {
- avatar->toggleInCombat();
- nextanim = Animation::jumpForward;
- } else if (avatar->hasActorFlags(Actor::ACT_KNEELING)) {
+ if (lastanim == Animation::walk || lastanim == Animation::run)
+ nextanim = Animation::jumpForward;
+ else
+ nextanim = Animation::jump;
+ // Jump always ends out of combat
+ avatar->clearInCombat();
+ } else if (avatar->isKneeling()) {
nextanim = Animation::stopKneeling;
avatar->clearActorFlag(Actor::ACT_KNEELING);
} else {
- // moving from combat stows weapon
+ // moving forward from combat stows weapon
nextanim = Animation::walk;
avatar->toggleInCombat();
}
@@ -133,30 +136,43 @@ void CruAvatarMoverProcess::handleCombatMode() {
} else if (hasMovementFlags(MOVE_BACK)) {
Animation::Sequence nextanim;
if (hasMovementFlags(MOVE_JUMP)) {
- nextanim = Animation::startKneeling;
- avatar->setActorFlag(Actor::ACT_KNEELING);
+ if (!avatar->isKneeling()) {
+ nextanim = Animation::startKneeling;
+ avatar->setActorFlag(Actor::ACT_KNEELING);
+ } else {
+ // Do nothing if already kneeling
+ return;
+ }
} else {
- nextanim = avatar->hasActorFlags(Actor::ACT_KNEELING) ?
- Animation::kneelingRetreat : Animation::retreat;
+ nextanim = Animation::retreat;
}
waitFor(avatar->doAnim(nextanim, direction));
return;
} else if (hasMovementFlags(MOVE_STEP)) {
- if (hasMovementFlags(MOVE_TURN_LEFT)) {
- avatar->doAnim(Animation::slideLeft, direction);
- return;
- } else if (hasMovementFlags(MOVE_TURN_RIGHT)) {
- avatar->doAnim(Animation::slideRight, direction);
+ if (avatar->isKneeling()) {
+ avatar->doAnim(Animation::stopKneeling, direction);
return;
+ } else {
+ if (hasMovementFlags(MOVE_TURN_LEFT)) {
+ avatar->doAnim(Animation::slideLeft, direction);
+ return;
+ } else if (hasMovementFlags(MOVE_TURN_RIGHT)) {
+ avatar->doAnim(Animation::slideRight, direction);
+ return;
+ }
}
} else if (hasMovementFlags(MOVE_JUMP)) {
if (hasMovementFlags(MOVE_TURN_LEFT)) {
- //direction = Direction_TurnByDelta(direction, 4, dirmode_16dirs);
- avatar->doAnim(Animation::combatRollLeft, direction);
+ if (avatar->isKneeling())
+ avatar->doAnim(Animation::slowCombatRollLeft, direction);
+ else
+ avatar->doAnim(Animation::combatRollLeft, direction);
return;
} else if (hasMovementFlags(MOVE_TURN_RIGHT)) {
- //direction = Direction_TurnByDelta(direction, -4, dirmode_16dirs);
- avatar->doAnim(Animation::combatRollRight, direction);
+ if (avatar->isKneeling())
+ avatar->doAnim(Animation::slowCombatRollRight, direction);
+ else
+ avatar->doAnim(Animation::combatRollRight, direction);
return;
}
}
@@ -170,19 +186,18 @@ void CruAvatarMoverProcess::handleCombatMode() {
return;
Animation::Sequence nextanim = Animation::combatStand;
- if (lastanim == Animation::run) {
- // want to run while in combat mode?
- // first sheath weapon
- nextanim = Animation::readyWeapon;
- } else if (Direction_Invert(direction) == nextdir) {
+ if (lastanim == Animation::run && !hasMovementFlags(MOVE_RUN)) {
+ // want to go back to combat mode from run
+ nextanim = Animation::stopRunningAndDrawWeapon;
+ } else if (hasMovementFlags(MOVE_BACK)) {
nextanim = Animation::retreat;
- nextdir = direction;
+ nextdir = Direction_Invert(direction);
}
if (hasMovementFlags(MOVE_RUN)) {
- // Take a step before running
- nextanim = Animation::startRun;
- avatar->toggleInCombat();
+ // Take a step before running. Don't clear combat mode in Cruasder
+ // - running always finishes with drawing weapon
+ nextanim = Animation::run;
}
nextanim = Animation::checkWeapon(nextanim, lastanim);
@@ -190,7 +205,7 @@ void CruAvatarMoverProcess::handleCombatMode() {
return;
}
- Animation::Sequence idleanim = avatar->hasActorFlags(Actor::ACT_KNEELING) ?
+ Animation::Sequence idleanim = avatar->isKneeling() ?
Animation::kneel : Animation::combatStand;
if (curdir != direction) {
@@ -214,6 +229,14 @@ void CruAvatarMoverProcess::handleNormalMode() {
Direction direction = avatar->getDir();
const bool stasis = Ultima8Engine::get_instance()->isAvatarInStasis();
+ if (hasMovementFlags(MOVE_STEP | MOVE_JUMP) && hasMovementFlags(MOVE_ANY_DIRECTION | MOVE_TURN_LEFT | MOVE_TURN_RIGHT)) {
+ // All jump and step movements in crusader are handled identically
+ // whether starting from combat mode or not.
+ avatar->setInCombat(0);
+ handleCombatMode();
+ return;
+ }
+
// Store current idle time. (Also see end of function.)
uint32 currentIdleTime = _idleTime;
_idleTime = 0;
@@ -231,16 +254,12 @@ void CruAvatarMoverProcess::handleNormalMode() {
if (standUpIfNeeded(direction))
return;
- // If still in combat stance, sheathe weapon
- if (!stasis && Animation::isCombatAnimU8(lastanim)) {
- putAwayWeapon(direction);
- return;
- }
-
if (!hasMovementFlags(MOVE_ANY_DIRECTION) && lastanim == Animation::run) {
// if we were running, slow to a walk before stopping
// (even in stasis)
- slowFromRun(direction);
+ waitFor(avatar->doAnim(Animation::stopRunningAndDrawWeapon, direction));
+ avatar->setInCombat(0);
+ avatar->clearActorFlag(Actor::ACT_COMBATRUN);
return;
}
@@ -248,13 +267,6 @@ void CruAvatarMoverProcess::handleNormalMode() {
if (stasis)
return;
- if (hasMovementFlags(MOVE_JUMP) && hasMovementFlags(MOVE_FORWARD)) {
- Animation::Sequence nextanim = Animation::jump;
- nextanim = Animation::checkWeapon(nextanim, lastanim);
- waitFor(avatar->doAnim(nextanim, direction));
- return;
- }
-
bool moving = (lastanim == Animation::step || lastanim == Animation::run || lastanim == Animation::walk);
DirectionMode dirmode = avatar->animDirMode(Animation::step);
@@ -266,15 +278,19 @@ void CruAvatarMoverProcess::handleNormalMode() {
Animation::Sequence nextanim = Animation::walk;
- if (hasMovementFlags(MOVE_STEP)) {
- nextanim = Animation::step;
- } else if (hasMovementFlags(MOVE_RUN)) {
+ if (hasMovementFlags(MOVE_RUN)) {
if (lastanim == Animation::run
- || lastanim == Animation::runningJump
- || lastanim == Animation::walk)
+ || lastanim == Animation::startRun
+ || lastanim == Animation::startRunWithLargeWeapon
+ || lastanim == Animation::walk) {
+ // keep running
nextanim = Animation::run;
- else
- nextanim = Animation::walk;
+ avatar->setActorFlag(Actor::ACT_COMBATRUN);
+ } else {
+ // start running
+ nextanim = Animation::startRun;
+ avatar->setActorFlag(Actor::ACT_COMBATRUN);
+ }
}
if (hasMovementFlags(MOVE_FORWARD)) {
@@ -283,10 +299,8 @@ void CruAvatarMoverProcess::handleNormalMode() {
}
if (hasMovementFlags(MOVE_BACK)) {
- step(nextanim, Direction_Invert(direction));
-
- // flip to move forward once turned
- setMovementFlag(MOVE_FORWARD);
+ avatar->toggleInCombat();
+ step(Animation::retreat, direction);
return;
}
@@ -306,12 +320,6 @@ void CruAvatarMoverProcess::handleNormalMode() {
if (Kernel::get_instance()->getNumProcesses(1, ActorAnimProcess::ACTOR_ANIM_PROC_TYPE))
return;
- // if we were running, slow to a walk before stopping
- if (lastanim == Animation::run) {
- waitFor(avatar->doAnim(Animation::walk, direction));
- return;
- }
-
// not doing anything in particular? stand
if (lastanim != Animation::stand && currentIdleTime == 0) {
waitFor(avatar->doAnim(Animation::stand, direction));
@@ -325,13 +333,12 @@ void CruAvatarMoverProcess::handleNormalMode() {
void CruAvatarMoverProcess::step(Animation::Sequence action, Direction direction,
bool adjusted) {
MainActor *avatar = getMainActor();
- Animation::Sequence lastanim = avatar->getLastAnim();
Animation::Result res = avatar->tryAnim(action, direction);
if (res != Animation::SUCCESS) {
World *world = World::get_instance();
- CurrentMap *currentmap = world->getCurrentMap();
+ const CurrentMap *currentmap = world->getCurrentMap();
// Search right/left gradually increasing distance to see if we can make the move work.
@@ -378,7 +385,6 @@ void CruAvatarMoverProcess::step(Animation::Sequence action, Direction direction
return;
debug(6, "Cru avatar step: picked action %d dir %d (test result %d)", action, direction, res);
- action = Animation::checkWeapon(action, lastanim);
waitFor(avatar->doAnim(action, direction));
}
@@ -397,7 +403,9 @@ void CruAvatarMoverProcess::tryAttack() {
} else {
if (canAttack()) {
// Fire event happens from animation
- waitFor(avatar->doAnim(Animation::attack, dir));
+ Animation::Sequence fireanim = (avatar->isKneeling() ?
+ Animation::kneelAndFire : Animation::attack);
+ waitFor(avatar->doAnim(fireanim, dir));
}
}
}
diff --git a/engines/ultima/ultima8/world/actors/main_actor.cpp b/engines/ultima/ultima8/world/actors/main_actor.cpp
index d97a3adc16..cfc8796799 100644
--- a/engines/ultima/ultima8/world/actors/main_actor.cpp
+++ b/engines/ultima/ultima8/world/actors/main_actor.cpp
@@ -689,7 +689,7 @@ void MainActor::nextInvItem() {
void MainActor::addFireAnimOffsets(int32 &x, int32 &y, int32 &z) {
assert(GAME_IS_CRUSADER);
- Animation::Sequence fireanim = (hasActorFlags(ACT_KNEELING) ? Animation::kneelAndFire : Animation::attack);
+ Animation::Sequence fireanim = (isKneeling() ? Animation::kneelAndFire : Animation::attack);
uint32 actionno = AnimDat::getActionNumberForSequence(fireanim, this);
Direction dir = getDir();
diff --git a/engines/ultima/ultima8/world/current_map.cpp b/engines/ultima/ultima8/world/current_map.cpp
index 5f27a6a7f8..945db6d2e2 100644
--- a/engines/ultima/ultima8/world/current_map.cpp
+++ b/engines/ultima/ultima8/world/current_map.cpp
@@ -343,7 +343,7 @@ Item *CurrentMap::findBestTargetItem(int32 x, int32 y, Direction dir, DirectionM
continue;
const Actor *actor = dynamic_cast<const Actor *>(item);
- if ((bestisoccl && !isoccl) || (bestisnpc && !actor) || !item->isOnScreen())
+ if ((bestisoccl && !isoccl) || (bestisnpc && !actor) || !item->isPartlyOnScreen())
continue;
int xdiff = abs(x - ix);
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index 5241c909eb..6bd94628b0 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -616,6 +616,28 @@ bool Item::isOnScreen() const {
return false;
}
+bool Item::isPartlyOnScreen() const {
+ GameMapGump *game_map = Ultima8Engine::get_instance()->getGameMapGump();
+
+ if (!game_map)
+ return false;
+
+ Rect game_map_dims;
+ int32 screenx = -1;
+ int32 screeny = -1;
+ game_map->GetLocationOfItem(_objId, screenx, screeny);
+ game_map->GetDims(game_map_dims);
+ int32 xd, yd, zd;
+ getFootpadWorld(xd, yd, zd);
+
+ if (game_map_dims.contains(screenx, screeny) ||
+ game_map_dims.contains(screenx + xd, screeny + yd)) {
+ return true;
+ }
+
+ return false;
+}
+
bool Item::canExistAt(int32 x, int32 y, int32 z, bool needsupport) const {
CurrentMap *cm = World::get_instance()->getCurrentMap();
const Item *support;
@@ -1302,7 +1324,7 @@ uint16 Item::fireDistance(Item *other, Direction dir, int16 xoff, int16 yoff, in
Actor *a = dynamic_cast<Actor *>(this);
if (a) {
Animation::Sequence anim;
- bool kneeling = a->hasActorFlags(Actor::ACT_KNEELING);
+ bool kneeling = a->isKneeling();
bool smallwpn = true;
MainActor *ma = dynamic_cast<MainActor *>(this);
Item *wpn = getItem(a->getActiveWeapon());
diff --git a/engines/ultima/ultima8/world/item.h b/engines/ultima/ultima8/world/item.h
index 7119a1af1d..2a4a7c3570 100644
--- a/engines/ultima/ultima8/world/item.h
+++ b/engines/ultima/ultima8/world/item.h
@@ -285,9 +285,12 @@ public:
//! Check if the centre of this item is on top of another item
bool isCentreOn(const Item &item2) const;
- //! Check if the item is currently visible on screen
+ //! Check if the item is currently entirely visible on screen
bool isOnScreen() const;
+ //! Check if the item is currently partly visible on screen
+ bool isPartlyOnScreen() const;
+
//! Check if this item can exist at the given coordinates
bool canExistAt(int32 x, int32 y, int32 z, bool needsupport = false) const;
Commit: ac6c4add3a21cb4984198d9e15493c8669e82481
https://github.com/scummvm/scummvm/commit/ac6c4add3a21cb4984198d9e15493c8669e82481
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-01-08T18:18:37+09:00
Commit Message:
ULTIMA8: Avoid wait/wake-up tight loops in attack process
Changed paths:
engines/ultima/ultima8/world/actors/attack_process.cpp
diff --git a/engines/ultima/ultima8/world/actors/attack_process.cpp b/engines/ultima/ultima8/world/actors/attack_process.cpp
index 9a26a4aae1..3bdeb732ee 100644
--- a/engines/ultima/ultima8/world/actors/attack_process.cpp
+++ b/engines/ultima/ultima8/world/actors/attack_process.cpp
@@ -887,6 +887,8 @@ void AttackProcess::setTimer3() {
}
void AttackProcess::sleep(int ticks) {
+ // waiting less than 2 ticks can cause a tight loop
+ ticks = MAX(ticks, 2);
Process *delayProc = new DelayProcess(ticks);
ProcId pid = Kernel::get_instance()->addProcess(delayProc);
waitFor(pid);
Commit: 7542d278a6f4bb3c84d403b7ac76d3f4c139daa4
https://github.com/scummvm/scummvm/commit/7542d278a6f4bb3c84d403b7ac76d3f4c139daa4
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-01-08T18:18:37+09:00
Commit Message:
ULTIMA8: Call hit usecode multiple times in Crusader
Changed paths:
engines/ultima/ultima8/world/item.cpp
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index 6bd94628b0..161a027442 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -1142,8 +1142,11 @@ int32 Item::collideMove(int32 dx, int32 dy, int32 dz, bool teleport, bool force,
uint16 proc_gothit = 0, proc_rel = 0;
// If hitting at start, we should have already
- // called gotHit and hit.
- if ((!it->_touching || it->_touchingFloor) && it->_hitTime >= 0) {
+ // called gotHit and hit. In Crusader we call
+ // hit for every hitting frame to make sickbays
+ // and teleporters work.
+ bool call_hit = it->_hitTime >= 0 || GAME_IS_CRUSADER;
+ if ((!it->_touching || it->_touchingFloor) && call_hit) {
if (_objId == 1 && guiapp->isShowTouchingItems())
item->setExtFlag(Item::EXT_HIGHLIGHT);
@@ -1790,6 +1793,7 @@ void Item::enterFastArea() {
if (actor && GAME_IS_CRUSADER) {
actor->clearLastActivityNo();
actor->clearInCombat();
+ actor->clearActorFlag(Actor::ACT_WEAPONREADY);
}
callUsecodeEvent_enterFastArea();
}
Commit: b4e50e21ef61d5ed6dde1d5c6655e07b03a9cd4f
https://github.com/scummvm/scummvm/commit/b4e50e21ef61d5ed6dde1d5c6655e07b03a9cd4f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-01-08T18:18:37+09:00
Commit Message:
ULTIMA8: Hold last Crusader target reticle frame
Changed paths:
engines/ultima/ultima8/world/target_reticle_process.cpp
engines/ultima/ultima8/world/target_reticle_process.h
diff --git a/engines/ultima/ultima8/world/target_reticle_process.cpp b/engines/ultima/ultima8/world/target_reticle_process.cpp
index 3a686a0436..0b214fe4b9 100644
--- a/engines/ultima/ultima8/world/target_reticle_process.cpp
+++ b/engines/ultima/ultima8/world/target_reticle_process.cpp
@@ -64,14 +64,23 @@ void TargetReticleProcess::run() {
return;
}
+ if (_reticleSpriteProcess && (!spriteProc || spriteProc->is_terminated())) {
+ // The sprite proc has finished but the target is still valid - replace
+ // with one that just holds the last frame.
+ Item *target = getItem(_lastTargetItem);
+ if (target)
+ putTargetReticleOnItem(target, true);
+ }
+
if (frameno - _lastUpdate < 2 * Kernel::FRAMES_PER_SECOND) {
return;
}
bool changed = findTargetItem();
- if (spriteProc && changed)
+ if (spriteProc && changed) {
// Terminate the old process.
spriteProc->terminate();
+ }
_lastUpdate = frameno;
}
@@ -94,7 +103,7 @@ bool TargetReticleProcess::findTargetItem() {
Item *lastItem = getItem(_lastTargetItem);
if (lastItem)
lastItem->clearExtFlag(Item::EXT_TARGET);
- putTargetReticleOnItem(item);
+ putTargetReticleOnItem(item, false);
_lastTargetDir = dir;
changed = true;
} else if (!item) {
@@ -115,7 +124,7 @@ void TargetReticleProcess::avatarMoved() {
_lastUpdate = 0;
}
-void TargetReticleProcess::putTargetReticleOnItem(Item *item) {
+void TargetReticleProcess::putTargetReticleOnItem(Item *item, bool last_frame) {
int32 x, y, z;
// TODO: the game does a bunch of other maths here to pick the right location.
@@ -124,7 +133,11 @@ void TargetReticleProcess::putTargetReticleOnItem(Item *item) {
item->getCentre(x, y, z);
z -= 8;
- Process *p = new SpriteProcess(0x59a, 0, 5, 1, 10, x, y, z, false);
+ Process *p;
+ if (!last_frame)
+ p = new SpriteProcess(0x59a, 0, 5, 1, 10, x, y, z, false);
+ else
+ p = new SpriteProcess(0x59a, 5, 5, 1, 1000, x, y, z, false);
_reticleSpriteProcess = Kernel::get_instance()->addProcess(p);
_lastTargetItem = item->getObjId();
@@ -155,6 +168,7 @@ void TargetReticleProcess::itemMoved(Item *item) {
if (spriteproc) {
if (actordir != _lastTargetDir || dirtoitem != _lastTargetDir) {
spriteproc->terminate();
+ _reticleSpriteProcess = 0;
clearSprite();
} else {
spriteproc->move(x, y, z);
diff --git a/engines/ultima/ultima8/world/target_reticle_process.h b/engines/ultima/ultima8/world/target_reticle_process.h
index d16942b282..e7d45590ec 100644
--- a/engines/ultima/ultima8/world/target_reticle_process.h
+++ b/engines/ultima/ultima8/world/target_reticle_process.h
@@ -68,7 +68,7 @@ public:
private:
bool findTargetItem();
- void putTargetReticleOnItem(Item *);
+ void putTargetReticleOnItem(Item *, bool last_frame);
void clearSprite();
bool _reticleEnabled;
Commit: ff910b0d915b94157102361047e1e87556e7de2e
https://github.com/scummvm/scummvm/commit/ff910b0d915b94157102361047e1e87556e7de2e
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-01-08T18:18:37+09:00
Commit Message:
ULTIMA8: Tone down Crusader splash damage
Changed paths:
engines/ultima/ultima8/world/fire_type.cpp
diff --git a/engines/ultima/ultima8/world/fire_type.cpp b/engines/ultima/ultima8/world/fire_type.cpp
index a0c0014bd8..5780a5643f 100644
--- a/engines/ultima/ultima8/world/fire_type.cpp
+++ b/engines/ultima/ultima8/world/fire_type.cpp
@@ -201,7 +201,7 @@ void FireType::applySplashDamageAround(const Point3 &pt, int damage, const Item
Point3 pt2;
splashitem->getLocation(pt2);
int splashrange = pt.maxDistXYZ(pt2);
- splashrange = (splashrange / 32) / 3;
+ splashrange = (splashrange / 16) / 3;
if (splashrange)
splashitemdamage /= splashrange;
}
Commit: 5d7b6625387ff62b1869b4567c1e456c6cc00f98
https://github.com/scummvm/scummvm/commit/5d7b6625387ff62b1869b4567c1e456c6cc00f98
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-01-08T18:18:37+09:00
Commit Message:
ULTIMA8: Don't update fast area when getting item location
Changed paths:
engines/ultima/ultima8/gumps/game_map_gump.cpp
diff --git a/engines/ultima/ultima8/gumps/game_map_gump.cpp b/engines/ultima/ultima8/gumps/game_map_gump.cpp
index ded60fbcd2..1bfc4d13c4 100644
--- a/engines/ultima/ultima8/gumps/game_map_gump.cpp
+++ b/engines/ultima/ultima8/gumps/game_map_gump.cpp
@@ -264,7 +264,7 @@ bool GameMapGump::GetLocationOfItem(uint16 itemid, int32 &gx, int32 &gy,
int32 cx, cy, cz;
CameraProcess *cam = CameraProcess::GetCameraProcess();
if (!cam) CameraProcess::GetCameraLocation(cx, cy, cz);
- else cam->GetLerped(cx, cy, cz, lerp_factor);
+ else cam->GetLerped(cx, cy, cz, lerp_factor, true);
// Screenspace bounding box bottom x coord (RNB x coord)
gx = (ix - iy) / 4;
Commit: bd00ab28a0c7f61268ca70bc195f34742456bba4
https://github.com/scummvm/scummvm/commit/bd00ab28a0c7f61268ca70bc195f34742456bba4
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-01-08T18:18:37+09:00
Commit Message:
ULTIMA8: Avoid corner-case of Crusader mover failing
Changed paths:
engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
diff --git a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
index c4117e71d9..56e57e8762 100644
--- a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
+++ b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
@@ -335,6 +335,7 @@ void CruAvatarMoverProcess::step(Animation::Sequence action, Direction direction
MainActor *avatar = getMainActor();
Animation::Result res = avatar->tryAnim(action, direction);
+ Animation::Result initialres = res;
if (res != Animation::SUCCESS) {
World *world = World::get_instance();
@@ -367,13 +368,16 @@ void CruAvatarMoverProcess::step(Animation::Sequence action, Direction direction
}
if (res != Animation::SUCCESS) {
- // reset location, couldn't move.
+ // reset location and result (in case it's END_OFF_LAND now)
+ // couldn't find a better move.
avatar->setLocation(origpt.x, origpt.y, origpt.z);
+ res = initialres;
}
}
if ((action == Animation::step || action == Animation::advance ||
action == Animation::retreat || action == Animation::run ||
+ action == Animation::startRunWithLargeWeapon ||
action == Animation::startRun || action == Animation::walk)
&& res == Animation::FAILURE) {
action = Animation::stand;
Commit: ad01f082649137f755b287854764556410f98b50
https://github.com/scummvm/scummvm/commit/ad01f082649137f755b287854764556410f98b50
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-01-08T18:18:37+09:00
Commit Message:
ULTIMA8: More tweaks for Crusader mover to bring closer to original
Changed paths:
engines/ultima/ultima8/world/actors/avatar_mover_process.h
engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
engines/ultima/ultima8/world/actors/cru_avatar_mover_process.h
engines/ultima/ultima8/world/actors/u8_avatar_mover_process.cpp
engines/ultima/ultima8/world/actors/u8_avatar_mover_process.h
engines/ultima/ultima8/world/crosshair_process.cpp
diff --git a/engines/ultima/ultima8/world/actors/avatar_mover_process.h b/engines/ultima/ultima8/world/actors/avatar_mover_process.h
index 4c245655f2..96ee244684 100644
--- a/engines/ultima/ultima8/world/actors/avatar_mover_process.h
+++ b/engines/ultima/ultima8/world/actors/avatar_mover_process.h
@@ -89,8 +89,6 @@ protected:
virtual void handleCombatMode() = 0;
virtual void handleNormalMode() = 0;
- virtual bool canAttack() = 0;
-
void turnToDirection(Direction direction);
bool checkTurn(Direction direction, bool moving);
diff --git a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
index 56e57e8762..aef2c65732 100644
--- a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
+++ b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
@@ -57,25 +57,33 @@ void CruAvatarMoverProcess::run() {
const MainActor *avatar = getMainActor();
assert(avatar);
- if (avatar->isInCombat() && !hasMovementFlags(MOVE_FORWARD | MOVE_BACK | MOVE_JUMP | MOVE_STEP)) {
- // See comment on _avatarAngle in header about these constants
- if (hasMovementFlags(MOVE_TURN_LEFT)) {
- if (hasMovementFlags(MOVE_RUN))
- _avatarAngle -= 375;
- else
- _avatarAngle -= 150;
-
- if (_avatarAngle < 0)
- _avatarAngle += 36000;
+ // When not in combat the angle is kept as -1
+ if (avatar->isInCombat()) {
+ if (_avatarAngle < 0) {
+ _avatarAngle = Direction_ToCentidegrees(avatar->getDir());
}
- if (hasMovementFlags(MOVE_TURN_RIGHT)) {
- if (hasMovementFlags(MOVE_RUN))
- _avatarAngle += 375;
- else
- _avatarAngle += 150;
+ if (!hasMovementFlags(MOVE_FORWARD | MOVE_BACK | MOVE_JUMP | MOVE_STEP)) {
+ // See comment on _avatarAngle in header about these constants
+ if (hasMovementFlags(MOVE_TURN_LEFT)) {
+ if (hasMovementFlags(MOVE_RUN))
+ _avatarAngle -= 375;
+ else
+ _avatarAngle -= 150;
+
+ if (_avatarAngle < 0)
+ _avatarAngle += 36000;
+ }
+ if (hasMovementFlags(MOVE_TURN_RIGHT)) {
+ if (hasMovementFlags(MOVE_RUN))
+ _avatarAngle += 375;
+ else
+ _avatarAngle += 150;
- _avatarAngle = _avatarAngle % 36000;
+ _avatarAngle = _avatarAngle % 36000;
+ }
}
+ } else {
+ _avatarAngle = -1;
}
// Now do the regular process
@@ -91,7 +99,7 @@ void CruAvatarMoverProcess::handleHangingMode() {
void CruAvatarMoverProcess::handleCombatMode() {
MainActor *avatar = getMainActor();
const Animation::Sequence lastanim = avatar->getLastAnim();
- Direction direction = Direction_FromCentidegrees(_avatarAngle);
+ Direction direction = (_avatarAngle >= 0 ? Direction_FromCentidegrees(_avatarAngle) : avatar->getDir());
const Direction curdir = avatar->getDir();
const bool stasis = Ultima8Engine::get_instance()->isAvatarInStasis();
@@ -180,7 +188,7 @@ void CruAvatarMoverProcess::handleCombatMode() {
int x, y;
getMovementFlagAxes(x, y);
if (x != 0 || y != 0) {
- Direction nextdir = Direction_FromCentidegrees(_avatarAngle);
+ Direction nextdir = (_avatarAngle >= 0 ? Direction_FromCentidegrees(_avatarAngle) : avatar->getDir());
if (checkTurn(nextdir, true))
return;
@@ -247,9 +255,6 @@ void CruAvatarMoverProcess::handleNormalMode() {
avatar->toggleInCombat();
}
- // In normal mode the internal angle is set based on the avatar direction
- _avatarAngle = Direction_ToCentidegrees(direction);
-
// If Avatar has fallen down and not dead, get up!
if (standUpIfNeeded(direction))
return;
@@ -392,26 +397,16 @@ void CruAvatarMoverProcess::step(Animation::Sequence action, Direction direction
waitFor(avatar->doAnim(action, direction));
}
-bool CruAvatarMoverProcess::canAttack() {
- MainActor *avatar = getMainActor();
- return avatar->isInCombat();
-}
-
void CruAvatarMoverProcess::tryAttack() {
MainActor *avatar = getMainActor();
Direction dir = avatar->getDir();
if (!avatar->isInCombat()) {
avatar->setInCombat(0);
- if (!avatar->hasActorFlags(Actor::ACT_WEAPONREADY))
- waitFor(avatar->doAnim(Animation::readyWeapon, dir));
- } else {
- if (canAttack()) {
- // Fire event happens from animation
- Animation::Sequence fireanim = (avatar->isKneeling() ?
- Animation::kneelAndFire : Animation::attack);
- waitFor(avatar->doAnim(fireanim, dir));
- }
}
+ // Fire event happens from animation
+ Animation::Sequence fireanim = (avatar->isKneeling() ?
+ Animation::kneelAndFire : Animation::attack);
+ waitFor(avatar->doAnim(fireanim, dir));
}
void CruAvatarMoverProcess::saveData(Common::WriteStream *ws) {
diff --git a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.h b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.h
index e99ce27628..1f8ee22a12 100644
--- a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.h
+++ b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.h
@@ -67,7 +67,6 @@ private:
void handleHangingMode() override;
void handleCombatMode() override;
void handleNormalMode() override;
- bool canAttack() override;
void step(Animation::Sequence action, Direction direction, bool adjusted = false);
diff --git a/engines/ultima/ultima8/world/actors/u8_avatar_mover_process.cpp b/engines/ultima/ultima8/world/actors/u8_avatar_mover_process.cpp
index bc771ee72f..f4b2ae73d6 100644
--- a/engines/ultima/ultima8/world/actors/u8_avatar_mover_process.cpp
+++ b/engines/ultima/ultima8/world/actors/u8_avatar_mover_process.cpp
@@ -754,16 +754,7 @@ bool U8AvatarMoverProcess::canAttack() {
}
void U8AvatarMoverProcess::tryAttack() {
- MainActor *avatar = getMainActor();
- Direction dir = avatar->getDir();
- if (!avatar->isInCombat()) {
- avatar->setInCombat(0);
- waitFor(avatar->doAnim(Animation::readyWeapon, dir));
- } else {
- if (canAttack()) {
- waitFor(avatar->doAnim(Animation::attack, dir));
- }
- }
+ error("tryAttack should only be called in Crusader");
}
void U8AvatarMoverProcess::saveData(Common::WriteStream *ws) {
diff --git a/engines/ultima/ultima8/world/actors/u8_avatar_mover_process.h b/engines/ultima/ultima8/world/actors/u8_avatar_mover_process.h
index 81fd454068..3cf988b787 100644
--- a/engines/ultima/ultima8/world/actors/u8_avatar_mover_process.h
+++ b/engines/ultima/ultima8/world/actors/u8_avatar_mover_process.h
@@ -52,7 +52,7 @@ protected:
void handleHangingMode() override;
void handleCombatMode() override;
void handleNormalMode() override;
- bool canAttack() override;
+ bool canAttack();
void step(Animation::Sequence action, Direction direction, bool adjusted = false);
void jump(Animation::Sequence action, Direction direction);
diff --git a/engines/ultima/ultima8/world/crosshair_process.cpp b/engines/ultima/ultima8/world/crosshair_process.cpp
index 132c42b356..74c4cfc4f8 100644
--- a/engines/ultima/ultima8/world/crosshair_process.cpp
+++ b/engines/ultima/ultima8/world/crosshair_process.cpp
@@ -65,6 +65,10 @@ void CrosshairProcess::run() {
return;
}
double angle = mover->getAvatarAngleDegrees() + 90.0;
+ if (angle < 90.0) {
+ // -1 is used to record the avatar is not in combat, so shouldn't happen?
+ return;
+ }
// Convert angle to 0~2pi
double rads = Common::deg2rad(angle);
float xoff = CROSSHAIR_DIST * cos(rads);
More information about the Scummvm-git-logs
mailing list