Skip to content

Commit cd265af

Browse files
FinnHornhooverdongresource
authored andcommitted
Original Racing Scores Functionality (#257)
1 parent 38c68f3 commit cd265af

File tree

4 files changed

+36
-17
lines changed

4 files changed

+36
-17
lines changed

src/Racing.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static void racingCancel(CNSocket* sock, CNPacketData* data) {
6666
INITSTRUCT(sP_FE2CL_REP_EP_RACE_CANCEL_SUCC, resp);
6767
sock->sendPacket(resp, P_FE2CL_REP_EP_RACE_CANCEL_SUCC);
6868

69-
/*
69+
/*
7070
* This request packet is used for both cancelling the race via the
7171
* NPC at the start, *and* failing the race by running out of time.
7272
* If the latter is to happen, the client disables movement until it
@@ -99,31 +99,37 @@ static void racingEnd(CNSocket* sock, CNPacketData* data) {
9999
if (EPData.find(mapNum) == EPData.end() || EPData[mapNum].EPID == 0)
100100
return; // IZ not found
101101

102+
EPInfo& epInfo = EPData[mapNum];
103+
EPRace& epRace = EPRaces[sock];
104+
102105
uint64_t now = getTime() / 1000;
106+
int timeDiff = now - epRace.startTime;
107+
int podsCollected = epRace.collectedRings.size();
103108

104-
int timeDiff = now - EPRaces[sock].startTime;
105-
int score = 500 * EPRaces[sock].collectedRings.size() - 10 * timeDiff;
106-
if (score < 0) score = 0; // lol
107-
int fm = score * plr->level * (1.0f / 36) * 0.3f;
109+
int score = std::min(epInfo.maxScore, (int)std::exp(
110+
(epInfo.podFactor * podsCollected) / epInfo.maxPods
111+
- (epInfo.timeFactor * timeDiff) / epInfo.maxTime
112+
+ epInfo.scaleFactor));
113+
int fm = (1.0 + std::exp(epInfo.scaleFactor - 1.0) * epInfo.podFactor * podsCollected) / epInfo.maxPods;
108114

109115
// we submit the ranking first...
110116
Database::RaceRanking postRanking = {};
111-
postRanking.EPID = EPData[mapNum].EPID;
117+
postRanking.EPID = epInfo.EPID;
112118
postRanking.PlayerID = plr->iID;
113-
postRanking.RingCount = EPRaces[sock].collectedRings.size();
119+
postRanking.RingCount = podsCollected;
114120
postRanking.Score = score;
115121
postRanking.Time = timeDiff;
116122
postRanking.Timestamp = getTimestamp();
117123
Database::postRaceRanking(postRanking);
118124

119125
// ...then we get the top ranking, which may or may not be what we just submitted
120-
Database::RaceRanking topRankingPlayer = Database::getTopRaceRanking(EPData[mapNum].EPID, plr->iID);
126+
Database::RaceRanking topRankingPlayer = Database::getTopRaceRanking(epInfo.EPID, plr->iID);
121127

122128
INITSTRUCT(sP_FE2CL_REP_EP_RACE_END_SUCC, resp);
123129

124130
// get rank scores and rewards
125-
std::vector<int>* rankScores = &EPRewards[EPData[mapNum].EPID].first;
126-
std::vector<int>* rankRewards = &EPRewards[EPData[mapNum].EPID].second;
131+
std::vector<int>* rankScores = &EPRewards[epInfo.EPID].first;
132+
std::vector<int>* rankRewards = &EPRewards[epInfo.EPID].second;
127133

128134
// top ranking
129135
int topRank = 0;

src/Racing.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
#include <set>
88

99
struct EPInfo {
10-
int zoneX, zoneY, EPID, maxScore, maxTime;
10+
// available through XDT (maxScore may be updated by drops)
11+
int zoneX, zoneY, EPID, maxScore;
12+
// available through drops
13+
int maxTime, maxPods;
14+
double scaleFactor, podFactor, timeFactor;
1115
};
1216

1317
struct EPRace {

src/TableData.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ static void loadPaths(json& pathData, int32_t* nextId) {
375375
Transport::NPCPaths.push_back(pathTemplate);
376376
}
377377
std::cout << "[INFO] Loaded " << Transport::NPCPaths.size() << " NPC paths" << std::endl;
378-
378+
379379
}
380380
catch (const std::exception& err) {
381381
std::cerr << "[FATAL] Malformed paths.json file! Reason:" << err.what() << std::endl;
@@ -584,8 +584,17 @@ static void loadDrops(json& dropData) {
584584
continue;
585585
}
586586

587-
// time limit isn't stored in the XDT, so we include it in the reward table instead
588-
Racing::EPData[EPMap].maxTime = race["TimeLimit"];
587+
EPInfo& epInfo = Racing::EPData[EPMap];
588+
589+
// max score is specified in the XDT, but can be updated if specified in the drops JSON
590+
epInfo.maxScore = (int)race["ScoreCap"];
591+
// time limit and total pods are not stored in the XDT, so we include it in the drops JSON
592+
epInfo.maxTime = (int)race["TimeLimit"];
593+
epInfo.maxPods = (int)race["TotalPods"];
594+
// IZ-specific calculated constants included in the drops JSON
595+
epInfo.scaleFactor = (double)race["ScaleFactor"];
596+
epInfo.podFactor = (double)race["PodFactor"];
597+
epInfo.timeFactor = (double)race["TimeFactor"];
589598

590599
// score cutoffs
591600
std::vector<int> rankScores;
@@ -686,7 +695,7 @@ static void loadEggs(json& eggData, int32_t* nextId) {
686695
}
687696
}
688697

689-
/*
698+
/*
690699
* Load gruntwork output, if it exists
691700
*/
692701
static void loadGruntworkPre(json& gruntwork, int32_t* nextId) {
@@ -1361,7 +1370,7 @@ void TableData::flush() {
13611370
targetIDs.push_back(tID);
13621371
for (int32_t tType : path.targetTypes)
13631372
targetTypes.push_back(tType);
1364-
1373+
13651374
pathObj["iBaseSpeed"] = path.speed;
13661375
pathObj["iTaskID"] = path.escortTaskID;
13671376
pathObj["bRelative"] = path.isRelative;

tdata

0 commit comments

Comments
 (0)