Skip to content

Commit ba85cda

Browse files
committed
more awbw replay work
1 parent 876fcb8 commit ba85cda

File tree

11 files changed

+173
-28
lines changed

11 files changed

+173
-28
lines changed

awbwReplayReader/awbwactionparser.cpp

Lines changed: 110 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#include <QJsonArray>
22

33
#include "awbwReplayReader/awbwactionparser.h"
4+
#include "awbwReplayReader/awbwreplayplayer.h"
45
#include "awbwReplayReader/awbwdatatypes.h"
56
#include "coreengine/memorymanagement.h"
67
#include "game/gameaction.h"
78
#include "game/gamemap.h"
9+
#include "game/unit.h"
810
#include "ai/coreai.h"
911

1012
const char* const AwbwActionParser::JSONKEY_ACTION = "action";
@@ -30,30 +32,40 @@ const char* const AwbwActionParser::JSONKEY_COMBATINFOVISION = "combatInfoVision
3032
const char* const AwbwActionParser::JSONKEY_COMBATINFO = "combatInfo";
3133
const char* const AwbwActionParser::JSONKEY_FIRE = "Fire";
3234
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";
3341

34-
AwbwActionParser::AwbwActionParser(GameMap* pMap)
35-
: m_pMap(pMap)
42+
AwbwActionParser::AwbwActionParser(AwbwReplayPlayer & pParent, GameMap* pMap)
43+
: m_pParent(pParent),
44+
m_pMap(pMap)
3645
{
3746
}
3847

3948
spGameAction AwbwActionParser::getAction(const QJsonObject & object)
4049
{
50+
m_lastAction = object;
4151
spGameAction action = MemoryManagement::create<GameAction>(m_pMap);
4252
QString actionType = object.value(JSONKEY_ACTION).toString().toLower();
4353
if (actionType == "move")
4454
{
4555
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());
4758
}
4859
else if (actionType == "capt")
4960
{
5061
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());
5264
}
5365
else if (actionType == "fire")
5466
{
5567
action->setActionID(CoreAI::ACTION_FIRE);
56-
addMovepath(object.value(JSONKEY_MOVE).toObject(), action);
68+
addMovepath(object.value(JSONKEY_MOVE).toObject(), action, -1, -1);
5769
addActionFireInfo(object, action);
5870
}
5971
else if (actionType == "build")
@@ -72,12 +84,12 @@ spGameAction AwbwActionParser::getAction(const QJsonObject & object)
7284
else if (actionType == "unload")
7385
{
7486
action->setActionID(CoreAI::ACTION_UNLOAD);
75-
87+
addMovepath(object.value(JSONKEY_MOVE).toObject(), action, -1, -1);
7688
}
7789
else if (actionType == "unhide")
7890
{
7991
action->setActionID(CoreAI::ACTION_UNSTEALTH);
80-
addMovepath(object, action);
92+
addMovepath(object.value(JSONKEY_MOVE).toObject(), action, -1, -1);
8193
}
8294
else if (actionType == "tag")
8395
{
@@ -87,7 +99,7 @@ spGameAction AwbwActionParser::getAction(const QJsonObject & object)
8799
else if (actionType == "supply")
88100
{
89101
action->setActionID(CoreAI::ACTION_SUPPORTALL_RATION);
90-
addMovepath(object, action);
102+
addMovepath(object, action, -1, -1);
91103
}
92104
else if (actionType == "resign")
93105
{
@@ -96,7 +108,7 @@ spGameAction AwbwActionParser::getAction(const QJsonObject & object)
96108
else if (actionType == "repair")
97109
{
98110
action->setActionID(CoreAI::ACTION_SUPPORTSINGLE_REPAIR);
99-
addMovepath(object, action);
111+
addMovepath(object.value(JSONKEY_MOVE).toObject(), action, -1, -1);
100112
}
101113
else if (actionType == "power")
102114
{
@@ -105,28 +117,30 @@ spGameAction AwbwActionParser::getAction(const QJsonObject & object)
105117
else if (actionType == "load")
106118
{
107119
action->setActionID(CoreAI::ACTION_LOAD);
108-
addMovepath(object, action);
120+
addMovepath(object.value(JSONKEY_MOVE).toObject(), action, -1, -1);
109121
}
110122
else if (actionType == "launch")
111123
{
112124
action->setActionID(CoreAI::ACTION_MISSILE);
125+
addMovepath(object.value(JSONKEY_MOVE).toObject(), action, -1, -1);
113126
}
114127
else if (actionType == "join")
115128
{
116129
action->setActionID(CoreAI::ACTION_JOIN);
117-
addMovepath(object, action);
130+
addMovepath(object.value(JSONKEY_MOVE).toObject(), action, -1, -1);
118131
}
119132
else if (actionType == "hide")
120133
{
121134
action->setActionID(CoreAI::ACTION_STEALTH);
122-
addMovepath(object, action);
135+
addMovepath(object.value(JSONKEY_MOVE).toObject(), action, -1, -1);
123136
}
124137
else if (actionType == "gameover")
125138
{
126139
}
127140
else if (actionType == "explode")
128141
{
129142
action->setActionID(CoreAI::ACTION_EXPLODE);
143+
addMovepath(object.value(JSONKEY_MOVE).toObject(), action, -1, -1);
130144
}
131145
else if (actionType == "end")
132146
{
@@ -138,7 +152,27 @@ spGameAction AwbwActionParser::getAction(const QJsonObject & object)
138152
return action;
139153
}
140154

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)
142176
{
143177
QJsonArray jsonPath = object.value(JSONKEY_PATH).toObject().value(JSONKEY_GLOBAL).toArray();
144178
QJsonObject unitObj = object.value(JSONKEY_UNIT).toObject().value(JSONKEY_GLOBAL).toObject();
@@ -158,26 +192,85 @@ void AwbwActionParser::addMovepath(const QJsonObject & object, spGameAction & ac
158192
action->setMovepath(path, pUnit->getFuel() - unitObj[JSONKEY_UNITS_FUEL].toInt());
159193
}
160194
}
195+
else
196+
{
197+
QPoint pos(x, y);
198+
action->setTarget(pos);
199+
QVector<QPoint> path = {pos};
200+
action->setMovepath(path, 0);
201+
}
161202
}
162203

163204
void AwbwActionParser::addBuildInfo(const QJsonObject & object, spGameAction & action)
164205
{
165206
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()];
166208
action->setTarget(QPoint(unitObj[JSONKEY_UNITS_X].toInt(), unitObj[JSONKEY_UNITS_Y].toInt()));
167209
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);
169211
action->setInputStep(action->getInputStep() + 1);
170212
}
171213

