mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	Magnetic and Switch V1
This commit is contained in:
		
							
								
								
									
										12
									
								
								classes.cpp
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								classes.cpp
									
									
									
									
									
								
							| @@ -757,6 +757,10 @@ monstertype minf[motypes] = { | ||||
|     "are stunned for a longer time if you push them into lava, fire, or a solid obstacle."}, | ||||
|   { 'W', 0x202020, "Hunting Dog (regrouping)",  | ||||
|     "When your plan has clearly failed, it is better to abandon it and go to a safe place, to have a chance of succeeding next time. This dog clearly knows this."}, | ||||
|   { 'B', 0xC00000, "North Pole", NODESCYET},  | ||||
|   { 'B', 0x0000C0, "South Pole", NODESCYET},  | ||||
|   { '@', 0xC00000, "Switcher A", NODESCYET},  | ||||
|   { '@', 0x0000C0, "Switcher B", NODESCYET},  | ||||
|    | ||||
|   // shmup specials | ||||
|   { '@', 0xC0C0C0, "Rogue", "In the Shoot'em Up mode, you are armed with thrown Knives."}, | ||||
| @@ -1203,8 +1207,10 @@ itemtype iinf[ittypes] = { | ||||
|     "Does not affect multi-tile monsters."}, | ||||
|   { '!', 0x80FF00, "Glowing Crystal", crystaldesc}, | ||||
|   { '!', 0x80FF80, "Snake Oil", NODESCYET}, | ||||
|   { '*', 0x80FF80, "Dock Treasure", NODESCYET}, | ||||
|   { '*', 0x80FF80, "Sea Glass", NODESCYET}, | ||||
|   { '*', 0x80FF80, "Invix Treasure", NODESCYET}, | ||||
|   { '*', 0x80FF80, "Monopole", NODESCYET}, | ||||
|   { '*', 0xFFFF80, "Junk", NODESCYET}, | ||||
|   }; | ||||
|  | ||||
| // --- wall types --- | ||||
| @@ -1571,7 +1577,9 @@ const landtype linf[landtypes] = { | ||||
|   { 0x80FF00, "Crystal World", crystaldesc}, | ||||
|   { 0x306030, "Snake Nest", NODESCYET}, | ||||
|   { 0x80FF00, "Docks", NODESCYET}, | ||||
|   { 0x306030, "Invisible", NODESCYET}, | ||||
|   { 0x306030, "Invincible", NODESCYET}, | ||||
|   { 0x306030, "Magnetosphere", NODESCYET}, | ||||
|   { 0x306030, "Switch", NODESCYET}, | ||||
|   }; | ||||
|  | ||||
| struct landtacinfo { eLand l; int tries, multiplier; }; | ||||
|   | ||||
							
								
								
									
										13
									
								
								classes.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								classes.h
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| static const int motypes = 152; | ||||
| static const int motypes = 156; | ||||
|  | ||||
| struct monstertype { | ||||
|   char  glyph; | ||||
| @@ -52,6 +52,8 @@ enum eMonster { | ||||
|   moButterfly, moNarciss, moMirrorSpirit, | ||||
|   moHunterDog, moTerraWarrior, moJiangshi, moVoidBeast, moLavaWolf, moHunterGuard, | ||||
|   moIceGolem, moSandBird, moSalamander, moHunterChanging, | ||||
|   moNorthPole, moSouthPole, | ||||
|   moSwitch1, moSwitch2, | ||||
|   // shmup specials | ||||
|   moPlayer, moBullet, moFlailBullet, moFireball, moTongue, moAirball, | ||||
|   // temporary | ||||
| @@ -68,7 +70,7 @@ struct genderswitch_t { | ||||
|  | ||||
| #define NUM_GS 6 | ||||
|  | ||||
| static const int ittypes = 125; | ||||
| static const int ittypes = 127; | ||||
|  | ||||
| struct itemtype { | ||||
|   char  glyph; | ||||
| @@ -113,7 +115,7 @@ enum eItem { | ||||
|   itLavaLily, itHunting, itBlizzard, itTerra, | ||||
|   itOrbSide1, itOrbSide2, itOrbSide3, | ||||
|   itOrbLava, itOrbMorph, itGlowCrystal, itSnake, | ||||
|   itDock, itInvix | ||||
|   itDock, itInvix, itMagnet, itSwitch | ||||
|   }; | ||||
|  | ||||
| static const int walltypes = 107; | ||||
| @@ -160,7 +162,7 @@ enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCav | ||||
|   waDock, waBurningDock | ||||
|   }; | ||||
|  | ||||
| static const int landtypes = 81; | ||||
| static const int landtypes = 83; | ||||
|  | ||||
| struct landtype { | ||||
|   int color; | ||||
| @@ -186,7 +188,8 @@ enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle | ||||
|   laMirrorWall, laMirrored, laMirrorWall2, laMirrored2, | ||||
|   laMirrorOld, | ||||
|   laVolcano, laBlizzard, laHunting, laTerracotta, laMercuryRiver, | ||||
|   laDual, laSnakeNest, laDocks, laInvincible | ||||
|   laDual, laSnakeNest, laDocks, laInvincible, laMagnetic, | ||||
|   laSwitch | ||||
|   }; | ||||
|  | ||||
| enum eGeometry {gNormal, gEuclid, gSphere, gElliptic, gQuotient, gQuotient2, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gGUARD}; | ||||
|   | ||||
							
								
								
									
										16
									
								
								flags.cpp
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								flags.cpp
									
									
									
									
									
								
							| @@ -276,7 +276,7 @@ int itemclass(eItem i) { | ||||
|     i == itGreenGrass || i == itBull || | ||||
|     i == itLavaLily || i == itHunting || | ||||
|     i == itBlizzard || i == itTerra || i == itGlowCrystal || i == itSnake || | ||||
|     i == itDock || i == itInvix | ||||
|     i == itDock || i == itInvix || i == itSwitch | ||||
|     ) | ||||
|     return IC_TREASURE; | ||||
|   if(i == itSavedPrincess || i == itStrongWind || i == itWarning) | ||||
| @@ -385,7 +385,18 @@ bool normalMover(eMonster m) { | ||||
|     m == moHunterDog || m == moTerraWarrior || m == moJiangshi ||  | ||||
|     m == moLavaWolf || m == moSalamander || | ||||
|     m == moHunterGuard || m == moHunterChanging || | ||||
|     m == moIceGolem || slowMover(m); | ||||
|     m == moIceGolem ||  | ||||
|     m == moNorthPole || m == moSouthPole || | ||||
|     m == moSwitch1 || m == moSwitch2 || | ||||
|     slowMover(m); | ||||
|   } | ||||
|  | ||||
| bool isMagneticPole(eMonster m) { | ||||
|   return m == moNorthPole || m == moSouthPole; | ||||
|   } | ||||
|  | ||||
| bool isSwitch(eMonster m) { | ||||
|   return m == moSwitch1 || m == moSwitch2; | ||||
|   } | ||||
|  | ||||
| // from-to | ||||
| @@ -494,6 +505,7 @@ bool isInactiveEnemy(cell *w, eMonster forwho) { | ||||
| bool isActiveEnemy(cell *w, eMonster forwho) { | ||||
|   if(((forwho == moPlayer) ? realstuntime(w) : realstuntime(w) > 1)) | ||||
|     return false; | ||||
|   if(w->monst == passive_switch) return false; | ||||
|   if(w->monst == moNone) return false; | ||||
|   if(isFriendly(w)) return false; | ||||
|   if(isInactiveEnemy(w, forwho)) return false; | ||||
|   | ||||
							
								
								
									
										37
									
								
								game.cpp
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								game.cpp
									
									
									
									
									
								
							| @@ -728,12 +728,28 @@ void moveBoatIfUsingOne(cell *to, cell *from) { | ||||
|     } | ||||
|   } | ||||
|  | ||||
| bool againstMagnet(cell *c1, cell *c2) { // (from, to) | ||||
|   if(!isMagneticPole(c1->monst)) | ||||
|     return false; | ||||
|   forCellEx(c3, c2)  | ||||
|     if(c3 != c1 && c3->monst == c1->monst) | ||||
|       return true; | ||||
|   forCellEx(c3, c1)  | ||||
|     if(c3->monst != c1->monst && isMagneticPole(c3->monst)) | ||||
|       if(!isNeighbor(c3, c2)) | ||||
|         return true; | ||||
|   return false; | ||||
|   } | ||||
|  | ||||
| bool passable_for(eMonster m, cell *w, cell *from, flagtype extra) { | ||||
|   if(w->monst && !(extra & P_MONSTER) && !isPlayerOn(w))  | ||||
|     return false; | ||||
|   if(m == moWolf) { | ||||
|     return (isIcyLand(w) || w->land == laVolcano) && (isPlayerOn(w) || passable(w, from, extra)); | ||||
|     } | ||||
|   if(isMagneticPole(m) && w && from && againstMagnet(from, w)) | ||||
|     return false; | ||||
|   if(m == passive_switch) return false; | ||||
|   if(normalMover(m) || isBug(m) || isDemon(m) || m == moHerdBull) { | ||||
|     if((isWitch(m) || m == moEvilGolem) && w->land != laPower && w->land != laHalloween) | ||||
|       return false; | ||||
| @@ -866,6 +882,8 @@ bool canAttack(cell *c1, eMonster m1, cell *c2, eMonster m2, flagtype flags) { | ||||
|   // cannot eat worms | ||||
|   if((flags & AF_EAT) && isWorm(m2)) return false; | ||||
|    | ||||
|   if(m1 == passive_switch || m2 == passive_switch) return false; | ||||
|    | ||||
|   if((flags & AF_GETPLAYER) && isPlayerOn(c2)) m2 = moPlayer; | ||||
|    | ||||
|   if(!m2) return false; | ||||
| @@ -1096,12 +1114,20 @@ bool krakensafe(cell *c) { | ||||
|     (c->item == itOrbAether && c->wall == waBoat); | ||||
|   } | ||||
|  | ||||
| eMonster active_switch() { | ||||
|   return eMonster(passive_switch ^ moSwitch1 ^ moSwitch2); | ||||
|   } | ||||
|    | ||||
| int monstersnear(stalemate1& sm) { | ||||
|  | ||||
|   cell *c = sm.moveto; | ||||
|   bool eaten = false; | ||||
|  | ||||
|   if(hardcore && sm.who == moPlayer) return 0; | ||||
|   dynamicval<eMonster> sw(passive_switch, passive_switch); | ||||
|   if(sm.moveto->item && itemclass(sm.moveto->item) == IC_TREASURE) | ||||
|     passive_switch = active_switch(); | ||||
|  | ||||
|   int res = 0; | ||||
|   bool fast = false; | ||||
|  | ||||
| @@ -3232,6 +3258,14 @@ void moveMonster(cell *ct, cell *cf) { | ||||
|   ct->hitpoints = cf->hitpoints; | ||||
|   ct->stuntime = cf->stuntime; | ||||
|    | ||||
|   if(isMagneticPole(m)) { | ||||
|     cell *other_pole = cf->mov[cf->mondir]; | ||||
|     if(other_pole) { | ||||
|       ct->mondir = neighborId(ct, other_pole), | ||||
|       other_pole->mondir = neighborId(other_pole, ct); | ||||
|       } | ||||
|     } | ||||
|    | ||||
|   if(fri || isBug(m) || items[itOrbDiscord]) stabbingAttack(cf, ct, m); | ||||
|  | ||||
|   if(isLeader(m)) { | ||||
| @@ -6787,7 +6821,10 @@ void terracotta() { | ||||
|       } | ||||
|   } | ||||
|  | ||||
| eMonster passive_switch; | ||||
|  | ||||
| void monstersTurn() { | ||||
|   passive_switch = (gold() & 1) ? moSwitch1 : moSwitch2; | ||||
|   mirror::breakAll(); | ||||
|   DEBT("bfs"); | ||||
|   bfs(); | ||||
|   | ||||
							
								
								
									
										18
									
								
								graph.cpp
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								graph.cpp
									
									
									
									
									
								
							| @@ -1212,6 +1212,13 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou | ||||
|     if(!peace::on) queuepoly(VBODY, shPSword, 0xFFFF00FF); | ||||
|     queuepoly(VHEAD, shHood, 0xD0D000C0); | ||||
|     } | ||||
|   else if(isSwitch(m)) { | ||||
|     otherbodyparts(V, darkena(col, 0, 0xC0), m, footphase); | ||||
|     ShadowV(V, shPBody); | ||||
|     queuepoly(VBODY, shPBody, darkena(col, 0, 0xC0)); | ||||
|     if(!peace::on) queuepoly(VBODY, shPSword, 0xFFFF00FF); | ||||
|     queuepoly(VHEAD, shHood, darkena(col, 0, 0xFF)); | ||||
|     } | ||||
|   else if(m == moPalace || m == moFatGuard || m == moVizier || m == moSkeleton) { | ||||
|     queuepoly(VBODY, shSabre, 0xFFFFFFFF); | ||||
|     if(m == moSkeleton) { | ||||
| @@ -1537,6 +1544,11 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, int col, dou | ||||
|     if(xch == 'D') acol = 0xD0D0D0; | ||||
|     queuepoly(VHEAD, shDemon, darkena(acol, 0, 0xFF)); | ||||
|     } | ||||
|   else if(isMagneticPole(m)) { | ||||
|     if(m == moNorthPole) | ||||
|       queuepolyat(VBODY * spin(M_PI), shTentacle, 0x000000C0, PPR_TENTACLE1); | ||||
|     queuepolyat(VBODY, shDisk, darkena(col, 0, 0xFF), PPR_MONSTER_BODY); | ||||
|     } | ||||
|   else if(isMetalBeast(m)) { | ||||
|     ShadowV(V, shTrylobite); | ||||
|     if(!mmspatial) | ||||
| @@ -1916,7 +1928,8 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) { | ||||
|   // golems, knights, and hyperbugs don't face the player (mondir-controlled) | ||||
|   // also whatever in the lineview mode | ||||
|  | ||||
|   else if(isFriendly(c) || isBug(c) || (c->monst && conformal::on) || c->monst == moKrakenH || (isBull(c->monst) && c->mondir != NODIR) || c->monst == moButterfly) { | ||||
|   else if(isFriendly(c) || isBug(c) || (c->monst && conformal::on) || c->monst == moKrakenH || (isBull(c->monst) && c->mondir != NODIR) || c->monst == moButterfly || isMagneticPole(c->monst) || | ||||
|     isSwitch(c->monst)) { | ||||
|     if(c->monst == moKrakenH) Vs = Vb, nospins = nospinb; | ||||
|     if(!nospins) Vs = Vs * ddspin(c, c->mondir, S42); | ||||
|     if(isFriendly(c)) drawPlayerEffects(Vs, c, false); | ||||
| @@ -2573,6 +2586,9 @@ void setcolors(cell *c, int& wcol, int &fcol) { | ||||
|       if(c->bardir == NOBARRIERS && c->barleft)  | ||||
|         fcol = minf[moBug0+c->barright].color; | ||||
|       break; | ||||
|     case laSwitch: | ||||
|       fcol = minf[passive_switch].color; | ||||
|       break; | ||||
|     case laTortoise: | ||||
|       fcol = tortoise::getMatchColor(getBits(c)); | ||||
|       if(c->wall == waBigTree) wcol = 0x709000; | ||||
|   | ||||
							
								
								
									
										3
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -2425,3 +2425,6 @@ extern bool need_mouseh; | ||||
| extern int whateveri, whateveri2; | ||||
|  | ||||
| void clear_euland(eLand first); | ||||
|  | ||||
| extern eMonster passive_switch; | ||||
|  | ||||
|   | ||||
							
								
								
									
										26
									
								
								landgen.cpp
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								landgen.cpp
									
									
									
									
									
								
							| @@ -651,6 +651,15 @@ void giantLandSwitch(cell *c, int d, cell *from) { | ||||
|         }       | ||||
|       break; | ||||
|      | ||||
|     case laSwitch: | ||||
|       ONEMPTY { | ||||
|         if(hrand(5000) < PT(100 + 2 * (kills[moSwitch1] + kills[moSwitch2]), 200) && notDippingFor(itSwitch)) | ||||
|           c->item = itSwitch; | ||||
|         if(hrand(8000) < 40 + 5 * (items[itSwitch] + yendor::hardness())) | ||||
|           c->monst = hrand(2) ? moSwitch1 : moSwitch2; | ||||
|         }       | ||||
|       break; | ||||
|      | ||||
|     case laDragon: | ||||
|       if(d == 9) { | ||||
|         int cd = getCdata(c, 3); | ||||
| @@ -1876,6 +1885,23 @@ void giantLandSwitch(cell *c, int d, cell *from) { | ||||
|          } | ||||
|        break; | ||||
|      | ||||
|     case laMagnetic: | ||||
|       if(d == 8) { | ||||
|         if(hrand(10000) < 30 && !c->monst && !c->wall) { | ||||
|           cell *c1 = c; | ||||
|           cell *c2 = createMov(c1, hrand(c1->type)); | ||||
|           if(c2->monst || c2->wall) return; | ||||
|           if(hrand(2)) swap(c1, c2); | ||||
|           forCellEx(c3, c1) if(c3->monst == moNorthPole) return; | ||||
|           forCellEx(c3, c2) if(c3->monst == moSouthPole) return; | ||||
|           c1->monst = moNorthPole; | ||||
|           c2->monst = moSouthPole; | ||||
|           c1->mondir = neighborId(c1, c2); | ||||
|           c2->mondir = neighborId(c2, c1); | ||||
|           } | ||||
|         } | ||||
|       break; | ||||
|      | ||||
|     case laDocks: { | ||||
|       if(d == 8) { | ||||
|         patterns::patterninfo si; | ||||
|   | ||||
| @@ -208,6 +208,9 @@ int isNative(eLand l, eMonster m) { | ||||
|  | ||||
|     case laDocks: | ||||
|       return among(m, moRatling, moPirate, moCShark, moAlbatross, moFireFairy) ? 2 : 0; | ||||
|      | ||||
|     case laSwitch: | ||||
|       return m == moSwitch1 || m == moSwitch2 ? 2 : 0; | ||||
|     } | ||||
|   return false; | ||||
|   } | ||||
| @@ -303,6 +306,7 @@ eItem treasureType(eLand l) { | ||||
|     case laSnakeNest: return itSnake; | ||||
|     case laDocks: return itDock; | ||||
|     case laInvincible: return itInvix; | ||||
|     case laSwitch: return itSwitch; | ||||
|      | ||||
|     case laCA: return itNone; | ||||
|     } | ||||
| @@ -535,6 +539,9 @@ bool landUnlocked(eLand l) { | ||||
|     case laDual: | ||||
|     case laSnakeNest: | ||||
|       return gold() >= R90; | ||||
|        | ||||
|     case laSwitch: | ||||
|       return gold() >= R90; | ||||
|     } | ||||
|   return false; | ||||
|   } | ||||
| @@ -951,7 +958,7 @@ vector<eLand> land_over = { | ||||
|   laHell, laCrossroads3, laCocytus, laPower, laCrossroads4, | ||||
|   laCrossroads5, | ||||
|   // EXTRA | ||||
|   laWildWest, laHalloween, laDual, laSnakeNest, laDocks, laInvincible, laCA | ||||
|   laWildWest, laHalloween, laDual, laSnakeNest, laDocks, laInvincible, laSwitch, laMagnetic, laCA | ||||
|   }; | ||||
|  | ||||
| vector<eLand> landlist; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue