Compare commits
14 Commits
b9608dcd4c
...
fbea2d91ce
Author | SHA1 | Date |
---|---|---|
Zeno Rogue | fbea2d91ce | |
Zeno Rogue | d4f449d994 | |
Zeno Rogue | 9807b1b3ba | |
Zeno Rogue | 4d761385ac | |
Zeno Rogue | 05b6cdea3e | |
Zeno Rogue | 10646933db | |
Zeno Rogue | 521b452436 | |
Zeno Rogue | 0323e4100e | |
Zeno Rogue | 0708c0e2bc | |
Zeno Rogue | b7db56812e | |
Zeno Rogue | 7fc90f116b | |
Zeno Rogue | 824fa9a732 | |
Zeno Rogue | 92603dddcc | |
Zeno Rogue | 32d329d81e |
|
@ -703,6 +703,9 @@ EX int coastval(cell *c, eLand base) {
|
||||||
if(!c->landparam) return UNKNOWN;
|
if(!c->landparam) return UNKNOWN;
|
||||||
return c->landparam & 255;
|
return c->landparam & 255;
|
||||||
}
|
}
|
||||||
|
else if(base == laWestWall) {
|
||||||
|
if(c->land != base) return 0;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if(c->land == laOceanWall || c->land == laCaribbean || c->land == laWhirlpool ||
|
if(c->land == laOceanWall || c->land == laCaribbean || c->land == laWhirlpool ||
|
||||||
c->land == laLivefjord || c->land == laWarpSea || c->land == laKraken || c->land == laDocks || c->land == laBrownian)
|
c->land == laLivefjord || c->land == laWarpSea || c->land == laKraken || c->land == laDocks || c->land == laBrownian)
|
||||||
|
|
|
@ -136,7 +136,7 @@ EX namespace bt {
|
||||||
h->emeraldval = gmod((parent->emeraldval - d1) * 7508, 15015);
|
h->emeraldval = gmod((parent->emeraldval - d1) * 7508, 15015);
|
||||||
break;
|
break;
|
||||||
case gTernary:
|
case gTernary:
|
||||||
if(d < 2)
|
if(d <= 2)
|
||||||
h->emeraldval = gmod(parent->emeraldval * 3 + d, 10010);
|
h->emeraldval = gmod(parent->emeraldval * 3 + d, 10010);
|
||||||
else
|
else
|
||||||
h->emeraldval = gmod((parent->emeraldval - d1) * 3337, 10010);
|
h->emeraldval = gmod((parent->emeraldval - d1) * 3337, 10010);
|
||||||
|
@ -854,14 +854,35 @@ auto bt_config = arg::add2("-btwidth", [] {arg::shift_arg_formula(vid.binary_wid
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EX bool pseudohept(cell *c) {
|
EX bool pseudohept(cell *c) {
|
||||||
if(WDIM == 2)
|
switch(geometry) {
|
||||||
return c->type & c->master->distance & 1;
|
case gBinary4:
|
||||||
else if(geometry == gHoroRec)
|
c->cmove(3);
|
||||||
return c->c.spin(S7-1) == 0 && (c->master->distance & 1) && c->cmove(S7-1)->c.spin(S7-1) == 0;
|
return (c->master->distance & 1) && (c->c.spin(3) == 0);
|
||||||
else if(geometry == gHoroTris)
|
|
||||||
return c->c.spin(S7-1) == 0 && (c->master->distance & 1);
|
case gBinaryTiling:
|
||||||
else
|
return c->master->distance & c->type & 1;
|
||||||
return (c->master->zebraval == 1) && (c->master->distance & 1);
|
|
||||||
|
case gTernary: {
|
||||||
|
return c->master->emeraldval & 1;
|
||||||
|
/* auto m = dynamic_cast<hrmap_binary*> (current_map());
|
||||||
|
auto o = m->origin;
|
||||||
|
int flips = 0;
|
||||||
|
while(m != o) {
|
||||||
|
if(m->master->distance >= o->master->distance) { if(m->c.spin(4) == 1) flips++; m = m->cmove(4); }
|
||||||
|
}
|
||||||
|
heptagon *origin;
|
||||||
|
c->cmove(4); return (c->c.spin(4) == 1); */
|
||||||
|
}
|
||||||
|
|
||||||
|
case gHoroRec:
|
||||||
|
return c->c.spin(S7-1) == 0 && (c->master->distance & 1) && c->cmove(S7-1)->c.spin(S7-1) == 0;
|
||||||
|
|
||||||
|
case gHoroTris:
|
||||||
|
return c->c.spin(S7-1) == 0 && (c->master->distance & 1);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (c->master->zebraval == 1) && (c->master->distance & 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EX pair<gp::loc, gp::loc> gpvalue(heptagon *h) {
|
EX pair<gp::loc, gp::loc> gpvalue(heptagon *h) {
|
||||||
|
|
|
@ -5203,3 +5203,16 @@ Bug fixes:
|
||||||
* in countHyperstones, two variants of Mirror are counted once
|
* in countHyperstones, two variants of Mirror are counted once
|
||||||
* specially generated lands (horocycles, Brown Islands) now respect Unlocked and LandIngame rules
|
* specially generated lands (horocycles, Brown Islands) now respect Unlocked and LandIngame rules
|
||||||
* fixed some more crashes related to SDL2 (e.g., right-click in shmup)
|
* fixed some more crashes related to SDL2 (e.g., right-click in shmup)
|
||||||
|
|
||||||
|
2024-04-09 02:46 Update 13.0g:
|
||||||
|
|
||||||
|
- New land structures: CR2-like, CR3-like, and "cursed"
|
||||||
|
- Space Rocks and Halloween stuff are now saved correctly (thanks to jlm)
|
||||||
|
- since the Aether users now see adjacent items in water, they can also pick them up
|
||||||
|
- fixed the bug where moving a boat with Compass would cause items to be picked up
|
||||||
|
- pushing an exploding barrel on a mine now causes an explosion
|
||||||
|
- fixed pressing numpad keys with numpad on acting both as moves and quick-keys
|
||||||
|
- a new pseudoheptagon pattern in standard binary and ternary tiling
|
||||||
|
- fixed the Free Fall being not inaccessible from some lands
|
||||||
|
- auto-pause shmup game when it loses focus
|
||||||
|
- fixed some possible crashes: with keys being generated on ivy, when using Orb of Space on Orb of Safety, Ocean in the chaos modes, after killing 400 mutants, when generating YASC message
|
||||||
|
|
|
@ -390,7 +390,7 @@ EX void create_yasc_message() {
|
||||||
if(captures.size() == 2 && context.size() == 1 && cwt.at->type == 6) {
|
if(captures.size() == 2 && context.size() == 1 && cwt.at->type == 6) {
|
||||||
vector<int> dirs;
|
vector<int> dirs;
|
||||||
forCellIdEx(c1, i, cwt.at) for(auto cap: captures) if(cap.first == c1) dirs.push_back(i);
|
forCellIdEx(c1, i, cwt.at) for(auto cap: captures) if(cap.first == c1) dirs.push_back(i);
|
||||||
if(abs(dirs[0]-dirs[1]) == 3) {
|
if(isize(dirs) == 2 && abs(dirs[0]-dirs[1]) == 3) {
|
||||||
auto c1 = captures.begin(); c1++;
|
auto c1 = captures.begin(); c1++;
|
||||||
yasc_message = XLAT("pinched by %the1 and %the2", captures.begin()->second, c1->second);
|
yasc_message = XLAT("pinched by %the1 and %the2", captures.begin()->second, c1->second);
|
||||||
}
|
}
|
||||||
|
|
|
@ -524,7 +524,7 @@ EX void handleKeyNormal(int sym, int uni) {
|
||||||
|
|
||||||
if(!(uni >= 'A' && uni <= 'Z') && DEFAULTCONTROL && !game_keys_scroll) {
|
if(!(uni >= 'A' && uni <= 'Z') && DEFAULTCONTROL && !game_keys_scroll) {
|
||||||
for(int i=0; i<8; i++)
|
for(int i=0; i<8; i++)
|
||||||
if(among(sym, keys_vi[i], keys_wasd[i], keys_numpad[i]))
|
if(among(sym, keys_vi[i], keys_wasd[i], (uni >= '0' && uni <= '9') ? -1 : keys_numpad[i]))
|
||||||
movepckeydir(i);
|
movepckeydir(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
game.cpp
2
game.cpp
|
@ -347,6 +347,8 @@ EX void pushThumper(const movei& mi) {
|
||||||
if(w == waThumperOn)
|
if(w == waThumperOn)
|
||||||
explode = 2;
|
explode = 2;
|
||||||
}
|
}
|
||||||
|
if(w == waExplosiveBarrel && cto->wall == waMineMine)
|
||||||
|
explode = 2;
|
||||||
destroyTrapsOn(cto);
|
destroyTrapsOn(cto);
|
||||||
if(cto->wall == waOpenPlate || cto->wall == waClosePlate) {
|
if(cto->wall == waOpenPlate || cto->wall == waClosePlate) {
|
||||||
toggleGates(cto, cto->wall);
|
toggleGates(cto, cto->wall);
|
||||||
|
|
4
hyper.h
4
hyper.h
|
@ -13,8 +13,8 @@
|
||||||
#define _HYPER_H_
|
#define _HYPER_H_
|
||||||
|
|
||||||
// version numbers
|
// version numbers
|
||||||
#define VER "13.0f"
|
#define VER "13.0g"
|
||||||
#define VERNUM_HEX 0xAA06
|
#define VERNUM_HEX 0xAA07
|
||||||
|
|
||||||
#include "sysconfig.h"
|
#include "sysconfig.h"
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ EX bool pickable_from_water(eItem it) {
|
||||||
|
|
||||||
EX bool cannotPickupItem(cell *c, bool telekinesis) {
|
EX bool cannotPickupItem(cell *c, bool telekinesis) {
|
||||||
if(pickable_from_water(c->item) && isWatery(c)) return false;
|
if(pickable_from_water(c->item) && isWatery(c)) return false;
|
||||||
return itemHidden(c) && !telekinesis && !(isWatery(c) && markOrb(itOrbFish));
|
return itemHidden(c) && !telekinesis && !(isWatery(c) && (markOrb(itOrbFish) || markOrb(itOrbAether)));
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool canPickupItemWithMagnetism(cell *c, cell *from) {
|
EX bool canPickupItemWithMagnetism(cell *c, cell *from) {
|
||||||
|
|
|
@ -2586,7 +2586,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
||||||
treasure_rate += variant::features[i].rate_change;
|
treasure_rate += variant::features[i].rate_change;
|
||||||
variant::features[i].build(c);
|
variant::features[i].build(c);
|
||||||
}
|
}
|
||||||
if(hrand(2000 - PT(kills[moVariantWarrior] * 5, 250)) < treasure_rate && !c->wall && !c->monst)
|
if(hrand(max(100, 2000 - PT(kills[moVariantWarrior] * 5, 250))) < treasure_rate && !c->wall && !c->monst)
|
||||||
c->item = itVarTreasure;
|
c->item = itVarTreasure;
|
||||||
}
|
}
|
||||||
if(d == 7 && c->wall == waTrapdoor) {
|
if(d == 7 && c->wall == waTrapdoor) {
|
||||||
|
|
|
@ -575,6 +575,7 @@ EX bool destroyHalfvine(cell *c, eWall newwall IS(waNone), int tval IS(6)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EX int coastvalEdge(cell *c) { return coastval(c, laIvoryTower); }
|
EX int coastvalEdge(cell *c) { return coastval(c, laIvoryTower); }
|
||||||
|
EX int coastvalWest(cell *c) { return coastval(c, laWestWall); }
|
||||||
|
|
||||||
EX int gravityLevel(cell *c) {
|
EX int gravityLevel(cell *c) {
|
||||||
if(c->land == laIvoryTower && ls::hv_structure())
|
if(c->land == laIvoryTower && ls::hv_structure())
|
||||||
|
@ -601,10 +602,10 @@ EX int gravityLevelDiff(cell *c, cell *d) {
|
||||||
if(shmup::on) return 0;
|
if(shmup::on) return 0;
|
||||||
|
|
||||||
int nid = neighborId(c, d);
|
int nid = neighborId(c, d);
|
||||||
int id1 = parent_id(c, 1, coastvalEdge) + 1;
|
int id1 = parent_id(c, 1, coastvalWest) + 1;
|
||||||
int di1 = angledist(c->type, id1, nid);
|
int di1 = angledist(c->type, id1, nid);
|
||||||
|
|
||||||
int id2 = parent_id(c, -1, coastvalEdge) - 1;
|
int id2 = parent_id(c, -1, coastvalWest) - 1;
|
||||||
int di2 = angledist(c->type, id2, nid);
|
int di2 = angledist(c->type, id2, nid);
|
||||||
|
|
||||||
if(di1 < di2) return 1;
|
if(di1 < di2) return 1;
|
||||||
|
@ -708,8 +709,8 @@ EX void checkTide(cell *c) {
|
||||||
if(!c2) continue;
|
if(!c2) continue;
|
||||||
if(c2->land == laBarrier || c2->land == laOceanWall) ;
|
if(c2->land == laBarrier || c2->land == laOceanWall) ;
|
||||||
else if(c2->land == laOcean)
|
else if(c2->land == laOcean)
|
||||||
seadist = min(seadist, c2->SEADIST ? c2->SEADIST+1 : 7),
|
seadist = min(seadist, c2->SEADIST >= 1 ? c2->SEADIST+1 : 7),
|
||||||
landdist = min(landdist, c2->LANDDIST ? c2->LANDDIST+1 : 7);
|
landdist = min(landdist, c2->LANDDIST >= 1 ? c2->LANDDIST+1 : 7);
|
||||||
else if(isSealand(c2->land)) seadist = 1;
|
else if(isSealand(c2->land)) seadist = 1;
|
||||||
else landdist = 1;
|
else landdist = 1;
|
||||||
}
|
}
|
||||||
|
@ -745,18 +746,27 @@ EX void checkTide(cell *c) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool makeEmpty(cell *c) {
|
EX bool makeNoMonster(cell *c) {
|
||||||
|
changes.ccell(c);
|
||||||
|
if(isAnyIvy(c->monst)) killMonster(c, moPlayer, 0);
|
||||||
|
else if(c->monst == moPair) {
|
||||||
|
changes.ccell(c->move(c->mondir));
|
||||||
|
if(c->move(c->mondir)->monst == moPair)
|
||||||
|
c->move(c->mondir)->monst = moNone;
|
||||||
|
}
|
||||||
|
else if(isWorm(c->monst)) {
|
||||||
|
if(!items[itOrbDomination]) return false;
|
||||||
|
}
|
||||||
|
else if(isMultitile(c->monst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else c->monst = moNone;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
EX bool makeEmpty(cell *c) {
|
||||||
if(c->monst != moPrincess) {
|
if(c->monst != moPrincess) {
|
||||||
if(isAnyIvy(c->monst)) killMonster(c, moPlayer, 0);
|
if(!makeNoMonster(c)) return false;
|
||||||
else if(c->monst == moPair) {
|
|
||||||
if(c->move(c->mondir)->monst == moPair)
|
|
||||||
c->move(c->mondir)->monst = moNone;
|
|
||||||
}
|
|
||||||
else if(isWorm(c->monst)) {
|
|
||||||
if(!items[itOrbDomination]) return false;
|
|
||||||
}
|
|
||||||
else c->monst = moNone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(c->land == laCanvas) ;
|
if(c->land == laCanvas) ;
|
||||||
|
|
3
orbs.cpp
3
orbs.cpp
|
@ -826,10 +826,11 @@ void telekinesis(cell *dest) {
|
||||||
|
|
||||||
moveItem(dest, cwt.at, true);
|
moveItem(dest, cwt.at, true);
|
||||||
eItem it = cwt.at->item;
|
eItem it = cwt.at->item;
|
||||||
|
bool saf = it == itOrbSafety;
|
||||||
collectItem(cwt.at, cwt.at, true);
|
collectItem(cwt.at, cwt.at, true);
|
||||||
if(cwt.at->item == it)
|
if(cwt.at->item == it)
|
||||||
animateMovement(match(dest, cwt.at), LAYER_BOAT);
|
animateMovement(match(dest, cwt.at), LAYER_BOAT);
|
||||||
else
|
else if(!saf)
|
||||||
animate_item_throw(dest, cwt.at, it);
|
animate_item_throw(dest, cwt.at, it);
|
||||||
|
|
||||||
useupOrb(itOrbSpace, cost.first);
|
useupOrb(itOrbSpace, cost.first);
|
||||||
|
|
|
@ -420,6 +420,8 @@ EX bool canPushStatueOn(cell *c, flagtype flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EX void moveBoat(const movei& mi) {
|
EX void moveBoat(const movei& mi) {
|
||||||
|
changes.ccell(mi.t);
|
||||||
|
changes.ccell(mi.s);
|
||||||
eWall x = mi.t->wall; mi.t->wall = mi.s->wall; mi.s->wall = x;
|
eWall x = mi.t->wall; mi.t->wall = mi.s->wall; mi.s->wall = x;
|
||||||
mi.t->mondir = mi.rev_dir_or(NODIR);
|
mi.t->mondir = mi.rev_dir_or(NODIR);
|
||||||
moveItem(mi.s, mi.t, false);
|
moveItem(mi.s, mi.t, false);
|
||||||
|
|
18
pcmove.cpp
18
pcmove.cpp
|
@ -214,6 +214,7 @@ struct pcmove {
|
||||||
bool fmsMove, fmsAttack, fmsActivate;
|
bool fmsMove, fmsAttack, fmsActivate;
|
||||||
int d;
|
int d;
|
||||||
int subdir;
|
int subdir;
|
||||||
|
/** used to tell perform_actual_move() that this is a boat move and thus we should not pick up items */
|
||||||
bool boatmove;
|
bool boatmove;
|
||||||
bool good_tortoise;
|
bool good_tortoise;
|
||||||
flagtype attackflags;
|
flagtype attackflags;
|
||||||
|
@ -844,13 +845,10 @@ bool pcmove::actual_move() {
|
||||||
return boat_move();
|
return boat_move();
|
||||||
|
|
||||||
if(!c2->monst && cwt.at->wall == waBoat && cwt.at->item != itOrbYendor && boatGoesThrough(c2) && markOrb(itOrbWater) && !nonAdjacentPlayer(c2, cwt.at) && fmsMove) {
|
if(!c2->monst && cwt.at->wall == waBoat && cwt.at->item != itOrbYendor && boatGoesThrough(c2) && markOrb(itOrbWater) && !nonAdjacentPlayer(c2, cwt.at) && fmsMove) {
|
||||||
|
if(c2->item && collectItem(c2, cwt.at)) return true;
|
||||||
if(c2->item && !cwt.at->item) moveItem(c2, cwt.at, false), boatmove = true;
|
|
||||||
placeWater(c2, cwt.at);
|
|
||||||
moveBoat(mi);
|
|
||||||
changes.ccell(c2);
|
changes.ccell(c2);
|
||||||
c2->mondir = revhint(cwt.at, d);
|
placeWater(c2, cwt.at);
|
||||||
if(c2->item) boatmove = !boatmove;
|
moveBoat(mi); boatmove = true;
|
||||||
return perform_actual_move();
|
return perform_actual_move();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1300,14 +1298,6 @@ bool pcmove::perform_actual_move() {
|
||||||
movecost(cwt.at, c2, 1);
|
movecost(cwt.at, c2, 1);
|
||||||
|
|
||||||
if(!boatmove && collectItem(c2, cwt.at)) return true;
|
if(!boatmove && collectItem(c2, cwt.at)) return true;
|
||||||
if(boatmove && c2->item && cwt.at->item) {
|
|
||||||
eItem it = c2->item;
|
|
||||||
c2->item = cwt.at->item;
|
|
||||||
if(collectItem(c2, cwt.at)) return true;
|
|
||||||
eItem it2 = c2->item;
|
|
||||||
c2->item = it;
|
|
||||||
cwt.at->item = it2;
|
|
||||||
}
|
|
||||||
if(doPickupItemsWithMagnetism(c2)) return true;
|
if(doPickupItemsWithMagnetism(c2)) return true;
|
||||||
|
|
||||||
if(isIcyLand(cwt.at) && cwt.at->wall == waNone && markOrb(itOrbWinter)) {
|
if(isIcyLand(cwt.at) && cwt.at->wall == waNone && markOrb(itOrbWinter)) {
|
||||||
|
|
|
@ -2590,7 +2590,7 @@ EX void turn(int delta) {
|
||||||
lmousetarget = mousetarget;
|
lmousetarget = mousetarget;
|
||||||
|
|
||||||
if(!shmup::on) return;
|
if(!shmup::on) return;
|
||||||
if(!(cmode & sm::NORMAL)) {
|
if(!(cmode & sm::NORMAL) || outoffocus) {
|
||||||
#if CAP_RACING
|
#if CAP_RACING
|
||||||
if(!in_pause) {
|
if(!in_pause) {
|
||||||
in_pause = true;
|
in_pause = true;
|
||||||
|
|
|
@ -278,10 +278,12 @@ EX namespace yendor {
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto rollbacks = std::move(changes.rollbacks);
|
||||||
for(int i=-1; i<key->type; i++) {
|
for(int i=-1; i<key->type; i++) {
|
||||||
cell *c2 = i >= 0 ? key->move(i) : key;
|
cell *c2 = i >= 0 ? key->move(i) : key;
|
||||||
checkTide(c2);
|
checkTide(c2);
|
||||||
c2->monst = moNone; c2->item = itNone;
|
makeNoMonster(c2);
|
||||||
|
c2->item = itNone;
|
||||||
if(!passable(c2, NULL, P_MIRROR | P_MONSTER)) {
|
if(!passable(c2, NULL, P_MIRROR | P_MONSTER)) {
|
||||||
if(c2->wall == waCavewall) c2->wall = waCavefloor;
|
if(c2->wall == waCavewall) c2->wall = waCavefloor;
|
||||||
else if(c2->wall == waDeadwall) c2->wall = waDeadfloor2;
|
else if(c2->wall == waDeadwall) c2->wall = waDeadfloor2;
|
||||||
|
@ -311,6 +313,7 @@ EX namespace yendor {
|
||||||
if(c2->land == laMirrorWall && i == -1)
|
if(c2->land == laMirrorWall && i == -1)
|
||||||
c2->wall = waNone;
|
c2->wall = waNone;
|
||||||
}
|
}
|
||||||
|
changes.rollbacks = std::move(rollbacks);
|
||||||
key->item = itKey;
|
key->item = itKey;
|
||||||
|
|
||||||
bool split_found = false;
|
bool split_found = false;
|
||||||
|
|
Loading…
Reference in New Issue