172214
void AwbwActionParser::addActionFireInfo(const QJsonObject & object, spGameAction & action)
173215
{
174216
QJsonObject fireInfo = object.value(JSONKEY_FIRE).toObject();
175-
QJsonObject copValues = fireInfo.value(JSONKEY_COPVALUES).toObject();
176217
QJsonObject combatInfo = fireInfo.value(JSONKEY_COMBATINFOVISION).toObject().value(JSONKEY_GLOBAL).toObject().value(JSONKEY_COMBATINFO).toObject();
177218
QJsonObject attackerData = combatInfo.value(JSONKEY_ATTACKER).toObject();
178219
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);
181231

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+
}
182237

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+
}
183276
}

awbwReplayReader/awbwactionparser.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <QJsonObject>
44
#include "game/gameaction.h"
55

6+
class AwbwReplayPlayer;
7+
68
class AwbwActionParser
79
{
810
public:
@@ -29,16 +31,26 @@ class AwbwActionParser
2931
static const char* const JSONKEY_COMBATINFO;
3032
static const char* const JSONKEY_FIRE;
3133
static const char* const JSONKEY_MOVE;
34+
static const char* const JSONKEY_AMMO;
35+
static const char* const JSONKEY_BUILDINGINFO;
36+
static const char* const JSONKEY_BUILDINGS_X;
37+
static const char* const JSONKEY_BUILDINGS_Y;
38+
static const char* const JSONKEY_CAPT;
39+
static const char* const JSONKEY_PLAYERID;
3240

33-
AwbwActionParser(GameMap* pMap);
41+
AwbwActionParser(AwbwReplayPlayer & pParent, GameMap* pMap);
3442

3543
spGameAction getAction(const QJsonObject & object);
36-
44+
void onPostAction();
3745
private:
38-
void addMovepath(const QJsonObject & object, spGameAction & action);
46+
void addMovepath(const QJsonObject & object, spGameAction & action, qint32 x, qint32 y);
3947
void addBuildInfo(const QJsonObject & object, spGameAction & action);
4048
void addActionFireInfo(const QJsonObject & object, spGameAction & action);
49+
void addDamageData(Unit* pAtk, Unit* pDef, const QJsonObject & atkData, const QJsonObject & defData, spGameAction & action);
50+
void updateCoData(const QJsonObject & data);
4151
private:
52+
AwbwReplayPlayer & m_pParent;
4253
GameMap* m_pMap;
54+
QJsonObject m_lastAction;
4355
};
4456

awbwReplayReader/awbwreplayerreader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ void AwbwReplayerReader::readPlayers(QTextStream & stream, GameState & newState)
301301
}
302302
else if (item == "eliminated")
303303
{
304-
player.funds = AwbwDataParser::readBool(stream, m_valid);
304+
player.eliminated = AwbwDataParser::readBool(stream, m_valid);
305305
}
306306
else if (item == "co_power")
307307
{

awbwReplayReader/awbwreplayplayer.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
AwbwReplayPlayer::AwbwReplayPlayer(GameMap* pMap)
1010
: m_pMap(pMap),
11-
m_actionParser(pMap)
11+
m_actionParser(*this, pMap)
1212
{
1313
connect(&m_mapDownloader, &AwbwMapDownloader::sigDownloadResult, this, &AwbwReplayPlayer::onDownloadResult, Qt::QueuedConnection);
1414
}
@@ -52,6 +52,11 @@ spGameAction AwbwReplayPlayer::nextAction()
5252
return action;
5353
}
5454

