mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-11 18:00:34 +00:00
racing:: achievements/leaderboards
This commit is contained in:
parent
ada9a99a5d
commit
e4939ad8d4
@ -71,6 +71,7 @@ const char* leadernames[NUMLEADER] = {
|
|||||||
|
|
||||||
#define LB_STATISTICS 62
|
#define LB_STATISTICS 62
|
||||||
#define LB_HALLOWEEN 63
|
#define LB_HALLOWEEN 63
|
||||||
|
#define LB_RACING 81
|
||||||
|
|
||||||
void upload_score(int id, int v);
|
void upload_score(int id, int v);
|
||||||
|
|
||||||
@ -87,7 +88,8 @@ bool wrongMode(char flags) {
|
|||||||
if(geometry != gNormal) return true;
|
if(geometry != gNormal) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(shmup::on != (flags == rg::shmup)) return true;
|
if(shmup::on != (flags == rg::shmup || flags == rg::racing)) return true;
|
||||||
|
if(racing::on != (flags == rg::racing)) return true;
|
||||||
#if CAP_DAILY
|
#if CAP_DAILY
|
||||||
if(daily::on != (flags == rg::daily)) return true;
|
if(daily::on != (flags == rg::daily)) return true;
|
||||||
#endif
|
#endif
|
||||||
@ -521,10 +523,11 @@ void achievement_score(int cat, int number) {
|
|||||||
else if(geometry) return;
|
else if(geometry) return;
|
||||||
if(CHANGED_VARIATION) return;
|
if(CHANGED_VARIATION) return;
|
||||||
if(randomPatternsMode) return;
|
if(randomPatternsMode) return;
|
||||||
if(shmup::on && cat != LB_PURE_TACTICS_SHMUP && cat != LB_PURE_TACTICS_COOP) return;
|
if(shmup::on && cat != LB_PURE_TACTICS_SHMUP && cat != LB_PURE_TACTICS_COOP && cat != LB_RACING) return;
|
||||||
if(yendor::on && cat != LB_YENDOR_CHALLENGE) return;
|
if(yendor::on && cat != LB_YENDOR_CHALLENGE) return;
|
||||||
if(tactic::on && cat != LB_PURE_TACTICS && cat != LB_PURE_TACTICS_SHMUP && cat != LB_PURE_TACTICS_COOP)
|
if(tactic::on && cat != LB_PURE_TACTICS && cat != LB_PURE_TACTICS_SHMUP && cat != LB_PURE_TACTICS_COOP)
|
||||||
return;
|
return;
|
||||||
|
if(racing::on && cat != LB_RACING) return;
|
||||||
upload_score(cat, number);
|
upload_score(cat, number);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
2
hyper.h
2
hyper.h
@ -162,6 +162,7 @@ void addMessage(string s, char spamtype = 0);
|
|||||||
#define NUMLEADER 82
|
#define NUMLEADER 82
|
||||||
#define LB_PURE_TACTICS_SHMUP 49
|
#define LB_PURE_TACTICS_SHMUP 49
|
||||||
#define LB_PURE_TACTICS_COOP 50
|
#define LB_PURE_TACTICS_COOP 50
|
||||||
|
#define LB_RACING 81
|
||||||
|
|
||||||
#if ISMOBILE || ISWEB || ISPANDORA || 1
|
#if ISMOBILE || ISWEB || ISPANDORA || 1
|
||||||
typedef double ld;
|
typedef double ld;
|
||||||
@ -4699,6 +4700,7 @@ namespace racing {
|
|||||||
void apply_seed();
|
void apply_seed();
|
||||||
string racetimeformat(int t);
|
string racetimeformat(int t);
|
||||||
void add_debug(cell *c);
|
void add_debug(cell *c);
|
||||||
|
void displayScore(eLand l);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool subscreen_split(reaction_t for_each_subscreen);
|
bool subscreen_split(reaction_t for_each_subscreen);
|
||||||
|
64
racing.cpp
64
racing.cpp
@ -15,6 +15,8 @@ bool on;
|
|||||||
bool player_relative = false;
|
bool player_relative = false;
|
||||||
bool track_ready;
|
bool track_ready;
|
||||||
|
|
||||||
|
bool official_race = false;
|
||||||
|
|
||||||
int TWIDTH;
|
int TWIDTH;
|
||||||
|
|
||||||
ld race_advance = 0;
|
ld race_advance = 0;
|
||||||
@ -75,7 +77,7 @@ struct ghost {
|
|||||||
vector<ghostmoment> history;
|
vector<ghostmoment> history;
|
||||||
};
|
};
|
||||||
|
|
||||||
using raceset = map<eLand, vector<ghost>>;
|
typedef map<eLand, vector<ghost>> raceset;
|
||||||
map<pair<string, int>, raceset> race_ghosts;
|
map<pair<string, int>, raceset> race_ghosts;
|
||||||
|
|
||||||
map<pair<string, int>, raceset> official_race_ghosts;
|
map<pair<string, int>, raceset> official_race_ghosts;
|
||||||
@ -83,6 +85,14 @@ map<pair<string, int>, raceset> official_race_ghosts;
|
|||||||
raceset& ghostset() { return race_ghosts[make_pair(track_code, modecode())]; }
|
raceset& ghostset() { return race_ghosts[make_pair(track_code, modecode())]; }
|
||||||
raceset& oghostset() { return official_race_ghosts[make_pair(track_code, modecode())]; }
|
raceset& oghostset() { return official_race_ghosts[make_pair(track_code, modecode())]; }
|
||||||
|
|
||||||
|
int get_score_in_land(eLand l) {
|
||||||
|
auto& gh = ghostset();
|
||||||
|
if(!gh.count(l)) return 0;
|
||||||
|
auto& v = gh[l];
|
||||||
|
if(!isize(v)) return 0;
|
||||||
|
return v[0].result;
|
||||||
|
}
|
||||||
|
|
||||||
array<vector<ghostmoment>, MAXPLAYER> current_history;
|
array<vector<ghostmoment>, MAXPLAYER> current_history;
|
||||||
|
|
||||||
string ghost_prefix = "default";
|
string ghost_prefix = "default";
|
||||||
@ -172,6 +182,10 @@ bool read_ghosts(string seed, int mcode) {
|
|||||||
for(auto gh: v)
|
for(auto gh: v)
|
||||||
println(hlog, " ", racetimeformat(gh.result), " : ", format("%08X", gh.checksum), " = ", minf[gh.cs.uicolor].name);
|
println(hlog, " ", racetimeformat(gh.result), " : ", format("%08X", gh.checksum), " = ", minf[gh.cs.uicolor].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fhstream f("officials.data", "wb");
|
||||||
|
hwrite(f, (const int&) VERNUM_HEX);
|
||||||
|
hwrite(f, ghostset());
|
||||||
}
|
}
|
||||||
|
|
||||||
string fname = ghost_filename(seed, mcode);
|
string fname = ghost_filename(seed, mcode);
|
||||||
@ -659,6 +673,12 @@ void generate_track() {
|
|||||||
|
|
||||||
race_start_tick = 0;
|
race_start_tick = 0;
|
||||||
for(int i=0; i<MAXPLAYER; i++) race_finish_tick[i] = 0;
|
for(int i=0; i<MAXPLAYER; i++) race_finish_tick[i] = 0;
|
||||||
|
|
||||||
|
official_race = (track_code == "OFFICIAL" && modecode() == 2);
|
||||||
|
if(official_race && race_checksum != oghostset() [specialland] [0].checksum) {
|
||||||
|
official_race = false;
|
||||||
|
addMessage(XLAT("Race did not generate correctly for some reason -- not ranked"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inrec = false;
|
bool inrec = false;
|
||||||
@ -840,6 +860,8 @@ string racetimeformat(int t) {
|
|||||||
|
|
||||||
void track_chooser(string new_track) {
|
void track_chooser(string new_track) {
|
||||||
dialog::init(XLAT("Racing"));
|
dialog::init(XLAT("Racing"));
|
||||||
|
|
||||||
|
map<char, eLand> landmap;
|
||||||
|
|
||||||
char let = 'a';
|
char let = 'a';
|
||||||
for(eLand l: race_lands) {
|
for(eLand l: race_lands) {
|
||||||
@ -848,6 +870,7 @@ void track_chooser(string new_track) {
|
|||||||
int best = LOST;
|
int best = LOST;
|
||||||
for(auto& gc: gh) best = min(best, gc.result);
|
for(auto& gc: gh) best = min(best, gc.result);
|
||||||
string s = (best == LOST) ? "" : racetimeformat(best);
|
string s = (best == LOST) ? "" : racetimeformat(best);
|
||||||
|
landmap[let] = l;
|
||||||
dialog::addSelItem(XLAT1(linf[l].name), s, let++);
|
dialog::addSelItem(XLAT1(linf[l].name), s, let++);
|
||||||
dialog::add_action([l, new_track] () {
|
dialog::add_action([l, new_track] () {
|
||||||
stop_game();
|
stop_game();
|
||||||
@ -1051,6 +1074,40 @@ void prepare_subscreens() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
map<string, map<eLand, int> > scoreboard;
|
||||||
|
|
||||||
|
void uploadScore() {
|
||||||
|
int tscore = 0;
|
||||||
|
for(eLand l: race_lands) {
|
||||||
|
int i = get_score_in_land(l);
|
||||||
|
if(!i) continue;
|
||||||
|
int score = 60000000 / i; // 1000 points for minute, 2000 points for 30 sec
|
||||||
|
tscore += score;
|
||||||
|
}
|
||||||
|
|
||||||
|
achievement_score(LB_RACING, tscore);
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayScore(eLand l) {
|
||||||
|
int vf = min((vid.yres-64) / 70, vid.xres/80);
|
||||||
|
int x = vid.xres / 4;
|
||||||
|
|
||||||
|
if(get_sync_status() == 1) {
|
||||||
|
displayfr(x, 56, 1, vf, "(syncing)", 0xC0C0C0, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vector<pair<int, string> > scores;
|
||||||
|
for(auto p: scoreboard) if(p.second.count(l)) scores.emplace_back(p.second[l], p.first);
|
||||||
|
sort(scores.begin(), scores.end());
|
||||||
|
int i = 0;
|
||||||
|
for(auto& sc: scores) {
|
||||||
|
int i0 = 56 + (i++) * vf;
|
||||||
|
displayfr(x, i0, 1, vf, racetimeformat(sc.first), 0xC0C0C0, 16);
|
||||||
|
displayfr(x+8, i0, 1, vf, sc.second, 0xC0C0C0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void race_won() {
|
void race_won() {
|
||||||
if(!race_finish_tick[current_player]) {
|
if(!race_finish_tick[current_player]) {
|
||||||
int result = ticks - race_start_tick;
|
int result = ticks - race_start_tick;
|
||||||
@ -1064,6 +1121,9 @@ void race_won() {
|
|||||||
if(place == 2) trophy[current_player] = 0xFFFFC0FF;
|
if(place == 2) trophy[current_player] = 0xFFFFC0FF;
|
||||||
if(place == 3) trophy[current_player] = 0x967444FF;
|
if(place == 3) trophy[current_player] = 0x967444FF;
|
||||||
|
|
||||||
|
if(place == 1 && losers && official_race)
|
||||||
|
achievement_gain("RACEWON", rg::racing);
|
||||||
|
|
||||||
race_finish_tick[current_player] = ticks;
|
race_finish_tick[current_player] = ticks;
|
||||||
charstyle gcs = getcs();
|
charstyle gcs = getcs();
|
||||||
for(color_t *x: {&gcs.skincolor, &gcs.haircolor, &gcs.dresscolor, &gcs.swordcolor, &gcs.dresscolor2}) {
|
for(color_t *x: {&gcs.skincolor, &gcs.haircolor, &gcs.dresscolor, &gcs.swordcolor, &gcs.dresscolor2}) {
|
||||||
@ -1080,6 +1140,8 @@ void race_won() {
|
|||||||
subtrack.resize(ghosts_to_save);
|
subtrack.resize(ghosts_to_save);
|
||||||
if(ghosts_to_save > 0)
|
if(ghosts_to_save > 0)
|
||||||
write_ghosts(track_code, modecode());
|
write_ghosts(track_code, modecode());
|
||||||
|
|
||||||
|
if(official_race) uploadScore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user