1 /*
2 * This file is part of EasyRPG Player.
3 *
4 * EasyRPG Player is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * EasyRPG Player is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 // Headers
19 #include <lcf/data.h>
20 #include "color.h"
21 #include "cache.h"
22 #include "input.h"
23 #include "player.h"
24 #include "game_system.h"
25 #include "game_actors.h"
26 #include "window_battlecommand.h"
27 #include "bitmap.h"
28
Window_BattleCommand(int x,int y,int width,int height)29 Window_BattleCommand::Window_BattleCommand(int x, int y, int width, int height) :
30 Window_Base(x, y, width, height) {
31
32 SetActor(0);
33
34 disabled.resize(commands.size());
35 index = -1;
36 top_row = 0;
37 cycle = 0;
38
39 SetContents(Bitmap::Create(width - 16, height - 16));
40
41 num_rows = contents->GetHeight() / 16;
42
43 Refresh();
44 }
45
SetEnabled(int index,bool enabled)46 void Window_BattleCommand::SetEnabled(int index, bool enabled) {
47 disabled[index] = enabled;
48 Refresh();
49 }
50
SetActive(bool active)51 void Window_BattleCommand::SetActive(bool active) {
52 index = active ? 0 : -1;
53 top_row = 0;
54 Window::SetActive(active);
55 Refresh();
56 }
57
Update()58 void Window_BattleCommand::Update() {
59 Window_Base::Update();
60
61 size_t num_commands = commands.size();
62 int old_index = index;
63 if (active && num_commands > 0 && index >= 0) {
64 if (Input::IsRepeated(Input::DOWN) || Input::IsTriggered(Input::SCROLL_DOWN)) {
65 Main_Data::game_system->SePlay(Main_Data::game_system->GetSystemSE(Main_Data::game_system->SFX_Cursor));
66 index++;
67 }
68
69 if (Input::IsRepeated(Input::UP) || Input::IsTriggered(Input::SCROLL_UP)) {
70 Main_Data::game_system->SePlay(Main_Data::game_system->GetSystemSE(Main_Data::game_system->SFX_Cursor));
71 index--;
72 }
73
74 index += num_commands;
75 index %= num_commands;
76
77 if (index < top_row)
78 top_row = index;
79 if (index > top_row + num_rows - 1)
80 top_row = index - num_rows + 1;
81
82 cycle++;
83 if (cycle % 20 == 0 || old_index != index)
84 Refresh();
85 }
86
87 UpdateCursorRect();
88 }
89
UpdateCursorRect()90 void Window_BattleCommand::UpdateCursorRect() {
91 if (index >= 0)
92 SetCursorRect(Rect(0, (index - top_row) * 16, contents->GetWidth(), 16));
93 else
94 SetCursorRect(Rect());
95 }
96
Refresh()97 void Window_BattleCommand::Refresh() {
98 if (!contents)
99 return;
100
101 size_t num_commands = commands.size();
102
103 contents->Clear();
104 for (unsigned int i = 0; i < num_commands; i++) {
105 Font::SystemColor color = disabled[i] ? Font::ColorDisabled : Font::ColorDefault;
106 DrawItem(i, color);
107 }
108
109 SetUpArrow(false);
110 SetDownArrow(false);
111 if (active && (cycle / 20) % 2 == 0) {
112 if (top_row > 0)
113 SetUpArrow(true);
114 if (top_row + num_rows < (int) num_commands)
115 SetDownArrow(true);
116 }
117 }
118
DrawItem(int index,Font::SystemColor color)119 void Window_BattleCommand::DrawItem(int index, Font::SystemColor color) {
120 int y = 16 * (index - top_row);
121 if (y < 0 || y + 16 > contents->GetHeight())
122 return;
123 contents->ClearRect(Rect(0, y, contents->GetWidth(), 16));
124 contents->TextDraw(2, y + 2, color, commands[index]);
125 }
126
GetIndex()127 int Window_BattleCommand::GetIndex() {
128 return index;
129 }
130
SetIndex(int _index)131 void Window_BattleCommand::SetIndex(int _index) {
132 index = _index;
133 }
134
SetActor(int _actor_id)135 void Window_BattleCommand::SetActor(int _actor_id) {
136 actor_id = (Player::IsRPG2k()) ? 0 : _actor_id;
137 commands.clear();
138
139 if (actor_id == 0) {
140 commands.push_back(!lcf::Data::terms.command_attack.empty() ? ToString(lcf::Data::terms.command_attack) : "Attack");
141 commands.push_back(!lcf::Data::terms.command_defend.empty() ? ToString(lcf::Data::terms.command_defend) : "Defend");
142 commands.push_back(!lcf::Data::terms.command_item.empty() ? ToString(lcf::Data::terms.command_item) : "Item");
143 commands.push_back(!lcf::Data::terms.command_skill.empty() ? ToString(lcf::Data::terms.command_skill) : "Skill");
144 }
145 else {
146 Game_Actor* actor = Main_Data::game_actors->GetActor(actor_id);
147 const std::vector<const lcf::rpg::BattleCommand*> bcmds = actor->GetBattleCommands();
148 for (const lcf::rpg::BattleCommand* command : bcmds) {
149 commands.push_back(ToString(command->name));
150 }
151 }
152
153 disabled.resize(commands.size());
154 Refresh();
155 }
156
GetSkillSubset()157 int Window_BattleCommand::GetSkillSubset() {
158 if (actor_id == 0)
159 return lcf::rpg::Skill::Type_normal;
160
161 Game_Actor* actor = Main_Data::game_actors->GetActor(actor_id);
162 const std::vector<const lcf::rpg::BattleCommand*> bcmds = actor->GetBattleCommands();
163 int bcmd = bcmds[index]->ID;
164
165 int idx = 4;
166 for (int i = 0; i < bcmd - 1; i++) {
167 const lcf::rpg::BattleCommand& command = lcf::Data::battlecommands.commands[i];
168 if (command.type == lcf::rpg::BattleCommand::Type_subskill)
169 idx++;
170 }
171
172 return idx;
173 }
174