2018-02-08 23:40:26 +00:00
// Hyperbolic Rogue -- Barriers
2019-08-10 11:43:24 +00:00
// Copyright (C) 2011-2019 Zeno Rogue, see 'hyper.cpp' for details
/** \file barriers.cpp
* \ brief This file implements routines related to barriers ( Great Walls and similar ) .
*/
2017-10-08 10:10:40 +00:00
2019-09-05 07:15:40 +00:00
# include "hyper.h"
2018-06-10 23:58:31 +00:00
namespace hr {
2019-08-09 20:07:03 +00:00
EX bool checkBarriersFront ( cellwalker bb , int q IS ( 5 ) , bool cross IS ( false ) ) {
2017-10-08 10:10:40 +00:00
2018-08-17 22:46:45 +00:00
if ( ! ctof ( bb . at ) )
2017-10-08 10:10:40 +00:00
return false ;
2018-08-17 22:46:45 +00:00
if ( bb . at - > mpdist < BARLEV ) return false ;
if ( bb . at - > mpdist = = BUGLEV ) return false ;
if ( bb . at - > bardir ! = NODIR ) return false ;
2018-08-28 15:17:34 +00:00
if ( bb . spin = = ( PURE ? 3 : 0 ) ) { q - - ; if ( ! q ) return true ; }
2017-10-08 10:10:40 +00:00
if ( ! cross ) for ( int i = 0 ; i < 7 ; i + + ) {
2018-03-24 11:59:01 +00:00
cellwalker bb2 = bb + i + wstep ;
2018-08-17 22:46:45 +00:00
if ( bb2 . at - > bardir ! = NODIR ) return false ;
2018-08-28 15:17:34 +00:00
if ( ! PURE ) {
2018-03-24 11:59:01 +00:00
bb2 = bb2 + 4 + wstep ;
2018-08-17 22:46:45 +00:00
if ( bb2 . at - > bardir ! = NODIR ) return false ;
2017-10-08 10:10:40 +00:00
}
}
2018-03-24 11:59:01 +00:00
bb + = wstep ;
2018-08-28 15:17:34 +00:00
if ( ! PURE ) { bb = bb + 3 + wstep + 3 + wstep ; }
2017-10-08 10:10:40 +00:00
return checkBarriersBack ( bb , q ) ;
}
2019-08-18 13:32:46 +00:00
/** return true if the cell c is not allowed to generate barriers because of other large things already existing nearby. */
2019-08-09 19:00:52 +00:00
EX bool hasbardir ( cell * c ) {
2023-09-18 13:41:53 +00:00
return c - > bardir ! = NODIR & & c - > bardir ! = NOBARRIERS & & c - > bardir ! = NOBARRIERS2 ;
2017-10-08 10:10:40 +00:00
}
2019-08-09 19:00:52 +00:00
EX void preventbarriers ( cell * c ) {
2022-12-08 18:38:06 +00:00
if ( mhybrid ) c = hybrid : : get_where ( c ) . first ;
2017-10-08 10:10:40 +00:00
if ( c & & c - > bardir = = NODIR ) c - > bardir = NOBARRIERS ;
}
2019-08-09 20:07:03 +00:00
EX bool checkBarriersBack ( cellwalker bb , int q IS ( 5 ) , bool cross IS ( false ) ) {
2020-02-23 02:48:46 +00:00
// printf("back, %p, s%d\n", hr::voidp(bb.at), bb.spin);
2017-10-08 10:10:40 +00:00
2018-08-17 22:46:45 +00:00
// if(mark) { printf("mpdist = %d [%d] bardir = %d spin=%d q=%d cross=%d\n", bb.at->mpdist, BARLEV, bb.at->bardir, bb.spin, q, cross); }
2017-10-08 10:10:40 +00:00
2018-08-17 22:46:45 +00:00
if ( bb . at - > mpdist < BARLEV ) return false ;
if ( bb . at - > mpdist = = BUGLEV ) return false ;
if ( bb . at - > bardir ! = NODIR ) return false ;
2017-10-08 10:10:40 +00:00
2018-08-17 22:46:45 +00:00
// if(bb.spin == 0 && bb.at->mpdist == INFD) return true;
2017-10-08 10:10:40 +00:00
if ( ! cross ) for ( int i = 0 ; i < 7 ; i + + ) {
2018-03-24 11:59:01 +00:00
cellwalker bb2 = bb + i + wstep ;
2018-08-17 22:46:45 +00:00
if ( bb2 . at - > bardir ! = NODIR ) return false ;
2018-08-28 15:17:34 +00:00
if ( ! PURE ) {
2018-03-24 11:59:01 +00:00
bb2 = bb2 + 4 + wstep ;
2018-08-17 22:46:45 +00:00
if ( bb2 . at - > bardir ! = NODIR ) return false ;
2017-10-08 10:10:40 +00:00
}
}
2018-08-28 15:17:34 +00:00
bb = bb + 3 + wstep + ( PURE ? 5 : 4 ) + wstep + 3 ;
2017-10-08 10:10:40 +00:00
return checkBarriersFront ( bb , q ) ;
}
2019-08-10 11:43:24 +00:00
/** warp coasts use a different algorithm for nowall barriers when has_nice_dual() is on. Check whether we should use this different algorithm when the lands are l1 and l2 */
2019-08-09 19:00:52 +00:00
EX bool warped_version ( eLand l1 , eLand l2 ) {
2021-07-29 20:28:59 +00:00
return ( has_nice_dual ( ) & & ( l1 = = laWarpCoast | | l1 = = laWarpSea | | l2 = = laWarpSea | | l2 = = laWarpCoast ) ) ;
2018-04-04 15:59:24 +00:00
}
2021-07-30 01:00:00 +00:00
EX int get_valence ( cellwalker bb , int dir , bool & ok ) {
2022-06-23 08:36:37 +00:00
if ( arb : : in ( ) & & arb : : current_or_slided ( ) . have_valence ) {
2022-04-22 22:40:08 +00:00
auto & sh = arb : : current_or_slided ( ) . shapes [ arb : : id_of ( bb . at - > master ) ] ;
if ( bb . mirrored ) dir = - dir ;
if ( dir = = 1 )
return sh . vertex_valence [ bb . spin ] ;
else
return sh . vertex_valence [ gmod ( bb . spin - 1 , bb . at - > type ) ] ;
}
2021-07-30 01:00:00 +00:00
int steps = 0 ;
cellwalker bb1 = bb ;
while ( bb1 ! = bb | | ! steps ) {
bb1 + = dir ;
bb1 + = wstep ;
steps + + ;
}
return steps ;
}
EX void set_and_wall ( cell * c , eLand l ) {
setland ( c , l ) ;
if ( c - > bardir = = NODIR ) {
c - > barleft = NOWALLSEP_USED ;
c - > bardir = NOBARRIERS ;
}
}
EX void surround_by ( bool setit , cellwalker bb , int dir , int a , int b , eLand which , bool swapped , bool & ok ) {
for ( int i = 0 ; i < a ; i + + ) {
bb + = dir ;
bb + = wstep ;
}
for ( int i = a ; i < b ; i + + ) {
if ( setit ) set_and_wall ( bb . at , which ) ;
else {
if ( bb . at - > bardir ! = NODIR ) ok = false ;
if ( swapped & & bb . at - > mpdist < BARLEV ) ok = false ;
}
bb + = dir ;
bb + = wstep ;
}
}
EX void spin_around_by ( cellwalker & bb , int dir , int q ) {
for ( int i = 0 ; i < q ; i + + ) {
bb + = dir ;
bb + = wstep ;
}
}
2021-07-30 21:48:48 +00:00
EX bool on_wall ( eLand ws ) {
return among ( ws , NOWALLSEP_WALL_CPOS , NOWALLSEP_WALL_CNEG , NOWALLSEP_WALL_EPOS , NOWALLSEP_WALL_ENEG ) ;
}
2021-08-04 15:41:54 +00:00
string wsname ( eLand ws ) {
if ( ws = = NOWALLSEP ) return " NO " ;
if ( ws = = NOWALLSEP_SWAP ) return " SWAP " ;
if ( ws = = NOWALLSEP_USED ) return " USED " ;
if ( ws = = NOWALLSEP_WALL ) return " WALL " ;
if ( ws = = NOWALLSEP_WALL_CPOS ) return " CPOS " ;
if ( ws = = NOWALLSEP_WALL_CNEG ) return " CNEG " ;
if ( ws = = NOWALLSEP_WALL_EPOS ) return " EPOS " ;
if ( ws = = NOWALLSEP_WALL_ENEG ) return " ENEG " ;
return dnameof ( ws ) ;
}
2021-07-30 22:52:59 +00:00
EX bool general_barrier_advance ( cellwalker & bb , int & dir , eLand & l1 , eLand & l2 , eLand & ws , bool setit ) {
2021-07-29 20:28:59 +00:00
bool ok = true ;
2021-07-30 01:00:00 +00:00
if ( ws = = NOWALLSEP_WALL ) {
/*
if ( setit ) bb . at - > monst = moBug0 ;
if ( setit ) bb . cpeek ( ) - > monst = moBug2 ;
*/
int steps = get_valence ( bb , dir , ok ) ;
if ( steps % 2 = = 0 ) goto again ;
2022-04-22 22:40:25 +00:00
if ( steps > = OINF ) return ok ;
2021-07-30 01:00:00 +00:00
int s = ( steps - 1 ) / 2 ;
surround_by ( setit , bb , dir , 1 , s , l1 , false , ok ) ;
surround_by ( setit , bb , dir , s + 1 , steps - 1 , l2 , true , ok ) ;
spin_around_by ( bb , dir , s ) ;
2021-07-30 21:48:48 +00:00
ws = dir > 0 ? NOWALLSEP_WALL_CPOS : NOWALLSEP_WALL_CNEG ;
// goto tile;
return ok ;
}
if ( on_wall ( ws ) ) {
bool at_corner = among ( ws , NOWALLSEP_WALL_CPOS , NOWALLSEP_WALL_CNEG ) ;
2021-07-30 01:00:00 +00:00
2021-07-30 01:24:09 +00:00
cell * current = bb . at ;
2021-07-30 01:00:00 +00:00
// if at_corner: bb is facing the tile 1 before the first inside
int t = bb . at - > type ;
int q = at_corner ? t / 2 : ( t - 1 ) / 2 ;
if ( 1 ) {
auto bb1 = bb ;
if ( at_corner ) bb1 + = dir ;
bb1 - = dir ;
for ( int i = 1 ; i < q ; i + + ) {
int d = get_valence ( bb1 , - dir , ok ) ;
2022-04-22 22:40:25 +00:00
if ( d > = OINF ) return ok ;
2021-08-04 15:58:52 +00:00
surround_by ( setit , bb1 , - dir , 1 , d , l1 , false , ok ) ;
2021-07-30 01:00:00 +00:00
bb1 - = dir ;
}
}
bb + = dir ;
for ( int i = 1 ; i < q ; i + + ) {
int d = get_valence ( bb , dir , ok ) ;
2022-04-22 22:40:25 +00:00
if ( d > = OINF ) return ok ;
2021-08-04 15:58:52 +00:00
surround_by ( setit , bb , dir , 1 , d , l2 , true , ok ) ;
2021-07-30 01:00:00 +00:00
bb + = dir ;
}
// bb is now facing the last neighbor inside
if ( t % 2 = = ( at_corner ? 1 : 0 ) ) {
2021-07-30 21:48:48 +00:00
if ( setit ) setbarrier ( current , l1 , l2 , at_corner ) ;
2021-07-30 01:00:00 +00:00
int d = get_valence ( bb , dir , ok ) ;
2022-04-22 22:40:25 +00:00
if ( d > = OINF ) return ok ;
2021-07-30 01:00:00 +00:00
surround_by ( setit , bb , dir , 2 , d , l2 , true , ok ) ;
bb + = dir ;
bb + = wstep ;
d = get_valence ( bb , - dir , ok ) ;
2022-04-22 22:40:25 +00:00
if ( d > = OINF ) return ok ;
2021-07-30 01:00:00 +00:00
surround_by ( setit , bb , - dir , 2 , d - 1 , l1 , false , ok ) ;
2021-07-30 21:48:48 +00:00
ws = dir > 0 ? NOWALLSEP_WALL_EPOS : NOWALLSEP_WALL_ENEG ;
return ok ;
2021-07-30 01:00:00 +00:00
}
int steps1 = get_valence ( bb , dir , ok ) ;
2022-04-22 22:40:25 +00:00
if ( steps1 > = OINF ) return ok ;
2021-07-30 21:48:48 +00:00
if ( setit ) setbarrier ( current , l1 , l2 , true ) ;
2021-07-30 01:24:09 +00:00
2021-07-30 21:48:48 +00:00
if ( steps1 % 2 = = 0 ) {
2021-07-30 01:00:00 +00:00
int s1 = steps1 / 2 ;
surround_by ( setit , bb , dir , 1 , s1 , l1 , false , ok ) ;
surround_by ( setit , bb , dir , s1 + 1 , steps1 - 1 , l2 , true , ok ) ;
spin_around_by ( bb , dir , s1 ) ;
2021-07-30 21:48:48 +00:00
ws = dir > 0 ? NOWALLSEP_WALL_CPOS : NOWALLSEP_WALL_CNEG ;
return ok ;
2021-07-30 01:00:00 +00:00
}
2021-07-30 21:48:48 +00:00
int s1 = ( steps1 - 1 ) / 2 ;
2021-07-30 01:00:00 +00:00
surround_by ( setit , bb , dir , 1 , s1 , l1 , false , ok ) ;
surround_by ( setit , bb , dir , s1 + 2 , steps1 - 1 , l2 , true , ok ) ;
spin_around_by ( bb , dir , s1 ) ;
2021-07-30 21:48:48 +00:00
bb + = dir ;
ws = NOWALLSEP_WALL ;
2021-07-30 01:00:00 +00:00
}
else if ( warped_version ( l1 , l2 ) ) {
2018-04-04 15:59:24 +00:00
bb = bb + wstep + ( 2 * dir ) + wstep + dir ;
2018-07-10 21:02:27 +00:00
dir = - dir ;
swap ( l1 , l2 ) ;
2017-10-08 10:10:40 +00:00
}
2021-07-29 20:28:59 +00:00
else {
again :
cellwalker bb1 = bb ;
2021-07-30 01:00:00 +00:00
int steps = get_valence ( bb , dir , ok ) ;
2022-04-22 22:40:25 +00:00
if ( steps > = OINF ) return ok ;
2021-07-29 20:28:59 +00:00
int s = 2 ;
if ( ws = = NOWALLSEP_SWAP ) s = 5 - s ;
if ( dir = = - 1 ) s = 5 - s ;
s = ( 1 + steps - s ) / 2 ;
2021-07-30 01:00:00 +00:00
surround_by ( setit , bb , dir , 1 , s , l1 , false , ok ) ;
surround_by ( setit , bb , dir , s + 2 , steps - 1 , l2 , true , ok ) ;
spin_around_by ( bb , dir , s ) ;
2021-07-29 20:28:59 +00:00
bb + = dir ;
if ( steps & 1 ) ws = ( ws = = NOWALLSEP ? NOWALLSEP_SWAP : NOWALLSEP ) ;
if ( bb . at = = bb1 . at ) goto again ;
2017-10-08 10:10:40 +00:00
}
2021-07-29 20:28:59 +00:00
return ok ;
}
2021-08-04 15:45:24 +00:00
EX bool general_barrier_check ( cellwalker bb , int q , int dir , eLand ws , eLand l1 IS ( laNone ) , eLand l2 IS ( laNone ) ) {
2021-07-29 20:28:59 +00:00
if ( l1 = = l2 ) {
if ( bb . at - > mpdist < BARLEV | | bb . cpeek ( ) - > mpdist < BARLEV | | bb . cpeek ( ) - > bardir ! = NODIR | | bb . at - > bardir ! = NODIR )
return false ;
for ( int i = 0 ; i < bb . at - > type ; i + + ) {
cell * c1 = bb . at - > move ( i ) ;
if ( ! c1 ) continue ;
if ( c1 - > bardir ! = NODIR ) return false ;
}
}
2021-08-04 15:43:51 +00:00
if ( l1 ! = l2 & & bb . at - > barleft ! = NOWALLSEP_USED ) {
2021-07-29 20:28:59 +00:00
bb . at - > bardir = bb . spin ; bb . at - > barright = l2 ; bb . at - > barleft = ws ;
setland ( bb . at , l1 ) ;
}
2021-08-04 15:45:24 +00:00
if ( q < = 0 ) return true ;
2021-07-29 20:28:59 +00:00
2021-07-30 22:52:59 +00:00
bool b = general_barrier_advance ( bb , dir , l1 , l2 , ws , l1 ! = l2 ) ;
2021-07-29 20:28:59 +00:00
if ( l1 = = l2 & & ! b ) return false ;
2021-08-04 15:45:24 +00:00
return general_barrier_check ( bb , q - 1 , dir , ws , l1 , l2 ) ;
2017-10-08 10:10:40 +00:00
}
2021-08-04 15:46:47 +00:00
EX bool general_barrier_check_after ( cellwalker bb , int steps , int q , int dir , eLand ws , eLand l1 IS ( laNone ) , eLand l2 IS ( laNone ) ) {
for ( int i = 0 ; i < steps ; i + + ) general_barrier_advance ( bb , dir , l1 , l2 , ws , l1 ! = l2 ) ;
return general_barrier_check ( bb , q , dir , ws , l1 , l2 ) ;
}
2019-08-09 19:00:52 +00:00
EX eWall getElementalWall ( eLand l ) {
2017-10-08 10:10:40 +00:00
if ( l = = laEAir ) return waChasm ;
if ( l = = laEEarth ) return waStone ;
if ( l = = laEFire ) return waEternalFire ;
if ( l = = laEWater ) return waSea ;
return waNone ;
}
2021-07-30 01:24:09 +00:00
EX void setbarrier ( cell * c , eLand l1 , eLand l2 , bool setbar ) {
if ( isSealand ( l1 ) & & isSealand ( l2 ) ) {
if ( l1 = = laKraken | | l2 = = laKraken )
if ( l1 ! = laWarpSea & & l2 ! = laWarpSea )
2017-10-08 10:10:40 +00:00
setbar = ! setbar ;
c - > wall = setbar ? waBarrier : waSea ;
c - > land = laOceanWall ;
}
2021-07-30 01:24:09 +00:00
else if ( isElemental ( l1 ) & & isElemental ( l2 ) ) {
2017-10-08 10:10:40 +00:00
c - > land = laElementalWall ;
2021-07-30 01:24:09 +00:00
c - > wall = getElementalWall ( l1 ) ;
2017-10-08 10:10:40 +00:00
}
2021-07-30 01:24:09 +00:00
else if ( l1 = = laHaunted | | l2 = = laHaunted ) {
2017-10-08 10:10:40 +00:00
c - > land = laHauntedWall ;
}
2021-07-30 01:24:09 +00:00
else if ( l1 = = laMirrored2 | | l2 = = laMirrored2 )
2017-10-08 10:10:40 +00:00
c - > land = laMirrorWall2 ;
2021-07-30 01:24:09 +00:00
else if ( l1 = = laMirrored | | l2 = = laMirrored )
2017-10-08 10:10:40 +00:00
c - > land = laMirrorWall ;
2021-07-30 01:24:09 +00:00
else if ( l1 = = laTerracotta & & l2 = = laTerracotta ) {
2017-10-08 10:10:40 +00:00
c - > land = laMercuryRiver ;
c - > wall = waMercury ;
}
else {
c - > wall = waBarrier ;
c - > land = laBarrier ;
}
}
2021-07-30 01:24:09 +00:00
EX void setbarrier ( cell * c ) {
setbarrier ( c , c - > barleft , c - > barright , ctof ( c ) ) ;
}
2023-12-12 19:02:53 +00:00
EX int setland_max = 5 ;
2019-08-09 19:00:52 +00:00
EX void setland ( cell * c , eLand l ) {
2017-10-08 10:10:40 +00:00
if ( c - > land ! = l ) {
c - > landparam = 0 ;
}
2023-12-12 19:02:53 +00:00
if ( l = = laNone & & setland_max > 0 ) {
setland_max - - ;
printf ( " error: set land to laNone \n " ) ; // NONEDEBUG
2017-10-08 10:10:40 +00:00
}
c - > land = l ;
}
2019-08-09 19:00:52 +00:00
EX void extendcheck ( cell * c ) {
2017-10-08 10:10:40 +00:00
return ;
2018-08-28 15:17:34 +00:00
if ( BITRUNCATED & & c - > landparam = = 0 & & c - > barleft ! = NOWALLSEP ) {
2017-10-08 10:10:40 +00:00
raiseBuggyGeneration ( c , " extend error " ) ;
}
}
2019-08-09 19:00:52 +00:00
EX bool mirrorwall ( cell * c ) {
2017-10-08 10:10:40 +00:00
return c - > barleft = = laMirrored | | c - > barright = = laMirrored ;
}
2019-08-09 19:00:52 +00:00
EX void extendBarrierFront ( cell * c ) {
2020-02-23 02:48:46 +00:00
limitgen ( " extend front %p \n " , hr : : voidp ( c ) ) ;
2017-10-08 10:10:40 +00:00
if ( buggyGeneration ) return ;
int ht = c - > landparam ;
extendcheck ( c ) ;
2018-08-17 22:46:45 +00:00
cellwalker bb ( c , c - > bardir ) ; setbarrier ( bb . at ) ;
2018-03-24 11:59:01 +00:00
bb + = wstep ;
2017-10-08 10:10:40 +00:00
2018-08-28 15:17:34 +00:00
if ( BITRUNCATED ) {
2018-08-17 22:46:45 +00:00
bb . at - > barleft = c - > barleft ;
bb . at - > barright = c - > barright ;
setbarrier ( bb . at ) ;
if ( ! mirrorwall ( bb . at ) )
bb . at - > landparam = ( ht - 4 ) ;
2017-10-08 10:10:40 +00:00
//printf("[A heat %d]\n", ht-4);
2018-03-24 11:59:01 +00:00
2018-08-17 22:46:45 +00:00
setland ( ( bb + 2 ) . cpeek ( ) , c - > barleft ) ;
setland ( ( bb + 4 ) . cpeek ( ) , c - > barright ) ;
2017-10-08 10:10:40 +00:00
2018-03-24 11:59:01 +00:00
bb = bb + 3 + wstep ;
2018-08-17 22:46:45 +00:00
bb . at - > barleft = c - > barright ;
bb . at - > barright = c - > barleft ;
setbarrier ( bb . at ) ;
if ( ! mirrorwall ( bb . at ) )
bb . at - > landparam = ( ht - 4 ) ^ 2 ;
2017-10-08 10:10:40 +00:00
//printf("[B heat %d]\n", (ht-4)^2);
2018-03-24 11:59:01 +00:00
bb = bb + 3 + wstep ;
2017-10-08 10:10:40 +00:00
2018-08-17 22:46:45 +00:00
bb . at - > barleft = c - > barleft ;
bb . at - > barright = c - > barright ;
if ( ! mirrorwall ( bb . at ) )
bb . at - > landparam = ht ^ 2 ;
2017-10-08 10:10:40 +00:00
}
//printf("[C heat %d]\n", (ht)^2);
2018-08-17 22:46:45 +00:00
bb . at - > bardir = bb . spin ;
bb . at - > barleft = c - > barright ;
bb . at - > barright = c - > barleft ;
2017-10-08 10:10:40 +00:00
// printf("#1\n");
2018-08-17 22:46:45 +00:00
extendcheck ( bb . at ) ;
extendBarrier ( bb . at ) ;
2017-10-08 10:10:40 +00:00
for ( int a = - 3 ; a < = 3 ; a + + ) if ( a ) {
2018-08-28 15:17:34 +00:00
bb . at = c ; bb . spin = c - > bardir ; bb + = ( PURE ? - a : a ) ; bb + = wstep ;
2018-08-17 22:46:45 +00:00
setland ( bb . at , a > 0 ? c - > barright : c - > barleft ) ;
2017-10-08 10:10:40 +00:00
}
}
2019-08-09 19:00:52 +00:00
EX void extendBarrierBack ( cell * c ) {
2020-02-23 02:48:46 +00:00
limitgen ( " extend back %p \n " , hr : : voidp ( c ) ) ;
2017-10-08 10:10:40 +00:00
if ( buggyGeneration ) return ;
int ht = c - > landparam ;
extendcheck ( c ) ;
2018-08-17 22:46:45 +00:00
cellwalker bb ( c , c - > bardir ) ; setbarrier ( bb . at ) ;
2018-08-28 15:17:34 +00:00
bb = bb + 3 + wstep + ( PURE ? 5 : 4 ) ;
setland ( bb . at , PURE ? c - > barleft : c - > barright ) ;
2018-03-24 11:59:01 +00:00
bb = bb + wstep + 3 ;
2018-08-17 22:46:45 +00:00
bb . at - > bardir = bb . spin ;
bb . at - > barleft = c - > barright ;
bb . at - > barright = c - > barleft ;
if ( ! mirrorwall ( bb . at ) )
bb . at - > landparam = ht ^ 11 ;
extendcheck ( bb . at ) ;
2017-10-08 10:10:40 +00:00
//printf("[D heat %d]\n", (ht^11));
// needed for CR2 to work
2018-08-28 15:17:34 +00:00
if ( BITRUNCATED ) {
2018-03-24 11:59:01 +00:00
auto bb2 = bb + wstep ;
2018-08-17 22:46:45 +00:00
bb2 . at - > barleft = c - > barright ;
bb2 . at - > barright = c - > barleft ;
if ( ! mirrorwall ( bb2 . at ) )
bb2 . at - > landparam = ( ht ^ 11 ) - 4 ;
2017-10-08 10:10:40 +00:00
}
//printf("[E heat %d]\n", (ht^11));
// printf("#2\n");
2018-08-17 22:46:45 +00:00
extendBarrier ( bb . at ) ;
2017-10-08 10:10:40 +00:00
}
2021-07-30 22:52:59 +00:00
EX void general_barrier_extend ( cell * c ) {
2017-10-08 10:10:40 +00:00
2021-07-29 20:28:59 +00:00
eLand ws = c - > barleft ;
2017-10-08 10:10:40 +00:00
cellwalker cw ( c , c - > bardir ) ;
2021-07-30 21:48:48 +00:00
c - > barleft = NOWALLSEP_USED ;
2021-07-29 20:28:59 +00:00
eLand l1 = c - > land ;
eLand l2 = c - > barright ;
2021-07-30 21:48:48 +00:00
if ( ! on_wall ( ws ) ) {
if ( c - > bardir = = NODIR ) {
println ( hlog , " error: NODIR barrier at " , c ) ;
return ;
}
setland ( cw . cpeek ( ) , l2 ) ;
cw . cpeek ( ) - > barleft = NOWALLSEP_USED ;
}
2021-08-04 15:46:47 +00:00
if ( ws = = NOWALLSEP_WALL & & barrier_cross ( l1 , l2 ) ) {
cellwalker p_cw = cw ;
eLand p_l1 = l1 , p_l2 = l2 ;
eLand p_ws = ws ;
int i = 1 ;
general_barrier_advance ( p_cw , i , p_l1 , p_l2 , p_ws , false ) ;
cellwalker n_cw = cw ;
eLand n_l1 = l1 , n_l2 = l2 ;
eLand n_ws = ws ;
i = - 1 ;
general_barrier_advance ( n_cw , i , n_l1 , n_l2 , n_ws , false ) ;
int dir = 0 ;
println ( hlog , " left " , n_cw , " = " , n_cw . at - > barleft , " right " , p_cw , " = " , p_cw . at - > barleft , " USED = " , NOWALLSEP_USED ) ;
if ( n_cw . at - > barleft = = NOWALLSEP_USED & & p_cw . at - > barleft ! = NOWALLSEP_USED ) dir = 1 ;
if ( p_cw . at - > barleft = = NOWALLSEP_USED & & n_cw . at - > barleft ! = NOWALLSEP_USED ) dir = - 1 ;
if ( dir ) {
if ( ! general_barrier_check_after ( cw , 2 , 10 , 1 , NOWALLSEP_WALL_EPOS , l1 , l1 ) ) {
println ( hlog , " failed to check 1 " ) ;
dir = 0 ;
}
if ( ! general_barrier_check_after ( cw + wstep , 2 , 10 , 1 , NOWALLSEP_WALL_EPOS , l1 , l1 ) ) {
println ( hlog , " failed to check 2 " ) ;
dir = 0 ;
}
}
if ( dir ) {
eLand xl1 = oppositeElement ( l1 , l2 ) ;
eLand xl2 = oppositeElement ( l2 , l1 ) ;
if ( dir = = 1 ) {
general_barrier_check_after ( cw , 0 , 10 , 1 , NOWALLSEP_WALL_EPOS , l1 , xl2 ) ;
general_barrier_check_after ( cw + wstep , 0 , 10 , 1 , NOWALLSEP_WALL_EPOS , xl1 , l2 ) ;
}
else {
general_barrier_check_after ( cw , 0 , 10 , 1 , NOWALLSEP_WALL_EPOS , xl2 , l1 ) ;
general_barrier_check_after ( cw + wstep , 0 , 10 , 1 , NOWALLSEP_WALL_EPOS , l2 , xl1 ) ;
}
general_barrier_check ( cw , 10 , dir , ws , xl2 , xl1 ) ;
return ;
}
}
2021-07-29 20:28:59 +00:00
for ( int i : { - 1 , 1 } ) {
2021-07-30 21:48:48 +00:00
if ( i = = - 1 & & among ( ws , NOWALLSEP_WALL_CPOS , NOWALLSEP_WALL_EPOS ) ) continue ;
if ( i = = + 1 & & among ( ws , NOWALLSEP_WALL_CNEG , NOWALLSEP_WALL_ENEG ) ) continue ;
2021-08-04 15:46:47 +00:00
// general_barrier_check((cw, 10, i, ws, l1, l2);
2021-07-30 21:48:48 +00:00
2021-07-29 20:28:59 +00:00
cellwalker cw0 = cw ;
eLand xl1 = l1 , xl2 = l2 ;
eLand ws1 = ws ;
int i1 = i ;
2021-07-30 22:52:59 +00:00
general_barrier_advance ( cw0 , i1 , xl1 , xl2 , ws1 , true ) ;
2018-08-17 22:46:45 +00:00
if ( cw0 . at - > barleft ! = NOWALLSEP_USED ) {
2021-07-29 20:28:59 +00:00
setland ( cw0 . at , xl1 ) ;
cw0 . at - > barleft = ws1 ;
cw0 . at - > barright = xl2 ;
cw0 . at - > bardir = cw0 . spin ;
2018-08-17 22:46:45 +00:00
extendcheck ( cw0 . at ) ;
extendBarrier ( cw0 . at ) ;
2017-10-08 10:10:40 +00:00
}
}
}
bool gotit = false ;
2019-08-09 19:00:52 +00:00
EX void extendCR5 ( cell * c ) {
2018-08-28 15:17:34 +00:00
if ( ! BITRUNCATED ) return ;
2017-10-08 10:10:40 +00:00
// if(c->barright == laCrossroads5) extendCR5(c);
eLand forbidden = c - > barleft ;
eLand forbidden2 = laNone ;
cellwalker cw ( c , c - > bardir ) ;
for ( int u = 0 ; u < 2 ; u + + ) {
// if(gotit) break;
2018-03-24 11:59:01 +00:00
cw = cw + 2 + wstep + 2 + wstep + 5 ;
2018-08-17 22:46:45 +00:00
if ( cw . at - > bardir = = NODIR ) {
cw . at - > landparam = 40 ;
cw . at - > bardir = cw . spin ;
cw . at - > barright = laCrossroads5 ;
2017-10-08 10:10:40 +00:00
eLand nland = forbidden ;
for ( int i = 0 ; i < 10 & & ( nland = = forbidden | | nland = = forbidden2 ) ; i + + )
nland = getNewLand ( laCrossroads5 ) ;
2021-04-23 17:45:50 +00:00
if ( ls : : single ( ) & & specialland = = laCrossroads5 )
nland = laCrossroads5 ;
2018-08-17 22:46:45 +00:00
cw . at - > barleft = forbidden2 = nland ;
2017-10-08 10:10:40 +00:00
landcount [ nland ] + + ;
2018-08-17 22:46:45 +00:00
extendBarrier ( cw . at ) ;
2017-10-08 10:10:40 +00:00
gotit = true ;
}
2018-08-17 22:46:45 +00:00
else forbidden2 = cw . at - > barleft ;
2017-10-08 10:10:40 +00:00
}
}
2019-08-09 19:00:52 +00:00
EX bool isbar4 ( cell * c ) {
2017-10-08 10:10:40 +00:00
return
c - > wall = = waBarrier | | c - > land = = laElementalWall | |
c - > land = = laMirrorWall | | c - > land = = laMirrorWall2 | |
c - > land = = laMercuryRiver ;
}
2021-08-04 15:46:47 +00:00
EX bool barrier_cross ( eLand l , eLand r ) {
if ( l = = laCrossroads3 | | r = = laCrossroads3 ) return hrand ( 100 ) < 66 ;
2024-04-06 08:36:51 +00:00
if ( land_structure = = lsCrossWalls ) return hrand ( 100 ) < 90 ;
2021-08-04 15:46:47 +00:00
if ( isElemental ( l ) & & isElemental ( r ) ) return hrand ( 100 ) < 75 ;
return false ;
}
2019-08-09 19:00:52 +00:00
EX void extendBarrier ( cell * c ) {
2020-02-23 02:48:46 +00:00
limitgen ( " extend barrier %p \n " , hr : : voidp ( c ) ) ;
2017-10-08 10:10:40 +00:00
if ( buggyGeneration ) return ;
if ( c - > barleft = = NOWALLSEP_USED ) return ;
extendcheck ( c ) ;
2020-02-23 02:48:46 +00:00
// printf("build barrier at %p", hr::voidp(c));
2017-10-08 10:10:40 +00:00
if ( c - > land = = laBarrier | | c - > land = = laElementalWall | | c - > land = = laHauntedWall | | c - > land = = laOceanWall | |
c - > land = = laMirrorWall | | c - > land = = laMirrorWall2 | | c - > land = = laMercuryRiver ) {
// printf("-> ready\n");
return ;
}
// if(c->wall == waWaxWall) return;
if ( c - > mpdist > BARLEV ) {
// printf("-> too far\n");
return ; // == INFD) return;
}
2021-08-04 15:43:51 +00:00
if ( c - > barleft = = NOWALLSEP | | c - > barleft = = NOWALLSEP_SWAP | | c - > barleft = = NOWALLSEP_WALL | | on_wall ( c - > barleft ) ) {
2019-09-13 01:10:26 +00:00
# if MAXMDIM >= 4
2019-05-08 16:33:08 +00:00
if ( WDIM = = 3 ) extend3D ( c ) ;
2019-09-13 01:10:26 +00:00
else
# endif
2021-07-30 22:52:59 +00:00
general_barrier_extend ( c ) ;
2017-10-08 10:10:40 +00:00
return ;
}
bool firstmirror =
( c - > barleft = = laMirrored | | c - > barright = = laMirrored ) & &
c - > barleft ! = laMirrored2 & & c - > barright ! = laMirrored2 ;
if ( firstmirror & & c - > barleft = = laMirror & & hrand ( 100 ) < 60 ) {
cellwalker cw ( c , c - > bardir ) ;
2018-08-28 15:17:34 +00:00
if ( BITRUNCATED ) cw + = wstep ;
2018-08-17 22:46:45 +00:00
if ( cw . at - > land ! = laMirrorWall )
2017-10-08 10:10:40 +00:00
if ( buildBarrier6 ( cw , 1 ) ) return ;
}
2018-08-28 15:17:34 +00:00
if ( firstmirror & & ( PURE ? c - > barleft = = laMirror : c - > barright = = laMirror ) & & hrand ( 100 ) < 60 ) {
2017-10-08 10:10:40 +00:00
cellwalker cw ( c , c - > bardir ) ;
2018-08-28 15:17:34 +00:00
if ( PURE ) {
2018-03-24 11:59:01 +00:00
cw = cw - 3 + wstep - 3 ;
2017-10-08 10:10:40 +00:00
}
else {
2018-03-24 11:59:01 +00:00
cw = cw + wstep + 3 + wstep - 1 ; // check this
2017-10-08 10:10:40 +00:00
}
if ( buildBarrier6 ( cw , 2 ) ) return ;
}
2024-04-06 16:33:29 +00:00
if ( land_structure = = lsCursedWalls & & c - > barleft ! = laMirror & & c - > barright ! = laMirror & & hrand ( 100 ) < 80 ) {
cellwalker cw ( c , c - > bardir ) ;
cw = cw + wstep + 3 + wstep - 1 ;
if ( buildBarrier6 ( cw , c - > barright , c - > barleft ) ) return ;
}
2021-08-04 15:46:47 +00:00
if ( barrier_cross ( c - > barleft , c - > barright ) | | ( firstmirror & & hrand ( 100 ) < 60 ) ) {
2017-10-08 10:10:40 +00:00
cellwalker cw ( c , c - > bardir ) ;
2018-08-28 15:17:34 +00:00
if ( PURE ) {
2018-03-24 11:59:01 +00:00
cw + = wstep ;
2018-08-17 22:46:45 +00:00
if ( isbar4 ( cw . at ) ) {
2018-03-24 11:59:01 +00:00
cw = cw + wstep + 3 + wstep - 1 + wstep ;
2018-08-17 22:46:45 +00:00
bool b = buildBarrier4 ( cw . at , cw . spin , 2 , oppositeElement ( c - > barleft , c - > barright ) , c - > barright ) ;
2017-10-08 10:10:40 +00:00
if ( b ) return ;
}
else {
bool b = buildBarrier4 ( c , c - > bardir , 1 , c - > barleft , c - > barright ) ;
if ( b ) return ;
}
}
else {
2018-03-24 11:59:01 +00:00
cw = cw + 3 + wstep ;
2018-08-17 22:46:45 +00:00
cell * cp = ( cw + 4 + wstep ) . at ;
2017-10-08 10:10:40 +00:00
if ( ! isbar4 ( cp ) ) {
2018-03-24 11:59:01 +00:00
cw = cw + 2 + wstep ;
2018-08-17 22:46:45 +00:00
bool b = buildBarrier4 ( cw . at , cw . spin , 2 , oppositeElement ( c - > barleft , c - > barright ) , c - > barright ) ;
2017-10-08 10:10:40 +00:00
if ( b ) return ;
}
else {
bool b = buildBarrier4 ( c , c - > bardir , 1 , c - > barleft , c - > barright ) ;
if ( b ) return ;
}
}
}
extendBarrierFront ( c ) ;
extendBarrierBack ( c ) ;
if ( c - > barright = = laCrossroads5 ) extendCR5 ( c ) ;
}
2019-08-09 19:00:52 +00:00
EX void buildBarrierForce ( cell * c , int d , eLand l ) {
2017-10-08 10:10:40 +00:00
c - > bardir = d ;
eLand oldland = c - > land ;
if ( oldland = = laNone ) {
raiseBuggyGeneration ( c , " oldland is NONE " ) ;
return ;
}
eLand newland = l ? l : getNewLand ( oldland ) ;
landcount [ newland ] + + ;
if ( d = = 4 | | d = = 5 | | d = = 6 ) c - > barleft = oldland , c - > barright = newland ;
else c - > barleft = newland , c - > barright = oldland ;
if ( ! mirrorwall ( c ) ) c - > landparam = 40 ;
extendcheck ( c ) ;
}
2019-08-09 19:00:52 +00:00
EX void buildBarrier ( cell * c , int d , eLand l IS ( laNone ) ) {
2021-07-30 01:00:00 +00:00
if ( ! old_nice_walls ( ) ) {
2021-07-30 22:52:59 +00:00
general_barrier_build ( NOWALLSEP_WALL , c , l ? l : getNewLand ( c - > land ) , NODIR ) ;
2021-07-30 01:00:00 +00:00
return ;
}
2017-10-08 10:10:40 +00:00
d % = 7 ;
cellwalker bb ( c , d ) ;
if ( checkBarriersFront ( bb ) & & checkBarriersBack ( bb ) )
buildBarrierForce ( c , d , l ) ;
}
2024-04-06 16:33:29 +00:00
/** mirror variant of 6-fold walls */
2019-08-09 19:00:52 +00:00
EX bool buildBarrier6 ( cellwalker cw , int type ) {
2020-02-23 02:48:46 +00:00
limitgen ( " build6 %p/%d (%d) \n " , hr : : voidp ( cw . at ) , cw . spin , type ) ;
2017-10-08 10:10:40 +00:00
cellwalker b [ 4 ] ;
if ( buggyGeneration ) return true ;
2018-08-28 15:17:34 +00:00
if ( BITRUNCATED ) {
2018-03-24 11:59:01 +00:00
b [ 0 ] = cw + wstep ;
b [ 1 ] = cw + 1 + wstep + 3 + wstep ;
b [ 2 ] = cw + 4 + wstep ;
b [ 3 ] = cw + 3 + wstep + 3 + wstep ;
2017-10-08 10:10:40 +00:00
}
else {
2018-03-24 11:59:01 +00:00
b [ 0 ] = cw ;
b [ 1 ] = cw + 3 + wstep + 3 ;
b [ 2 ] = cw - 2 + wstep - 3 ;
b [ 3 ] = cw - 3 + wstep + 2 + wstep - 3 ;
2018-08-17 22:46:45 +00:00
if ( type = = 1 & & b [ 3 ] . at - > land ! = laMirrorWall ) return false ;
if ( type = = 2 & & ( b [ 1 ] + wstep ) . at - > land ! = laMirrorWall ) return false ;
// if(type == 2 && b[2].at->land != laMirrorWall) return false;
2017-10-08 10:10:40 +00:00
}
if ( false ) {
for ( int z = 0 ; z < 4 ; z + + ) {
2020-02-23 02:48:46 +00:00
printf ( " %p/%d \n " , hr : : voidp ( b [ z ] . at ) , b [ z ] . spin ) ;
2018-08-17 22:46:45 +00:00
b [ z ] . at - > wall = waStrandedBoat ; b [ z ] . at - > land = laAlchemist ;
b [ z ] . at - > mondir = b [ z ] . spin ;
b [ z ] . at - > mpdist = 7 ;
b [ z ] . at - > item = eItem ( 1 + z ) ;
2017-10-08 10:10:40 +00:00
buggyGeneration = true ;
}
return true ;
}
if ( type = = 1 ) {
2018-08-28 15:17:34 +00:00
if ( ! ( PURE ? checkBarriersFront : checkBarriersBack ) ( b [ 1 ] , 6 , true ) ) return false ;
if ( ! ( PURE ? checkBarriersFront : checkBarriersBack ) ( b [ 2 ] , 6 , true ) ) return false ;
2017-10-08 10:10:40 +00:00
}
else {
2018-08-28 15:17:34 +00:00
if ( ! ( PURE ? checkBarriersFront : checkBarriersBack ) ( b [ 0 ] , 6 , true ) ) return false ;
if ( ! ( PURE ? checkBarriersFront : checkBarriersBack ) ( b [ 3 ] , 6 , true ) ) return false ;
2017-10-08 10:10:40 +00:00
}
2024-04-06 16:33:29 +00:00
eLand m0 = laMirror ;
eLand m1 = laMirrored ;
eLand m2 = laMirrored2 ;
eLand mw1 = laMirrorWall ;
eLand mw2 = laMirrorWall2 ;
eWall w = waMirrorWall ;
2017-10-08 10:10:40 +00:00
for ( int d = 0 ; d < 4 ; d + + ) {
2018-08-17 22:46:45 +00:00
b [ d ] . at - > bardir = b [ d ] . spin ;
2017-10-08 10:10:40 +00:00
2018-08-28 15:17:34 +00:00
if ( PURE ) {
2024-04-06 16:33:29 +00:00
b [ 0 ] . at - > barleft = m1 , b [ 0 ] . at - > barright = m2 ;
b [ 1 ] . at - > barleft = m0 , b [ 1 ] . at - > barright = m1 ;
b [ 2 ] . at - > barleft = m2 , b [ 2 ] . at - > barright = m1 ;
b [ 3 ] . at - > barleft = m1 , b [ 3 ] . at - > barright = m0 ;
2017-10-08 10:10:40 +00:00
}
else {
2024-04-06 16:33:29 +00:00
b [ 0 ] . at - > barleft = m0 , b [ 0 ] . at - > barright = m1 ;
b [ 1 ] . at - > barleft = m1 , b [ 1 ] . at - > barright = m0 ;
b [ 2 ] . at - > barleft = m1 , b [ 2 ] . at - > barright = m2 ;
b [ 3 ] . at - > barleft = m2 , b [ 3 ] . at - > barright = m1 ;
2017-10-08 10:10:40 +00:00
}
2018-08-28 15:17:34 +00:00
( PURE ? extendBarrierFront : extendBarrierBack ) ( b [ d ] . at ) ;
2017-10-08 10:10:40 +00:00
}
2018-08-28 15:17:34 +00:00
if ( PURE & & false ) {
2017-10-08 10:10:40 +00:00
for ( int z = 0 ; z < 4 ; z + + )
2018-08-17 22:46:45 +00:00
b [ z ] . at - > item = eItem ( 1 + z + 4 * type ) ;
2017-10-08 10:10:40 +00:00
for ( int a = 0 ; a < 4 ; a + + )
2018-08-17 22:46:45 +00:00
extendBarrierBack ( ( b [ a ] + wstep ) . at ) ;
2017-10-08 10:10:40 +00:00
}
2018-08-28 15:17:34 +00:00
if ( BITRUNCATED ) {
2024-04-06 16:33:29 +00:00
setland ( ( cw + 1 ) . cpeek ( ) , mw1 ) ;
setland ( ( cw + 2 ) . cpeek ( ) , m1 ) ;
setland ( ( cw + 3 ) . cpeek ( ) , mw2 ) ;
setland ( ( cw + 4 ) . cpeek ( ) , mw2 ) ;
setland ( ( cw + 5 ) . cpeek ( ) , m1 ) ;
setland ( ( cw + 0 ) . cpeek ( ) , mw1 ) ;
setland ( ( b [ 0 ] + 2 ) . cpeek ( ) , m1 ) ;
setland ( ( b [ 3 ] + 6 ) . cpeek ( ) , m2 ) ;
setland ( ( b [ 3 ] + 5 ) . cpeek ( ) , m2 ) ;
setland ( ( b [ 1 ] - 1 ) . cpeek ( ) , m1 ) ;
setland ( ( b [ 2 ] - 2 ) . cpeek ( ) , m1 ) ;
setland ( ( b [ 1 ] - 2 ) . cpeek ( ) , m1 ) ;
setland ( ( b [ 0 ] - 2 ) . cpeek ( ) , m0 ) ;
cw . at - > land = mw1 ;
cw . at - > wall = w ;
2018-08-17 22:46:45 +00:00
cw . at - > landparam = 1 ;
2017-10-08 10:10:40 +00:00
}
else {
2024-04-06 16:33:29 +00:00
setland ( cw . at , mw2 ) ;
setland ( ( cw + 0 ) . cpeek ( ) , mw2 ) ;
setland ( ( cw + 1 ) . cpeek ( ) , m1 ) ;
setland ( ( cw + 2 ) . cpeek ( ) , m1 ) ;
setland ( ( cw + 3 ) . cpeek ( ) , mw1 ) ;
setland ( ( cw + 4 ) . cpeek ( ) , m1 ) ;
setland ( ( cw + 5 ) . cpeek ( ) , mw2 ) ;
setland ( ( cw + 6 ) . cpeek ( ) , m2 ) ;
2017-10-08 10:10:40 +00:00
2024-04-06 16:33:29 +00:00
setland ( ( b [ 1 ] ) . cpeek ( ) , mw1 ) ;
setland ( ( b [ 1 ] + 1 ) . cpeek ( ) , m0 ) ;
setland ( ( b [ 1 ] + 2 ) . cpeek ( ) , mw1 ) ;
setland ( ( b [ 1 ] + 6 ) . cpeek ( ) , m1 ) ;
2017-10-08 10:10:40 +00:00
2024-04-06 16:33:29 +00:00
setland ( ( b [ 0 ] + wstep - 2 ) . cpeek ( ) , m1 ) ;
setland ( ( b [ 3 ] + wstep - 2 ) . cpeek ( ) , m1 ) ;
2017-10-08 10:10:40 +00:00
}
return true ;
}
2024-04-06 16:33:29 +00:00
EX int curse_percentage = 10 ;
/** cursed variant of 6-fold walls */
EX bool buildBarrier6 ( cellwalker cw , eLand m0 , eLand m1 ) {
cellwalker b [ 6 ] ;
if ( buggyGeneration ) return true ;
for ( int i = 0 ; i < 6 ; i + = 2 )
b [ i ] = cw + i + wstep ;
for ( int i = 1 ; i < 6 ; i + = 2 )
b [ i ] = cw + i + wstep + 3 + wstep ;
for ( int i = 0 ; i < 6 ; i + + ) if ( i ! = 1 ) {
if ( ! ( PURE ? checkBarriersFront : checkBarriersBack ) ( b [ i ] , 6 , true ) ) return false ;
}
for ( int d = 0 ; d < 6 ; d + + ) {
b [ d ] . at - > bardir = b [ d ] . spin ;
b [ d ] . at - > barleft = ( d & 1 ) ? m1 : m0 ;
b [ d ] . at - > barright = ( d & 1 ) ? m0 : m1 ;
( PURE ? extendBarrierFront : extendBarrierBack ) ( b [ d ] . at ) ;
}
cw . at - > land = laBarrier ;
cw . at - > wall = waBarrier ;
forCellCM ( c , cw . at ) { c - > land = laBarrier ; c - > wall = waBarrier ; }
for ( int d = 0 ; d < 6 ; d + = 2 ) {
setland ( ( b [ d ] - 2 ) . cpeek ( ) , m0 ) ;
setland ( ( b [ d ] + 2 ) . cpeek ( ) , m1 ) ;
setland ( ( b [ d + 1 ] - 2 ) . cpeek ( ) , m1 ) ;
setland ( ( b [ d + 1 ] + 2 ) . cpeek ( ) , m0 ) ;
}
if ( hrand ( 100 ) < curse_percentage ) {
setland ( cw . at , laCursed ) ;
cw . at - > wall = waRubble ;
cw . at - > monst = moHexer ;
cw . at - > item = random_curse ( ) ;
}
return true ;
}
2019-08-09 19:00:52 +00:00
EX bool buildBarrier4 ( cell * c , int d , int mode , eLand ll , eLand lr ) {
2020-02-23 02:48:46 +00:00
limitgen ( " build4 %p \n " , hr : : voidp ( c ) ) ;
2017-10-08 10:10:40 +00:00
if ( buggyGeneration ) return true ;
d % = 7 ;
2018-03-24 11:59:01 +00:00
cellwalker cd ( c , d ) ;
cellwalker b1 = cd ;
2018-08-28 15:17:34 +00:00
cellwalker b2 = PURE ? cd + wstep : cd + wstep + 3 + wstep + 3 + wstep ;
cellwalker b3 = PURE ? cd - 1 + wstep + 3 : cd + wstep + 4 + wstep + 4 ;
cellwalker b4 = PURE ? cd + 1 + wstep - 3 : cd + wstep - 4 + wstep - 4 ;
2017-10-08 10:10:40 +00:00
if ( mode = = 0 ) {
if ( ! ( ( checkBarriersBack ( b1 ) & & checkBarriersBack ( b2 ) ) ) ) return false ;
if ( ! ( ( checkBarriersFront ( b3 ) & & checkBarriersFront ( b4 ) ) ) ) return false ;
}
if ( mode = = 1 ) {
if ( ! ( checkBarriersFront ( b3 , 5 , true ) & & checkBarriersFront ( b4 , 5 , true ) ) )
return false ;
}
if ( mode = = 2 ) {
if ( ! ( ( checkBarriersBack ( b1 , 5 , true ) & & checkBarriersBack ( b2 , 5 , true ) ) ) )
return false ;
}
eLand xl = oppositeElement ( ll , lr ) ;
eLand xr = oppositeElement ( lr , ll ) ;
c - > bardir = d , c - > barleft = ll , c - > barright = lr ; extendBarrierBack ( c ) ;
2018-08-17 22:46:45 +00:00
c = b2 . at ; d = b2 . spin ;
2017-10-08 10:10:40 +00:00
c - > bardir = d , c - > barleft = xl , c - > barright = xr ; extendBarrierBack ( c ) ;
2018-08-17 22:46:45 +00:00
c = b3 . at ; d = b3 . spin ;
2017-10-08 10:10:40 +00:00
c - > bardir = d , c - > barleft = xl , c - > barright = lr ; extendBarrierFront ( c ) ;
2018-08-17 22:46:45 +00:00
c = b4 . at ; d = b4 . spin ;
2017-10-08 10:10:40 +00:00
c - > bardir = d , c - > barleft = ll , c - > barright = xr ; extendBarrierFront ( c ) ;
2018-08-28 15:17:34 +00:00
if ( BITRUNCATED ) for ( int a = - 3 ; a < = 3 ; a + + ) if ( a ) {
2018-08-17 22:46:45 +00:00
setland ( ( b1 + a ) . cpeek ( ) , a > 0 ? lr : ll ) ;
setland ( ( b2 + a ) . cpeek ( ) , a > 0 ? xr : xl ) ;
setland ( ( b3 + a ) . cpeek ( ) , a > 0 ? lr : xl ) ;
setland ( ( b4 + a ) . cpeek ( ) , a > 0 ? xr : ll ) ;
2017-10-08 10:10:40 +00:00
}
2018-08-28 15:17:34 +00:00
if ( PURE ) setbarrier ( b1 . at ) , setbarrier ( b2 . at ) , setbarrier ( b3 . at ) , setbarrier ( b4 . at ) ;
2017-10-08 10:10:40 +00:00
2018-08-28 15:17:34 +00:00
if ( BITRUNCATED ) {
2017-10-08 10:10:40 +00:00
cell * cp ;
2018-08-17 22:46:45 +00:00
cp = ( b1 + wstep ) . at ;
2017-10-08 10:10:40 +00:00
cp - > barleft = ll ; cp - > barright = lr ; setbarrier ( cp ) ;
2018-08-17 22:46:45 +00:00
cp = ( b2 + wstep ) . at ;
2017-10-08 10:10:40 +00:00
cp - > barleft = xl ; cp - > barright = xr ; setbarrier ( cp ) ;
}
return true ;
}
2019-08-09 19:00:52 +00:00
EX void buildBarrierStrong ( cell * c , int d , bool oldleft , eLand newland ) {
2017-10-08 10:10:40 +00:00
d % = 7 ;
cellwalker bb ( c , d ) ;
c - > bardir = d ;
eLand oldland = c - > land ;
landcount [ newland ] + + ;
if ( oldleft ) c - > barleft = oldland , c - > barright = newland ;
else c - > barleft = newland , c - > barright = oldland ;
2018-08-17 22:46:45 +00:00
extendcheck ( bb . at ) ;
2017-10-08 10:10:40 +00:00
}
2019-08-09 19:00:52 +00:00
EX void buildBarrierStrong ( cell * c , int d , bool oldleft ) {
2018-03-29 22:20:33 +00:00
buildBarrierStrong ( c , d , oldleft , getNewLand ( c - > land ) ) ;
}
2019-08-09 19:00:52 +00:00
EX void buildCrossroads2 ( cell * c ) {
2017-10-08 10:10:40 +00:00
if ( buggyGeneration ) return ;
if ( ! c ) return ;
2023-12-15 08:54:27 +00:00
if ( ls : : hv_structure ( ) ) return ;
2017-10-08 10:10:40 +00:00
for ( int i = 0 ; i < c - > type ; i + + )
2018-08-17 22:46:45 +00:00
if ( c - > move ( i ) & & ! c - > move ( i ) - > landparam & & c - > move ( i ) - > mpdist < c - > mpdist )
buildCrossroads2 ( c - > move ( i ) ) ;
2017-10-08 10:10:40 +00:00
if ( hasbardir ( c ) )
extendBarrier ( c ) ;
if ( c - > land ! = laCrossroads2 ) return ;
if ( ! c - > landparam ) {
for ( int i = 0 ; i < c - > type ; i + + ) {
cell * c2 = createMov ( c , i ) ;
if ( c2 & & c2 - > landparam & & ( c2 - > land = = laCrossroads2 | | c2 - > land = = laBarrier ) ) {
for ( int j = 0 ; j < c2 - > type ; j + + ) {
createMov ( c2 , j ) ;
2018-08-17 22:46:45 +00:00
cell * c3 = c2 - > move ( j ) ;
2017-10-08 10:10:40 +00:00
if ( c3 & & c3 - > landparam & & ( c3 - > land = = laCrossroads2 | | c3 - > land = = laBarrier ) ) {
int h2 = c2 - > landparam ;
int h3 = c3 - > landparam ;
if ( h2 > 100 ) { raiseBuggyGeneration ( c2 , " bad c2 landparam " ) ; return ; }
if ( h3 > 100 ) { raiseBuggyGeneration ( c3 , " bad c3 landparam " ) ; return ; }
// ambiguous
if ( h2 / 4 = = 1 & & h3 / 4 = = 3 ) continue ;
if ( h2 / 4 = = 3 & & h3 / 4 = = 1 ) continue ;
for ( int d = 0 ; d < c2 - > type ; d + + )
if ( emeraldtable [ h2 ] [ d ] = = h3 ) {
2018-08-17 22:46:45 +00:00
int nh = emeraldtable [ h2 ] [ ( 42 + d + c - > c . spin ( i ) - j ) % c2 - > type ] ;
2017-10-08 10:10:40 +00:00
if ( c - > landparam > 0 & & c - > landparam ! = nh ) {
printf ( " CONFLICT \n " ) ;
raiseBuggyGeneration ( c , " CONFLICT " ) ;
}
c - > landparam = nh ;
}
if ( c - > landparam = = 0 )
printf ( " H2 = %d H3=%d \n " , c2 - > landparam , c3 - > landparam ) ;
}
}
if ( c - > landparam = = 0 ) {
printf ( " H2 = %d \n " , c2 - > landparam ) ;
// halted = true;
// c->heat = -1;
raiseBuggyGeneration ( c , " buildCrossroads2x " ) ;
return ;
}
}
}
if ( c - > landparam ) {
// for(int i=0; i<c->type; i++) {
2018-08-17 22:46:45 +00:00
// cell *c2 = c->move(i);
2017-10-08 10:10:40 +00:00
// buildCrossroads2(c2);
// }
}
else {
raiseBuggyGeneration ( c , " buildCrossroads2 " ) ;
return ;
}
}
int h = c - > landparam ;
if ( h / 4 > = 8 & & h / 4 < = 11 ) {
2017-10-30 18:10:25 +00:00
for ( int i = 0 ; i < c - > type ; i + + ) if ( c - > land ! = laBarrier ) {
cell * c2 = createMov ( c , i ) ;
if ( c2 - > land = = laBarrier ) continue ;
c2 - > land = laCrossroads2 ;
if ( ! c2 - > landparam ) buildCrossroads2 ( c2 ) ;
2017-10-08 10:10:40 +00:00
}
if ( h / 4 = = 8 | | h / 4 = = 10 )
for ( int i = 0 ; i < c - > type ; i + + ) {
2018-08-17 22:46:45 +00:00
if ( c - > move ( i ) & & c - > move ( i ) - > landparam = = h - 4 ) {
2017-10-08 10:10:40 +00:00
bool oldleft = true ;
for ( int j = 1 ; j < = 3 ; j + + )
2018-08-17 22:46:45 +00:00
if ( c - > modmove ( i + j ) & & c - > modmove ( i + j ) - > mpdist < c - > mpdist )
2017-10-08 10:10:40 +00:00
oldleft = false ;
c - > landparam = h ;
2021-04-23 17:45:50 +00:00
if ( ls : : single ( ) )
buildBarrierStrong ( c , i , oldleft , specialland ) ;
else
buildBarrierStrong ( c , i , oldleft ) ;
2017-10-08 10:10:40 +00:00
c - > landparam = h ;
extendBarrier ( c ) ;
}
}
}
}
2019-05-06 23:08:49 +00:00
# if MAXMDIM >= 4
2021-07-11 10:28:19 +00:00
EX bool bufferzone ( ) { return PURE & & S7 = = 6 ; }
EX int basic_tests ( ) { return 50 ; }
2021-07-11 09:48:33 +00:00
2021-07-11 13:07:40 +00:00
EX bool valid_dir ( const vector < char > & ad , int j , cell * c ) {
bool bch = variation = = eVariation : : bch ;
if ( ! bch ) return ad [ j ] = = 1 ;
if ( ad [ j ] ! = 2 ) return false ;
2021-07-12 09:07:22 +00:00
auto ad1 = currentmap - > get_cellshape ( c ) . dirdist [ j ] ;
2021-07-11 13:07:40 +00:00
int a = 0 ;
for ( auto & dd : ad1 ) if ( dd = = 1 ) a + + ;
int a0 = 0 ;
for ( auto & dd : ad ) if ( dd = = 1 ) a0 + + ;
return a < 6 ;
}
2019-08-09 19:00:52 +00:00
EX void extend3D ( cell * c ) {
2019-03-10 17:37:09 +00:00
eLand l1 = c - > land ;
c - > barleft = NOWALLSEP_USED ;
cellwalker cw ( c , c - > bardir ) ;
2021-07-11 09:48:33 +00:00
if ( bufferzone ( ) ) {
2019-03-10 17:37:09 +00:00
cw + = wstep ; cw + = rev ;
cw . at - > bardir = NOBARRIERS ;
setland ( cw . at , laBarrier ) ;
}
auto cw1 = cw + wstep ;
setland ( cw1 . at , c - > barright ) ;
if ( cw1 . at - > bardir = = NODIR ) {
cw1 . at - > barleft = NOWALLSEP_USED ;
cw1 . at - > barright = l1 ;
cw1 . at - > bardir = cw1 . spin ;
}
2021-07-11 13:07:40 +00:00
bool bch = variation = = eVariation : : bch ;
auto & ad = currentmap - > dirdist ( cw ) ;
for ( int j = 0 ; j < cw . at - > type ; j + + ) {
if ( ! valid_dir ( ad , j , cw . at ) ) {
if ( bch & & ad [ j ] = = 1 ) {
cell * c1 = cw . at - > cmove ( j ) ;
c1 - > bardir = NOBARRIERS ;
setland ( c1 , c - > barright ) ;
}
if ( bch & & ad [ j ] = = 2 ) {
cell * c1 = cw . at - > cmove ( j ) ;
c1 - > bardir = NOBARRIERS ;
setland ( c1 , l1 ) ;
}
continue ;
}
2021-07-11 09:48:33 +00:00
cellwalker bb2 = currentmap - > strafe ( cw , j ) ;
if ( bufferzone ( ) ) { bb2 + = rev ; bb2 + = wstep ; }
2019-03-10 17:37:09 +00:00
if ( bb2 . at - > bardir = = NODIR ) {
bb2 . at - > bardir = bb2 . spin ;
bb2 . at - > barleft = NOWALLSEP ;
bb2 . at - > barright = c - > barright ;
bb2 . at - > land = l1 ;
// bb2.at->item = itGold;
extendBarrier ( bb2 . at ) ;
}
}
}
bool built = false ;
2019-08-09 19:00:52 +00:00
EX bool buildBarrier3D ( cell * c , eLand l2 , int forced_dir ) {
2019-03-10 17:37:09 +00:00
if ( forced_dir = = NODIR ) {
2021-07-11 13:07:40 +00:00
for ( int t = 0 ; t < c - > type ; t + + ) if ( ( ! c - > move ( t ) | | c - > move ( t ) - > mpdist > c - > mpdist ) & & buildBarrier3D ( c , l2 , t ) ) return true ;
2019-03-10 17:37:09 +00:00
return false ;
}
2021-07-11 13:07:40 +00:00
bool bch = variation = = eVariation : : bch ;
2019-03-10 17:37:09 +00:00
cellwalker cw ( c , forced_dir ) ;
2021-07-11 13:07:40 +00:00
if ( bch ) {
auto & ad = currentmap - > dirdist ( cw ) ;
int a = 0 ;
for ( auto & dd : ad ) if ( dd = = 1 ) a + + ;
if ( a = = 6 ) return false ;
}
2021-07-11 09:48:33 +00:00
if ( bufferzone ( ) ) { cw + = wstep ; cw + = rev ; }
2019-03-10 17:37:09 +00:00
set < cell * > listed_cells = { cw . at } ;
2021-07-11 10:28:19 +00:00
vector < cellwalker > to_test { cw } ;
int tc = basic_tests ( ) ;
2019-03-10 17:37:09 +00:00
for ( int i = 0 ; i < isize ( to_test ) ; i + + ) {
auto bb = to_test [ i ] ;
if ( bb . at - > mpdist < BARLEV ) return false ;
if ( bb . cpeek ( ) - > mpdist < BARLEV ) return false ;
if ( bb . cpeek ( ) - > bardir ! = NODIR ) return false ;
2021-07-11 09:48:33 +00:00
if ( bufferzone ( ) & & ( bb + rev ) . cpeek ( ) - > mpdist < BARLEV ) return false ;
if ( bufferzone ( ) & & ( bb + rev ) . cpeek ( ) - > bardir ! = NODIR ) return false ;
2019-03-10 17:37:09 +00:00
if ( bb . at - > bardir ! = NODIR ) return false ;
2021-07-11 13:07:40 +00:00
auto & ad = currentmap - > dirdist ( bb ) ;
2021-07-11 10:28:19 +00:00
for ( int j = 0 ; j < bb . at - > type ; j + + ) {
if ( i < tc ) bb . at - > cmove ( j ) ;
2021-07-11 13:07:40 +00:00
if ( ! bb . at - > move ( j ) ) continue ;
if ( ! valid_dir ( ad , j , bb . at ) ) continue ;
cellwalker bb2 = currentmap - > strafe ( bb , j ) ;
if ( listed_cells . count ( bb2 . at ) ) continue ;
listed_cells . insert ( bb2 . at ) ;
to_test . push_back ( bb2 ) ;
2019-03-10 17:37:09 +00:00
}
}
for ( int i = 0 ; i < isize ( to_test ) ; i + + ) {
auto bb = to_test [ i ] ;
2021-07-11 09:48:33 +00:00
if ( bufferzone ( ) ) { bb . at - > bardir = NOBARRIERS ; setland ( bb . at , laBarrier ) ; bb + = rev ; bb + = wstep ; }
2019-03-10 17:37:09 +00:00
bb . at - > land = c - > land ;
bb . at - > bardir = bb . spin ;
bb . at - > barleft = NOWALLSEP ;
bb . at - > barright = l2 ;
extendBarrier ( bb . at ) ;
}
built = true ;
return true ;
}
2019-05-06 23:08:49 +00:00
# endif
2019-03-10 17:37:09 +00:00
2019-08-09 20:07:03 +00:00
EX bool buildBarrierNowall ( cell * c , eLand l2 , int forced_dir IS ( NODIR ) ) {
2021-07-30 22:52:59 +00:00
return general_barrier_build ( NOWALLSEP , c , l2 , forced_dir ) ;
2021-07-30 01:00:00 +00:00
}
2021-07-30 22:52:59 +00:00
EX bool general_barrier_build ( eLand ws , cell * c , eLand l2 , int forced_dir IS ( NODIR ) ) {
2017-10-08 10:10:40 +00:00
2019-10-10 11:09:31 +00:00
if ( S3 > = OINF ) { c - > land = l2 ; return true ; }
2019-05-06 23:08:49 +00:00
# if MAXMDIM >= 4
2019-03-09 22:56:12 +00:00
// 3D binary tilings create walls using their own methods
2019-12-14 11:05:01 +00:00
if ( WDIM = = 3 & & bt : : in ( ) ) return false ;
2019-03-09 22:56:12 +00:00
2019-05-08 16:33:08 +00:00
if ( WDIM = = 3 & & hyperbolic ) return buildBarrier3D ( c , l2 , forced_dir ) ;
2019-05-06 23:08:49 +00:00
# endif
2019-03-10 17:37:09 +00:00
2017-10-08 10:10:40 +00:00
if ( c - > land = = laNone ) {
2020-02-23 02:48:46 +00:00
printf ( " barrier nowall! [%p] \n " , hr : : voidp ( c ) ) ;
2017-10-08 10:10:40 +00:00
raiseBuggyGeneration ( c , " barrier nowall! " ) ;
return false ;
}
2018-04-04 15:59:24 +00:00
bool warpv = warped_version ( c - > land , l2 ) ;
2019-12-14 10:42:16 +00:00
if ( warpv & & ! arcm : : in ( ) & & ! pseudohept ( c ) ) return false ;
2018-04-04 15:59:24 +00:00
2020-01-18 15:03:32 +00:00
vector < int > ds = hrandom_permutation ( c - > type ) ;
2021-07-29 20:28:59 +00:00
eLand wsx = warpv ? laWarpCoast : laNone ;
eLand l1 = c - > land ;
if ( forced_dir ! = NODIR ) {
cellwalker cw ( c , forced_dir ) ;
2021-08-04 15:45:24 +00:00
general_barrier_check ( cw , 20 , - 1 , ws , l1 , l2 ) ;
general_barrier_check ( cw , 20 , 1 , ws , l1 , l2 ) ;
2021-07-29 20:28:59 +00:00
extendBarrier ( c ) ;
return true ;
}
2018-04-04 15:59:24 +00:00
2021-07-29 20:28:59 +00:00
for ( int d : ds ) {
if ( c - > move ( d ) & & c - > move ( d ) - > mpdist < = c - > mpdist ) continue ;
2021-08-04 15:45:24 +00:00
cellwalker cw ( c , d ) ;
if ( general_barrier_check ( cw , 20 , - 1 , ws , wsx , wsx ) & & general_barrier_check ( cw , 20 , 1 , ws , wsx , wsx ) ) {
general_barrier_check ( cw , 20 , - 1 , ws , l1 , l2 ) ;
general_barrier_check ( cw , 20 , 1 , ws , l1 , l2 ) ;
2017-10-08 10:10:40 +00:00
extendBarrier ( c ) ;
return true ;
}
}
2018-02-08 21:27:12 +00:00
return false ;
2017-10-08 10:10:40 +00:00
}
2018-06-10 23:58:31 +00:00
}