Initial commit
This commit is contained in:
346
engines/ultima/nuvie/views/actor_view.cpp
Normal file
346
engines/ultima/nuvie/views/actor_view.cpp
Normal file
@@ -0,0 +1,346 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
#include "ultima/nuvie/script/script.h"
|
||||
#include "ultima/nuvie/views/view.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/core/party.h"
|
||||
#include "ultima/nuvie/portraits/portrait.h"
|
||||
#include "ultima/nuvie/views/actor_view.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
extern GUI_status inventoryViewButtonCallback(void *data);
|
||||
extern GUI_status partyViewButtonCallback(void *data);
|
||||
|
||||
#define MD Game::get_game()->get_game_type()==NUVIE_GAME_MD
|
||||
|
||||
|
||||
ActorView::ActorView(const Configuration *cfg) : View(cfg), portrait(nullptr),
|
||||
portrait_data(nullptr), in_party(false), cursor_tile(nullptr),
|
||||
show_cursor(false) {
|
||||
cursor_pos.x = 2;
|
||||
cursor_pos.px = cursor_pos.py = 0;
|
||||
}
|
||||
|
||||
ActorView::~ActorView() {
|
||||
if (portrait_data != nullptr)
|
||||
free(portrait_data);
|
||||
}
|
||||
|
||||
bool ActorView::init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om, Portrait *port) {
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6)
|
||||
View::init(x, y, f, p, tm, om);
|
||||
else
|
||||
View::init(x, y - 2, f, p, tm, om);
|
||||
|
||||
portrait = port;
|
||||
|
||||
add_command_icons(tmp_screen, view_manager);
|
||||
|
||||
set_party_member(0);
|
||||
cursor_tile = tile_manager->get_cursor_tile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ActorView::set_party_member(uint8 party_member) {
|
||||
in_party = false;
|
||||
|
||||
if (View::set_party_member(party_member)
|
||||
&& !Game::get_game()->get_event()->using_control_cheat()) {
|
||||
in_party = true;
|
||||
if (party_button) party_button->Show();
|
||||
} else {
|
||||
if (left_button) left_button->Hide();
|
||||
if (right_button) right_button->Hide();
|
||||
if (party_button) party_button->Hide();
|
||||
}
|
||||
|
||||
if (portrait) { // this might not be set yet. if called from View::init()
|
||||
if (portrait_data)
|
||||
free(portrait_data);
|
||||
|
||||
if (in_party)
|
||||
portrait_data = portrait->get_portrait_data(party->get_actor(cur_party_member));
|
||||
else {
|
||||
Player *player = Game::get_game()->get_player();
|
||||
portrait_data = portrait->get_portrait_data(player->get_actor());
|
||||
}
|
||||
if (portrait_data == nullptr)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ActorView::Display(bool full_redraw) {
|
||||
|
||||
if (portrait_data != nullptr && (full_redraw || update_display || Game::get_game()->is_original_plus_full_map())) {
|
||||
update_display = false;
|
||||
if (MD) {
|
||||
fill_md_background(bg_color, area);
|
||||
screen->blit(area.left + 1, area.top + 16, portrait_data, 8, portrait->get_portrait_width(), portrait->get_portrait_height(), portrait->get_portrait_width(), true);
|
||||
} else {
|
||||
screen->fill(bg_color, area.left, area.top, area.width(), area.height());
|
||||
screen->blit(area.left, area.top + 8, portrait_data, 8, portrait->get_portrait_width(), portrait->get_portrait_height(), portrait->get_portrait_width(), false);
|
||||
}
|
||||
display_name();
|
||||
display_actor_stats();
|
||||
DisplayChildren(); //draw buttons
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
if (show_cursor && cursor_tile != nullptr) {
|
||||
screen->blit(cursor_pos.px, cursor_pos.py, (unsigned char *)cursor_tile->data,
|
||||
8, 16, 16, 16, true, nullptr);
|
||||
screen->update(cursor_pos.px, cursor_pos.py, 16, 16);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ActorView::add_command_icons(Screen *tmp_screen, void *view_manager) {
|
||||
int x_off = 0; // U6 and MD
|
||||
int y = 80; // U6
|
||||
Tile *tile;
|
||||
Graphics::ManagedSurface *button_image;
|
||||
Graphics::ManagedSurface *button_image2;
|
||||
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_SE) {
|
||||
x_off = 1;
|
||||
y = 96;
|
||||
} else if (MD)
|
||||
y = 100;
|
||||
|
||||
//FIX need to handle clicked button image, check image free on destruct.
|
||||
|
||||
tile = tile_manager->get_tile(MD ? 282 : 387); //left arrow icon
|
||||
button_image = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
button_image2 = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
left_button = new GUI_Button(this, x_off, y, button_image, button_image2, this);
|
||||
this->AddWidget(left_button);
|
||||
|
||||
tile = tile_manager->get_tile(MD ? 279 : 384); //party view icon
|
||||
button_image = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
button_image2 = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
party_button = new GUI_Button(view_manager, 16 + x_off, y, button_image, button_image2, this);
|
||||
this->AddWidget(party_button);
|
||||
|
||||
tile = tile_manager->get_tile(MD ? 281 : 386); //inventory view icon
|
||||
button_image = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
button_image2 = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
inventory_button = new GUI_Button(view_manager, 2 * 16 + x_off, y, button_image, button_image2, this);
|
||||
this->AddWidget(inventory_button);
|
||||
|
||||
tile = tile_manager->get_tile(MD ? 283 : 388); //right arrow icon
|
||||
button_image = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
button_image2 = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
right_button = new GUI_Button(this, 3 * 16 + x_off, y, button_image, button_image2, this);
|
||||
this->AddWidget(right_button);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ActorView::display_name() {
|
||||
const char *name;
|
||||
int y_off = 0;
|
||||
if (MD)
|
||||
y_off = 4;
|
||||
else if (Game::get_game()->get_game_type() == NUVIE_GAME_SE)
|
||||
y_off = 1;
|
||||
|
||||
if (in_party)
|
||||
name = party->get_actor_name(cur_party_member);
|
||||
else
|
||||
name = Game::get_game()->get_player()->get_actor()->get_name(true);
|
||||
|
||||
if (name == nullptr)
|
||||
return;
|
||||
|
||||
font->drawString(screen, name, area.left + ((136) - strlen(name) * 8) / 2, area.top + y_off);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ActorView::display_actor_stats() {
|
||||
Actor *actor;
|
||||
char buf[10];
|
||||
int x_off = 0;
|
||||
int y_off = 0;
|
||||
uint8 hp_text_color = 0; //standard text color
|
||||
|
||||
if (in_party)
|
||||
actor = party->get_actor(cur_party_member);
|
||||
else
|
||||
actor = Game::get_game()->get_player()->get_actor();
|
||||
|
||||
if (MD) {
|
||||
x_off = -1;
|
||||
} else if (Game::get_game()->get_game_type() == NUVIE_GAME_SE) {
|
||||
x_off = 2;
|
||||
y_off = - 6;
|
||||
}
|
||||
|
||||
hp_text_color = actor->get_hp_text_color();
|
||||
|
||||
Common::sprintf_s(buf, "%d", Game::get_game()->get_script()->call_actor_str_adj(actor)); //actor->get_strength());
|
||||
uint8 str_len = font->drawString(screen, "STR:", area.left + 5 * 16 + x_off, area.top + y_off + 16);
|
||||
font->drawString(screen, buf, area.left + 5 * 16 + x_off + str_len, area.top + y_off + 16, actor->get_str_text_color(), 0);
|
||||
|
||||
Common::sprintf_s(buf, "%d", Game::get_game()->get_script()->call_actor_dex_adj(actor));
|
||||
str_len = font->drawString(screen, "DEX:", area.left + 5 * 16 + x_off, area.top + y_off + 16 + 8);
|
||||
font->drawString(screen, buf, area.left + 5 * 16 + x_off + str_len, area.top + y_off + 16 + 8, actor->get_dex_text_color(), 0);
|
||||
|
||||
Common::sprintf_s(buf, "INT:%d", Game::get_game()->get_script()->call_actor_int_adj(actor));
|
||||
font->drawString(screen, buf, area.left + 5 * 16 + x_off, area.top + y_off + 16 + 2 * 8);
|
||||
|
||||
if (MD || Game::get_game()->get_game_type() == NUVIE_GAME_SE) {
|
||||
Common::sprintf_s(buf, "%3d", actor->get_hp());
|
||||
str_len = font->drawString(screen, "HP:", area.left + 5 * 16 + x_off, area.top + y_off + 16 + 3 * 8);
|
||||
font->drawString(screen, buf, strlen(buf), area.left + 5 * 16 + x_off + str_len, area.top + y_off + 16 + 3 * 8, hp_text_color, 0);
|
||||
|
||||
Common::sprintf_s(buf, "HM:%3d", actor->get_maxhp());
|
||||
font->drawString(screen, buf, area.left + 5 * 16 + x_off, area.top + y_off + 16 + 4 * 8);
|
||||
|
||||
Common::sprintf_s(buf, "Lev:%2d", actor->get_level());
|
||||
font->drawString(screen, buf, area.left + 5 * 16 + x_off, area.top + y_off + 16 + 5 * 8);
|
||||
|
||||
font->drawString(screen, "Exper:", area.left + 5 * 16 + x_off, area.top + y_off + 16 + 6 * 8);
|
||||
Common::sprintf_s(buf, "%6d", actor->get_exp());
|
||||
font->drawString(screen, buf, area.left + 5 * 16 + x_off, area.top + y_off + 16 + 7 * 8);
|
||||
return;
|
||||
}
|
||||
|
||||
font->drawString(screen, "Magic", area.left + 5 * 16, area.top + 16 + 4 * 8);
|
||||
Common::sprintf_s(buf, "%d/%d", actor->get_magic(), actor->get_maxmagic());
|
||||
font->drawString(screen, buf, area.left + 5 * 16, area.top + 16 + 5 * 8);
|
||||
|
||||
font->drawString(screen, "Health", area.left + 5 * 16, area.top + 16 + 6 * 8);
|
||||
Common::sprintf_s(buf, "%3d", actor->get_hp());
|
||||
font->drawString(screen, buf, strlen(buf), area.left + 5 * 16, area.top + 16 + 7 * 8, hp_text_color, 0);
|
||||
Common::sprintf_s(buf, " /%d", actor->get_maxhp());
|
||||
font->drawString(screen, buf, area.left + 5 * 16, area.top + 16 + 7 * 8);
|
||||
|
||||
font->drawString(screen, "Lev/Exp", area.left + 5 * 16, area.top + 16 + 8 * 8);
|
||||
Common::sprintf_s(buf, "%d/%d", actor->get_level(), actor->get_exp());
|
||||
font->drawString(screen, buf, area.left + 5 * 16, area.top + 16 + 9 * 8);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GUI_status ActorView::MouseWheel(sint32 x, sint32 y) {
|
||||
int xpos, ypos;
|
||||
screen->get_mouse_location(&xpos, &ypos);
|
||||
|
||||
xpos -= area.left;
|
||||
ypos -= area.top;
|
||||
if (xpos < 0 || ypos > area.top + area.height() - 7)
|
||||
return GUI_PASS; // goes to MsgScroll
|
||||
|
||||
if (y > 0) {
|
||||
View::callback(BUTTON_CB, left_button, Game::get_game()->get_view_manager());
|
||||
} else if (y < 0) {
|
||||
View::callback(BUTTON_CB, right_button, Game::get_game()->get_view_manager());
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status ActorView::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
/* Move the cursor around and use command icons.
|
||||
*/
|
||||
GUI_status ActorView::KeyDown(const Common::KeyState &key) {
|
||||
if (!show_cursor) // FIXME: don't rely on show_cursor to get/pass focus
|
||||
return GUI_PASS;
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
|
||||
switch (keybinder->GetActionKeyType(a)) {
|
||||
case SOUTH_WEST_KEY:
|
||||
case NORTH_WEST_KEY:
|
||||
case WEST_KEY:
|
||||
moveCursorToButton(cursor_pos.x - 1);
|
||||
break;
|
||||
case NORTH_EAST_KEY:
|
||||
case SOUTH_EAST_KEY:
|
||||
case EAST_KEY:
|
||||
moveCursorToButton(cursor_pos.x + 1);
|
||||
break;
|
||||
case DO_ACTION_KEY:
|
||||
select_button();
|
||||
break;
|
||||
case NORTH_KEY: // would otherwise move invisible mapwindow cursor
|
||||
case SOUTH_KEY:
|
||||
break;
|
||||
default:
|
||||
// set_show_cursor(false); // newAction() can move cursor here
|
||||
return GUI_PASS;
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
/* Put cursor over one of the command icons. */
|
||||
void ActorView::moveCursorToButton(sint8 button_num) {
|
||||
if (button_num < 0 || button_num > 3)
|
||||
return;
|
||||
cursor_pos.x = button_num;
|
||||
update_cursor();
|
||||
update_display = true;
|
||||
}
|
||||
|
||||
/* Update on-screen location (px,py) of cursor.
|
||||
*/
|
||||
void ActorView::update_cursor() {
|
||||
cursor_pos.px = ((cursor_pos.x + 1) * 16) - 16;
|
||||
cursor_pos.py = party_button->area.top;
|
||||
cursor_pos.px += area.left;
|
||||
//cursor_pos.py += area.top;
|
||||
}
|
||||
|
||||
void ActorView::set_show_cursor(bool state) {
|
||||
show_cursor = state;
|
||||
update_display = true;
|
||||
}
|
||||
|
||||
void ActorView::select_button() {
|
||||
ViewManager *view_manager = Game::get_game()->get_view_manager();
|
||||
if (cursor_pos.x == 0) // left
|
||||
View::callback(BUTTON_CB, left_button, view_manager);
|
||||
if (cursor_pos.x == 1) // party
|
||||
View::callback(BUTTON_CB, party_button, view_manager);
|
||||
if (cursor_pos.x == 2) // inventory
|
||||
View::callback(BUTTON_CB, inventory_button, view_manager);
|
||||
if (cursor_pos.x == 3) // right
|
||||
View::callback(BUTTON_CB, right_button, view_manager);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
81
engines/ultima/nuvie/views/actor_view.h
Normal file
81
engines/ultima/nuvie/views/actor_view.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* 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 NUVIE_VIEWS_ACTOR_VIEW_H
|
||||
#define NUVIE_VIEWS_ACTOR_VIEW_H
|
||||
|
||||
#include "ultima/nuvie/views/view.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class Screen;
|
||||
class Font;
|
||||
class TileManager;
|
||||
class ObjManager;
|
||||
class Portrait;
|
||||
class Party;
|
||||
|
||||
class ActorView : public View {
|
||||
|
||||
Portrait *portrait;
|
||||
|
||||
unsigned char *portrait_data;
|
||||
struct actcursor_pos_s {
|
||||
uint8 x;
|
||||
uint32 px, py;
|
||||
} cursor_pos;
|
||||
Tile *cursor_tile;
|
||||
bool show_cursor;
|
||||
|
||||
public:
|
||||
ActorView(const Configuration *cfg);
|
||||
~ActorView() override;
|
||||
|
||||
bool init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om, Portrait *port);
|
||||
|
||||
bool set_party_member(uint8 party_member) override;
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
void update() {
|
||||
update_display = true;
|
||||
}
|
||||
void set_show_cursor(bool state);
|
||||
void moveCursorToButton(sint8 button_num);
|
||||
|
||||
protected:
|
||||
|
||||
void add_command_icons(Screen *tmp_screen, void *view_manager);
|
||||
void display_name();
|
||||
void display_actor_stats();
|
||||
bool in_party;
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
void update_cursor();
|
||||
void select_button();
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
399
engines/ultima/nuvie/views/container_view_gump.cpp
Normal file
399
engines/ultima/nuvie/views/container_view_gump.cpp
Normal file
@@ -0,0 +1,399 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
#include "ultima/nuvie/core/u6_objects.h"
|
||||
#include "ultima/nuvie/core/party.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/fonts/font_manager.h"
|
||||
#include "ultima/nuvie/views/container_widget_gump.h"
|
||||
#include "ultima/nuvie/views/container_view_gump.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static const int CONTAINER_WIDGET_OFFSET = 29;
|
||||
#define CHECK_X 0
|
||||
|
||||
ContainerViewGump::ContainerViewGump(const Configuration *cfg) : DraggableView(cfg),
|
||||
gump_button(nullptr), up_arrow_button(nullptr), down_arrow_button(nullptr),
|
||||
doll_button(nullptr), left_arrow_button(nullptr),
|
||||
right_arrow_button(nullptr), container_widget(nullptr), font(nullptr),
|
||||
actor(nullptr), container_obj(nullptr), container_widget_y_offset(0) {
|
||||
}
|
||||
|
||||
ContainerViewGump::~ContainerViewGump() {
|
||||
}
|
||||
|
||||
bool ContainerViewGump::init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om, Obj *container_obj_type) {
|
||||
View::init(x, y, f, p, tm, om);
|
||||
|
||||
//actor = p->get_actor(p->get_leader()); don't have party leader as default, get owner of container obj or leave nullptr (moved to init_container_type)
|
||||
|
||||
Common::Path datadir = GUI::get_gui()->get_data_dir();
|
||||
Common::Path imagefile;
|
||||
Common::Path path;
|
||||
|
||||
build_path(datadir, "images", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "gumps", path);
|
||||
datadir = path;
|
||||
|
||||
init_container_type(datadir, container_obj_type);
|
||||
|
||||
set_bg_color_key(0, 0x70, 0xfc);
|
||||
|
||||
//font = new GUI_Font(GUI_FONT_GUMP);
|
||||
//font->setColoring( 0x08, 0x08, 0x08, 0x80, 0x58, 0x30, 0x00, 0x00, 0x00);
|
||||
font = f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ContainerViewGump::init_container_type(const Common::Path &datadir, Obj *obj_type) {
|
||||
|
||||
|
||||
if (obj_type != nullptr) {
|
||||
if (obj_type->is_in_inventory())
|
||||
actor = obj_type->get_actor_holding_obj();
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6) {
|
||||
if (obj_type->obj_n == OBJ_U6_CHEST)
|
||||
return init_chest(datadir);
|
||||
else if (obj_type->obj_n == OBJ_U6_CRATE)
|
||||
return init_crate(datadir);
|
||||
else if (obj_type->obj_n == OBJ_U6_BARREL)
|
||||
return init_barrel(datadir);
|
||||
else if (obj_type->obj_n == OBJ_U6_DEAD_GARGOYLE)
|
||||
return init_corpse(datadir, "corpse_gargoyle_bg.bmp");
|
||||
else if (obj_type->obj_n == OBJ_U6_DEAD_BODY
|
||||
|| obj_type->obj_n == OBJ_U6_GRAVE || obj_type->obj_n == OBJ_U6_REMAINS)
|
||||
return init_corpse(datadir, "corpse_body_bg.bmp");
|
||||
else if (obj_type->obj_n == OBJ_U6_DEAD_CYCLOPS)
|
||||
return init_corpse(datadir, "corpse_cyclops_bg.bmp");
|
||||
else if (obj_type->obj_n == OBJ_U6_DEAD_ANIMAL || obj_type->obj_n == OBJ_U6_MOUSE
|
||||
|| obj_type->obj_n == OBJ_U6_MONGBAT || obj_type->obj_n == OBJ_U6_DRAKE
|
||||
|| obj_type->obj_n == OBJ_U6_REAPER)
|
||||
return init_corpse(datadir, "corpse_animal_bg.bmp");
|
||||
}
|
||||
}
|
||||
|
||||
return init_backpack(datadir, obj_type ? !obj_type->is_in_inventory() : true);
|
||||
}
|
||||
|
||||
void ContainerViewGump::init_backpack(const Common::Path &datadir, bool extend_area_w) {
|
||||
Common::Path imagefile, path;
|
||||
uint8 check_y = 27;
|
||||
gump_button = loadButton(datadir, "gump", CHECK_X, check_y);
|
||||
|
||||
build_path(datadir, "container", path);
|
||||
|
||||
up_arrow_button = loadButton(path, "cont_up", 83, 35);
|
||||
down_arrow_button = loadButton(path, "cont_down", 83, 66);
|
||||
|
||||
build_path(path, "backpack_bg.bmp", imagefile);
|
||||
|
||||
bg_image = SDL_LoadBMP(imagefile);
|
||||
|
||||
doll_button = loadButton(path, "cont_doll", area.left + 18, area.top + bg_image->h);
|
||||
left_arrow_button = loadButton(path, "cont_left", area.left + 18 + 11, area.top + bg_image->h);
|
||||
right_arrow_button = loadButton(path, "cont_right", area.left + 18 + 22, area.top + bg_image->h);
|
||||
|
||||
SetRect(area.left, area.top, bg_image->w, bg_image->h + 16); //111, 101);
|
||||
|
||||
container_widget = new ContainerWidgetGump(config, this);
|
||||
container_widget_y_offset = CONTAINER_WIDGET_OFFSET;
|
||||
container_widget->init(actor, 21, container_widget_y_offset, 4, 3, tile_manager, obj_manager, font, CHECK_X, check_y);
|
||||
|
||||
AddWidget(container_widget);
|
||||
if (extend_area_w) // text extends beyond the gump
|
||||
area.right += 4;
|
||||
}
|
||||
|
||||
void ContainerViewGump::init_chest(const Common::Path &datadir) {
|
||||
Common::Path imagefile, path;
|
||||
uint8 check_y = 56;
|
||||
gump_button = loadButton(datadir, "gump", CHECK_X, check_y);
|
||||
|
||||
build_path(datadir, "container", path);
|
||||
|
||||
up_arrow_button = loadButton(path, "cont_up", 85, 31);
|
||||
down_arrow_button = loadButton(path, "cont_down", 85, 47);
|
||||
|
||||
build_path(path, "chest_bg.bmp", imagefile);
|
||||
|
||||
bg_image = SDL_LoadBMP(imagefile);
|
||||
|
||||
SetRect(area.left, area.top, bg_image->w, bg_image->h + 16); //111, 101);
|
||||
|
||||
container_widget = new ContainerWidgetGump(config, this);
|
||||
container_widget_y_offset = CONTAINER_WIDGET_OFFSET - 1;
|
||||
container_widget->init(actor, 21, container_widget_y_offset, 4, 2, tile_manager, obj_manager, font, CHECK_X, check_y);
|
||||
|
||||
AddWidget(container_widget);
|
||||
}
|
||||
|
||||
void ContainerViewGump::init_crate(const Common::Path &datadir) {
|
||||
Common::Path imagefile, path;
|
||||
uint8 check_y = 63;
|
||||
gump_button = loadButton(datadir, "gump", CHECK_X, check_y);
|
||||
|
||||
build_path(datadir, "container", path);
|
||||
|
||||
up_arrow_button = loadButton(path, "cont_up", 100, 15);
|
||||
down_arrow_button = loadButton(path, "cont_down", 100, 46);
|
||||
|
||||
build_path(path, "crate_bg.bmp", imagefile);
|
||||
|
||||
bg_image = SDL_LoadBMP(imagefile);
|
||||
|
||||
SetRect(area.left, area.top, bg_image->w, bg_image->h);
|
||||
|
||||
container_widget = new ContainerWidgetGump(config, this);
|
||||
container_widget_y_offset = 10;
|
||||
container_widget->init(actor, 21, container_widget_y_offset, 5, 3, tile_manager, obj_manager, font, CHECK_X, check_y);
|
||||
|
||||
AddWidget(container_widget);
|
||||
}
|
||||
|
||||
void ContainerViewGump::init_barrel(const Common::Path &datadir) {
|
||||
Common::Path imagefile, path;
|
||||
uint8 check_y = 55;
|
||||
gump_button = loadButton(datadir, "gump", CHECK_X, check_y);
|
||||
|
||||
build_path(datadir, "container", path);
|
||||
|
||||
up_arrow_button = loadButton(path, "cont_up", 102, 28);
|
||||
down_arrow_button = loadButton(path, "cont_down", 102, 42);
|
||||
|
||||
build_path(path, "barrel_bg.bmp", imagefile);
|
||||
|
||||
bg_image = SDL_LoadBMP(imagefile);
|
||||
|
||||
SetRect(area.left, area.top, bg_image->w, bg_image->h);
|
||||
|
||||
container_widget = new ContainerWidgetGump(config, this);
|
||||
container_widget_y_offset = 24;
|
||||
container_widget->init(actor, 38, container_widget_y_offset, 4, 2, tile_manager, obj_manager, font, CHECK_X, check_y);
|
||||
|
||||
AddWidget(container_widget);
|
||||
}
|
||||
|
||||
void ContainerViewGump::init_corpse(const Common::Path &datadir, Std::string bg_filename) {
|
||||
Common::Path imagefile, path;
|
||||
uint8 check_y = 25;
|
||||
gump_button = loadButton(datadir, "gump", CHECK_X, check_y);
|
||||
|
||||
build_path(datadir, "container", path);
|
||||
|
||||
up_arrow_button = loadButton(path, "cont_up", 67, 28);
|
||||
down_arrow_button = loadButton(path, "cont_down", 67, 78);
|
||||
|
||||
build_path(path, bg_filename, imagefile);
|
||||
|
||||
bg_image = SDL_LoadBMP(imagefile);
|
||||
|
||||
SetRect(area.left, area.top, bg_image->w, bg_image->h);
|
||||
|
||||
container_widget = new ContainerWidgetGump(config, this);
|
||||
container_widget_y_offset = 26;
|
||||
container_widget->init(actor, 20, container_widget_y_offset, 3, 4, tile_manager, obj_manager, font, CHECK_X, check_y);
|
||||
|
||||
AddWidget(container_widget);
|
||||
}
|
||||
void ContainerViewGump::set_actor(Actor *a) {
|
||||
actor = a;
|
||||
container_obj = nullptr;
|
||||
container_widget->set_actor(a);
|
||||
if (doll_button)
|
||||
doll_button->Show();
|
||||
if (party->get_member_num(a) >= 0) {
|
||||
if (left_arrow_button)
|
||||
left_arrow_button->Show();
|
||||
if (right_arrow_button)
|
||||
right_arrow_button->Show();
|
||||
} else {
|
||||
if (left_arrow_button)
|
||||
left_arrow_button->Hide();
|
||||
if (right_arrow_button)
|
||||
right_arrow_button->Hide();
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerViewGump::set_container_obj(Obj *o) {
|
||||
container_obj = o;
|
||||
container_widget->set_container(container_obj);
|
||||
if (doll_button)
|
||||
doll_button->Hide();
|
||||
if (left_arrow_button)
|
||||
left_arrow_button->Hide();
|
||||
if (right_arrow_button)
|
||||
right_arrow_button->Hide();
|
||||
}
|
||||
|
||||
void ContainerViewGump::Display(bool full_redraw) {
|
||||
//display_level_text();
|
||||
//display_spell_list_text();
|
||||
Common::Rect dst;
|
||||
dst = area;
|
||||
SDL_BlitSurface(bg_image, nullptr, surface, &dst);
|
||||
|
||||
DisplayChildren(full_redraw);
|
||||
|
||||
if (actor) {
|
||||
font->drawString(screen, actor->get_name(), area.left + 18, area.top + 2, 15, 15);
|
||||
display_inventory_weight();
|
||||
}
|
||||
update_display = false;
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ContainerViewGump::display_inventory_weight() {
|
||||
uint8 strength = actor->get_strength();
|
||||
unsigned int equip_weight = Game::get_game()->get_view_manager()->get_display_weight(actor->get_inventory_weight());
|
||||
char string[11]; //I:nnn/nnns\0
|
||||
|
||||
snprintf(string, 10, "I:%u/%us", equip_weight, strength * 2);
|
||||
font->drawString(screen, string, area.left + (container_obj ? 18 : 18 + 34), area.top + bg_image->h + 2, 15, 15);
|
||||
}
|
||||
|
||||
void ContainerViewGump::left_arrow() {
|
||||
sint8 party_mem_num = party->get_member_num(actor);
|
||||
if (party_mem_num >= 0) {
|
||||
if (party_mem_num > 0)
|
||||
party_mem_num--;
|
||||
else
|
||||
party_mem_num = party->get_party_size() - 1;
|
||||
|
||||
set_actor(party->get_actor(party_mem_num));
|
||||
force_full_redraw_if_needed();
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerViewGump::right_arrow() {
|
||||
set_actor(party->get_actor((party->get_member_num(actor) + 1) % party->get_party_size()));
|
||||
force_full_redraw_if_needed();
|
||||
}
|
||||
|
||||
GUI_status ContainerViewGump::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
//close gump and return control to Magic class for clean up.
|
||||
if (caller == gump_button) {
|
||||
Game::get_game()->get_view_manager()->close_gump(this);
|
||||
return GUI_YUM;
|
||||
} else if (caller == down_arrow_button) {
|
||||
container_widget->down_arrow();
|
||||
return GUI_YUM;
|
||||
} else if (caller == up_arrow_button) {
|
||||
container_widget->up_arrow();
|
||||
return GUI_YUM;
|
||||
} else if (doll_button && caller == doll_button) {
|
||||
Game::get_game()->get_view_manager()->open_doll_view(actor);
|
||||
return GUI_YUM;
|
||||
} else if (left_arrow_button && caller == left_arrow_button) {
|
||||
left_arrow();
|
||||
return GUI_YUM;
|
||||
} else if (right_arrow_button && caller == right_arrow_button) {
|
||||
right_arrow();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status ContainerViewGump::KeyDown(const Common::KeyState &key) {
|
||||
if (left_arrow_button && left_arrow_button->Status() == WIDGET_VISIBLE) { // okay to change member number
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
|
||||
switch (keybinder->GetActionKeyType(a)) {
|
||||
case NEXT_PARTY_MEMBER_KEY:
|
||||
right_arrow();
|
||||
return GUI_YUM;
|
||||
case PREVIOUS_PARTY_MEMBER_KEY:
|
||||
left_arrow();
|
||||
return GUI_YUM;
|
||||
case HOME_KEY:
|
||||
set_actor(party->get_actor(0));
|
||||
force_full_redraw_if_needed();
|
||||
return GUI_YUM;
|
||||
case END_KEY:
|
||||
set_actor(party->get_actor(party->get_party_size() - 1));
|
||||
force_full_redraw_if_needed();
|
||||
return GUI_YUM;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* moved into container widget
|
||||
switch(key.keycode)
|
||||
{
|
||||
case Common::KEYCODE_RETURN:
|
||||
case Common::KEYCODE_KP_ENTER:
|
||||
|
||||
return GUI_YUM;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*/
|
||||
return container_widget->KeyDown(key);
|
||||
}
|
||||
|
||||
GUI_status ContainerViewGump::MouseWheel(sint32 x, sint32 y) {
|
||||
int xpos, ypos;
|
||||
screen->get_mouse_location(&xpos, &ypos);
|
||||
ypos -= area.top;
|
||||
|
||||
if (ypos >= container_widget_y_offset && ypos < container_widget_y_offset + container_widget->H()) {
|
||||
if (y > 0) {
|
||||
container_widget->up_arrow();
|
||||
} else if (y < 0) {
|
||||
container_widget->down_arrow();
|
||||
}
|
||||
} else {
|
||||
if (is_actor_container() && party->get_member_num(actor) >= 0) {
|
||||
if (y > 0) {
|
||||
left_arrow();
|
||||
} else if (y < 0) {
|
||||
right_arrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status ContainerViewGump::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
return DraggableView::MouseDown(x, y, button);
|
||||
}
|
||||
|
||||
GUI_status ContainerViewGump::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
return DraggableView::MouseUp(x, y, button);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
110
engines/ultima/nuvie/views/container_view_gump.h
Normal file
110
engines/ultima/nuvie/views/container_view_gump.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/* 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 NUVIE_VIEWS_CONTAINER_VIEW_GUMP_H
|
||||
#define NUVIE_VIEWS_CONTAINER_VIEW_GUMP_H
|
||||
|
||||
#include "ultima/nuvie/views/draggable_view.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class ObjManager;
|
||||
class Screen;
|
||||
class Actor;
|
||||
class Font;
|
||||
class U6Bmp;
|
||||
class Font;
|
||||
class ContainerWidgetGump;
|
||||
|
||||
class ContainerViewGump : public DraggableView {
|
||||
|
||||
GUI_Button *gump_button;
|
||||
GUI_Button *up_arrow_button;
|
||||
GUI_Button *down_arrow_button;
|
||||
GUI_Button *left_arrow_button;
|
||||
GUI_Button *right_arrow_button;
|
||||
GUI_Button *doll_button;
|
||||
|
||||
ContainerWidgetGump *container_widget;
|
||||
uint16 container_widget_y_offset;
|
||||
|
||||
Font *font;
|
||||
|
||||
Actor *actor;
|
||||
Obj *container_obj;
|
||||
|
||||
public:
|
||||
ContainerViewGump(const Configuration *cfg);
|
||||
~ContainerViewGump() override;
|
||||
|
||||
bool init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om, Obj *container_obj_type);
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
void set_actor(Actor *a);
|
||||
const Actor *get_actor() const {
|
||||
return actor;
|
||||
}
|
||||
void set_container_obj(Obj *o);
|
||||
const Obj *get_container_obj() const {
|
||||
return container_obj;
|
||||
}
|
||||
|
||||
bool is_actor_container() const {
|
||||
return container_obj == nullptr;
|
||||
}
|
||||
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override {
|
||||
return DraggableView::MouseMotion(x, y, state);
|
||||
}
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
void MoveRelative(int dx, int dy) override {
|
||||
return DraggableView::MoveRelative(dx, dy);
|
||||
}
|
||||
|
||||
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
protected:
|
||||
|
||||
void init_container_type(const Common::Path &datadir, Obj *obj_type);
|
||||
void init_backpack(const Common::Path &datadir, bool extend_area_w);
|
||||
void init_chest(const Common::Path &datadir);
|
||||
void init_crate(const Common::Path &datadir);
|
||||
void init_barrel(const Common::Path &datadir);
|
||||
void init_corpse(const Common::Path &datadir, Std::string bg_filename);
|
||||
void display_inventory_weight();
|
||||
|
||||
void left_arrow();
|
||||
void right_arrow();
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
549
engines/ultima/nuvie/views/container_widget.cpp
Normal file
549
engines/ultima/nuvie/views/container_widget.cpp
Normal file
@@ -0,0 +1,549 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_llist.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/screen/game_palette.h"
|
||||
#include "ultima/nuvie/views/container_widget.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/core/game_clock.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/core/timed_event.h"
|
||||
#include "ultima/nuvie/usecode/usecode.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/actors/actor_manager.h"
|
||||
#include "ultima/nuvie/script/script.h"
|
||||
#include "ultima/nuvie/views/inventory_font.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
ContainerWidget::ContainerWidget(const Configuration *cfg, GUI_CallBack *callback)
|
||||
: GUI_Widget(nullptr, 0, 0, 0, 0), config(cfg), callback_object(callback),
|
||||
container_obj(nullptr), tile_manager(nullptr), obj_manager(nullptr),
|
||||
selected_obj(nullptr), target_cont(nullptr), actor(nullptr),
|
||||
target_obj(nullptr), fill_bg(false), empty_tile(nullptr), row_offset(0),
|
||||
rows(0), cols(0), bg_color(0), obj_font_color(0) {
|
||||
ready_obj = nullptr; // FIXME: this is unused but I might need it again -- SB-X
|
||||
config->value("config/GameType", game_type);
|
||||
}
|
||||
|
||||
ContainerWidget::~ContainerWidget() {
|
||||
|
||||
}
|
||||
|
||||
bool ContainerWidget::init(Actor *a, uint16 x, uint16 y, TileManager *tm, ObjManager *om, Font *f) {
|
||||
tile_manager = tm;
|
||||
obj_manager = om;
|
||||
|
||||
rows = CONTAINER_WIDGET_ROWS;
|
||||
cols = CONTAINER_WIDGET_COLS;
|
||||
|
||||
bg_color = Game::get_game()->get_palette()->get_bg_color();
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6)
|
||||
obj_font_color = 0x48;
|
||||
else
|
||||
obj_font_color = 0;
|
||||
|
||||
fill_bg = true;
|
||||
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6)
|
||||
empty_tile = tile_manager->get_tile(410);
|
||||
else if (Game::get_game()->get_game_type() == NUVIE_GAME_MD) // FIXME: different depending on npc
|
||||
empty_tile = tile_manager->get_tile(273);
|
||||
else
|
||||
empty_tile = tile_manager->get_tile(392);
|
||||
|
||||
GUI_Widget::Init(nullptr, x, y, cols * 16 + 8, (rows + 1) * 16);
|
||||
|
||||
set_actor(a);
|
||||
set_accept_mouseclick(true, USE_BUTTON); // accept [double]clicks from button1 (even if double-click disabled we need clicks)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ContainerWidget::set_actor(Actor *a) {
|
||||
actor = a;
|
||||
container_obj = nullptr;
|
||||
row_offset = 0;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void ContainerWidget::Display(bool full_redraw) {
|
||||
if (fill_bg) {
|
||||
//clear the screen first inventory icons, 4 x 3 tiles
|
||||
screen->fill(bg_color, area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
display_inventory_list();
|
||||
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
|
||||
void ContainerWidget::display_inventory_list() {
|
||||
const Tile *tile;
|
||||
U6LList *objlist;
|
||||
U6Link *link;
|
||||
Obj *obj = nullptr;
|
||||
uint16 i, j;
|
||||
uint16 skip_num;
|
||||
|
||||
if (container_obj)
|
||||
objlist = container_obj->container;
|
||||
else
|
||||
objlist = actor->get_inventory_list();
|
||||
if (objlist == nullptr)
|
||||
link = nullptr;
|
||||
else
|
||||
link = objlist->start();
|
||||
|
||||
//skip row_offset rows of objects.
|
||||
skip_num = row_offset * cols;
|
||||
for (i = 0; link != nullptr && i < skip_num; link = link->next) {
|
||||
obj = (Obj *)link->data;
|
||||
if (obj->is_readied() == false)
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = 0; i < rows; i++) {
|
||||
for (j = 0; j < cols; j++) {
|
||||
if (link != nullptr) {
|
||||
obj = (Obj *)link->data;
|
||||
if (obj->is_readied()) { //skip any readied objects
|
||||
for (; link != nullptr && obj->is_readied(); link = link->next)
|
||||
obj = (Obj *)link->data;
|
||||
} else
|
||||
link = link->next;
|
||||
|
||||
tile = tile_manager->get_tile(obj_manager->get_obj_tile_num(obj) + obj->frame_n);
|
||||
if (link == nullptr) {
|
||||
if (obj->is_readied()) //last object is readied so skip it.
|
||||
tile = empty_tile;
|
||||
}
|
||||
} else
|
||||
tile = empty_tile;
|
||||
|
||||
//tile = tile_manager->get_tile(actor->indentory_tile());
|
||||
|
||||
screen->blit(area.left + j * 16, area.top + i * 16, (const unsigned char *)empty_tile->data, 8, 16, 16, 16, true);
|
||||
if (tile != empty_tile) {
|
||||
//draw qty string for stackable items
|
||||
if (obj_manager->is_stackable(obj))
|
||||
display_qty_string(area.left + j * 16, area.top + i * 16, obj->qty);
|
||||
|
||||
//draw special char for Keys.
|
||||
if (game_type == NUVIE_GAME_U6 && obj->obj_n == 64)
|
||||
display_special_char(area.left + j * 16, area.top + i * 16, obj->quality);
|
||||
}
|
||||
|
||||
screen->blit(area.left + j * 16, area.top + i * 16, (const unsigned char *)tile->data, 8, 16, 16, 16, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerWidget::display_qty_string(uint16 x, uint16 y, uint16 qty) {
|
||||
uint8 len, i, offset;
|
||||
char buf[6];
|
||||
|
||||
Common::sprintf_s(buf, "%d", qty);
|
||||
len = strlen(buf);
|
||||
|
||||
offset = (16 - len * 4) / 2;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
screen->blitbitmap(x + offset + 4 * i, y + 11, inventory_font[buf[i] - 48], 3, 5, obj_font_color, bg_color);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ContainerWidget::display_special_char(uint16 x, uint16 y, uint8 quality) {
|
||||
if (quality + 9 >= NUVIE_MICRO_FONT_COUNT)
|
||||
return;
|
||||
|
||||
screen->blitbitmap(x + 6, y + 11, inventory_font[quality + 9], 3, 5, obj_font_color, bg_color);
|
||||
}
|
||||
|
||||
GUI_status ContainerWidget::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
//Events *event = Game::get_game()->get_event();
|
||||
//MsgScroll *scroll = Game::get_game()->get_scroll();
|
||||
x -= area.left;
|
||||
y -= area.top;
|
||||
|
||||
// ABOEING
|
||||
if (/*actor && */(button == USE_BUTTON || button == ACTION_BUTTON || button == DRAG_BUTTON)) {
|
||||
Obj *obj; // FIXME: duplicating code in DollWidget
|
||||
if ((obj = get_obj_at_location(x, y)) != nullptr) {
|
||||
// send to View
|
||||
if (callback_object->callback(INVSELECT_CB, this, obj) == GUI_PASS
|
||||
&& button == DRAG_BUTTON)
|
||||
selected_obj = obj; // start dragging
|
||||
return GUI_YUM;
|
||||
}
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
inline uint16 ContainerWidget::get_list_position(int x, int y) {
|
||||
uint16 list_pos;
|
||||
|
||||
list_pos = (y / 16) * cols + x / 16;
|
||||
list_pos += row_offset * cols;
|
||||
|
||||
return list_pos;
|
||||
}
|
||||
|
||||
Obj *ContainerWidget::get_obj_at_location(int x, int y) {
|
||||
uint8 location;
|
||||
U6LList *inventory;
|
||||
U6Link *link;
|
||||
Obj *obj = nullptr;
|
||||
uint16 i;
|
||||
|
||||
|
||||
location = get_list_position(x, y); //find the position of the object we hit in the inventory
|
||||
|
||||
if (container_obj)
|
||||
inventory = container_obj->container;
|
||||
else
|
||||
inventory = actor->get_inventory_list();
|
||||
if (inventory == nullptr)
|
||||
link = nullptr;
|
||||
else
|
||||
link = inventory->start();
|
||||
|
||||
for (i = 0; link != nullptr && i <= location; link = link->next) {
|
||||
obj = (Obj *)link->data;
|
||||
if (obj->is_readied() == false)
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i > location && obj && obj->is_readied() == false) // don't return readied or non existent objects
|
||||
return obj;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// change container, ready/unready object, activate arrows
|
||||
GUI_status ContainerWidget::MouseUp(int /*x*/, int /*y*/, Events::MouseButton button) {
|
||||
if (button == USE_BUTTON) {
|
||||
//x -= area.left;
|
||||
//y -= area.top;
|
||||
|
||||
if (selected_obj) {
|
||||
// only act now if objects can't be used with DoubleClick
|
||||
if (!Game::get_game()->get_map_window()->is_doubleclick_enabled())
|
||||
try_click();
|
||||
else {
|
||||
wait_for_mouseclick(USE_BUTTON);
|
||||
ready_obj = selected_obj;
|
||||
}
|
||||
|
||||
selected_obj = nullptr;
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
bool ContainerWidget::up_arrow() {
|
||||
if (row_offset > 0) {
|
||||
row_offset--;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ContainerWidget::down_arrow() {
|
||||
uint32 num_objects;
|
||||
|
||||
if (container_obj)
|
||||
num_objects = container_obj->container_count_objects();
|
||||
else
|
||||
num_objects = actor->inventory_count_objects(false);
|
||||
|
||||
if ((sint32)(num_objects - row_offset * cols) > (sint32)(rows * cols)) {
|
||||
row_offset++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
GUI_status ContainerWidget::MouseMotion(int x, int y, uint8 state) {
|
||||
Tile *tile;
|
||||
|
||||
if (selected_obj && !dragging) {
|
||||
dragging = true;
|
||||
tile = tile_manager->get_tile(obj_manager->get_obj_tile_num(selected_obj->obj_n) + selected_obj->frame_n);
|
||||
bool out_of_range = false;
|
||||
if (!selected_obj->is_in_inventory() && Game::get_game()->get_map_window()->is_interface_fullscreen_in_combat()) {
|
||||
Obj *obj = selected_obj->is_in_container() ? selected_obj->get_container_obj(true) : selected_obj;
|
||||
MapCoord obj_loc(obj->x, obj->y, obj->z);
|
||||
Actor *player = Game::get_game()->get_player()->get_actor();
|
||||
if (player->get_location().distance(obj_loc) > 1)
|
||||
out_of_range = true;
|
||||
}
|
||||
return gui_drag_manager->start_drag(this, GUI_DRAG_OBJ, selected_obj, tile->data, 16, 16, 8, out_of_range);
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
void ContainerWidget::drag_drop_success(int x, int y, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "ContainerWidget::drag_drop_success()\n");
|
||||
dragging = false;
|
||||
|
||||
// handled by drop target
|
||||
// if(container_obj)
|
||||
// container_obj->container->remove(selected_obj);
|
||||
// else
|
||||
// actor->inventory_remove_obj(selected_obj);
|
||||
|
||||
selected_obj = nullptr;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void ContainerWidget::drag_drop_failed(int x, int y, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "ContainerWidget::drag_drop_failed()\n");
|
||||
dragging = false;
|
||||
selected_obj = nullptr;
|
||||
}
|
||||
|
||||
bool ContainerWidget::drag_set_target_obj(int x, int y) {
|
||||
|
||||
target_obj = get_obj_at_location(x, y);
|
||||
target_cont = get_container();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContainerWidget::drag_accept_drop(int x, int y, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "ContainerWidget::drag_accept_drop()\n");
|
||||
if (message == GUI_DRAG_OBJ) {
|
||||
Obj *obj = (Obj *)data;
|
||||
x -= area.left;
|
||||
y -= area.top;
|
||||
if (target_obj == nullptr) { //we need to check this so we don't screw up target_obj on subsequent calls
|
||||
if (drag_set_target_obj(x, y) == false) {
|
||||
DEBUG(0, LEVEL_WARNING, "ContainerWidget: Didn't hit any widget object targets!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Actor *container_owner = (container_obj ? container_obj->get_actor_holding_obj() : nullptr);
|
||||
if (!container_owner)
|
||||
container_owner = actor;
|
||||
if (!obj->is_in_inventory()) {
|
||||
if (container_owner) {
|
||||
Game::get_game()->get_scroll()->display_string("Get-");
|
||||
Game::get_game()->get_scroll()->display_string(obj_manager->look_obj(obj, OBJ_SHOW_PREFIX));
|
||||
if (Game::get_game()->get_script()->call_actor_get_obj(container_owner, obj) == false) {
|
||||
Game::get_game()->get_scroll()->message("\n\n");
|
||||
return false;
|
||||
}
|
||||
Game::get_game()->get_scroll()->message("\n\n");
|
||||
}
|
||||
} else if (container_owner && obj->get_actor_holding_obj() != container_owner) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
event->display_move_text(container_owner, obj);
|
||||
if (!event->can_move_obj_between_actors(obj, obj->get_actor_holding_obj(), container_owner, false)) {
|
||||
Game::get_game()->get_scroll()->message("\n\n");
|
||||
return false;
|
||||
}
|
||||
Game::get_game()->get_scroll()->message("\n\n");
|
||||
}
|
||||
if (!obj_manager->can_get_obj(obj)) {
|
||||
Game::get_game()->get_scroll()->message("Not possible.\n\n");
|
||||
return false;
|
||||
}
|
||||
Actor *grabber = actor;
|
||||
if (!grabber)
|
||||
grabber = Game::get_game()->get_player()->get_actor();
|
||||
if (container_obj && !container_obj->is_in_inventory()
|
||||
&& !Game::get_game()->get_map_window()->can_get_obj(grabber, container_obj)) {
|
||||
Game::get_game()->get_scroll()->message("\n\nblocked\n\n");
|
||||
return false;
|
||||
}
|
||||
if (!obj->is_in_inventory() && !obj->is_readied()) {
|
||||
if (!Game::get_game()->get_map_window()->can_get_obj(grabber, obj)) {
|
||||
Game::get_game()->get_scroll()->message("\n\nblocked\n\n");
|
||||
return false;
|
||||
}
|
||||
if (obj_manager->obj_is_damaging(obj, Game::get_game()->get_player()->get_actor())) {
|
||||
Game::get_game()->get_player()->subtract_movement_points(3);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
UseCode *usecode = Game::get_game()->get_usecode();
|
||||
if (usecode->is_chest(obj) && obj->frame_n == 0) //open chest
|
||||
obj->frame_n = 1; //close the chest
|
||||
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop Accepted\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop Refused\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
void ContainerWidget::drag_perform_drop(int /*x*/, int /*y*/, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "ContainerWidget::drag_perform_drop()\n");
|
||||
Obj *obj;
|
||||
|
||||
//x -= area.left;
|
||||
//y -= area.top;
|
||||
|
||||
if (message == GUI_DRAG_OBJ) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop into inventory.\n");
|
||||
obj = (Obj *)data;
|
||||
bool moving_between_actors = obj->get_actor_holding_obj() != actor;
|
||||
if (moving_between_actors)
|
||||
Game::get_game()->get_player()->subtract_movement_points(3);
|
||||
if (target_cont && obj_manager->can_store_obj(target_cont, obj)) {
|
||||
obj_manager->moveto_container(obj, target_cont);
|
||||
} else if (target_obj && obj_manager->can_store_obj(target_obj, obj)) {
|
||||
obj_manager->moveto_container(obj, target_obj);
|
||||
} else {
|
||||
if (obj->is_readied()) {
|
||||
Game::get_game()->get_event()->unready(obj);
|
||||
if (moving_between_actors)
|
||||
obj_manager->moveto_inventory(obj, actor);
|
||||
} else
|
||||
obj_manager->moveto_inventory(obj, actor);
|
||||
}
|
||||
|
||||
Redraw();
|
||||
}
|
||||
|
||||
Game::get_game()->get_map_window()->updateBlacking();
|
||||
target_obj = nullptr;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ContainerWidget::drag_draw(int x, int y, int message, void *data) {
|
||||
Tile *tile;
|
||||
|
||||
if (!selected_obj)
|
||||
return;
|
||||
|
||||
tile = tile_manager->get_tile(obj_manager->get_obj_tile_num(selected_obj) + selected_obj->frame_n);
|
||||
|
||||
int nx = x - 8;
|
||||
int ny = y - 8;
|
||||
|
||||
if (nx + 16 >= screen->get_width())
|
||||
nx = screen->get_width() - 17;
|
||||
else if (nx < 0)
|
||||
nx = 0;
|
||||
|
||||
if (ny + 16 >= screen->get_height())
|
||||
ny = screen->get_height() - 17;
|
||||
else if (ny < 0)
|
||||
ny = 0;
|
||||
|
||||
screen->blit(nx, ny, tile->data, 8, 16, 16, 16, true);
|
||||
screen->update(nx, ny, 16, 16);
|
||||
}
|
||||
|
||||
|
||||
void ContainerWidget::try_click() {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
UseCode *usecode = Game::get_game()->get_usecode();
|
||||
Actor *owner = nullptr;
|
||||
if (!selected_obj)
|
||||
selected_obj = ready_obj;
|
||||
if (selected_obj)
|
||||
owner = Game::get_game()->get_actor_manager()->get_actor(selected_obj->x);
|
||||
if (!owner || !owner->is_in_party())
|
||||
owner = Game::get_game()->get_player()->get_actor();
|
||||
switch (event->get_mode()) {
|
||||
case MOVE_MODE:
|
||||
case EQUIP_MODE: {
|
||||
if (!selected_obj)
|
||||
return;
|
||||
bool locked_chest = (usecode->is_chest(selected_obj) && selected_obj->frame_n > 1);
|
||||
if (usecode->is_container(selected_obj) && !locked_chest) {
|
||||
row_offset = 0;
|
||||
container_obj = selected_obj;
|
||||
if (usecode->is_chest(container_obj)) {
|
||||
usecode->process_effects(container_obj, owner);
|
||||
Redraw();
|
||||
}
|
||||
} else {
|
||||
event->ready(selected_obj, owner);
|
||||
Redraw();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GET_MODE:
|
||||
event->perform_get(selected_obj, nullptr, Game::get_game()->get_player()->get_actor());
|
||||
break;
|
||||
case ATTACK_MODE:
|
||||
event->close_gumps();
|
||||
break;
|
||||
default:
|
||||
event->select_view_obj(selected_obj, owner);
|
||||
break;
|
||||
}
|
||||
ready_obj = nullptr;
|
||||
selected_obj = nullptr;
|
||||
}
|
||||
|
||||
/* Use object. */
|
||||
GUI_status ContainerWidget::MouseDouble(int x, int y, Events::MouseButton button) {
|
||||
// we have to check if double-clicks are allowed here, since we use single-clicks
|
||||
if (!Game::get_game()->get_map_window()->is_doubleclick_enabled())
|
||||
return GUI_PASS;
|
||||
Obj *obj = selected_obj;
|
||||
|
||||
ready_obj = nullptr;
|
||||
selected_obj = nullptr;
|
||||
|
||||
// if(!actor)
|
||||
// return(GUI_YUM);
|
||||
if (!obj)
|
||||
return MouseUp(x, y, button); // probably hit an arrow
|
||||
Game::get_game()->get_view_manager()->double_click_obj(obj);
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status ContainerWidget::MouseClick(int x, int y, Events::MouseButton button) {
|
||||
return MouseUp(x, y, button);
|
||||
}
|
||||
|
||||
// change container, ready/unready object, activate arrows
|
||||
GUI_status ContainerWidget::MouseDelayed(int x, int y, Events::MouseButton button) {
|
||||
if (ready_obj)
|
||||
try_click();
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
124
engines/ultima/nuvie/views/container_widget.h
Normal file
124
engines/ultima/nuvie/views/container_widget.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/* 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 NUVIE_VIEWS_CONTAINER_WIDGET_H
|
||||
#define NUVIE_VIEWS_CONTAINER_WIDGET_H
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/core/obj_manager.h"
|
||||
#include "ultima/nuvie/views/inventory_message.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static const int CONTAINER_WIDGET_ROWS = 3;
|
||||
static const int CONTAINER_WIDGET_COLS = 4;
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class Actor;
|
||||
class Font;
|
||||
|
||||
class ContainerWidget : public GUI_Widget {
|
||||
|
||||
protected:
|
||||
const Configuration *config;
|
||||
|
||||
int game_type;
|
||||
|
||||
TileManager *tile_manager;
|
||||
ObjManager *obj_manager;
|
||||
|
||||
Actor *actor;
|
||||
Obj *container_obj;
|
||||
|
||||
Obj *selected_obj, *target_obj, *ready_obj;
|
||||
Obj *target_cont;
|
||||
uint16 rows, cols;
|
||||
uint16 row_offset;
|
||||
|
||||
uint8 bg_color;
|
||||
uint8 obj_font_color;
|
||||
|
||||
bool fill_bg;
|
||||
|
||||
const Tile *empty_tile;
|
||||
|
||||
public:
|
||||
ContainerWidget(const Configuration *cfg, GUI_CallBack *callback = nullptr);
|
||||
~ContainerWidget() override;
|
||||
|
||||
bool init(Actor *a, uint16 x, uint16 y, TileManager *tm, ObjManager *om, Font *f);
|
||||
virtual void set_actor(Actor *a);
|
||||
const Actor *get_actor() const {
|
||||
return actor;
|
||||
}
|
||||
Obj *get_container() {
|
||||
return container_obj;
|
||||
}
|
||||
void set_container(Obj *obj) {
|
||||
container_obj = obj;
|
||||
row_offset = 0;
|
||||
Redraw();
|
||||
}
|
||||
bool is_showing_container() const {
|
||||
return (container_obj != nullptr ? true : false);
|
||||
}
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override;
|
||||
GUI_status MouseDouble(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseClick(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseDelayed(int x, int y, Events::MouseButton button) override;
|
||||
|
||||
void drag_drop_success(int x, int y, int message, void *data) override;
|
||||
void drag_drop_failed(int x, int y, int message, void *data) override;
|
||||
|
||||
bool drag_accept_drop(int x, int y, int message, void *data) override;
|
||||
void drag_perform_drop(int x, int y, int message, void *data) override;
|
||||
|
||||
void drag_draw(int x, int y, int message, void *data) override;
|
||||
|
||||
protected:
|
||||
|
||||
GUI_CallBack *callback_object; // object-selected callback
|
||||
|
||||
inline uint16 get_list_position(int x, int y);
|
||||
void display_inventory_list();
|
||||
inline void display_qty_string(uint16 x, uint16 y, uint16 qty);
|
||||
inline void display_special_char(uint16 x, uint16 y, uint8 quality);
|
||||
void display_arrows();
|
||||
|
||||
bool drag_set_target_obj(int x, int y);
|
||||
void try_click();
|
||||
|
||||
public:
|
||||
bool up_arrow();
|
||||
bool down_arrow();
|
||||
Obj *get_obj_at_location(int x, int y);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
193
engines/ultima/nuvie/views/container_widget_gump.cpp
Normal file
193
engines/ultima/nuvie/views/container_widget_gump.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/views/container_widget_gump.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static const Tile gump_empty_tile = {
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
//uint8 qty;
|
||||
//uint8 flags;
|
||||
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
||||
{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 143, 142, 141, 141, 142, 143, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 143, 141, 141, 142, 142, 141, 141, 143, 255, 255, 255, 255,
|
||||
255, 255, 255, 143, 141, 142, 143, 143, 143, 143, 142, 141, 143, 255, 255, 255,
|
||||
255, 255, 143, 141, 142, 143, 0, 0, 0, 0, 143, 142, 141, 143, 255, 255,
|
||||
255, 255, 142, 141, 143, 0, 0, 0, 0, 0, 0, 143, 141, 142, 255, 255,
|
||||
255, 255, 141, 142, 143, 0, 0, 0, 0, 0, 0, 143, 142, 141, 255, 255,
|
||||
255, 255, 141, 142, 143, 0, 0, 0, 0, 0, 0, 143, 142, 141, 255, 255,
|
||||
255, 255, 142, 141, 143, 0, 0, 0, 0, 0, 0, 143, 141, 142, 255, 255,
|
||||
255, 255, 143, 141, 142, 143, 0, 0, 0, 0, 143, 142, 141, 143, 255, 255,
|
||||
255, 255, 255, 143, 141, 142, 143, 143, 143, 143, 142, 141, 143, 255, 255, 255,
|
||||
255, 255, 255, 255, 143, 141, 141, 142, 142, 141, 141, 143, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 143, 142, 141, 141, 142, 143, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ContainerWidgetGump::ContainerWidgetGump(const Configuration *cfg, GUI_CallBack *callback)
|
||||
: ContainerWidget(cfg, callback), cursor_tile(nullptr), check_x(0), check_y(0),
|
||||
cursor_x(0), cursor_y(0), show_cursor(true) {
|
||||
empty_tile = &gump_empty_tile;
|
||||
obj_font_color = 15;
|
||||
bg_color = 0;
|
||||
fill_bg = false;
|
||||
}
|
||||
|
||||
ContainerWidgetGump::~ContainerWidgetGump() {
|
||||
|
||||
}
|
||||
|
||||
bool ContainerWidgetGump::init(Actor *a, uint16 x, uint16 y, uint8 Cols, uint8 Rows, TileManager *tm, ObjManager *om, Font *f, uint8 check_xoff, uint8 check_yoff) {
|
||||
tile_manager = tm;
|
||||
obj_manager = om;
|
||||
|
||||
rows = Rows;
|
||||
cols = Cols;
|
||||
check_x = - x + check_xoff;
|
||||
check_y = - y + check_yoff;
|
||||
//objlist_offset_x = 0;
|
||||
//objlist_offset_y = 0;
|
||||
|
||||
//72 = 4 * 16 + 8
|
||||
GUI_Widget::Init(nullptr, x, y, cols * 16, rows * 16);
|
||||
|
||||
set_actor(a);
|
||||
set_accept_mouseclick(true, 0);//USE_BUTTON); // accept [double]clicks from button1 (even if double-click disabled we need clicks)
|
||||
|
||||
cursor_tile = tile_manager->get_gump_cursor_tile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ContainerWidgetGump::Display(bool full_redraw) {
|
||||
display_inventory_list();
|
||||
if (show_cursor) {
|
||||
screen->blit(area.left + (cursor_x < 0 ? check_x : cursor_x * 16), area.top + (cursor_x < 0 ? check_y : cursor_y * 16),
|
||||
(const unsigned char *)cursor_tile->data, 8, 16, 16, 16, true);
|
||||
}
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
void ContainerWidgetGump::cursor_right() {
|
||||
if (cursor_x < cols - 1) {
|
||||
if (get_obj_at_location((cursor_x + 1) * 16, cursor_y * 16) != nullptr) {
|
||||
cursor_x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerWidgetGump::cursor_left() {
|
||||
if (cursor_x > -1) {
|
||||
cursor_x--;
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerWidgetGump::cursor_up() {
|
||||
if (cursor_y > 0) {
|
||||
cursor_y--;
|
||||
} else {
|
||||
up_arrow();
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerWidgetGump::cursor_down() {
|
||||
if (get_obj_at_location(0, (cursor_y + 1) * 16) != nullptr) { //check that we can move down one row.
|
||||
if (cursor_y < rows - 1) {
|
||||
cursor_y++;
|
||||
} else {
|
||||
down_arrow();
|
||||
}
|
||||
|
||||
for (; cursor_x > 0; cursor_x--) {
|
||||
if (get_obj_at_location(cursor_x * 16, cursor_y * 16) != nullptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GUI_status ContainerWidgetGump::KeyDown(const Common::KeyState &key) {
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
|
||||
switch (keybinder->GetActionKeyType(a)) {
|
||||
case NORTH_KEY:
|
||||
cursor_up();
|
||||
break;
|
||||
case SOUTH_KEY:
|
||||
cursor_down();
|
||||
break;
|
||||
case WEST_KEY:
|
||||
cursor_left();
|
||||
break;
|
||||
case EAST_KEY:
|
||||
cursor_right();
|
||||
break;
|
||||
case DO_ACTION_KEY:
|
||||
if (cursor_x == -1) {
|
||||
Game::get_game()->get_view_manager()->close_gump((DraggableView *)parent);
|
||||
break;
|
||||
}
|
||||
selected_obj = get_obj_at_location(cursor_x * 16, cursor_y * 16);
|
||||
if (selected_obj) {
|
||||
try_click();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void ContainerWidgetGump::set_actor(Actor *a) {
|
||||
cursor_x = cursor_y = 0;
|
||||
ContainerWidget::set_actor(a);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
67
engines/ultima/nuvie/views/container_widget_gump.h
Normal file
67
engines/ultima/nuvie/views/container_widget_gump.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* 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 NUVIE_VIEWS_CONTAINER_WIDGET_GUMP_H
|
||||
#define NUVIE_VIEWS_CONTAINER_WIDGET_GUMP_H
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/core/obj_manager.h"
|
||||
#include "ultima/nuvie/views/container_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class Actor;
|
||||
class Font;
|
||||
|
||||
class ContainerWidgetGump : public ContainerWidget {
|
||||
|
||||
private:
|
||||
sint16 cursor_x;
|
||||
uint16 cursor_y;
|
||||
sint16 check_x, check_y;
|
||||
const Tile *cursor_tile;
|
||||
bool show_cursor;
|
||||
|
||||
public:
|
||||
ContainerWidgetGump(const Configuration *cfg, GUI_CallBack *callback = nullptr);
|
||||
~ContainerWidgetGump() override;
|
||||
|
||||
bool init(Actor *a, uint16 x, uint16 y, uint8 Cols, uint8 Rows, TileManager *tm, ObjManager *om, Font *f, uint8 check_xoff, uint8 check_yoff);
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
|
||||
void set_actor(Actor *a) override;
|
||||
private:
|
||||
|
||||
void cursor_right();
|
||||
void cursor_left();
|
||||
void cursor_up();
|
||||
void cursor_down();
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
684
engines/ultima/nuvie/views/doll_view_gump.cpp
Normal file
684
engines/ultima/nuvie/views/doll_view_gump.cpp
Normal file
@@ -0,0 +1,684 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
#include "ultima/nuvie/core/party.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/views/container_view_gump.h"
|
||||
#include "ultima/nuvie/views/doll_widget.h"
|
||||
#include "ultima/nuvie/views/doll_view_gump.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
DollViewGump::DollViewGump(const Configuration *cfg)
|
||||
: DraggableView(cfg), gump_button(nullptr), combat_button(nullptr),
|
||||
heart_button(nullptr), party_button(nullptr), inventory_button(nullptr),
|
||||
doll_widget(nullptr), actor_doll(nullptr), font(nullptr), actor(nullptr),
|
||||
cursor_tile(nullptr), is_avatar(false), show_cursor(true),
|
||||
cursor_pos(CURSOR_HEAD), cursor_xoff(50), cursor_yoff(16) {
|
||||
}
|
||||
|
||||
DollViewGump::~DollViewGump() {
|
||||
if (font)
|
||||
delete font;
|
||||
if (actor_doll)
|
||||
delete actor_doll;
|
||||
}
|
||||
|
||||
bool DollViewGump::init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Actor *a, Font *f, Party *p, TileManager *tm, ObjManager *om) {
|
||||
View::init(x, y, f, p, tm, om);
|
||||
|
||||
SetRect(area.left, area.top, 108, 136);
|
||||
|
||||
actor = a;
|
||||
is_avatar = actor->is_avatar();
|
||||
cursor_tile = tile_manager->get_gump_cursor_tile();
|
||||
doll_widget = new DollWidget(config, this);
|
||||
doll_widget->init(actor, 26, 16, tile_manager, obj_manager);
|
||||
|
||||
AddWidget(doll_widget);
|
||||
|
||||
Common::Path datadir = GUI::get_gui()->get_data_dir();
|
||||
Common::Path imagefile;
|
||||
Common::Path path;
|
||||
|
||||
Graphics::ManagedSurface *image, *image1;
|
||||
|
||||
build_path(datadir, "images", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "gumps", path);
|
||||
datadir = path;
|
||||
|
||||
gump_button = loadButton(datadir, "gump", 0, 112);
|
||||
|
||||
build_path(datadir, "left_arrow.bmp", imagefile);
|
||||
image = SDL_LoadBMP(imagefile);
|
||||
image1 = SDL_LoadBMP(imagefile);
|
||||
|
||||
left_button = new GUI_Button(this, 23, 7, image, image1, this);
|
||||
this->AddWidget(left_button);
|
||||
|
||||
build_path(datadir, "right_arrow.bmp", imagefile);
|
||||
image = SDL_LoadBMP(imagefile);
|
||||
image1 = SDL_LoadBMP(imagefile);
|
||||
|
||||
right_button = new GUI_Button(this, 86, 7, image, image1, this);
|
||||
this->AddWidget(right_button);
|
||||
|
||||
build_path(datadir, "doll", path);
|
||||
datadir = path;
|
||||
|
||||
build_path(datadir, "doll_bg.bmp", imagefile);
|
||||
bg_image = SDL_LoadBMP(imagefile);
|
||||
|
||||
set_bg_color_key(0, 0x70, 0xfc);
|
||||
|
||||
build_path(datadir, "combat_btn_up.bmp", imagefile);
|
||||
image = SDL_LoadBMP(imagefile);
|
||||
build_path(datadir, "combat_btn_down.bmp", imagefile);
|
||||
image1 = SDL_LoadBMP(imagefile);
|
||||
|
||||
combat_button = new GUI_Button(nullptr, 23, 92, image, image1, this);
|
||||
this->AddWidget(combat_button);
|
||||
|
||||
heart_button = loadButton(datadir, "heart", 23, 108);
|
||||
party_button = loadButton(datadir, "party", 47, 108);
|
||||
inventory_button = loadButton(datadir, "inventory", 71, 108);
|
||||
|
||||
font = new GUI_Font(GUI_FONT_GUMP);
|
||||
font->setColoring(0x08, 0x08, 0x08, 0x80, 0x58, 0x30, 0x00, 0x00, 0x00);
|
||||
|
||||
if (party->get_member_num(actor) < 0) {
|
||||
if (Game::get_game()->get_event()->using_control_cheat() == false)
|
||||
heart_button->Hide();
|
||||
left_button->Hide();
|
||||
right_button->Hide();
|
||||
}
|
||||
party_button->Hide();
|
||||
is_avatar = actor->is_avatar();
|
||||
ViewManager *vm = Game::get_game()->get_view_manager();
|
||||
if (is_avatar)
|
||||
actor_doll = vm->loadAvatarDollImage(actor_doll);
|
||||
else
|
||||
actor_doll = vm->loadCustomActorDollImage(actor_doll, actor->get_actor_num());
|
||||
setColorKey(actor_doll);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DollViewGump::setColorKey(Graphics::ManagedSurface *image) {
|
||||
if (image) {
|
||||
bg_color_key = image->format.RGBToColor(0xf1, 0x0f, 0xc4);
|
||||
image->setTransparentColor(bg_color_key);
|
||||
}
|
||||
}
|
||||
|
||||
static const char combat_mode_tbl[][8] = {"COMMAND", "FRONT", "REAR", "FLANK", "BERSERK", "RETREAT", "ASSAULT"};
|
||||
static const char combat_mode_tbl_se[][8] = {"COMMAND", "RANGED", "FLEE", "CLOSE"};
|
||||
static const char combat_mode_tbl_md[][8] = {"COMMAND", "RANGED", "FLEE", "ATTACK"};
|
||||
|
||||
void DollViewGump::set_actor(Actor *a) {
|
||||
actor = a;
|
||||
if (actor) {
|
||||
is_avatar = actor->is_avatar();
|
||||
ViewManager *vm = Game::get_game()->get_view_manager();
|
||||
if (is_avatar)
|
||||
actor_doll = vm->loadAvatarDollImage(actor_doll);
|
||||
else
|
||||
actor_doll = vm->loadCustomActorDollImage(actor_doll, actor->get_actor_num());
|
||||
setColorKey(actor_doll);
|
||||
}
|
||||
|
||||
if (doll_widget)
|
||||
doll_widget->set_actor(actor);
|
||||
}
|
||||
|
||||
GUI_status DollViewGump::set_cursor_pos(gumpCursorPos pos) {
|
||||
cursor_pos = pos;
|
||||
switch (cursor_pos) {
|
||||
case CURSOR_LEFT:
|
||||
cursor_xoff = 18;
|
||||
cursor_yoff = 2;
|
||||
return GUI_YUM;
|
||||
case CURSOR_RIGHT:
|
||||
cursor_xoff = 82;
|
||||
cursor_yoff = 2;
|
||||
return GUI_YUM;
|
||||
case CURSOR_HEAD:
|
||||
cursor_xoff = 50;
|
||||
cursor_yoff = 16;
|
||||
return GUI_YUM;
|
||||
case CURSOR_NECK:
|
||||
cursor_xoff = 26;
|
||||
cursor_yoff = 24;
|
||||
return GUI_YUM;
|
||||
case CURSOR_RIGHT_HAND:
|
||||
cursor_xoff = 26;
|
||||
cursor_yoff = 40;
|
||||
return GUI_YUM;
|
||||
case CURSOR_CHEST:
|
||||
cursor_xoff = 74;
|
||||
cursor_yoff = 24;
|
||||
return GUI_YUM;
|
||||
case CURSOR_LEFT_HAND:
|
||||
cursor_xoff = 74;
|
||||
cursor_yoff = 40;
|
||||
return GUI_YUM;
|
||||
case CURSOR_RIGHT_RING:
|
||||
cursor_xoff = 26;
|
||||
cursor_yoff = 57;
|
||||
return GUI_YUM;
|
||||
case CURSOR_LEFT_RING:
|
||||
cursor_xoff = 74;
|
||||
cursor_yoff = 57;
|
||||
return GUI_YUM;
|
||||
case CURSOR_FEET:
|
||||
cursor_xoff = 50;
|
||||
cursor_yoff = 63;
|
||||
return GUI_YUM;
|
||||
case CURSOR_CHECK:
|
||||
cursor_xoff = 1;
|
||||
cursor_yoff = 111;
|
||||
return GUI_YUM;
|
||||
case CURSOR_COMBAT:
|
||||
cursor_xoff = 23;
|
||||
cursor_yoff = 92;
|
||||
return GUI_YUM;
|
||||
case CURSOR_HEART:
|
||||
cursor_xoff = 26;
|
||||
cursor_yoff = 109;
|
||||
return GUI_YUM;
|
||||
case CURSOR_PARTY:
|
||||
cursor_xoff = 50;
|
||||
cursor_yoff = 109;
|
||||
return GUI_YUM;
|
||||
case CURSOR_INVENTORY:
|
||||
default :
|
||||
cursor_xoff = 74;
|
||||
cursor_yoff = 109;
|
||||
return GUI_YUM;
|
||||
}
|
||||
}
|
||||
|
||||
void DollViewGump::Display(bool full_redraw) {
|
||||
//display_level_text();
|
||||
//display_spell_list_text();
|
||||
Common::Rect dst;
|
||||
dst = area;
|
||||
dst.setWidth(108);
|
||||
dst.setHeight(136);
|
||||
SDL_BlitSurface(bg_image, nullptr, surface, &dst);
|
||||
|
||||
if (actor_doll) {
|
||||
dst.translate(45, 32);
|
||||
SDL_BlitSurface(actor_doll, nullptr, surface, &dst);
|
||||
}
|
||||
|
||||
uint8 w = font->getCenter(actor->get_name(), 58);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + 29 + w, area.top + 7, actor->get_name());
|
||||
|
||||
displayEquipWeight();
|
||||
|
||||
DisplayChildren(full_redraw);
|
||||
displayCombatMode();
|
||||
if (show_cursor)
|
||||
screen->blit(area.left + cursor_xoff, area.top + cursor_yoff,
|
||||
(const unsigned char *)cursor_tile->data, 8, 16, 16, 16, true);
|
||||
update_display = false;
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void DollViewGump::displayEquipWeight() {
|
||||
uint8 strength = actor->get_strength();
|
||||
unsigned int equip_weight = Game::get_game()->get_view_manager()->get_display_weight(actor->get_inventory_equip_weight());
|
||||
char string[4]; //nnn\0
|
||||
|
||||
snprintf(string, 4, "%u", equip_weight);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + ((equip_weight > 9) ? 59 : 64), area.top + 82, string);
|
||||
|
||||
snprintf(string, 4, "%u", strength);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + ((strength > 9) ? 76 : 81), area.top + 82, string);
|
||||
}
|
||||
|
||||
void DollViewGump::displayCombatMode() {
|
||||
if (!actor->is_in_party() || party->get_member_num(actor) == 0)
|
||||
return;
|
||||
uint8 index = get_combat_mode_index(actor);
|
||||
const char *text;
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6)
|
||||
text = combat_mode_tbl[index];
|
||||
else if (Game::get_game()->get_game_type() == NUVIE_GAME_MD)
|
||||
text = combat_mode_tbl_md[index];
|
||||
else // SE
|
||||
text = combat_mode_tbl_se[index];
|
||||
uint8 c = font->getCenter(text, 55);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + 36 + c, area.top + 97, text);
|
||||
}
|
||||
|
||||
void DollViewGump::left_arrow() {
|
||||
if (party->get_member_num(actor) < 0)
|
||||
return;
|
||||
uint8 party_mem_num = party->get_member_num(actor);
|
||||
if (party_mem_num > 0)
|
||||
party_mem_num--;
|
||||
else
|
||||
party_mem_num = party->get_party_size() - 1;
|
||||
|
||||
set_actor(party->get_actor(party_mem_num));
|
||||
}
|
||||
|
||||
void DollViewGump::right_arrow() {
|
||||
if (party->get_member_num(actor) < 0)
|
||||
return;
|
||||
set_actor(party->get_actor((party->get_member_num(actor) + 1) % party->get_party_size()));
|
||||
}
|
||||
|
||||
GUI_status DollViewGump::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
//close gump and return control to Magic class for clean up.
|
||||
if (event->get_mode() == ATTACK_MODE || caller == gump_button) {
|
||||
Game::get_game()->get_view_manager()->close_gump(this);
|
||||
return GUI_YUM;
|
||||
} else if (caller == right_button) {
|
||||
right_arrow();
|
||||
} else if (caller == left_button) {
|
||||
left_arrow();
|
||||
} else if (caller == inventory_button) {
|
||||
Game::get_game()->get_view_manager()->open_container_view(actor);
|
||||
} else if (caller == heart_button) {
|
||||
Game::get_game()->get_view_manager()->open_portrait_gump(actor);
|
||||
} else if (caller == combat_button) {
|
||||
activate_combat_button();
|
||||
} else if (caller == party_button) { // FIXME: What is this supposed to do?
|
||||
|
||||
} else if (caller == doll_widget) {
|
||||
if (event->get_mode() != MOVE_MODE && event->get_mode() != EQUIP_MODE) {
|
||||
Obj *obj = (Obj *)data;
|
||||
event->select_view_obj(obj, actor);
|
||||
return GUI_YUM;
|
||||
}
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status DollViewGump::moveCursorRelative(NuvieDir direction) {
|
||||
gumpCursorPos cursor_left = actor->is_in_party() ? CURSOR_LEFT : CURSOR_HEAD; // don't allow pickpocket or control cheat into arrow area
|
||||
gumpCursorPos cursor_right = actor->is_in_party() ? CURSOR_RIGHT : CURSOR_HEAD;
|
||||
gumpCursorPos cursor_party; // no party button yet so skip it
|
||||
gumpCursorPos cursor_heart; // not available in pickpocket mode
|
||||
|
||||
if (!actor->is_in_party() && !Game::get_game()->get_event()->using_control_cheat()) {
|
||||
if (direction == NUVIE_DIR_SW || direction == NUVIE_DIR_W)
|
||||
cursor_heart = CURSOR_CHECK;
|
||||
else
|
||||
cursor_heart = CURSOR_INVENTORY;
|
||||
} else
|
||||
cursor_heart = CURSOR_HEART;
|
||||
|
||||
if (direction == NUVIE_DIR_W || direction == NUVIE_DIR_SW)
|
||||
cursor_party = cursor_heart;
|
||||
else
|
||||
cursor_party = CURSOR_INVENTORY;
|
||||
|
||||
switch (cursor_pos) {
|
||||
case CURSOR_LEFT:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_NE:
|
||||
case NUVIE_DIR_E:
|
||||
return set_cursor_pos(CURSOR_RIGHT);
|
||||
case NUVIE_DIR_SW:
|
||||
case NUVIE_DIR_S:
|
||||
return set_cursor_pos(CURSOR_NECK);
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(CURSOR_HEAD);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_RIGHT:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_W:
|
||||
case NUVIE_DIR_NW:
|
||||
return set_cursor_pos(CURSOR_LEFT);
|
||||
case NUVIE_DIR_S:
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(CURSOR_CHEST);
|
||||
case NUVIE_DIR_SW:
|
||||
return set_cursor_pos(CURSOR_HEAD);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_HEAD:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_N:
|
||||
case NUVIE_DIR_NW:
|
||||
return set_cursor_pos(cursor_left);
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(cursor_right);
|
||||
case NUVIE_DIR_W:
|
||||
case NUVIE_DIR_SW:
|
||||
return set_cursor_pos(CURSOR_NECK);
|
||||
case NUVIE_DIR_E:
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(CURSOR_CHEST);
|
||||
case NUVIE_DIR_S:
|
||||
return set_cursor_pos(CURSOR_FEET);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_NECK:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_N:
|
||||
case NUVIE_DIR_NW:
|
||||
return set_cursor_pos(cursor_left);
|
||||
case NUVIE_DIR_E:
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(CURSOR_HEAD);
|
||||
case NUVIE_DIR_S:
|
||||
case NUVIE_DIR_SW:
|
||||
return set_cursor_pos(CURSOR_RIGHT_HAND);
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(CURSOR_LEFT_HAND);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_CHEST:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_N:
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(cursor_right);
|
||||
case NUVIE_DIR_W:
|
||||
case NUVIE_DIR_NW:
|
||||
return set_cursor_pos(CURSOR_HEAD);
|
||||
case NUVIE_DIR_SW:
|
||||
return set_cursor_pos(CURSOR_RIGHT_HAND);
|
||||
case NUVIE_DIR_S:
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(CURSOR_LEFT_HAND);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_RIGHT_HAND:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_N:
|
||||
case NUVIE_DIR_NW:
|
||||
return set_cursor_pos(CURSOR_NECK);
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(CURSOR_CHEST);
|
||||
case NUVIE_DIR_E:
|
||||
return set_cursor_pos(CURSOR_LEFT_HAND);
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(CURSOR_FEET);
|
||||
case NUVIE_DIR_S:
|
||||
case NUVIE_DIR_SW:
|
||||
return set_cursor_pos(CURSOR_RIGHT_RING);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_LEFT_HAND:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_N:
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(CURSOR_CHEST);
|
||||
case NUVIE_DIR_NW:
|
||||
return set_cursor_pos(CURSOR_HEAD);
|
||||
case NUVIE_DIR_W:
|
||||
return set_cursor_pos(CURSOR_RIGHT_HAND);
|
||||
case NUVIE_DIR_SW:
|
||||
return set_cursor_pos(CURSOR_FEET);
|
||||
case NUVIE_DIR_S:
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(CURSOR_LEFT_RING);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_RIGHT_RING:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_N:
|
||||
case NUVIE_DIR_NW:
|
||||
return set_cursor_pos(CURSOR_RIGHT_HAND);
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(CURSOR_LEFT_HAND);
|
||||
case NUVIE_DIR_S:
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(CURSOR_FEET);
|
||||
case NUVIE_DIR_SW:
|
||||
return set_cursor_pos(CURSOR_COMBAT);
|
||||
case NUVIE_DIR_E:
|
||||
return set_cursor_pos(CURSOR_LEFT_RING);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_LEFT_RING:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_N:
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(CURSOR_LEFT_HAND);
|
||||
case NUVIE_DIR_NW:
|
||||
return set_cursor_pos(CURSOR_RIGHT_HAND);
|
||||
case NUVIE_DIR_W:
|
||||
return set_cursor_pos(CURSOR_RIGHT_RING);
|
||||
case NUVIE_DIR_S:
|
||||
case NUVIE_DIR_SW:
|
||||
return set_cursor_pos(CURSOR_FEET);
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(CURSOR_COMBAT);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_FEET:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_N:
|
||||
return set_cursor_pos(CURSOR_HEAD);
|
||||
case NUVIE_DIR_W:
|
||||
case NUVIE_DIR_NW:
|
||||
return set_cursor_pos(CURSOR_RIGHT_RING);
|
||||
case NUVIE_DIR_E:
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(CURSOR_LEFT_RING);
|
||||
case NUVIE_DIR_S:
|
||||
case NUVIE_DIR_SW:
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(CURSOR_COMBAT);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_COMBAT:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_N:
|
||||
case NUVIE_DIR_NW:
|
||||
return set_cursor_pos(CURSOR_RIGHT_RING);
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(CURSOR_FEET);
|
||||
case NUVIE_DIR_SW:
|
||||
return set_cursor_pos(CURSOR_CHECK);
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(cursor_party);
|
||||
case NUVIE_DIR_S:
|
||||
return set_cursor_pos(cursor_heart);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_CHECK:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(CURSOR_COMBAT);
|
||||
case NUVIE_DIR_E:
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(cursor_heart);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_HEART:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_N:
|
||||
case NUVIE_DIR_NW:
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(CURSOR_COMBAT);
|
||||
case NUVIE_DIR_W:
|
||||
case NUVIE_DIR_SW:
|
||||
return set_cursor_pos(CURSOR_CHECK);
|
||||
case NUVIE_DIR_E:
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(cursor_party);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_PARTY:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_N:
|
||||
case NUVIE_DIR_NW:
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(CURSOR_COMBAT);
|
||||
case NUVIE_DIR_W:
|
||||
case NUVIE_DIR_SW:
|
||||
return set_cursor_pos(cursor_heart);
|
||||
case NUVIE_DIR_E:
|
||||
case NUVIE_DIR_SE:
|
||||
return set_cursor_pos(CURSOR_INVENTORY);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
case CURSOR_INVENTORY:
|
||||
switch (direction) {
|
||||
case NUVIE_DIR_N:
|
||||
case NUVIE_DIR_NW:
|
||||
case NUVIE_DIR_NE:
|
||||
return set_cursor_pos(CURSOR_COMBAT);
|
||||
case NUVIE_DIR_W:
|
||||
case NUVIE_DIR_SW:
|
||||
return set_cursor_pos(cursor_party);
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
default:
|
||||
return GUI_YUM;
|
||||
}
|
||||
}
|
||||
|
||||
GUI_status DollViewGump::KeyDown(const Common::KeyState &key) {
|
||||
// I was restricting numpad keys when in numlock but there shouldn't be any needed number input
|
||||
// bool numlock = (key.flags & Common::KBD_NUM); // SDL doesn't get the proper num lock state in Windows
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
|
||||
switch (keybinder->GetActionKeyType(a)) {
|
||||
case SOUTH_WEST_KEY:
|
||||
return moveCursorRelative(NUVIE_DIR_SW);
|
||||
case SOUTH_EAST_KEY:
|
||||
return moveCursorRelative(NUVIE_DIR_SE);
|
||||
case NORTH_WEST_KEY:
|
||||
return moveCursorRelative(NUVIE_DIR_NW);
|
||||
case NORTH_EAST_KEY:
|
||||
return moveCursorRelative(NUVIE_DIR_NE);
|
||||
case NORTH_KEY:
|
||||
return moveCursorRelative(NUVIE_DIR_N);
|
||||
case SOUTH_KEY:
|
||||
return moveCursorRelative(NUVIE_DIR_S);
|
||||
case WEST_KEY:
|
||||
return moveCursorRelative(NUVIE_DIR_W);
|
||||
case EAST_KEY:
|
||||
return moveCursorRelative(NUVIE_DIR_E);
|
||||
case NEXT_PARTY_MEMBER_KEY:
|
||||
right_arrow();
|
||||
return GUI_YUM;
|
||||
case PREVIOUS_PARTY_MEMBER_KEY:
|
||||
left_arrow();
|
||||
return GUI_YUM;
|
||||
case HOME_KEY:
|
||||
set_actor(party->get_actor(0));
|
||||
return GUI_YUM;
|
||||
case END_KEY:
|
||||
set_actor(party->get_actor(party->get_party_size() - 1));
|
||||
return GUI_YUM;
|
||||
case DO_ACTION_KEY: {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
bool in_party = party->get_member_num(actor) >= 0;
|
||||
if (event->get_mode() == ATTACK_MODE || cursor_pos == CURSOR_CHECK) {
|
||||
Game::get_game()->get_view_manager()->close_gump(this);
|
||||
} else if (cursor_pos == CURSOR_LEFT) {
|
||||
left_arrow();
|
||||
} else if (cursor_pos == CURSOR_RIGHT) {
|
||||
right_arrow();
|
||||
} else if (cursor_pos == CURSOR_COMBAT) {
|
||||
activate_combat_button();
|
||||
} else if (cursor_pos == CURSOR_HEART) {
|
||||
if (in_party || event->using_control_cheat())
|
||||
Game::get_game()->get_view_manager()->open_portrait_gump(actor);
|
||||
} else if (cursor_pos == CURSOR_PARTY) {
|
||||
if (in_party) {
|
||||
}
|
||||
} else if (cursor_pos == CURSOR_INVENTORY) {
|
||||
Game::get_game()->get_view_manager()->open_container_view(actor);
|
||||
} else {
|
||||
Obj *obj = actor->inventory_get_readied_object((uint8)cursor_pos);
|
||||
if (event->get_mode() == MOVE_MODE || event->get_mode() == EQUIP_MODE) {
|
||||
if (obj)
|
||||
event->unready(obj);
|
||||
} else
|
||||
event->select_view_obj(obj, actor);
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
void DollViewGump::activate_combat_button() {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
if (actor->is_in_party() && party->get_member_num(actor) != 0) {
|
||||
set_combat_mode(actor);
|
||||
update_display = true;
|
||||
} else if (event->get_mode() != INPUT_MODE && event->get_mode() != CAST_MODE
|
||||
&& event->get_mode() != ATTACK_MODE)
|
||||
event->newAction(COMBAT_MODE);
|
||||
}
|
||||
|
||||
GUI_status DollViewGump::MouseWheel(sint32 x, sint32 y) {
|
||||
if (y > 0) {
|
||||
left_arrow();
|
||||
} else if (y < 0) {
|
||||
right_arrow();
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status DollViewGump::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
return DraggableView::MouseDown(x, y, button);
|
||||
}
|
||||
|
||||
GUI_status DollViewGump::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
return DraggableView::MouseUp(x, y, button);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
107
engines/ultima/nuvie/views/doll_view_gump.h
Normal file
107
engines/ultima/nuvie/views/doll_view_gump.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* 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 NUVIE_VIEWS_DOLL_VIEW_GUMP_H
|
||||
#define NUVIE_VIEWS_DOLL_VIEW_GUMP_H
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/views/draggable_view.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class ObjManager;
|
||||
class Screen;
|
||||
class Actor;
|
||||
class Font;
|
||||
class DollWidget;
|
||||
|
||||
static const int DOLLVIEWGUMP_HEIGHT = 136;
|
||||
|
||||
class DollViewGump : public DraggableView {
|
||||
|
||||
GUI_Button *gump_button;
|
||||
GUI_Button *combat_button;
|
||||
GUI_Button *heart_button;
|
||||
GUI_Button *party_button;
|
||||
GUI_Button *inventory_button;
|
||||
DollWidget *doll_widget;
|
||||
|
||||
GUI_Font *font;
|
||||
|
||||
Actor *actor;
|
||||
bool is_avatar;
|
||||
bool show_cursor;
|
||||
const Tile *cursor_tile;
|
||||
gumpCursorPos cursor_pos;
|
||||
uint8 cursor_xoff, cursor_yoff;
|
||||
|
||||
Graphics::ManagedSurface *actor_doll;
|
||||
|
||||
public:
|
||||
DollViewGump(const Configuration *cfg);
|
||||
~DollViewGump() override;
|
||||
|
||||
bool init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Actor *a, Font *f, Party *p, TileManager *tm, ObjManager *om);
|
||||
|
||||
void set_actor(Actor *a);
|
||||
Actor *get_actor() {
|
||||
return actor;
|
||||
}
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override {
|
||||
return DraggableView::MouseMotion(x, y, state);
|
||||
}
|
||||
GUI_status MouseWheel(sint32 xpos, sint32 ypos) override;
|
||||
void MoveRelative(int dx, int dy) override {
|
||||
return DraggableView::MoveRelative(dx, dy);
|
||||
}
|
||||
|
||||
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
protected:
|
||||
|
||||
void displayEquipWeight();
|
||||
void displayCombatMode();
|
||||
|
||||
void left_arrow();
|
||||
void right_arrow();
|
||||
|
||||
private:
|
||||
|
||||
void activate_combat_button();
|
||||
void setColorKey(Graphics::ManagedSurface *image);
|
||||
GUI_status set_cursor_pos(gumpCursorPos pos);
|
||||
GUI_status moveCursorRelative(NuvieDir direction);
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
557
engines/ultima/nuvie/views/doll_widget.cpp
Normal file
557
engines/ultima/nuvie/views/doll_widget.cpp
Normal file
@@ -0,0 +1,557 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// FIX need to subclass this class for U6, MD & SE
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/files/u6_lib_n.h"
|
||||
#include "ultima/nuvie/files/u6_shape.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/actors/actor_manager.h"
|
||||
#include "ultima/nuvie/screen/game_palette.h"
|
||||
#include "ultima/nuvie/views/doll_widget.h"
|
||||
#include "ultima/nuvie/gui/widgets/command_bar.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/files/nuvie_bmp_file.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static const byte gump_blocked_tile_data[] = {
|
||||
170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
|
||||
170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
|
||||
170, 170, 170, 170, 64, 178, 55, 54, 54, 55, 178, 64, 170, 170, 170, 170,
|
||||
170, 170, 170, 64, 55, 168, 64, 170, 170, 64, 168, 55, 64, 170, 170, 170,
|
||||
170, 170, 64, 55, 64, 170, 170, 170, 170, 170, 12, 12, 55, 64, 170, 170,
|
||||
170, 170, 178, 130, 170, 170, 170, 170, 170, 12, 12, 12, 168, 178, 170, 170,
|
||||
170, 170, 55, 64, 170, 170, 170, 170, 12, 12, 12, 170, 64, 55, 170, 170,
|
||||
170, 170, 54, 170, 170, 170, 170, 12, 12, 12, 170, 170, 170, 54, 170, 170,
|
||||
170, 170, 54, 170, 170, 170, 12, 12, 12, 170, 170, 170, 170, 54, 170, 170,
|
||||
170, 170, 55, 64, 170, 12, 12, 12, 170, 170, 170, 170, 64, 55, 170, 170,
|
||||
170, 170, 178, 168, 12, 12, 12, 170, 170, 170, 170, 170, 168, 178, 170, 170,
|
||||
170, 170, 64, 55, 12, 12, 170, 170, 170, 170, 170, 64, 55, 64, 170, 170,
|
||||
170, 170, 170, 64, 55, 168, 64, 170, 170, 64, 168, 55, 64, 170, 170, 170,
|
||||
170, 170, 170, 170, 64, 178, 55, 54, 54, 55, 178, 64, 170, 170, 170, 170,
|
||||
170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
|
||||
170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170
|
||||
};
|
||||
|
||||
static const byte gump_empty_tile_data[] = {
|
||||
170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
|
||||
170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
|
||||
170, 170, 170, 170, 64, 178, 55, 54, 54, 55, 178, 64, 170, 170, 170, 170,
|
||||
170, 170, 170, 64, 55, 168, 64, 170, 170, 64, 168, 55, 64, 170, 170, 170,
|
||||
170, 170, 64, 55, 64, 170, 170, 170, 170, 170, 170, 64, 55, 64, 170, 170,
|
||||
170, 170, 178, 130, 170, 170, 170, 170, 170, 170, 170, 170, 168, 178, 170, 170,
|
||||
170, 170, 55, 64, 170, 170, 170, 170, 170, 170, 170, 170, 64, 55, 170, 170,
|
||||
170, 170, 54, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 54, 170, 170,
|
||||
170, 170, 54, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 54, 170, 170,
|
||||
170, 170, 55, 64, 170, 170, 170, 170, 170, 170, 170, 170, 64, 55, 170, 170,
|
||||
170, 170, 178, 168, 170, 170, 170, 170, 170, 170, 170, 170, 168, 178, 170, 170,
|
||||
170, 170, 64, 55, 64, 170, 170, 170, 170, 170, 170, 64, 55, 64, 170, 170,
|
||||
170, 170, 170, 64, 55, 168, 64, 170, 170, 64, 168, 55, 64, 170, 170, 170,
|
||||
170, 170, 170, 170, 64, 178, 55, 54, 54, 55, 178, 64, 170, 170, 170, 170,
|
||||
170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
|
||||
170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170
|
||||
};
|
||||
|
||||
DollWidget::DollWidget(const Configuration *cfg, GUI_CallBack *callback)
|
||||
: GUI_Widget(nullptr, 0, 0, 0, 0), config(cfg), callback_object(callback),
|
||||
actor(nullptr), tile_manager(nullptr), selected_obj(nullptr),
|
||||
obj_manager(nullptr), unready_obj(nullptr), empty_tile(nullptr),
|
||||
blocked_tile(nullptr), need_to_free_tiles(false), use_new_dolls(true),
|
||||
old_use_new_dolls(true), actor_doll(nullptr), doll_bg(nullptr),
|
||||
md_doll_shp(nullptr), is_in_portrait_view(false) {
|
||||
bg_color = Game::get_game()->get_palette()->get_bg_color();
|
||||
// Set up hit rects
|
||||
item_hit_rects[0] = Common::Rect(24, 0, 24 + 16, 0 + 16); // ACTOR_HEAD
|
||||
item_hit_rects[1] = Common::Rect(0, 8, 0 + 16, 8 + 16); // ACTOR_NECK
|
||||
item_hit_rects[2] = Common::Rect(48, 8, 48 + 16, 8 + 16); // ACTOR_BODY
|
||||
item_hit_rects[3] = Common::Rect(0, 24, 0 + 16, 24 + 16); // ACTOR_ARM
|
||||
item_hit_rects[4] = Common::Rect(48, 24, 48 + 16, 24 + 16); // ACTOR_ARM_2
|
||||
item_hit_rects[5] = Common::Rect(0, 40, 0 + 16, 40 + 16); // ACTOR_HAND
|
||||
item_hit_rects[6] = Common::Rect(48, 40, 48 + 16, 40 + 16); // ACTOR_HAND_2
|
||||
item_hit_rects[7] = Common::Rect(24, 48, 24 + 16, 48 + 16); // ACTOR_FOOT
|
||||
}
|
||||
|
||||
DollWidget::~DollWidget() {
|
||||
if (need_to_free_tiles) {
|
||||
if (blocked_tile)
|
||||
delete blocked_tile;
|
||||
if (empty_tile)
|
||||
delete empty_tile;
|
||||
}
|
||||
free_doll_shapes();
|
||||
}
|
||||
|
||||
bool DollWidget::init(Actor *a, uint16 x, uint16 y, TileManager *tm, ObjManager *om, bool in_portrait_view) {
|
||||
tile_manager = tm;
|
||||
obj_manager = om;
|
||||
is_in_portrait_view = in_portrait_view;
|
||||
if (!Game::get_game()->is_new_style() || is_in_portrait_view) {
|
||||
switch (Game::get_game()->get_game_type()) {
|
||||
case NUVIE_GAME_U6 :
|
||||
blocked_tile = tile_manager->get_tile(TILE_U6_BLOCKED_EQUIP);
|
||||
empty_tile = tile_manager->get_tile(TILE_U6_EQUIP);
|
||||
break;
|
||||
|
||||
case NUVIE_GAME_SE :
|
||||
blocked_tile = tile_manager->get_tile(TILE_SE_BLOCKED_EQUIP);
|
||||
empty_tile = tile_manager->get_tile(TILE_SE_EQUIP);
|
||||
break;
|
||||
|
||||
case NUVIE_GAME_MD :
|
||||
blocked_tile = tile_manager->get_tile(TILE_MD_BLOCKED_EQUIP); // FIXME: different depending on npc
|
||||
empty_tile = tile_manager->get_tile(TILE_MD_EQUIP); // FIXME: different depending on npc
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
blocked_tile = new Tile();
|
||||
memcpy(&blocked_tile->data, &gump_blocked_tile_data, 256);
|
||||
empty_tile = new Tile();
|
||||
memcpy(&empty_tile->data, &gump_empty_tile_data, 256);
|
||||
need_to_free_tiles = true;
|
||||
}
|
||||
|
||||
GUI_Widget::Init(nullptr, x, y, 64, 64);
|
||||
|
||||
set_actor(a);
|
||||
set_accept_mouseclick(true, USE_BUTTON); // accept [double]clicks from button1 (even if double-click disabled we need clicks)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DollWidget::free_doll_shapes() {
|
||||
if (actor_doll) {
|
||||
delete actor_doll;
|
||||
actor_doll = nullptr;
|
||||
}
|
||||
if (doll_bg) {
|
||||
delete doll_bg;
|
||||
doll_bg = nullptr;
|
||||
}
|
||||
if (md_doll_shp) {
|
||||
delete md_doll_shp;
|
||||
md_doll_shp = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void DollWidget::setColorKey(Graphics::ManagedSurface *image) {
|
||||
if (image) {
|
||||
uint32 bg_color_key = image->format.RGBToColor(0xf1, 0x0f, 0xc4);
|
||||
image->setTransparentColor(bg_color_key);
|
||||
}
|
||||
}
|
||||
|
||||
void DollWidget::set_actor(Actor *a) {
|
||||
actor = a;
|
||||
if (!Game::get_game()->is_new_style()) { // needed so it can be changed in the menus
|
||||
config->value(config_get_game_key(config) + "/use_new_dolls", use_new_dolls, false);
|
||||
if (old_use_new_dolls != use_new_dolls) {
|
||||
if (!use_new_dolls)
|
||||
free_doll_shapes();
|
||||
old_use_new_dolls = use_new_dolls;
|
||||
}
|
||||
}
|
||||
if (use_new_dolls) {
|
||||
free_doll_shapes();
|
||||
if (actor) {
|
||||
ViewManager *vm = Game::get_game()->get_view_manager();
|
||||
if (actor->is_avatar())
|
||||
actor_doll = vm->loadAvatarDollImage(actor_doll, true);
|
||||
else
|
||||
actor_doll = vm->loadCustomActorDollImage(actor_doll, actor->get_actor_num(), true);
|
||||
setColorKey(actor_doll);
|
||||
if (actor_doll) {
|
||||
Common::Path imagefile;
|
||||
build_path(vm->getDollDataDirString(), "orig_style", imagefile);
|
||||
build_path(imagefile, "doll_bg.bmp", imagefile);
|
||||
NuvieBmpFile bmp;
|
||||
doll_bg = bmp.getSdlSurface32(imagefile);
|
||||
if (doll_bg) {
|
||||
Common::Rect dst(3, 1, 30, 31);
|
||||
SDL_BlitSurface(actor_doll, nullptr, doll_bg, &dst);
|
||||
setColorKey(doll_bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (Game::get_game()->get_game_type() == NUVIE_GAME_MD) {
|
||||
load_md_doll_shp();
|
||||
}
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void DollWidget::load_md_doll_shp() {
|
||||
if (actor == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (md_doll_shp)
|
||||
delete md_doll_shp;
|
||||
|
||||
md_doll_shp = new U6Shape();
|
||||
U6Lib_n file;
|
||||
Common::Path filename;
|
||||
config_get_path(config, "mdinv.lzc", filename);
|
||||
file.open(filename, 4, NUVIE_GAME_MD);
|
||||
uint8 num = actor->get_actor_num() + 1;
|
||||
if (actor->is_avatar() && Game::get_game()->get_player()->get_gender() == 0) {
|
||||
num--;
|
||||
}
|
||||
unsigned char *temp_buf = file.get_item(num);
|
||||
if (temp_buf) {
|
||||
md_doll_shp->load(temp_buf + 8);
|
||||
free(temp_buf);
|
||||
} else {
|
||||
delete md_doll_shp;
|
||||
md_doll_shp = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const Common::Rect *DollWidget::get_item_hit_rect(uint8 location) const {
|
||||
if (location < 8)
|
||||
return &item_hit_rects[location];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void DollWidget::Display(bool full_redraw) {
|
||||
//if(full_redraw || update_display)
|
||||
// {
|
||||
update_display = false;
|
||||
|
||||
if (actor != nullptr)
|
||||
display_doll();
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
inline void DollWidget::display_new_doll() {
|
||||
if (doll_bg) {
|
||||
Common::Rect dst;
|
||||
dst = area;
|
||||
dst.translate(15, 15);
|
||||
dst.setWidth(33);
|
||||
dst.setHeight(33);
|
||||
SDL_BlitSurface(doll_bg, nullptr, surface, &dst);
|
||||
}
|
||||
}
|
||||
|
||||
inline void DollWidget::display_old_doll() {
|
||||
Tile *tile;
|
||||
uint16 i, j;
|
||||
int tilenum = 368;
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_MD) // FIXME: different depending on npc - Also needs npc doll info code
|
||||
tilenum = 275;
|
||||
else if (Game::get_game()->get_game_type() == NUVIE_GAME_SE) {
|
||||
if (actor->get_obj_n() == 310 || actor->get_obj_n() == 311
|
||||
|| actor->get_obj_n() == 312)
|
||||
tilenum = 404;
|
||||
else if (actor->get_obj_n() == 318)
|
||||
tilenum = 408;
|
||||
else
|
||||
tilenum = 400;
|
||||
}
|
||||
// screen->fill(bg_color, area.left, area.top, area.width(), area.height()); // should be taken care of by the main view
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 2; j++) { // draw doll
|
||||
tile = tile_manager->get_tile(tilenum + i * 2 + j);
|
||||
screen->blit(area.left + 16 + j * 16, area.top + 16 + i * 16, tile->data, 8, 16, 16, 16, true);
|
||||
}
|
||||
}
|
||||
if (md_doll_shp) {
|
||||
uint16 w, h;
|
||||
md_doll_shp->get_size(&w, &h);
|
||||
screen->blit(area.left + 20, area.top + 18, md_doll_shp->get_data(), 8, w, h, w, true);
|
||||
}
|
||||
}
|
||||
|
||||
inline void DollWidget::display_doll() {
|
||||
if (!Game::get_game()->is_new_style() || is_in_portrait_view) {
|
||||
if (use_new_dolls)
|
||||
display_new_doll();
|
||||
else
|
||||
display_old_doll();
|
||||
}
|
||||
display_readied_object(ACTOR_NECK, area.left, (area.top + 8) + 0 * 16, actor, empty_tile);
|
||||
display_readied_object(ACTOR_BODY, area.left + 3 * 16, (area.top + 8) + 0 * 16, actor, empty_tile);
|
||||
|
||||
display_readied_object(ACTOR_ARM, area.left, (area.top + 8) + 1 * 16, actor, empty_tile);
|
||||
display_readied_object(ACTOR_ARM_2, area.left + 3 * 16, (area.top + 8) + 1 * 16, actor, actor->is_double_handed_obj_readied() ? blocked_tile : empty_tile);
|
||||
|
||||
display_readied_object(ACTOR_HAND, area.left, (area.top + 8) + 2 * 16, actor, empty_tile);
|
||||
display_readied_object(ACTOR_HAND_2, area.left + 3 * 16, (area.top + 8) + 2 * 16, actor, empty_tile);
|
||||
|
||||
display_readied_object(ACTOR_HEAD, area.left + 16 + 8, area.top, actor, empty_tile);
|
||||
display_readied_object(ACTOR_FOOT, area.left + 16 + 8, area.top + 3 * 16, actor, empty_tile);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
inline void DollWidget::display_readied_object(uint8 location, uint16 x, uint16 y, Actor *theActor, Tile *emptyTile) {
|
||||
Obj *obj;
|
||||
Tile *tile;
|
||||
|
||||
obj = theActor->inventory_get_readied_object(location);
|
||||
|
||||
if (obj)
|
||||
tile = tile_manager->get_tile(obj_manager->get_obj_tile_num(obj->obj_n) + obj->frame_n);
|
||||
else
|
||||
tile = emptyTile;
|
||||
|
||||
screen->blit(x, y, tile->data, 8, 16, 16, 16, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// when no action is pending the Use button may be used to start dragging,
|
||||
// otherwise it has the same effect as ENTER (using InventoryView's callback)
|
||||
GUI_status DollWidget::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
uint8 location;
|
||||
Obj *obj;
|
||||
x -= area.left;
|
||||
y -= area.top;
|
||||
|
||||
CommandBar *command_bar = Game::get_game()->get_command_bar();
|
||||
if (button == ACTION_BUTTON && event->get_mode() == MOVE_MODE
|
||||
&& command_bar->get_selected_action() > 0) { // Exclude attack mode too
|
||||
if (command_bar->try_selected_action() == false) // start new action
|
||||
return GUI_YUM; // false if new event doesn't need target
|
||||
}
|
||||
|
||||
if (actor && selected_obj == nullptr && (button == USE_BUTTON || button == ACTION_BUTTON || button == DRAG_BUTTON)) {
|
||||
for (location = 0; location < 8; location++) {
|
||||
if (HitRect(x, y, item_hit_rects[location])) { // FIXME: duplicating code in InventoryWidget
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Hit %d\n", location);
|
||||
obj = actor->inventory_get_readied_object(location);
|
||||
if (button == ACTION_BUTTON && command_bar->get_selected_action() > 0
|
||||
&& event->get_mode() == INPUT_MODE) {
|
||||
if (obj) {
|
||||
event->select_obj(obj, actor);
|
||||
return GUI_YUM;
|
||||
} else {
|
||||
// has not found a target yet
|
||||
Game::get_game()->get_scroll()->display_string("nothing!\n");
|
||||
event->endAction(true);
|
||||
event->set_mode(MOVE_MODE);
|
||||
}
|
||||
return GUI_PASS;
|
||||
}
|
||||
if (obj) {
|
||||
|
||||
if ((event->get_mode() == MOVE_MODE || event->get_mode() == EQUIP_MODE)
|
||||
&& button == DRAG_BUTTON)
|
||||
selected_obj = obj; // start dragging
|
||||
else // send to View
|
||||
callback_object->callback(INVSELECT_CB, this, obj);
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
// un-ready selected item
|
||||
GUI_status DollWidget::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
|
||||
// only act now if double-click is disabled
|
||||
if (selected_obj && !Game::get_game()->get_map_window()->is_doubleclick_enabled()) {
|
||||
event->unready(selected_obj);
|
||||
Redraw();
|
||||
unready_obj = nullptr;
|
||||
} else if (selected_obj) {
|
||||
wait_for_mouseclick(USE_BUTTON);
|
||||
unready_obj = selected_obj;
|
||||
}
|
||||
|
||||
selected_obj = nullptr;
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status DollWidget::MouseClick(int x, int y, Events::MouseButton button) {
|
||||
return MouseUp(x, y, button);
|
||||
}
|
||||
|
||||
GUI_status DollWidget::MouseMotion(int x, int y, uint8 state) {
|
||||
Tile *tile;
|
||||
|
||||
if (selected_obj && !dragging && Game::get_game()->is_dragging_enabled()) {
|
||||
dragging = true;
|
||||
tile = tile_manager->get_tile(obj_manager->get_obj_tile_num(selected_obj->obj_n) + selected_obj->frame_n);
|
||||
return gui_drag_manager->start_drag(this, GUI_DRAG_OBJ, selected_obj, tile->data, 16, 16, 8);
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
void DollWidget::drag_drop_success(int x, int y, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "DollWidget::drag_drop_success()\n");
|
||||
dragging = false;
|
||||
// handled by drop target
|
||||
// actor->remove_readied_object(selected_obj);
|
||||
// actor->inventory_remove_obj(selected_obj);
|
||||
selected_obj = nullptr;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void DollWidget::drag_drop_failed(int x, int y, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "DollWidget::drag_drop_failed()\n");
|
||||
dragging = false;
|
||||
selected_obj = nullptr;
|
||||
}
|
||||
|
||||
bool DollWidget::drag_accept_drop(int x, int y, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "DollWidget::drag_accept_drop()\n");
|
||||
if (message == GUI_DRAG_OBJ) {
|
||||
Obj *obj = (Obj *)data;
|
||||
if (obj->is_readied() && obj->get_actor_holding_obj() == actor) {
|
||||
// FIXME: need to detect ready location so player can switch hands
|
||||
DEBUG(0, LEVEL_WARNING, "DollWidget: Object already equipped!\n");
|
||||
return false;
|
||||
}
|
||||
if (obj->get_actor_holding_obj() != actor) {
|
||||
if (obj->is_in_inventory()) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
event->display_move_text(actor, obj);
|
||||
if (event->can_move_obj_between_actors(obj, obj->get_actor_holding_obj(), actor, false)) {
|
||||
Game::get_game()->get_player()->subtract_movement_points(3);
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop Accepted\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obj->get_actor_holding_obj() == actor
|
||||
|| Game::get_game()->get_map_window()->can_get_obj(actor, obj)) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop Accepted\n");
|
||||
return true;
|
||||
} else {
|
||||
DEBUG(0, LEVEL_WARNING, "DollWidget: Must be holding object!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop Refused\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
void DollWidget::drag_perform_drop(int /*x*/, int /*y*/, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "DollWidget::drag_perform_drop()\n");
|
||||
Obj *obj;
|
||||
|
||||
//x -= area.left;
|
||||
//y -= area.top;
|
||||
|
||||
if (message == GUI_DRAG_OBJ) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Ready item.\n");
|
||||
obj = (Obj *)data;
|
||||
|
||||
bool can_equip = true;
|
||||
if (!obj->is_in_inventory()) { // get
|
||||
// event->newAction(GET_MODE);
|
||||
Game::get_game()->get_scroll()->display_string("Get-");
|
||||
can_equip = Game::get_game()->get_event()->perform_get(obj, nullptr, actor);
|
||||
// if(!can_equip)
|
||||
// {
|
||||
// assert(!(obj->status & OBJ_STATUS_IN_CONTAINER));
|
||||
// obj_manager->add_obj(obj); // add back to map
|
||||
// }
|
||||
} else
|
||||
obj_manager->moveto_inventory(obj, actor);
|
||||
if (can_equip) { // ready
|
||||
assert(!obj->is_readied());
|
||||
Game::get_game()->get_event()->ready(obj, actor);
|
||||
}
|
||||
Redraw();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void DollWidget::drag_draw(int x, int y, int message, void *data) {
|
||||
Tile *tile;
|
||||
|
||||
if (!selected_obj)
|
||||
return;
|
||||
|
||||
tile = tile_manager->get_tile(obj_manager->get_obj_tile_num(selected_obj) + selected_obj->frame_n);
|
||||
|
||||
int nx = x - 8;
|
||||
int ny = y - 8;
|
||||
|
||||
if (nx + 16 >= screen->get_width())
|
||||
nx = screen->get_width() - 17;
|
||||
else if (nx < 0)
|
||||
nx = 0;
|
||||
|
||||
if (ny + 16 >= screen->get_height())
|
||||
ny = screen->get_height() - 17;
|
||||
else if (ny < 0)
|
||||
ny = 0;
|
||||
|
||||
screen->blit(nx, ny, tile->data, 8, 16, 16, 16, true);
|
||||
screen->update(nx, ny, 16, 16);
|
||||
}
|
||||
|
||||
|
||||
/* Use object.
|
||||
*/
|
||||
GUI_status DollWidget::MouseDouble(int x, int y, Events::MouseButton button) {
|
||||
// we have to check if double-clicks are allowed here, since we use single-clicks
|
||||
if (!Game::get_game()->get_map_window()->is_doubleclick_enabled())
|
||||
return GUI_PASS;
|
||||
Events *event = Game::get_game()->get_event();
|
||||
Obj *obj = selected_obj;
|
||||
|
||||
unready_obj = nullptr;
|
||||
selected_obj = nullptr;
|
||||
|
||||
if (!(actor && obj))
|
||||
return GUI_YUM;
|
||||
|
||||
if (event->newAction(USE_MODE))
|
||||
event->select_obj(obj);
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
// change container, ready/unready object, activate arrows
|
||||
GUI_status DollWidget::MouseDelayed(int x, int y, Events::MouseButton button) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
if (unready_obj) {
|
||||
event->unready(unready_obj);
|
||||
Redraw();
|
||||
unready_obj = nullptr;
|
||||
}
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
101
engines/ultima/nuvie/views/doll_widget.h
Normal file
101
engines/ultima/nuvie/views/doll_widget.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/* 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 NUVIE_VIEWS_DOLL_WIDGET_H
|
||||
#define NUVIE_VIEWS_DOLL_WIDGET_H
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/core/tile_manager.h"
|
||||
#include "ultima/nuvie/core/obj_manager.h"
|
||||
#include "ultima/nuvie/views/inventory_message.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class Actor;
|
||||
class U6Shape;
|
||||
|
||||
class DollWidget : public GUI_Widget {
|
||||
|
||||
const Configuration *config;
|
||||
TileManager *tile_manager;
|
||||
ObjManager *obj_manager;
|
||||
|
||||
Actor *actor;
|
||||
bool use_new_dolls, old_use_new_dolls;
|
||||
|
||||
Obj *selected_obj, *unready_obj;
|
||||
|
||||
uint8 bg_color;
|
||||
bool is_in_portrait_view;
|
||||
bool need_to_free_tiles;
|
||||
Tile *empty_tile, *blocked_tile;
|
||||
|
||||
U6Shape *md_doll_shp;
|
||||
Graphics::ManagedSurface *actor_doll, *doll_bg;
|
||||
|
||||
public:
|
||||
DollWidget(const Configuration *cfg, GUI_CallBack *callback = nullptr);
|
||||
~DollWidget() override;
|
||||
|
||||
bool init(Actor *a, uint16 x, uint16 y, TileManager *tm, ObjManager *om, bool in_portrat_view = false);
|
||||
void free_doll_shapes();
|
||||
void setColorKey(Graphics::ManagedSurface *image);
|
||||
void set_actor(Actor *a);
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override;
|
||||
GUI_status MouseDouble(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseClick(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseDelayed(int x, int y, Events::MouseButton button) override;
|
||||
|
||||
void drag_drop_success(int x, int y, int message, void *data) override;
|
||||
void drag_drop_failed(int x, int y, int message, void *data) override;
|
||||
|
||||
bool drag_accept_drop(int x, int y, int message, void *data) override;
|
||||
void drag_perform_drop(int x, int y, int message, void *data) override;
|
||||
|
||||
void drag_draw(int x, int y, int message, void *data) override;
|
||||
|
||||
const Common::Rect *get_item_hit_rect(uint8 location) const;
|
||||
|
||||
protected:
|
||||
|
||||
GUI_CallBack *callback_object; // object-selected callback
|
||||
|
||||
void display_doll();
|
||||
void display_old_doll();
|
||||
void display_new_doll();
|
||||
void display_readied_object(uint8 location, uint16 x, uint16 y, Actor *actor, Tile *emptyTile);
|
||||
|
||||
private:
|
||||
Common::Rect item_hit_rects[8];
|
||||
|
||||
void load_md_doll_shp();
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
145
engines/ultima/nuvie/views/draggable_view.cpp
Normal file
145
engines/ultima/nuvie/views/draggable_view.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/views/draggable_view.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
DraggableView::DraggableView(const Configuration *cfg) : View(cfg),
|
||||
drag(false), button_x(0), button_y(0), bg_image(nullptr),
|
||||
bg_color_key(0), always_need_full_redraw_when_moved(false) {
|
||||
Game *game = Game::get_game();
|
||||
if (game->is_orig_style() || game->is_original_plus_cutoff_map()) {
|
||||
need_full_redraw_when_moved = true;
|
||||
always_need_full_redraw_when_moved = true;
|
||||
} else if (game->get_game_width() < game->get_screen()->get_width()
|
||||
|| game->get_game_height() < game->get_screen()->get_height()) {
|
||||
need_full_redraw_when_moved = true;
|
||||
always_need_full_redraw_when_moved = false;
|
||||
} else // no need to set always_need_full_redraw_when_moved
|
||||
need_full_redraw_when_moved = false;
|
||||
}
|
||||
|
||||
DraggableView::~DraggableView() {
|
||||
if (bg_image) {
|
||||
delete bg_image;
|
||||
bg_image = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void DraggableView::set_bg_color_key(uint8 r, uint8 g, uint8 b) {
|
||||
if (bg_image) {
|
||||
bg_color_key = bg_image->format.RGBToColor(0, 0x70, 0xfc);
|
||||
bg_image->setTransparentColor(bg_color_key);
|
||||
}
|
||||
}
|
||||
|
||||
GUI_status DraggableView::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
if (bg_image && HitRect(x, y)) {
|
||||
uint32 pixel = sdl_getpixel(bg_image, x - area.left, y - area.top);
|
||||
if (pixel == bg_color_key) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
}
|
||||
drag = true;
|
||||
button_x = x;
|
||||
button_y = y;
|
||||
|
||||
moveToFront();
|
||||
if (Game::get_game()->is_new_style()) {
|
||||
Game::get_game()->get_scroll()->moveToFront();
|
||||
}
|
||||
grab_focus();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status DraggableView::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
drag = false;
|
||||
|
||||
release_focus();
|
||||
if (button == Events::BUTTON_RIGHT) {
|
||||
Game::get_game()->get_view_manager()->close_gump(this);
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status DraggableView::MouseMotion(int x, int y, uint8 state) {
|
||||
int dx, dy;
|
||||
|
||||
if (!drag || state == 0) //state is 0 if no button pressed
|
||||
return GUI_PASS;
|
||||
|
||||
dx = x - button_x;
|
||||
dy = y - button_y;
|
||||
|
||||
button_x = x;
|
||||
button_y = y;
|
||||
|
||||
GUI::get_gui()->moveWidget(this, dx, dy);
|
||||
// Redraw();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void DraggableView::force_full_redraw_if_needed() {
|
||||
if (need_full_redraw_when_moved) {
|
||||
if (always_need_full_redraw_when_moved // or over background
|
||||
|| (area.right > Game::get_game()->get_game_width() + Game::get_game()->get_game_x_offset()
|
||||
|| area.left < Game::get_game()->get_game_x_offset() || area.top < Game::get_game()->get_game_y_offset()
|
||||
|| area.bottom > Game::get_game()->get_game_height() + Game::get_game()->get_game_y_offset()))
|
||||
GUI::get_gui()->force_full_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void DraggableView::MoveRelative(int dx, int dy) {
|
||||
int new_x = area.left + dx;
|
||||
|
||||
if (new_x < 0) {
|
||||
dx = -area.left;
|
||||
} else if (new_x + area.width() > screen->get_width()) {
|
||||
dx = screen->get_width() - (area.left + area.width());
|
||||
}
|
||||
|
||||
int new_y = area.top + dy;
|
||||
|
||||
if (new_y < 0) {
|
||||
dy = -area.top;
|
||||
} else if (new_y + area.height() > screen->get_height()) {
|
||||
dy = screen->get_height() - (area.top + area.height());
|
||||
}
|
||||
|
||||
force_full_redraw_if_needed(); // needs to happen before the move
|
||||
GUI_Widget::MoveRelative(dx, dy);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
61
engines/ultima/nuvie/views/draggable_view.h
Normal file
61
engines/ultima/nuvie/views/draggable_view.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* 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 NUVIE_VIEWS_INVENTORY_FONT_H
|
||||
#define NUVIE_VIEWS_INVENTORY_FONT_H
|
||||
|
||||
#include "ultima/nuvie/views/view.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class GUI_Button;
|
||||
|
||||
class DraggableView: public View {
|
||||
protected:
|
||||
Graphics::ManagedSurface *bg_image;
|
||||
uint32 bg_color_key;
|
||||
|
||||
private:
|
||||
bool drag, need_full_redraw_when_moved, always_need_full_redraw_when_moved;
|
||||
int button_x, button_y;
|
||||
|
||||
public:
|
||||
DraggableView(const Configuration *config);
|
||||
~DraggableView() override;
|
||||
|
||||
/* events, used for dragging the area. */
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override;
|
||||
void MoveRelative(int dx, int dy) override;
|
||||
|
||||
protected:
|
||||
void set_bg_color_key(uint8 r, uint8 g, uint8 b);
|
||||
void force_full_redraw_if_needed();
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
244
engines/ultima/nuvie/views/inventory_font.h
Normal file
244
engines/ultima/nuvie/views/inventory_font.h
Normal file
@@ -0,0 +1,244 @@
|
||||
/* 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 NUVIE_VIEWS_INVENTORY_FONT_H
|
||||
#define NUVIE_VIEWS_INVENTORY_FONT_H
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static const int NUVIE_MICRO_FONT_COUNT = 26;
|
||||
|
||||
const unsigned char inventory_font[NUVIE_MICRO_FONT_COUNT][15] = {
|
||||
{
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1
|
||||
}
|
||||
,
|
||||
{
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1
|
||||
}
|
||||
,
|
||||
{
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 1, 1
|
||||
}
|
||||
,
|
||||
{
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
1, 1, 1
|
||||
}
|
||||
,
|
||||
{
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1
|
||||
}
|
||||
,
|
||||
{
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
1, 1, 1
|
||||
}
|
||||
,
|
||||
{
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1
|
||||
}
|
||||
,
|
||||
{
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1
|
||||
}
|
||||
,
|
||||
{
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1
|
||||
}
|
||||
,
|
||||
{
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1
|
||||
}
|
||||
, // A
|
||||
{
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1
|
||||
}
|
||||
, // B
|
||||
{
|
||||
1, 1, 0,
|
||||
1, 0, 1,
|
||||
1, 1, 0,
|
||||
1, 0, 1,
|
||||
1, 1, 0
|
||||
}
|
||||
, // C
|
||||
{
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 1, 1
|
||||
}
|
||||
, // D
|
||||
{
|
||||
1, 1, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 0
|
||||
}
|
||||
, // E
|
||||
{
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 1, 1
|
||||
}
|
||||
, // F
|
||||
{
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 1, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0
|
||||
}
|
||||
, // G
|
||||
{
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1
|
||||
}
|
||||
, // H
|
||||
{
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1
|
||||
}
|
||||
, // I
|
||||
{
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
1, 1, 1
|
||||
}
|
||||
, // J
|
||||
{
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1
|
||||
}
|
||||
, // K
|
||||
{
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 1
|
||||
}
|
||||
, // L
|
||||
{
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 1, 1
|
||||
}
|
||||
, // M
|
||||
{
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1
|
||||
}
|
||||
, // n
|
||||
{
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 1
|
||||
}
|
||||
, // o
|
||||
{
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1
|
||||
}
|
||||
, // P
|
||||
{
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
1, 0, 0
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
28
engines/ultima/nuvie/views/inventory_message.h
Normal file
28
engines/ultima/nuvie/views/inventory_message.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/* 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 NUVIE_VIEWS_INVENTORY_MESSAGE_H
|
||||
#define NUVIE_VIEWS_INVENTORY_MESSAGE_H
|
||||
|
||||
static const uint16 BUTTON_CB = 0x1;
|
||||
static const uint16 INVSELECT_CB = 0x2;
|
||||
|
||||
#endif
|
||||
700
engines/ultima/nuvie/views/inventory_view.cpp
Normal file
700
engines/ultima/nuvie/views/inventory_view.cpp
Normal file
@@ -0,0 +1,700 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
#include "ultima/nuvie/misc/u6_llist.h"
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
#include "ultima/nuvie/views/doll_widget.h"
|
||||
#include "ultima/nuvie/views/inventory_widget.h"
|
||||
#include "ultima/nuvie/views/inventory_view.h"
|
||||
#include "ultima/nuvie/core/party.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/usecode/usecode.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static const char combat_mode_tbl[][8] = {"COMMAND", " FRONT", " REAR", " FLANK", "BERSERK", "RETREAT", "ASSAULT"};
|
||||
static const char combat_mode_tbl_se[][6] = {"CMND", "RANGE", "FLEE", "CLOSE"};
|
||||
static const char combat_mode_tbl_md[][6] = {"CMND", "RANGE", "FLEE", "ATTK"};
|
||||
#define MD Game::get_game()->get_game_type()==NUVIE_GAME_MD
|
||||
|
||||
InventoryView::InventoryView(const Configuration *cfg)
|
||||
: View(cfg), doll_widget(nullptr), inventory_widget(nullptr),
|
||||
combat_button(nullptr), cursor_tile(nullptr), show_cursor(false),
|
||||
is_party_member(false), picking_pocket(false), outside_actor(nullptr),
|
||||
lock_actor(false) {
|
||||
cursor_pos.area = INVAREA_LIST;
|
||||
cursor_pos.x = cursor_pos.y = 0;
|
||||
cursor_pos.px = cursor_pos.py = 0;
|
||||
}
|
||||
|
||||
InventoryView::~InventoryView() {
|
||||
}
|
||||
|
||||
bool InventoryView::set_party_member(uint8 party_member) {
|
||||
if (lock_actor || party_member >= party->get_party_size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
picking_pocket = false;
|
||||
|
||||
if (View::set_party_member(party_member)
|
||||
&& !Game::get_game()->get_event()->using_control_cheat()) {
|
||||
is_party_member = true;
|
||||
if (doll_widget)
|
||||
doll_widget->set_actor(party->get_actor(cur_party_member));
|
||||
if (inventory_widget)
|
||||
inventory_widget->set_actor(party->get_actor(cur_party_member));
|
||||
|
||||
show_buttons();
|
||||
|
||||
if (combat_button) {
|
||||
if (party_member == 0)
|
||||
combat_button->Hide();
|
||||
else
|
||||
combat_button->Show();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
is_party_member = false;
|
||||
hide_buttons();
|
||||
|
||||
if (actor_button) actor_button->Show();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InventoryView::set_actor(Actor *actor, bool pickpocket) {
|
||||
if (lock_actor)
|
||||
return false;
|
||||
|
||||
if (party->contains_actor(actor)) {
|
||||
set_party_member(party->get_member_num(actor));
|
||||
return true;
|
||||
}
|
||||
picking_pocket = pickpocket;
|
||||
is_party_member = false;
|
||||
outside_actor = actor;
|
||||
if (doll_widget)
|
||||
doll_widget->set_actor(actor);
|
||||
if (inventory_widget)
|
||||
inventory_widget->set_actor(actor);
|
||||
|
||||
if (picking_pocket) {
|
||||
if (actor_button) actor_button->Hide();
|
||||
}
|
||||
hide_buttons();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InventoryView::init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om) {
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6)
|
||||
View::init(x, y, f, p, tm, om);
|
||||
else
|
||||
View::init(x, y - 2, f, p, tm, om);
|
||||
|
||||
doll_widget = new DollWidget(config, this);
|
||||
doll_widget->init(party->get_actor(cur_party_member), 0, 8, tile_manager, obj_manager, true);
|
||||
|
||||
AddWidget(doll_widget);
|
||||
|
||||
inventory_widget = new InventoryWidget(config, this);
|
||||
inventory_widget->init(party->get_actor(cur_party_member), 64, 8, tile_manager, obj_manager, font);
|
||||
|
||||
AddWidget(inventory_widget);
|
||||
|
||||
add_command_icons(tmp_screen, view_manager);
|
||||
|
||||
cursor_tile = tile_manager->get_cursor_tile();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void InventoryView::PlaceOnScreen(Screen *s, GUI_DragManager *dm, int x, int y) {
|
||||
GUI_Widget::PlaceOnScreen(s, dm, x, y);
|
||||
update_cursor(); // initial position; uses area
|
||||
}
|
||||
|
||||
|
||||
void InventoryView::Display(bool full_redraw) {
|
||||
full_redraw = true;
|
||||
if (full_redraw || update_display) {
|
||||
if (MD)
|
||||
fill_md_background(lock_actor ? 7 : bg_color, area);
|
||||
else
|
||||
screen->fill(bg_color, area.left, area.top, area.width(), area.height());
|
||||
|
||||
if (is_party_member)
|
||||
display_combat_mode();
|
||||
display_name();
|
||||
display_inventory_weights();
|
||||
}
|
||||
|
||||
DisplayChildren(full_redraw);
|
||||
|
||||
if (full_redraw || update_display) {
|
||||
update_display = false;
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
if (show_cursor && cursor_tile != nullptr) {
|
||||
screen->blit(cursor_pos.px, cursor_pos.py, (unsigned char *)cursor_tile->data,
|
||||
8, 16, 16, 16, true, nullptr);
|
||||
screen->update(cursor_pos.px, cursor_pos.py, 16, 16);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void InventoryView::display_name() {
|
||||
const char *name;
|
||||
int y_off = 0;
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_SE)
|
||||
y_off = 1;
|
||||
if (is_party_member)
|
||||
name = party->get_actor_name(cur_party_member);
|
||||
else if (picking_pocket)
|
||||
name = outside_actor->get_name();
|
||||
else
|
||||
name = Game::get_game()->get_player()->get_actor()->get_name(true);
|
||||
if (name == nullptr)
|
||||
return;
|
||||
|
||||
font->drawString(screen, name, area.left + ((136) - strlen(name) * 8) / 2, area.top + y_off);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void InventoryView::add_command_icons(Screen *tmp_screen, void *view_manager) {
|
||||
Tile *tile;
|
||||
int y = 96;
|
||||
if (MD)
|
||||
y = 100;
|
||||
else if (Game::get_game()->get_game_type() == NUVIE_GAME_U6)
|
||||
y = 80;
|
||||
Graphics::ManagedSurface *button_image;
|
||||
Graphics::ManagedSurface *button_image2;
|
||||
//FIX need to handle clicked button image, check image free on destruct.
|
||||
|
||||
tile = tile_manager->get_tile(MD ? 282 : 387); //left arrow icon
|
||||
button_image = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
button_image2 = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
left_button = new GUI_Button(this, 0, y, button_image, button_image2, this);
|
||||
this->AddWidget(left_button);
|
||||
|
||||
tile = tile_manager->get_tile(MD ? 279 : 384); //party view icon
|
||||
button_image = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
button_image2 = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
party_button = new GUI_Button(view_manager, 16, y, button_image, button_image2, this);
|
||||
this->AddWidget(party_button);
|
||||
|
||||
tile = tile_manager->get_tile(MD ? 280 : 385); //actor view icon
|
||||
button_image = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
button_image2 = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
actor_button = new GUI_Button(view_manager, 2 * 16, y, button_image, button_image2, this);
|
||||
this->AddWidget(actor_button);
|
||||
|
||||
tile = tile_manager->get_tile(MD ? 283 : 388); //right arrow icon
|
||||
button_image = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
button_image2 = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
right_button = new GUI_Button(this, 3 * 16, y, button_image, button_image2, this);
|
||||
this->AddWidget(right_button);
|
||||
|
||||
if (MD)
|
||||
tile = tile_manager->get_tile(285); //combat icon
|
||||
else if (Game::get_game()->get_game_type() == NUVIE_GAME_SE)
|
||||
tile = tile_manager->get_tile(365); //combat icon
|
||||
else
|
||||
tile = tile_manager->get_tile(391); //combat icon
|
||||
button_image = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
button_image2 = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
combat_button = new GUI_Button(this, 4 * 16, y, button_image, button_image2, this); //FIX combat
|
||||
this->AddWidget(combat_button);
|
||||
|
||||
}
|
||||
|
||||
void InventoryView::display_inventory_weights() {
|
||||
uint8 strength;
|
||||
unsigned int inv_weight;
|
||||
unsigned int equip_weight;
|
||||
Actor *actor;
|
||||
if (is_party_member)
|
||||
actor = party->get_actor(cur_party_member);
|
||||
else if (picking_pocket)
|
||||
actor = outside_actor;
|
||||
else
|
||||
actor = Game::get_game()->get_player()->get_actor();
|
||||
char string[9]; // "E:xx/xxs"
|
||||
|
||||
strength = actor->get_strength();
|
||||
|
||||
ViewManager *vm = Game::get_game()->get_view_manager();
|
||||
inv_weight = vm->get_display_weight(actor->get_inventory_weight());
|
||||
equip_weight = vm->get_display_weight(actor->get_inventory_equip_weight());
|
||||
|
||||
snprintf(string, 9, "E:%u/%us", equip_weight, strength);
|
||||
font->drawString(screen, string, area.left, area.top + 72);
|
||||
|
||||
snprintf(string, 9, "I:%u/%us", inv_weight, strength * 2);
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6)
|
||||
font->drawString(screen, string, area.left + 4 * 16 + 8, area.top + 72);
|
||||
else
|
||||
font->drawString(screen, string, area.left, area.top + 80);
|
||||
}
|
||||
|
||||
void InventoryView::display_combat_mode() {
|
||||
Actor *actor = party->get_actor(cur_party_member);
|
||||
|
||||
uint8 index = get_combat_mode_index(actor);
|
||||
if (Game::get_game()->get_game_type() != NUVIE_GAME_U6) {
|
||||
int y_off = 96;
|
||||
if (MD)
|
||||
y_off = 100;
|
||||
Tile *tile;
|
||||
|
||||
// Avatar combat text background (where command button is for other party members)
|
||||
if (actor->get_actor_num() == 1 || actor->get_actor_num() == 0) {
|
||||
if (MD)
|
||||
tile = tile_manager->get_tile(284);
|
||||
else
|
||||
tile = tile_manager->get_tile(364);
|
||||
screen->blit(area.left + 4 * 16, area.top + y_off, tile->data, 8, 16, 16, 16, true);
|
||||
}
|
||||
if (MD) // combat text background
|
||||
tile = tile_manager->get_tile(286);
|
||||
else // SE
|
||||
tile = tile_manager->get_tile(366);
|
||||
screen->blit(area.left + 5 * 16, area.top + y_off, tile->data, 8, 16, 16, 16, true);
|
||||
screen->blit(area.left + 6 * 16, area.top + y_off, tile->data, 8, 16, 16, 16, true); // reuse
|
||||
|
||||
if (MD) // last combat text background
|
||||
tile = tile_manager->get_tile(287);
|
||||
else
|
||||
tile = tile_manager->get_tile(368);
|
||||
screen->blit(area.left + 7 * 16, area.top + y_off, tile->data, 8, 16, 16, 16, true);
|
||||
|
||||
if (MD)
|
||||
font->drawString(screen, combat_mode_tbl_md[index], area.left + 5 * 16, area.top + 101);
|
||||
else
|
||||
font->drawString(screen, combat_mode_tbl_se[index], area.left + 5 * 16, area.top + 98);
|
||||
} else
|
||||
font->drawString(screen, combat_mode_tbl[index], area.left + 5 * 16, area.top + 88);
|
||||
}
|
||||
|
||||
/* Move the cursor around, ready or unready objects, select objects, switch
|
||||
* to container view, use command icons.
|
||||
*/
|
||||
GUI_status InventoryView::KeyDown(const Common::KeyState &key) {
|
||||
if (!show_cursor) // FIXME: don't rely on show_cursor to get/pass focus
|
||||
return GUI_PASS;
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
|
||||
switch (keybinder->GetActionKeyType(a)) {
|
||||
// keypad arrow keys (moveCursorRelative doesn't accept diagonals)
|
||||
case SOUTH_WEST_KEY:
|
||||
moveCursorRelative(0, 1);
|
||||
moveCursorRelative(-1, 0);
|
||||
break;
|
||||
case SOUTH_EAST_KEY:
|
||||
moveCursorRelative(0, 1);
|
||||
moveCursorRelative(1, 0);
|
||||
break;
|
||||
case NORTH_WEST_KEY:
|
||||
moveCursorRelative(0, -1);
|
||||
moveCursorRelative(-1, 0);
|
||||
break;
|
||||
case NORTH_EAST_KEY:
|
||||
moveCursorRelative(0, -1);
|
||||
moveCursorRelative(1, 0);
|
||||
break;
|
||||
case NORTH_KEY:
|
||||
moveCursorRelative(0, -1);
|
||||
break;
|
||||
case SOUTH_KEY:
|
||||
moveCursorRelative(0, 1);
|
||||
break;
|
||||
case WEST_KEY:
|
||||
moveCursorRelative(-1, 0);
|
||||
break;
|
||||
case EAST_KEY:
|
||||
moveCursorRelative(1, 0);
|
||||
break;
|
||||
case DO_ACTION_KEY:
|
||||
select_objAtCursor();
|
||||
break;
|
||||
case TOGGLE_CURSOR_KEY :
|
||||
if (is_party_member) { // when in pickpocket mode we don't want to allow tabing to map window.
|
||||
set_show_cursor(false);
|
||||
return GUI_PASS;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// set_show_cursor(false); // newAction() can move cursor here
|
||||
return GUI_PASS;
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
|
||||
/* Put cursor over one of the readied-item slots. */
|
||||
void InventoryView::moveCursorToSlot(uint8 slot_num) {
|
||||
cursor_pos.area = INVAREA_DOLL;
|
||||
cursor_pos.x = slot_num;
|
||||
}
|
||||
|
||||
/* Put cursor over one of the visible inventory slots. (column inv_x, row inv_y) */
|
||||
void InventoryView::moveCursorToInventory(uint8 inv_x, uint8 inv_y) {
|
||||
cursor_pos.area = INVAREA_LIST;
|
||||
cursor_pos.x = inv_x;
|
||||
cursor_pos.y = inv_y;
|
||||
}
|
||||
|
||||
/* Put cursor over one of the command icons. */
|
||||
void InventoryView::moveCursorToButton(uint8 button_num) {
|
||||
cursor_pos.area = INVAREA_COMMAND;
|
||||
cursor_pos.x = button_num;
|
||||
}
|
||||
|
||||
/* Put cursor over the container or actor icon above the inventory widget. */
|
||||
void InventoryView::moveCursorToTop() {
|
||||
cursor_pos.area = INVAREA_TOP;
|
||||
}
|
||||
|
||||
/* Put cursor over the next slot or icon in relative direction new_x, new_y. */
|
||||
void InventoryView::moveCursorRelative(sint8 new_x, sint8 new_y) {
|
||||
uint32 x = cursor_pos.x, y = cursor_pos.y;
|
||||
if (cursor_pos.area == INVAREA_LIST) {
|
||||
if (x == 0 && new_x < 0) {
|
||||
if (y == 0)
|
||||
moveCursorToSlot(2);
|
||||
else if (y == 1)
|
||||
moveCursorToSlot(4);
|
||||
else if (y == 2)
|
||||
moveCursorToSlot(6);
|
||||
else if (y == 3) {
|
||||
if (!picking_pocket)
|
||||
moveCursorToButton(3);
|
||||
}
|
||||
} else if (y == 0 && new_y < 0) {
|
||||
if (inventory_widget->up_arrow()) // scroll up
|
||||
update_display = true;
|
||||
else
|
||||
moveCursorToTop(); // move to container icon
|
||||
} else if (y == (uint8)(inventory_widget->get_num_rows() - 1) && new_y > 0) {
|
||||
if (inventory_widget->down_arrow()) // scroll down
|
||||
update_display = true;
|
||||
else if (!picking_pocket)
|
||||
moveCursorToButton((x == 0) ? 3 : 4); // move to command icon
|
||||
} else if ((x + new_x) <= 3)
|
||||
moveCursorToInventory(x + new_x, y + new_y);
|
||||
} else if (cursor_pos.area == INVAREA_DOLL) {
|
||||
// moves from these readied items can jump to inventory list
|
||||
if (new_x > 0 && x == 2)
|
||||
moveCursorToInventory(0, 0);
|
||||
else if (new_x > 0 && x == 4)
|
||||
moveCursorToInventory(0, 1);
|
||||
else if (new_x > 0 && x == 6)
|
||||
moveCursorToInventory(0, 2);
|
||||
// moves from these readied items can jump to command icons
|
||||
else if (new_y > 0 && x == 5 && !picking_pocket)
|
||||
moveCursorToButton(0);
|
||||
else if (new_y > 0 && x == 6 && !picking_pocket)
|
||||
moveCursorToButton(2);
|
||||
else if (new_y > 0 && x == 7 && !picking_pocket)
|
||||
moveCursorToButton(1);
|
||||
// the rest move between readied items
|
||||
else if (x == 0)
|
||||
moveCursorToSlot((new_x < 0) ? 1
|
||||
: (new_x > 0) ? 2
|
||||
: (new_y > 0) ? 7 : 0);
|
||||
else if (x == 7)
|
||||
moveCursorToSlot((new_x < 0) ? 5
|
||||
: (new_x > 0) ? 6
|
||||
: (new_y < 0) ? 0 : 7);
|
||||
else if (x == 1)
|
||||
moveCursorToSlot((new_x > 0) ? 0
|
||||
: (new_y > 0) ? 3 : 1);
|
||||
else if (x == 3)
|
||||
moveCursorToSlot((new_x > 0) ? 4
|
||||
: (new_y < 0) ? 1
|
||||
: (new_y > 0) ? 5 : 3);
|
||||
else if (x == 5)
|
||||
moveCursorToSlot((new_x > 0) ? 7
|
||||
: (new_y < 0) ? 3 : 5);
|
||||
else if (x == 2)
|
||||
moveCursorToSlot((new_x < 0) ? 0
|
||||
: (new_y > 0) ? 4 : 2);
|
||||
else if (x == 4)
|
||||
moveCursorToSlot((new_x < 0) ? 3
|
||||
: (new_y < 0) ? 2
|
||||
: (new_y > 0) ? 6 : 4);
|
||||
else if (x == 6)
|
||||
moveCursorToSlot((new_x < 0) ? 7
|
||||
: (new_y < 0) ? 4 : 6);
|
||||
} else if (cursor_pos.area == INVAREA_COMMAND) {
|
||||
if (new_y < 0) {
|
||||
if (x == 0)
|
||||
moveCursorToSlot(5);
|
||||
else if (x == 1)
|
||||
moveCursorToSlot(7);
|
||||
else if (x == 2)
|
||||
moveCursorToSlot(6);
|
||||
else if (x == 3)
|
||||
moveCursorToInventory(0, inventory_widget->get_num_rows() - 1);
|
||||
else if (x == 4)
|
||||
moveCursorToInventory(1, inventory_widget->get_num_rows() - 1);
|
||||
} else if (((sint16)x + new_x) >= 0 && (x + new_x) <= 4)
|
||||
moveCursorToButton(x + new_x);
|
||||
update_display = true;
|
||||
} else if (cursor_pos.area == INVAREA_TOP)
|
||||
if (new_y > 0) {
|
||||
moveCursorToInventory(cursor_pos.x, 0);
|
||||
update_display = true;
|
||||
}
|
||||
update_cursor();
|
||||
}
|
||||
|
||||
|
||||
/* Update on-screen location (px,py) of cursor.
|
||||
*/
|
||||
void InventoryView::update_cursor() {
|
||||
const Common::Rect *ready_loc;
|
||||
nuvie_game_t gametype = Game::get_game()->get_game_type();
|
||||
switch (cursor_pos.area) {
|
||||
case INVAREA_LIST:
|
||||
if (gametype == NUVIE_GAME_U6) {
|
||||
cursor_pos.px = area.left + (4 * 16 + 8) + cursor_pos.x * 16;
|
||||
} else {
|
||||
cursor_pos.px = inventory_widget->area.left + cursor_pos.x * 16;
|
||||
}
|
||||
cursor_pos.py = area.top + 16 + 8 + cursor_pos.y * 16;
|
||||
break;
|
||||
case INVAREA_TOP:
|
||||
cursor_pos.px = inventory_widget->area.left + (gametype == NUVIE_GAME_U6 ? 32 : (inventory_widget->area.width() - 16) / 2);
|
||||
cursor_pos.py = inventory_widget->area.top;
|
||||
break;
|
||||
case INVAREA_DOLL:
|
||||
ready_loc = doll_widget->get_item_hit_rect(cursor_pos.x);
|
||||
cursor_pos.px = ready_loc->left + doll_widget->area.left;
|
||||
cursor_pos.py = ready_loc->top + doll_widget->area.top;
|
||||
break;
|
||||
case INVAREA_COMMAND:
|
||||
cursor_pos.px = ((cursor_pos.x + 1) * 16) - 16;
|
||||
cursor_pos.py = left_button->area.top; //80;
|
||||
cursor_pos.px += area.left;
|
||||
//cursor_pos.py += area.top;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryView::set_show_cursor(bool state) {
|
||||
|
||||
show_cursor = state;
|
||||
update_display = true;
|
||||
ViewManager *vm = Game::get_game()->get_view_manager();
|
||||
if (state == true && vm->get_current_view() != this) // second comparison prevents endless loop
|
||||
vm->set_inventory_mode();
|
||||
|
||||
}
|
||||
|
||||
void InventoryView::hide_buttons() {
|
||||
if (left_button) left_button->Hide();
|
||||
if (right_button) right_button->Hide();
|
||||
// if(actor_button) actor_button->Hide();
|
||||
if (party_button) party_button->Hide();
|
||||
if (combat_button) combat_button->Hide();
|
||||
}
|
||||
|
||||
void InventoryView::show_buttons() {
|
||||
// if(left_button) left_button->Show(); // these two shouldn't be needed
|
||||
// if(right_button) right_button->Show(); // and cause problems
|
||||
if (actor_button) actor_button->Show();
|
||||
if (party_button) party_button->Show();
|
||||
if (combat_button) combat_button->Show();
|
||||
}
|
||||
|
||||
/* Returns pointer to object at cursor position, or nullptr.
|
||||
*/
|
||||
Obj *InventoryView::get_objAtCursor() {
|
||||
// emulate mouse; use center of cursor
|
||||
uint32 hit_x = cursor_pos.px + 8 - inventory_widget->area.left,
|
||||
hit_y = cursor_pos.py + 8 - inventory_widget->area.top;
|
||||
if (cursor_pos.area == INVAREA_LIST)
|
||||
return (inventory_widget->get_obj_at_location(hit_x, hit_y));
|
||||
else if (cursor_pos.area == INVAREA_DOLL)
|
||||
return (inventory_widget->get_actor()->inventory_get_readied_object(cursor_pos.x));
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
/* Do an action with the object under the cursor, or call the function for a
|
||||
selected button. This is called when pressing ENTER. */
|
||||
void InventoryView::select_objAtCursor() {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
ViewManager *view_manager = Game::get_game()->get_view_manager();
|
||||
Obj *obj = get_objAtCursor();
|
||||
|
||||
if (cursor_pos.area == INVAREA_TOP && event->can_target_icon()) {
|
||||
if (inventory_widget->is_showing_container() && event->get_last_mode() != PUSH_MODE)
|
||||
select_obj((Obj *)inventory_widget->get_container());
|
||||
else if (inventory_widget->is_showing_container()
|
||||
&& inventory_widget->get_container()->get_engine_loc() == OBJ_LOC_CONT)
|
||||
select_obj((Obj *)inventory_widget->get_container()->parent);
|
||||
else
|
||||
event->select_actor(inventory_widget->get_actor());
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_party_member) {
|
||||
// special areas
|
||||
if (cursor_pos.area == INVAREA_COMMAND) {
|
||||
if (cursor_pos.x == 0) // left
|
||||
View::callback(BUTTON_CB, left_button, view_manager);
|
||||
if (cursor_pos.x == 1) // party
|
||||
View::callback(BUTTON_CB, party_button, view_manager);
|
||||
if (cursor_pos.x == 2) // status
|
||||
View::callback(BUTTON_CB, actor_button, view_manager);
|
||||
if (cursor_pos.x == 3) // right
|
||||
View::callback(BUTTON_CB, right_button, view_manager);
|
||||
if (cursor_pos.x == 4) // strategy
|
||||
callback(BUTTON_CB, combat_button, view_manager);
|
||||
return;
|
||||
} else if (cursor_pos.area == INVAREA_TOP) {
|
||||
if (inventory_widget->is_showing_container())
|
||||
inventory_widget->set_prev_container();
|
||||
else
|
||||
Game::get_game()->get_view_manager()->set_party_mode();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor_pos.area == INVAREA_DOLL || cursor_pos.area == INVAREA_LIST)
|
||||
select_obj(obj); // do action with an object
|
||||
}
|
||||
|
||||
|
||||
/* Ready an object or pass it to Events. Pass nullptr if an empty space is selected.
|
||||
* Returns true if the object was "used". The caller is free to handle the
|
||||
* object if false is returned.
|
||||
*/
|
||||
bool InventoryView::select_obj(Obj *obj) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
switch (event->get_mode()) {
|
||||
case MOVE_MODE:
|
||||
case EQUIP_MODE: {
|
||||
if (!obj)
|
||||
break;
|
||||
bool locked_chest = (Game::get_game()->get_usecode()->is_chest(obj) && obj->frame_n > 1);
|
||||
if (Game::get_game()->get_usecode()->is_container(obj) && !locked_chest)
|
||||
inventory_widget->set_container(obj);
|
||||
else {
|
||||
if (obj->is_readied())
|
||||
return event->unready(obj);
|
||||
else
|
||||
return event->ready(obj, inventory_widget->get_actor());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ATTACK_MODE:
|
||||
set_show_cursor(false);
|
||||
event->cancelAction();
|
||||
return false;
|
||||
default:
|
||||
event->select_view_obj(obj, inventory_widget->get_actor());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
GUI_status InventoryView::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status InventoryView::MouseWheel(sint32 x, sint32 y) {
|
||||
|
||||
if (!is_party_member)
|
||||
return GUI_PASS;
|
||||
|
||||
int xpos, ypos;
|
||||
screen->get_mouse_location(&xpos, &ypos);
|
||||
|
||||
xpos -= area.left;
|
||||
ypos -= area.top;
|
||||
bool wheel_range = (xpos >= 0 && ypos < area.top + area.height() - 6);
|
||||
|
||||
if (y > 0 && wheel_range) {
|
||||
View::callback(BUTTON_CB, left_button, Game::get_game()->get_view_manager());
|
||||
return GUI_YUM;
|
||||
} else if (y < 0 && wheel_range) {
|
||||
View::callback(BUTTON_CB, right_button, Game::get_game()->get_view_manager());
|
||||
return GUI_YUM;
|
||||
}
|
||||
return GUI_PASS; // goes to MsgScroll
|
||||
}
|
||||
|
||||
/* Messages from child widgets, Inventory & Doll.
|
||||
**INVSELECT is called when an object is selected with MouseDown.*
|
||||
**BUTTON is called when one of the command buttons is selected.*
|
||||
* Returns GUI_PASS if the data was not used.
|
||||
*/
|
||||
GUI_status InventoryView::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
if (msg != INVSELECT_CB) { // hit one of the command buttons
|
||||
if (caller == combat_button) {
|
||||
if (cur_party_member != 0) { // You can't change combat modes for the avatar.
|
||||
Actor *actor = party->get_actor(cur_party_member);
|
||||
set_combat_mode(actor);
|
||||
update_display = true;
|
||||
}
|
||||
|
||||
return GUI_YUM;
|
||||
} else
|
||||
return View::callback(msg, caller, data);
|
||||
}
|
||||
|
||||
// selecting an object from InventoryWidget only works while getting input
|
||||
Events *event = Game::get_game()->get_event();
|
||||
if (event->get_mode() == INPUT_MODE) {
|
||||
if (select_obj((Obj *)data))
|
||||
return GUI_YUM;
|
||||
}
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
void InventoryView::simulate_CB_callback() {
|
||||
callback(BUTTON_CB, combat_button, Game::get_game()->get_view_manager());
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
112
engines/ultima/nuvie/views/inventory_view.h
Normal file
112
engines/ultima/nuvie/views/inventory_view.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/* 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 NUVIE_VIEWS_INVENTORY_VIEW_H
|
||||
#define NUVIE_VIEWS_INVENTORY_VIEW_H
|
||||
|
||||
#include "ultima/nuvie/views/view.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class ObjManager;
|
||||
class Screen;
|
||||
class Actor;
|
||||
class Font;
|
||||
class Party;
|
||||
class DollWidget;
|
||||
class InventoryWidget;
|
||||
|
||||
class InventoryView : public View {
|
||||
|
||||
DollWidget *doll_widget;
|
||||
InventoryWidget *inventory_widget;
|
||||
GUI_Button *combat_button;
|
||||
bool is_party_member;
|
||||
bool picking_pocket;
|
||||
Actor *outside_actor;
|
||||
bool lock_actor;
|
||||
|
||||
enum invarea {
|
||||
INVAREA_LIST = 0, // cursor is over the inventory list (x,y)
|
||||
INVAREA_TOP, // the actor or container icon
|
||||
INVAREA_DOLL, // the readied-items list (0-7)
|
||||
INVAREA_COMMAND // the command icons (0-4)
|
||||
};
|
||||
struct invcursor_pos_s {
|
||||
enum invarea area;
|
||||
uint8 x, y; // y is only used for inventory list
|
||||
uint32 px, py;
|
||||
} cursor_pos;
|
||||
Tile *cursor_tile;
|
||||
bool show_cursor;
|
||||
|
||||
public:
|
||||
InventoryView(const Configuration *cfg);
|
||||
~InventoryView() override;
|
||||
|
||||
bool init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om);
|
||||
bool set_party_member(uint8 party_member) override;
|
||||
bool set_actor(Actor *actor, bool pickpocket = false);
|
||||
void set_show_cursor(bool state);
|
||||
void moveCursorToSlot(uint8 slot_num);
|
||||
void moveCursorToInventory(uint8 inv_x = 0, uint8 inv_y = 0);
|
||||
void moveCursorRelative(sint8 new_x, sint8 new_y);
|
||||
void moveCursorToButton(uint8 button_num = 0);
|
||||
void moveCursorToTop();
|
||||
bool select_obj(Obj *obj);
|
||||
void select_objAtCursor();
|
||||
Obj *get_objAtCursor();
|
||||
InventoryWidget *get_inventory_widget() {
|
||||
return inventory_widget;
|
||||
};
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
void PlaceOnScreen(Screen *s, GUI_DragManager *dm, int x, int y) override;
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
void simulate_CB_callback();
|
||||
bool is_picking_pocket() const {
|
||||
return picking_pocket;
|
||||
}
|
||||
void lock_to_actor(bool value) {
|
||||
lock_actor = value;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void display_name();
|
||||
void add_command_icons(Screen *tmp_screen, void *view_manager);
|
||||
void display_inventory_weights();
|
||||
void display_combat_mode();
|
||||
void update_cursor();
|
||||
void hide_buttons();
|
||||
void show_buttons();
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
668
engines/ultima/nuvie/views/inventory_widget.cpp
Normal file
668
engines/ultima/nuvie/views/inventory_widget.cpp
Normal file
@@ -0,0 +1,668 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_llist.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/screen/game_palette.h"
|
||||
#include "ultima/nuvie/views/inventory_widget.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/core/game_clock.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/core/timed_event.h"
|
||||
#include "ultima/nuvie/usecode/usecode.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/gui/widgets/command_bar.h"
|
||||
#include "ultima/nuvie/views/inventory_font.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
InventoryWidget::InventoryWidget(const Configuration *cfg, GUI_CallBack *callback)
|
||||
: GUI_Widget(nullptr, 0, 0, 0, 0), config(cfg), callback_object(callback),
|
||||
container_obj(nullptr), tile_manager(nullptr), obj_manager(nullptr),
|
||||
selected_obj(nullptr), font(nullptr), actor(nullptr), target_obj(nullptr),
|
||||
target_cont(nullptr), empty_tile(nullptr), row_offset(0), icon_x(0),
|
||||
bg_color(0), objlist_offset_x(0), objlist_offset_y(0), obj_font_color(0) {
|
||||
|
||||
ready_obj = nullptr; // FIXME: this is unused but I might need it again -- SB-X
|
||||
|
||||
config->value("config/GameType", game_type);
|
||||
|
||||
arrow_rects[0] = Common::Rect(0, 16, 0 + 8, 16 + 8);
|
||||
arrow_rects[1] = Common::Rect(0, 3 * 16 + 8, 0 + 8, 3 * 16 + 8 + 8);
|
||||
}
|
||||
|
||||
InventoryWidget::~InventoryWidget() {
|
||||
|
||||
}
|
||||
|
||||
bool InventoryWidget::init(Actor *a, uint16 x, uint16 y, TileManager *tm, ObjManager *om, Font *f) {
|
||||
tile_manager = tm;
|
||||
obj_manager = om;
|
||||
font = f;
|
||||
|
||||
bg_color = Game::get_game()->get_palette()->get_bg_color();
|
||||
obj_font_color = 0;
|
||||
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6) {
|
||||
icon_x = 32;
|
||||
obj_font_color = 0x48;
|
||||
objlist_offset_x = 8;
|
||||
} else {
|
||||
icon_x = 23;
|
||||
objlist_offset_x = 0;
|
||||
}
|
||||
objlist_offset_y = 16;
|
||||
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6) {
|
||||
empty_tile = tile_manager->get_tile(410);
|
||||
GUI_Widget::Init(nullptr, x, y, 72, 64); //72 = 4 * 16 + 8
|
||||
} else if (Game::get_game()->get_game_type() == NUVIE_GAME_MD) { // FIXME: different depending on npc
|
||||
empty_tile = tile_manager->get_tile(273);
|
||||
GUI_Widget::Init(nullptr, x, y, 64, 82);
|
||||
} else { // SE
|
||||
empty_tile = tile_manager->get_tile(392);
|
||||
GUI_Widget::Init(nullptr, x + 2, y, 64, 82);
|
||||
}
|
||||
|
||||
set_actor(a);
|
||||
set_accept_mouseclick(true, USE_BUTTON); // accept [double]clicks from button1 (even if double-click disabled we need clicks)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InventoryWidget::set_actor(Actor *a) {
|
||||
actor = a;
|
||||
container_obj = nullptr;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
Obj *InventoryWidget::get_prev_container() {
|
||||
if (container_obj && container_obj->get_engine_loc() == OBJ_LOC_CONT)
|
||||
return (Obj *)container_obj->parent;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void InventoryWidget::set_prev_container() {
|
||||
if (!container_obj)
|
||||
return;
|
||||
|
||||
if (container_obj->get_engine_loc() == OBJ_LOC_CONT)
|
||||
set_container((Obj *)container_obj->parent);
|
||||
else
|
||||
set_container(nullptr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void InventoryWidget::Display(bool full_redraw) {
|
||||
if (full_redraw || update_display) {
|
||||
// screen->fill(bg_color, area.left, area.top, area.width(), area.height());
|
||||
display_inventory_container();
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6)
|
||||
display_arrows();
|
||||
}
|
||||
//screen->blit(area.left+40,area.top+16,portrait_data,8,56,64,56,false);
|
||||
|
||||
//clear the screen first inventory icons, 4 x 3 tiles
|
||||
// screen->fill(bg_color, area.left +objlist_offset_x, area.top + objlist_offset_y, 16 * 4, 16 * 3); // doesn't seem to be needed
|
||||
display_inventory_list();
|
||||
|
||||
if (full_redraw || update_display) {
|
||||
update_display = false;
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
} else {
|
||||
screen->update(area.left + objlist_offset_x, area.top + 16, area.width() - objlist_offset_x, area.height() - 16); // update only the inventory list
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//either an Actor or an object container.
|
||||
void InventoryWidget::display_inventory_container() {
|
||||
Tile *tile;
|
||||
if (!container_obj) //display actor
|
||||
tile = tile_manager->get_tile(actor->get_downward_facing_tile_num());
|
||||
else // display container object
|
||||
tile = tile_manager->get_tile(obj_manager->get_obj_tile_num(container_obj) + container_obj->frame_n);
|
||||
|
||||
screen->blit(area.left + icon_x, area.top, tile->data, 8, 16, 16, 16, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void InventoryWidget::display_inventory_list() {
|
||||
const Tile *tile;
|
||||
U6LList *inventory;
|
||||
U6Link *link;
|
||||
Obj *obj = nullptr;
|
||||
uint16 i, j;
|
||||
uint16 skip_num;
|
||||
int max_rows = 4;
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6)
|
||||
max_rows = 3;
|
||||
|
||||
if (container_obj)
|
||||
inventory = container_obj->container;
|
||||
else
|
||||
inventory = actor->get_inventory_list();
|
||||
if (inventory == nullptr)
|
||||
link = nullptr;
|
||||
else
|
||||
link = inventory->start();
|
||||
|
||||
//skip row_offset rows of objects.
|
||||
skip_num = row_offset * 4;
|
||||
for (i = 0; link != nullptr && i < skip_num; link = link->next) {
|
||||
obj = (Obj *)link->data;
|
||||
if (obj->is_readied() == false)
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for (i = 0; i < max_rows; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (link != nullptr) {
|
||||
obj = (Obj *)link->data;
|
||||
if (obj->is_readied()) { //skip any readied objects
|
||||
for (; link != nullptr && obj->is_readied(); link = link->next)
|
||||
obj = (Obj *)link->data;
|
||||
} else
|
||||
link = link->next;
|
||||
|
||||
tile = tile_manager->get_tile(obj_manager->get_obj_tile_num(obj) + obj->frame_n);
|
||||
if (link == nullptr) {
|
||||
if (obj->is_readied()) //last object is readied so skip it.
|
||||
tile = empty_tile;
|
||||
}
|
||||
} else
|
||||
tile = empty_tile;
|
||||
|
||||
//tile = tile_manager->get_tile(actor->indentory_tile());
|
||||
if (tile == empty_tile)
|
||||
screen->blit((area.left + objlist_offset_x) + j * 16, area.top + objlist_offset_y + i * 16, (const unsigned char *)empty_tile->data, 8, 16, 16, 16, true);
|
||||
if (tile != empty_tile) {
|
||||
//draw qty string for stackable items
|
||||
if (obj_manager->is_stackable(obj))
|
||||
display_qty_string((area.left + objlist_offset_x) + j * 16, area.top + objlist_offset_y + i * 16, obj->qty);
|
||||
|
||||
//draw special char for Keys.
|
||||
if (game_type == NUVIE_GAME_U6 && obj->obj_n == 64)
|
||||
display_special_char((area.left + objlist_offset_x) + j * 16, area.top + objlist_offset_y + i * 16, obj->quality);
|
||||
}
|
||||
|
||||
screen->blit((area.left + objlist_offset_x) + j * 16, area.top + objlist_offset_y + i * 16, (const unsigned char *)tile->data, 8, 16, 16, 16, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryWidget::display_qty_string(uint16 x, uint16 y, uint16 qty) {
|
||||
uint8 len, i, offset;
|
||||
char buf[6];
|
||||
|
||||
Common::sprintf_s(buf, "%d", qty);
|
||||
len = strlen(buf);
|
||||
|
||||
offset = (16 - len * 4) / 2;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
screen->blitbitmap(x + offset + 4 * i, y + 11, inventory_font[buf[i] - 48], 3, 5, obj_font_color, bg_color);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void InventoryWidget::display_special_char(uint16 x, uint16 y, uint8 quality) {
|
||||
if (quality + 9 >= NUVIE_MICRO_FONT_COUNT)
|
||||
return;
|
||||
|
||||
screen->blitbitmap(x + 6, y + 11, inventory_font[quality + 9], 3, 5, obj_font_color, bg_color);
|
||||
}
|
||||
|
||||
void InventoryWidget::display_arrows() {
|
||||
uint32 num_objects;
|
||||
|
||||
if (is_showing_container()) {
|
||||
if (container_obj->container)
|
||||
num_objects = container_obj->container->count();
|
||||
else
|
||||
num_objects = 0;
|
||||
} else
|
||||
num_objects = actor->inventory_count_objects(false);
|
||||
|
||||
if (num_objects <= 12) //reset row_offset if we only have one page of objects
|
||||
row_offset = 0;
|
||||
|
||||
if (row_offset > 0) //display top arrow
|
||||
font->drawChar(screen, 24, area.left, area.top + 16);
|
||||
|
||||
if (num_objects - row_offset * 4 > 12) //display bottom arrow
|
||||
font->drawChar(screen, 25, area.left, area.top + 3 * 16 + 8);
|
||||
}
|
||||
|
||||
GUI_status InventoryWidget::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
CommandBar *command_bar = Game::get_game()->get_command_bar();
|
||||
x -= area.left;
|
||||
y -= area.top;
|
||||
|
||||
if (y < 17)
|
||||
return GUI_PASS;
|
||||
|
||||
Obj *obj = get_obj_at_location(x, y);
|
||||
|
||||
if (button == ACTION_BUTTON && event->get_mode() == MOVE_MODE
|
||||
&& command_bar->get_selected_action() > 0) { // Exclude attack mode too
|
||||
if (command_bar->try_selected_action() == false) // start new action
|
||||
return GUI_PASS; // false if new event doesn't need target
|
||||
}
|
||||
if (button == ACTION_BUTTON && command_bar->get_selected_action() > 0
|
||||
&& event->get_mode() == INPUT_MODE) {
|
||||
if (obj)
|
||||
event->select_obj(obj); // the returned location
|
||||
else {
|
||||
Game::get_game()->get_scroll()->display_string("nothing!\n");
|
||||
event->endAction(true);
|
||||
event->set_mode(MOVE_MODE);
|
||||
}
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
// ABOEING
|
||||
if (actor && (button == USE_BUTTON || button == ACTION_BUTTON || button == DRAG_BUTTON)) {
|
||||
if (obj) { // FIXME: duplicating code in DollWidget
|
||||
// send to View
|
||||
if (callback_object->callback(INVSELECT_CB, this, obj) == GUI_PASS
|
||||
&& button == DRAG_BUTTON)
|
||||
selected_obj = obj; // start dragging
|
||||
return GUI_YUM;
|
||||
}
|
||||
}
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
inline uint16 InventoryWidget::get_list_position(int x, int y) {
|
||||
uint16 list_pos;
|
||||
|
||||
list_pos = ((y - objlist_offset_y) / 16) * 4 + (x - objlist_offset_x) / 16;
|
||||
list_pos += row_offset * 4;
|
||||
|
||||
return list_pos;
|
||||
}
|
||||
|
||||
Obj *InventoryWidget::get_obj_at_location(int x, int y) {
|
||||
uint8 location;
|
||||
U6LList *inventory;
|
||||
U6Link *link;
|
||||
Obj *obj = nullptr;
|
||||
uint16 i;
|
||||
|
||||
if (x >= objlist_offset_x && y >= objlist_offset_y) {
|
||||
location = get_list_position(x, y); //find the position of the object we hit in the inventory
|
||||
|
||||
if (container_obj)
|
||||
inventory = container_obj->container;
|
||||
else
|
||||
inventory = actor->get_inventory_list();
|
||||
if (inventory == nullptr)
|
||||
link = nullptr;
|
||||
else
|
||||
link = inventory->start();
|
||||
|
||||
for (i = 0; link != nullptr && i <= location; link = link->next) {
|
||||
obj = (Obj *)link->data;
|
||||
if (obj->is_readied() == false)
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i > location && obj && obj->is_readied() == false) // don't return readied or non existent objects
|
||||
return obj;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GUI_status InventoryWidget::MouseWheel(sint32 x, sint32 y) {
|
||||
int xpos, ypos;
|
||||
screen->get_mouse_location(&xpos, &ypos);
|
||||
|
||||
xpos -= area.left;
|
||||
ypos -= area.top;
|
||||
if (xpos < 0 || ypos > area.top + area.height() - 10)
|
||||
return GUI_PASS; // goes to InventoryView
|
||||
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6) {
|
||||
if (y > 0) {
|
||||
up_arrow();
|
||||
}
|
||||
if (y < 0) {
|
||||
down_arrow();
|
||||
}
|
||||
|
||||
selected_obj = nullptr;
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
// change container, ready/unready object, activate arrows
|
||||
GUI_status InventoryWidget::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
|
||||
CommandBar *command_bar = Game::get_game()->get_command_bar();
|
||||
|
||||
if (button == USE_BUTTON || (button == ACTION_BUTTON
|
||||
&& command_bar->get_selected_action() > 0)) { // Exclude attack mode too
|
||||
x -= area.left;
|
||||
y -= area.top;
|
||||
if (x >= icon_x && x <= icon_x + 15 && // hit top icon either actor or container
|
||||
y >= 0 && y <= 15) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
|
||||
if (button == ACTION_BUTTON && event->get_mode() == MOVE_MODE) {
|
||||
if (command_bar->try_selected_action() == false) // start new action
|
||||
return GUI_PASS; // false if new event doesn't need target
|
||||
}
|
||||
|
||||
if (event->can_target_icon()) {
|
||||
if (is_showing_container() && event->get_last_mode() != PUSH_MODE)
|
||||
event->select_obj((Obj *)container_obj, actor);
|
||||
else if (is_showing_container() && get_container()->get_engine_loc() == OBJ_LOC_CONT)
|
||||
event->select_obj((Obj *)get_container()->parent, actor);
|
||||
else
|
||||
event->select_actor(actor);
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
if (is_showing_container())
|
||||
set_prev_container(); //return to previous container or main actor inventory
|
||||
else if (!event->using_control_cheat())
|
||||
Game::get_game()->get_view_manager()->set_party_mode();
|
||||
|
||||
Redraw();
|
||||
}
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6) {
|
||||
if (HitRect(x, y, arrow_rects[0])) //up arrow hit rect
|
||||
up_arrow();
|
||||
else if (HitRect(x, y, arrow_rects[1])) //down arrow hit rect
|
||||
down_arrow();
|
||||
}
|
||||
|
||||
// only act now if objects can't be used with DoubleClick
|
||||
if (selected_obj && !Game::get_game()->get_map_window()->is_doubleclick_enabled())
|
||||
try_click();
|
||||
else if (selected_obj) {
|
||||
wait_for_mouseclick(USE_BUTTON);
|
||||
ready_obj = selected_obj;
|
||||
}
|
||||
}
|
||||
|
||||
selected_obj = nullptr;
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
bool InventoryWidget::up_arrow() {
|
||||
if (row_offset > 0) {
|
||||
row_offset--;
|
||||
Redraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InventoryWidget::down_arrow() {
|
||||
uint32 num_objects;
|
||||
if (container_obj)
|
||||
num_objects = container_obj->container_count_objects();
|
||||
else
|
||||
num_objects = actor->inventory_count_objects(false);
|
||||
|
||||
if (num_objects - row_offset * 4 > 12) {
|
||||
row_offset++;
|
||||
Redraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
GUI_status InventoryWidget::MouseMotion(int x, int y, uint8 state) {
|
||||
Tile *tile;
|
||||
|
||||
if (selected_obj && !dragging && Game::get_game()->is_dragging_enabled()) {
|
||||
dragging = true;
|
||||
tile = tile_manager->get_tile(obj_manager->get_obj_tile_num(selected_obj) + selected_obj->frame_n);
|
||||
return gui_drag_manager->start_drag(this, GUI_DRAG_OBJ, selected_obj, tile->data, 16, 16, 8);
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
void InventoryWidget::drag_drop_success(int x, int y, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "InventoryWidget::drag_drop_success()\n");
|
||||
dragging = false;
|
||||
|
||||
// handled by drop target
|
||||
// if(container_obj)
|
||||
// container_obj->container->remove(selected_obj);
|
||||
// else
|
||||
// actor->inventory_remove_obj(selected_obj);
|
||||
|
||||
selected_obj = nullptr;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void InventoryWidget::drag_drop_failed(int x, int y, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "InventoryWidget::drag_drop_failed()\n");
|
||||
dragging = false;
|
||||
selected_obj = nullptr;
|
||||
}
|
||||
|
||||
bool InventoryWidget::drag_set_target_obj(int x, int y) {
|
||||
if (x >= 32 && x < 48 && y < 16) {
|
||||
target_obj = nullptr;
|
||||
target_cont = get_prev_container(); //returns parent container or nullptr if we're back at the inventory.
|
||||
} else if (x >= objlist_offset_x && y >= objlist_offset_y) {
|
||||
target_obj = get_obj_at_location(x, y);
|
||||
target_cont = get_container();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InventoryWidget::drag_accept_drop(int x, int y, int message, void *data) {
|
||||
GUI::get_gui()->force_full_redraw();
|
||||
DEBUG(0, LEVEL_DEBUGGING, "InventoryWidget::drag_accept_drop()\n");
|
||||
if (message == GUI_DRAG_OBJ) {
|
||||
Obj *obj = (Obj *)data;
|
||||
x -= area.left;
|
||||
y -= area.top;
|
||||
if (target_obj == nullptr) { //we need to check this so we don't screw up target_obj on subsequent calls
|
||||
if (drag_set_target_obj(x, y) == false) {
|
||||
DEBUG(0, LEVEL_WARNING, "InventoryWidget: Didn't hit any widget object targets!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Actor *src_actor = Game::get_game()->get_player()->get_actor();
|
||||
|
||||
if (obj->get_actor_holding_obj() == actor)
|
||||
src_actor = actor;
|
||||
else if (!obj->is_in_inventory() && actor == Game::get_game()->get_player()->get_actor()) {
|
||||
Game::get_game()->get_scroll()->display_string("Get-");
|
||||
Game::get_game()->get_scroll()->display_string(obj_manager->look_obj(obj, OBJ_SHOW_PREFIX));
|
||||
} else
|
||||
Game::get_game()->get_event()->display_move_text(actor, obj);
|
||||
|
||||
if (!obj->is_in_inventory()
|
||||
&& !Game::get_game()->get_map_window()->can_get_obj(actor, obj)) {
|
||||
Game::get_game()->get_scroll()->message("\n\nblocked\n\n");
|
||||
return false;
|
||||
}
|
||||
if ((Game::get_game()->get_usecode()->has_getcode(obj)
|
||||
&& !Game::get_game()->get_usecode()->get_obj(obj, actor))
|
||||
|| !Game::get_game()->get_event()->can_move_obj_between_actors(obj, src_actor, actor)) {
|
||||
Game::get_game()->get_scroll()->message("\n\n");
|
||||
return false;
|
||||
} else if (!obj->is_in_inventory()
|
||||
&& obj_manager->obj_is_damaging(obj, Game::get_game()->get_player()->get_actor())) {
|
||||
Game::get_game()->get_player()->subtract_movement_points(3);
|
||||
return false;
|
||||
} else if (src_actor != actor || !obj->is_in_inventory())
|
||||
Game::get_game()->get_scroll()->message("\n\n");
|
||||
|
||||
if (src_actor != actor) // get plus move
|
||||
Game::get_game()->get_player()->subtract_movement_points(8);
|
||||
else if (!obj->is_in_inventory()) // get
|
||||
Game::get_game()->get_player()->subtract_movement_points(3);
|
||||
|
||||
UseCode *usecode = Game::get_game()->get_usecode();
|
||||
if (usecode->is_chest(obj) && obj->frame_n == 0) //open chest
|
||||
obj->frame_n = 1; //close the chest
|
||||
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop Accepted\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop Refused\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
void InventoryWidget::drag_perform_drop(int /*x*/, int /*y*/, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "InventoryWidget::drag_perform_drop()\n");
|
||||
Obj *obj;
|
||||
|
||||
//x -= area.left;
|
||||
//y -= area.top;
|
||||
|
||||
if (message == GUI_DRAG_OBJ) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop into inventory.\n");
|
||||
obj = (Obj *)data;
|
||||
|
||||
if (target_obj && obj_manager->can_store_obj(target_obj, obj)) {
|
||||
obj_manager->moveto_container(obj, target_obj);
|
||||
} else if (target_cont && obj_manager->can_store_obj(target_cont, obj)) {
|
||||
obj_manager->moveto_container(obj, target_cont);
|
||||
} else {
|
||||
if (obj->is_readied())
|
||||
Game::get_game()->get_event()->unready(obj);
|
||||
else
|
||||
obj_manager->moveto_inventory(obj, actor);
|
||||
}
|
||||
|
||||
Redraw();
|
||||
}
|
||||
|
||||
Game::get_game()->get_map_window()->updateBlacking();
|
||||
target_obj = nullptr;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void InventoryWidget::drag_draw(int x, int y, int message, void *data) {
|
||||
Tile *tile;
|
||||
|
||||
if (!selected_obj)
|
||||
return;
|
||||
|
||||
tile = tile_manager->get_tile(obj_manager->get_obj_tile_num(selected_obj) + selected_obj->frame_n);
|
||||
|
||||
int nx = x - 8;
|
||||
int ny = y - 8;
|
||||
|
||||
if (nx + 16 >= screen->get_width())
|
||||
nx = screen->get_width() - 17;
|
||||
else if (nx < 0)
|
||||
nx = 0;
|
||||
|
||||
if (ny + 16 >= screen->get_height())
|
||||
ny = screen->get_height() - 17;
|
||||
else if (ny < 0)
|
||||
ny = 0;
|
||||
|
||||
screen->blit(nx, ny, tile->data, 8, 16, 16, 16, true);
|
||||
screen->update(nx, ny, 16, 16);
|
||||
}
|
||||
|
||||
void InventoryWidget::try_click() {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
UseCode *usecode = Game::get_game()->get_usecode();
|
||||
if (!selected_obj)
|
||||
selected_obj = ready_obj;
|
||||
if (!selected_obj)
|
||||
return;
|
||||
bool locked_chest = (usecode->is_chest(selected_obj) && selected_obj->frame_n > 1);
|
||||
if (event->get_mode() == ATTACK_MODE)
|
||||
event->cancelAction();
|
||||
else if (usecode->is_container(selected_obj) && !locked_chest) { // open up the container.
|
||||
container_obj = selected_obj;
|
||||
if (usecode->is_chest(container_obj) && selected_obj->frame_n == 1)
|
||||
usecode->process_effects(container_obj, actor);
|
||||
Redraw();
|
||||
} else { // attempt to ready selected object.
|
||||
event->ready(selected_obj, actor);
|
||||
Redraw();
|
||||
}
|
||||
ready_obj = nullptr;
|
||||
selected_obj = nullptr;
|
||||
}
|
||||
|
||||
/* Use object. */
|
||||
GUI_status InventoryWidget::MouseDouble(int x, int y, Events::MouseButton button) {
|
||||
// we have to check if double-clicks are allowed here, since we use single-clicks
|
||||
if (!Game::get_game()->get_map_window()->is_doubleclick_enabled())
|
||||
return GUI_PASS;
|
||||
Obj *obj = selected_obj;
|
||||
|
||||
ready_obj = nullptr;
|
||||
selected_obj = nullptr;
|
||||
|
||||
if (!actor)
|
||||
return GUI_YUM;
|
||||
if (!obj)
|
||||
return MouseUp(x, y, button); // probably hit an arrow
|
||||
|
||||
Game::get_game()->get_view_manager()->double_click_obj(obj);
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status InventoryWidget::MouseClick(int x, int y, Events::MouseButton button) {
|
||||
return MouseUp(x, y, button);
|
||||
}
|
||||
|
||||
// change container, ready/unready object, activate arrows
|
||||
GUI_status InventoryWidget::MouseDelayed(int x, int y, Events::MouseButton button) {
|
||||
if (ready_obj)
|
||||
try_click();
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
128
engines/ultima/nuvie/views/inventory_widget.h
Normal file
128
engines/ultima/nuvie/views/inventory_widget.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/* 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 NUVIE_VIEWS_INVENTORY_WIDGET_H
|
||||
#define NUVIE_VIEWS_INVENTORY_WIDGET_H
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/core/obj_manager.h"
|
||||
#include "ultima/nuvie/views/inventory_message.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class Actor;
|
||||
class Font;
|
||||
|
||||
class InventoryWidget : public GUI_Widget {
|
||||
private:
|
||||
Common::Rect arrow_rects[2];
|
||||
protected:
|
||||
const Configuration *config;
|
||||
|
||||
int game_type;
|
||||
|
||||
TileManager *tile_manager;
|
||||
ObjManager *obj_manager;
|
||||
Font *font;
|
||||
|
||||
Actor *actor;
|
||||
Obj *container_obj;
|
||||
|
||||
Obj *selected_obj, *target_obj, *ready_obj;
|
||||
Obj *target_cont;
|
||||
uint16 row_offset;
|
||||
uint8 icon_x;
|
||||
uint8 bg_color;
|
||||
uint8 objlist_offset_x, objlist_offset_y;
|
||||
uint8 obj_font_color;
|
||||
|
||||
const Tile *empty_tile;
|
||||
|
||||
public:
|
||||
InventoryWidget(const Configuration *cfg, GUI_CallBack *callback = nullptr);
|
||||
~InventoryWidget() override;
|
||||
|
||||
bool init(Actor *a, uint16 x, uint16 y, TileManager *tm, ObjManager *om, Font *f);
|
||||
void set_actor(Actor *a);
|
||||
Actor *get_actor() {
|
||||
return actor;
|
||||
}
|
||||
Obj *get_container() {
|
||||
return container_obj;
|
||||
}
|
||||
void set_container(Obj *obj) {
|
||||
container_obj = obj;
|
||||
row_offset = 0;
|
||||
Redraw();
|
||||
}
|
||||
Obj *get_prev_container();
|
||||
void set_prev_container();
|
||||
bool is_showing_container() {
|
||||
return (container_obj != nullptr ? true : false);
|
||||
}
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override;
|
||||
GUI_status MouseDouble(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseClick(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseDelayed(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
void drag_drop_success(int x, int y, int message, void *data) override;
|
||||
void drag_drop_failed(int x, int y, int message, void *data) override;
|
||||
|
||||
bool drag_accept_drop(int x, int y, int message, void *data) override;
|
||||
void drag_perform_drop(int x, int y, int message, void *data) override;
|
||||
|
||||
void drag_draw(int x, int y, int message, void *data) override;
|
||||
|
||||
uint8 get_num_rows() const {
|
||||
return game_type == NUVIE_GAME_U6 ? 3 : 4;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
GUI_CallBack *callback_object; // object-selected callback
|
||||
|
||||
inline uint16 get_list_position(int x, int y);
|
||||
void display_inventory_container();
|
||||
void display_inventory_list();
|
||||
inline void display_qty_string(uint16 x, uint16 y, uint16 qty);
|
||||
inline void display_special_char(uint16 x, uint16 y, uint8 quality);
|
||||
void display_arrows();
|
||||
|
||||
bool drag_set_target_obj(int x, int y);
|
||||
void try_click();
|
||||
|
||||
public:
|
||||
bool up_arrow();
|
||||
bool down_arrow();
|
||||
Obj *get_obj_at_location(int x, int y);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
311
engines/ultima/nuvie/views/map_editor_view.cpp
Normal file
311
engines/ultima/nuvie/views/map_editor_view.cpp
Normal file
@@ -0,0 +1,311 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/core/map.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/views/map_editor_view.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static const int TILES_W = 5;
|
||||
static const int TILES_H = 10;
|
||||
|
||||
MapEditorView::MapEditorView(const Configuration *cfg) : View(cfg), roof_tiles(nullptr),
|
||||
map_window(nullptr), up_button(nullptr), down_button(nullptr),
|
||||
selectedTile(0), tile_offset(0) {
|
||||
}
|
||||
|
||||
MapEditorView::~MapEditorView() {
|
||||
}
|
||||
|
||||
bool MapEditorView::init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om) {
|
||||
View::init(x, y, f, p, tm, om);
|
||||
|
||||
SetRect(area.left, area.top, 90, 200);
|
||||
bg_color = 119;
|
||||
|
||||
Common::Path datadir = GUI::get_gui()->get_data_dir();
|
||||
Common::Path path;
|
||||
|
||||
build_path(datadir, "images", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "gumps", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "mapeditor", path);
|
||||
datadir = path;
|
||||
|
||||
up_button = loadButton(datadir, "up", 0, 7);
|
||||
down_button = loadButton(datadir, "down", 0, 186);
|
||||
|
||||
map_window = Game::get_game()->get_map_window();
|
||||
roof_tiles = map_window->get_roof_tiles();
|
||||
|
||||
map_window->set_show_cursor(true);
|
||||
map_window->moveCursor(7, 6);
|
||||
map_window->set_roof_display_mode(ROOF_DISPLAY_FORCE_ON);
|
||||
map_window->set_enable_blacking(false);
|
||||
map_window->set_show_grid(false);
|
||||
|
||||
Game::get_game()->set_mouse_pointer(1); //crosshairs
|
||||
|
||||
tile_offset = 0;
|
||||
selectedTile = 3;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MapEditorView::Display(bool full_redraw) {
|
||||
Common::Rect src(0, 0, 16, 16), dst(0, 0, 16, 16);
|
||||
screen->fill(bg_color, area.left, area.top, area.width(), area.height());
|
||||
|
||||
DisplayChildren(full_redraw);
|
||||
|
||||
uint16 tile_num = tile_offset;
|
||||
|
||||
for (int i = 0; i < TILES_H; i++) {
|
||||
for (int j = 0; j < TILES_W; j++) {
|
||||
dst.left = area.left + 3 + (j * 17);
|
||||
dst.top = area.top + 16 + (i * 17);
|
||||
|
||||
src.left = (tile_num % MAPWINDOW_ROOFTILES_IMG_W) * 16;
|
||||
src.top = (tile_num / MAPWINDOW_ROOFTILES_IMG_W) * 16;
|
||||
|
||||
if (tile_num == selectedTile)
|
||||
screen->fill(15, dst.left - 1, dst.top - 1, 18, 18);
|
||||
|
||||
SDL_BlitSurface(roof_tiles, &src, surface, &dst);
|
||||
tile_num++;
|
||||
}
|
||||
}
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
GUI_status MapEditorView::KeyDown(const Common::KeyState &key) {
|
||||
MapCoord loc;
|
||||
uint16 *roof_data;
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
ActionKeyType action_type = keybinder->GetActionKeyType(a);
|
||||
|
||||
// alt input
|
||||
if (key.flags & Common::KBD_ALT) {
|
||||
Common::KeyState key_without_alt = key; // need to see what action is without alt
|
||||
byte mod_without_flags = key_without_alt.flags; // this and next 2 lines are due SDL_Keymod not wanting to do the bitwise ~ operation
|
||||
mod_without_flags &= ~Common::KBD_ALT;
|
||||
key_without_alt.flags = mod_without_flags;
|
||||
ActionType action_without_alt = keybinder->get_ActionType(key_without_alt);
|
||||
|
||||
if (keybinder->GetActionKeyType(action_without_alt) <= SOUTH_WEST_KEY)
|
||||
action_type = keybinder->GetActionKeyType(action_without_alt);
|
||||
|
||||
switch (action_type) {
|
||||
case NORTH_KEY:
|
||||
if (selectedTile >= TILES_W)
|
||||
update_selected_tile_relative(-TILES_W);
|
||||
return GUI_YUM;
|
||||
case SOUTH_KEY:
|
||||
update_selected_tile_relative(TILES_W);
|
||||
return GUI_YUM;
|
||||
case WEST_KEY:
|
||||
update_selected_tile_relative(-1);
|
||||
return GUI_YUM;
|
||||
case EAST_KEY:
|
||||
update_selected_tile_relative(1);
|
||||
return GUI_YUM;
|
||||
case SOUTH_WEST_KEY:
|
||||
update_selected_tile_relative(TILES_W);
|
||||
if (selectedTile % TILES_W) // don't wrap
|
||||
update_selected_tile_relative(-1);
|
||||
return GUI_YUM;
|
||||
case SOUTH_EAST_KEY:
|
||||
update_selected_tile_relative(TILES_W);
|
||||
if ((selectedTile + 1) % TILES_W) // don't wrap
|
||||
update_selected_tile_relative(1);
|
||||
return GUI_YUM;
|
||||
case NORTH_WEST_KEY:
|
||||
if (selectedTile >= TILES_W)
|
||||
update_selected_tile_relative(-TILES_W);
|
||||
if (selectedTile % TILES_W) // don't wrap
|
||||
update_selected_tile_relative(-1);
|
||||
return GUI_YUM;
|
||||
case NORTH_EAST_KEY:
|
||||
if (selectedTile >= TILES_W)
|
||||
update_selected_tile_relative(-TILES_W);
|
||||
if ((selectedTile + 1) % TILES_W) // don't wrap
|
||||
update_selected_tile_relative(1);
|
||||
return GUI_YUM;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (key.flags == 0) {
|
||||
if (key.keycode == Common::KEYCODE_g) {
|
||||
toggleGrid();
|
||||
return GUI_YUM;
|
||||
} else if (key.keycode == Common::KEYCODE_s) {
|
||||
Game::get_game()->get_game_map()->saveRoofData();
|
||||
return GUI_YUM;
|
||||
}
|
||||
}
|
||||
|
||||
switch (action_type) {
|
||||
case MSGSCROLL_UP_KEY:
|
||||
update_selected_tile_relative(-(TILES_W * TILES_H));
|
||||
break;
|
||||
case MSGSCROLL_DOWN_KEY:
|
||||
update_selected_tile_relative(TILES_W * TILES_H);
|
||||
break;
|
||||
case SOUTH_WEST_KEY:
|
||||
map_window->moveMapRelative(-1, 1);
|
||||
break;
|
||||
case SOUTH_EAST_KEY:
|
||||
map_window->moveMapRelative(1, 1);
|
||||
break;
|
||||
case NORTH_WEST_KEY:
|
||||
map_window->moveMapRelative(-1, -1);
|
||||
break;
|
||||
case NORTH_EAST_KEY:
|
||||
map_window->moveMapRelative(1, -1);
|
||||
break;
|
||||
|
||||
case NORTH_KEY:
|
||||
map_window->moveMapRelative(0, -1);
|
||||
break;
|
||||
case SOUTH_KEY:
|
||||
map_window->moveMapRelative(0, 1);
|
||||
break;
|
||||
case WEST_KEY:
|
||||
map_window->moveMapRelative(-1, 0);
|
||||
break;
|
||||
case EAST_KEY:
|
||||
map_window->moveMapRelative(1, 0);
|
||||
break;
|
||||
case DO_ACTION_KEY:
|
||||
|
||||
loc = map_window->get_cursorCoord();
|
||||
roof_data = Game::get_game()->get_game_map()->get_roof_data(loc.z);
|
||||
if (roof_data) {
|
||||
roof_data[loc.y * 1024 + loc.x] = selectedTile;
|
||||
}
|
||||
break;
|
||||
case TOGGLE_CURSOR_KEY :
|
||||
|
||||
break;
|
||||
case HOME_KEY:
|
||||
selectedTile = 0;
|
||||
tile_offset = 0;
|
||||
break;
|
||||
case END_KEY:
|
||||
selectedTile = MAPWINDOW_ROOFTILES_IMG_W * MAPWINDOW_ROOFTILES_IMG_H - 1;
|
||||
tile_offset = (TILES_W * TILES_H) * (selectedTile / (TILES_W * TILES_H));
|
||||
break;
|
||||
case CANCEL_ACTION_KEY:
|
||||
//Game::get_game()->get_view_manager()->close_gump(this);
|
||||
close_view();
|
||||
GUI::get_gui()->removeWidget((GUI_Widget *)this);
|
||||
break;
|
||||
default:
|
||||
keybinder->handle_always_available_keys(a);
|
||||
break; // was GUI_PASS pefore action_type change
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status MapEditorView::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status MapEditorView::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
|
||||
if (button == Events::BUTTON_RIGHT) {
|
||||
//Game::get_game()->get_view_manager()->close_gump(this);
|
||||
close_view();
|
||||
GUI::get_gui()->removeWidget((GUI_Widget *)this);
|
||||
} else if (HitRect(x, y)) {
|
||||
x -= area.left;
|
||||
x -= 3;
|
||||
y -= area.top;
|
||||
y -= 16;
|
||||
selectedTile = tile_offset + (y / 17) * TILES_W + (x / 17);
|
||||
} else {
|
||||
int wx, wy;
|
||||
uint8 level;
|
||||
map_window->get_level(&level);
|
||||
map_window->mouseToWorldCoords(x, y, wx, wy);
|
||||
setTile((uint16)wx, (uint16)wy, level);
|
||||
|
||||
}
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status MapEditorView::MouseMotion(int x, int y, uint8 state) {
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void MapEditorView::setTile(uint16 x, uint16 y, uint8 level) {
|
||||
uint16 *roof_data = Game::get_game()->get_game_map()->get_roof_data(level);
|
||||
if (roof_data) {
|
||||
roof_data[y * ((level == 0) ? 1024 : 256) + x] = selectedTile;
|
||||
}
|
||||
}
|
||||
|
||||
void MapEditorView::toggleGrid() {
|
||||
map_window->set_show_grid(!map_window->is_grid_showing());
|
||||
}
|
||||
|
||||
void MapEditorView::close_view() {
|
||||
map_window->set_show_cursor(false);
|
||||
map_window->set_roof_display_mode(ROOF_DISPLAY_NORMAL);
|
||||
map_window->set_enable_blacking(true);
|
||||
map_window->set_show_grid(false);
|
||||
release_focus();
|
||||
Hide();
|
||||
}
|
||||
|
||||
void MapEditorView::update_selected_tile_relative(sint32 rel_value) {
|
||||
if ((sint32)selectedTile + rel_value < 0 || (sint32)selectedTile + rel_value >= (MAPWINDOW_ROOFTILES_IMG_W * MAPWINDOW_ROOFTILES_IMG_H))
|
||||
return;
|
||||
|
||||
selectedTile = selectedTile + rel_value;
|
||||
tile_offset = (TILES_W * TILES_H) * (selectedTile / (TILES_W * TILES_H));
|
||||
}
|
||||
|
||||
GUI_status MapEditorView::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
if (caller == up_button) {
|
||||
update_selected_tile_relative(-(TILES_W * TILES_H));
|
||||
return GUI_YUM;
|
||||
} else if (caller == down_button) {
|
||||
update_selected_tile_relative(TILES_W * TILES_H);
|
||||
return GUI_YUM;
|
||||
}
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
65
engines/ultima/nuvie/views/map_editor_view.h
Normal file
65
engines/ultima/nuvie/views/map_editor_view.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* 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 NUVIE_VIEWS_MAP_EDITOR_VIEW_H
|
||||
#define NUVIE_VIEWS_MAP_EDITOR_VIEW_H
|
||||
|
||||
#include "ultima/nuvie/views/view.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class GUI_Button;
|
||||
class MapWindow;
|
||||
|
||||
class MapEditorView: public View {
|
||||
private:
|
||||
Graphics::ManagedSurface *roof_tiles;
|
||||
MapWindow *map_window;
|
||||
uint16 selectedTile;
|
||||
uint16 tile_offset;
|
||||
GUI_Button *up_button;
|
||||
GUI_Button *down_button;
|
||||
public:
|
||||
MapEditorView(const Configuration *config);
|
||||
~MapEditorView() override;
|
||||
|
||||
bool init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om);
|
||||
void Display(bool full_redraw) override;
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override;
|
||||
|
||||
void close_view() override;
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
protected:
|
||||
void setTile(uint16 x, uint16 y, uint8 level);
|
||||
void toggleGrid();
|
||||
private:
|
||||
void update_selected_tile_relative(sint32 rel_value);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
87
engines/ultima/nuvie/views/md_sky_strip_widget.cpp
Normal file
87
engines/ultima/nuvie/views/md_sky_strip_widget.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/core/game_clock.h"
|
||||
#include "ultima/nuvie/files/u6_shape.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/views/md_sky_strip_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
MDSkyStripWidget::MDSkyStripWidget(const Configuration *cfg, GameClock *c, Player *p)
|
||||
: GUI_Widget(nullptr, 0, 0, 0, 0), config(cfg), player(p), _clock(c) {
|
||||
}
|
||||
|
||||
MDSkyStripWidget::~MDSkyStripWidget() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MDSkyStripWidget::init(sint16 x, sint16 y) {
|
||||
Common::Path filename;
|
||||
|
||||
GUI_Widget::Init(nullptr, x, y, 112, 11);
|
||||
config_get_path(config, "mdscreen.lzc", filename);
|
||||
|
||||
strip1.load_from_lzc(filename, 2, 2);
|
||||
strip2.load_from_lzc(filename, 2, 3);
|
||||
}
|
||||
|
||||
void MDSkyStripWidget::Display(bool full_redraw) {
|
||||
if (full_redraw || update_display) {
|
||||
update_display = false;
|
||||
|
||||
uint8 z = player->get_actor() ? player->get_actor()->get_z() : 0;
|
||||
if (z == 0) {
|
||||
display_surface();
|
||||
} else if (z == 1) {
|
||||
screen->fill(0, area.left, area.top, area.width(), area.height());
|
||||
} else {
|
||||
screen->fill(7, area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MDSkyStripWidget::display_surface() {
|
||||
uint16 w, h;
|
||||
strip1.get_size(&w, &h);
|
||||
uint8 hour = _clock->get_hour();
|
||||
uint8 minute = _clock->get_minute();
|
||||
unsigned char *shp_data = hour < 12 ? strip1.get_data() : strip2.get_data();
|
||||
|
||||
if (hour >= 12) {
|
||||
hour -= 12;
|
||||
}
|
||||
|
||||
shp_data += hour * 16 + (minute / 15) * 4;
|
||||
|
||||
screen->blit(area.left, area.top, shp_data, 8, area.width(), area.height(), w, false);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
57
engines/ultima/nuvie/views/md_sky_strip_widget.h
Normal file
57
engines/ultima/nuvie/views/md_sky_strip_widget.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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 NUVIE_VIEWS_MD_SKY_STRIP_WIDGET_H
|
||||
#define NUVIE_VIEWS_MD_SKY_STRIP_WIDGET_H
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/files/u6_shape.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class GameClock;
|
||||
class Configuration;
|
||||
class Player;
|
||||
|
||||
class MDSkyStripWidget : public GUI_Widget {
|
||||
|
||||
protected:
|
||||
const Configuration *config;
|
||||
GameClock *_clock;
|
||||
U6Shape strip1, strip2;
|
||||
Player *player;
|
||||
|
||||
public:
|
||||
MDSkyStripWidget(const Configuration *cfg, GameClock *c, Player *p);
|
||||
~MDSkyStripWidget() override;
|
||||
|
||||
void init(sint16 x, sint16 y);
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
private:
|
||||
void display_surface();
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
388
engines/ultima/nuvie/views/party_view.cpp
Normal file
388
engines/ultima/nuvie/views/party_view.cpp
Normal file
@@ -0,0 +1,388 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/core/party.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/core/game_clock.h"
|
||||
#include "ultima/nuvie/views/party_view.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/core/weather.h"
|
||||
#include "ultima/nuvie/script/script.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/gui/widgets/command_bar.h"
|
||||
#include "ultima/nuvie/usecode/usecode.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/views/sun_moon_strip_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
extern GUI_status inventoryViewButtonCallback(void *data);
|
||||
extern GUI_status actorViewButtonCallback(void *data);
|
||||
|
||||
#define U6 Game::get_game()->get_game_type()==NUVIE_GAME_U6
|
||||
#define SE Game::get_game()->get_game_type()==NUVIE_GAME_SE
|
||||
#define MD Game::get_game()->get_game_type()==NUVIE_GAME_MD
|
||||
|
||||
PartyView::PartyView(const Configuration *cfg) : View(cfg), player(nullptr),
|
||||
view_manager(nullptr), party_view_targeting(false), row_offset(0),
|
||||
sun_moon_widget(nullptr) {
|
||||
}
|
||||
|
||||
PartyView::~PartyView() {
|
||||
|
||||
}
|
||||
|
||||
bool PartyView::init(void *vm, uint16 x, uint16 y, Font *f, Party *p, Player *pl, TileManager *tm, ObjManager *om) {
|
||||
View::init(x, y, f, p, tm, om);
|
||||
// PartyView is 8px wider than other Views, for the arrows
|
||||
// ...and 3px taller, for the sky (SB-X)
|
||||
if (U6)
|
||||
SetRect(area.left, area.top, area.width() + 8, area.height() + 3);
|
||||
else
|
||||
SetRect(area.left, area.top, area.width(), area.height());
|
||||
|
||||
view_manager = vm;
|
||||
player = pl;
|
||||
|
||||
if (U6) {
|
||||
sun_moon_widget = new SunMoonStripWidget(player, tile_manager);
|
||||
sun_moon_widget->init(area.left, area.top);
|
||||
AddWidget(sun_moon_widget);
|
||||
}
|
||||
|
||||
config->value("config/input/party_view_targeting", party_view_targeting, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GUI_status PartyView::MouseWheel(sint32 x, sint32 y) {
|
||||
int xpos, ypos;
|
||||
screen->get_mouse_location(&xpos, &ypos);
|
||||
|
||||
xpos -= area.left;
|
||||
ypos -= area.top;
|
||||
if (xpos < 0 || ypos > area.top + area.height() - 6)
|
||||
return GUI_PASS; // goes to MsgScrollw
|
||||
|
||||
if (y > 0) {
|
||||
if (up_arrow())
|
||||
Redraw();
|
||||
}
|
||||
if (y < 0) {
|
||||
if (down_arrow())
|
||||
Redraw();
|
||||
}
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status PartyView::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
x -= area.left;
|
||||
y -= area.top;
|
||||
|
||||
if (y < 18 && U6) // clicked on skydisplay
|
||||
return GUI_PASS;
|
||||
if (y < 4 && MD)
|
||||
return GUI_PASS;
|
||||
|
||||
int rowH = 16;
|
||||
if (MD)
|
||||
rowH = 24;
|
||||
|
||||
uint8 party_size = party->get_party_size();
|
||||
if (SE) {
|
||||
if (party_size > 7) party_size = 7;
|
||||
} else if (party_size > 5) party_size = 5; // can only display/handle 5 at a time
|
||||
|
||||
Common::Rect arrow_rects_U6[2] = { Common::Rect(0, 18, 0 + 8, 18 + 8), Common::Rect(0, 90, 0 + 8, 90 + 8) };
|
||||
Common::Rect arrow_rects[2] = { Common::Rect(0, 6, 0 + 7, 6 + 8), Common::Rect(0, 102, 0 + 7, 102 + 8) };
|
||||
Common::Rect arrow_up_rect_MD[1] = { Common::Rect(0, 15, 0 + 7, 15 + 8) };
|
||||
|
||||
if (HitRect(x, y, U6 ? arrow_rects_U6[0] : (MD ? arrow_up_rect_MD[0] : arrow_rects[0]))) { //up arrow hit rect
|
||||
if (up_arrow())
|
||||
Redraw();
|
||||
return GUI_YUM;
|
||||
}
|
||||
if (HitRect(x, y, U6 ? arrow_rects_U6[1] : arrow_rects[1])) { //down arrow hit rect
|
||||
if (down_arrow())
|
||||
Redraw();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
int x_offset = 7;
|
||||
int y_offset = 18;
|
||||
if (SE) {
|
||||
x_offset = 6;
|
||||
y_offset = 2;
|
||||
} else if (MD)
|
||||
y_offset = 4;
|
||||
if (y > party_size * rowH + y_offset - 1) // clicked below actors
|
||||
return GUI_YUM;
|
||||
|
||||
if (x >= x_offset) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
CommandBar *command_bar = Game::get_game()->get_command_bar();
|
||||
|
||||
if (button == ACTION_BUTTON && event->get_mode() == MOVE_MODE
|
||||
&& command_bar->get_selected_action() > 0) { // Exclude attack mode too
|
||||
if (command_bar->try_selected_action() == false) // start new action
|
||||
return GUI_PASS; // false if new event doesn't need target
|
||||
}
|
||||
if ((party_view_targeting || (button == ACTION_BUTTON
|
||||
&& command_bar->get_selected_action() > 0)) && event->can_target_icon()) {
|
||||
x += area.left;
|
||||
y += area.top;
|
||||
Actor *actor = get_actor(x, y);
|
||||
if (actor) {
|
||||
event->select_actor(actor);
|
||||
return GUI_YUM;
|
||||
}
|
||||
}
|
||||
set_party_member(((y - y_offset) / rowH) + row_offset);
|
||||
if (x >= x_offset + 17) { // clicked an actor name
|
||||
actorViewButtonCallback(view_manager);
|
||||
} else { // clicked an actor icon
|
||||
inventoryViewButtonCallback(view_manager);
|
||||
}
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
Actor *PartyView::get_actor(int x, int y) {
|
||||
x -= area.left;
|
||||
y -= area.top;
|
||||
|
||||
uint8 party_size = party->get_party_size();
|
||||
int rowH = 16;
|
||||
int y_offset = 18;
|
||||
if (MD) {
|
||||
rowH = 24;
|
||||
y_offset = 0;
|
||||
}
|
||||
if (SE) {
|
||||
y_offset = 2;
|
||||
if (party_size > 7) party_size = 7;
|
||||
} else if (party_size > 5) party_size = 5; // can only display/handle 5 at a time
|
||||
|
||||
if (y > party_size * rowH + y_offset) // clicked below actors
|
||||
return nullptr;
|
||||
|
||||
if (x >= 8) {
|
||||
return party->get_actor(((y - y_offset) / rowH) + row_offset);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool PartyView::drag_accept_drop(int x, int y, int message, void *data) {
|
||||
GUI::get_gui()->force_full_redraw();
|
||||
DEBUG(0, LEVEL_DEBUGGING, "PartyView::drag_accept_drop()\n");
|
||||
if (message == GUI_DRAG_OBJ) {
|
||||
MsgScroll *scroll = Game::get_game()->get_scroll();
|
||||
|
||||
Obj *obj = (Obj *)data;
|
||||
Actor *actor = get_actor(x, y);
|
||||
if (actor) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
event->display_move_text(actor, obj);
|
||||
if (!obj->is_in_inventory()
|
||||
&& !Game::get_game()->get_map_window()->can_get_obj(actor, obj)) {
|
||||
Game::get_game()->get_scroll()->message("\n\nblocked\n\n");
|
||||
return false;
|
||||
}
|
||||
if ((!Game::get_game()->get_usecode()->has_getcode(obj)
|
||||
|| Game::get_game()->get_usecode()->get_obj(obj, actor))
|
||||
&& event->can_move_obj_between_actors(obj, player->get_actor(), actor)) {
|
||||
if (actor == player->get_actor()) // get
|
||||
player->subtract_movement_points(3);
|
||||
else // get plus move
|
||||
player->subtract_movement_points(8);
|
||||
if (!obj->is_in_inventory() &&
|
||||
obj_manager->obj_is_damaging(obj, Game::get_game()->get_player()->get_actor()))
|
||||
return false;
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop Accepted\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
scroll->display_string("\n\n");
|
||||
scroll->display_prompt();
|
||||
}
|
||||
|
||||
Redraw();
|
||||
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop Refused\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
void PartyView::drag_perform_drop(int x, int y, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "InventoryWidget::drag_perform_drop()\n");
|
||||
Obj *obj;
|
||||
|
||||
if (message == GUI_DRAG_OBJ) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop into inventory.\n");
|
||||
obj = (Obj *)data;
|
||||
|
||||
Actor *actor = get_actor(x, y);
|
||||
if (actor) {
|
||||
obj_manager->moveto_inventory(obj, actor);
|
||||
}
|
||||
MsgScroll *scroll = Game::get_game()->get_scroll();
|
||||
scroll->display_string("\n\n");
|
||||
scroll->display_prompt();
|
||||
|
||||
Redraw();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void PartyView::Display(bool full_redraw) {
|
||||
|
||||
if (full_redraw || update_display || MD || Game::get_game()->is_original_plus_full_map()) {
|
||||
uint8 party_size = party->get_party_size();
|
||||
int rowH = 16;
|
||||
if (MD)
|
||||
rowH = 24;
|
||||
update_display = false;
|
||||
uint8 end_offset = row_offset + 5;
|
||||
if (MD)
|
||||
fill_md_background(bg_color, area);
|
||||
else
|
||||
screen->fill(bg_color, area.left, area.top, area.width(), area.height());
|
||||
//if(U6)
|
||||
// display_sun_moon_strip();
|
||||
|
||||
display_arrows();
|
||||
|
||||
if (SE)
|
||||
end_offset = row_offset + 7;
|
||||
if (end_offset > party_size)
|
||||
end_offset = party_size;
|
||||
|
||||
for (uint8 i = row_offset; i < end_offset; i++) {
|
||||
Actor *actor = party->get_actor(i);
|
||||
Tile *actor_tile = tile_manager->get_tile(actor->get_downward_facing_tile_num());
|
||||
|
||||
int x_offset = 8;
|
||||
int y_offset = 18;
|
||||
uint8 hp_text_color = 0; //standard text color
|
||||
|
||||
if (U6)
|
||||
hp_text_color = 0x48; //standard text color
|
||||
if (SE) {
|
||||
x_offset = 6;
|
||||
y_offset = 1;
|
||||
}
|
||||
if (MD) {
|
||||
x_offset = 8;
|
||||
y_offset = 6;
|
||||
GameClock *clock = Game::get_game()->get_clock();
|
||||
if (clock->get_purple_berry_counter(actor->get_actor_num()) > 0) {
|
||||
screen->blit(area.left + x_offset + 16, area.top + y_offset + (i - row_offset)*rowH, tile_manager->get_tile(TILE_MD_PURPLE_BERRY_MARKER)->data, 8, 16, 16, 16, true);
|
||||
}
|
||||
if (clock->get_green_berry_counter(actor->get_actor_num()) > 0) {
|
||||
screen->blit(area.left + x_offset + 32, area.top + y_offset + (i - row_offset)*rowH, tile_manager->get_tile(TILE_MD_GREEN_BERRY_MARKER)->data, 8, 16, 16, 16, true);
|
||||
}
|
||||
if (clock->get_brown_berry_counter(actor->get_actor_num()) > 0) {
|
||||
screen->blit(area.left + x_offset + 32, area.top + y_offset + (i - row_offset)*rowH, tile_manager->get_tile(TILE_MD_BROWN_BERRY_MARKER)->data, 8, 16, 16, 16, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
screen->blit(area.left + x_offset, area.top + y_offset + (i - row_offset)*rowH, actor_tile->data, 8, 16, 16, 16, true);
|
||||
const char *actor_name = party->get_actor_name(i);
|
||||
|
||||
if (SE) {
|
||||
x_offset = 4;
|
||||
y_offset = 0;
|
||||
}
|
||||
if (MD)
|
||||
y_offset = -3;
|
||||
// FIXME: Martian Dreams text is somewhat center aligned
|
||||
font->drawString(screen, actor_name, area.left + x_offset + 24, area.top + y_offset + (i - row_offset) * rowH + 8);
|
||||
char hp_string[4];
|
||||
Common::sprintf_s(hp_string, "%3d", actor->get_hp());
|
||||
hp_text_color = actor->get_hp_text_color();
|
||||
if (SE) {
|
||||
x_offset = -7;
|
||||
y_offset = 3;
|
||||
}
|
||||
if (MD) {
|
||||
x_offset = -16;
|
||||
y_offset = 14;
|
||||
}
|
||||
font->drawString(screen, hp_string, strlen(hp_string), area.left + x_offset + 112, area.top + y_offset + (i - row_offset) * rowH, hp_text_color, 0);
|
||||
}
|
||||
DisplayChildren(full_redraw);
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool PartyView::up_arrow() {
|
||||
if (row_offset > 0) {
|
||||
row_offset--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PartyView::down_arrow() {
|
||||
if ((row_offset + (SE ? 7 : 5)) < party->get_party_size()) {
|
||||
row_offset++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PartyView::display_arrows() {
|
||||
int x_offset = 0;
|
||||
int y_offset = 0;
|
||||
if (SE || MD) {
|
||||
x_offset = 2;
|
||||
y_offset = 12;
|
||||
}
|
||||
uint8 max_party_size = 5;
|
||||
uint8 party_size = party->get_party_size();
|
||||
if (SE)
|
||||
max_party_size = 7;
|
||||
if (party_size <= max_party_size) // reset
|
||||
row_offset = 0;
|
||||
|
||||
if ((party_size - row_offset) > max_party_size) // display bottom arrow
|
||||
font->drawChar(screen, 25, area.left - x_offset, area.top + 90 + y_offset);
|
||||
if (MD)
|
||||
y_offset = 3;
|
||||
if (row_offset > 0) // display top arrow
|
||||
font->drawChar(screen, 24, area.left - x_offset, area.top + 18 - y_offset);
|
||||
}
|
||||
// </SB-X>
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
87
engines/ultima/nuvie/views/party_view.h
Normal file
87
engines/ultima/nuvie/views/party_view.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* 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 NUVIE_VIEWS_PARTY_VIEW_H
|
||||
#define NUVIE_VIEWS_PARTY_VIEW_H
|
||||
|
||||
#include "ultima/nuvie/views/view.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class ObjManager;
|
||||
class Screen;
|
||||
class Font;
|
||||
class Party;
|
||||
class Player;
|
||||
class Actor;
|
||||
class SunMoonStripWidget;
|
||||
|
||||
class PartyView : public View {
|
||||
|
||||
Player *player;
|
||||
void *view_manager;
|
||||
uint16 row_offset; // first party member displayed
|
||||
SunMoonStripWidget *sun_moon_widget;
|
||||
|
||||
public:
|
||||
PartyView(const Configuration *cfg);
|
||||
~PartyView() override;
|
||||
|
||||
bool init(void *vm, uint16 x, uint16 y, Font *f, Party *p, Player *pl, TileManager *tm, ObjManager *om);
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
bool drag_accept_drop(int x, int y, int message, void *data) override;
|
||||
void drag_perform_drop(int x, int y, int message, void *data) override;
|
||||
void Display(bool full_redraw) override;
|
||||
void update() {
|
||||
update_display = true;
|
||||
}
|
||||
void display_sun_moon_strip();
|
||||
void set_party_view_targeting(bool val) {
|
||||
party_view_targeting = val;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void display_surface_strip();
|
||||
void display_dungeon_strip();
|
||||
void display_arrows();
|
||||
void display_sun_moon(Tile *tile, uint8 pos);
|
||||
void display_sun(uint8 hour, uint8 minute, bool eclipse);
|
||||
void display_moons(uint8 day, uint8 hour, uint8 minute = 0);
|
||||
|
||||
bool up_arrow();
|
||||
bool down_arrow();
|
||||
bool party_view_targeting;
|
||||
|
||||
Actor *get_actor(int x, int y);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
245
engines/ultima/nuvie/views/portrait_view.cpp
Normal file
245
engines/ultima/nuvie/views/portrait_view.cpp
Normal file
@@ -0,0 +1,245 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/shared/std/string.h"
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/files/u6_lib_n.h"
|
||||
#include "ultima/nuvie/files/u6_shape.h"
|
||||
|
||||
#include "ultima/nuvie/core/game.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/portraits/portrait.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/views/doll_widget.h"
|
||||
#include "ultima/nuvie/views/portrait_view.h"
|
||||
#include "ultima/nuvie/views/sun_moon_strip_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
PortraitView::PortraitView(const Configuration *cfg) : View(cfg),
|
||||
portrait_data(nullptr), portrait(nullptr), bg_data(nullptr),
|
||||
name_string(new string), show_cursor(false), doll_widget(nullptr),
|
||||
waiting(false), display_doll(false), cur_actor_num(0) {
|
||||
gametype = get_game_type(cfg);
|
||||
|
||||
//FIXME: Portraits in SE/MD are different size than in U6! 79x85 76x83
|
||||
switch (gametype) {
|
||||
case NUVIE_GAME_U6:
|
||||
portrait_width = 56;
|
||||
portrait_height = 64;
|
||||
break;
|
||||
case NUVIE_GAME_SE:
|
||||
portrait_width = 79;
|
||||
portrait_height = 85;
|
||||
break;
|
||||
case NUVIE_GAME_MD:
|
||||
portrait_width = 76;
|
||||
portrait_height = 83;
|
||||
break;
|
||||
default:
|
||||
error("Unsupported game type in PortraitView");
|
||||
}
|
||||
}
|
||||
|
||||
PortraitView::~PortraitView() {
|
||||
if (portrait_data != nullptr)
|
||||
free(portrait_data);
|
||||
|
||||
if (bg_data != nullptr)
|
||||
delete bg_data;
|
||||
|
||||
delete name_string;
|
||||
}
|
||||
|
||||
bool PortraitView::init(uint16 x, uint16 y, Font *f, Party *p, Player *player, TileManager *tm, ObjManager *om, Portrait *port) {
|
||||
View::init(x, y, f, p, tm, om);
|
||||
|
||||
portrait = port;
|
||||
|
||||
doll_widget = new DollWidget(config, this);
|
||||
doll_widget->init(nullptr, 0, 16, tile_manager, obj_manager, true);
|
||||
|
||||
AddWidget(doll_widget);
|
||||
doll_widget->Hide();
|
||||
|
||||
if (gametype == NUVIE_GAME_U6) {
|
||||
SunMoonStripWidget *sun_moon_widget = new SunMoonStripWidget(player, tile_manager);
|
||||
sun_moon_widget->init(-8, -2);
|
||||
AddWidget(sun_moon_widget);
|
||||
} else if (gametype == NUVIE_GAME_MD) {
|
||||
load_background("mdscreen.lzc", 1);
|
||||
} else if (gametype == NUVIE_GAME_SE) {
|
||||
load_background("bkgrnd.lzc", 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PortraitView::load_background(const char *f, uint8 lib_offset) {
|
||||
U6Lib_n file;
|
||||
bg_data = new U6Shape();
|
||||
Common::Path path;
|
||||
config_get_path(config, f, path);
|
||||
file.open(path, 4, gametype);
|
||||
unsigned char *temp_buf = file.get_item(lib_offset);
|
||||
bg_data->load(temp_buf + 8);
|
||||
free(temp_buf);
|
||||
}
|
||||
|
||||
void PortraitView::Display(bool full_redraw) {
|
||||
|
||||
if (Game::get_game()->is_new_style() || Game::get_game()->is_original_plus_full_map())
|
||||
screen->fill(bg_color, area.left, area.top, area.width(), area.height());
|
||||
if (portrait_data != nullptr/* && (full_redraw || update_display)*/) {
|
||||
update_display = false;
|
||||
if (gametype == NUVIE_GAME_U6) {
|
||||
if (display_doll)
|
||||
screen->blit(area.left + 72, area.top + 16, portrait_data, 8, portrait_width, portrait_height, portrait_width, false);
|
||||
else
|
||||
screen->blit(area.left + (area.width() - portrait_width) / 2, area.top + (area.height() - portrait_height) / 2, portrait_data, 8, portrait_width, portrait_height, portrait_width, true);
|
||||
display_name(80);
|
||||
} else if (gametype == NUVIE_GAME_MD) {
|
||||
uint16 w, h;
|
||||
bg_data->get_size(&w, &h);
|
||||
screen->blit(area.left, area.top - 2, bg_data->get_data(), 8, w, h, w, true);
|
||||
|
||||
screen->blit(area.left + (area.width() - portrait_width) / 2, area.top + 6, portrait_data, 8, portrait_width, portrait_height, portrait_width, true);
|
||||
display_name(100);
|
||||
} else if (gametype == NUVIE_GAME_SE) {
|
||||
uint16 w, h;
|
||||
bg_data->get_size(&w, &h);
|
||||
screen->blit(area.left, area.top, bg_data->get_data(), 8, w, h, w, true);
|
||||
|
||||
screen->blit(area.left + (area.width() - portrait_width) / 2 + 1, area.top + 1, portrait_data, 8, portrait_width, portrait_height, portrait_width, true);
|
||||
display_name(98);
|
||||
}
|
||||
}
|
||||
if (show_cursor && gametype == NUVIE_GAME_U6) { // FIXME: should we be using scroll's drawCursor?
|
||||
screen->fill(bg_color, area.left, area.top + area.height() - 8, 8, 8);
|
||||
Game::get_game()->get_scroll()->drawCursor(area.left, area.top + area.height() - 8);
|
||||
}
|
||||
DisplayChildren(full_redraw);
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
bool PortraitView::set_portrait(Actor *actor, const char *name) {
|
||||
if (Game::get_game()->is_new_style())
|
||||
this->Show();
|
||||
cur_actor_num = actor->get_actor_num();
|
||||
int doll_x_offset = 0;
|
||||
|
||||
if (portrait_data != nullptr)
|
||||
free(portrait_data);
|
||||
|
||||
portrait_data = portrait->get_portrait_data(actor);
|
||||
|
||||
if (gametype == NUVIE_GAME_U6 && actor->has_readied_objects()) {
|
||||
if (portrait_data == nullptr)
|
||||
doll_x_offset = 34;
|
||||
|
||||
doll_widget->MoveRelativeToParent(doll_x_offset, 16);
|
||||
|
||||
display_doll = true;
|
||||
doll_widget->Show();
|
||||
doll_widget->set_actor(actor);
|
||||
} else {
|
||||
display_doll = false;
|
||||
doll_widget->Hide();
|
||||
doll_widget->set_actor(nullptr);
|
||||
|
||||
if (portrait_data == nullptr)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name == nullptr)
|
||||
name = actor->get_name();
|
||||
if (name == nullptr)
|
||||
name_string->assign(""); // just in case
|
||||
else
|
||||
name_string->assign(name);
|
||||
|
||||
if (screen)
|
||||
screen->fill(bg_color, area.left, area.top, area.width(), area.height());
|
||||
|
||||
Redraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
void PortraitView::display_name(uint16 y_offset) {
|
||||
const char *name;
|
||||
|
||||
name = name_string->c_str();
|
||||
|
||||
font->drawString(screen, name, area.left + (area.width() - strlen(name) * 8) / 2, area.top + y_offset);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* On any input return to previous status view if waiting.
|
||||
* Returns true if event was used.
|
||||
*/
|
||||
GUI_status PortraitView::HandleEvent(const Common::Event *event) {
|
||||
if (waiting && (
|
||||
event->type == Common::EVENT_LBUTTONDOWN
|
||||
|| event->type == Common::EVENT_RBUTTONDOWN
|
||||
|| event->type == Common::EVENT_MBUTTONDOWN
|
||||
|| event->type == Common::EVENT_KEYDOWN)
|
||||
) {
|
||||
if (Game::get_game()->is_new_style())
|
||||
this->Hide();
|
||||
else // FIXME revert to previous status view
|
||||
Game::get_game()->get_view_manager()->set_inventory_mode();
|
||||
// Game::get_game()->get_scroll()->set_input_mode(false);
|
||||
Game::get_game()->get_scroll()->message("\n");
|
||||
set_waiting(false);
|
||||
return GUI_YUM;
|
||||
}
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
|
||||
/* Start/stop waiting for input to continue, and (for now) steal cursor from
|
||||
* MsgScroll.
|
||||
*/
|
||||
void PortraitView::set_waiting(bool state) {
|
||||
if (state == true && display_doll == false && portrait_data == nullptr) { // don't wait for nothing
|
||||
if (Game::get_game()->is_new_style())
|
||||
this->Hide();
|
||||
return;
|
||||
}
|
||||
waiting = state;
|
||||
set_show_cursor(waiting);
|
||||
Game::get_game()->get_scroll()->set_show_cursor(!waiting);
|
||||
Game::get_game()->get_gui()->lock_input(waiting ? this : nullptr);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
91
engines/ultima/nuvie/views/portrait_view.h
Normal file
91
engines/ultima/nuvie/views/portrait_view.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/* 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 NUVIE_VIEWS_PORTRAIT_VIEW_H
|
||||
#define NUVIE_VIEWS_PORTRAIT_VIEW_H
|
||||
|
||||
#include "ultima/nuvie/views/view.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class Portrait;
|
||||
class Screen;
|
||||
class Font;
|
||||
class ObjManager;
|
||||
class Party;
|
||||
class Player;
|
||||
class Actor;
|
||||
class DollWidget;
|
||||
class U6Shape;
|
||||
|
||||
class PortraitView : public View {
|
||||
|
||||
nuvie_game_t gametype;
|
||||
|
||||
uint8 cur_actor_num;
|
||||
Portrait *portrait;
|
||||
Std::string *name_string;
|
||||
|
||||
unsigned char *portrait_data;
|
||||
U6Shape *bg_data;
|
||||
uint8 portrait_width;
|
||||
uint8 portrait_height;
|
||||
|
||||
bool waiting; // waiting for input, then will return to previous view
|
||||
bool show_cursor; // indicate waiting for input
|
||||
// uint16 cursor_x, cursor_y;
|
||||
|
||||
DollWidget *doll_widget;
|
||||
bool display_doll;
|
||||
|
||||
public:
|
||||
PortraitView(const Configuration *cfg);
|
||||
~PortraitView() override;
|
||||
|
||||
bool init(uint16 x, uint16 y, Font *f, Party *p, Player *player, TileManager *tm, ObjManager *om, Portrait *port);
|
||||
void Display(bool full_redraw) override;
|
||||
GUI_status HandleEvent(const Common::Event *event) override;
|
||||
|
||||
bool set_portrait(Actor *actor, const char *name);
|
||||
void set_show_cursor(bool state) {
|
||||
show_cursor = state;
|
||||
}
|
||||
void set_waiting(bool state);
|
||||
bool get_waiting() const {
|
||||
return waiting;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void display_name(uint16 y_offset);
|
||||
|
||||
private:
|
||||
void load_background(const char *filename, uint8 lib_offset);
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
293
engines/ultima/nuvie/views/portrait_view_gump.cpp
Normal file
293
engines/ultima/nuvie/views/portrait_view_gump.cpp
Normal file
@@ -0,0 +1,293 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
#include "ultima/nuvie/core/party.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/portraits/portrait.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/views/container_widget_gump.h"
|
||||
#include "ultima/nuvie/views/portrait_view_gump.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
PortraitViewGump::PortraitViewGump(const Configuration *cfg) : DraggableView(cfg),
|
||||
portrait(nullptr), font(nullptr), gump_button(nullptr), portrait_data(nullptr),
|
||||
actor(nullptr), cursor_tile(nullptr), show_cursor(true),
|
||||
cursor_pos(CURSOR_CHECK), cursor_xoff(1), cursor_yoff(67) {
|
||||
}
|
||||
|
||||
PortraitViewGump::~PortraitViewGump() {
|
||||
if (font)
|
||||
delete font;
|
||||
if (portrait_data)
|
||||
free(portrait_data);
|
||||
}
|
||||
|
||||
bool PortraitViewGump::init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om, Portrait *por, Actor *a) {
|
||||
View::init(x, y, f, p, tm, om);
|
||||
|
||||
SetRect(area.left, area.top, 188, 91);
|
||||
|
||||
portrait = por;
|
||||
set_actor(a);
|
||||
|
||||
Common::Path datadir = GUI::get_gui()->get_data_dir();
|
||||
Common::Path imagefile;
|
||||
Common::Path path;
|
||||
|
||||
build_path(datadir, "images", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "gumps", path);
|
||||
datadir = path;
|
||||
|
||||
gump_button = loadButton(datadir, "gump", 0, 67);
|
||||
|
||||
build_path(datadir, "portrait_bg.bmp", imagefile);
|
||||
bg_image = SDL_LoadBMP(imagefile);
|
||||
|
||||
set_bg_color_key(0, 0x70, 0xfc);
|
||||
|
||||
font = new GUI_Font(GUI_FONT_GUMP);
|
||||
font->setColoring(0x08, 0x08, 0x08, 0x80, 0x58, 0x30, 0x00, 0x00, 0x00);
|
||||
|
||||
Graphics::ManagedSurface *image, *image1;
|
||||
|
||||
build_path(datadir, "left_arrow.bmp", imagefile);
|
||||
image = SDL_LoadBMP(imagefile);
|
||||
image1 = SDL_LoadBMP(imagefile);
|
||||
|
||||
left_button = new GUI_Button(this, 23, 6, image, image1, this);
|
||||
this->AddWidget(left_button);
|
||||
|
||||
build_path(datadir, "right_arrow.bmp", imagefile);
|
||||
image = SDL_LoadBMP(imagefile);
|
||||
image1 = SDL_LoadBMP(imagefile);
|
||||
|
||||
right_button = new GUI_Button(this, 166, 6, image, image1, this);
|
||||
this->AddWidget(right_button);
|
||||
|
||||
if (party->get_member_num(actor) < 0) {
|
||||
left_button->Hide();
|
||||
right_button->Hide();
|
||||
}
|
||||
cursor_tile = tile_manager->get_gump_cursor_tile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PortraitViewGump::set_actor(Actor *a) {
|
||||
actor = a;
|
||||
if (portrait_data)
|
||||
free(portrait_data);
|
||||
portrait_data = portrait->get_portrait_data(actor);
|
||||
}
|
||||
|
||||
void PortraitViewGump::left_arrow() {
|
||||
if (party->get_member_num(actor) < 0)
|
||||
return;
|
||||
uint8 party_mem_num = party->get_member_num(actor);
|
||||
if (party_mem_num > 0)
|
||||
party_mem_num--;
|
||||
else
|
||||
party_mem_num = party->get_party_size() - 1;
|
||||
|
||||
set_actor(party->get_actor(party_mem_num));
|
||||
}
|
||||
|
||||
void PortraitViewGump::right_arrow() {
|
||||
if (party->get_member_num(actor) < 0)
|
||||
return;
|
||||
set_actor(party->get_actor((party->get_member_num(actor) + 1) % party->get_party_size()));
|
||||
}
|
||||
|
||||
void PortraitViewGump::Display(bool full_redraw) {
|
||||
Common::String buf; //xxxxx\n
|
||||
//display_level_text();
|
||||
//display_spell_list_text();
|
||||
Common::Rect dst;
|
||||
dst = area;
|
||||
SDL_BlitSurface(bg_image, nullptr, surface, &dst);
|
||||
|
||||
DisplayChildren(full_redraw);
|
||||
screen->blit(area.left + 25, area.top + 17, portrait_data, 8, portrait->get_portrait_width(), portrait->get_portrait_height(), portrait->get_portrait_width(), false);
|
||||
|
||||
int w, h;
|
||||
w = font->getCenter(actor->get_name(), 138);
|
||||
|
||||
font->setColoring(0x08, 0x08, 0x08, 0x80, 0x58, 0x30, 0x00, 0x00, 0x00);
|
||||
|
||||
font->textOut(screen->get_sdl_surface(), area.left + 29 + w, area.top + 6, actor->get_name());
|
||||
|
||||
buf = Common::String::format("%d", actor->get_strength());
|
||||
font->textExtent(buf.c_str(), &w, &h);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + 170 - w, area.top + 18, buf.c_str());
|
||||
|
||||
buf = Common::String::format("%d", actor->get_dexterity());
|
||||
font->textExtent(buf.c_str(), &w, &h);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + 170 - w, area.top + 27, buf.c_str());
|
||||
|
||||
buf = Common::String::format("%d", actor->get_intelligence());
|
||||
font->textExtent(buf.c_str(), &w, &h);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + 170 - w, area.top + 36, buf.c_str());
|
||||
|
||||
font->setColoring(0x6c, 0x00, 0x00, 0xbc, 0x34, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
buf = Common::String::format("%d", actor->get_magic());
|
||||
font->textExtent(buf.c_str(), &w, &h);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + 142 - w, area.top + 55, buf.c_str());
|
||||
|
||||
buf = Common::String::format("%d", actor->get_maxmagic());
|
||||
font->textExtent(buf.c_str(), &w, &h);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + 170 - w, area.top + 55, buf.c_str());
|
||||
|
||||
font->setColoring(0x00, 0x3c, 0x70, 0x74, 0x74, 0x74, 0x00, 0x00, 0x00);
|
||||
|
||||
buf = Common::String::format("%d", actor->get_hp());
|
||||
font->textExtent(buf.c_str(), &w, &h);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + 142 - w, area.top + 64, buf.c_str());
|
||||
|
||||
buf = Common::String::format("%d", actor->get_maxhp());
|
||||
font->textExtent(buf.c_str(), &w, &h);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + 170 - w, area.top + 64, buf.c_str());
|
||||
|
||||
font->setColoring(0xa8, 0x28, 0x00, 0xa8, 0x54, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
buf = Common::String::format("%d", actor->get_level());
|
||||
font->textExtent(buf.c_str(), &w, &h);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + 142 - w, area.top + 73, buf.c_str());
|
||||
|
||||
buf = Common::String::format("%d", actor->get_exp());
|
||||
font->textExtent(buf.c_str(), &w, &h);
|
||||
font->textOut(screen->get_sdl_surface(), area.left + 170 - w, area.top + 73, buf.c_str());
|
||||
|
||||
if (show_cursor) {
|
||||
screen->blit(area.left + cursor_xoff, area.top + cursor_yoff, (const unsigned char *)cursor_tile->data, 8, 16, 16, 16, true);
|
||||
}
|
||||
|
||||
update_display = false;
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
GUI_status PortraitViewGump::set_cursor_pos(gumpCursorPos pos) {
|
||||
if (party->get_member_num(actor) < 0)
|
||||
return GUI_YUM;
|
||||
cursor_pos = pos;
|
||||
if (cursor_pos == CURSOR_CHECK) {
|
||||
cursor_xoff = 1;
|
||||
cursor_yoff = 67;
|
||||
} else if (cursor_pos == CURSOR_LEFT) {
|
||||
cursor_xoff = 18;
|
||||
cursor_yoff = 1;
|
||||
} else {
|
||||
cursor_xoff = 162;
|
||||
cursor_yoff = 1;
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status PortraitViewGump::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
//close gump and return control to Magic class for clean up.
|
||||
if (caller == gump_button) {
|
||||
Game::get_game()->get_view_manager()->close_gump(this);
|
||||
return GUI_YUM;
|
||||
} else if (caller == left_button) {
|
||||
left_arrow();
|
||||
} else if (caller == right_button) {
|
||||
right_arrow();
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status PortraitViewGump::KeyDown(const Common::KeyState &key) {
|
||||
// I was checking for numlock but probably don't need to
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
|
||||
switch (keybinder->GetActionKeyType(a)) {
|
||||
case SOUTH_WEST_KEY:
|
||||
case SOUTH_KEY:
|
||||
return set_cursor_pos(CURSOR_CHECK);
|
||||
case NORTH_KEY:
|
||||
if (cursor_pos == CURSOR_CHECK)
|
||||
return set_cursor_pos(CURSOR_LEFT);
|
||||
return GUI_YUM;
|
||||
case NORTH_WEST_KEY:
|
||||
case WEST_KEY:
|
||||
if (cursor_pos == CURSOR_RIGHT)
|
||||
return set_cursor_pos(CURSOR_LEFT);
|
||||
return set_cursor_pos(CURSOR_CHECK);
|
||||
case NORTH_EAST_KEY:
|
||||
case SOUTH_EAST_KEY:
|
||||
case EAST_KEY:
|
||||
if (cursor_pos == CURSOR_CHECK)
|
||||
return set_cursor_pos(CURSOR_LEFT);
|
||||
return set_cursor_pos(CURSOR_RIGHT);
|
||||
case DO_ACTION_KEY:
|
||||
if (cursor_pos == CURSOR_CHECK)
|
||||
Game::get_game()->get_view_manager()->close_gump(this);
|
||||
else if (cursor_pos == CURSOR_LEFT)
|
||||
left_arrow();
|
||||
else
|
||||
right_arrow();
|
||||
return GUI_YUM;
|
||||
case NEXT_PARTY_MEMBER_KEY:
|
||||
right_arrow();
|
||||
return GUI_YUM;
|
||||
case PREVIOUS_PARTY_MEMBER_KEY:
|
||||
left_arrow();
|
||||
return GUI_YUM;
|
||||
case HOME_KEY:
|
||||
if (party->get_member_num(actor) >= 0)
|
||||
set_actor(party->get_actor(0));
|
||||
return GUI_YUM;
|
||||
case END_KEY:
|
||||
if (party->get_member_num(actor) >= 0)
|
||||
set_actor(party->get_actor(party->get_party_size() - 1));
|
||||
return GUI_YUM;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status PortraitViewGump::MouseWheel(sint32 x, sint32 y) {
|
||||
if (y > 0) {
|
||||
left_arrow();
|
||||
} else if (y < 0) {
|
||||
right_arrow();
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status PortraitViewGump::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
return DraggableView::MouseDown(x, y, button);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
78
engines/ultima/nuvie/views/portrait_view_gump.h
Normal file
78
engines/ultima/nuvie/views/portrait_view_gump.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* 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 NUVIE_VIEWS_PORTRAIT_VIEW_GUMP_H
|
||||
#define NUVIE_VIEWS_PORTRAIT_VIEW_GUMP_H
|
||||
|
||||
#include "ultima/nuvie/views/draggable_view.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class ObjManager;
|
||||
class Screen;
|
||||
class Actor;
|
||||
class Font;
|
||||
class U6Bmp;
|
||||
class Portrait;
|
||||
|
||||
class PortraitViewGump : public DraggableView {
|
||||
|
||||
GUI_Button *gump_button;
|
||||
|
||||
GUI_Font *font;
|
||||
|
||||
Portrait *portrait;
|
||||
unsigned char *portrait_data;
|
||||
Actor *actor;
|
||||
bool show_cursor;
|
||||
const Tile *cursor_tile;
|
||||
gumpCursorPos cursor_pos;
|
||||
uint8 cursor_xoff, cursor_yoff;
|
||||
|
||||
public:
|
||||
PortraitViewGump(const Configuration *cfg);
|
||||
~PortraitViewGump() override;
|
||||
|
||||
bool init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om, Portrait *por, Actor *a);
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
|
||||
protected:
|
||||
|
||||
void set_actor(Actor *a);
|
||||
void left_arrow();
|
||||
void right_arrow();
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
GUI_status set_cursor_pos(gumpCursorPos pos);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
121
engines/ultima/nuvie/views/scroll_view_gump.cpp
Normal file
121
engines/ultima/nuvie/views/scroll_view_gump.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/fonts/font_manager.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/views/scroll_widget_gump.h"
|
||||
#include "ultima/nuvie/views/scroll_view_gump.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static const int SIGN_BG_W = (SCROLLWIDGETGUMP_W + 16);
|
||||
static const int SIGN_BG_H = (SCROLLWIDGETGUMP_H + 16);
|
||||
|
||||
ScrollViewGump::ScrollViewGump(const Configuration *cfg) : DraggableView(cfg), scroll_widget(nullptr) {
|
||||
}
|
||||
|
||||
ScrollViewGump::~ScrollViewGump() {
|
||||
|
||||
}
|
||||
|
||||
bool ScrollViewGump::init(Screen *tmp_screen, void *view_manager, Font *f, Party *p, TileManager *tm, ObjManager *om, Std::string text_string) {
|
||||
uint16 x_off = Game::get_game()->get_game_x_offset();
|
||||
uint16 y_off = Game::get_game()->get_game_y_offset();
|
||||
|
||||
x_off += (Game::get_game()->get_game_width() - SIGN_BG_W) / 2;
|
||||
y_off += (Game::get_game()->get_game_height() - SIGN_BG_H) / 2;
|
||||
|
||||
View::init(x_off, y_off, f, p, tm, om);
|
||||
SetRect(area.left, area.top, SIGN_BG_W, SIGN_BG_H);
|
||||
/*
|
||||
Std::string datadir = GUI::get_gui()->get_data_dir();
|
||||
Std::string imagefile;
|
||||
Std::string path;
|
||||
|
||||
build_path(datadir, "images", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "gumps", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "sign", path);
|
||||
datadir = path;
|
||||
|
||||
build_path(datadir, "sign_bg.bmp", imagefile);
|
||||
bg_image = SDL_LoadBMP(imagefile.c_str());
|
||||
|
||||
set_bg_color_key(0, 0x70, 0xfc);
|
||||
*/
|
||||
scroll_widget = new ScrollWidgetGump(config, tmp_screen);
|
||||
scroll_widget->init(config, Game::get_game()->get_font_manager()->get_conv_font());
|
||||
|
||||
scroll_widget->display_string(text_string);
|
||||
|
||||
AddWidget(scroll_widget);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ScrollViewGump::Display(bool full_redraw) {
|
||||
/*
|
||||
Common::Rect dst;
|
||||
dst = area;
|
||||
SDL_BlitSurface(bg_image, nullptr, surface, &dst);
|
||||
*/
|
||||
screen->fill(26, area.left, area.top, area.width(), area.height());
|
||||
DisplayChildren(full_redraw);
|
||||
|
||||
//font->textOut(screen->get_sdl_surface(), area.left + 29, area.top + 6, "This is a test sign");
|
||||
|
||||
//font->drawString(screen, sign_text, strlen(sign_text), area.left + (area.width() - font->getStringWidth(sign_text)) / 2, area.top + (area.height() - 19) / 2, 0, 0);
|
||||
update_display = false;
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GUI_status ScrollViewGump::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
if (scroll_widget->MouseDown(x, y, button) != GUI_YUM) {
|
||||
Game::get_game()->get_view_manager()->close_gump(this);
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status ScrollViewGump::KeyDown(const Common::KeyState &key) {
|
||||
if (scroll_widget->KeyDown(key) != GUI_YUM) {
|
||||
Game::get_game()->get_view_manager()->close_gump(this);
|
||||
}
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status ScrollViewGump::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
Game::get_game()->get_view_manager()->close_gump(this);
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
60
engines/ultima/nuvie/views/scroll_view_gump.h
Normal file
60
engines/ultima/nuvie/views/scroll_view_gump.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* 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 NUVIE_VIEWS_SCROLL_VIEW_GUMP_H
|
||||
#define NUVIE_VIEWS_SCROLL_VIEW_GUMP_H
|
||||
|
||||
#include "ultima/nuvie/views/draggable_view.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class ObjManager;
|
||||
class Screen;
|
||||
class ScrollWidgetGump;
|
||||
|
||||
class ScrollViewGump : public DraggableView {
|
||||
|
||||
ScrollWidgetGump *scroll_widget;
|
||||
|
||||
public:
|
||||
ScrollViewGump(const Configuration *cfg);
|
||||
~ScrollViewGump() override;
|
||||
|
||||
bool init(Screen *tmp_screen, void *view_manager, Font *f, Party *p, TileManager *tm, ObjManager *om, Std::string text_string);
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
307
engines/ultima/nuvie/views/scroll_widget_gump.cpp
Normal file
307
engines/ultima/nuvie/views/scroll_widget_gump.cpp
Normal file
@@ -0,0 +1,307 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/shared/std/string.h"
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/fonts/font_manager.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/screen/game_palette.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/portraits/portrait.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/fonts/conv_font.h"
|
||||
#include "ultima/nuvie/views/scroll_widget_gump.h"
|
||||
#include "ultima/nuvie/actors/actor_manager.h"
|
||||
#include "ultima/nuvie/core/timed_event.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
// ScrollWidgetGump Class
|
||||
|
||||
ScrollWidgetGump::ScrollWidgetGump(const Configuration *cfg, Screen *s) :
|
||||
arrow_up_rect(SCROLLWIDGETGUMP_W - 8 - 1, 4 + 1,
|
||||
SCROLLWIDGETGUMP_W - 8 - 1 + 7, 4 + 1 + 5),
|
||||
arrow_down_rect(SCROLLWIDGETGUMP_W - 8 - 1, SCROLLWIDGETGUMP_H - 8 + 3,
|
||||
SCROLLWIDGETGUMP_W - 8 - 1 + 7, SCROLLWIDGETGUMP_H - 8 + 3 + 5) {
|
||||
drop_target = false; //we don't participate in drag and drop.
|
||||
|
||||
font_normal = Game::get_game()->get_font_manager()->get_conv_font();
|
||||
|
||||
font_garg = Game::get_game()->get_font_manager()->get_conv_garg_font();
|
||||
|
||||
init(cfg, font_normal);
|
||||
|
||||
font_color = 0; // black
|
||||
font_highlight = FONT_COLOR_U6_HIGHLIGHT;
|
||||
|
||||
scroll_width = 40;
|
||||
scroll_height = 10;
|
||||
|
||||
show_up_arrow = false;
|
||||
show_down_arrow = false;
|
||||
|
||||
GUI_Widget::Init(nullptr, 0, 0, SCROLLWIDGETGUMP_W, SCROLLWIDGETGUMP_H);
|
||||
|
||||
add_new_line(); //MsgScroll requires a line to start.
|
||||
|
||||
position = 0;
|
||||
// ignore_page_breaks = true;
|
||||
}
|
||||
|
||||
ScrollWidgetGump::~ScrollWidgetGump() {
|
||||
// ignore_page_breaks = false;
|
||||
}
|
||||
|
||||
void ScrollWidgetGump::set_font(uint8 font_type) {
|
||||
if (font_type == NUVIE_FONT_NORMAL) {
|
||||
font = font_normal;
|
||||
} else {
|
||||
font = font_garg;
|
||||
}
|
||||
}
|
||||
|
||||
bool ScrollWidgetGump::is_garg_font() {
|
||||
return (font == font_garg);
|
||||
}
|
||||
|
||||
bool ScrollWidgetGump::can_fit_token_on_msgline(MsgLine *msg_line, MsgText *token) {
|
||||
if (msg_line->get_display_width() + token->getDisplayWidth() > SCROLLWIDGETGUMP_W - 8 - 8) {
|
||||
return false; //token doesn't fit on the current line.
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScrollWidgetGump::parse_token(MsgText *token) {
|
||||
if (token->s[0] == '*') // We don't want page breaks in the scroll widget.
|
||||
return true;
|
||||
|
||||
return MsgScroll::parse_token(token);
|
||||
}
|
||||
|
||||
void ScrollWidgetGump::display_string(const Std::string &s) {
|
||||
MsgScroll::display_string(s);
|
||||
update_arrows();
|
||||
}
|
||||
|
||||
void ScrollWidgetGump::Display(bool full_redraw) {
|
||||
MsgText *token;
|
||||
|
||||
uint16 y = area.top + 4;
|
||||
Std::list<MsgLine *>::iterator iter;
|
||||
|
||||
if (show_up_arrow) {
|
||||
font_normal->drawChar(screen, FONT_UP_ARROW_CHAR, area.left + SCROLLWIDGETGUMP_W - 8, area.top + 4);
|
||||
}
|
||||
|
||||
if (show_down_arrow) {
|
||||
font_normal->drawChar(screen, FONT_DOWN_ARROW_CHAR, area.left + SCROLLWIDGETGUMP_W - 8, area.top + SCROLLWIDGETGUMP_H - 8);
|
||||
}
|
||||
|
||||
iter = msg_buf.begin();
|
||||
for (uint16 i = 0; i < position && iter != msg_buf.end(); i++)
|
||||
iter++;
|
||||
|
||||
for (uint16 i = 0; i < scroll_height && iter != msg_buf.end(); i++, iter++) {
|
||||
MsgLine *msg_line = *iter;
|
||||
Std::list<MsgText *>::iterator iter1;
|
||||
|
||||
iter1 = msg_line->text.begin();
|
||||
|
||||
//if not last record or if last record is not an empty line.
|
||||
if (i + position < ((int)msg_buf.size() - 1) || (iter1 != msg_line->text.end() && ((*iter)->total_length != 0))) {
|
||||
//screen->fill(26, area.left, y + (i==0?-4:4), scroll_width * 7 + 8, (i==0?18:10));
|
||||
|
||||
|
||||
for (uint16 total_length = 0; iter1 != msg_line->text.end() ; iter1++) {
|
||||
token = *iter1;
|
||||
|
||||
total_length += token->font->drawString(screen, token->s.c_str(), area.left + 4 + 4 + total_length, y + 4, font_color, font_highlight); //FIX for hardcoded font height
|
||||
}
|
||||
y += 10;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
GUI_status ScrollWidgetGump::KeyDown(const Common::KeyState &key) {
|
||||
ScrollEventType event = SCROLL_ESCAPE;
|
||||
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
|
||||
switch (keybinder->GetActionKeyType(a)) {
|
||||
case MSGSCROLL_DOWN_KEY:
|
||||
event = SCROLL_PAGE_DOWN;
|
||||
break;
|
||||
case SOUTH_KEY:
|
||||
event = SCROLL_DOWN;
|
||||
break;
|
||||
case MSGSCROLL_UP_KEY:
|
||||
event = SCROLL_PAGE_UP;
|
||||
break;
|
||||
case NORTH_KEY:
|
||||
event = SCROLL_UP;
|
||||
break;
|
||||
case HOME_KEY:
|
||||
event = SCROLL_TO_BEGINNING;
|
||||
break;
|
||||
case END_KEY:
|
||||
event = SCROLL_TO_END;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
if (scroll_movement_event(event) == GUI_YUM)
|
||||
return GUI_YUM;
|
||||
|
||||
return MsgScroll::KeyDown(key);
|
||||
}
|
||||
|
||||
GUI_status ScrollWidgetGump::MouseWheel(sint32 x, sint32 y) {
|
||||
ScrollEventType event = SCROLL_ESCAPE;
|
||||
|
||||
if (y > 0)
|
||||
event = SCROLL_UP;
|
||||
if (y < 0)
|
||||
event = SCROLL_DOWN;
|
||||
|
||||
return scroll_movement_event(event);
|
||||
}
|
||||
|
||||
GUI_status ScrollWidgetGump::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
ScrollEventType event = SCROLL_ESCAPE;
|
||||
|
||||
switch (button) {
|
||||
case Events::BUTTON_LEFT : {
|
||||
x -= area.left;
|
||||
y -= area.top;
|
||||
if (HitRect(x, y, arrow_up_rect))
|
||||
event = SCROLL_UP;
|
||||
else if (HitRect(x, y, arrow_down_rect))
|
||||
event = SCROLL_DOWN;
|
||||
// FIXME - uncomment when we get a checkmark
|
||||
// else if(show_down_arrow || show_up_arrow) // don't close if scrollable
|
||||
// return GUI_YUM;
|
||||
break;
|
||||
}
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
return scroll_movement_event(event);
|
||||
}
|
||||
|
||||
GUI_status ScrollWidgetGump::scroll_movement_event(ScrollEventType event) {
|
||||
switch (event) {
|
||||
case SCROLL_UP :
|
||||
if (position > 0) {
|
||||
//timer = new TimedCallback(this, nullptr, 2000);
|
||||
position--;
|
||||
update_arrows();
|
||||
//grab_focus();
|
||||
}
|
||||
return GUI_YUM;
|
||||
|
||||
case SCROLL_DOWN :
|
||||
//timer = new TimedCallback(this, nullptr, 2000);
|
||||
if (page_break && position + scroll_height >= (int)msg_buf.size()) {
|
||||
if (position + scroll_height == (int)msg_buf.size()) // break was just off the page so advance text
|
||||
position++;
|
||||
process_page_break();
|
||||
update_arrows();
|
||||
} else if (position + scroll_height < (int)msg_buf.size()) {
|
||||
position++;
|
||||
update_arrows();
|
||||
}
|
||||
return GUI_YUM;
|
||||
case SCROLL_PAGE_UP:
|
||||
if (position > 0) {
|
||||
position = position > scroll_height ? position - scroll_height : 0;
|
||||
update_arrows();
|
||||
}
|
||||
return GUI_YUM;
|
||||
case SCROLL_PAGE_DOWN:
|
||||
if (position + scroll_height < (int)msg_buf.size() || page_break) {
|
||||
if (position + scroll_height >= (int)msg_buf.size())
|
||||
position = (int)msg_buf.size();
|
||||
else {
|
||||
position += scroll_height;
|
||||
update_arrows();
|
||||
return GUI_YUM;
|
||||
}
|
||||
if (page_break) { // we didn't have enough text showing to fill out the current page.
|
||||
position = msg_buf.size();
|
||||
process_page_break();
|
||||
}
|
||||
update_arrows();
|
||||
}
|
||||
return GUI_YUM;
|
||||
case SCROLL_TO_BEGINNING :
|
||||
if (position > 0) {
|
||||
position = 0;
|
||||
update_arrows();
|
||||
}
|
||||
return GUI_YUM;
|
||||
case SCROLL_TO_END :
|
||||
if (position + scroll_height < (int)msg_buf.size() || page_break) {
|
||||
while (position + scroll_height < (int)msg_buf.size() || page_break) {
|
||||
if (page_break)
|
||||
process_page_break();
|
||||
else // added else just in case noting is added to the buffer
|
||||
position++;
|
||||
}
|
||||
update_arrows();
|
||||
}
|
||||
return GUI_YUM;
|
||||
default :
|
||||
//release_focus();
|
||||
//new TimedCallback(this, nullptr, 50);
|
||||
break;
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
void ScrollWidgetGump::update_arrows() {
|
||||
if (position == 0) {
|
||||
show_up_arrow = false;
|
||||
} else {
|
||||
show_up_arrow = true;
|
||||
}
|
||||
|
||||
if (position + scroll_height < (int)msg_buf.size() || page_break) {
|
||||
show_down_arrow = true;
|
||||
} else {
|
||||
show_down_arrow = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
119
engines/ultima/nuvie/views/scroll_widget_gump.h
Normal file
119
engines/ultima/nuvie/views/scroll_widget_gump.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/* 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 NUVIE_VIEWS_SCROLL_WIDGET_GUMP_H
|
||||
#define NUVIE_VIEWS_SCROLL_WIDGET_GUMP_H
|
||||
|
||||
#include "ultima/nuvie/misc/call_back.h"
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/shared/std/containers.h"
|
||||
#include "ultima/shared/std/string.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
using Std::list;
|
||||
|
||||
|
||||
class Configuration;
|
||||
class Actor;
|
||||
class CallBack;
|
||||
|
||||
typedef enum {
|
||||
SCROLL_UP,
|
||||
SCROLL_DOWN,
|
||||
SCROLL_PAGE_UP,
|
||||
SCROLL_PAGE_DOWN,
|
||||
SCROLL_ESCAPE,
|
||||
SCROLL_TO_BEGINNING,
|
||||
SCROLL_TO_END
|
||||
} ScrollEventType;
|
||||
|
||||
static const int SCROLLWIDGETGUMP_W = 200;
|
||||
static const int SCROLLWIDGETGUMP_H = 100;
|
||||
|
||||
class ScrollWidgetGump: public MsgScroll {
|
||||
|
||||
Font *font_normal;
|
||||
Font *font_garg;
|
||||
|
||||
uint8 font_color;
|
||||
uint8 font_highlight;
|
||||
uint16 position;
|
||||
|
||||
Std::string trailing_whitespace;
|
||||
|
||||
bool show_up_arrow;
|
||||
bool show_down_arrow;
|
||||
|
||||
public:
|
||||
|
||||
ScrollWidgetGump(const Configuration *cfg, Screen *s);
|
||||
~ScrollWidgetGump() override;
|
||||
|
||||
bool parse_token(MsgText *token) override;
|
||||
|
||||
bool can_display_prompt() const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
void display_prompt() override {}
|
||||
void display_string(const Std::string &s);
|
||||
void display_string(const Std::string &s, Font *f, bool include_on_map_window) override {
|
||||
return MsgScroll::display_string(s, f, include_on_map_window);
|
||||
}
|
||||
|
||||
void set_font(uint8 font_type) override;
|
||||
bool is_garg_font() override;
|
||||
|
||||
bool can_fit_token_on_msgline(MsgLine *msg_line, MsgText *token) override;
|
||||
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM; // otherwise we do Msgscroll::MouseUp
|
||||
}
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
|
||||
void move_scroll_down() override {
|
||||
scroll_movement_event(SCROLL_DOWN);
|
||||
}
|
||||
void move_scroll_up() override {
|
||||
scroll_movement_event(SCROLL_UP);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
const Common::Rect arrow_up_rect;
|
||||
const Common::Rect arrow_down_rect;
|
||||
|
||||
GUI_status scroll_movement_event(ScrollEventType event);
|
||||
void update_arrows();
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
131
engines/ultima/nuvie/views/sign_view_gump.cpp
Normal file
131
engines/ultima/nuvie/views/sign_view_gump.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/fonts/bmp_font.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/views/sign_view_gump.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static const int SIGN_BG_W = 246;
|
||||
static const int SIGN_BG_H = 101;
|
||||
|
||||
SignViewGump::SignViewGump(const Configuration *cfg) : DraggableView(cfg), sign_text(nullptr) {
|
||||
font = new BMPFont();
|
||||
|
||||
Common::Path datadir = GUI::get_gui()->get_data_dir();
|
||||
Common::Path imagefile;
|
||||
Common::Path path;
|
||||
|
||||
build_path(datadir, "images", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "gumps", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "sign", path);
|
||||
datadir = path;
|
||||
|
||||
build_path(datadir, "sign_font", imagefile);
|
||||
|
||||
((BMPFont *)font)->init(imagefile, true);
|
||||
}
|
||||
|
||||
SignViewGump::~SignViewGump() {
|
||||
if (font)
|
||||
delete font;
|
||||
|
||||
if (sign_text) {
|
||||
free(sign_text);
|
||||
}
|
||||
}
|
||||
|
||||
bool SignViewGump::init(Screen *tmp_screen, void *view_manager, Font *f, Party *p, TileManager *tm, ObjManager *om, const char *text_string, uint16 length) {
|
||||
uint16 x_off = Game::get_game()->get_game_x_offset();
|
||||
uint16 y_off = Game::get_game()->get_game_y_offset();
|
||||
|
||||
x_off += (Game::get_game()->get_game_width() - SIGN_BG_W) / 2;
|
||||
y_off += (Game::get_game()->get_game_height() - SIGN_BG_H) / 2;
|
||||
|
||||
View::init(x_off, y_off, f, p, tm, om);
|
||||
SetRect(area.left, area.top, SIGN_BG_W, SIGN_BG_H);
|
||||
|
||||
Common::Path datadir = GUI::get_gui()->get_data_dir();
|
||||
Common::Path imagefile;
|
||||
Common::Path path;
|
||||
|
||||
build_path(datadir, "images", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "gumps", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "sign", path);
|
||||
datadir = path;
|
||||
|
||||
build_path(datadir, "sign_bg.bmp", imagefile);
|
||||
bg_image = SDL_LoadBMP(imagefile);
|
||||
|
||||
set_bg_color_key(0, 0x70, 0xfc);
|
||||
|
||||
sign_text = (char *)malloc(length + 1);
|
||||
memcpy(sign_text, text_string, length);
|
||||
sign_text[length] = '\0';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SignViewGump::Display(bool full_redraw) {
|
||||
Common::Rect dst;
|
||||
dst = area;
|
||||
SDL_BlitSurface(bg_image, nullptr, surface, &dst);
|
||||
|
||||
DisplayChildren(full_redraw);
|
||||
|
||||
//font->textOut(screen->get_sdl_surface(), area.left + 29, area.top + 6, "This is a test sign");
|
||||
|
||||
font->drawString(screen, sign_text, strlen(sign_text), area.left + (area.width() - font->getStringWidth(sign_text)) / 2, area.top + (area.height() - 19) / 2, 0, 0);
|
||||
update_display = false;
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GUI_status SignViewGump::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
Game::get_game()->get_view_manager()->close_gump(this);
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status SignViewGump::KeyDown(const Common::KeyState &key) {
|
||||
Game::get_game()->get_view_manager()->close_gump(this);
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status SignViewGump::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
Game::get_game()->get_view_manager()->close_gump(this);
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
59
engines/ultima/nuvie/views/sign_view_gump.h
Normal file
59
engines/ultima/nuvie/views/sign_view_gump.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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 NUVIE_VIEWS_SIGN_VIEW_GUMP_H
|
||||
#define NUVIE_VIEWS_SIGN_VIEW_GUMP_H
|
||||
|
||||
#include "ultima/nuvie/views/draggable_view.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class ObjManager;
|
||||
class Screen;
|
||||
class Font;
|
||||
//class BMPFont;
|
||||
|
||||
class SignViewGump : public DraggableView {
|
||||
|
||||
Font *font;
|
||||
char *sign_text;
|
||||
|
||||
public:
|
||||
SignViewGump(const Configuration *cfg);
|
||||
~SignViewGump() override;
|
||||
|
||||
bool init(Screen *tmp_screen, void *view_manager, Font *f, Party *p, TileManager *tm, ObjManager *om, const char *text_string, uint16 length);
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
540
engines/ultima/nuvie/views/spell_view.cpp
Normal file
540
engines/ultima/nuvie/views/spell_view.cpp
Normal file
@@ -0,0 +1,540 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
#include "ultima/nuvie/misc/u6_llist.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/files/u6_bmp.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
#include "ultima/nuvie/views/doll_widget.h"
|
||||
#include "ultima/nuvie/views/inventory_widget.h"
|
||||
#include "ultima/nuvie/views/spell_view.h"
|
||||
#include "ultima/nuvie/core/party.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/usecode/usecode.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/script/script.h"
|
||||
#include "ultima/nuvie/core/u6_objects.h"
|
||||
#include "ultima/nuvie/core/magic.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static const char circle_num_tbl[][8] = {"1ST", "2ND", "3RD", "4TH", "5TH", "6TH", "7TH", "8TH"};
|
||||
static const int obj_n_reagent[8] = {OBJ_U6_MANDRAKE_ROOT, OBJ_U6_NIGHTSHADE, OBJ_U6_BLACK_PEARL, OBJ_U6_BLOOD_MOSS, OBJ_U6_SPIDER_SILK, OBJ_U6_GARLIC, OBJ_U6_GINSENG, OBJ_U6_SULFUROUS_ASH};
|
||||
|
||||
static const int NEWMAGIC_BMP_W = 144;
|
||||
static const int NEWMAGIC_BMP_H = 82;
|
||||
|
||||
SpellView::SpellView(const Configuration *cfg) : DraggableView(cfg), spell_container(nullptr),
|
||||
background(nullptr), level(1), all_spells_mode(false), spell_num(0),
|
||||
event_mode(false), num_spells_per_page(8), caster(nullptr) {
|
||||
}
|
||||
|
||||
SpellView::~SpellView() {
|
||||
if (background) {
|
||||
delete background;
|
||||
}
|
||||
}
|
||||
|
||||
bool SpellView::init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om) {
|
||||
View::init(x, y, f, p, tm, om);
|
||||
|
||||
SetRect(area.left, area.top, NEWMAGIC_BMP_W, NEWMAGIC_BMP_H + 16);
|
||||
Common::Path filename;
|
||||
|
||||
config_get_path(config, "newmagic.bmp", filename);
|
||||
background = new U6Bmp();
|
||||
if (background->load(filename) == false)
|
||||
return false;
|
||||
|
||||
add_command_icons(tmp_screen, view_manager);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SpellView::PlaceOnScreen(Screen *s, GUI_DragManager *dm, int x, int y) {
|
||||
GUI_Widget::PlaceOnScreen(s, dm, x, y);
|
||||
}
|
||||
|
||||
void SpellView::set_spell_caster(Actor *actor, Obj *s_container, bool eventMode) {
|
||||
caster = actor;
|
||||
spell_container = s_container;
|
||||
event_mode = eventMode;
|
||||
|
||||
for (int shift = 0; shift < 8; shift++) {
|
||||
caster_reagents[shift] = caster->inventory_count_object(obj_n_reagent[shift]);
|
||||
}
|
||||
|
||||
level = (spell_container->quality / 16) + 1;
|
||||
spell_num = spell_container->quality - (16 * level);
|
||||
|
||||
|
||||
if (Game::get_game()->has_unlimited_casting() || spell_container->find_in_container(OBJ_U6_SPELL, MAGIC_ALL_SPELLS, OBJ_MATCH_QUALITY))
|
||||
all_spells_mode = true;
|
||||
else
|
||||
all_spells_mode = false;
|
||||
|
||||
fill_cur_spell_list();
|
||||
update_buttons();
|
||||
Game::get_game()->set_mouse_pointer(1); // crosshairs
|
||||
}
|
||||
|
||||
void SpellView::Display(bool full_redraw) {
|
||||
if (full_redraw || update_display) {
|
||||
screen->fill(bg_color, area.left, area.top + NEWMAGIC_BMP_H, area.width(), area.height() - NEWMAGIC_BMP_H);
|
||||
|
||||
screen->blit(area.left, area.top, background->get_data(), 8, NEWMAGIC_BMP_W, NEWMAGIC_BMP_H, NEWMAGIC_BMP_W, true);
|
||||
}
|
||||
|
||||
display_level_text();
|
||||
display_spell_list_text();
|
||||
|
||||
DisplayChildren(full_redraw);
|
||||
#if 1 // FIXME: This shouldn't need to be in the loop
|
||||
update_buttons(); // It doesn't seem to hurt speed though
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
#else
|
||||
if (full_redraw || update_display) {
|
||||
update_display = false;
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8 SpellView::fill_cur_spell_list() {
|
||||
Magic *m = Game::get_game()->get_magic();
|
||||
int j = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
cur_spells[i] = -1;
|
||||
|
||||
if (m->get_spell((level - 1) * 16 + i) != nullptr && (all_spells_mode || spell_container->find_in_container(OBJ_U6_SPELL, (level - 1) * 16 + i, OBJ_MATCH_QUALITY)))
|
||||
cur_spells[j++] = (level - 1) * 16 + i;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
sint8 SpellView::get_selected_index() const {
|
||||
for (uint8 i = 0; i < 16; i++) {
|
||||
if (cur_spells[i] == spell_container->quality) {
|
||||
return (sint8)i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SpellView::set_prev_level() {
|
||||
if (level == 1)
|
||||
return;
|
||||
|
||||
uint8 old_level = level;
|
||||
|
||||
|
||||
uint8 num_spells = 0;
|
||||
for (; num_spells == 0;) {
|
||||
level--;
|
||||
|
||||
if (level == 0)
|
||||
break;
|
||||
|
||||
num_spells = fill_cur_spell_list();
|
||||
}
|
||||
|
||||
if (num_spells == 0) {
|
||||
level = old_level;
|
||||
fill_cur_spell_list();
|
||||
}
|
||||
|
||||
if (num_spells > num_spells_per_page)
|
||||
spell_container->quality = cur_spells[num_spells_per_page];
|
||||
else {
|
||||
spell_container->quality = cur_spells[0];
|
||||
}
|
||||
}
|
||||
|
||||
void SpellView::set_next_level() {
|
||||
if (level == 8)
|
||||
return;
|
||||
|
||||
uint8 old_level = level;
|
||||
|
||||
|
||||
uint8 num_spells = 0;
|
||||
for (; num_spells == 0;) {
|
||||
level++;
|
||||
|
||||
if (level == 9)
|
||||
break;
|
||||
|
||||
num_spells = fill_cur_spell_list();
|
||||
}
|
||||
|
||||
if (num_spells == 0) {
|
||||
level = old_level;
|
||||
fill_cur_spell_list();
|
||||
} else
|
||||
spell_container->quality = cur_spells[0];
|
||||
}
|
||||
|
||||
void SpellView::move_left() {
|
||||
sint8 index = get_selected_index();
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
|
||||
if (index >= num_spells_per_page) {
|
||||
spell_container->quality = cur_spells[0];
|
||||
} else {
|
||||
set_prev_level();
|
||||
}
|
||||
|
||||
update_buttons();
|
||||
update_display = true;
|
||||
}
|
||||
|
||||
void SpellView::move_right() {
|
||||
sint8 index = get_selected_index();
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
|
||||
if (index >= num_spells_per_page || cur_spells[num_spells_per_page] == -1) {
|
||||
set_next_level();
|
||||
} else {
|
||||
spell_container->quality = cur_spells[num_spells_per_page];
|
||||
}
|
||||
|
||||
update_buttons();
|
||||
update_display = true;
|
||||
}
|
||||
|
||||
GUI_status SpellView::move_up() {
|
||||
sint8 index = get_selected_index();
|
||||
|
||||
if (index > 0 && index != num_spells_per_page) {
|
||||
spell_container->quality = cur_spells[index - 1];
|
||||
update_display = true;
|
||||
} else
|
||||
move_left();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status SpellView::move_down() {
|
||||
sint8 index = get_selected_index();
|
||||
|
||||
if (index != -1 && index < 15 && index != (num_spells_per_page - 1)) {
|
||||
if (cur_spells[index + 1] != -1) {
|
||||
spell_container->quality = cur_spells[index + 1];
|
||||
update_display = true;
|
||||
} else
|
||||
move_right();
|
||||
} else
|
||||
move_right();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void SpellView::display_level_text() {
|
||||
font->drawString(screen, circle_num_tbl[level - 1], area.left + 96 + 8, area.top + NEWMAGIC_BMP_H);
|
||||
font->drawString(screen, "level", area.left + 96, area.top + NEWMAGIC_BMP_H + 8);
|
||||
return;
|
||||
}
|
||||
|
||||
void SpellView::display_spell_list_text() {
|
||||
Magic *m = Game::get_game()->get_magic();
|
||||
|
||||
sint8 index = get_selected_index();
|
||||
|
||||
if (index >= num_spells_per_page)
|
||||
index = num_spells_per_page;
|
||||
else
|
||||
index = 0;
|
||||
|
||||
for (uint8 i = 0; i < num_spells_per_page; i++) {
|
||||
sint16 spellNum = cur_spells[i + index];
|
||||
if (spellNum != -1) {
|
||||
Spell *spell = m->get_spell((uint8)spellNum);
|
||||
|
||||
display_spell_text(spell, i, spell_container->quality);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpellView::display_spell_text(Spell *spell, uint16 line_num, uint8 selected_spell) {
|
||||
line_num++;
|
||||
|
||||
font->drawString(screen, spell->name, area.left + 16, area.top + (line_num * 8));
|
||||
font->drawString(screen, Common::String::format("%d", get_available_spell_count(spell)).c_str(), area.left + NEWMAGIC_BMP_W - 24, area.top + (line_num * 8));
|
||||
|
||||
if (spell->num == selected_spell)
|
||||
font->drawChar(screen, 26, area.left + 8, area.top + (line_num * 8));
|
||||
}
|
||||
|
||||
uint16 SpellView::get_available_spell_count(const Spell *s) const {
|
||||
if (s->reagents == 0) // Help and Armageddon
|
||||
return 1;
|
||||
if (Game::get_game()->has_unlimited_casting())
|
||||
return 99;
|
||||
sint32 min_reagents = -1;
|
||||
for (int shift = 0; shift < 8; shift++) {
|
||||
if (1 << shift & s->reagents) {
|
||||
if (min_reagents == -1 || caster_reagents[shift] < min_reagents)
|
||||
min_reagents = caster_reagents[shift];
|
||||
}
|
||||
}
|
||||
|
||||
if (min_reagents == -1)
|
||||
min_reagents = 0;
|
||||
|
||||
return (uint16)min_reagents;
|
||||
}
|
||||
|
||||
void SpellView::add_command_icons(Screen *tmp_screen, void *view_manager) {
|
||||
Tile *tile;
|
||||
Graphics::ManagedSurface *button_image;
|
||||
Graphics::ManagedSurface *button_image2;
|
||||
|
||||
tile = tile_manager->get_tile(412); //left arrow icon
|
||||
button_image = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
button_image2 = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
left_button = new GUI_Button(this, 2 * 16, NEWMAGIC_BMP_H, button_image, button_image2, this);
|
||||
this->AddWidget(left_button);
|
||||
|
||||
tile = tile_manager->get_tile(413); //right arrow icon
|
||||
button_image = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
button_image2 = tmp_screen->create_sdl_surface_from(tile->data, 8, 16, 16, 16);
|
||||
right_button = new GUI_Button(this, 3 * 16, NEWMAGIC_BMP_H, button_image, button_image2, this);
|
||||
this->AddWidget(right_button);
|
||||
}
|
||||
|
||||
void SpellView::event_mode_select_spell() {
|
||||
sint16 spellNum = get_selected_spell();
|
||||
Game::get_game()->get_event()->select_spell_num(spellNum);
|
||||
release_focus();
|
||||
}
|
||||
|
||||
/* Move the cursor around
|
||||
*/
|
||||
GUI_status SpellView::KeyDown(const Common::KeyState &key) {
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
|
||||
switch (keybinder->GetActionKeyType(a)) {
|
||||
case NORTH_KEY:
|
||||
return move_up();
|
||||
case SOUTH_KEY:
|
||||
return move_down();
|
||||
case WEST_KEY:
|
||||
case PREVIOUS_PARTY_MEMBER_KEY:
|
||||
move_left();
|
||||
break;
|
||||
case EAST_KEY:
|
||||
case NEXT_PARTY_MEMBER_KEY:
|
||||
move_right();
|
||||
break;
|
||||
case HOME_KEY:
|
||||
// TODO - add going to first viable page
|
||||
break;
|
||||
case END_KEY:
|
||||
// TODO - add going to last viable page
|
||||
break;
|
||||
case DO_ACTION_KEY:
|
||||
if (Game::get_game()->get_event()->is_looking_at_spellbook()) {
|
||||
show_spell_description();
|
||||
return GUI_YUM;
|
||||
}
|
||||
if (event_mode) {
|
||||
event_mode_select_spell();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
case CANCEL_ACTION_KEY:
|
||||
return cancel_spell();
|
||||
case TOGGLE_CURSOR_KEY :
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return GUI_PASS;
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status SpellView::cancel_spell() {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
if (event->is_looking_at_spellbook()) {
|
||||
close_look();
|
||||
return GUI_YUM;
|
||||
} else if (event_mode) {
|
||||
event->select_spell_num(-1);
|
||||
release_focus();
|
||||
return GUI_YUM;
|
||||
}
|
||||
event->set_mode(CAST_MODE);
|
||||
event->cancelAction();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status SpellView::MouseWheel(sint32 x, sint32 y) {
|
||||
if (y > 0)
|
||||
return move_up();
|
||||
if (y < 0)
|
||||
return move_down();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status SpellView::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
y -= area.top;
|
||||
x -= area.left;
|
||||
Events *event = Game::get_game()->get_event();
|
||||
bool selecting_spell_target, canceling_spell, doing_nothing;
|
||||
if (Game::get_game()->is_original_plus()) {
|
||||
if (Game::get_game()->is_original_plus_full_map())
|
||||
selecting_spell_target = (x < -7 || y > 194);
|
||||
else
|
||||
selecting_spell_target = (x < -7);
|
||||
canceling_spell = (x > 1 && (y > 101 || x > 137));
|
||||
doing_nothing = ((x > -8 && x < 16) || (x > -8 && (y < 8 || (y > 71 && y < 195))));
|
||||
} else {
|
||||
selecting_spell_target = (x < 0 && y > 0 && y < 162);
|
||||
canceling_spell = (x > 1 && (y > 101 || x > 137));
|
||||
doing_nothing = (y < 8 || y > 71 || x < 16 || x > 134);
|
||||
}
|
||||
|
||||
if (button == Events::BUTTON_RIGHT)
|
||||
return cancel_spell();
|
||||
|
||||
if (selecting_spell_target && !event_mode) { // cast selected spell on the map
|
||||
if (event->is_looking_at_spellbook()) {
|
||||
close_look();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
event->target_spell();
|
||||
if (event->get_mode() == INPUT_MODE) {
|
||||
y += area.top;
|
||||
x += area.left;
|
||||
Game::get_game()->get_map_window()->select_target(x, y);
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
if (canceling_spell) // cancel spell
|
||||
return cancel_spell();
|
||||
if (doing_nothing) // do nothing
|
||||
return GUI_YUM;
|
||||
// selecting spell index
|
||||
|
||||
sint8 index = get_selected_index();
|
||||
|
||||
if (index >= num_spells_per_page)
|
||||
index = num_spells_per_page;
|
||||
else
|
||||
index = 0;
|
||||
y = (y / num_spells_per_page) - 1;
|
||||
//printf("x = %d, y = %d index=%d\n", x, y, index);
|
||||
|
||||
if (cur_spells[index + y] != -1) {
|
||||
spell_container->quality = cur_spells[index + y];
|
||||
update_display = true;
|
||||
if (event->is_looking_at_spellbook())
|
||||
show_spell_description();
|
||||
else if (event_mode)
|
||||
event_mode_select_spell();
|
||||
else
|
||||
Game::get_game()->get_event()->target_spell();
|
||||
}
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void SpellView::hide_buttons() {
|
||||
if (left_button) left_button->Hide();
|
||||
if (right_button) right_button->Hide();
|
||||
}
|
||||
|
||||
void SpellView::show_buttons() {
|
||||
if (left_button) left_button->Show();
|
||||
if (right_button) right_button->Show();
|
||||
}
|
||||
|
||||
void SpellView::update_buttons() {
|
||||
show_buttons();
|
||||
sint8 index = get_selected_index();
|
||||
|
||||
if (level == 1 && index <= (num_spells_per_page - 1) && left_button)
|
||||
left_button->Hide();
|
||||
|
||||
uint8 old_level = level;
|
||||
uint8 num_spells = 0;
|
||||
for (; num_spells == 0;) {
|
||||
level++;
|
||||
if (level == 9)
|
||||
break;
|
||||
num_spells = fill_cur_spell_list();
|
||||
}
|
||||
level = old_level;
|
||||
fill_cur_spell_list();
|
||||
|
||||
if (right_button && ((level < 8 && num_spells == 0) || level == 8)
|
||||
&& cur_spells[num_spells_per_page * (1 + index / num_spells_per_page)] == -1)
|
||||
right_button->Hide();
|
||||
}
|
||||
|
||||
void SpellView::close_look() {
|
||||
Game::get_game()->get_event()->set_looking_at_spellbook(false);
|
||||
Game::get_game()->get_scroll()->display_prompt();
|
||||
Game::get_game()->get_view_manager()->close_spell_mode();
|
||||
Game::get_game()->get_event()->endAction();
|
||||
}
|
||||
|
||||
void SpellView::show_spell_description() {
|
||||
if (get_selected_index() != -1) {
|
||||
sint16 index = get_selected_spell();
|
||||
if (index < 256 && index > -1)
|
||||
Game::get_game()->get_magic()->show_spell_description((uint8)index);
|
||||
}
|
||||
close_look();
|
||||
}
|
||||
|
||||
GUI_status SpellView::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
|
||||
if (caller == left_button) {
|
||||
move_left();
|
||||
return GUI_YUM;
|
||||
} else if (caller == right_button) {
|
||||
move_right();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
136
engines/ultima/nuvie/views/spell_view.h
Normal file
136
engines/ultima/nuvie/views/spell_view.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/* 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 NUVIE_VIEWS_SPELL_VIEW_H
|
||||
#define NUVIE_VIEWS_SPELL_VIEW_H
|
||||
|
||||
#include "ultima/nuvie/views/draggable_view.h"
|
||||
#include "ultima/nuvie/core/obj.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class ObjManager;
|
||||
class Screen;
|
||||
class Actor;
|
||||
class Font;
|
||||
class U6Bmp;
|
||||
class Spell;
|
||||
|
||||
class SpellView : public DraggableView {
|
||||
|
||||
U6Bmp *background;
|
||||
bool all_spells_mode;
|
||||
|
||||
protected:
|
||||
bool event_mode; //this means we are reporting the spell_num back to the event class. Used by the enchant spell.
|
||||
|
||||
Obj *spell_container;
|
||||
Actor *caster;
|
||||
uint16 caster_reagents[8];
|
||||
|
||||
uint8 level;
|
||||
uint8 spell_num;
|
||||
|
||||
sint16 cur_spells[16];
|
||||
|
||||
uint8 num_spells_per_page;
|
||||
|
||||
public:
|
||||
SpellView(const Configuration *cfg);
|
||||
~SpellView() override;
|
||||
|
||||
virtual bool init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om);
|
||||
|
||||
void set_spell_caster(Actor *actor, Obj *s_container, bool eventMode);
|
||||
sint16 get_selected_spell() const {
|
||||
if (spell_container) {
|
||||
return spell_container->quality;
|
||||
} else return -1;
|
||||
}
|
||||
void Display(bool full_redraw) override;
|
||||
void PlaceOnScreen(Screen *s, GUI_DragManager *dm, int x, int y) override;
|
||||
void close_look();
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseEnter(uint8 state) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseLeave(uint8 state) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseClick(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseDouble(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseDelayed(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseHeld(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
|
||||
protected:
|
||||
|
||||
void event_mode_select_spell();
|
||||
|
||||
void add_command_icons(Screen *tmp_screen, void *view_manager);
|
||||
void hide_buttons();
|
||||
void show_buttons();
|
||||
void update_buttons();
|
||||
|
||||
void move_left();
|
||||
void move_right();
|
||||
GUI_status move_up();
|
||||
GUI_status move_down();
|
||||
|
||||
void set_prev_level();
|
||||
void set_next_level();
|
||||
|
||||
virtual uint8 fill_cur_spell_list();
|
||||
sint8 get_selected_index() const;
|
||||
|
||||
void display_level_text();
|
||||
void display_spell_list_text();
|
||||
void display_spell_text(Spell *spell, uint16 line_num, uint8 selected_spell);
|
||||
void show_spell_description();
|
||||
GUI_status cancel_spell();
|
||||
uint16 get_available_spell_count(const Spell *s) const;
|
||||
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
356
engines/ultima/nuvie/views/spell_view_gump.cpp
Normal file
356
engines/ultima/nuvie/views/spell_view_gump.cpp
Normal file
@@ -0,0 +1,356 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
#include "ultima/nuvie/core/magic.h"
|
||||
#include "ultima/nuvie/views/spell_view_gump.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/files/nuvie_bmp_file.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
SpellViewGump::SpellViewGump(const Configuration *cfg) : SpellView(cfg),
|
||||
gump_button(nullptr), font(nullptr), selected_spell(-1) {
|
||||
num_spells_per_page = 10;
|
||||
bg_image = nullptr;
|
||||
}
|
||||
|
||||
SpellViewGump::~SpellViewGump() {
|
||||
delete font;
|
||||
}
|
||||
|
||||
bool SpellViewGump::init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om) {
|
||||
View::init(x, y, f, p, tm, om);
|
||||
|
||||
SetRect(area.left, area.top, 162, 108);
|
||||
|
||||
Common::Path datadir = GUI::get_gui()->get_data_dir();
|
||||
Common::Path imagefile;
|
||||
Common::Path path;
|
||||
|
||||
Graphics::ManagedSurface *image, *image1;
|
||||
|
||||
build_path(datadir, "images", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "gumps", path);
|
||||
datadir = path;
|
||||
|
||||
build_path(datadir, "gump_btn_up.bmp", imagefile);
|
||||
image = SDL_LoadBMP(imagefile);
|
||||
build_path(datadir, "gump_btn_down.bmp", imagefile);
|
||||
image1 = SDL_LoadBMP(imagefile);
|
||||
|
||||
gump_button = new GUI_Button(nullptr, 0, 9, image, image1, this);
|
||||
this->AddWidget(gump_button);
|
||||
|
||||
build_path(datadir, "spellbook", path);
|
||||
datadir = path;
|
||||
|
||||
build_path(datadir, "spellbook_left_arrow.bmp", imagefile);
|
||||
image = SDL_LoadBMP(imagefile); //we load this twice as they are freed in ~GUI_Button()
|
||||
image1 = SDL_LoadBMP(imagefile);
|
||||
|
||||
left_button = new GUI_Button(this, 27, 4, image, image1, this);
|
||||
this->AddWidget(left_button);
|
||||
|
||||
build_path(datadir, "spellbook_right_arrow.bmp", imagefile);
|
||||
image = SDL_LoadBMP(imagefile);
|
||||
image1 = SDL_LoadBMP(imagefile);
|
||||
|
||||
right_button = new GUI_Button(this, 132, 4, image, image1, this);
|
||||
this->AddWidget(right_button);
|
||||
|
||||
font = new GUI_Font(GUI_FONT_GUMP);
|
||||
font->setColoring(0x7c, 0x00, 0x00, 0xd0, 0x70, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint8 SpellViewGump::fill_cur_spell_list() {
|
||||
uint8 count = SpellView::fill_cur_spell_list();
|
||||
|
||||
//load spell images
|
||||
Common::Path datadir = GUI::get_gui()->get_data_dir();
|
||||
Common::Path path;
|
||||
|
||||
build_path(datadir, "images", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "gumps", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "spellbook", path);
|
||||
datadir = path;
|
||||
|
||||
Common::Path imagefile;
|
||||
build_path(datadir, "spellbook_bg.bmp", imagefile);
|
||||
|
||||
delete bg_image;
|
||||
bg_image = bmp.getSdlSurface32(imagefile);
|
||||
if (bg_image == nullptr) {
|
||||
DEBUG(0, LEVEL_ERROR, "Failed to load spellbook_bg.bmp from '%s' directory\n", datadir.toString().c_str());
|
||||
return count;
|
||||
}
|
||||
|
||||
set_bg_color_key(0, 0x70, 0xfc);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
char filename[24]; // spellbook_spell_xxx.bmp\0
|
||||
Common::sprintf_s(filename, "spellbook_spell_%03d.bmp", cur_spells[i]);
|
||||
build_path(datadir, filename, imagefile);
|
||||
Graphics::ManagedSurface *spell_image = bmp.getSdlSurface32(imagefile);
|
||||
if (spell_image == nullptr) {
|
||||
DEBUG(0, LEVEL_ERROR, "Failed to load %s from '%s' directory\n", filename, datadir.toString().c_str());
|
||||
} else {
|
||||
Common::Rect dst;
|
||||
|
||||
uint8 base = (level - 1) * 16;
|
||||
uint8 spell = cur_spells[i] - base;
|
||||
|
||||
dst.left = ((spell < 5) ? 25 : 88);
|
||||
dst.top = 18 + (spell % 5) * 14;
|
||||
dst.setWidth(58);
|
||||
dst.setHeight(13);
|
||||
|
||||
SDL_BlitSurface(spell_image, nullptr, bg_image, &dst);
|
||||
delete spell_image;
|
||||
printSpellQty(cur_spells[i], dst.left + ((spell < 5) ? 50 : 48), dst.top);
|
||||
}
|
||||
}
|
||||
|
||||
loadCircleString(datadir);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void SpellViewGump::loadCircleString(const Common::Path &datadir) {
|
||||
Common::Path imagefile;
|
||||
char filename[7]; // n.bmp\0
|
||||
|
||||
Common::sprintf_s(filename, "%d.bmp", level);
|
||||
build_path(datadir, filename, imagefile);
|
||||
|
||||
Common::ScopedPtr<Graphics::ManagedSurface> s(bmp.getSdlSurface32(imagefile));
|
||||
if (s) {
|
||||
Common::Rect dst;
|
||||
dst = Common::Rect(70, 7, 74, 13);
|
||||
SDL_BlitSurface(s.get(), nullptr, bg_image, &dst);
|
||||
}
|
||||
|
||||
switch (level) {
|
||||
case 1 :
|
||||
loadCircleSuffix(datadir, "st.bmp");
|
||||
break;
|
||||
case 2 :
|
||||
loadCircleSuffix(datadir, "nd.bmp");
|
||||
break;
|
||||
case 3 :
|
||||
loadCircleSuffix(datadir, "rd.bmp");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SpellViewGump::loadCircleSuffix(const Common::Path &datadir, const Std::string &image) {
|
||||
Common::Path imagefile;
|
||||
|
||||
build_path(datadir, image, imagefile);
|
||||
Common::ScopedPtr<Graphics::ManagedSurface> s(bmp.getSdlSurface32(imagefile));
|
||||
if (s) {
|
||||
Common::Rect dst;
|
||||
dst = Common::Rect(75, 7, 82, 13);
|
||||
SDL_BlitSurface(s.get(), nullptr, bg_image, &dst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SpellViewGump::printSpellQty(uint8 spellNum, uint16 x, uint16 y) {
|
||||
Magic *m = Game::get_game()->get_magic();
|
||||
|
||||
Spell *spell = m->get_spell((uint8)spellNum);
|
||||
|
||||
uint16 qty = get_available_spell_count(spell);
|
||||
|
||||
if (qty < 10)
|
||||
x += 5;
|
||||
|
||||
font->textOut(bg_image, x, y, Common::String::format("%d", qty).c_str());
|
||||
}
|
||||
|
||||
void SpellViewGump::Display(bool full_redraw) {
|
||||
//display_level_text();
|
||||
//display_spell_list_text();
|
||||
Common::Rect dst;
|
||||
dst = area;
|
||||
dst.setWidth(162);
|
||||
dst.setHeight(108);
|
||||
SDL_BlitSurface(bg_image, nullptr, surface, &dst);
|
||||
|
||||
DisplayChildren(full_redraw);
|
||||
|
||||
sint16 spell = get_selected_spell();
|
||||
|
||||
if (spell < 0)
|
||||
spell = 0;
|
||||
|
||||
spell = spell % 16;
|
||||
screen->fill(248, area.left + ((spell < 5) ? 75 : 136), area.top + 18 + 7 + (spell % 5) * 14, 10, 1);
|
||||
|
||||
update_display = false;
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GUI_status SpellViewGump::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
//close gump and return control to Magic class for clean up.
|
||||
if (caller == gump_button) {
|
||||
if (Game::get_game()->get_event()->is_looking_at_spellbook())
|
||||
close_look();
|
||||
else
|
||||
close_spellbook();
|
||||
return GUI_YUM;
|
||||
} else if (caller == left_button) {
|
||||
move_left();
|
||||
return GUI_YUM;
|
||||
} else if (caller == right_button) {
|
||||
move_right();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
void SpellViewGump::close_spellbook() {
|
||||
Game::get_game()->get_event()->close_spellbook();
|
||||
}
|
||||
|
||||
sint16 SpellViewGump::getSpell(int x, int y) const {
|
||||
int localy = y - area.top;
|
||||
int localx = x - area.left;
|
||||
|
||||
localy += 3; //align the pointer in the center of the crosshair cursor.
|
||||
localx += 3;
|
||||
|
||||
if (localy < 21 || localy > 88 || localx < 28 || localx > 148) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8 spell = (level - 1) * 16;
|
||||
|
||||
|
||||
if (localx >= 89)
|
||||
spell += 5;
|
||||
|
||||
spell += (localy - 20) / 14;
|
||||
|
||||
for (uint8 i = 0; cur_spells[i] != -1 && i < 16; i++) {
|
||||
if (cur_spells[i] == spell) {
|
||||
return spell;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
GUI_status SpellViewGump::MouseWheel(sint32 x, sint32 y) {
|
||||
if (y > 0) {
|
||||
move_left();
|
||||
} else if (y < 0) {
|
||||
move_right();
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status SpellViewGump::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
if (button == Events::BUTTON_RIGHT) {
|
||||
close_spellbook();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
sint16 clicked_spell = getSpell(x, y);
|
||||
|
||||
if (clicked_spell != -1) {
|
||||
selected_spell = clicked_spell;
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
bool can_target = true; // maybe put this check into GUI_widget
|
||||
if (HitRect(x, y)) {
|
||||
if (bg_image) {
|
||||
uint32 pixel = sdl_getpixel(bg_image, x - area.left, y - area.top);
|
||||
if (pixel != bg_color_key)
|
||||
can_target = false;
|
||||
} else
|
||||
can_target = false;
|
||||
}
|
||||
|
||||
if (can_target) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
if (event->is_looking_at_spellbook()) {
|
||||
close_spellbook();
|
||||
return GUI_YUM;
|
||||
}
|
||||
if (!event_mode)
|
||||
event->target_spell(); //Simulate a global key down event.
|
||||
if (event->get_mode() == INPUT_MODE)
|
||||
Game::get_game()->get_map_window()->select_target(x, y);
|
||||
if (event->get_mode() != MOVE_MODE)
|
||||
close_spellbook();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
return DraggableView::MouseDown(x, y, button);
|
||||
}
|
||||
|
||||
GUI_status SpellViewGump::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
if (button == Events::BUTTON_RIGHT)
|
||||
return GUI_YUM;
|
||||
|
||||
sint16 spell = getSpell(x, y);
|
||||
|
||||
if (spell != -1 && spell == selected_spell) {
|
||||
spell_container->quality = spell;
|
||||
if (Game::get_game()->get_event()->is_looking_at_spellbook())
|
||||
show_spell_description();
|
||||
else if (event_mode) {
|
||||
event_mode_select_spell();
|
||||
} else {
|
||||
//Simulate a global key down event.
|
||||
Game::get_game()->get_event()->target_spell();
|
||||
}
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
|
||||
auto ret = DraggableView::MouseUp(x, y, button);
|
||||
grab_focus(); // Dragging releases focus, grab it again
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
83
engines/ultima/nuvie/views/spell_view_gump.h
Normal file
83
engines/ultima/nuvie/views/spell_view_gump.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* 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 NUVIE_VIEWS_SPELL_VIEW_GUMP_H
|
||||
#define NUVIE_VIEWS_SPELL_VIEW_GUMP_H
|
||||
|
||||
#include "ultima/nuvie/views/spell_view.h"
|
||||
#include "ultima/nuvie/files/nuvie_bmp_file.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class ObjManager;
|
||||
class Screen;
|
||||
class Actor;
|
||||
class Font;
|
||||
class U6Bmp;
|
||||
class Spell;
|
||||
|
||||
static const int SPELLVIEWGUMP_WIDTH = 162;
|
||||
|
||||
class SpellViewGump : public SpellView {
|
||||
|
||||
GUI_Button *gump_button;
|
||||
sint16 selected_spell;
|
||||
GUI_Font *font;
|
||||
NuvieBmpFile bmp;
|
||||
public:
|
||||
SpellViewGump(const Configuration *cfg);
|
||||
~SpellViewGump() override;
|
||||
|
||||
bool init(Screen *tmp_screen, void *view_manager, uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om) override;
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override {
|
||||
return DraggableView::MouseMotion(x, y, state);
|
||||
}
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
void MoveRelative(int dx, int dy) override {
|
||||
return DraggableView::MoveRelative(dx, dy);
|
||||
}
|
||||
|
||||
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
protected:
|
||||
|
||||
sint16 getSpell(int x, int y) const;
|
||||
|
||||
uint8 fill_cur_spell_list() override;
|
||||
void loadCircleString(const Common::Path &datadir);
|
||||
void loadCircleSuffix(const Common::Path &datadir, const Std::string &image);
|
||||
void printSpellQty(uint8 spell_num, uint16 x, uint16 y);
|
||||
|
||||
void close_spellbook();
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
228
engines/ultima/nuvie/views/sun_moon_ribbon.cpp
Normal file
228
engines/ultima/nuvie/views/sun_moon_ribbon.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/files/nuvie_bmp_file.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/core/weather.h"
|
||||
#include "ultima/nuvie/core/game_clock.h"
|
||||
#include "ultima/nuvie/views/sun_moon_ribbon.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static const int SUNMOON_RIBBON_END_WIDTH = 5;
|
||||
static const int SUNMOON_RIBBON_WIDTH = 48;
|
||||
static const int SUNMOON_RIBBON_HEIGHT = 14;
|
||||
static const int SUNMOON_RIBBON_DIR_WIDTH = 14;
|
||||
static const int SUNMOON_RIBBON_TOTAL_WIDTH = (SUNMOON_RIBBON_WIDTH + SUNMOON_RIBBON_DIR_WIDTH);
|
||||
|
||||
SunMoonRibbon::SunMoonRibbon(Player *p, Weather *w, TileManager *tm)
|
||||
: SunMoonStripWidget(p, tm), bg_data(nullptr), weather(w), retracted(true),
|
||||
current_time(0) {
|
||||
}
|
||||
|
||||
SunMoonRibbon::~SunMoonRibbon() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SunMoonRibbon::init(Screen *) {
|
||||
GUI_Widget::Init(nullptr, Game::get_game()->get_game_x_offset()
|
||||
+ Game::get_game()->get_game_width() - SUNMOON_RIBBON_TOTAL_WIDTH,
|
||||
Game::get_game()->get_game_y_offset(),
|
||||
SUNMOON_RIBBON_TOTAL_WIDTH,SUNMOON_RIBBON_HEIGHT);
|
||||
|
||||
loadBgImage(0);
|
||||
}
|
||||
|
||||
void SunMoonRibbon::loadBgImage(uint8 num) {
|
||||
char filename[6]; // "n.bmp\0"
|
||||
Common::Path datadir = GUI::get_gui()->get_data_dir();
|
||||
Common::Path imagefile;
|
||||
Common::Path path;
|
||||
NuvieBmpFile bmp;
|
||||
|
||||
build_path(datadir, "images", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "gumps", path);
|
||||
datadir = path;
|
||||
build_path(datadir, "celestial", path);
|
||||
datadir = path;
|
||||
|
||||
Common::sprintf_s(filename, "%d.bmp", num);
|
||||
build_path(datadir, filename, imagefile);
|
||||
|
||||
if (bg_data)
|
||||
delete bg_data;
|
||||
bg_data = bmp.getSdlSurface32(imagefile);
|
||||
|
||||
uint32 bg_color_key = bg_data->format.RGBToColor(0xb3, 0x94, 0x78);
|
||||
bg_data->setTransparentColor(bg_color_key);
|
||||
}
|
||||
|
||||
void SunMoonRibbon::Display(bool full_redraw) {
|
||||
update_display = false;
|
||||
uint8 level = player->get_location_level();
|
||||
|
||||
GameClock *clock = Game::get_game()->get_clock();
|
||||
uint16 time = 324; //not completely dark - used when in dungeons
|
||||
|
||||
if (level == 0 || level == 5)
|
||||
time = clock->get_hour() * 60 + clock->get_minute();
|
||||
|
||||
update_hour(time);
|
||||
|
||||
if (!retracted && (level == 0 || level == 5))
|
||||
display_surface_strip();
|
||||
else
|
||||
display_dungeon_strip();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SunMoonRibbon::update_hour(uint16 time) {
|
||||
static const uint8 dawn_tbl[] = {8, 7, 7, 6, 5, 4, 3, 2, 1, 0};
|
||||
static const uint8 dusk_tbl[] = {1, 2, 3, 4, 5, 6, 7, 7, 7, 8};
|
||||
|
||||
time = time / 6;
|
||||
|
||||
if (current_time != time || bg_data == nullptr) {
|
||||
current_time = time;
|
||||
uint8 bg_num = 8; //night
|
||||
if (current_time >= 50 && current_time < 60) {
|
||||
bg_num = dawn_tbl[current_time - 50]; //dawn
|
||||
} else if (current_time >= 60 && current_time < 190) {
|
||||
bg_num = 0; //day time
|
||||
} else if (current_time >= 190 && current_time < 200) { //dusk
|
||||
bg_num = dusk_tbl[current_time - 190]; //dusk
|
||||
}
|
||||
loadBgImage(bg_num);
|
||||
}
|
||||
}
|
||||
|
||||
void SunMoonRibbon::display_sun_moon(const Tile *tile, uint8 pos) {
|
||||
static const struct {
|
||||
sint16 x, y;
|
||||
} skypos[15] = { // sky positions relative to area
|
||||
{ SUNMOON_RIBBON_WIDTH - 0 * 3, 7 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 1 * 3, 6 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 2 * 3, 5 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 3 * 3, 4 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 4 * 3, 3 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 5 * 3, 2 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 6 * 3, 1 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 7 * 3, 0 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 8 * 3, 1 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 9 * 3, 2 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 10 * 3, 3 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 11 * 3, 4 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 12 * 3, 5 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 13 * 3, 6 },
|
||||
{ SUNMOON_RIBBON_WIDTH - 14 * 3, 7 }
|
||||
};
|
||||
|
||||
uint16 x = area.left + skypos[pos].x - 10, y = area.top + skypos[pos].y;
|
||||
|
||||
screen->blit(x, y, tile->data, 8 , 16, area.height() - skypos[pos].y > 16 ? 16 : area.height() - skypos[pos].y, 16, true);
|
||||
}
|
||||
|
||||
void SunMoonRibbon::display_surface_strip() {
|
||||
Common::Rect src = Common::Rect(SUNMOON_RIBBON_WIDTH, SUNMOON_RIBBON_HEIGHT);
|
||||
Common::Rect dest = area;
|
||||
dest.setWidth(SUNMOON_RIBBON_WIDTH);
|
||||
dest.setHeight(SUNMOON_RIBBON_HEIGHT);
|
||||
|
||||
SDL_BlitSurface(bg_data, &src, surface, &dest);
|
||||
|
||||
GameClock *clock = Game::get_game()->get_clock();
|
||||
bool eclipse = weather->is_eclipse();
|
||||
|
||||
display_sun(clock->get_hour(), 0/*minutes*/, eclipse);
|
||||
|
||||
if (!eclipse)
|
||||
display_moons(clock->get_day(), clock->get_hour());
|
||||
|
||||
src.left = SUNMOON_RIBBON_WIDTH + weather->get_wind_dir() * SUNMOON_RIBBON_DIR_WIDTH;
|
||||
uint8 dir;
|
||||
if (weather->is_displaying_from_wind_dir()) { // points dir wind is coming from
|
||||
const uint8 from_wind_pos[] = { 1, 3, 5, 7, 2, 4, 6, 8, 0 };
|
||||
dir = from_wind_pos[weather->get_wind_dir()];
|
||||
} else { // points dir wind is blowing to
|
||||
const uint8 to_wind_pos[] = { 5, 7, 1, 3, 6, 8, 2, 4, 0 };
|
||||
dir = to_wind_pos[weather->get_wind_dir()];
|
||||
}
|
||||
src.left = SUNMOON_RIBBON_WIDTH + dir * SUNMOON_RIBBON_DIR_WIDTH;
|
||||
src.top = 0;
|
||||
src.setWidth(SUNMOON_RIBBON_DIR_WIDTH);
|
||||
src.setHeight(SUNMOON_RIBBON_HEIGHT);
|
||||
|
||||
dest = area;
|
||||
dest.left = area.left + SUNMOON_RIBBON_WIDTH;
|
||||
dest.setWidth(SUNMOON_RIBBON_DIR_WIDTH);
|
||||
dest.setHeight(SUNMOON_RIBBON_HEIGHT);
|
||||
|
||||
SDL_BlitSurface(bg_data, &src, surface, &dest);
|
||||
|
||||
|
||||
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
void SunMoonRibbon::display_dungeon_strip() {
|
||||
Common::Rect src;
|
||||
Common::Rect dest;
|
||||
|
||||
src = Common::Rect(SUNMOON_RIBBON_END_WIDTH, SUNMOON_RIBBON_HEIGHT);
|
||||
|
||||
dest.left = area.left + SUNMOON_RIBBON_TOTAL_WIDTH - SUNMOON_RIBBON_END_WIDTH;
|
||||
dest.top = area.top;
|
||||
dest.setWidth(SUNMOON_RIBBON_END_WIDTH);
|
||||
dest.setHeight(SUNMOON_RIBBON_HEIGHT);
|
||||
|
||||
SDL_BlitSurface(bg_data, &src, surface, &dest);
|
||||
screen->update(dest.left, dest.top, dest.width(), dest.height());
|
||||
}
|
||||
|
||||
GUI_status SunMoonRibbon::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
Common::Rect rect = area;
|
||||
|
||||
if (retracted) {
|
||||
rect.left = area.left + SUNMOON_RIBBON_TOTAL_WIDTH - SUNMOON_RIBBON_END_WIDTH;
|
||||
rect.setWidth(SUNMOON_RIBBON_END_WIDTH);
|
||||
if (HitRect(x, y, rect)) {
|
||||
retracted = false;
|
||||
return GUI_YUM;
|
||||
}
|
||||
} else {
|
||||
if (HitRect(x, y, rect)) {
|
||||
retracted = true;
|
||||
return GUI_YUM;
|
||||
}
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
68
engines/ultima/nuvie/views/sun_moon_ribbon.h
Normal file
68
engines/ultima/nuvie/views/sun_moon_ribbon.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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 NUVIE_VIEWS_SUN_MOON_RIBBON_H
|
||||
#define NUVIE_VIEWS_SUN_MOON_RIBBON_H
|
||||
|
||||
#include "ultima/nuvie/views/sun_moon_strip_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class SunMoonRibbon : public SunMoonStripWidget {
|
||||
|
||||
private:
|
||||
Graphics::ManagedSurface *bg_data;
|
||||
Weather *weather;
|
||||
bool retracted;
|
||||
uint16 current_time;
|
||||
|
||||
public:
|
||||
SunMoonRibbon(Player *p, Weather *w, TileManager *tm);
|
||||
~SunMoonRibbon() override;
|
||||
|
||||
void init(Screen *screen);
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
|
||||
|
||||
void extend() {
|
||||
retracted = false;
|
||||
}
|
||||
void retract() {
|
||||
retracted = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
void display_sun_moon(const Tile *tile, uint8 pos) override;
|
||||
|
||||
private:
|
||||
void loadBgImage(uint8 num);
|
||||
void display_surface_strip();
|
||||
void display_dungeon_strip();
|
||||
void update_hour(uint16 time);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
155
engines/ultima/nuvie/views/sun_moon_strip_widget.cpp
Normal file
155
engines/ultima/nuvie/views/sun_moon_strip_widget.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/core/weather.h"
|
||||
#include "ultima/nuvie/core/game_clock.h"
|
||||
#include "ultima/nuvie/views/sun_moon_strip_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
SunMoonStripWidget::SunMoonStripWidget(Player *p, TileManager *tm)
|
||||
: GUI_Widget(nullptr, 0, 0, 0, 0), player(p), tile_manager(tm) {
|
||||
}
|
||||
|
||||
SunMoonStripWidget::~SunMoonStripWidget() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SunMoonStripWidget::init(sint16 x, sint16 y) {
|
||||
GUI_Widget::Init(nullptr, x, y, 100, 20);
|
||||
}
|
||||
|
||||
void SunMoonStripWidget::Display(bool full_redraw) {
|
||||
//if(full_redraw || update_display)
|
||||
// {
|
||||
update_display = false;
|
||||
uint8 level = player->get_location_level();
|
||||
|
||||
if (level == 0 || level == 5)
|
||||
display_surface_strip();
|
||||
else
|
||||
display_dungeon_strip();
|
||||
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SunMoonStripWidget::display_surface_strip() {
|
||||
GameClock *clock = Game::get_game()->get_clock();
|
||||
Weather *weather = Game::get_game()->get_weather();
|
||||
bool eclipse = weather->is_eclipse();
|
||||
|
||||
display_sun(clock->get_hour(), 0/*minutes*/, eclipse);
|
||||
|
||||
if (!eclipse)
|
||||
display_moons(clock->get_day(), clock->get_hour());
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
Tile *tile = tile_manager->get_tile(352 + i);
|
||||
screen->blit(area.left + 8 + i * 16, area.top, tile->data, 8, 16, 16, 16, true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void SunMoonStripWidget::display_dungeon_strip() {
|
||||
Tile *tile = tile_manager->get_tile(372);
|
||||
screen->blit(area.left + 8, area.top, tile->data, 8, 16, 16, 16, true);
|
||||
|
||||
tile = tile_manager->get_tile(373);
|
||||
|
||||
for (int i = 1; i < 8; i++) {
|
||||
screen->blit(area.left + 8 + i * 16, area.top, tile->data, 8, 16, 16, 16, true);
|
||||
}
|
||||
|
||||
tile = tile_manager->get_tile(374);
|
||||
screen->blit(area.left + 8 + 7 * 16 + 8, area.top, tile->data, 8, 16, 16, 16, true);
|
||||
|
||||
return;
|
||||
}
|
||||
// <SB-X>
|
||||
void SunMoonStripWidget::display_sun_moon(const Tile *tile, uint8 pos) {
|
||||
struct {
|
||||
sint16 x, y;
|
||||
} skypos[15] = { // sky positions relative to area
|
||||
{ 8 + 7 * 16 - 0 * 8, 6 }, // 7*16 is the first position on the right side
|
||||
{ 8 + 7 * 16 - 1 * 8, 3 },
|
||||
{ 8 + 7 * 16 - 2 * 8, 1 },
|
||||
{ 8 + 7 * 16 - 3 * 8, -1 },
|
||||
{ 8 + 7 * 16 - 4 * 8, -2 },
|
||||
{ 8 + 7 * 16 - 5 * 8, -3 },
|
||||
{ 8 + 7 * 16 - 6 * 8, -4 },
|
||||
{ 8 + 7 * 16 - 7 * 8, -4 },
|
||||
{ 8 + 7 * 16 - 8 * 8, -4 },
|
||||
{ 8 + 7 * 16 - 9 * 8, -3 },
|
||||
{ 8 + 7 * 16 - 10 * 8, -2 },
|
||||
{ 8 + 7 * 16 - 11 * 8, -1 },
|
||||
{ 8 + 7 * 16 - 12 * 8, 1 },
|
||||
{ 8 + 7 * 16 - 13 * 8, 3 },
|
||||
{ 8 + 7 * 16 - 14 * 8, 6 }
|
||||
};
|
||||
|
||||
int height = 16;
|
||||
uint16 x = area.left + skypos[pos].x, y = area.top + skypos[pos].y;
|
||||
if (skypos[pos].y == 6) // goes through the bottom if not reduced
|
||||
height = 10;
|
||||
screen->blit(x, y, tile->data, 8 , 16, height, 16, true);
|
||||
}
|
||||
|
||||
void SunMoonStripWidget::display_sun(uint8 hour, uint8 minute, bool eclipse) {
|
||||
uint16 sun_tile = 0;
|
||||
if (eclipse)
|
||||
sun_tile = 363; //eclipsed sun
|
||||
else if (hour == 5 || hour == 19)
|
||||
sun_tile = 361; //orange sun
|
||||
else if (hour > 5 && hour < 19)
|
||||
sun_tile = 362; //yellow sun
|
||||
else return; //no sun
|
||||
display_sun_moon(tile_manager->get_tile(sun_tile), hour - 5);
|
||||
}
|
||||
|
||||
void SunMoonStripWidget::display_moons(uint8 day, uint8 hour, uint8 minute) {
|
||||
// trammel (starts 1 hour ahead of sun)
|
||||
uint8 phase = uint8(nearbyint((day - 1) / TRAMMEL_PHASE)) % 8;
|
||||
Tile *tileA = tile_manager->get_tile((phase == 0) ? 584 : 584 + (8 - phase)); // reverse order in tilelist
|
||||
uint8 posA = ((hour + 1) + 3 * phase) % 24; // advance 3 positions each phase-change
|
||||
|
||||
// felucca (starts 1 hour behind sun)
|
||||
// ...my FELUCCA_PHASE may be wrong but this method works with it...
|
||||
sint8 phaseb = (day - 1) % uint8(nearbyint(FELUCCA_PHASE * 8)) - 1;
|
||||
phase = (phaseb >= 0) ? phaseb : 0;
|
||||
Tile *tileB = tile_manager->get_tile((phase == 0) ? 584 : 584 + (8 - phase)); // reverse order in tilelist
|
||||
uint8 posB = ((hour - 1) + 3 * phase) % 24; // advance 3 positions per phase-change
|
||||
|
||||
if (posA >= 5 && posA <= 19)
|
||||
display_sun_moon(tileA, posA - 5);
|
||||
if (posB >= 5 && posB <= 19)
|
||||
display_sun_moon(tileB, posB - 5);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
59
engines/ultima/nuvie/views/sun_moon_strip_widget.h
Normal file
59
engines/ultima/nuvie/views/sun_moon_strip_widget.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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 NUVIE_VIEWS_SUN_MOON_STRIP_WIDGET_H
|
||||
#define NUVIE_VIEWS_SUN_MOON_STRIP_WIDGET_H
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/core/tile_manager.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Player;
|
||||
|
||||
class SunMoonStripWidget : public GUI_Widget {
|
||||
|
||||
protected:
|
||||
TileManager *tile_manager;
|
||||
Player *player;
|
||||
|
||||
public:
|
||||
SunMoonStripWidget(Player *p, TileManager *tm);
|
||||
~SunMoonStripWidget() override;
|
||||
|
||||
void init(sint16 x, sint16 y);
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
protected:
|
||||
virtual void display_sun_moon(const Tile *tile, uint8 pos);
|
||||
void display_sun(uint8 hour, uint8 minute, bool eclipse);
|
||||
void display_moons(uint8 day, uint8 hour, uint8 minute = 0);
|
||||
|
||||
private:
|
||||
void display_surface_strip();
|
||||
void display_dungeon_strip();
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
211
engines/ultima/nuvie/views/view.cpp
Normal file
211
engines/ultima/nuvie/views/view.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/core/party.h"
|
||||
#include "ultima/nuvie/screen/game_palette.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/views/view.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
View::View(const Configuration *cfg) : GUI_Widget(nullptr, 0, 0, 0, 0),
|
||||
config(cfg), new_ui_mode(false), left_button(nullptr), font(nullptr),
|
||||
tile_manager(nullptr), right_button(nullptr), obj_manager(nullptr),
|
||||
party(nullptr), party_button(nullptr), inventory_button(nullptr),
|
||||
actor_button(nullptr), bg_color(0), cur_party_member(0) {
|
||||
}
|
||||
|
||||
View::~View() {
|
||||
}
|
||||
|
||||
bool View::init(uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om) {
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6)
|
||||
GUI_Widget::Init(nullptr, x, y, 136, 96);
|
||||
else if (Game::get_game()->get_game_type() == NUVIE_GAME_SE)
|
||||
GUI_Widget::Init(nullptr, x + 7, y - 2, 132, 113);
|
||||
else
|
||||
GUI_Widget::Init(nullptr, x + 8, y - 4, 128, 118);
|
||||
Hide();
|
||||
font = f;
|
||||
party = p;
|
||||
tile_manager = tm;
|
||||
obj_manager = om;
|
||||
|
||||
set_party_member(0);
|
||||
|
||||
bg_color = Game::get_game()->get_palette()->get_bg_color();
|
||||
|
||||
|
||||
new_ui_mode = Game::get_game()->is_new_style();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool View::set_party_member(uint8 party_member) {
|
||||
uint16 size = party->get_party_size();
|
||||
|
||||
if (party_member < size) {
|
||||
cur_party_member = party_member;
|
||||
|
||||
if (left_button && right_button) {
|
||||
if (party_member == 0)
|
||||
left_button->Hide();
|
||||
else
|
||||
left_button->Show();
|
||||
|
||||
if (party_member == size - 1)
|
||||
right_button->Hide();
|
||||
else
|
||||
right_button->Show();
|
||||
}
|
||||
|
||||
Redraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool View::next_party_member() {
|
||||
if ((cur_party_member + 1) < party->get_party_size())
|
||||
return set_party_member(cur_party_member + 1);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool View::prev_party_member() {
|
||||
if (cur_party_member != 0)
|
||||
return set_party_member(cur_party_member - 1);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void View::fill_md_background(uint8 color, const Common::Rect &r) {
|
||||
Screen *scr = Game::get_game()->get_screen();
|
||||
scr->fill(color, r.left + 1, r.top + 9, 1, 1); // left pillar
|
||||
scr->fill(color, r.left + 2, r.top + 6, 1, 4); // left pillar
|
||||
scr->fill(color, r.left + 3, r.top + 3, 1, 11); // left pillar
|
||||
scr->fill(color, r.left + r.width() - 2, r.top + 9, 1, 1); // right pillar
|
||||
scr->fill(color, r.left + r.width() - 3, r.top + 6, 1, 4); // right pillar
|
||||
scr->fill(color, r.left + r.width() - 4, r.top + 3, 1, 11); // right pillar
|
||||
scr->fill(color, r.left + 4, r.top, r.width() - 8, 15); // top center
|
||||
scr->fill(color, r.left, r.top + 14, r.width(), r.height() - 14); // bottom
|
||||
//scr->fill(15, r.left, r.top, r.width(), r.height()); // bottom
|
||||
|
||||
}
|
||||
|
||||
void View::set_combat_mode(Actor *actor) {
|
||||
uint8 combat_mode = actor->get_combat_mode();
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6) {
|
||||
combat_mode++;
|
||||
if (combat_mode > ACTOR_WT_ASSAULT)
|
||||
combat_mode = ACTOR_WT_PLAYER;
|
||||
} else {
|
||||
if (combat_mode == ACTOR_WT_PLAYER)
|
||||
combat_mode = ACTOR_WT_RANGED;
|
||||
else if (combat_mode == ACTOR_WT_RANGED)
|
||||
combat_mode = ACTOR_WT_RETREAT;
|
||||
else if (combat_mode == ACTOR_WT_RETREAT)
|
||||
combat_mode = ACTOR_WT_ASSAULT;
|
||||
else if (combat_mode == ACTOR_WT_ASSAULT)
|
||||
combat_mode = ACTOR_WT_PLAYER;
|
||||
}
|
||||
actor->set_combat_mode(combat_mode);
|
||||
}
|
||||
|
||||
uint8 View::get_combat_mode_index(const Actor *actor) const {
|
||||
uint8 combat_mode = actor->get_combat_mode();
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6)
|
||||
return combat_mode - 2;
|
||||
else {
|
||||
uint8 combat_mode_index = 0;
|
||||
if (combat_mode == ACTOR_WT_PLAYER)
|
||||
combat_mode_index = 0;
|
||||
else if (combat_mode == ACTOR_WT_RANGED)
|
||||
combat_mode_index = 1;
|
||||
else if (combat_mode == ACTOR_WT_RETREAT)
|
||||
combat_mode_index = 2;
|
||||
else if (combat_mode == ACTOR_WT_ASSAULT)
|
||||
combat_mode_index = 3;
|
||||
|
||||
return combat_mode_index;
|
||||
}
|
||||
}
|
||||
|
||||
GUI_status View::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
ViewManager *view_manager;
|
||||
|
||||
if (caller == left_button) {
|
||||
prev_party_member();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
if (caller == right_button) {
|
||||
next_party_member();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
if (caller == actor_button) {
|
||||
view_manager = (ViewManager *)data;
|
||||
view_manager->set_actor_mode();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
if (caller == party_button) {
|
||||
view_manager = (ViewManager *)data;
|
||||
view_manager->set_party_mode();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
if (caller == inventory_button) {
|
||||
view_manager = (ViewManager *)data;
|
||||
view_manager->set_inventory_mode();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_Button *View::loadButton(const Common::Path &dir, Std::string name, uint16 x, uint16 y) {
|
||||
GUI_Button *button;
|
||||
Common::Path imagefile;
|
||||
|
||||
Graphics::ManagedSurface *image, *image1;
|
||||
build_path(dir, name + "_btn_up.bmp", imagefile);
|
||||
image = SDL_LoadBMP(imagefile);
|
||||
build_path(dir, name + "_btn_down.bmp", imagefile);
|
||||
image1 = SDL_LoadBMP(imagefile);
|
||||
|
||||
button = new GUI_Button(nullptr, x, y, image, image1, this);
|
||||
this->AddWidget(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
85
engines/ultima/nuvie/views/view.h
Normal file
85
engines/ultima/nuvie/views/view.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* 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 NUVIE_VIEWS_VIEW_H
|
||||
#define NUVIE_VIEWS_VIEW_H
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
GUI_status viewLeftButtonCallback(void *data);
|
||||
GUI_status viewRightButtonCallback(void *data);
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class Screen;
|
||||
class Font;
|
||||
class ObjManager;
|
||||
class Party;
|
||||
class GUI_Button;
|
||||
class Actor;
|
||||
|
||||
class View: public GUI_Widget {
|
||||
protected:
|
||||
const Configuration *config;
|
||||
|
||||
GUI_Button *left_button, *right_button, *actor_button, *party_button, *inventory_button;
|
||||
|
||||
Font *font;
|
||||
TileManager *tile_manager;
|
||||
ObjManager *obj_manager;
|
||||
Party *party;
|
||||
|
||||
uint8 cur_party_member;
|
||||
uint8 bg_color;
|
||||
bool new_ui_mode;
|
||||
|
||||
public:
|
||||
|
||||
View(const Configuration *cfg);
|
||||
~View() override;
|
||||
|
||||
bool init(uint16 x, uint16 y, Font *f, Party *p, TileManager *tm, ObjManager *om);
|
||||
|
||||
virtual bool set_party_member(uint8 party_member);
|
||||
uint8 get_party_member_num() const {
|
||||
return cur_party_member;
|
||||
}
|
||||
bool next_party_member();
|
||||
bool prev_party_member();
|
||||
void fill_md_background(uint8 color, const Common::Rect &r);
|
||||
void set_combat_mode(Actor *actor);
|
||||
uint8 get_combat_mode_index(const Actor *actor) const;
|
||||
|
||||
virtual void close_view() {}
|
||||
|
||||
protected:
|
||||
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
GUI_Button *loadButton(const Common::Path &dir, Std::string name, uint16 x, uint16 y);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
586
engines/ultima/nuvie/views/view_manager.cpp
Normal file
586
engines/ultima/nuvie/views/view_manager.cpp
Normal file
@@ -0,0 +1,586 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/views/actor_view.h"
|
||||
#include "ultima/nuvie/views/portrait_view.h"
|
||||
#include "ultima/nuvie/views/inventory_view.h"
|
||||
#include "ultima/nuvie/views/doll_view_gump.h"
|
||||
#include "ultima/nuvie/views/container_view_gump.h"
|
||||
#include "ultima/nuvie/views/portrait_view_gump.h"
|
||||
#include "ultima/nuvie/views/sign_view_gump.h"
|
||||
#include "ultima/nuvie/views/scroll_view_gump.h"
|
||||
#include "ultima/nuvie/views/party_view.h"
|
||||
#include "ultima/nuvie/views/spell_view.h"
|
||||
#include "ultima/nuvie/views/spell_view_gump.h"
|
||||
#include "ultima/nuvie/views/sun_moon_ribbon.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/views/map_editor_view.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/core/party.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/portraits/portrait.h"
|
||||
#include "ultima/nuvie/usecode/usecode.h"
|
||||
#include "ultima/nuvie/files/nuvie_bmp_file.h"
|
||||
#include "ultima/nuvie/views/md_sky_strip_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
ViewManager::ViewManager(const Configuration *cfg) : config(cfg),
|
||||
current_view(nullptr), gui(nullptr), font(nullptr), tile_manager(nullptr),
|
||||
obj_manager(nullptr), party(nullptr), portrait(nullptr), actor_view(nullptr),
|
||||
inventory_view(nullptr), portrait_view(nullptr), party_view(nullptr),
|
||||
spell_view(nullptr), doll_next_party_member(0), ribbon(nullptr),
|
||||
mdSkyWidget(nullptr) {
|
||||
config->value("config/GameType", game_type);
|
||||
}
|
||||
|
||||
ViewManager::~ViewManager() {
|
||||
// only delete the views that are not currently active
|
||||
if (current_view != actor_view) delete actor_view;
|
||||
if (current_view != inventory_view) delete inventory_view;
|
||||
if (current_view != party_view) delete party_view;
|
||||
if (current_view != portrait_view) delete portrait_view;
|
||||
if (current_view != spell_view) delete spell_view;
|
||||
|
||||
}
|
||||
|
||||
bool ViewManager::init(GUI *g, Font *f, Party *p, Player *player, TileManager *tm, ObjManager *om, Portrait *por) {
|
||||
gui = g;
|
||||
font = f;
|
||||
party = p;
|
||||
tile_manager = tm;
|
||||
obj_manager = om;
|
||||
portrait = por;
|
||||
|
||||
uint16 x_off = Game::get_game()->get_game_x_offset();
|
||||
uint16 y_off = Game::get_game()->get_game_y_offset();
|
||||
if (Game::get_game()->is_original_plus())
|
||||
x_off += Game::get_game()->get_game_width() - 320;
|
||||
|
||||
inventory_view = new InventoryView(config);
|
||||
inventory_view->init(gui->get_screen(), this, 176 + x_off, 8 + y_off, font, party, tile_manager, obj_manager);
|
||||
|
||||
portrait_view = new PortraitView(config);
|
||||
portrait_view->init(176 + x_off, 8 + y_off, font, party, player, tile_manager, obj_manager, portrait);
|
||||
|
||||
if (!Game::get_game()->is_new_style()) {
|
||||
//inventory_view = new InventoryView(config);
|
||||
//inventory_view->init(gui->get_screen(), this, 176+x_off,8+y_off, font, party, tile_manager, obj_manager);
|
||||
actor_view = new ActorView(config);
|
||||
actor_view->init(gui->get_screen(), this, 176 + x_off, 8 + y_off, font, party, tile_manager, obj_manager, portrait);
|
||||
|
||||
party_view = new PartyView(config);
|
||||
if (game_type == NUVIE_GAME_U6) {
|
||||
party_view->init(this, 168 + x_off, 6 + y_off, font, party, player, tile_manager, obj_manager);
|
||||
spell_view = new SpellView(config);
|
||||
} else {
|
||||
party_view->init(this, 176 + x_off, 6 + y_off, font, party, player, tile_manager, obj_manager);
|
||||
}
|
||||
if (game_type == NUVIE_GAME_MD) {
|
||||
if (Game::get_game()->is_new_style() == false) {
|
||||
mdSkyWidget = new MDSkyStripWidget(config, Game::get_game()->get_clock(), player);
|
||||
mdSkyWidget->init(32 + x_off, 2 + y_off);
|
||||
gui->AddWidget(mdSkyWidget);
|
||||
if (Game::get_game()->is_original_plus())
|
||||
mdSkyWidget->Hide();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//inventory_view = new InventoryViewGump(config);
|
||||
//inventory_view->init(gui->get_screen(), this, 176+x_off,8+y_off, font, party, tile_manager, obj_manager);
|
||||
if (game_type == NUVIE_GAME_U6) {
|
||||
spell_view = new SpellViewGump(config);
|
||||
ribbon = new SunMoonRibbon(player, Game::get_game()->get_weather(), tile_manager);
|
||||
ribbon->init(gui->get_screen());
|
||||
gui->AddWidget(ribbon);
|
||||
ribbon->Hide(); //will be shown on first call to update()
|
||||
}
|
||||
}
|
||||
|
||||
uint16 spell_x_offset = 168 + x_off;
|
||||
if (Game::get_game()->is_new_style()) {
|
||||
spell_x_offset = Game::get_game()->get_game_width() - SPELLVIEWGUMP_WIDTH + x_off;
|
||||
}
|
||||
|
||||
if (spell_view) {
|
||||
spell_view->init(gui->get_screen(), this, spell_x_offset, 6 + y_off, font, party, tile_manager, obj_manager);
|
||||
}
|
||||
//set_current_view((View *)party_view);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewManager::reload() {
|
||||
if (!Game::get_game()->is_new_style())
|
||||
actor_view->set_party_member(0);
|
||||
inventory_view->lock_to_actor(false);
|
||||
inventory_view->set_party_member(0);
|
||||
|
||||
set_party_mode();
|
||||
update();
|
||||
}
|
||||
|
||||
bool ViewManager::set_current_view(View *view) {
|
||||
uint8 cur_party_member;
|
||||
|
||||
//actor_view->set_party_member(cur_party_member);
|
||||
if (view == nullptr) // || game_type != NUVIE_GAME_U6) //HACK! remove this when views support MD and SE
|
||||
return false;
|
||||
|
||||
if (current_view == view) // nothing to do if view is already the current_view.
|
||||
return false;
|
||||
|
||||
if (current_view != nullptr) {
|
||||
gui->removeWidget((GUI_Widget *)current_view);//remove current widget from gui
|
||||
|
||||
cur_party_member = current_view->get_party_member_num();
|
||||
view->set_party_member(cur_party_member);
|
||||
}
|
||||
|
||||
current_view = view;
|
||||
view->Show();
|
||||
gui->AddWidget((GUI_Widget *)view);
|
||||
view->Redraw();
|
||||
gui->Display();
|
||||
|
||||
if (actor_view) {
|
||||
if (view != actor_view) {
|
||||
actor_view->set_show_cursor(false);
|
||||
actor_view->release_focus();
|
||||
}
|
||||
}
|
||||
|
||||
if (inventory_view) {
|
||||
if (view != inventory_view) {
|
||||
inventory_view->set_show_cursor(false);
|
||||
inventory_view->release_focus();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewManager::close_current_view() {
|
||||
if (current_view == nullptr)
|
||||
return;
|
||||
|
||||
gui->removeWidget((GUI_Widget *)current_view);//remove current widget from gui
|
||||
current_view = nullptr;
|
||||
}
|
||||
|
||||
void ViewManager::update() {
|
||||
if (current_view)
|
||||
current_view->Redraw();
|
||||
|
||||
if (ribbon && ribbon->Status() == WIDGET_HIDDEN) {
|
||||
ribbon->Show();
|
||||
}
|
||||
|
||||
if (mdSkyWidget) {
|
||||
mdSkyWidget->Redraw();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// We only change to portrait mode if the actor has a portrait.
|
||||
void ViewManager::set_portrait_mode(Actor *actor, const char *name) {
|
||||
if (portrait_view->set_portrait(actor, name) == true) {
|
||||
set_current_view((View *)portrait_view);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewManager::set_inventory_mode() {
|
||||
set_current_view((View *)inventory_view);
|
||||
Events *event = Game::get_game()->get_event();
|
||||
if (event->get_mode() == EQUIP_MODE || event->get_mode() == INPUT_MODE
|
||||
|| event->get_mode() == ATTACK_MODE)
|
||||
inventory_view->set_show_cursor(true);
|
||||
}
|
||||
|
||||
void ViewManager::set_party_mode() {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
if (event->get_mode() == EQUIP_MODE)
|
||||
event->cancelAction();
|
||||
else if (event->get_mode() == INPUT_MODE || event->get_mode() == ATTACK_MODE)
|
||||
event->moveCursorToMapWindow();
|
||||
|
||||
if (!Game::get_game()->is_new_style())
|
||||
set_current_view((View *)party_view);
|
||||
return;
|
||||
}
|
||||
|
||||
void ViewManager::set_actor_mode() {
|
||||
set_current_view((View *)actor_view);
|
||||
Events *event = Game::get_game()->get_event();
|
||||
if (event->get_mode() == EQUIP_MODE || event->get_mode() == INPUT_MODE
|
||||
|| event->get_mode() == ATTACK_MODE) {
|
||||
actor_view->set_show_cursor(true);
|
||||
actor_view->moveCursorToButton(2);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewManager::set_spell_mode(Actor *caster, Obj *spell_container, bool eventMode) {
|
||||
if (spell_view != nullptr) {
|
||||
spell_view->set_spell_caster(caster, spell_container, eventMode);
|
||||
set_current_view((View *)spell_view);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void ViewManager::close_spell_mode() {
|
||||
if (spell_view) {
|
||||
//FIXME this should set previous view. Don't default to inventory view.
|
||||
spell_view->release_focus();
|
||||
if (!Game::get_game()->is_new_style())
|
||||
set_inventory_mode();
|
||||
else
|
||||
close_current_view();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewManager::open_doll_view(Actor *actor) {
|
||||
Screen *screen = Game::get_game()->get_screen();
|
||||
|
||||
if (Game::get_game()->is_new_style()) {
|
||||
if (actor == nullptr) {
|
||||
actor = doll_view_get_next_party_member();
|
||||
}
|
||||
DollViewGump *doll = get_doll_view(actor);
|
||||
if (doll == nullptr) {
|
||||
uint16 x_off = Game::get_game()->get_game_x_offset();
|
||||
uint16 y_off = Game::get_game()->get_game_y_offset();
|
||||
uint8 num_doll_gumps = doll_gumps.size();
|
||||
doll = new DollViewGump(config);
|
||||
uint16 x = 12 * num_doll_gumps;
|
||||
uint16 y = 12 * num_doll_gumps;
|
||||
|
||||
if (y + DOLLVIEWGUMP_HEIGHT > screen->get_height())
|
||||
y = screen->get_height() - DOLLVIEWGUMP_HEIGHT;
|
||||
|
||||
doll->init(Game::get_game()->get_screen(), this, x + x_off, y + y_off, actor, font, party, tile_manager, obj_manager);
|
||||
|
||||
add_view((View *)doll);
|
||||
add_gump(doll);
|
||||
doll_gumps.push_back(doll);
|
||||
} else {
|
||||
move_gump_to_top(doll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Actor *ViewManager::doll_view_get_next_party_member() {
|
||||
if (doll_gumps.empty()) {
|
||||
doll_next_party_member = 0; //reset to first party member when there are no doll gumps on screen.
|
||||
}
|
||||
Actor *a = party->get_actor(doll_next_party_member);
|
||||
doll_next_party_member = (doll_next_party_member + 1) % party->get_party_size();
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
DollViewGump *ViewManager::get_doll_view(Actor *actor) {
|
||||
for (DraggableView *draggable : doll_gumps) {
|
||||
DollViewGump *view = (DollViewGump *)draggable;
|
||||
if (view->get_actor() == actor) {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ContainerViewGump *ViewManager::get_container_view(Actor *actor, Obj *obj) {
|
||||
for (DraggableView *draggable : container_gumps) {
|
||||
ContainerViewGump *view = (ContainerViewGump *)draggable;
|
||||
if (actor) {
|
||||
if (view->is_actor_container() && view->get_actor() == actor) {
|
||||
return view;
|
||||
}
|
||||
} else if (obj) {
|
||||
if (!view->is_actor_container() && view->get_container_obj() == obj) {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ViewManager::open_container_view(Actor *actor, Obj *obj) {
|
||||
ContainerViewGump *view = get_container_view(actor, obj);
|
||||
|
||||
if (view == nullptr) {
|
||||
uint16 x_off = Game::get_game()->get_game_x_offset();
|
||||
uint16 y_off = Game::get_game()->get_game_y_offset();
|
||||
uint16 container_x, container_y;
|
||||
if (!Game::get_game()->is_new_style()) {
|
||||
container_x = x_off;
|
||||
container_y = y_off;
|
||||
} else {
|
||||
container_x = Game::get_game()->get_game_width() - 120 + x_off;
|
||||
container_y = 20 + y_off;
|
||||
}
|
||||
|
||||
view = new ContainerViewGump(config);
|
||||
view->init(Game::get_game()->get_screen(), this, container_x, container_y, font, party, tile_manager, obj_manager, obj);
|
||||
if (actor)
|
||||
view->set_actor(actor);
|
||||
else
|
||||
view->set_container_obj(obj);
|
||||
|
||||
container_gumps.push_back(view);
|
||||
add_gump(view);
|
||||
add_view((View *)view);
|
||||
} else {
|
||||
move_gump_to_top(view);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewManager::close_container_view(Actor *actor) {
|
||||
ContainerViewGump *view = get_container_view(actor, nullptr);
|
||||
|
||||
if (view) {
|
||||
close_gump(view);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewManager::open_mapeditor_view() {
|
||||
if (Game::get_game()->is_new_style() && Game::get_game()->is_roof_mode()) {
|
||||
uint16 x_off = Game::get_game()->get_game_x_offset();
|
||||
uint16 y_off = Game::get_game()->get_game_y_offset();
|
||||
x_off += Game::get_game()->get_game_width() - 90;
|
||||
MapEditorView *view = new MapEditorView(config);
|
||||
view->init(Game::get_game()->get_screen(), this, x_off , y_off, font, party, tile_manager, obj_manager);
|
||||
add_view((View *)view);
|
||||
view->grab_focus();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewManager::open_portrait_gump(Actor *a) {
|
||||
if (Game::get_game()->is_new_style()) {
|
||||
uint16 x_off = Game::get_game()->get_game_x_offset();
|
||||
uint16 y_off = Game::get_game()->get_game_y_offset();
|
||||
PortraitViewGump *view = new PortraitViewGump(config);
|
||||
view->init(Game::get_game()->get_screen(), this, 62 + x_off, y_off, font, party, tile_manager, obj_manager, portrait, a);
|
||||
add_view((View *)view);
|
||||
add_gump(view);
|
||||
view->grab_focus();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewManager::open_sign_gump(const char *sign_text, uint16 length) {
|
||||
if (Game::get_game()->is_using_text_gumps()) { // check should be useless
|
||||
SignViewGump *view = new SignViewGump(config);
|
||||
view->init(Game::get_game()->get_screen(), this, font, party, tile_manager, obj_manager, sign_text, length);
|
||||
add_view((View *)view);
|
||||
add_gump(view);
|
||||
view->grab_focus();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewManager::open_scroll_gump(const char *text, uint16 length) {
|
||||
if (Game::get_game()->is_using_text_gumps()) { // check should be useless
|
||||
ScrollViewGump *view = new ScrollViewGump(config);
|
||||
view->init(Game::get_game()->get_screen(), this, font, party, tile_manager, obj_manager, string(text, length));
|
||||
add_view((View *)view);
|
||||
add_gump(view);
|
||||
view->grab_focus();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewManager::add_view(View *view) {
|
||||
view->Show();
|
||||
gui->AddWidget((GUI_Widget *)view);
|
||||
if (Game::get_game()->is_new_style()) {
|
||||
Game::get_game()->get_scroll()->moveToFront();
|
||||
}
|
||||
view->Redraw();
|
||||
gui->Display();
|
||||
}
|
||||
|
||||
void ViewManager::add_gump(DraggableView *gump) {
|
||||
gumps.push_back(gump);
|
||||
Game::get_game()->get_map_window()->set_walking(false);
|
||||
if (ribbon) {
|
||||
ribbon->extend();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewManager::close_gump(DraggableView *gump) {
|
||||
gumps.remove(gump);
|
||||
container_gumps.remove(gump);
|
||||
doll_gumps.remove(gump);
|
||||
|
||||
gump->close_view();
|
||||
gump->Delete();
|
||||
//gui->removeWidget((GUI_Widget *)gump);
|
||||
|
||||
if (gumps.empty() && ribbon != nullptr) {
|
||||
ribbon->retract();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewManager::close_all_gumps() {
|
||||
while (!gumps.empty())
|
||||
close_gump(gumps.front());
|
||||
//TODO make sure all gump objects have been deleted by GUI.
|
||||
}
|
||||
|
||||
void ViewManager::move_gump_to_top(DraggableView *gump) {
|
||||
gump->moveToFront();
|
||||
Game::get_game()->get_scroll()->moveToFront();
|
||||
}
|
||||
|
||||
// callbacks for switching views
|
||||
|
||||
GUI_status partyViewButtonCallback(void *data) {
|
||||
ViewManager *view_manager;
|
||||
|
||||
view_manager = (ViewManager *)data;
|
||||
|
||||
view_manager->set_party_mode();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status actorViewButtonCallback(void *data) {
|
||||
ViewManager *view_manager;
|
||||
|
||||
view_manager = (ViewManager *)data;
|
||||
|
||||
view_manager->set_actor_mode();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status inventoryViewButtonCallback(void *data) {
|
||||
ViewManager *view_manager;
|
||||
|
||||
view_manager = (ViewManager *)data;
|
||||
|
||||
view_manager->set_inventory_mode();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void ViewManager::double_click_obj(Obj *obj) {
|
||||
Events *event = Game::get_game()->get_event();
|
||||
if (Game::get_game()->get_usecode()->is_readable(obj)) { // look at a scroll or book
|
||||
event->set_mode(LOOK_MODE);
|
||||
event->look(obj);
|
||||
event->endAction(false); // FIXME: should be in look()
|
||||
} else if (event->newAction(USE_MODE))
|
||||
event->select_obj(obj);
|
||||
}
|
||||
|
||||
unsigned int ViewManager::get_display_weight(float weight) {
|
||||
if (weight > 1)
|
||||
return static_cast<unsigned int>(roundf(weight));
|
||||
else if (weight > 0)
|
||||
return 1;
|
||||
else // weight == 0 (or somehow negative)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// beginning of custom doll functions shared between DollWidget and DollViewGump
|
||||
Common::Path ViewManager::getDollDataDirString() {
|
||||
if (!DollDataDirString.empty())
|
||||
return DollDataDirString;
|
||||
DollDataDirString = GUI::get_gui()->get_data_dir();
|
||||
Common::Path path;
|
||||
build_path(DollDataDirString, "images", path);
|
||||
DollDataDirString = path;
|
||||
build_path(DollDataDirString, "gumps", path);
|
||||
DollDataDirString = path;
|
||||
build_path(DollDataDirString, "doll", path);
|
||||
DollDataDirString = path;
|
||||
|
||||
return DollDataDirString;
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *ViewManager::loadAvatarDollImage(Graphics::ManagedSurface *avatar_doll, bool orig) {
|
||||
char filename[17]; //avatar_nn_nn.bmp\0
|
||||
Common::Path imagefile;
|
||||
uint8 portrait_num = Game::get_game()->get_portrait()->get_avatar_portrait_num();
|
||||
|
||||
Common::sprintf_s(filename, "avatar_%s_%02d.bmp", get_game_tag(Game::get_game()->get_game_type()), portrait_num);
|
||||
if (orig) {
|
||||
build_path(getDollDataDirString(), "orig_style", imagefile);
|
||||
build_path(imagefile, filename, imagefile);
|
||||
} else {
|
||||
build_path(getDollDataDirString(), filename, imagefile);
|
||||
}
|
||||
if (avatar_doll)
|
||||
delete avatar_doll;
|
||||
NuvieBmpFile bmp;
|
||||
avatar_doll = bmp.getSdlSurface32(imagefile);
|
||||
if (avatar_doll == nullptr)
|
||||
avatar_doll = loadGenericDollImage(orig);
|
||||
return avatar_doll;
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *ViewManager::loadCustomActorDollImage(Graphics::ManagedSurface *actor_doll, uint8 actor_num, bool orig) {
|
||||
char filename[17]; //actor_nn_nnn.bmp\0
|
||||
Common::Path imagefile;
|
||||
|
||||
if (actor_doll)
|
||||
delete actor_doll;
|
||||
|
||||
Common::sprintf_s(filename, "actor_%s_%03d.bmp", get_game_tag(Game::get_game()->get_game_type()), actor_num);
|
||||
if (orig) {
|
||||
build_path(getDollDataDirString(), "orig_style", imagefile);
|
||||
build_path(imagefile, filename, imagefile);
|
||||
} else {
|
||||
build_path(getDollDataDirString(), filename, imagefile);
|
||||
}
|
||||
NuvieBmpFile bmp;
|
||||
actor_doll = bmp.getSdlSurface32(imagefile);
|
||||
|
||||
if (actor_doll == nullptr)
|
||||
actor_doll = loadGenericDollImage(orig);
|
||||
return actor_doll;
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *ViewManager::loadGenericDollImage(bool orig) {
|
||||
char filename[14]; //avatar_nn.bmp\0
|
||||
Common::Path imagefile;
|
||||
|
||||
Common::sprintf_s(filename, "actor_%s.bmp", get_game_tag(Game::get_game()->get_game_type()));
|
||||
if (orig) {
|
||||
build_path(getDollDataDirString(), "orig_style", imagefile);
|
||||
build_path(imagefile, filename, imagefile);
|
||||
} else {
|
||||
build_path(getDollDataDirString(), filename, imagefile);
|
||||
}
|
||||
NuvieBmpFile bmp;
|
||||
return bmp.getSdlSurface32(imagefile);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
175
engines/ultima/nuvie/views/view_manager.h
Normal file
175
engines/ultima/nuvie/views/view_manager.h
Normal file
@@ -0,0 +1,175 @@
|
||||
/* 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 NUVIE_VIEWS_VIEW_MANAGER_H
|
||||
#define NUVIE_VIEWS_VIEW_MANAGER_H
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class GUI;
|
||||
class TileManager;
|
||||
class ObjManager;
|
||||
class Portrait;
|
||||
class Party;
|
||||
class Player;
|
||||
class Font;
|
||||
class Actor;
|
||||
class Obj;
|
||||
|
||||
class View;
|
||||
class PartyView;
|
||||
class PortraitView;
|
||||
class InventoryView;
|
||||
class ActorView;
|
||||
class SpellView;
|
||||
class ContainerViewGump;
|
||||
class DollViewGump;
|
||||
class DraggableView;
|
||||
class SunMoonRibbon;
|
||||
class MDSkyStripWidget;
|
||||
|
||||
using Std::list;
|
||||
|
||||
typedef enum { CURSOR_HEAD, CURSOR_NECK, CURSOR_CHEST, CURSOR_RIGHT_HAND, CURSOR_LEFT_HAND, CURSOR_RIGHT_RING, CURSOR_LEFT_RING, CURSOR_FEET,
|
||||
CURSOR_LEFT, CURSOR_RIGHT, CURSOR_COMBAT, CURSOR_CHECK, CURSOR_HEART, CURSOR_PARTY, CURSOR_INVENTORY
|
||||
} gumpCursorPos;
|
||||
|
||||
class ViewManager {
|
||||
protected:
|
||||
|
||||
const Configuration *config;
|
||||
int game_type;
|
||||
GUI *gui;
|
||||
Font *font;
|
||||
TileManager *tile_manager;
|
||||
ObjManager *obj_manager;
|
||||
Party *party;
|
||||
Portrait *portrait;
|
||||
|
||||
ActorView *actor_view;
|
||||
InventoryView *inventory_view;
|
||||
PortraitView *portrait_view;
|
||||
PartyView *party_view;
|
||||
SpellView *spell_view;
|
||||
|
||||
View *current_view;
|
||||
|
||||
Std::list<DraggableView *> container_gumps;
|
||||
Std::list<DraggableView *> doll_gumps;
|
||||
Std::list<DraggableView *> gumps;
|
||||
|
||||
uint8 doll_next_party_member;
|
||||
|
||||
SunMoonRibbon *ribbon;
|
||||
MDSkyStripWidget *mdSkyWidget;
|
||||
|
||||
Common::Path DollDataDirString;
|
||||
|
||||
public:
|
||||
|
||||
ViewManager(const Configuration *cfg);
|
||||
virtual ~ViewManager();
|
||||
|
||||
bool init(GUI *g, Font *f, Party *p, Player *player, TileManager *tm, ObjManager *om, Portrait *por);
|
||||
void reload();
|
||||
|
||||
void update();
|
||||
|
||||
void set_portrait_mode(Actor *actor, const char *name);
|
||||
void set_inventory_mode();
|
||||
void set_party_mode();
|
||||
void set_actor_mode();
|
||||
void set_spell_mode(Actor *caster, Obj *spell_container, bool eventMode = false);
|
||||
|
||||
void close_spell_mode();
|
||||
|
||||
View *get_current_view() {
|
||||
return current_view;
|
||||
}
|
||||
ActorView *get_actor_view() {
|
||||
return actor_view;
|
||||
}
|
||||
InventoryView *get_inventory_view() {
|
||||
return inventory_view;
|
||||
}
|
||||
PortraitView *get_portrait_view() {
|
||||
return portrait_view;
|
||||
}
|
||||
PartyView *get_party_view() {
|
||||
return party_view;
|
||||
}
|
||||
SpellView *get_spell_view() {
|
||||
return spell_view;
|
||||
}
|
||||
MDSkyStripWidget *get_mdSkyWidget() {
|
||||
return mdSkyWidget;
|
||||
}
|
||||
|
||||
void close_current_view();
|
||||
|
||||
void open_doll_view(Actor *actor);
|
||||
|
||||
void open_container_view(Obj *obj) {
|
||||
open_container_view(nullptr, obj);
|
||||
}
|
||||
void open_container_view(Actor *actor) {
|
||||
open_container_view(actor, nullptr);
|
||||
}
|
||||
|
||||
void close_container_view(Actor *actor);
|
||||
|
||||
void open_mapeditor_view();
|
||||
void open_portrait_gump(Actor *a);
|
||||
void open_sign_gump(const char *sign_text, uint16 length);
|
||||
void open_scroll_gump(const char *text, uint16 length);
|
||||
void close_gump(DraggableView *gump);
|
||||
void close_all_gumps();
|
||||
bool gumps_are_active() {
|
||||
return !gumps.empty();
|
||||
}
|
||||
|
||||
bool set_current_view(View *view);
|
||||
void double_click_obj(Obj *obj);
|
||||
unsigned int get_display_weight(float weight);
|
||||
|
||||
// custom doll functions shared between DollWidget and DollViewGump
|
||||
Common::Path getDollDataDirString();
|
||||
Graphics::ManagedSurface *loadAvatarDollImage(Graphics::ManagedSurface *avatar_doll, bool orig = false);
|
||||
Graphics::ManagedSurface *loadCustomActorDollImage(Graphics::ManagedSurface *actor_doll, uint8 actor_num, bool orig = false);
|
||||
Graphics::ManagedSurface *loadGenericDollImage(bool orig);
|
||||
|
||||
protected:
|
||||
|
||||
Actor *doll_view_get_next_party_member();
|
||||
DollViewGump *get_doll_view(Actor *actor);
|
||||
ContainerViewGump *get_container_view(Actor *actor, Obj *obj);
|
||||
void open_container_view(Actor *actor, Obj *obj);
|
||||
void add_gump(DraggableView *gump);
|
||||
void add_view(View *view);
|
||||
void move_gump_to_top(DraggableView *gump);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user