mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-23 21:07:17 +00:00
crossbow achievements
This commit is contained in:
parent
0de012923a
commit
558b8d7aff
@ -10,7 +10,7 @@
|
|||||||
#include "hyper.h"
|
#include "hyper.h"
|
||||||
namespace hr {
|
namespace hr {
|
||||||
|
|
||||||
#define NUMLEADER 87
|
#define NUMLEADER 90
|
||||||
|
|
||||||
EX bool test_achievements = false;
|
EX bool test_achievements = false;
|
||||||
|
|
||||||
@ -80,7 +80,10 @@ EX const char* leadernames[NUMLEADER] = {
|
|||||||
"Lazurite Figurines", // 83
|
"Lazurite Figurines", // 83
|
||||||
"Water Lilies", // 84
|
"Water Lilies", // 84
|
||||||
"Capon Stones", // 85
|
"Capon Stones", // 85
|
||||||
"Crystal Dice" // 86
|
"Crystal Dice", // 86
|
||||||
|
"Crossbow (bull)", // 87
|
||||||
|
"Crossbow (geodesic)", // 88
|
||||||
|
"Crossbow (geometric)", // 89
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LB_STATISTICS 62
|
#define LB_STATISTICS 62
|
||||||
@ -109,7 +112,6 @@ EX bool wrongMode(char flags) {
|
|||||||
if(casual) return true;
|
if(casual) return true;
|
||||||
if(flags == rg::global) return false;
|
if(flags == rg::global) return false;
|
||||||
if(flags == rg::fail) return true;
|
if(flags == rg::fail) return true;
|
||||||
if(bow::weapon) return true;
|
|
||||||
|
|
||||||
if(flags != rg::special_geometry && flags != rg::special_geometry_nicewalls) {
|
if(flags != rg::special_geometry && flags != rg::special_geometry_nicewalls) {
|
||||||
if(!BITRUNCATED) return true;
|
if(!BITRUNCATED) return true;
|
||||||
@ -630,6 +632,10 @@ EX void achievement_count(const string& s, int current, int prev) {
|
|||||||
achievement_gain("BUG3");
|
achievement_gain("BUG3");
|
||||||
if(s == "ELEC" && current >= 10)
|
if(s == "ELEC" && current >= 10)
|
||||||
achievement_gain("ELEC3");
|
achievement_gain("ELEC3");
|
||||||
|
if(s == "BOWVARIETY" && current >= 2)
|
||||||
|
achievement_gain("BOWVARIETY1");
|
||||||
|
if(s == "BOWVARIETY" && current >= 6)
|
||||||
|
achievement_gain("BOWVARIETY2");
|
||||||
}
|
}
|
||||||
|
|
||||||
int specific_improved = 0;
|
int specific_improved = 0;
|
||||||
@ -655,7 +661,6 @@ EX void achievement_score(int cat, int number) {
|
|||||||
#ifdef HAVE_ACHIEVEMENTS
|
#ifdef HAVE_ACHIEVEMENTS
|
||||||
if(cheater) return;
|
if(cheater) return;
|
||||||
if(casual) return;
|
if(casual) return;
|
||||||
if(bow::weapon) return;
|
|
||||||
LATE( achievement_score(cat, number); )
|
LATE( achievement_score(cat, number); )
|
||||||
if(disksize) return;
|
if(disksize) return;
|
||||||
if(cat == LB_HALLOWEEN) {
|
if(cat == LB_HALLOWEEN) {
|
||||||
@ -796,6 +801,9 @@ EX void achievement_final(bool really_final) {
|
|||||||
if(PURE) specialcode+=4;
|
if(PURE) specialcode+=4;
|
||||||
if(numplayers() > 1) specialcode+=8;
|
if(numplayers() > 1) specialcode+=8;
|
||||||
if(inv::on) specialcode+=16;
|
if(inv::on) specialcode+=16;
|
||||||
|
if(bow::crossbow_mode && bow::style == bow::cbBull) specialcode += 32;
|
||||||
|
if(bow::crossbow_mode && bow::style == bow::cbGeodesic) specialcode += 64;
|
||||||
|
if(bow::crossbow_mode && bow::style == bow::cbGeometric) specialcode += 96;
|
||||||
|
|
||||||
if(sphere && specialland == laHalloween) {
|
if(sphere && specialland == laHalloween) {
|
||||||
if(specialcode) return;
|
if(specialcode) return;
|
||||||
@ -822,6 +830,9 @@ EX void achievement_final(bool really_final) {
|
|||||||
case 8: sid = 61; break;
|
case 8: sid = 61; break;
|
||||||
case 9: sid = 44; break;
|
case 9: sid = 44; break;
|
||||||
case 16: sid = 69; break;
|
case 16: sid = 69; break;
|
||||||
|
case 32: sid = 87; break;
|
||||||
|
case 64: sid = 88; break;
|
||||||
|
case 96: sid = 89; break;
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2944,6 +2944,8 @@ EX }
|
|||||||
|
|
||||||
EX namespace kraken {
|
EX namespace kraken {
|
||||||
|
|
||||||
|
EX map<cell*, bool> half_killed;
|
||||||
|
|
||||||
EX cell *head(cell *c) {
|
EX cell *head(cell *c) {
|
||||||
if(c->monst == moKrakenH) return c;
|
if(c->monst == moKrakenH) return c;
|
||||||
if(c->monst == moKrakenT) return c->move(c->mondir);
|
if(c->monst == moKrakenT) return c->move(c->mondir);
|
||||||
@ -3045,6 +3047,7 @@ EX namespace kraken {
|
|||||||
c3->monst = moNone;
|
c3->monst = moNone;
|
||||||
}
|
}
|
||||||
c->monst = moKrakenH;
|
c->monst = moKrakenH;
|
||||||
|
if(half_killed.count(c2)) { half_killed[c] = half_killed[c2]; half_killed.erase(c2); }
|
||||||
vector<pair<cell*, cell*> > acells;
|
vector<pair<cell*, cell*> > acells;
|
||||||
acells.push_back(make_pair(c2, c));
|
acells.push_back(make_pair(c2, c));
|
||||||
forCellIdEx(c3, i, c) {
|
forCellIdEx(c3, i, c) {
|
||||||
@ -3516,6 +3519,7 @@ auto ccm = addHook(hooks_clearmemory, 0, [] () {
|
|||||||
clearing::stats.clear();
|
clearing::stats.clear();
|
||||||
clearing::score.clear();
|
clearing::score.clear();
|
||||||
tortoise::emap.clear();
|
tortoise::emap.clear();
|
||||||
|
kraken::half_killed.clear();
|
||||||
tortoise::babymap.clear();
|
tortoise::babymap.clear();
|
||||||
dragon::target = NULL;
|
dragon::target = NULL;
|
||||||
#if CAP_FIELD
|
#if CAP_FIELD
|
||||||
@ -3548,6 +3552,7 @@ auto ccm = addHook(hooks_clearmemory, 0, [] () {
|
|||||||
addHook(hooks_removecells, 0, [] () {
|
addHook(hooks_removecells, 0, [] () {
|
||||||
for(cell *c: removed_cells) clearing::score.erase(c);
|
for(cell *c: removed_cells) clearing::score.erase(c);
|
||||||
for(auto& am: adj_memo) am.clear();
|
for(auto& am: adj_memo) am.clear();
|
||||||
|
for(cell *c: removed_cells) kraken::half_killed.erase(c);
|
||||||
eliminate_if(heat::offscreen_heat, is_cell_removed);
|
eliminate_if(heat::offscreen_heat, is_cell_removed);
|
||||||
eliminate_if(heat::offscreen_fire, is_cell_removed);
|
eliminate_if(heat::offscreen_fire, is_cell_removed);
|
||||||
eliminate_if(princess::infos, [] (princess::info*& i) {
|
eliminate_if(princess::infos, [] (princess::info*& i) {
|
||||||
|
49
crossbow.cpp
49
crossbow.cpp
@ -374,6 +374,33 @@ EX void shoot() {
|
|||||||
|
|
||||||
vector<bowpoint> pushes;
|
vector<bowpoint> pushes;
|
||||||
|
|
||||||
|
// for achievements
|
||||||
|
set<eMonster> kills;
|
||||||
|
vector<pair<cell*, int>> healthy_dragons;
|
||||||
|
map<cell*, pair<int, int>> kraken_hits;
|
||||||
|
int dragon_hits = 0;
|
||||||
|
|
||||||
|
// for achievements
|
||||||
|
for(auto& mov: bowpath) {
|
||||||
|
cell *c = mov.prev.at;
|
||||||
|
if(c->monst == moDragonHead) {
|
||||||
|
bool healthy = true;
|
||||||
|
cell *c1 = c;
|
||||||
|
int qty = 0;
|
||||||
|
for(int i=0; i<iteration_limit; i++) {
|
||||||
|
if(!isDragon(c1)) break;
|
||||||
|
if(!c1->hitpoints) { healthy = false; break; }
|
||||||
|
if(c1->mondir == NODIR) break;
|
||||||
|
c1 = c1->move(c1->mondir);
|
||||||
|
qty++;
|
||||||
|
}
|
||||||
|
if(healthy) healthy_dragons.emplace_back(c, qty);
|
||||||
|
}
|
||||||
|
if(c->monst == moKrakenT && c->hitpoints) {
|
||||||
|
kraken_hits[kraken::head(c)].first++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(auto& mov: bowpath) {
|
for(auto& mov: bowpath) {
|
||||||
cell *c = mov.prev.at;
|
cell *c = mov.prev.at;
|
||||||
cell *cf = mov.prev.cpeek();
|
cell *cf = mov.prev.cpeek();
|
||||||
@ -401,6 +428,7 @@ EX void shoot() {
|
|||||||
mirror::breakMirror(mov.next, -1);
|
mirror::breakMirror(mov.next, -1);
|
||||||
eMonster m = c->monst;
|
eMonster m = c->monst;
|
||||||
if(!m || isMimic(m)) continue;
|
if(!m || isMimic(m)) continue;
|
||||||
|
if(m == moKrakenH) continue;
|
||||||
|
|
||||||
if(!canAttack(cf, who, c, m, attackflags)) {
|
if(!canAttack(cf, who, c, m, attackflags)) {
|
||||||
if(among(m, moSleepBull, moHerdBull)) {
|
if(among(m, moSleepBull, moHerdBull)) {
|
||||||
@ -420,11 +448,16 @@ EX void shoot() {
|
|||||||
bool push = (items[itCurseWeakness] || (isStunnable(c->monst) && c->hitpoints > 1));
|
bool push = (items[itCurseWeakness] || (isStunnable(c->monst) && c->hitpoints > 1));
|
||||||
push = push && (!(mov.flags & bpLAST) && monsterPushable(c));
|
push = push && (!(mov.flags & bpLAST) && monsterPushable(c));
|
||||||
|
|
||||||
|
// for achievements
|
||||||
|
if(isDragon(m)) dragon_hits++;
|
||||||
|
if(m == moKrakenT && c->hitpoints) kraken_hits[kraken::head(c)].second++;
|
||||||
|
|
||||||
if(m && attackMonster(c, attackflags | AF_MSG, who)) hit_anything = true;
|
if(m && attackMonster(c, attackflags | AF_MSG, who)) hit_anything = true;
|
||||||
|
|
||||||
if(!c->monst || isAnyIvy(m)) {
|
if(!c->monst || isAnyIvy(m)) {
|
||||||
spread_plague(cf, c, movei(mov.prev).rev().d, moPlayer);
|
spread_plague(cf, c, movei(mov.prev).rev().d, moPlayer);
|
||||||
produceGhost(c, m, moPlayer);
|
produceGhost(c, m, moPlayer);
|
||||||
|
kills.insert(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(push) pushes.push_back(mov);
|
if(push) pushes.push_back(mov);
|
||||||
@ -446,6 +479,22 @@ EX void shoot() {
|
|||||||
|
|
||||||
reverse(bowpath.begin(), bowpath.end());
|
reverse(bowpath.begin(), bowpath.end());
|
||||||
|
|
||||||
|
// three achievements:
|
||||||
|
achievement_count("BOWVARIETY", kills.size(), 0);
|
||||||
|
|
||||||
|
for(auto p: healthy_dragons) {
|
||||||
|
cell *c = p.first;
|
||||||
|
if(c->monst != moDragonHead && dragon_hits >= p.second)
|
||||||
|
achievement_gain_once("BOWDRAGON");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto kh: kraken_hits) {
|
||||||
|
if(kh.second.first == 3 && kh.second.second == 3) {
|
||||||
|
if(kraken::half_killed[kh.first]) achievement_gain_once("BOWKRAKEN");
|
||||||
|
else kraken::half_killed[kh.first] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gen_bowpath_map();
|
gen_bowpath_map();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user