1 /************************************************************************
2 * *
3 * FreeSynd - a remake of the classic Bullfrog game "Syndicate". *
4 * *
5 * Copyright (C) 2013 Benoit Blancard <benblan@users.sourceforge.net>*
6 * *
7 * This program is free software; you can redistribute it and / or *
8 * modify it under the terms of the GNU General Public License as *
9 * published by the Free Software Foundation; either version 2 of the *
10 * License, or (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15 * General Public License for more details. *
16 * *
17 * You can view the GNU General Public License, online, at the GNU *
18 * project's web site; see <http://www.gnu.org/licenses/gpl.html>. *
19 * The full text of the license is also included in the file COPYING. *
20 * *
21 ************************************************************************/
22
23 #include "menus/agentselectorrenderer.h"
24 #include "gfx/screen.h"
25 #include "app.h"
26 #include "ped.h"
27
28 const int AgentSelectorRenderer::kIpaBarWidth = 56;
29 const int AgentSelectorRenderer::kIpaBarHeight = 10;
30 const int AgentSelectorRenderer::kIpaBarLeft13 = 4;
31 const int AgentSelectorRenderer::kIpaBarLeft24 = 68;
32 const int AgentSelectorRenderer::kIpaBarTop12 = 48;
33 const int AgentSelectorRenderer::kIpaBarTop34 = 148;
34 const int AgentSelectorRenderer::kIpaYOffset = 14;
35
36 /*!
37 *
38 */
hasClickedOnAgentSelector(int x,int y,SelectorEvent & evt)39 bool AgentSelectorRenderer::hasClickedOnAgentSelector(int x, int y, SelectorEvent & evt) {
40 evt.eventType = SelectorEvent::kNone;
41 if (y < 46) {
42 evt.eventType = SelectorEvent::kSelectAgent;
43 if (x < 64) {
44 evt.agentSlot = 0;
45 } else {
46 evt.agentSlot = 1;
47 }
48 }
49
50 else if (y >= 42 + 48 + 10 && y < 42 + 48 + 10 + 46) {
51 evt.eventType = SelectorEvent::kSelectAgent;
52 if (x < 64) {
53 evt.agentSlot = 2;
54 } else {
55 evt.agentSlot = 3;
56 }
57 }
58 else
59 {
60 scanCoordsForIPA(x,y, evt);
61 }
62
63 return evt.eventType != SelectorEvent::kNone;
64 }
65
scanCoordsForIPA(int x,int y,SelectorEvent & evt)66 void AgentSelectorRenderer::scanCoordsForIPA(int x, int y, SelectorEvent & evt)
67 {
68 IPAStim::IPAType types[] = {IPAStim::Adrenaline, IPAStim::Perception, IPAStim::Intelligence};
69 // For each agent
70 for(size_t a = 0; a < AgentManager::kMaxSlot; ++a)
71 {
72 int barLeft = getIpaBarLeftForAgent(a);
73 if(x >= barLeft && x <= barLeft + kIpaBarWidth)
74 {
75 // For each type of IPA
76 for (int i = 0; i < 3; ++i) {
77 int barTop = getIpaBarTop(a, types[i]);
78 if( y >= barTop && y <= barTop + kIpaBarHeight) {
79 evt.eventType = SelectorEvent::kSelectIpa;
80 evt.agentSlot = a;
81 evt.IpaType = types[i];
82 evt.percentage = getPercentage(barLeft, x);
83 return;
84 }
85 }
86 }
87 }
88 }
89
90 /*!
91 * Draws all the elements
92 * for one bar
93 */
drawIPABar(int agent,IPAStim * stim)94 void AgentSelectorRenderer::drawIPABar(int agent, IPAStim *stim)
95 {
96 // Convert those percentages to pixels
97 int amount_x = (float)kIpaBarWidth * ((float)stim->getAmount()/100.0);
98 int effect_x = (float)kIpaBarWidth * ((float)stim->getEffect()/100.0);
99 int dependency_x = (float)kIpaBarWidth * ((float)stim->getDependency()/100.0);
100
101 IPAStim::IPAType type = stim->getType();
102
103 // Draw a bar between the current level and the dependency marker
104 // x needs to be leftmost...
105 int left, width;
106 boxify(left, width, amount_x, dependency_x);
107 if(width > 0) {
108 g_Screen.drawRect(getIpaBarLeftForAgent(agent) + left,
109 getIpaBarTop(agent, type),
110 width, kIpaBarHeight, colourForIpaType(type));
111 }
112
113 // NB: this bar stops rendering when it's neck-a-neck with 'amount'
114 if(amount_x != effect_x)
115 {
116 boxify(left, width, effect_x, dependency_x);
117 if(width > 0) {
118 g_Screen.drawRect(getIpaBarLeftForAgent(agent) + left,
119 getIpaBarTop(agent, type),
120 width, kIpaBarHeight, dim_colour(type));
121 }
122 }
123
124 // Draw a vertical white line to mark the dependency level
125 g_Screen.drawVLine(getIpaBarLeftForAgent(agent) + dependency_x,
126 getIpaBarTop(agent, type), kIpaBarHeight, 12);
127 }
128
129 /*!
130 * Draw the complete selector for an agent.
131 * \param agentSlot
132 * \param pAgent
133 * \param isSelected
134 */
drawSelectorForAgent(size_t agentSlot,PedInstance * pAgent,bool isSelected)135 void AgentSelectorRenderer::drawSelectorForAgent(size_t agentSlot,
136 PedInstance *pAgent, bool isSelected)
137 {
138 // parity check
139 int topX = (agentSlot & 0x01) * 64;
140 // 2,3 should be drawn at (46 + 44 + 10)
141 int topY = (agentSlot >> 1) * (46 + 44 + 10);
142 int spriteSelected = 1772 + agentSlot;
143 int springUnselected = 1748 + (agentSlot > 1 ? agentSlot + 2 : agentSlot);
144
145 // Draw the background of selector
146 g_App.gameSprites().sprite(isSelected ? spriteSelected : springUnselected)->draw(
147 topX, topY, 0);
148 g_App.gameSprites().sprite(isSelected ? 1778 : 1754)->draw(
149 topX, topY + 46, 0);
150
151 if (pAgent) {
152 // draw health bar
153 int ydiff = 36 * pAgent->health() / pAgent->startHealth();
154 g_Screen.drawRect(topX + 51,
155 topY + 6 + 36 - ydiff, 7, ydiff, 12);
156
157 //draw animation within selectors
158 pAgent->drawSelectorAnim(topX + 32, topY + 38);
159
160 // draw IPA, for alive only agents
161 if (pAgent->isAlive()) {
162 drawIPABar(agentSlot, pAgent->adrenaline_);
163 drawIPABar(agentSlot, pAgent->perception_);
164 drawIPABar(agentSlot, pAgent->intelligence_);
165 }
166 }
167 }
168
169 /*!
170 * Draw all elements for the agent selectors.
171 */
render(SquadSelection & selection,Squad * pSquad)172 void AgentSelectorRenderer::render(SquadSelection & selection, Squad * pSquad) {
173 for (size_t a = 0; a < AgentManager::kMaxSlot; a++) {
174 PedInstance * pAgent = pSquad->member(a);
175 drawSelectorForAgent(a, pAgent, selection.isAgentSelected(a));
176 }
177 }
178