mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 21:59:17 +00:00
TWP: Add verb shake
This commit is contained in:
parent
986a18dcbd
commit
6a38a1fa62
@ -312,7 +312,7 @@ static SQInteger findScreenPosition(HSQUIRRELVM v) {
|
||||
if (!actorSlot)
|
||||
return 0;
|
||||
for (int i = 1; i < MAX_VERBS; i++) {
|
||||
Verb vb = actorSlot->verbs[i];
|
||||
const Verb &vb = actorSlot->verbSlots[i]._verb;
|
||||
if (vb.id.id == verb) {
|
||||
SpriteSheet *verbSheet = g_twp->_resManager->spriteSheet("VerbSheet");
|
||||
const SpriteSheetFrame *verbFrame = &verbSheet->getFrame(Common::String::format("%s_en", vb.image.c_str()));
|
||||
@ -763,7 +763,7 @@ static SQInteger setVerb(HSQUIRRELVM v) {
|
||||
debugC(kDebugGenScript, "setVerb %lld, %lld, %lld, %s", actorSlot, verbSlot, id, text.c_str());
|
||||
VerbId verbId;
|
||||
verbId.id = id;
|
||||
g_twp->_hud->_actorSlots[actorSlot - 1].verbs[verbSlot] = Verb(verbId, image, fun, text, key, flags);
|
||||
g_twp->_hud->_actorSlots[actorSlot - 1].verbSlots[verbSlot]._verb = Verb(verbId, image, fun, text, key, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,31 @@
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "twp/twp.h"
|
||||
#include "twp/motor.h"
|
||||
#include "twp/hud.h"
|
||||
#include "twp/resmanager.h"
|
||||
|
||||
namespace Twp {
|
||||
|
||||
class ShakeVerb : public Motor {
|
||||
public:
|
||||
virtual ~ShakeVerb() {}
|
||||
ShakeVerb(VerbSlot *slot, float amount) : _slot(slot), _amount(amount) {}
|
||||
|
||||
private:
|
||||
virtual void onUpdate(float elapsed) override {
|
||||
_shakeTime += 40.f * elapsed;
|
||||
_elapsed += elapsed;
|
||||
_slot->_shakeOffset = Math::Vector2d(_amount * cos(_shakeTime + 0.3f), _amount * sin(_shakeTime));
|
||||
}
|
||||
|
||||
private:
|
||||
VerbSlot *_slot = nullptr;
|
||||
float _amount = 0.f;
|
||||
float _shakeTime = 0.f;
|
||||
float _elapsed = 0.f;
|
||||
};
|
||||
|
||||
Verb::Verb() = default;
|
||||
|
||||
Verb::Verb(VerbId verbId, const Common::String &img, const Common::String &f, const Common::String &t, const Common::String &k, int fl)
|
||||
@ -175,22 +195,17 @@ void Hud::drawCore(const Math::Matrix4 &trsf) {
|
||||
_shader._normalColor = slot->verbUiColors.verbHighlight;
|
||||
_shader._highlightColor = slot->verbUiColors.verbHighlightTint;
|
||||
|
||||
bool isOver = false;
|
||||
for (int i = 1; i < MAX_VERBS; i++) {
|
||||
const Verb &verb = slot->verbs[i];
|
||||
if (verb.image.size() > 0) {
|
||||
const SpriteSheetFrame &verbFrame = verbSheet->getFrame(Common::String::format("%s%s_%s", verb.image.c_str(), verbSuffix.c_str(), lang.c_str()));
|
||||
bool over = verbFrame.spriteSourceSize.contains(_mousePos.getX(), _mousePos.getY());
|
||||
isOver |= over;
|
||||
Color color = (over || (verb.id.id == _defaultVerbId)) ? verbHighlight : verbColor;
|
||||
if (_mouseClick && over) {
|
||||
selectVerb(verb);
|
||||
}
|
||||
drawSprite(verbFrame, verbTexture, Color::withAlpha(color, getAlpha()), trsf);
|
||||
const VerbSlot &verbSlot = slot->verbSlots[i];
|
||||
if (verbSlot._verb.image.size() > 0) {
|
||||
const SpriteSheetFrame &verbFrame = verbSheet->getFrame(Common::String::format("%s%s_%s", verbSlot._verb.image.c_str(), verbSuffix.c_str(), lang.c_str()));
|
||||
Color color = (verbSlot._over || (verbSlot._verb.id.id == _defaultVerbId)) ? verbHighlight : verbColor;
|
||||
Math::Matrix4 t(trsf);
|
||||
t.translate(Math::Vector3d(verbSlot._shakeOffset.getX(), verbSlot._shakeOffset.getY(), 0.f));
|
||||
drawSprite(verbFrame, verbTexture, Color::withAlpha(color, getAlpha()), t);
|
||||
}
|
||||
}
|
||||
g_twp->getGfx().use(saveShader);
|
||||
_over = isOver;
|
||||
}
|
||||
|
||||
void Hud::update(float elapsed, const Math::Vector2d &pos, Common::SharedPtr<Object> hotspot, bool mouseClick) {
|
||||
@ -210,6 +225,42 @@ void Hud::update(float elapsed, const Math::Vector2d &pos, Common::SharedPtr<Obj
|
||||
float alpha = MIN(_fadeTime, 2.0f) / 2.0f;
|
||||
setAlpha(alpha);
|
||||
}
|
||||
|
||||
ActorSlot *slot = actorSlot(_actor);
|
||||
if (!slot)
|
||||
return;
|
||||
|
||||
bool retroVerbs = ConfMan.getBool("retroVerbs");
|
||||
Common::String lang = ConfMan.get("language");
|
||||
Common::String verbSuffix = retroVerbs ? "_retro" : "";
|
||||
SpriteSheet *verbSheet = g_twp->_resManager->spriteSheet("VerbSheet");
|
||||
bool isOver = false;
|
||||
for (int i = 1; i < MAX_VERBS; i++) {
|
||||
VerbSlot &verbSlot = slot->verbSlots[i];
|
||||
if (verbSlot._verb.image.size() > 0) {
|
||||
const SpriteSheetFrame &verbFrame = verbSheet->getFrame(Common::String::format("%s%s_%s", verbSlot._verb.image.c_str(), verbSuffix.c_str(), lang.c_str()));
|
||||
bool over = verbFrame.spriteSourceSize.contains(_mousePos.getX(), _mousePos.getY());
|
||||
// shake choice when cursor is over
|
||||
if ((verbSlot._shakeTime > 0.0f) && verbSlot._shake) {
|
||||
verbSlot._shake->update(elapsed);
|
||||
verbSlot._shakeTime -= elapsed;
|
||||
if (verbSlot._shakeTime < 0.f) {
|
||||
verbSlot._shakeTime = 0.f;
|
||||
}
|
||||
}
|
||||
if (over && !verbSlot._over && verbSlot._shakeTime < 0.1f) {
|
||||
verbSlot._shakeTime = 0.25f;
|
||||
verbSlot._shake = Common::ScopedPtr<Motor>(new ShakeVerb(&verbSlot, 1.2f));
|
||||
verbSlot._over = over;
|
||||
}
|
||||
verbSlot._over = over;
|
||||
isOver |= over;
|
||||
if (_mouseClick && over) {
|
||||
selectVerb(verbSlot._verb);
|
||||
}
|
||||
}
|
||||
}
|
||||
_over = isOver;
|
||||
}
|
||||
|
||||
void Hud::setVisible(bool visible) {
|
||||
|
@ -60,10 +60,21 @@ struct Verb {
|
||||
Verb(VerbId id, const Common::String &image, const Common::String &fun, const Common::String &text, const Common::String &key, int flags = 0);
|
||||
};
|
||||
|
||||
struct VerbSlot {
|
||||
Verb _verb;
|
||||
float _shakeTime = 0.f;
|
||||
Common::ScopedPtr<Motor> _shake;
|
||||
Math::Vector2d _shakeOffset;
|
||||
bool _over = false;
|
||||
|
||||
VerbSlot() {}
|
||||
VerbSlot(Verb verb) : _verb(verb) {}
|
||||
};
|
||||
|
||||
struct ActorSlot {
|
||||
public:
|
||||
VerbUiColors verbUiColors;
|
||||
Verb verbs[MAX_VERBS];
|
||||
VerbSlot verbSlots[MAX_VERBS];
|
||||
bool selectable = false;
|
||||
Common::SharedPtr<Object> actor;
|
||||
|
||||
@ -71,9 +82,9 @@ public:
|
||||
ActorSlot();
|
||||
|
||||
Verb *getVerb(int id) {
|
||||
for (auto &verb : verbs) {
|
||||
if (verb.id.id == id) {
|
||||
return &verb;
|
||||
for (auto &verbSlot : verbSlots) {
|
||||
if (verbSlot._verb.id.id == id) {
|
||||
return &verbSlot._verb;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -898,7 +898,7 @@ static SQInteger objectValidVerb(HSQUIRRELVM v) {
|
||||
if (g_twp->_actor) {
|
||||
ActorSlot *slot = g_twp->_hud->actorSlot(g_twp->_actor);
|
||||
for (int i = 0; i < MAX_VERBS; i++) {
|
||||
Verb *vb = &slot->verbs[i];
|
||||
const Verb *vb = &slot->verbSlots[i]._verb;
|
||||
if (vb->id.id == verb) {
|
||||
if (sqrawexists(obj->_table, vb->fun)) {
|
||||
sqpush(v, true);
|
||||
|
@ -259,7 +259,7 @@ void TwpEngine::clickedAt(const Math::Vector2d &scrPos) {
|
||||
cancelSentence(_actor);
|
||||
if (_actor->_room == _room)
|
||||
Object::walk(_actor, roomPos);
|
||||
_hud->selectVerb(_hud->actorSlot(_actor)->verbs[0]);
|
||||
_hud->selectVerb(_hud->actorSlot(_actor)->verbSlots[0]._verb);
|
||||
_holdToMove = true;
|
||||
}
|
||||
|
||||
@ -804,7 +804,7 @@ static void setVerbAction(int verbSlot) {
|
||||
ActorSlot *slot = g_twp->_hud->actorSlot(g_twp->_actor);
|
||||
if (!slot)
|
||||
return;
|
||||
g_twp->_hud->selectVerb(slot->verbs[verbSlot]);
|
||||
g_twp->_hud->selectVerb(slot->verbSlots[verbSlot]._verb);
|
||||
}
|
||||
|
||||
Common::Error TwpEngine::run() {
|
||||
@ -1377,7 +1377,7 @@ void TwpEngine::enterRoom(Common::SharedPtr<Room> room, Common::SharedPtr<Object
|
||||
_room->setOverlay(Color(0.f, 0.f, 0.f, 0.f));
|
||||
_camera->setBounds(Rectf::fromMinMax(Math::Vector2d(), _room->_roomSize));
|
||||
if (_actor && _hud->actorSlot(_actor))
|
||||
_hud->selectVerb(_hud->actorSlot(_actor)->verbs[0]);
|
||||
_hud->selectVerb(_hud->actorSlot(_actor)->verbSlots[0]._verb);
|
||||
|
||||
// move current actor to the new room
|
||||
Math::Vector2d camPos;
|
||||
@ -1663,7 +1663,7 @@ void TwpEngine::resetVerb() {
|
||||
_noun1 = nullptr;
|
||||
_noun2 = nullptr;
|
||||
_useFlag = UseFlag::ufNone;
|
||||
_hud->_verb = _hud->actorSlot(_actor)->verbs[0];
|
||||
_hud->_verb = _hud->actorSlot(_actor)->verbSlots[0]._verb;
|
||||
}
|
||||
|
||||
bool TwpEngine::callVerb(Common::SharedPtr<Object> actor, VerbId verbId, Common::SharedPtr<Object> noun1, Common::SharedPtr<Object> noun2) {
|
||||
@ -1677,7 +1677,7 @@ bool TwpEngine::callVerb(Common::SharedPtr<Object> actor, VerbId verbId, Common:
|
||||
Common::String noun2name = !noun2 ? "null" : noun2->_key;
|
||||
ActorSlot *slot = _hud->actorSlot(actor);
|
||||
Verb *verb = slot->getVerb(verbId.id);
|
||||
Common::String verbFuncName = verb ? verb->fun : slot->verbs[0].fun;
|
||||
Common::String verbFuncName = verb ? verb->fun : slot->verbSlots[0]._verb.fun;
|
||||
debugC(kDebugGame, "callVerb(%s,%s,%s,%s)", name.c_str(), verbFuncName.c_str(), noun1name.c_str(), noun2name.c_str());
|
||||
|
||||
// test if object became untouchable
|
||||
|
Loading…
Reference in New Issue
Block a user