55+
void AwbwReplayPlayer::onPostAction()
56+
{
57+
m_actionParser.onPostAction();
58+
}
59+
5560
qint32 AwbwReplayPlayer::getRecordSize()
5661
{
5762
qint32 count = 0;
@@ -85,14 +90,14 @@ IReplayReader::DayInfo AwbwReplayPlayer::getDayFromPosition(qint32 count)
8590
qint32 index = 0;
8691
dayInfo.day = gameStates[0].day;
8792
dayInfo.player = playerMapping[gameStates[0].turn];
88-
while (index < actions.size() &&
89-
index < gameStates.size() &&
93+
while (index < actions.size() - 1 &&
94+
index < gameStates.size() - 1 &&
9095
currentCount < count)
9196
{
9297
currentCount += actions[index].actionData.size();
98+
++index;
9399
dayInfo.day = gameStates[index].day;
94100
dayInfo.player = playerMapping[gameStates[index].turn];
95-
++index;
96101
}
97102
}
98103
return dayInfo;
@@ -113,14 +118,14 @@ void AwbwReplayPlayer::seekToDay(IReplayReader::DayInfo dayInfo)
113118
while (gameStateIndex < actions.size() &&
114119
gameStateIndex < gameStates.size())
115120
{
116-
m_currentActionPos += actions[gameStateIndex].actionData.size();
117121
if (dayInfo.day == gameStates[gameStateIndex].day &&
118122
dayInfo.player == playerMapping[gameStates[gameStateIndex].turn])
119123
{
120124
break;
121125
}
122126
else
123127
{
128+
m_currentActionPos += actions[gameStateIndex].actionData.size();
124129
++gameStateIndex;
125130
}
126131
}
@@ -205,13 +210,15 @@ void AwbwReplayPlayer::loadMap(bool withOutUnits, IReplayReader::DayInfo dayInfo
205210
m_pMap->getPlayer(i)->setBaseGameInput(BaseGameInputIF::createAi(m_pMap, GameEnums::AiTypes::AiTypes_ProxyAi));
206211
if (gameStateIndex < states.size())
207212
{
208-
m_pMap->getPlayer(i)->setFundsModifier(gameStates[gameStateIndex].fundsPerBuilding / 1000);
213+
m_pMap->getPlayer(i)->setFundsModifier(static_cast<float>(gameStates[gameStateIndex].fundsPerBuilding) / 1000.0f);
214+
m_pMap->getPlayer(i)->setFunds(gameStates[gameStateIndex].players[i].funds);
209215
}
210216
}
211217
m_pMap->setCurrentPlayer(dayInfo.player);
212218
if (gameStateIndex < states.size())
213219
{
214220
loadGameRules(states, gameStateIndex);
221+
m_pMap->setCurrentDay(dayInfo.day);
215222
}
216223
m_pMap->updateSprites();
217224
Mainapp::getInstance()->continueRendering();
@@ -241,6 +248,17 @@ void AwbwReplayPlayer::loadGameRules(const QVector<AwbwReplayerReader::GameState
241248
pRule->changeWeather("WEATHER_SNOW", m_pMap->getPlayerCount());
242249
}
243250
pRule->setEnableDayToDayCoAbilities(gameStates[gameStateIndex].usePowers);
251+
pRule->setRandomWeather(false);
252+
}
253+
254+
const AwbwReplayerReader & AwbwReplayPlayer::getReplayReader() const
255+
{
256+
return m_replayReader;
257+
}
258+
259+
qint32 AwbwReplayPlayer::getCurrentActionPos() const
260+
{
261+
return m_currentActionPos;
244262
}
245263

246264
void AwbwReplayPlayer::loadBuildings(const QVector<AwbwReplayerReader::GameState> & gameStates, qint32 gameStateIndex)
@@ -363,7 +381,7 @@ void AwbwReplayPlayer::loadCo(const AwbwReplayerReader::CoInfo & coInfo, Player*
363381
auto powerStars = pCO->getPowerStars();
364382
if (powerStars > 0)
365383
{
366-
pCO->setPowerFilled(coInfo.power / (coInfo.maxPower / powerStars));
384+
pCO->setPowerFilled(static_cast<double>(coInfo.power) / (static_cast<double>(coInfo.maxPower) / static_cast<double>(powerStars)));
367385
}
368386
}
369387
}

0 commit comments

Comments
 (0)