mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-30 21:42:59 +00:00 
			
		
		
		
	Terracotta now works in shmup
This commit is contained in:
		| @@ -202,10 +202,10 @@ void drawArrowTraps() { | ||||
|      | ||||
|     try { | ||||
|       transmatrix& t0 = gmatrix.at(r[0]); | ||||
|       transmatrix& t1 = gmatrix.at(r[1]); | ||||
|       transmatrix& t1 = gmatrix.at(r[4]); | ||||
|  | ||||
|       queueline(tC0(t0), tC0(t1), 0xFF0000FF, 4, PPR_ITEM); | ||||
|       if((c->wparam & 7) == 3) { | ||||
|       if((c->wparam & 7) == 3 && !shmup::on) { | ||||
| //        queueline(t0 * randomPointIn(r[0]->type), t1 * randomPointIn(r[1]->type), 0xFFFFFFFF, 4, PPR_ITEM); | ||||
|         int tt = ticks % 401; | ||||
|          | ||||
| @@ -222,3 +222,8 @@ void drawArrowTraps() { | ||||
|     } | ||||
|   } | ||||
|  | ||||
| auto ccm_blizzard = addHook(clearmemory, 0, [] () { | ||||
|   arrowtraps.clear(); | ||||
|   blizzardcells.clear(); | ||||
|   bcells.clear(); | ||||
|   }); | ||||
|   | ||||
| @@ -2008,7 +2008,7 @@ namespace heat { | ||||
|           } | ||||
|         } | ||||
|        | ||||
|       if(c->wall == waArrowTrap && c->wparam) { | ||||
|       if(c->wall == waArrowTrap && c->wparam && !shmup::on) { | ||||
|         c->wparam++; | ||||
|         if(c->wparam == 3) { | ||||
|           if(canAttack(c, moArrowTrap, c, c->monst, AF_GETPLAYER)) | ||||
|   | ||||
| @@ -183,8 +183,8 @@ bool isAnyIvy(eMonster m) { | ||||
|  | ||||
| bool isBulletType(eMonster m) {  | ||||
|   return  | ||||
|     m == moBullet || m == moFlailBullet ||  | ||||
|     m == moFireball || m == moTongue || m == moAirball;  | ||||
|     m == moBullet || m == moFlailBullet || m == moFireball ||  | ||||
|     m == moTongue || m == moAirball || m == moArrowTrap;  | ||||
|   } | ||||
|  | ||||
| bool isMutantIvy(cell *c) { return isMutantIvy(c->monst); } | ||||
|   | ||||
							
								
								
									
										51
									
								
								game.cpp
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								game.cpp
									
									
									
									
									
								
							| @@ -2983,26 +2983,29 @@ bool isCentralTrap(cell *c) { | ||||
|   return i == 2; | ||||
|   } | ||||
|  | ||||
| array<cell*, 2> traplimits(cell *c) { | ||||
|   array<cell*, 2> res; | ||||
| array<cell*, 5> traplimits(cell *c) { | ||||
|   array<cell*, 5> res; | ||||
|   int q = 0; | ||||
|   res[2] = c; | ||||
|   for(int d=0; d<c->type; d++) { | ||||
|     cellwalker cw(c, d); | ||||
|     cwstep(cw); | ||||
|     if(cw.c->wall != waArrowTrap) continue; | ||||
|     res[1+q*2] = cw.c; | ||||
|     cwspin(cw, cw.c->type/2); | ||||
|     if((cw.c->type&1) && cwpeek(cw, 0)->wall != waStone) cwspin(cw, 1); | ||||
|     cwstep(cw); | ||||
|     res[q++] = cw.c; | ||||
|     res[(q++)*4] = cw.c; | ||||
|     } | ||||
|   while(q<2) res[q++] = NULL; | ||||
|   while(q<2) { res[q*4] = res[1+q*2] = NULL; q++; } | ||||
|   return res; | ||||
|   } | ||||
|  | ||||
| void activateArrowTrap(cell *c) { | ||||
|   if(c->wall == waArrowTrap && c->wparam == 0) { | ||||
|     c->wparam = 1; | ||||
|     c->wparam = shmup::on ? 2 : 1; | ||||
|     forCellEx(c2, c) activateArrowTrap(c2); | ||||
|     if(shmup::on) shmup::activateArrow(c); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -3093,7 +3096,7 @@ void playerMoveEffects(cell *c1, cell *c2) { | ||||
|   if((c2->wall == waClosePlate || c2->wall == waOpenPlate) && !markOrb(itOrbAether)) | ||||
|     toggleGates(c2, c2->wall); | ||||
|  | ||||
|   if(c2->wall == waArrowTrap && !markOrb(itOrbAether)) | ||||
|   if(c2->wall == waArrowTrap && c2->wparam == 0 && !markOrb(itOrbAether)) | ||||
|     activateArrowTrap(c2); | ||||
|      | ||||
|   princess::playernear(c2); | ||||
| @@ -6620,26 +6623,36 @@ namespace orbbull { | ||||
| // predictable or not | ||||
| static constexpr bool randterra = false; | ||||
|  | ||||
| void terracotta() { | ||||
|   for(int i=0; i<numplayers(); i++) | ||||
|     forCellEx(c2, playerpos(i)) | ||||
|       if(c2->wall == waTerraWarrior) { | ||||
| void terracotta(cell *c) { | ||||
|   if(c->wall == waTerraWarrior) { | ||||
|     bool live = false; | ||||
|     if(randterra) { | ||||
|           c2->landparam++; | ||||
|           if((c2->landparam == 3 && hrand(3) == 0) || | ||||
|             (c2->landparam == 4 && hrand(2) == 0) ||  | ||||
|             c2->landparam == 5) | ||||
|       c->landparam++; | ||||
|       if((c->landparam == 3 && hrand(3) == 0) || | ||||
|         (c->landparam == 4 && hrand(2) == 0) ||  | ||||
|         c->landparam == 5) | ||||
|           live = true; | ||||
|       } | ||||
|     else { | ||||
|           c2->landparam--; | ||||
|           live = !c2->landparam; | ||||
|       c->landparam--; | ||||
|       live = !c->landparam; | ||||
|       } | ||||
|     if(live) | ||||
|           c2->monst = moTerraWarrior, | ||||
|           c2->hitpoints = 7, | ||||
|           c2->wall = waNone; | ||||
|       c->monst = moTerraWarrior, | ||||
|       c->hitpoints = 7, | ||||
|       c->wall = waNone; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| void terracotta() { | ||||
|   for(int i=0; i<numplayers(); i++) | ||||
|     forCellEx(c, playerpos(i)) { | ||||
|       if(shmup::on) { | ||||
|         forCellEx(c2, c) | ||||
|           terracotta(c2); | ||||
|         } | ||||
|       else | ||||
|         terracotta(c); | ||||
|       } | ||||
|   } | ||||
|  | ||||
|   | ||||
							
								
								
									
										1
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -233,6 +233,7 @@ namespace shmup { | ||||
|   void virtualRebase(shmup::monster *m, bool tohex); | ||||
|   void fixStorage(); | ||||
|   void addShmupHelp(string& out); | ||||
|   void activateArrow(cell *c); | ||||
|   } | ||||
|  | ||||
| // graph | ||||
|   | ||||
							
								
								
									
										73
									
								
								shmup.cpp
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								shmup.cpp
									
									
									
									
									
								
							| @@ -1444,6 +1444,48 @@ bool hornKills(eMonster m) { | ||||
|     m != moSalamander && m != moTerraWarrior; | ||||
|   } | ||||
|  | ||||
| queue<pair<int, cell*>> traplist; | ||||
|  | ||||
| void activateArrow(cell *c) { | ||||
|   if(isCentralTrap(c)) | ||||
|     traplist.emplace(ticks + 500, c); | ||||
|   } | ||||
|  | ||||
| monster arrowtrap_fakeparent; | ||||
|  | ||||
| void doTraps() { | ||||
|   while(true) {  | ||||
|     if(traplist.empty()) return; | ||||
|     auto t = traplist.front(); | ||||
|     if(t.first > ticks) return; | ||||
|     int d = t.second->wparam; | ||||
|     if(d == 2) { | ||||
|       auto tl = traplimits(t.second); | ||||
|       for(int i=1; i<4; i++) if(tl[i]) tl[i]->wparam = 3; | ||||
|       traplist.emplace(t.first + 500, t.second); | ||||
|        | ||||
|       for(int i=0; i<5; i += 4) try { | ||||
|         transmatrix& tu = gmatrix.at(tl[i]); | ||||
|         transmatrix& tv = gmatrix.at(tl[4-i]); | ||||
|         monster* bullet = new monster; | ||||
|         bullet->base = tl[i]; | ||||
|         bullet->at = rspintox(inverse(tu) * tC0(tv)); | ||||
|         bullet->type = moArrowTrap; | ||||
|         bullet->parent = &arrowtrap_fakeparent; | ||||
|         bullet->pid = 0; | ||||
|         bullet->parenttype = moArrowTrap; | ||||
|         additional.push_back(bullet); | ||||
|         } | ||||
|       catch(out_of_range) {} | ||||
|       } | ||||
|     else if(d == 3) { | ||||
|       auto tl = traplimits(t.second); | ||||
|       for(int i=1; i<4; i++) if(tl[i]) tl[i]->wparam = 0; | ||||
|       } | ||||
|     traplist.pop(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| bool hornStuns(eMonster m) { | ||||
|   return !isBulletType(m) && m != moRoseBeauty; | ||||
|   } | ||||
| @@ -1757,6 +1799,9 @@ void movePlayer(monster *m, int delta) { | ||||
|       if(c2->wall == waClosePlate || c2->wall == waOpenPlate) | ||||
|         toggleGates(c2, c2->wall); | ||||
|  | ||||
|       if(c2->wall == waArrowTrap && c2->wparam == 0 && !markOrb(itOrbAether)) | ||||
|        activateArrowTrap(c2); | ||||
|    | ||||
|       if(c2->item == itOrbYendor && !peace::on) yendor::check(c2); | ||||
|       collectItem(c2); | ||||
|       } | ||||
| @@ -2106,6 +2151,8 @@ void moveBullet(monster *m, int delta) { | ||||
|     m->vel = 1/500.; | ||||
|   else if(m->type == moAirball) | ||||
|     m->vel = 1/200.; | ||||
|   else if(m->type == moArrowTrap) | ||||
|     m->vel = 1/200.; | ||||
|   else if(m->type == moTongue) { | ||||
|     m->vel = 1/1500.; | ||||
|     if(m->isVirtual || !m->parent || intval(nat*C0, m->parent->pat*C0) > SCALE2 * 0.4) | ||||
| @@ -2131,7 +2178,7 @@ void moveBullet(monster *m, int delta) { | ||||
|    | ||||
|   bool godragon = m->type == moFireball && isDragon(c2->monst); | ||||
|    | ||||
|   if(m->type != moTongue && !(godragon || passable(c2, m->base, P_BULLET | P_MIRRORWALL))) { | ||||
|   if(m->type != moTongue && !(godragon || (c2==m->base && m->type == moArrowTrap) || passable(c2, m->base, P_BULLET | P_MIRRORWALL))) { | ||||
|     m->dead = true; | ||||
|     if(m->type != moAirball) killMonster(c2, m->parent ? m->parent->type : moNone); | ||||
|     // cell *c = m->base; | ||||
| @@ -2161,7 +2208,8 @@ void moveBullet(monster *m, int delta) { | ||||
|   // items[itOrbWinter] = 100; items[itOrbLife] = 100; | ||||
|    | ||||
|   if(!m->isVirtual) for(monster* m2: nonvirtual) { | ||||
|     if(m2 == m || (m2 == m->parent && m->vel >= 0) || m2->parent == m->parent) continue; | ||||
|     if(m2 == m || (m2 == m->parent && m->vel >= 0) || m2->parent == m->parent)  | ||||
|       continue; | ||||
|      | ||||
|     // Flailers only killable by themselves | ||||
|     if(m2->type == moFlailer && m2 != m->parent) continue; | ||||
| @@ -2221,7 +2269,7 @@ void moveBullet(monster *m, int delta) { | ||||
|         continue; | ||||
|         } | ||||
|       // conventional missiles cannot hurt some monsters | ||||
|       bool conv = (m->type == moBullet || m->type == moFlailBullet || m->type == moTongue); | ||||
|       bool conv = (m->type == moBullet || m->type == moFlailBullet || m->type == moTongue || m->type == moArrowTrap); | ||||
|  | ||||
|       if(m2->type == moGreater && conv) { | ||||
|         m->dead = true; | ||||
| @@ -2243,7 +2291,7 @@ void moveBullet(monster *m, int delta) { | ||||
|         } | ||||
|       // Knights reflect bullets | ||||
|       if(m2->type == moKnight) { | ||||
|         if(m->parent) { | ||||
|         if(m->parent && m->parent != &arrowtrap_fakeparent) { | ||||
|           nat = nat * rspintox(inverse(m->pat) * m->parent->pat * C0); | ||||
|           m->rebasePat(nat); | ||||
|           } | ||||
| @@ -2379,7 +2427,7 @@ void moveMonster(monster *m, int delta) { | ||||
|   else { | ||||
|    | ||||
|     if(m->type == moSleepBull && !m->isVirtual) { | ||||
|       for(monster *m2: nonvirtual) if(m2!=m && m2->type != moBullet) { | ||||
|       for(monster *m2: nonvirtual) if(m2!=m && m2->type != moBullet && m2->type != moArrowTrap) { | ||||
|         double d = intval(m2->pat*C0, nat*C0); | ||||
|         if(d < SCALE2*3 && m2->type == moPlayer) m->type = moRagingBull; | ||||
|         } | ||||
| @@ -2554,7 +2602,7 @@ void moveMonster(monster *m, int delta) { | ||||
|  | ||||
|   monster* crashintomon = NULL; | ||||
|    | ||||
|   if(!m->isVirtual) for(monster *m2: nonvirtual) if(m2!=m && m2->type != moBullet) { | ||||
|   if(!m->isVirtual) for(monster *m2: nonvirtual) if(m2!=m && m2->type != moBullet && m2->type != moArrowTrap) { | ||||
|     double d = intval(m2->pat*C0, nat*C0); | ||||
|     if(d < SCALE2 * 0.1) crashintomon = m2; | ||||
|     } | ||||
| @@ -2620,6 +2668,9 @@ void moveMonster(monster *m, int delta) { | ||||
|   if(c2 != m->base && (c2->wall == waClosePlate || c2->wall == waOpenPlate) && !ignoresPlates(m->type)) | ||||
|     toggleGates(c2, c2->wall, 3); | ||||
|  | ||||
|   if(c2 != m->base && c2->wall == waArrowTrap && c2->wparam == 0 && !ignoresPlates(m->type)) | ||||
|     activateArrowTrap(c2); | ||||
|  | ||||
|   if(c2 != m->base && mayExplodeMine(c2, m->type))  | ||||
|     killMonster(m, moNone); | ||||
|    | ||||
| @@ -2891,6 +2942,7 @@ void turn(int delta) { | ||||
|         break; | ||||
|        | ||||
|       case moBullet: case moFlailBullet: case moFireball: case moTongue: case moAirball: | ||||
|       case moArrowTrap: | ||||
|         moveBullet(m, delta); | ||||
|         break; | ||||
|        | ||||
| @@ -2945,6 +2997,8 @@ void turn(int delta) { | ||||
|    | ||||
|   if(shmup::on) { | ||||
|  | ||||
|     doTraps(); | ||||
|  | ||||
|     bool tick = curtime >= nextmove; | ||||
|     keepLightning = ticks <= lightat + 1000; | ||||
|     cwt.c = pc[0]->base; | ||||
| @@ -2977,6 +3031,7 @@ void turn(int delta) { | ||||
|         if(havewhat&HF_HEX) movehex(false); | ||||
|         wandering(); | ||||
|         livecaves(); | ||||
|         terracotta(); | ||||
|         heat::processfires(); | ||||
|         if(havewhat&HF_WHIRLPOOL) whirlpool::move(); | ||||
|         if(havewhat&HF_WHIRLWIND) whirlwind::move(); | ||||
| @@ -3201,6 +3256,11 @@ bool drawMonster(const transmatrix& V, cell *c, const transmatrix*& Vboat, trans | ||||
|           } | ||||
|         break; | ||||
|         } | ||||
|       case moArrowTrap: { | ||||
|         queuepoly(mmscale(view, 1.15), shTrapArrow, 0xFFFFFFFF); | ||||
|         ShadowV(view, shTrapArrow); | ||||
|         break; | ||||
|         } | ||||
|       case moTongue: { | ||||
|         queuepoly(mmscale(view, 1.15), shTongue, (minf[m->parenttype].color << 8) | 0xFF); | ||||
|         ShadowV(view, shTongue); | ||||
| @@ -3261,6 +3321,7 @@ void clearMonsters() { | ||||
| void clearMemory() { | ||||
|   clearMonsters(); | ||||
|   gmatrix.clear(); | ||||
|   traplist = {}; | ||||
|   curtime = 0; | ||||
|   nextmove = 0; | ||||
|   nextdragon = 0; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue