1
1
#include < QJsonArray>
2
2
3
3
#include " awbwReplayReader/awbwactionparser.h"
4
+ #include " awbwReplayReader/awbwreplayplayer.h"
4
5
#include " awbwReplayReader/awbwdatatypes.h"
5
6
#include " coreengine/memorymanagement.h"
6
7
#include " game/gameaction.h"
7
8
#include " game/gamemap.h"
9
+ #include " game/unit.h"
8
10
#include " ai/coreai.h"
9
11
10
12
const char * const AwbwActionParser::JSONKEY_ACTION = " action" ;
@@ -30,30 +32,40 @@ const char* const AwbwActionParser::JSONKEY_COMBATINFOVISION = "combatInfoVision
30
32
const char * const AwbwActionParser::JSONKEY_COMBATINFO = " combatInfo" ;
31
33
const char * const AwbwActionParser::JSONKEY_FIRE = " Fire" ;
32
34
const char * const AwbwActionParser::JSONKEY_MOVE = " Move" ;
35
+ const char * const AwbwActionParser::JSONKEY_AMMO = " units_ammo" ;
36
+ const char * const AwbwActionParser::JSONKEY_BUILDINGINFO = " buildingInfo" ;
37
+ const char * const AwbwActionParser::JSONKEY_BUILDINGS_X = " buildings_x" ;
38
+ const char * const AwbwActionParser::JSONKEY_BUILDINGS_Y = " buildings_y" ;
39
+ const char * const AwbwActionParser::JSONKEY_CAPT = " Capt" ;
40
+ const char * const AwbwActionParser::JSONKEY_PLAYERID = " playerId" ;
33
41
34
- AwbwActionParser::AwbwActionParser (GameMap* pMap)
35
- : m_pMap(pMap)
42
+ AwbwActionParser::AwbwActionParser (AwbwReplayPlayer & pParent, GameMap* pMap)
43
+ : m_pParent(pParent),
44
+ m_pMap(pMap)
36
45
{
37
46
}
38
47
39
48
spGameAction AwbwActionParser::getAction (const QJsonObject & object)
40
49
{
50
+ m_lastAction = object;
41
51
spGameAction action = MemoryManagement::create<GameAction>(m_pMap);
42
52
QString actionType = object.value (JSONKEY_ACTION).toString ().toLower ();
43
53
if (actionType == " move" )
44
54
{
45
55
action->setActionID (CoreAI::ACTION_WAIT);
46
- addMovepath (object, action);
56
+ QJsonObject startPoint = object.value (JSONKEY_UNIT).toObject ()[JSONKEY_GLOBAL].toObject ();
57
+ addMovepath (object, action, startPoint.value (JSONKEY_UNITS_X).toInt (), startPoint.value (JSONKEY_UNITS_Y).toInt ());
47
58
}
48
59
else if (actionType == " capt" )
49
60
{
50
61
action->setActionID (CoreAI::ACTION_CAPTURE);
51
- addMovepath (object, action);
62
+ QJsonObject startPoint = object.value (JSONKEY_CAPT).toObject ()[JSONKEY_BUILDINGINFO].toObject ();
63
+ addMovepath (object.value (JSONKEY_MOVE).toObject (), action, startPoint[JSONKEY_BUILDINGS_X].toInt (), startPoint[JSONKEY_BUILDINGS_Y].toInt ());
52
64
}
53
65
else if (actionType == " fire" )
54
66
{
55
67
action->setActionID (CoreAI::ACTION_FIRE);
56
- addMovepath (object.value (JSONKEY_MOVE).toObject (), action);
68
+ addMovepath (object.value (JSONKEY_MOVE).toObject (), action, - 1 , - 1 );
57
69
addActionFireInfo (object, action);
58
70
}
59
71
else if (actionType == " build" )
@@ -72,12 +84,12 @@ spGameAction AwbwActionParser::getAction(const QJsonObject & object)
72
84
else if (actionType == " unload" )
73
85
{
74
86
action->setActionID (CoreAI::ACTION_UNLOAD);
75
-
87
+ addMovepath (object. value (JSONKEY_MOVE). toObject (), action, - 1 , - 1 );
76
88
}
77
89
else if (actionType == " unhide" )
78
90
{
79
91
action->setActionID (CoreAI::ACTION_UNSTEALTH);
80
- addMovepath (object, action);
92
+ addMovepath (object. value (JSONKEY_MOVE). toObject () , action, - 1 , - 1 );
81
93
}
82
94
else if (actionType == " tag" )
83
95
{
@@ -87,7 +99,7 @@ spGameAction AwbwActionParser::getAction(const QJsonObject & object)
87
99
else if (actionType == " supply" )
88
100
{
89
101
action->setActionID (CoreAI::ACTION_SUPPORTALL_RATION);
90
- addMovepath (object, action);
102
+ addMovepath (object, action, - 1 , - 1 );
91
103
}
92
104
else if (actionType == " resign" )
93
105
{
@@ -96,7 +108,7 @@ spGameAction AwbwActionParser::getAction(const QJsonObject & object)
96
108
else if (actionType == " repair" )
97
109
{
98
110
action->setActionID (CoreAI::ACTION_SUPPORTSINGLE_REPAIR);
99
- addMovepath (object, action);
111
+ addMovepath (object. value (JSONKEY_MOVE). toObject () , action, - 1 , - 1 );
100
112
}
101
113
else if (actionType == " power" )
102
114
{
@@ -105,28 +117,30 @@ spGameAction AwbwActionParser::getAction(const QJsonObject & object)
105
117
else if (actionType == " load" )
106
118
{
107
119
action->setActionID (CoreAI::ACTION_LOAD);
108
- addMovepath (object, action);
120
+ addMovepath (object. value (JSONKEY_MOVE). toObject () , action, - 1 , - 1 );
109
121
}
110
122
else if (actionType == " launch" )
111
123
{
112
124
action->setActionID (CoreAI::ACTION_MISSILE);
125
+ addMovepath (object.value (JSONKEY_MOVE).toObject (), action, -1 , -1 );
113
126
}
114
127
else if (actionType == " join" )
115
128
{
116
129
action->setActionID (CoreAI::ACTION_JOIN);
117
- addMovepath (object, action);
130
+ addMovepath (object. value (JSONKEY_MOVE). toObject () , action, - 1 , - 1 );
118
131
}
119
132
else if (actionType == " hide" )
120
133
{
121
134
action->setActionID (CoreAI::ACTION_STEALTH);
122
- addMovepath (object, action);
135
+ addMovepath (object. value (JSONKEY_MOVE). toObject () , action, - 1 , - 1 );
123
136
}
124
137
else if (actionType == " gameover" )
125
138
{
126
139
}
127
140
else if (actionType == " explode" )
128
141
{
129
142
action->setActionID (CoreAI::ACTION_EXPLODE);
143
+ addMovepath (object.value (JSONKEY_MOVE).toObject (), action, -1 , -1 );
130
144
}
131
145
else if (actionType == " end" )
132
146
{
@@ -138,7 +152,27 @@ spGameAction AwbwActionParser::getAction(const QJsonObject & object)
138
152
return action;
139
153
}
140
154
141
- void AwbwActionParser::addMovepath (const QJsonObject & object, spGameAction & action)
155
+ void AwbwActionParser::onPostAction ()
156
+ {
157
+ if (m_lastAction.value (JSONKEY_ACTION).isString ())
158
+ {
159
+ QString actionType = m_lastAction.value (JSONKEY_ACTION).toString ().toLower ();
160
+ if (actionType == " end" )
161
+ {
162
+ m_pParent.seekToDay (m_pParent.getDayFromPosition (m_pParent.getCurrentActionPos ()));
163
+ }
164
+ else if (actionType == " fire" )
165
+ {
166
+ QJsonObject fireInfo = m_lastAction.value (JSONKEY_FIRE).toObject ();
167
+ QJsonObject copValues = fireInfo.value (JSONKEY_COPVALUES).toObject ();
168
+ updateCoData (copValues[JSONKEY_ATTACKER].toObject ());
169
+ updateCoData (copValues[JSONKEY_DEFENDER].toObject ());
170
+ }
171
+ }
172
+ m_lastAction = QJsonObject ();
173
+ }
174
+
175
+ void AwbwActionParser::addMovepath (const QJsonObject & object, spGameAction & action, qint32 x, qint32 y)
142
176
{
143
177
QJsonArray jsonPath = object.value (JSONKEY_PATH).toObject ().value (JSONKEY_GLOBAL).toArray ();
144
178
QJsonObject unitObj = object.value (JSONKEY_UNIT).toObject ().value (JSONKEY_GLOBAL).toObject ();
@@ -158,26 +192,85 @@ void AwbwActionParser::addMovepath(const QJsonObject & object, spGameAction & ac
158
192
action->setMovepath (path, pUnit->getFuel () - unitObj[JSONKEY_UNITS_FUEL].toInt ());
159
193
}
160
194
}
195
+ else
196
+ {
197
+ QPoint pos (x, y);
198
+ action->setTarget (pos);
199
+ QVector<QPoint> path = {pos};
200
+ action->setMovepath (path, 0 );
201
+ }
161
202
}
162
203
163
204
void AwbwActionParser::addBuildInfo (const QJsonObject & object, spGameAction & action)
164
205
{
165
206
QJsonObject unitObj = object.value (JSONKEY_NEWUNIT).toObject ().value (JSONKEY_GLOBAL).toObject ();
207
+ QString unitId = AwbwDataTypes::UNIT_ID_ID_MAP[unitObj[JSONKEY_UNITS_NAME].toString ().toLower ()];
166
208
action->setTarget (QPoint (unitObj[JSONKEY_UNITS_X].toInt (), unitObj[JSONKEY_UNITS_Y].toInt ()));
167
209
action->setCosts (action->getCosts () + unitObj[JSONKEY_UNITS_COST].toInt ());
168
- action->writeDataString (AwbwDataTypes::UNIT_ID_ID_MAP[unitObj[JSONKEY_UNITS_NAME]. toString ()] );
210
+ action->writeDataString (unitId );
169
211
action->setInputStep (action->getInputStep () + 1 );
170
212
}
171
213
172
214
void AwbwActionParser::addActionFireInfo (const QJsonObject & object, spGameAction & action)
173
215
{
174
216
QJsonObject fireInfo = object.value (JSONKEY_FIRE).toObject ();
175
- QJsonObject copValues = fireInfo.value (JSONKEY_COPVALUES).toObject ();
176
217
QJsonObject combatInfo = fireInfo.value (JSONKEY_COMBATINFOVISION).toObject ().value (JSONKEY_GLOBAL).toObject ().value (JSONKEY_COMBATINFO).toObject ();
177
218
QJsonObject attackerData = combatInfo.value (JSONKEY_ATTACKER).toObject ();
178
219
QJsonObject defenderData = combatInfo.value (JSONKEY_DEFENDER).toObject ();
179
- Unit* pAttacker = action->getPerformingUnit ();
180
- Unit* pDefender = m_pMap->getTerrain (defenderData[JSONKEY_UNITS_X].toInt (), defenderData[JSONKEY_UNITS_Y].toInt ())->getUnit ();
220
+ if (action->getTarget ().x () < 0 )
221
+ {
222
+ QPoint pos (attackerData[JSONKEY_UNITS_X].toInt (), attackerData[JSONKEY_UNITS_Y].toInt ());
223
+ action->setTarget (pos);
224
+ QVector<QPoint> path = {pos};
225
+ action->setMovepath (path, 0 );
226
+ }
227
+ qint32 defX = defenderData[JSONKEY_UNITS_X].toInt ();
228
+ qint32 defY = defenderData[JSONKEY_UNITS_Y].toInt ();
229
+ action->writeDataInt32 (defX);
230
+ action->writeDataInt32 (defY);
181
231
232
+ Unit* pAttacker = action->getTargetUnit ();
233
+ Unit* pDefender = m_pMap->getTerrain (defX, defY)->getUnit ();
234
+ addDamageData (pAttacker, pDefender, attackerData, defenderData, action);
235
+ addDamageData (pDefender, pAttacker, defenderData, attackerData, action);
236
+ }
182
237
238
+ void AwbwActionParser::addDamageData (Unit* pAtk, Unit* pDef, const QJsonObject & atkData, const QJsonObject & defData, spGameAction & action)
239
+ {
240
+ action->writeDataInt32 ((pDef->getHp () - defData[JSONKEY_UNITS_HIT_POINTS].toInt ()) * Unit::MAX_UNIT_HP);
241
+ if (pAtk->getAmmo1 () > atkData[JSONKEY_AMMO].toInt () ||
242
+ !pAtk->hasAmmo2 ())
243
+ {
244
+ action->writeDataInt32 (0 );
245
+ }
246
+ else
247
+ {
248
+ action->writeDataInt32 (1 );
249
+ }
250
+ }
251
+
252
+ void AwbwActionParser::updateCoData (const QJsonObject & data)
253
+ {
254
+ const auto & replayReader = m_pParent.getReplayReader ();
255
+ const auto & gameStates = replayReader.getGameStates ();
256
+ for (auto & player : gameStates[0 ].players )
257
+ {
258
+ if (player.playerId == data[JSONKEY_PLAYERID].toInt ())
259
+ {
260
+ auto * pPlayer = m_pMap->getPlayer (player.playerIdx );
261
+ auto * pCO = pPlayer->getCO (0 );
262
+ if (pCO != nullptr )
263
+ {
264
+ auto powerStars = pCO->getPowerStars ();
265
+ pCO->setPowerFilled (data[JSONKEY_COPVALUE].toDouble () / (static_cast <double >(player.coData .maxPower ) / static_cast <double >(powerStars)));
266
+ }
267
+ pCO = pPlayer->getCO (1 );
268
+ if (pCO != nullptr )
269
+ {
270
+ auto powerStars = pCO->getPowerStars ();
271
+ pCO->setPowerFilled (data[JSONKEY_TAGVALUE].toDouble () / (static_cast <double >(player.tagCoData .maxPower ) / static_cast <double >(powerStars)));
272
+ }
273
+ break ;
274
+ }
275
+ }
183
276
}
0 commit comments