HYPNO: better handling of killed animations using transitions in boyz

This commit is contained in:
neuromancer 2022-05-18 20:41:34 +02:00
parent d4f75dc5aa
commit 2cb7f4ef53
6 changed files with 60 additions and 31 deletions

View File

@ -211,7 +211,7 @@ void HypnoEngine::runArcade(ArcadeShooting *arc) {
initSegment(arc);
// Transitions
ArcadeTransitions transitions = arc->transitions;
_transitions = arc->transitions;
_levelId = arc->id;
_shootSound = arc->shootSound;
@ -376,8 +376,8 @@ void HypnoEngine::runArcade(ArcadeShooting *arc) {
break;
}
if (!transitions.empty()) {
transition = checkTransition(transitions, arc);
if (!_transitions.empty()) {
transition = checkTransition(_transitions, arc);
}
if (_background->decoder && _background->decoder->getCurFrame() >= int(segments[_segmentIdx].start + segments[_segmentIdx].size - 2)) {

View File

@ -227,6 +227,11 @@ bool BoyzEngine::checkTransition(ArcadeTransitions &transitions, ArcadeShooting
drawCursorArcade(g_system->getEventManager()->getMousePos());
} else if (!at.sound.empty()) {
playSound(at.sound, 1, at.soundRate);
} else if (at.jumpToTime > 0) {
_background->decoder->forceSeekToFrame(at.jumpToTime);
_masks->decoder->forceSeekToFrame(at.jumpToTime);
} else if (at.loseLevel) {
_health = 0;
} else
error ("Invalid transition at %d", ttime);
@ -346,6 +351,14 @@ bool BoyzEngine::shoot(const Common::Point &mousePos, ArcadeShooting *arc, bool
_background->decoder->forceSeekToFrame(_shoots[i].explosionFrames[0].start - 3);
_masks->decoder->forceSeekToFrame(_shoots[i].explosionFrames[0].start - 3);
if (_shoots[i].jumpToTimeAfterKilled == -1000) {
ArcadeTransition at("", 0, "", 0, _shoots[i].explosionFrames[0].lastFrame() - 1);
at.loseLevel = true;
_transitions.push_front(at);
}
return false;
} else if (!_shoots[i].nonHostile && secondary) {
if (_shoots[i].interactionFrame > 0) {
@ -380,6 +393,12 @@ bool BoyzEngine::shoot(const Common::Point &mousePos, ArcadeShooting *arc, bool
_background->decoder->forceSeekToFrame(_shoots[i].explosionFrames[0].start - 3);
_masks->decoder->forceSeekToFrame(_shoots[i].explosionFrames[0].start - 3);
changeCursor(_crosshairsActive[_currentWeapon], _crosshairsPalette, true);
if (_shoots[i].jumpToTimeAfterKilled > 0) {
ArcadeTransition at("", 0, "", 0, _shoots[i].explosionFrames[0].lastFrame() - 1);
at.jumpToTime = _shoots[i].jumpToTimeAfterKilled;
_transitions.push_front(at);
}
}
return false;
}
@ -413,6 +432,8 @@ void BoyzEngine::missedTarget(Shoot *s, ArcadeShooting *arc) {
return;
} else if (s->missedAnimation == uint32(-1)) {
_skipLevel = true;
} else if (s->missedAnimation == uint32(-1000)) {
_health = 0;
} else {
int missedAnimation = s->missedAnimation + 3;
if (missedAnimation > int(_background->decoder->getFrameCount()) - 1) {

View File

@ -431,6 +431,7 @@ public:
nonHostile = false;
playInteractionAudio = false;
animalSound = "";
jumpToTimeAfterKilled = 0;
}
Common::String name;
Filename animation;
@ -451,7 +452,7 @@ public:
uint32 paletteOffset;
uint32 paletteSize;
// Mask
// Missed animation
uint32 missedAnimation;
// Sounds
@ -477,7 +478,7 @@ public:
bool nonHostile;
bool isAnimal;
Common::String checkIfDestroyed;
int jumpToTimeAfterKilled;
};
typedef Common::Array<Shoot> Shoots;
@ -537,6 +538,8 @@ public:
palette = palette_;
sound = sound_;
soundRate = soundRate_;
loseLevel = false;
jumpToTime = 0;
time = time_;
}
@ -544,6 +547,8 @@ public:
Filename palette;
Filename sound;
uint32 soundRate;
bool loseLevel;
uint32 jumpToTime;
uint32 time;
};

View File

@ -631,8 +631,8 @@ static const yytype_int16 yyrline[] =
405, 409, 413, 417, 421, 425, 429, 433, 437, 441,
445, 449, 453, 456, 460, 465, 470, 473, 478, 483,
487, 493, 497, 500, 501, 502, 505, 509, 512, 517,
520, 521, 531, 537, 541, 552, 556, 557, 561, 565,
569, 572, 575, 577
520, 521, 531, 538, 542, 553, 557, 558, 562, 566,
570, 573, 576, 578
};
#endif
@ -2193,23 +2193,24 @@ yyreduce:
{
assert((yyvsp[-1].i) > (yyvsp[-2].i));
FrameInfo fi((yyvsp[-2].i), (yyvsp[-1].i) - (yyvsp[-2].i));
shoot->jumpToTimeAfterKilled = (yyvsp[0].i);
shoot->explosionFrames.push_back(fi);
debugC(1, kHypnoDebugParser, "K %d %d %d", (yyvsp[-2].i), (yyvsp[-1].i), (yyvsp[0].i));
}
#line 2200 "engines/hypno/grammar_arc.cpp"
#line 2201 "engines/hypno/grammar_arc.cpp"
break;
case 103: /* bline: KTOK NUM NUM */
#line 537 "engines/hypno/grammar_arc.y"
#line 538 "engines/hypno/grammar_arc.y"
{ debugC(1, kHypnoDebugParser, "K %d %d", (yyvsp[-1].i), (yyvsp[0].i));
FrameInfo fi((yyvsp[-1].i), 1);
shoot->explosionFrames.push_back(fi);
}
#line 2209 "engines/hypno/grammar_arc.cpp"
#line 2210 "engines/hypno/grammar_arc.cpp"
break;
case 104: /* bline: SNTOK FILENAME enc */
#line 541 "engines/hypno/grammar_arc.y"
#line 542 "engines/hypno/grammar_arc.y"
{
if (Common::String("S0") == (yyvsp[-2].s))
shoot->enemySound = (yyvsp[-1].s);
@ -2221,86 +2222,86 @@ yyreduce:
shoot->animalSound = (yyvsp[-1].s);
debugC(1, kHypnoDebugParser, "SN %s", (yyvsp[-1].s)); }
#line 2225 "engines/hypno/grammar_arc.cpp"
#line 2226 "engines/hypno/grammar_arc.cpp"
break;
case 105: /* bline: SNTOK */
#line 552 "engines/hypno/grammar_arc.y"
#line 553 "engines/hypno/grammar_arc.y"
{
debugC(1, kHypnoDebugParser, "SN");
}
#line 2233 "engines/hypno/grammar_arc.cpp"
#line 2234 "engines/hypno/grammar_arc.cpp"
break;
case 106: /* bline: GTOK */
#line 556 "engines/hypno/grammar_arc.y"
#line 557 "engines/hypno/grammar_arc.y"
{ debugC(1, kHypnoDebugParser, "G"); }
#line 2239 "engines/hypno/grammar_arc.cpp"
#line 2240 "engines/hypno/grammar_arc.cpp"
break;
case 107: /* bline: TTOK NUM NUM NUM */
#line 557 "engines/hypno/grammar_arc.y"
#line 558 "engines/hypno/grammar_arc.y"
{
shoot->interactionFrame = (yyvsp[-2].i);
debugC(1, kHypnoDebugParser, "T %d %d %d", (yyvsp[-2].i), (yyvsp[-1].i), (yyvsp[0].i));
}
#line 2248 "engines/hypno/grammar_arc.cpp"
#line 2249 "engines/hypno/grammar_arc.cpp"
break;
case 108: /* bline: TTOK NUM */
#line 561 "engines/hypno/grammar_arc.y"
#line 562 "engines/hypno/grammar_arc.y"
{
shoot->interactionFrame = (yyvsp[0].i);
debugC(1, kHypnoDebugParser, "T %d", (yyvsp[0].i));
}
#line 2257 "engines/hypno/grammar_arc.cpp"
#line 2258 "engines/hypno/grammar_arc.cpp"
break;
case 109: /* bline: TTOK */
#line 565 "engines/hypno/grammar_arc.y"
#line 566 "engines/hypno/grammar_arc.y"
{
shoot->isAnimal = true;
debugC(1, kHypnoDebugParser, "T");
}
#line 2266 "engines/hypno/grammar_arc.cpp"
#line 2267 "engines/hypno/grammar_arc.cpp"
break;
case 110: /* bline: MTOK */
#line 569 "engines/hypno/grammar_arc.y"
#line 570 "engines/hypno/grammar_arc.y"
{
debugC(1, kHypnoDebugParser, "M");
}
#line 2274 "engines/hypno/grammar_arc.cpp"
#line 2275 "engines/hypno/grammar_arc.cpp"
break;
case 111: /* bline: NTOK */
#line 572 "engines/hypno/grammar_arc.y"
#line 573 "engines/hypno/grammar_arc.y"
{
shoot->noEnemySound = true;
debugC(1, kHypnoDebugParser, "N"); }
#line 2282 "engines/hypno/grammar_arc.cpp"
#line 2283 "engines/hypno/grammar_arc.cpp"
break;
case 112: /* bline: NRTOK */
#line 575 "engines/hypno/grammar_arc.y"
#line 576 "engines/hypno/grammar_arc.y"
{
debugC(1, kHypnoDebugParser, "NR"); }
#line 2289 "engines/hypno/grammar_arc.cpp"
#line 2290 "engines/hypno/grammar_arc.cpp"
break;
case 113: /* bline: ZTOK */
#line 577 "engines/hypno/grammar_arc.y"
#line 578 "engines/hypno/grammar_arc.y"
{
g_parsedArc->shoots.push_back(*shoot);
//delete shoot;
//shoot = nullptr;
debugC(1, kHypnoDebugParser, "Z");
}
#line 2300 "engines/hypno/grammar_arc.cpp"
#line 2301 "engines/hypno/grammar_arc.cpp"
break;
#line 2304 "engines/hypno/grammar_arc.cpp"
#line 2305 "engines/hypno/grammar_arc.cpp"
default: break;
}

View File

@ -531,6 +531,7 @@ bline: FNTOK FILENAME {
| KTOK NUM NUM NUM {
assert($3 > $2);
FrameInfo fi($2, $3 - $2);
shoot->jumpToTimeAfterKilled = $4;
shoot->explosionFrames.push_back(fi);
debugC(1, kHypnoDebugParser, "K %d %d %d", $2, $3, $4);
}

View File

@ -251,6 +251,7 @@ public:
Filename _currentPalette;
virtual bool availableObjectives();
virtual bool checkArcadeObjectives();
ArcadeTransitions _transitions;
virtual bool checkTransition(ArcadeTransitions &transitions, ArcadeShooting *arc);
virtual Common::Point getPlayerPosition(bool needsUpdate);
virtual Common::Point computeTargetPosition(const Common::Point &mousePos);