mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-09 03:10:22 +00:00
PETKA: added heroes implementation without walking system
This commit is contained in:
parent
afa777da2a
commit
1599f21861
@ -20,10 +20,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/system.h"
|
||||
|
||||
#include "petka/petka.h"
|
||||
#include "petka/q_manager.h"
|
||||
#include "petka/q_system.h"
|
||||
#include "petka/flc.h"
|
||||
#include "petka/video.h"
|
||||
#include "petka/sound.h"
|
||||
#include "petka/objects/heroes.h"
|
||||
|
||||
namespace Petka {
|
||||
@ -40,6 +44,7 @@ QObjectPetka::QObjectPetka() {
|
||||
_surfId = -5;
|
||||
_surfH = 0;
|
||||
_surfW = 0;
|
||||
_field98 = 1.0;
|
||||
}
|
||||
|
||||
void QObjectPetka::processMessage(const QMessage &arg) {
|
||||
@ -79,6 +84,229 @@ void QObjectPetka::initSurface() {
|
||||
_surfH = flc->getHeight() * _field98;
|
||||
}
|
||||
|
||||
void QObjectPetka::walk(int x, int y) {
|
||||
Common::Point walkPos(x, y);
|
||||
if (_isShown) {
|
||||
Common::Point currPos;
|
||||
if (_isWalking) {
|
||||
// currPos = _walkObj->currPos();
|
||||
} else {
|
||||
currPos.x = _x_;
|
||||
currPos.y = _y_;
|
||||
}
|
||||
|
||||
if (currPos.sqrDist(walkPos) >= 25 * 25) {
|
||||
//_walkObj->init(currPos, walkPos);
|
||||
_destX = x;
|
||||
_destY = y;
|
||||
_resourceId = _imageId; // + _walkObj->getResId() + 10;
|
||||
_isWalking = true;
|
||||
_animate = true;
|
||||
|
||||
initSurface();
|
||||
FlicDecoder *flc = g_vm->resMgr()->loadFlic(_resourceId);
|
||||
flc->setFrame(1);
|
||||
|
||||
g_vm->videoSystem()->makeAllDirty();
|
||||
|
||||
_field7C = 0;
|
||||
_time = 0;
|
||||
_msgProcessingPaused = true;
|
||||
}
|
||||
} else {
|
||||
setPos(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void QObjectPetka::draw() {
|
||||
if (!_isShown || _resourceId == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_animate && _startSound) {
|
||||
if (_sound) {
|
||||
_sound->play(!_notLoopedSound);
|
||||
}
|
||||
_startSound = false;
|
||||
}
|
||||
|
||||
FlicDecoder *flc = g_vm->resMgr()->loadFlic(_resourceId);
|
||||
Graphics::Surface *surf = g_vm->resMgr()->loadBitmap(_surfId);
|
||||
if (!flc || !surf) {
|
||||
return;
|
||||
}
|
||||
Graphics::Surface *conv = flc->getCurrentFrame()->convertTo(g_system->getScreenFormat(), flc->getPalette());
|
||||
surf->copyRectToSurface(*conv, 0, 0, Common::Rect(0, 0, flc->getWidth() - 1, flc->getHeight() - 1));
|
||||
|
||||
Common::Rect srcRect(0, 0, _surfW, _surfH);
|
||||
Common::Rect dstRect(srcRect);
|
||||
dstRect.translate(_x, _y);
|
||||
|
||||
g_vm->videoSystem()->screen().transBlitFrom(*surf, srcRect, dstRect, flc->getTransColor(surf->format));
|
||||
conv->free();
|
||||
delete conv;
|
||||
}
|
||||
|
||||
void QObjectPetka::setPos(int x, int y) {
|
||||
y = MIN(y, 480);
|
||||
FlicDecoder *flc = g_vm->resMgr()->loadFlic(_resourceId);
|
||||
|
||||
_field98 = calcSmth(y);
|
||||
|
||||
_surfH = flc->getHeight() * _field98;
|
||||
_surfW = flc->getWidth() * _field98;
|
||||
|
||||
_x_ = x;
|
||||
_y_ = y;
|
||||
|
||||
_x = x - _surfW / 2;
|
||||
_y = y - _surfH;
|
||||
|
||||
g_vm->videoSystem()->makeAllDirty();
|
||||
}
|
||||
|
||||
double QObjectPetka::calcSmth(int y) {
|
||||
QSystem *qsys = g_vm->getQSystem();
|
||||
|
||||
y = MIN(y, 480);
|
||||
|
||||
|
||||
if (!qsys->_unkMap.contains(qsys->_room->_name)) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
const UnkStruct &unk = qsys->_unkMap.getVal(qsys->_room->_name);
|
||||
|
||||
|
||||
double res = (y - unk.f3) * unk.f2 / (unk.f4 - unk.f3);
|
||||
if (res < 0.0)
|
||||
res = 0.0;
|
||||
|
||||
if (res + unk.f1 > unk.f5)
|
||||
return unk.f5;
|
||||
return res + unk.f1;
|
||||
}
|
||||
|
||||
void QObjectPetka::updateWalk() {
|
||||
if (_isWalking) {
|
||||
_isWalking = false;
|
||||
setPos(_destX, _destY);
|
||||
|
||||
QMessage msg {_id, kSet, (uint16)_imageId, 1, 0, nullptr, 0};
|
||||
if (_heroReaction) {
|
||||
uint i;
|
||||
for (i = 0; i < _heroReaction->messages.size(); ++i) {
|
||||
if (_heroReaction->messages[i].opcode == kGoTo || _heroReaction->messages[i].opcode == kSetSeq) {
|
||||
_resourceId = _imageId; // + _walkObj->getResOffset() + 10;
|
||||
|
||||
FlicDecoder *flc = g_vm->resMgr()->loadFlic(_resourceId);
|
||||
flc->setFrame(1);
|
||||
|
||||
initSurface();
|
||||
|
||||
processMessage(QMessage {_id, kAnimate, 0, 0, 0, nullptr, 0});
|
||||
|
||||
_heroReaction->messages.push_back(msg);
|
||||
_heroReaction->messages.push_back(QMessage {_id, kAnimate, 1, 0, 0, nullptr, 0});
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == _heroReaction->messages.size())
|
||||
processMessage(msg);
|
||||
} else {
|
||||
processMessage(msg);
|
||||
}
|
||||
_msgProcessingPaused = false;
|
||||
g_vm->videoSystem()->makeAllDirty();
|
||||
}
|
||||
}
|
||||
|
||||
void QObjectPetka::setReactionAfterWalk(uint index, QReaction **reaction, QMessageObject *sender, bool deleteReaction) {
|
||||
QReaction *r = *reaction;
|
||||
_heroReaction = nullptr;
|
||||
|
||||
stopWalk();
|
||||
|
||||
QMessage msg {_id, kWalked, 0, 0, 0, sender, 0};
|
||||
_heroReaction = new QReaction();
|
||||
_sender = sender;
|
||||
|
||||
for (uint i = index + 1; i < r->messages.size(); ++i) {
|
||||
_heroReaction->messages.push_back(r->messages[i]);
|
||||
}
|
||||
|
||||
if (deleteReaction) {
|
||||
if (r == *reaction) {
|
||||
if (*reaction) {
|
||||
delete *reaction;
|
||||
}
|
||||
*reaction = nullptr;
|
||||
} else {
|
||||
delete r;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void QObjectPetka::stopWalk() {
|
||||
_isWalking = false;
|
||||
_msgProcessingPaused = false;
|
||||
|
||||
Common::List<QMessage> &list = g_vm->getQSystem()->_messages;
|
||||
for (Common::List<QMessage>::iterator it = list.begin(); it != list.end();) {
|
||||
if (it->opcode == kWalked && it->objId == _id) {
|
||||
it->objId = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
delete _heroReaction;
|
||||
_heroReaction = nullptr;
|
||||
|
||||
if (!_field7C) {
|
||||
QMessage msg {_id, kSet, (uint16)_imageId, 1, 0, nullptr, 0};
|
||||
processMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void QObjectPetka::update(int time) {
|
||||
if (!_animate || !_isShown)
|
||||
return;
|
||||
_time += time;
|
||||
FlicDecoder *flc = g_vm->resMgr()->loadFlic(_resourceId);
|
||||
if (flc && flc->getFrameCount() != 1) {
|
||||
while (_time >= flc->getDelay()) {
|
||||
if (_sound && _hasSound && flc->getCurFrame() == 0) {
|
||||
_startSound = true;
|
||||
_hasSound = false;
|
||||
}
|
||||
flc->setFrame(-1);
|
||||
if (flc->getCurFrame() == flc->getFrameCount() - 1) {
|
||||
if (_notLoopedSound) {
|
||||
_hasSound = _sound != nullptr;
|
||||
}
|
||||
g_vm->getQSystem()->addMessage(_id, kEnd, _resourceId, 0, 0, 0, 0);
|
||||
}
|
||||
if (flc->getCurFrame() + 1 == flc->getFrameCount() / 2) {
|
||||
g_vm->getQSystem()->addMessage(_id, kHalf, _resourceId, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (_field7C && flc->getCurFrame() == 0)
|
||||
_time = -10000;
|
||||
|
||||
updateWalk();
|
||||
flc = g_vm->resMgr()->loadFlic(_resourceId);
|
||||
|
||||
_surfH = flc->getHeight() * _field98;
|
||||
_surfW = flc->getWidth() * _field98;
|
||||
|
||||
_time -= flc->getDelay();
|
||||
|
||||
g_vm->videoSystem()->addDirtyRect(Common::Rect(_x, _y, _surfW + _x, _surfH + _y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QObjectChapayev::QObjectChapayev() {
|
||||
_x = 477;
|
||||
_y = 350;
|
||||
|
@ -33,7 +33,19 @@ public:
|
||||
void processMessage(const QMessage &msg) override;
|
||||
void initSurface();
|
||||
|
||||
protected:
|
||||
void walk(int x, int y);
|
||||
void stopWalk();
|
||||
void updateWalk();
|
||||
void setReactionAfterWalk(uint index, QReaction **reaction, QMessageObject *sender, bool deleteReaction);
|
||||
|
||||
void draw() override;
|
||||
void update(int time) override;
|
||||
void setPos(int x, int y) override;
|
||||
|
||||
double calcSmth(int y);
|
||||
|
||||
|
||||
public:
|
||||
int _field7C;
|
||||
int _surfW;
|
||||
int _surfH;
|
||||
@ -43,6 +55,8 @@ protected:
|
||||
int _imageId;
|
||||
double _field98;
|
||||
// walkObj
|
||||
int _destX;
|
||||
int _destY;
|
||||
bool _isWalking;
|
||||
bool _isPetka;
|
||||
QReaction *_heroReaction;
|
||||
|
@ -57,7 +57,7 @@ QMessageObject::QMessageObject() {
|
||||
_isShown = true;
|
||||
_isActive = true;
|
||||
_updateZ = 0;
|
||||
_field_38 = 0;
|
||||
_msgProcessingPaused = 0;
|
||||
_notLoopedSound = true;
|
||||
_startSound = false;
|
||||
_hasSound = false;
|
||||
@ -89,12 +89,13 @@ void processSavedReaction(QReaction **reaction, QMessageObject *sender) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
case kWalk:
|
||||
case kWalkTo:
|
||||
case kWalkVich:
|
||||
g_vm->getQSystem()->_petka->setReactionAfterWalk(i, &r, sender, 1);
|
||||
break;
|
||||
case kWalkVich:
|
||||
g_vm->getQSystem()->_chapayev->setReactionAfterWalk(i, &r, sender, 1);
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
processed = false;
|
||||
break;
|
||||
@ -113,10 +114,10 @@ void processSavedReaction(QReaction **reaction, QMessageObject *sender) {
|
||||
void QMessageObject::processMessage(const QMessage &msg) {
|
||||
bool reacted = false;
|
||||
for (uint i = 0; i < _reactions.size(); ++i) {
|
||||
QReaction &r = _reactions[i];
|
||||
if (r.opcode != msg.opcode ||
|
||||
(r.status != -1 && r.status != _status) ||
|
||||
(r.senderId != -1 && r.senderId != msg.sender->_id)) {
|
||||
QReaction *r = &_reactions[i];
|
||||
if (r->opcode != msg.opcode ||
|
||||
(r->status != -1 && r->status != _status) ||
|
||||
(r->senderId != -1 && r->senderId != msg.sender->_id)) {
|
||||
continue;
|
||||
}
|
||||
bool res;
|
||||
@ -124,8 +125,8 @@ void QMessageObject::processMessage(const QMessage &msg) {
|
||||
g_vm->getBigDialogue()->setDialog(_id, msg.opcode, -1);
|
||||
g_vm->getQSystem()->_mainInterface->_dialog._sender = this;
|
||||
}
|
||||
for (uint j = 0; j < r.messages.size(); ++j) {
|
||||
QMessage &rMsg = r.messages[j];
|
||||
for (uint j = 0; j < r->messages.size(); ++j) {
|
||||
QMessage &rMsg = r->messages[j];
|
||||
if (rMsg.opcode == kCheck && g_vm->getQSystem()->findObject(rMsg.objId)->_status != rMsg.arg1) {
|
||||
break;
|
||||
}
|
||||
@ -145,8 +146,8 @@ void QMessageObject::processMessage(const QMessage &msg) {
|
||||
case kDialog:
|
||||
delete g_dialogReaction;
|
||||
g_dialogReaction = new QReaction();
|
||||
for (uint z = j + 1; z < r.messages.size(); ++z) {
|
||||
g_dialogReaction->messages.push_back(r.messages[z]);
|
||||
for (uint z = j + 1; z < r->messages.size(); ++z) {
|
||||
g_dialogReaction->messages.push_back(r->messages[z]);
|
||||
}
|
||||
break;
|
||||
case kPlay: {
|
||||
@ -154,17 +155,19 @@ void QMessageObject::processMessage(const QMessage &msg) {
|
||||
delete obj->_reaction;
|
||||
obj->_reaction = new QReaction();
|
||||
obj->_reactionResId = rMsg.arg1;
|
||||
for (uint z = j + 1; z < r.messages.size(); ++z) {
|
||||
obj->_reaction->messages.push_back(r.messages[z]);
|
||||
for (uint z = j + 1; z < r->messages.size(); ++z) {
|
||||
obj->_reaction->messages.push_back(r->messages[z]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
|
||||
case kWalk:
|
||||
case kWalkTo:
|
||||
case kWalkVich:
|
||||
g_vm->getQSystem()->_petka->setReactionAfterWalk(j, &r, this, 0);
|
||||
break;
|
||||
case kWalkVich:
|
||||
g_vm->getQSystem()->_chapayev->setReactionAfterWalk(j, &r, this, 0);
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
processed = false;
|
||||
}
|
||||
@ -291,6 +294,44 @@ void QMessageObject::processMessage(const QMessage &msg) {
|
||||
case kJumpVich:
|
||||
g_vm->getQSystem()->_petka->setPos((msg.arg1 == -1 ? _walkX : msg.arg1), (msg.arg2 == -1 ? _walkY : msg.arg2));
|
||||
break;
|
||||
case kWalk:
|
||||
if (!reacted) {
|
||||
if (_walkX == -1) {
|
||||
g_vm->getQSystem()->_petka->walk(msg.arg1, msg.arg2);
|
||||
|
||||
} else {
|
||||
g_vm->getQSystem()->_petka->walk(_walkX, _walkY);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kWalkTo: {
|
||||
int destX = msg.arg1;
|
||||
int destY = msg.arg2;
|
||||
if (destX == -1 || destY == -1) {
|
||||
destX = _walkX;
|
||||
destY = _walkY;
|
||||
}
|
||||
if (destX != -1) {
|
||||
g_vm->getQSystem()->_petka->walk(destX, destY);
|
||||
QReaction *r = g_vm->getQSystem()->_petka->_heroReaction;
|
||||
if (r) {
|
||||
for (uint i = 0; i < r->messages.size(); ++i) {
|
||||
if (r->messages[i].opcode == kGoTo) {
|
||||
g_vm->getQSystem()->_chapayev->walk(_walkX, _walkY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kWalkVich:
|
||||
if (msg.arg1 == -1 || msg.arg2 == -1) {
|
||||
g_vm->getQSystem()->_chapayev->walk(msg.arg1, msg.arg2);
|
||||
} else if (_walkX != -1) {
|
||||
g_vm->getQSystem()->_chapayev->walk(_walkX, _walkY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
g_vm->getBigDialogue()->setDialog(_id, msg.opcode, -1);
|
||||
@ -335,10 +376,13 @@ bool QObject::isInPoint(int x, int y) {
|
||||
if (!_isActive)
|
||||
return false;
|
||||
FlicDecoder *flc = g_vm->resMgr()->loadFlic(_resourceId);
|
||||
Common::Rect rect(_x, _y, _x + flc->getWidth(), _y + flc->getHeight());
|
||||
if (!rect.contains(x, y))
|
||||
return false;
|
||||
return *(byte *) flc->getCurrentFrame()->getBasePtr(x - _x, y - _y) != 0;
|
||||
if (flc) {
|
||||
Common::Rect rect(_x, _y, _x + flc->getWidth(), _y + flc->getHeight());
|
||||
if (!rect.contains(x, y))
|
||||
return false;
|
||||
return *(byte *) flc->getCurrentFrame()->getBasePtr(x - _x, y - _y) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void QObject::draw() {
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
int32 _isShown;
|
||||
int32 _animate;
|
||||
int _updateZ;
|
||||
int _field_38;
|
||||
int _msgProcessingPaused;
|
||||
int _isActive;
|
||||
int _startSound;
|
||||
int _hasSound;
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "petka/q_manager.h"
|
||||
#include "petka/interfaces/main.h"
|
||||
#include "petka/objects/object_bg.h"
|
||||
#include "petka/objects/heroes.h"
|
||||
|
||||
namespace Petka {
|
||||
|
||||
@ -59,10 +60,14 @@ void QObjectBG::processMessage(const QMessage &msg) {
|
||||
case kNoMap:
|
||||
_showMap = 0;
|
||||
break;
|
||||
case kGoTo:
|
||||
case kGoTo: {
|
||||
g_vm->getQSystem()->_mainInterface->loadRoom(_id, false);
|
||||
g_vm->videoSystem()->makeAllDirty();
|
||||
QMessageObject *obj = g_vm->getQSystem()->findObject(_id);
|
||||
g_vm->getQSystem()->_petka->setPos(obj->_walkX, obj->_walkY);
|
||||
g_vm->getQSystem()->_chapayev->setPos(obj->_walkX, obj->_walkY - 2);
|
||||
break;
|
||||
}
|
||||
case kSetSeq:
|
||||
break;
|
||||
case kEndSeq:
|
||||
|
@ -133,6 +133,21 @@ bool QSystem::init() {
|
||||
}
|
||||
for (uint i = 0; i < bgsCount; ++i) {
|
||||
readObject(_bgs[i], *stream, namesIni, castIni);
|
||||
|
||||
|
||||
Common::String val;
|
||||
bgsIni.getKey(_bgs[i]._name, "Settings", val);
|
||||
|
||||
if (!val.empty()) {
|
||||
UnkStruct unk;
|
||||
|
||||
sscanf(val.c_str(), "%lf %lf %d %d %lf", &unk.f1, &unk.f2, &unk.f3, &unk.f4, &unk.f5);
|
||||
|
||||
_unkMap.setVal(_bgs[i]._name, unk);
|
||||
}
|
||||
|
||||
|
||||
|
||||
_allObjects.push_back(&_bgs[i]);
|
||||
}
|
||||
|
||||
@ -255,7 +270,7 @@ void QSystem::load(Common::ReadStream *s) {
|
||||
uint count = s->readUint32LE();
|
||||
for (uint i = 0; i < count; ++i) {
|
||||
QMessageObject *obj = findObject(readString(s));
|
||||
obj->_field_38 = s->readUint32LE();
|
||||
obj->_msgProcessingPaused = s->readUint32LE();
|
||||
obj->_status = s->readUint32LE();
|
||||
obj->_resourceId = s->readUint32LE();
|
||||
obj->_z = s->readUint32LE();
|
||||
@ -295,7 +310,7 @@ void QSystem::save(Common::WriteStream *s) {
|
||||
s->writeUint32LE(_allObjects.size());
|
||||
for (uint i = 0; i < _allObjects.size(); ++i) {
|
||||
writeString(s, _allObjects[i]->_name);
|
||||
s->writeUint32LE(_allObjects[i]->_field_38);
|
||||
s->writeUint32LE(_allObjects[i]->_msgProcessingPaused);
|
||||
s->writeUint32LE(_allObjects[i]->_status);
|
||||
s->writeUint32LE(_allObjects[i]->_resourceId);
|
||||
s->writeUint32LE(_allObjects[i]->_z);
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "common/ptr.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/list.h"
|
||||
#include "common/hashmap.h"
|
||||
#include "common/hash-str.h"
|
||||
|
||||
#include "petka/objects/object_bg.h"
|
||||
|
||||
@ -44,6 +46,14 @@ class InterfacePanel;
|
||||
class InterfaceMap;
|
||||
class Interface;
|
||||
|
||||
struct UnkStruct {
|
||||
double f1;
|
||||
double f2;
|
||||
int f3;
|
||||
int f4;
|
||||
double f5;
|
||||
};
|
||||
|
||||
class QSystem {
|
||||
public:
|
||||
explicit QSystem();
|
||||
@ -85,6 +95,8 @@ public:
|
||||
Interface *_currInterface;
|
||||
Interface *_prevInterface;
|
||||
|
||||
Common::HashMap<Common::String, UnkStruct> _unkMap;
|
||||
|
||||
int _isIniting;
|
||||
int _fxId;
|
||||
int _musicId;
|
||||
|
Loading…
Reference in New Issue
Block a user