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