diff --git a/classes.cpp b/classes.cpp index 7b07cfd4..f27e52c7 100644 --- a/classes.cpp +++ b/classes.cpp @@ -381,7 +381,7 @@ const char *mirroreddesc = "Mirror walls reflect Mimics, lightning bolts, and " "missiles perfectly."; -const int motypes = 151; +const int motypes = 152; struct monstertype { char glyph; @@ -756,6 +756,7 @@ monstertype minf[motypes] = { "Salamanders are tough lizard-like creatures. Their tough skin protects them " "from both physical attacks and heat. Salamanders " "are stunned for a longer time if you push them into lava, fire, or a solid obstacle."}, + { 'W', 0x202020, "Hunting Dog (preparing ambush)", huntingdesc}, // shmup specials { '@', 0xC0C0C0, "Rogue", "In the Shoot'em Up mode, you are armed with thrown Knives."}, @@ -818,7 +819,7 @@ enum eMonster { moHerdBull, moRagingBull, moSleepBull, moButterfly, moNarciss, moMirrorSpirit, moHunterDog, moTerraWarrior, moJiangshi, moVoidBeast, moLavaWolf, moHunterGuard, - moIceGolem, moSandBird, moSalamander, + moIceGolem, moSandBird, moSalamander, moHunterChanging, // shmup specials moPlayer, moBullet, moFlailBullet, moFireball, moTongue, moAirball, // temporary diff --git a/flags.cpp b/flags.cpp index bad0cba4..71db9525 100644 --- a/flags.cpp +++ b/flags.cpp @@ -382,7 +382,7 @@ bool normalMover(eMonster m) { m == moNarciss || m == moMirrorSpirit || m == moHunterDog || m == moTerraWarrior || m == moJiangshi || m == moLavaWolf || m == moSalamander || - m == moHunterGuard || + m == moHunterGuard || m == moHunterChanging || m == moIceGolem || slowMover(m); } diff --git a/game.cpp b/game.cpp index 99b9c53d..4b5e3086 100644 --- a/game.cpp +++ b/game.cpp @@ -1818,6 +1818,7 @@ void killMonster(cell *c, eMonster who, flagtype deathflags) { if(m == moTentacleGhost) m = moGhost; if(!isBulletType(m)) kills[m]++; if(m == moHunterGuard) m = moHunterDog; + if(m == moHunterChanging) m = moHunterDog; if(!c->item) if(m == moButterfly && (deathflags & AF_BULL)) c->item = itBull; @@ -3199,6 +3200,7 @@ void moveMonster(cell *ct, cell *cf) { else { ct->monst = m; if(m == moWolf) ct->monst = moWolfMoved; + if(m == moHunterChanging) ct->stuntime = 1; if(ct->monst != moTentacleGhost) ct->mondir = neighborId(ct, cf); } @@ -3516,6 +3518,9 @@ int moveval(cell *c1, cell *c2, int d, int mf) { if(m == moRagingBull && c1->mondir != NODIR) return 1500 - bulldist(c2); + // actually they just run away + if(m == moHunterChanging && c2->pathdist > c1->pathdist) return 1600; + if(hunt && (mf & MF_PATHDIST) && c2->pathdist < c1->pathdist && !peace::on) return 1500; // good move // prefer straight direction when wandering @@ -5008,6 +5013,9 @@ void specialMoves() { eMonster m = c->monst; + if(m == moHunterGuard && items[itHunting] >= 10) + c->monst = moHunterChanging; + if(m == moSleepBull && !peace::on) { bool wakeup = false; forCellEx(c2, c) if(c2->monst == moGadfly) { @@ -6015,10 +6023,7 @@ int ambushSize(cell *c, eItem what) { return ambushval; switch(what) { case itHunting: - if(qty <= 16) - return qty; - else - return max(33-qty, 6); + return min(min(qty, max(33-qty, 6)), 15); case itOrbSide3: return restricted ? 10 : 20; diff --git a/graph.cpp b/graph.cpp index df05f9da..cce4c530 100644 --- a/graph.cpp +++ b/graph.cpp @@ -1045,7 +1045,7 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou } queuepoly(VABODY, shBugArmor, darkena(col, 1, 0xFF)); } - else if(m == moRunDog || m == moHunterDog || m == moHunterGuard) { + else if(m == moRunDog || m == moHunterDog || m == moHunterGuard || m == moHunterChanging) { if(!mmspatial && !footphase) queuepoly(VABODY, shDogBody, darkena(col, 0, 0xFF)); else { @@ -1062,6 +1062,7 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou bool redeyes = false; if(m == moHunterDog) eyecolor = 0xFF0000, redeyes = true; if(m == moHunterGuard) eyecolor = 0xFF6000, redeyes = true; + if(m == moHunterChanging) eyecolor = 0xFFFF00, redeyes = true; int eyes = darkena(eyecolor, 0, 0xFF); if(redeyes) poly_outline = eyes, minwidth_global = 1; @@ -1864,6 +1865,8 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) { hyperpoint V1 = spintox(V0) * V0; Vs = cwtV * rspintox(V0) * rpushxto0(V1) * pispin; + if(c->monst == moHunterChanging) + Vs = Vs * spin(M_PI); } if(c->monst == moShadow) diff --git a/landgen.cpp b/landgen.cpp index 0cddf6bc..5e047c66 100644 --- a/landgen.cpp +++ b/landgen.cpp @@ -1511,14 +1511,54 @@ void giantLandSwitch(cell *c, int d, cell *from) { if(hrand(1000) < 20) { if(openplains(c)) { if(hrand(2) == 0) { - c->item = itHunting; - vector next; - forCellEx(c2, c) if(c2->mpdist > 7) next.push_back(c2); - if(size(next) && items[itHunting] < 10) { - cell *c3 = next[hrand(size(next))]; - forCellEx(c4, c3) if(c4->mpdist > 7 && !isNeighbor(c4, c)) - c4->monst = moHunterGuard; + if(!items[itHunting]) { + vector> next; + int bonus = c->type - 4; + for(int i=0; itype; i++) { + cellwalker cw0(c, i); + cwstep(cw0); cwrevstep(cw0); + cellwalker cw1(c, i+bonus); + cwspin(cw1, 0); cwstep(cw1); cwrevstep(cw1); + if(cw0.c->mpdist > 7) + if(cw1.c->mpdist > 7) + next.emplace_back(cw0.c, cw1.c); + } + if(size(next)) { + c->item = itHunting; + auto& p = next[hrand(size(next))]; + p.first->monst = moHunterGuard; + p.second->monst = moHunterGuard; + } } + else if(items[itHunting] < 10) { + vector next; + forCellEx(c2, c) if(c2->mpdist > 7 && c2->type == 6) next.push_back(c2); + if(size(next)) { + c->item = itHunting; + cell *c3 = next[hrand(size(next))]; + vector dogcells; + forCellEx(c4, c3) if(c4->mpdist > 7 && !isNeighbor(c4, c)) + dogcells.push_back(c4); + if(items[itHunting] < 10 && size(dogcells) >= 2) { + while(true) { + cell *dog1 = dogcells[hrand(size(dogcells))]; + cell *dog2 = dogcells[hrand(size(dogcells))]; + if(isNeighbor(dog1, dog2)) { + dog1->monst = moHunterGuard; + dog1->landparam = 0; + dog2->monst = moHunterGuard; + dog2->landparam = 1; + break; + } + } + } + else if(size(dogcells)) { + c->item = itHunting; + dogcells[hrand(size(dogcells))]->monst = moHunterGuard; + } + } + } + else c->item = itHunting; } else placeLocalSpecial(c, 10); }