Files
scummvm-cursorfix/engines/qdengine/minigames/shveik_shkatulka.h
2026-02-02 04:50:13 +01:00

399 lines
11 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef QDENGINE_MINIGAMES_SHVEIK_SHKATULKA_H
#define QDENGINE_MINIGAMES_SHVEIK_SHKATULKA_H
#include "common/debug.h"
#include "qdengine/qd_fwd.h"
#include "qdengine/qdcore/qd_minigame_interface.h"
namespace QDEngine {
class qdShveikShkatulkaMiniGame : public qdMiniGameInterface {
public:
qdShveikShkatulkaMiniGame() {}
~qdShveikShkatulkaMiniGame() {}
bool init(const qdEngineInterface *engine_interface) {
debugC(1, kDebugMinigames, "ShveikShkatulka::init()");
_engine = engine_interface;
_scene = engine_interface->current_scene_interface();
if (!_scene)
return false;
_stones[0] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x31"); // "камень1"
_stones[1] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x32"); // "камень2"
_stones[2] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x33"); // "камень3"
_stones[3] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x34"); // "камень4"
_stones[4] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x35"); // "камень5"
_stones[5] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x36"); // "камень6"
_stones[6] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x37"); // "камень7"
_stones[7] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x38"); // "камень8"
_stones[8] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x39"); // "камень9"
_stones[9] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x31\x30"); // "камень10"
_stones[10] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x31\x31"); // "камень11"
_stones[11] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x31\x32"); // "камень12"
_stones[12] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x31\x33"); // "камень13"
_stones[13] = _scene->object_interface("\xea\xe0\xec\xe5\xed\xfc\x31\x34"); // "камень14"
_cursorObj = _scene->object_interface("\xea\xf3\xf0\xf1\xee\xf0"); // "курсор"
_doneObj = _scene->object_interface("$done");
_startObj = _scene->object_interface("\x24\xe7\xe0\xef\xf3\xf1\xea"); // "$запуск"
_jumpSoundObj = _scene->object_interface("\xe7\xe2\xf3\xea\x20\xef\xe5\xf0\xe5\xf1\xea\xee\xea\xe0"); // "звук перескока"
_direction = kDirNone;
_cursorTakenFlag = 0;
_someVar3 = 0;
_needSnap = false;
if (_startObj->is_state_active("\xed\xe5\x20\xe1\xfb\xeb")) { // "не был"
resetStones();
_startObj->set_state("\xe1\xfb\xeb"); // "был"
}
return true;
}
enum {
kDirNone,
kDirUp,
kDirRight,
kDirDown,
kDirLeft
};
bool quant(float dt) {
debugC(3, kDebugMinigames, "ShveikShkatulka::quant(%f)", dt);
if (checkSolution()) {
_doneObj->set_state("\xe4\xe0"); // "да"
_cursorObj->set_state("nottaken");
_draggedStone = 0;
_direction = kDirNone;
_cursorTakenFlag = 0;
_someVar3 = 0;
_needSnap = 0;
return true;
}
if (_engine->is_mouse_event_active(qdmg::qdEngineInterfaceImpl::MOUSE_EV_LEFT_DOWN)
&& _scene->mouse_click_object_interface()) {
const char *state = _scene->mouse_click_object_interface()->current_state_name();
if (state[0] == '1' || state[0] == '2') {
_draggedStone = _scene->mouse_click_object_interface();
_mousePos = _engine->mouse_cursor_position();
_cursorTakenFlag = 1;
_someVar3 = 1;
} else if (state[0] == '0') {
resetStones();
}
}
if (_engine->is_mouse_event_active(qdmg::qdEngineInterfaceImpl::MOUSE_EV_LEFT_UP) && _cursorTakenFlag) {
_draggedStone = 0;
_cursorTakenFlag = 0;
_someVar3 = 0;
_needSnap = false;
_direction = kDirNone;
}
mgVect2i curPos = _engine->mouse_cursor_position();
if (_cursorTakenFlag) {
if (!_needSnap) {
_mouseDelta.x = curPos.x - _mousePos.x;
_mouseDelta.y = curPos.y - _mousePos.y;
if (ABS(_mouseDelta.x) <= ABS(_mouseDelta.y)) { // Going down
const char *state = _draggedStone->current_state_name();
int draggedStonePos;
if (state[2] == '\0')
draggedStonePos = state[1] - '0';
else if (state[2] == '0')
draggedStonePos = 10;
else
draggedStonePos = 11;
int off = 60;
if (draggedStonePos == 3 || draggedStonePos == 8) {
int delta = 0;
if (curPos.y <= _mousePos.y) {
if (draggedStonePos == 3)
delta = 186;
else
delta = 0;
} else {
if (draggedStonePos == 8)
delta = 196;
else
delta = 0;
}
off = delta + 150;
}
if (ABS(_mouseDelta.y) > off) {
if (curPos.y <= _mousePos.y)
_direction = kDirUp;
else
_direction = kDirDown;
_needSnap = true;
}
} else if (ABS(_mouseDelta.x) > 60) {
if (curPos.x <= _mousePos.x)
_direction = kDirLeft;
else
_direction = kDirRight;
_needSnap = true;
}
}
if (_cursorTakenFlag && _needSnap) {
const char *state = _draggedStone->current_state_name();
int draggedStonePos;
if (state[2] == '\0')
draggedStonePos = state[1] - '0';
else if (state[2] == '0')
draggedStonePos = 10;
else
draggedStonePos = 11;
int side = state[0] - '0';
int pos = -1;
if (side == 1) {
switch (_direction) {
case kDirUp:
if (draggedStonePos != 8 || checkStonePosition(3, 1) || checkStonePosition(8, 2))
break;
pos = 3;
break;
case kDirRight:
if (draggedStonePos == 4
|| draggedStonePos == 11
|| checkStonePosition(draggedStonePos + 1, 1)
|| checkStonePosition(draggedStonePos, 2))
break;
pos = draggedStonePos + 1;
break;
case kDirDown:
if (draggedStonePos != 3 || checkStonePosition(8, 1) || checkStonePosition(8, 2))
break;
pos = 8;
break;
case kDirLeft:
if (draggedStonePos == 1
|| draggedStonePos == 5
|| checkStonePosition(draggedStonePos - 1, 1)
|| checkStonePosition(draggedStonePos - 1, 2))
break;
pos = draggedStonePos - 1;
break;
default:
break;
}
} else {
switch (_direction) {
case kDirUp:
if (draggedStonePos != 8 || checkStonePosition(3, 1) || checkStonePosition(3, 2))
break;
pos = 3;
break;
case kDirRight:
if (draggedStonePos == 4
|| draggedStonePos == 11
|| checkStonePosition(draggedStonePos + 1, 1)
|| checkStonePosition(draggedStonePos + 1, 2))
break;
pos = draggedStonePos + 1;
break;
case kDirDown:
if (draggedStonePos != 3 || checkStonePosition(8, 2) || checkStonePosition(3, 1))
break;
pos = 8;
break;
case kDirLeft:
if (draggedStonePos == 1
|| draggedStonePos == 5
|| checkStonePosition(draggedStonePos, 1)
|| checkStonePosition(draggedStonePos - 1, 2))
break;
pos = draggedStonePos - 1;
break;
default:
break;
}
}
if (pos == -1) {
_cursorTakenFlag = 0;
_someVar3 = 0;
} else {
_draggedStone->set_state(Common::String::format("%d%d", side, pos).c_str());
_mousePos = curPos;
_jumpSoundObj->set_state("\xe4\xe0"); // "да"
}
_direction = kDirNone;
_needSnap = false;
}
}
if (_cursorTakenFlag)
_cursorObj->set_state("taken");
else
_cursorObj->set_state("nottaken");
return true;
}
bool finit() {
debugC(1, kDebugMinigames, "ShveikShkatulka::finit()");
if (_scene) {
_engine->release_scene_interface(_scene);
_scene = 0;
}
return true;
}
bool new_game(const qdEngineInterface *engine_interface) {
return true;
}
int save_game(const qdEngineInterface *engine_interface, const qdMinigameSceneInterface *scene_interface, char *buffer, int buffer_size) {
return 0;
}
int load_game(const qdEngineInterface *engine_interface, const qdMinigameSceneInterface *scene_interface, const char *buffer, int buffer_size) {
return 0;
}
enum { INTERFACE_VERSION = 112 };
int version() const {
return INTERFACE_VERSION;
}
private:
void resetStones() {
_stones[0]->set_state("15");
_stones[1]->set_state("16");
_stones[2]->set_state("17");
_stones[3]->set_state("110");
_stones[4]->set_state("11");
_stones[5]->set_state("12");
_stones[6]->set_state("14");
_stones[7]->set_state("26");
_stones[8]->set_state("27");
_stones[9]->set_state("210");
_stones[10]->set_state("211");
_stones[11]->set_state("21");
_stones[12]->set_state("22");
_stones[13]->set_state("24");
}
bool checkSolution() {
return
_stones[0]->is_state_active("110")
&& _stones[1]->is_state_active("16")
&& _stones[2]->is_state_active("17")
&& _stones[3]->is_state_active("18")
&& _stones[4]->is_state_active("15")
&& _stones[5]->is_state_active("111")
&& _stones[6]->is_state_active("19")
&& _stones[7]->is_state_active("26")
&& _stones[8]->is_state_active("28")
&& _stones[9]->is_state_active("210")
&& _stones[10]->is_state_active("211")
&& _stones[11]->is_state_active("29")
&& _stones[12]->is_state_active("27")
&& _stones[13]->is_state_active("25");
}
bool checkStonePosition(int targetPos, int leftStones) {
int n = leftStones == 1 ? 0 : 7;
for (int i = 0; i < 7; i++) {
const char *state = _stones[n + i]->current_state_name();
int pos;
if (state[2] == '\0')
pos = state[1] - '0';
else if (state[2] == '0')
pos = 10;
else
pos = 11;
if (pos == targetPos)
return true;
}
return false;
}
private:
const qdEngineInterface *_engine = nullptr;
qdMinigameSceneInterface *_scene = nullptr;
int _direction = kDirNone;
bool _cursorTakenFlag = false;
mgVect2i _mousePos;
mgVect2i _mouseDelta;
int _someVar3 = 0;
bool _needSnap = false;
qdMinigameObjectInterface *_stones[14] = { nullptr };
qdMinigameObjectInterface *_draggedStone = nullptr;
qdMinigameObjectInterface *_cursorObj = nullptr;
qdMinigameObjectInterface *_doneObj = nullptr;
qdMinigameObjectInterface *_startObj = nullptr;
qdMinigameObjectInterface *_jumpSoundObj = nullptr;
};
} // namespace QDEngine
#endif // QDENGINE_MINIGAMES_SHVEIK_SHKATULKA_H