1 ////////////////////////////////////////////////////////////////////////////////
2 // Copyright (C) 2004-2011 by The Allacrost Project
3 // Copyright (C) 2012-2016 by Bertram (Valyria Tear)
4 // All Rights Reserved
5 //
6 // This code is licensed under the GNU GPL version 2. It is free software and
7 // you may modify it and/or redistribute it under the terms of this license.
8 // See https://www.gnu.org/copyleft/gpl.html for details.
9 ////////////////////////////////////////////////////////////////////////////////
10
11 #include "command_settings.h"
12
13 #include "modes/battle/objects/battle_character.h"
14
15 #include "engine/video/video.h"
16
17 #include "common/global/global.h"
18 #include "common/global/media/battle_media.h"
19 #include "common/global/actors/global_character.h"
20
21 using namespace vt_global;
22 using namespace vt_gui;
23 using namespace vt_utils;
24 using namespace vt_video;
25
26 namespace vt_battle
27 {
28
29 namespace private_battle
30 {
31
32 const float LIST_POSITION_X = 140.0f;
33 const float LIST_POSITION_Y = 15.0f;
34 const float LIST_SIZE_X = 350.0f;
35 const float LIST_SIZE_Y = 100.0f;
36
37 // Offset used to properly align the target icons in the skill and item selection lists
38 const uint32_t TARGET_ICON_OFFSET = 288;
39
CommandSettings(BattleCharacter * character,MenuWindow & window)40 CommandSettings::CommandSettings(BattleCharacter* character, MenuWindow& window) :
41 _character(character),
42 _last_category(CATEGORY_WEAPON),
43 _last_item(0),
44 _last_self_target(BattleTarget()),
45 _last_character_target(BattleTarget()),
46 _last_enemy_target(BattleTarget())
47 {
48 _weapon_skill_list.SetOwner(&window);
49 _weapon_skill_list.SetPosition(LIST_POSITION_X, LIST_POSITION_Y);
50 _weapon_skill_list.SetDimensions(LIST_SIZE_X, LIST_SIZE_Y, 1, 255, 1, 4);
51 _weapon_skill_list.SetAlignment(VIDEO_X_LEFT, VIDEO_Y_TOP);
52 _weapon_skill_list.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
53 _weapon_skill_list.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
54 _weapon_skill_list.SetTextStyle(TextStyle("text20"));
55 _weapon_skill_list.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
56 _weapon_skill_list.SetCursorOffset(-50.0f, -25.0f);
57 _weapon_skill_list.AnimateScrolling(false);
58
59 _weapon_target_list.SetOwner(&window);
60 _weapon_target_list.SetPosition(LIST_POSITION_X + TARGET_ICON_OFFSET, LIST_POSITION_Y);
61 _weapon_target_list.SetDimensions(LIST_SIZE_X - TARGET_ICON_OFFSET, LIST_SIZE_Y, 1, 255, 1, 4);
62 _weapon_target_list.SetAlignment(VIDEO_X_LEFT, VIDEO_Y_TOP);
63 _weapon_target_list.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
64 _weapon_target_list.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
65 _weapon_target_list.SetTextStyle(TextStyle("text20"));
66 _weapon_target_list.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
67 _weapon_target_list.AnimateScrolling(false);
68
69 _magic_skill_list.SetOwner(&window);
70 _magic_skill_list.SetPosition(LIST_POSITION_X, LIST_POSITION_Y);
71 _magic_skill_list.SetDimensions(LIST_SIZE_X, LIST_SIZE_Y, 1, 255, 1, 4);
72 _magic_skill_list.SetAlignment(VIDEO_X_LEFT, VIDEO_Y_TOP);
73 _magic_skill_list.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
74 _magic_skill_list.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
75 _magic_skill_list.SetTextStyle(TextStyle("text20"));
76 _magic_skill_list.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
77 _magic_skill_list.SetCursorOffset(-50.0f, -25.0f);
78 _magic_skill_list.AnimateScrolling(false);
79
80 _magic_target_list.SetOwner(&window);
81 _magic_target_list.SetPosition(LIST_POSITION_X + TARGET_ICON_OFFSET, LIST_POSITION_Y);
82 _magic_target_list.SetDimensions(LIST_SIZE_X - TARGET_ICON_OFFSET, LIST_SIZE_Y, 1, 255, 1, 4);
83 _magic_target_list.SetAlignment(VIDEO_X_LEFT, VIDEO_Y_TOP);
84 _magic_target_list.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
85 _magic_target_list.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
86 _magic_target_list.SetTextStyle(TextStyle("text20"));
87 _magic_target_list.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
88 _magic_target_list.AnimateScrolling(false);
89
90 _special_skill_list.SetOwner(&window);
91 _special_skill_list.SetPosition(LIST_POSITION_X, LIST_POSITION_Y);
92 _special_skill_list.SetDimensions(LIST_SIZE_X, LIST_SIZE_Y, 1, 255, 1, 4);
93 _special_skill_list.SetAlignment(VIDEO_X_LEFT, VIDEO_Y_TOP);
94 _special_skill_list.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
95 _special_skill_list.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
96 _special_skill_list.SetTextStyle(TextStyle("text20"));
97 _special_skill_list.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
98 _special_skill_list.SetCursorOffset(-50.0f, -25.0f);
99 _special_skill_list.AnimateScrolling(false);
100
101 _special_target_list.SetOwner(&window);
102 _special_target_list.SetPosition(LIST_POSITION_X + TARGET_ICON_OFFSET, LIST_POSITION_Y);
103 _special_target_list.SetDimensions(LIST_SIZE_X - TARGET_ICON_OFFSET, LIST_SIZE_Y, 1, 255, 1, 4);
104 _special_target_list.SetAlignment(VIDEO_X_LEFT, VIDEO_Y_TOP);
105 _special_target_list.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
106 _special_target_list.SetVerticalWrapMode(VIDEO_WRAP_MODE_STRAIGHT);
107 _special_target_list.SetTextStyle(TextStyle("text20"));
108 _special_target_list.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
109 _special_target_list.AnimateScrolling(false);
110
111 if(_character == nullptr) {
112 PRINT_WARNING << "constructor received nullptr character pointer" << std::endl;
113 return;
114 }
115
116 BattleMedia& battle_media = GlobalManager->GetBattleMedia();
117
118 // Construct the weapon, magic, and special skill lists for the character
119 std::vector<GlobalSkill *>* skill_list = nullptr;
120 std::shared_ptr<GlobalWeapon> char_wpn = _character->GetGlobalCharacter()->GetEquippedWeapon();
121
122 if (char_wpn)
123 skill_list = _character->GetGlobalCharacter()->GetWeaponSkills();
124 else
125 skill_list = _character->GetGlobalCharacter()->GetBareHandsSkills();
126 for(uint32_t i = 0; i < skill_list->size(); i++) {
127 _weapon_skill_list.AddOption(ustring());
128 if (!skill_list->at(i)->GetIconFilename().empty()) {
129 _weapon_skill_list.AddOptionElementImage(i, skill_list->at(i)->GetIconFilename());
130 _weapon_skill_list.GetEmbeddedImage(i)->SetHeightKeepRatio(25);
131 _weapon_skill_list.AddOptionElementPosition(i, 30);
132 }
133 else {
134 // Check for the weapon icon
135 std::string wpn_icon_filename;
136 if (char_wpn)
137 wpn_icon_filename = char_wpn->GetIconImage().GetFilename();
138 else
139 wpn_icon_filename = "data/inventory/weapons/fist-human.png";
140
141 if (!wpn_icon_filename.empty()) {
142 _weapon_skill_list.AddOptionElementImage(i, wpn_icon_filename);
143 _weapon_skill_list.GetEmbeddedImage(i)->SetHeightKeepRatio(25);
144 _weapon_skill_list.AddOptionElementPosition(i, 30);
145 }
146 }
147 _weapon_skill_list.AddOptionElementText(i, skill_list->at(i)->GetName());
148
149 _weapon_target_list.AddOption(ustring());
150 _weapon_target_list.AddOptionElementImage(i, battle_media.GetTargetTypeIcon(skill_list->at(i)->GetTargetType()));
151 _weapon_target_list.AddOptionElementPosition(i, 45);
152 _weapon_target_list.AddOptionElementText(i, MakeUnicodeString(NumberToString(skill_list->at(i)->GetSPRequired())));
153 if(skill_list->at(i)->GetSPRequired() > _character->GetGlobalCharacter()->GetSkillPoints()) {
154 _weapon_skill_list.EnableOption(i, false);
155 _weapon_target_list.EnableOption(i, false);
156 }
157 }
158 if(!skill_list->empty()) {
159 _weapon_skill_list.SetSelection(0);
160 _weapon_target_list.SetSelection(0);
161 }
162
163 skill_list = _character->GetGlobalCharacter()->GetMagicSkills();
164 for(uint32_t i = 0; i < skill_list->size(); i++) {
165 _magic_skill_list.AddOption(ustring());
166 if (!skill_list->at(i)->GetIconFilename().empty()) {
167 _magic_skill_list.AddOptionElementImage(i, skill_list->at(i)->GetIconFilename());
168 _magic_skill_list.GetEmbeddedImage(i)->SetHeightKeepRatio(25);
169 _magic_skill_list.AddOptionElementPosition(i, 30);
170 }
171 _magic_skill_list.AddOptionElementText(i, skill_list->at(i)->GetName());
172
173 _magic_target_list.AddOption(ustring());
174 _magic_target_list.AddOptionElementImage(i, battle_media.GetTargetTypeIcon(skill_list->at(i)->GetTargetType()));
175 _magic_target_list.AddOptionElementPosition(i, 45);
176 _magic_target_list.AddOptionElementText(i, MakeUnicodeString(NumberToString(skill_list->at(i)->GetSPRequired())));
177 if(skill_list->at(i)->GetSPRequired() > _character->GetGlobalCharacter()->GetSkillPoints()) {
178 _magic_skill_list.EnableOption(i, false);
179 _magic_target_list.EnableOption(i, false);
180 }
181 }
182 if(!skill_list->empty()) {
183 _magic_skill_list.SetSelection(0);
184 _magic_target_list.SetSelection(0);
185 }
186
187 skill_list = _character->GetGlobalCharacter()->GetSpecialSkills();
188 for(uint32_t i = 0; i < skill_list->size(); i++) {
189 _special_skill_list.AddOption(ustring());
190 if (!skill_list->at(i)->GetIconFilename().empty()) {
191 _special_skill_list.AddOptionElementImage(i, skill_list->at(i)->GetIconFilename());
192 _special_skill_list.GetEmbeddedImage(i)->SetHeightKeepRatio(25);
193 _special_skill_list.AddOptionElementPosition(i, 30);
194 }
195 _special_skill_list.AddOptionElementText(i, skill_list->at(i)->GetName());
196
197 _special_target_list.AddOption(ustring());
198 _special_target_list.AddOptionElementImage(i, battle_media.GetTargetTypeIcon(skill_list->at(i)->GetTargetType()));
199 _special_target_list.AddOptionElementPosition(i, 45);
200 _special_target_list.AddOptionElementText(i, MakeUnicodeString(NumberToString(skill_list->at(i)->GetSPRequired())));
201 if(skill_list->at(i)->GetSPRequired() > _character->GetGlobalCharacter()->GetSkillPoints()) {
202 _special_skill_list.EnableOption(i, false);
203 _special_target_list.EnableOption(i, false);
204 }
205 }
206 if(!skill_list->empty()) {
207 _special_skill_list.SetSelection(0);
208 _special_target_list.SetSelection(0);
209 }
210 }
211
RefreshLists()212 void CommandSettings::RefreshLists()
213 {
214 uint32_t require_sp = 0xFFFFFFFF;
215 uint32_t current_sp = _character->GetSkillPoints();
216 std::vector<GlobalSkill *>* skill_list = nullptr;
217
218 skill_list = _character->GetGlobalCharacter()->GetWeaponSkills();
219 for(uint32_t i = 0; i < skill_list->size(); ++i) {
220 require_sp = skill_list->at(i)->GetSPRequired();
221 if(require_sp > current_sp) {
222 _weapon_skill_list.EnableOption(i, false);
223 _weapon_target_list.EnableOption(i, false);
224 }
225 else {
226 _weapon_skill_list.EnableOption(i, true);
227 _weapon_target_list.EnableOption(i, true);
228 }
229 }
230
231 skill_list = _character->GetGlobalCharacter()->GetMagicSkills();
232 for(uint32_t i = 0; i < skill_list->size(); ++i) {
233 require_sp = skill_list->at(i)->GetSPRequired();
234 if(require_sp > current_sp) {
235 _magic_skill_list.EnableOption(i, false);
236 _magic_target_list.EnableOption(i, false);
237 }
238 else {
239 _magic_skill_list.EnableOption(i, true);
240 _magic_target_list.EnableOption(i, true);
241 }
242 }
243
244 skill_list = _character->GetGlobalCharacter()->GetSpecialSkills();
245 for(uint32_t i = 0; i < skill_list->size(); ++i) {
246 require_sp = skill_list->at(i)->GetSPRequired();
247 if(require_sp > current_sp) {
248 _special_skill_list.EnableOption(i, false);
249 _special_target_list.EnableOption(i, false);
250 }
251 else {
252 _special_skill_list.EnableOption(i, true);
253 _special_target_list.EnableOption(i, true);
254 }
255 }
256 }
257
SaveLastTarget(BattleTarget & target)258 void CommandSettings::SaveLastTarget(BattleTarget &target)
259 {
260 switch(target.GetType()) {
261 case GLOBAL_TARGET_SELF_POINT:
262 case GLOBAL_TARGET_SELF:
263 _last_self_target = target;
264 break;
265 case GLOBAL_TARGET_ALLY_POINT:
266 case GLOBAL_TARGET_ALLY:
267 case GLOBAL_TARGET_ALLY_EVEN_DEAD:
268 case GLOBAL_TARGET_DEAD_ALLY_ONLY:
269 _last_character_target = target;
270 break;
271 case GLOBAL_TARGET_FOE_POINT:
272 case GLOBAL_TARGET_FOE:
273 _last_enemy_target = target;
274 break;
275 case GLOBAL_TARGET_ALL_ALLIES:
276 case GLOBAL_TARGET_ALL_FOES:
277 break; // Party type targets are not retained
278 default:
279 PRINT_WARNING << "target argument was an invalid type: " << target.GetType() << std::endl;
280 break;
281 }
282 }
283
284 } // namespace private_battle
285
286 } // namespace vt_battle
287