slime spill is now predictable when multiple colors hit the same cell at once

This commit is contained in:
Zeno Rogue 2022-04-26 15:43:33 +02:00
parent 7adb3dac5a
commit 920fc454f0
4 changed files with 45 additions and 7 deletions

View File

@ -226,6 +226,27 @@ EX void killIvy(cell *c, eMonster who) {
killIvy(c->move(i), who), kills[moIvyDead]++;
}
struct spillinfo {
eWall orig;
int spill_a, spill_b;
spillinfo() { spill_a = spill_b = 0; }
};
map<cell*, spillinfo> spillinfos;
EX void reset_spill() {
spillinfos.clear();
}
EX void record_spillinfo(cell *c, eWall t) {
if(!isAlchAny(t)) return;
auto& si = spillinfos[c];
if(si.spill_a == 0 && si.spill_b == 0) si.orig = c->wall;
if(si.spill_a == 0 && si.spill_b == 0) si.orig = c->wall;
if(t == waFloorA) si.spill_a++;
if(t == waFloorB) si.spill_b++;
}
EX void prespill(cell* c, eWall t, int rad, cell *from) {
if(againstWind(c, from)) return;
changes.ccell(c);
@ -280,8 +301,10 @@ EX void prespill(cell* c, eWall t, int rad, cell *from) {
c->wall == waCamelotMoat || c->wall == waSea || c->wall == waCTree ||
c->wall == waRubble || c->wall == waGargoyleFloor || c->wall == waGargoyle ||
c->wall == waRose || c->wall == waPetrified || c->wall == waPetrifiedBridge || c->wall == waRuinWall ||
among(c->wall, waDeepWater, waShallow))
among(c->wall, waDeepWater, waShallow)) {
record_spillinfo(c, t);
t = waTemporary;
}
if(c->wall == waSulphur) {
// remove the center as it would not look good
@ -296,6 +319,7 @@ EX void prespill(cell* c, eWall t, int rad, cell *from) {
destroyHalfvine(c);
if(c->wall == waTerraWarrior) kills[waTerraWarrior]++;
record_spillinfo(c, t);
c->wall = t;
// destroy items...
c->item = itNone;
@ -324,7 +348,18 @@ EX void spillfix(cell* c, eWall t, int rad) {
}
EX void spill(cell* c, eWall t, int rad) {
prespill(c,t,rad, c); spillfix(c,t,rad);
if(isAlchAny(c) && (spillinfos[c].spill_a || spillinfos[c].spill_b) && isAlchAny(spillinfos[c].orig))
t = spillinfos[c].orig;
prespill(c,t,rad, c);
spillfix(c,t,rad);
for(auto si: spillinfos) {
if(si.second.spill_a && si.second.spill_b)
si.first->wall =
si.second.spill_a > si.second.spill_b ? waFloorA :
si.second.spill_b > si.second.spill_a ? waFloorB :
isAlchAny(si.second.orig) ? si.second.orig :
waNone;
}
}
EX void degradeDemons() {

View File

@ -809,6 +809,7 @@ EX void findWormIvy(cell *c) {
}
EX void monstersTurn() {
reset_spill();
checkSwitch();
mirror::breakAll();
DEBB(DF_TURN, ("bfs"));

View File

@ -218,12 +218,12 @@ EX void reduceOrbPowers() {
items[itWarning] = 0;
}
eWall orig_wall;
EX void flashAlchemist(cell *c) {
if(isAlch(c)) {
if(isAlch(cwt.at))
c->wall = cwt.at->wall;
else
c->wall = eWall(c->wall ^ waFloorB ^ waFloorA);
if(isAlch(c) && isAlch(orig_wall)) {
record_spillinfo(c, orig_wall);
c->wall = orig_wall;
}
}
@ -292,6 +292,7 @@ EX void flashCell(cell *c, eMonster killer, flagtype flags) {
EX void activateFlashFrom(cell *cf, eMonster who, flagtype flags) {
drawFlash(cf);
orig_wall = cwt.at->wall;
playSound(cf, "storm");
for(int i=0; i<isize(dcal); i++) {
cell *c = dcal[i];

View File

@ -242,6 +242,7 @@ EX bool movepcto(int d, int subdir IS(1), bool checkonly IS(false)) {
}
bool pcmove::movepcto() {
reset_spill();
if(dual::state == 1) return dual::movepc(d, subdir, checkonly);
if(d >= 0 && !checkonly && subdir != 1 && subdir != -1) printf("subdir = %d\n", subdir);
mip.t = NULL;