1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-25 01:20:37 +00:00

YASC codes

This commit is contained in:
Zeno Rogue 2021-05-24 16:14:02 +02:00
parent 887fc9e1e2
commit 7fc91b1eaf
4 changed files with 127 additions and 60 deletions

View File

@ -30,6 +30,26 @@ EX int lastkills;
EX vector<bool> legalmoves; EX vector<bool> legalmoves;
/* why is a move illegal */
EX vector<int> move_issues;
#if HDR
static const int miVALID = 10000;
static const int miENTITY = 11000;
static const int miRESTRICTED = 10100;
static const int miTHREAT = 10010;
static const int miWALL = 10001;
#endif
EX int checked_move_issue;
EX int yasc_code;
EX void check_if_monster() {
eMonster m = cwt.peek()->monst;
if(m && m != passive_switch && !isFriendly(m))
checked_move_issue = miENTITY;
}
EX bool hasSafeOrb(cell *c) { EX bool hasSafeOrb(cell *c) {
return return
c->item == itOrbSafety || c->item == itOrbSafety ||
@ -272,21 +292,35 @@ EX void checkmove() {
for(int i=0; i<ittypes; i++) orbusedbak[i] = orbused[i]; for(int i=0; i<ittypes; i++) orbusedbak[i] = orbused[i];
legalmoves.clear(); legalmoves.resize(cwt.at->type+1, false); legalmoves.clear(); legalmoves.resize(cwt.at->type+1, false);
move_issues.clear(); move_issues.resize(cwt.at->type, 0);
canmove = haveRangedTarget(); canmove = haveRangedTarget();
items[itWarning]+=2; items[itWarning]+=2;
if(movepcto(-1, 0, true)) canmove = legalmoves[cwt.at->type] = true; if(movepcto(-1, 0, true))
canmove = legalmoves[cwt.at->type] = true;
if(vid.mobilecompasssize || !canmove) if(true) {
for(int i=0; i<cwt.at->type; i++) for(int i=0; i<cwt.at->type; i++) {
if(movepcto(1, -1, true)) if(movepcto(1, -1, true)) {
canmove = legalmoves[cwt.spin] = true;
if(vid.mobilecompasssize || !canmove)
for(int i=0; i<cwt.at->type; i++)
if(movepcto(1, 1, true))
canmove = legalmoves[cwt.spin] = true; canmove = legalmoves[cwt.spin] = true;
}
check_if_monster();
move_issues[cwt.spin] = checked_move_issue;
if(!legalmoves[cwt.spin]) {
if(movepcto(1, 1, true)) {
canmove = legalmoves[cwt.spin] = true;
}
check_if_monster();
move_issues[cwt.spin] = checked_move_issue;
}
}
}
if(kills[moPlayer]) canmove = false; if(kills[moPlayer]) canmove = false;
yasc_code = 0;
for(int i=0; i<cwt.at->type; i++)
yasc_code += move_issues[i];
#if CAP_INV #if CAP_INV
if(inv::on && !canmove && !inv::incheck) { if(inv::on && !canmove && !inv::incheck) {
if(inv::remaining[itOrbSafety] || inv::remaining[itOrbFreedom]) if(inv::remaining[itOrbSafety] || inv::remaining[itOrbFreedom])

View File

@ -644,6 +644,12 @@ EX void initConfig() {
param_b(resizable, "resizable", true) param_b(resizable, "resizable", true)
-> editable("resizable window", 'r'); -> editable("resizable window", 'r');
param_b(display_yasc_codes, "yasc", false)
-> editable("YASC codes", 'Y')
-> set_reaction([] {
addMessage("YASC codes: Sides-Entity-Restrict-Threat-Wall");
});
param_b(vid.relative_font, "relative_font", true) param_b(vid.relative_font, "relative_font", true)
-> editable("set relative font size", 'r') -> editable("set relative font size", 'r')
-> set_reaction(compute_fsize); -> set_reaction(compute_fsize);
@ -1763,6 +1769,8 @@ EX void configureInterface() {
add_edit(glyphsortorder); add_edit(glyphsortorder);
add_edit(vid.graphglyph); add_edit(vid.graphglyph);
add_edit(display_yasc_codes);
dialog::addSelItem(XLAT("draw crosshair"), crosshair_size > 0 ? fts(crosshair_size) : ONOFF(false), 'x'); dialog::addSelItem(XLAT("draw crosshair"), crosshair_size > 0 ? fts(crosshair_size) : ONOFF(false), 'x');
dialog::add_action([] () { dialog::add_action([] () {
dialog::editNumber(crosshair_size, 0, 100, 1, 10, XLAT("crosshair size"), XLAT( dialog::editNumber(crosshair_size, 0, 100, 1, 10, XLAT("crosshair size"), XLAT(

View File

@ -117,14 +117,16 @@ bool pcmove::checkNeedMove(bool checkonly, bool attacking) {
return false; return false;
int flags = 0; int flags = 0;
if(cwt.at->monst) { if(cwt.at->monst) {
if(isMountable(cwt.at->monst)) if(vmsg(miRESTRICTED)) {
addMessage(XLAT("You need to dismount %the1!", cwt.at->monst)); if(isMountable(cwt.at->monst))
else addMessage(XLAT("You need to dismount %the1!", cwt.at->monst));
addMessage(XLAT("You need to move to give space to %the1!", cwt.at->monst)); else
addMessage(XLAT("You need to move to give space to %the1!", cwt.at->monst));
}
} }
else if(cwt.at->wall == waRoundTable) { else if(cwt.at->wall == waRoundTable) {
if(markOrb2(itOrbAether)) return false; if(markOrb2(itOrbAether)) return false;
if(vmsg()) if(vmsg(miRESTRICTED))
addMessage(XLAT("It would be impolite to land on the table!")); addMessage(XLAT("It would be impolite to land on the table!"));
} }
else if(cwt.at->wall == waLake) { else if(cwt.at->wall == waLake) {
@ -132,47 +134,48 @@ bool pcmove::checkNeedMove(bool checkonly, bool attacking) {
if(markOrb2(itOrbFish)) return false; if(markOrb2(itOrbFish)) return false;
if(in_gravity_zone(cwt.at) && passable(cwt.at, NULL, P_ISPLAYER)) return false; if(in_gravity_zone(cwt.at) && passable(cwt.at, NULL, P_ISPLAYER)) return false;
flags |= AF_FALL; flags |= AF_FALL;
if(vmsg()) addMessage(XLAT("Ice below you is melting! RUN!")); if(vmsg(miWALL)) addMessage(XLAT("Ice below you is melting! RUN!"));
} }
else if(!attacking && cellEdgeUnstable(cwt.at)) { else if(!attacking && cellEdgeUnstable(cwt.at)) {
if(markOrb2(itOrbAether)) return false; if(markOrb2(itOrbAether)) return false;
if(in_gravity_zone(cwt.at) && passable(cwt.at, NULL, P_ISPLAYER)) return false; if(in_gravity_zone(cwt.at) && passable(cwt.at, NULL, P_ISPLAYER)) return false;
if(vmsg()) addMessage(XLAT("Nothing to stand on here!")); if(vmsg(miRESTRICTED)) addMessage(XLAT("Nothing to stand on here!"));
return true; return true;
} }
else if(among(cwt.at->wall, waSea, waCamelotMoat, waLake, waDeepWater)) { else if(among(cwt.at->wall, waSea, waCamelotMoat, waLake, waDeepWater)) {
if(markOrb(itOrbFish)) return false; if(markOrb(itOrbFish)) return false;
if(markOrb2(itOrbAether)) return false; if(markOrb2(itOrbAether)) return false;
if(in_gravity_zone(cwt.at) && passable(cwt.at, NULL, P_ISPLAYER)) return false; if(in_gravity_zone(cwt.at) && passable(cwt.at, NULL, P_ISPLAYER)) return false;
if(vmsg()) addMessage(XLAT("You have to run away from the water!")); if(vmsg(miWALL)) addMessage(XLAT("You have to run away from the water!"));
} }
else if(cwt.at->wall == waClosedGate) { else if(cwt.at->wall == waClosedGate) {
if(markOrb2(itOrbAether)) return false; if(markOrb2(itOrbAether)) return false;
if(vmsg()) addMessage(XLAT("The gate is closing right on you! RUN!")); if(vmsg(miWALL)) addMessage(XLAT("The gate is closing right on you! RUN!"));
} }
else if(isFire(cwt.at) && !markOrb(itOrbWinter) && !markOrb(itCurseWater) && !markOrb2(itOrbShield)) { else if(isFire(cwt.at) && !markOrb(itOrbWinter) && !markOrb(itCurseWater) && !markOrb2(itOrbShield)) {
if(markOrb2(itOrbAether)) return false; if(markOrb2(itOrbAether)) return false;
if(vmsg()) addMessage(XLAT("This spot will be burning soon! RUN!")); if(vmsg(miWALL)) addMessage(XLAT("This spot will be burning soon! RUN!"));
} }
else if(cwt.at->wall == waMagma && !markOrb(itOrbWinter) && !markOrb(itCurseWater) && !markOrb2(itOrbShield)) { else if(cwt.at->wall == waMagma && !markOrb(itOrbWinter) && !markOrb(itCurseWater) && !markOrb2(itOrbShield)) {
if(markOrb2(itOrbAether)) return false; if(markOrb2(itOrbAether)) return false;
if(in_gravity_zone(cwt.at) && passable(cwt.at, cwt.at, P_ISPLAYER)) return false; if(in_gravity_zone(cwt.at) && passable(cwt.at, cwt.at, P_ISPLAYER)) return false;
if(vmsg()) addMessage(XLAT("Run away from the magma!")); if(vmsg(miWALL)) addMessage(XLAT("Run away from the magma!"));
} }
else if(cwt.at->wall == waChasm) { else if(cwt.at->wall == waChasm) {
if(markOrb2(itOrbAether)) return false; if(markOrb2(itOrbAether)) return false;
if(in_gravity_zone(cwt.at) && passable(cwt.at, cwt.at, P_ISPLAYER)) return false; if(in_gravity_zone(cwt.at) && passable(cwt.at, cwt.at, P_ISPLAYER)) return false;
flags |= AF_FALL; flags |= AF_FALL;
if(vmsg()) addMessage(XLAT("The floor has collapsed! RUN!")); if(vmsg(miWALL)) addMessage(XLAT("The floor has collapsed! RUN!"));
} }
else if(items[itOrbAether] > ORBBASE && !passable(cwt.at, NULL, P_ISPLAYER | P_NOAETHER)) { else if(items[itOrbAether] > ORBBASE && !passable(cwt.at, NULL, P_ISPLAYER | P_NOAETHER)) {
if(markOrb2(itOrbAether)) return false; if(markOrb2(itOrbAether)) return false;
vmsg(miWALL);
return true; return true;
} }
else if(!passable(cwt.at, NULL, P_ISPLAYER)) { else if(!passable(cwt.at, NULL, P_ISPLAYER)) {
if(isFire(cwt.at)) return false; // already checked: have Shield if(isFire(cwt.at)) return false; // already checked: have Shield
if(markOrb2(itOrbAether)) return false; if(markOrb2(itOrbAether)) return false;
if(vmsg()) addMessage(XLAT("Your Aether power has expired! RUN!")); if(vmsg(miWALL)) addMessage(XLAT("Your Aether power has expired! RUN!"));
} }
else return false; else return false;
if(hardcore && !checkonly) if(hardcore && !checkonly)
@ -220,15 +223,16 @@ struct pcmove {
movei mi, mip; movei mi, mip;
pcmove() : mi(nullptr, nullptr, 0), mip(nullptr, nullptr, 0) {} pcmove() : mi(nullptr, nullptr, 0), mip(nullptr, nullptr, 0) {}
bool vmsg(); bool vmsg(int code);
}; };
#endif #endif
EX cell *global_pushto; EX cell *global_pushto;
bool pcmove::vmsg() { changes.rollback(); return errormsgs && !checkonly; } bool pcmove::vmsg(int code) { checked_move_issue = code; changes.rollback(); return errormsgs && !checkonly; }
EX bool movepcto(int d, int subdir IS(1), bool checkonly IS(false)) { EX bool movepcto(int d, int subdir IS(1), bool checkonly IS(false)) {
checked_move_issue = miVALID;
pcmove pcm; pcmove pcm;
pcm.checkonly = checkonly; pcm.checkonly = checkonly;
pcm.d = d; pcm.subdir = subdir; pcm.d = d; pcm.subdir = subdir;
@ -262,7 +266,7 @@ bool pcmove::movepcto() {
lastmountpos[0] = cwt.at; lastmountpos[0] = cwt.at;
if(againstRose(cwt.at, NULL) && d<0 && !scentResistant()) { if(againstRose(cwt.at, NULL) && d<0 && !scentResistant()) {
if(vmsg()) if(vmsg(miRESTRICTED))
addMessage("You just cannot stand in place, those roses smell too nicely."); addMessage("You just cannot stand in place, those roses smell too nicely.");
return false; return false;
} }
@ -359,7 +363,7 @@ bool pcmove::swing() {
mirror::act(origd, mirror::SPINMULTI | mirror::ATTACK); mirror::act(origd, mirror::SPINMULTI | mirror::ATTACK);
if(monstersnear_add_pmi(movei(cwt.at, STAY))) { if(monstersnear_add_pmi(movei(cwt.at, STAY))) {
if(vmsg()) if(vmsg(miTHREAT))
wouldkill("You would be killed by %the1!"); wouldkill("You would be killed by %the1!");
return false; return false;
} }
@ -604,7 +608,7 @@ bool pcmove::actual_move() {
} }
if(againstRose(cwt.at, c2) && !scentResistant()) { if(againstRose(cwt.at, c2) && !scentResistant()) {
if(vmsg()) addMessage("Those roses smell too nicely. You have to come towards them."); if(vmsg(miRESTRICTED)) addMessage("Those roses smell too nicely. You have to come towards them.");
return false; return false;
} }
@ -629,7 +633,7 @@ bool pcmove::actual_move() {
mip = determinePush(cwt, subdir, [c2] (cell *c) { return canPushThumperOn(c, c2, cwt.at); }); mip = determinePush(cwt, subdir, [c2] (cell *c) { return canPushThumperOn(c, c2, cwt.at); });
if(mip.t) changes.ccell(mip.t); if(mip.t) changes.ccell(mip.t);
if(mip.d == NO_SPACE) { if(mip.d == NO_SPACE) {
if(vmsg()) addMessage(XLAT("No room to push %the1.", c2->wall)); if(vmsg(miWALL)) addMessage(XLAT("No room to push %the1.", c2->wall));
return false; return false;
} }
nextmovetype = lmMove; nextmovetype = lmMove;
@ -641,7 +645,7 @@ bool pcmove::actual_move() {
} }
if(c2->item == itHolyGrail && roundTableRadius(c2) < newRoundTableRadius()) { if(c2->item == itHolyGrail && roundTableRadius(c2) < newRoundTableRadius()) {
if(vmsg()) addMessage(XLAT("That was not a challenge. Find a larger castle!")); if(vmsg(miRESTRICTED)) addMessage(XLAT("That was not a challenge. Find a larger castle!"));
return false; return false;
} }
@ -681,21 +685,21 @@ bool pcmove::boat_move() {
cell *& c2 = mi.t; cell *& c2 = mi.t;
if(againstWind(c2, cwt.at)) { if(againstWind(c2, cwt.at)) {
if(vmsg()) blowaway_message(c2); if(vmsg(miRESTRICTED)) blowaway_message(c2);
return false; return false;
} }
if(againstCurrent(c2, cwt.at) && !markOrb(itOrbWater)) { if(againstCurrent(c2, cwt.at) && !markOrb(itOrbWater)) {
if(markOrb(itOrbFish) || markOrb(itOrbAether) || gravity_state) if(markOrb(itOrbFish) || markOrb(itOrbAether) || gravity_state)
return after_escape(); return after_escape();
if(vmsg()) addMessage(XLAT("You cannot go against the current!")); if(vmsg(miRESTRICTED)) addMessage(XLAT("You cannot go against the current!"));
return false; return false;
} }
if(cwt.at->item == itOrbYendor) { if(cwt.at->item == itOrbYendor) {
if(markOrb(itOrbFish) || markOrb(itOrbAether) || gravity_state) if(markOrb(itOrbFish) || markOrb(itOrbAether) || gravity_state)
return after_escape(); return after_escape();
if(vmsg()) addMessage(XLAT("The Orb of Yendor is locked in with powerful magic.")); if(vmsg(miRESTRICTED)) addMessage(XLAT("The Orb of Yendor is locked in with powerful magic."));
return false; return false;
} }
@ -755,7 +759,7 @@ bool pcmove::after_escape() {
if(push_behind && !c2->monst && !nonAdjacentPlayer(c2, cwt.at) && fmsMove) { if(push_behind && !c2->monst && !nonAdjacentPlayer(c2, cwt.at) && fmsMove) {
eWall what = c2->wall; eWall what = c2->wall;
if(!thruVine(c2, cwt.at) && !canPushStatueOn(cwt.at, P_ISPLAYER)) { if(!thruVine(c2, cwt.at) && !canPushStatueOn(cwt.at, P_ISPLAYER)) {
if(vmsg()) { if(vmsg(miRESTRICTED)) {
if(isFire(cwt.at)) if(isFire(cwt.at))
addMessage(XLAT("You have to escape first!")); addMessage(XLAT("You have to escape first!"));
else else
@ -838,7 +842,7 @@ bool pcmove::after_escape() {
} }
else if(c2->monst == moKnight) { else if(c2->monst == moKnight) {
#if CAP_COMPLEX2 #if CAP_COMPLEX2
if(vmsg()) camelot::knightFlavorMessage(c2); if(vmsg(miWALL)) camelot::knightFlavorMessage(c2);
#endif #endif
return false; return false;
} }
@ -846,11 +850,11 @@ bool pcmove::after_escape() {
&& !(peace::on && !isMultitile(c2->monst) && !good_tortoise)) && !(peace::on && !isMultitile(c2->monst) && !good_tortoise))
return attack(); return attack();
else if(!passable(c2, cwt.at, P_USEBOAT | P_ISPLAYER | P_MIRROR | P_MONSTER)) { else if(!passable(c2, cwt.at, P_USEBOAT | P_ISPLAYER | P_MIRROR | P_MONSTER)) {
if(vmsg()) tell_why_impassable(); tell_why_impassable();
return false; return false;
} }
else if(items[itFatigue] + fatigue_cost(mi) > 10) { else if(items[itFatigue] + fatigue_cost(mi) > 10) {
if(vmsg()) if(vmsg(miRESTRICTED))
addMessage(XLAT("You are too fatigued!")); addMessage(XLAT("You are too fatigued!"));
return false; return false;
} }
@ -886,27 +890,42 @@ bool pcmove::move_if_okay() {
void pcmove::tell_why_impassable() { void pcmove::tell_why_impassable() {
cell*& c2 = mi.t; cell*& c2 = mi.t;
if(nonAdjacent(cwt.at,c2)) { if(nonAdjacent(cwt.at,c2)) {
addMessage(geosupport_football() < 2 ? if(vmsg(miRESTRICTED)) addMessage(geosupport_football() < 2 ?
XLAT("You cannot move between the cells without dots here!") : XLAT("You cannot move between the cells without dots here!") :
XLAT("You cannot move between the triangular cells here!") XLAT("You cannot move between the triangular cells here!")
); );
} }
else if(againstWind(c2, cwt.at)) blowaway_message(c2); else if(againstWind(c2, cwt.at)) {
else if(isAlch(c2)) if(vmsg(miRESTRICTED))
addMessage(XLAT("Wrong color!")); blowaway_message(c2);
else if(c2->wall == waRoundTable) }
addMessage(XLAT("It would be impolite to land on the table!")); else if(isAlch(c2)) {
else if(snakelevel(cwt.at) >= 3 && snakelevel(c2) == 0 && !isWall(c2)) if(vmsg(miRESTRICTED))
addMessage(XLAT("You would get hurt!", c2->wall)); addMessage(XLAT("Wrong color!"));
else if(cellEdgeUnstable(cwt.at) && cellEdgeUnstable(c2)) { }
addMessage(XLAT("Gravity does not allow this!")); else if(c2->wall == waRoundTable) {
if(vmsg(miRESTRICTED))
addMessage(XLAT("It would be impolite to land on the table!"));
}
else if(snakelevel(cwt.at) >= 3 && snakelevel(c2) == 0 && !isWall(c2)) {
if(vmsg(miRESTRICTED))
addMessage(XLAT("You would get hurt!", c2->wall));
}
else if(cellEdgeUnstable(cwt.at) && cellEdgeUnstable(c2)) {
if(vmsg(miRESTRICTED))
addMessage(XLAT("Gravity does not allow this!"));
}
else if(c2->wall == waChasm && c2->land == laDual) {
if(vmsg(miRESTRICTED))
addMessage(XLAT("You cannot move there!"));
}
else if(!c2->wall) {
if(vmsg(miRESTRICTED))
addMessage(XLAT("You cannot move there!"));
} }
else if(c2->wall == waChasm && c2->land == laDual)
addMessage(XLAT("You cannot move there!"));
else if(!c2->wall)
addMessage(XLAT("You cannot move there!"));
else { else {
addMessage(XLAT("You cannot move through %the1!", c2->wall)); if(vmsg(miWALL))
addMessage(XLAT("You cannot move through %the1!", c2->wall));
} }
} }
@ -927,14 +946,14 @@ bool pcmove::attack() {
if(!ca) { if(!ca) {
if(forcedmovetype == fmAttack) { if(forcedmovetype == fmAttack) {
if(monstersnear_add_pmi(movei(cwt.at, STAY))) { if(monstersnear_add_pmi(movei(cwt.at, STAY))) {
if(vmsg()) wouldkill("%The1 would get you!"); if(vmsg(miTHREAT)) wouldkill("%The1 would get you!");
return false; return false;
} }
nextmovetype = lmSkip; nextmovetype = lmSkip;
addMessage(XLAT("You swing your sword at %the1.", c2->monst)); addMessage(XLAT("You swing your sword at %the1.", c2->monst));
return swing(); return swing();
} }
if(vmsg()) tell_why_cannot_attack(); if(vmsg(miENTITY)) tell_why_cannot_attack();
return false; return false;
} }
@ -1008,7 +1027,7 @@ bool pcmove::attack() {
swordAttackStatic(); swordAttackStatic();
if(monstersnear_add_pmi(movei(cwt.at, STAY))) { if(monstersnear_add_pmi(movei(cwt.at, STAY))) {
if(vmsg()) wouldkill("You would be killed by %the1!"); if(vmsg(miTHREAT)) wouldkill("You would be killed by %the1!");
return false; return false;
} }
if(checkonly) return true; if(checkonly) return true;
@ -1142,7 +1161,7 @@ bool pcmove::perform_move_or_jump() {
if(mi.t->monst == moFriendlyIvy) changes.ccell(mi.t), mi.t->monst = moNone; if(mi.t->monst == moFriendlyIvy) changes.ccell(mi.t), mi.t->monst = moNone;
if(monstersnear_add_pmi(pmi)) { if(monstersnear_add_pmi(pmi)) {
if(vmsg()) wouldkill("%The1 would kill you there!"); if(vmsg(miTHREAT)) wouldkill("%The1 would kill you there!");
return false; return false;
} }
@ -1187,7 +1206,7 @@ bool pcmove::stay() {
items[itFatigue] = 0; items[itFatigue] = 0;
if(monstersnear_add_pmi(mi)) { if(monstersnear_add_pmi(mi)) {
if(vmsg()) wouldkill("%The1 would get you!"); if(vmsg(miTHREAT)) wouldkill("%The1 would get you!");
return false; return false;
} }
if(checkonly) return true; if(checkonly) return true;

View File

@ -28,12 +28,18 @@ EX string getgametime_s(int timespent IS(getgametime())) {
return buf; return buf;
} }
EX bool display_yasc_codes;
string timeline() { string timeline() {
return string s;
shmup::on ? if(shmup::on)
XLAT("%1 knives (%2)", its(turncount), getgametime_s()) s = XLAT("%1 knives (%2)", its(turncount), getgametime_s());
: else {
XLAT("%1 turns (%2)", its(turncount), getgametime_s()); s = XLAT("%1 turns (%2)", its(turncount), getgametime_s());
if(display_yasc_codes)
s+= " YASC code: " + its(yasc_code);
}
return s;
} }
EX void noaction() {} EX void noaction() {}