#RequireContext CGameCtnEditorPluginScriptHandler
#Include "MapUnits" as MapUnits
#Include "MathLib" as MathLib
Text CreateManialink()
{
declare MLText =
"""
""";
return MLText;
}
Void PB(Text BlockName, Integer X, Integer Y, Integer Z, ::CardinalDirections Dir)
{
PlaceBlock(BlockModels[BlockName], , Dir);
}
Void PlaceStart(
Integer X, Integer Z, Integer Y,
::CardinalDirections Dir,
Integer CoordYBaseSol)
{
PB("ArenaStart", 1+(X*2), CoordYBaseSol+(Y*2), 1+(Z*2), Dir);
}
Void PlaceFinish(
Integer X, Integer Z, Integer Y,
::CardinalDirections Dir,
Integer CoordYBaseSol)
{
PB("ArenaFinish", 1+(X*2), CoordYBaseSol+(Y*2), 1+(Z*2), Dir);
}
Void PlaceUp(
Integer X, Integer Z, Integer Y,
::CardinalDirections Dir,
Integer CoordYBaseSol)
{
declare Integer Xl = 1 + (X*2);
declare Integer Yl = CoordYBaseSol + (Y*2);
declare Integer Zl = 1 + (Z*2);
if (Dir == ::CardinalDirections::North) {
PB("ArenaSlopeStart", Xl, Yl, Zl+1, Dir);
PB("ArenaSlopeEnd", Xl, Yl+1, Zl+2, Dir);
}
if (Dir == ::CardinalDirections::East) {
PB("ArenaSlopeStart", Xl-1, Yl, Zl, Dir);
PB("ArenaSlopeEnd", Xl-2, Yl+1, Zl, Dir);
}
if (Dir == ::CardinalDirections::South) {
PB("ArenaSlopeStart", Xl, Yl, Zl-1, Dir);
PB("ArenaSlopeEnd", Xl, Yl+1, Zl-2, Dir);
}
if (Dir == ::CardinalDirections::West) {
PB("ArenaSlopeStart", Xl+1, Yl, Zl, Dir);
PB("ArenaSlopeEnd", Xl+2, Yl+1, Zl, Dir);
}
}
Void PlaceNESW(Integer X, Integer Y, Integer Z, Integer Val, Boolean Light)
{
declare Text TypeBloc = "ArenaSimpleBase";
if (Light) {
//TypeBloc = "ArenaFloodLightBaseCeiling";
}
PB(TypeBloc, X, Y, Z, ::CardinalDirections::North);
TypeBloc = "ArenaSimpleBaseNoPillar";
declare Boolean ValBitN = ((Val / 1 ) % 2) > 0;
declare Boolean ValBitE = ((Val / 2 ) % 2) > 0;
declare Boolean ValBitS = ((Val / 4 ) % 2) > 0;
declare Boolean ValBitW = ((Val / 8 ) % 2) > 0;
if (ValBitN) {
PB(TypeBloc, X, Y, Z+1, ::CardinalDirections::North);
}
if (ValBitE) {
PB(TypeBloc, X-1, Y, Z, ::CardinalDirections::East);
}
if (ValBitS) {
PB(TypeBloc, X, Y, Z-1, ::CardinalDirections::South);
}
if (ValBitW) {
PB(TypeBloc, X+1, Y, Z, ::CardinalDirections::West);
}
}
/////////////////////////////////////
// Draw the laby
Void DrawLaby(
Integer[] Tab,
Integer XSize, Integer ZSize, Integer YSize,
Integer CoordYBaseSol)
{
declare Text TxtDebug for ManialinkPage;
declare Integer XMax = XSize-1;
declare Integer ZMax = ZSize-1;
declare Integer YMax = YSize-1;
for(Y,0,YMax) {
TxtDebug = "Posing (" ^ Y ^ "/" ^ YMax ^ ")";
yield;
for(Z,0,ZMax) {
for(X,0,XMax) {
PlaceNESW(
1+(X*2), CoordYBaseSol + (Y*2), 1+(Z*2),
Tab[ X + (Z*XSize) + (Y*XSize*ZSize) ],
Y > 0);
}
}
}
yield;
}
/////////////////////////////////////
// Vérifie si un bloc est totalement vide
// ou le bloc est vide au sol = "Dirt"
Boolean EstVideOuDirt( Integer X, Integer Y, Integer Z )
{
declare CGameCtnBlock B = GetBlock();
if (B==Null) {
return True;
}
return (B.BlockModel.Id=="Dirt");
}
/////////////////////////////////////
// Vérifie si un bloc est totalement vide
Boolean EstVide( Integer X, Integer Y, Integer Z )
{
declare CGameCtnBlock B = GetBlock();
return (B==Null);
}
/////////////////////////////////////
// Return ValRetour if Block is of known type
Integer ValIf(
Integer X, Integer Y, Integer Z,
Integer ValRetour,
Text[] ListBlocsAcceptables)
{
declare CGameCtnBlock B = GetBlock();
if (B != Null) {
if ( ListBlocsAcceptables.exists(B.BlockModel.Id) ) {
return ValRetour;
}
}
return 0;
}
Void Pass_1_4( Integer CoordYBaseSol )
{
declare Text TxtDebug for ManialinkPage;
declare Text[] BlocsOk =
[ "ArenaSimpleBase", "ArenaSimpleBaseNoPillar", "ArenaFloodLightBaseCeiling" ];
declare Text[] BlocsErr =
[ "ArenaSlopeStart", "ArenaSlopeEnd",
"ArenaStart", "ArenaFinish",
"RoadRaceCornerOut", "RoadRaceToArena", "RoadRaceToArenaMirror" ];
declare Text[] BlocsDirt =
[ "Dirt" ];
declare Integer X;
declare Integer Y;
declare Integer Z;
declare Integer S;
declare Integer XMax = Map.Size[0]-2;
declare Integer YMax = Map.Size[1]-2;
declare Integer ZMax = Map.Size[2]-2;
/* (!!) Supra important : yield sert à mettre à jour
* l'affichage et à prendre en compte tous les changements
* sur la map (= pose de blocs etc.) et TANT QU'ON NE FAIT
* PAS "yield", des appels tels que GetBlock()
* reverront du *VIDE* même si on a posé des blocs.
* => Juste avant d'utiliser intensivement la détection
* de ce qu'il y a posé afin d'embellir le circuit,
* j'appelle "yield", pour m'assurer que tout est ok :
*/
yield;
//XMax = 10;
//YMax = CoordYBaseSol+2;
YMax = CoordYBaseSol+23;
//ZMax = 10;
// Coordonnées à tester via des bits activés :
//
// 1 2 4
// 8 16 32
// 64 128 256
//
// 512 = autre bloc non autorisé
Y = CoordYBaseSol;
while (Y <= YMax) {
TxtDebug = "Pass 1/4 (" ^ Y ^ "/" ^ YMax ^ ")";
yield;
Z = 1;
while (Z <= ZMax) {
X = 1;
while (X <= XMax) {
S =
ValIf( X+1, Y, Z+1, 1, BlocsOk) + ValIf( X , Y, Z+1, 2, BlocsOk) + ValIf( X-1, Y, Z+1, 4, BlocsOk) +
ValIf( X+1, Y, Z , 8, BlocsOk) + ValIf( X , Y, Z , 16, BlocsOk) + ValIf( X-1, Y, Z , 32, BlocsOk) +
ValIf( X+1, Y, Z-1, 64, BlocsOk) + ValIf( X , Y, Z-1, 128, BlocsOk) + ValIf( X-1, Y, Z-1, 256, BlocsOk) +
// (!) Astuce : on ajoute un bit qui fait qu'on ne
// pourra jamais rien poser car le chiffre sera trop
// élevé, s'il y a des blocs qu'on ne veut pas qui
// soient présents :
ValIf( X+1, Y , Z+1, 512, BlocsErr) + ValIf( X , Y, Z+1, 1024, BlocsErr) + ValIf( X-1, Y, Z+1, 2048, BlocsErr) +
ValIf( X+1, Y , Z , 4096, BlocsErr) + ValIf( X-1, Y, Z , 8192, BlocsErr) +
ValIf( X+1, Y , Z-1, 16384, BlocsErr) + ValIf( X , Y, Z-1, 32768, BlocsErr) + ValIf( X-1, Y, Z-1, 65536, BlocsErr) +
ValIf( X , Y+1, Z , 131072, BlocsErr);
//if ((S==18) && ((X!=1) || (Y>CoordYBaseSol) || (Z!=1)))
if (S==18) {
//
// 18 = Ces blocs :
//
// --- 2 ---
// --- 16 ---
// --- --- ---
//
PB("ArenaSimpleBase", X, Y+1, Z, ::CardinalDirections::North);
/* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
if (S==144) {
//
// 144 = Ces blocs :
//
// --- --- ---
// --- 16 ---
// --- 128 ---
//
PB("ArenaSimpleBase", X, Y+1, Z, ::CardinalDirections::North);
/* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
if (S==24) {
//
// 24 = Ces blocs :
//
// --- --- ---
// 8 16 ---
// --- --- ---
//
PB("ArenaSimpleBase", X, Y+1, Z, ::CardinalDirections::North);
/* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
if (S==48) {
//
// 48 = Ces blocs :
//
// --- --- ---
// --- 16 32
// --- --- ---
//
PB("ArenaSimpleBase", X, Y+1, Z, ::CardinalDirections::North);
/* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
X += 1;
}
Z += 1;
}
Y += 2;
}
yield;
}
Void Pass_2_4( Integer CoordYBaseSol )
{
declare Text TxtDebug for ManialinkPage;
declare Text[] BlocsOk =
[ "ArenaSimpleBase", "ArenaSimpleBaseNoPillar", "ArenaFloodLightBaseCeiling" ];
declare Text[] BlocsErr =
[ "ArenaSlopeStart", "ArenaSlopeEnd",
"ArenaStart", "ArenaFinish",
"RoadRaceCornerOut", "RoadRaceToArena", "RoadRaceToArenaMirror" ];
declare Text[] BlocsDirt =
[ "Dirt" ];
declare Integer X;
declare Integer Y;
declare Integer Z;
declare Integer S;
declare Integer XMax = Map.Size[0]-2;
declare Integer YMax = Map.Size[1]-2;
declare Integer ZMax = Map.Size[2]-2;
/* (!!) Supra important : voir commentaire sur yield dans Pass_1_4() */
yield;
//XMax = 10;
//YMax = CoordYBaseSol+2;
YMax = CoordYBaseSol+23;
//ZMax = 10;
// Coordonnées à tester via des bits activés :
//
// 1 2 4
// 8 16 32
// 64 128 256
//
// 512 = autre bloc non autorisé
Y = CoordYBaseSol;
while (Y <= YMax) {
TxtDebug = "Pass 2/4 (" ^ Y ^ "/" ^ YMax ^ ")";
yield;
Z = 1;
while (Z <= ZMax) {
X = 1;
while (X <= XMax) {
S =
ValIf( X+1, Y, Z+1, 1, BlocsOk) + ValIf( X , Y, Z+1, 2, BlocsOk) + ValIf( X-1, Y, Z+1, 4, BlocsOk) +
ValIf( X+1, Y, Z , 8, BlocsOk) + ValIf( X , Y, Z , 16, BlocsOk) + ValIf( X-1, Y, Z , 32, BlocsOk) +
ValIf( X+1, Y, Z-1, 64, BlocsOk) + ValIf( X , Y, Z-1, 128, BlocsOk) + ValIf( X-1, Y, Z-1, 256, BlocsOk) +
// (!) Astuce : on ajoute un bit qui fait qu'on ne
// pourra jamais rien poser car le chiffre sera trop
// élevé, s'il y a des blocs qu'on ne veut pas qui
// soient présents :
ValIf( X+1, Y , Z+1, 512, BlocsErr) + ValIf( X , Y, Z+1, 512, BlocsErr) + ValIf( X-1, Y, Z+1, 512, BlocsErr) +
ValIf( X+1, Y , Z , 512, BlocsErr) + ValIf( X-1, Y, Z , 512, BlocsErr) +
ValIf( X+1, Y , Z-1, 512, BlocsErr) + ValIf( X , Y, Z-1, 512, BlocsErr) + ValIf( X-1, Y, Z-1, 512, BlocsErr) +
ValIf( X , Y+1, Z+1, 512, BlocsErr) +
ValIf( X+1, Y+1 , Z , 512, BlocsErr) + ValIf( X , Y+1, Z , 512, BlocsErr) + ValIf( X-1, Y+1, Z , 512, BlocsErr) +
ValIf( X , Y+1, Z-1, 512, BlocsErr);
if (S==50) {
//
// 50 = Ces blocs :
//
// --- 2 ---
// --- 16 32
// --- --- ---
//
// Blocks pour le nord :
RemoveBlock();
RemoveBlock();
// Blocks pour l'est :
RemoveBlock();
RemoveBlock();
PB("RoadRaceCornerOut", X, Y+1, Z, ::CardinalDirections::North);
PB("RoadRaceToArenaMirror", X, Y, Z+1, ::CardinalDirections::South);
PB("RoadRaceToArena", X-1, Y, Z, ::CardinalDirections::West);
/* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
//if ((S==2dd6) && ((X!=1) || (Y!=CoordYBaseSol) || (Z!=1)))
if (S==26) {
//
// 26 = Ces blocs :
//
// --- 2 ---
// 8 16 ---
// --- --- ---
//
// Blocks pour le nord :
RemoveBlock();
RemoveBlock();
// Blocks pour l'ouest :
RemoveBlock();
RemoveBlock();
PB("RoadRaceCornerOut", X, Y+1, Z, ::CardinalDirections::West);
PB("RoadRaceToArena", X, Y, Z+1, ::CardinalDirections::South);
PB("RoadRaceToArenaMirror", X+1, Y, Z, ::CardinalDirections::East);
/* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
if (S==152) {
//
// 152 = Ces blocs :
//
// --- --- ---
// 8 16 ---
// --- 128 ---
//
// Blocks pour le sud :
RemoveBlock();
RemoveBlock();
// Blocks pour l'ouest :
RemoveBlock();
RemoveBlock();
PB("RoadRaceCornerOut", X, Y+1, Z, ::CardinalDirections::South);
PB("RoadRaceToArena", X+1, Y, Z, ::CardinalDirections::East);
PB("RoadRaceToArenaMirror", X, Y, Z-1, ::CardinalDirections::North);
/* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
if (S==176) {
//
// 176 = Ces blocs :
//
// --- --- ---
// --- 16 32
// --- 128 ---
//
// Blocks pour le sud :
RemoveBlock();
RemoveBlock();
// Blocks pour l'est :
RemoveBlock();
RemoveBlock();
RemoveBlock();
PB("RoadRaceCornerOut", X, Y+1, Z, ::CardinalDirections::East);
PB("RoadRaceToArenaMirror", X-1, Y, Z, ::CardinalDirections::West);
PB("RoadRaceToArena", X, Y, Z-1, ::CardinalDirections::North);
/* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
X += 1;
}
Z += 1;
}
Y += 2;
}
yield;
}
Void Pass_3_4( Integer CoordYBaseSol )
{
declare Text TxtDebug for ManialinkPage;
TxtDebug = "Pass 3/4";
declare Text[] BlocsOk =
[ "ArenaSimpleBase", "ArenaSimpleBaseNoPillar", "ArenaFloodLightBaseCeiling" ];
declare Text[] BlocToArena =
[ "RoadRaceToArena" ];
declare Text[] BlocToArenaMirror =
[ "RoadRaceToArenaMirror" ];
declare Boolean Reloop;
declare Integer X;
declare Integer Y;
declare Integer Z;
declare Integer S;
declare Integer XMax = Map.Size[0]-2;
declare Integer YMax = Map.Size[1]-2;
declare Integer ZMax = Map.Size[2]-2;
/* (!!) Supra important : voir commentaire sur yield dans Pass_1_4() */
yield;
//XMax = 10;
//YMax = CoordYBaseSol+2;
YMax = CoordYBaseSol+23;
//ZMax = 10;
Reloop = True;
while (Reloop)
{
Reloop = False;
Y = CoordYBaseSol;
while (Y <= YMax) {
TxtDebug = "Pass 3/4 (" ^ Y ^ "/" ^ YMax ^ ")";
yield;
Z = 1;
while (Z <= ZMax) {
X = 1;
while (X <= XMax) {
if ( (ValIf( X-1, Y, Z, 1, BlocToArenaMirror)==1) &&
(ValIf( X, Y, Z, 1, BlocsOk)==1) &&
(ValIf( X, Y, Z-1, 1, BlocsOk)==1) &&
EstVide( X+1, Y, Z) &&
EstVide( X, Y, Z+1) ) {
// Portion de route :
// "o" = nouvelle, "+" = ancienne :
// +
// +
// oo+++
// o
// o
//
// Retirer BlocsToArena
RemoveBlock();
//// Blocks pour BlocsToArena :
RemoveBlock();
RemoveBlock();
PB("RoadRaceStraight", X-1, Y+1, Z, ::CardinalDirections::North);
PB("RoadRaceCornerIn", X, Y+1, Z, ::CardinalDirections::North);
PB("RoadRaceToArenaMirror", X, Y, Z-1, ::CardinalDirections::North);
Reloop = True;
///* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
if ( (ValIf( X, Y+1, Z-1, 1, BlocToArenaMirror)==1) &&
(ValIf( X, Y, Z, 1, BlocsOk)==1) &&
(ValIf( X+1, Y, Z, 1, BlocsOk)==1) &&
EstVide( X, Y, Z+1) &&
EstVide( X-1, Y, Z) ) {
// Portion de route :
// "o" = nouvelle, "+" = ancienne :
//
// ooo
// o
// +
// +++
//
// Retirer BlocsToArena
RemoveBlock();
////// Blocks pour BlocsToArena :
RemoveBlock();
RemoveBlock();
PB("RoadRaceStraight", X, Y+1, Z-1, ::CardinalDirections::East);
PB("RoadRaceCornerIn", X, Y+1, Z, ::CardinalDirections::East);
PB("RoadRaceToArenaMirror", X+1, Y, Z, ::CardinalDirections::East);
/////* (!) Voir gros commentaire sur yield juste avant cette boucle : */
Reloop = True;
yield;
}
if ( (ValIf( X, Y+1, Z-1, 1, BlocToArena)==1) &&
(ValIf( X, Y, Z, 1, BlocsOk)==1) &&
(ValIf( X-1, Y, Z, 1, BlocsOk)==1) &&
EstVide( X, Y, Z+1) &&
EstVide( X+1, Y, Z) ) {
// Portion de route :
// "o" = nouvelle, "+" = ancienne :
//
// ooo
// o
// +
// +++
//
// Retirer BlocsToArena
RemoveBlock();
////// Blocks pour BlocsToArena :
RemoveBlock();
RemoveBlock();
PB("RoadRaceStraight", X, Y+1, Z-1, ::CardinalDirections::West);
PB("RoadRaceCornerIn", X, Y+1, Z, ::CardinalDirections::North);
PB("RoadRaceToArena", X-1, Y, Z, ::CardinalDirections::West);
///////* (!) Voir gros commentaire sur yield juste avant cette boucle : */
Reloop = True;
yield;
}
if ( (ValIf( X, Y+1, Z-1, 1, BlocToArena)==1) &&
(ValIf( X-1, Y+1, Z, 1, BlocToArenaMirror)==1) &&
(ValIf( X, Y, Z, 1, BlocsOk)==1) &&
EstVide( X, Y , Z+1) &&
EstVide( X, Y+1, Z) &&
EstVide( X+1, Y, Z) ) {
// Portion de route :
// "o" = nouvelle, "+" = ancienne :
//
// oo++
// o +
// +
// ++
//
// Retirer BlocsToArena
RemoveBlock();
RemoveBlock();
PB("RoadRaceStraight", X-1, Y+1, Z, ::CardinalDirections::North);
PB("RoadRaceCornerIn", X, Y+1, Z, ::CardinalDirections::North);
PB("RoadRaceStraight", X, Y+1, Z-1, ::CardinalDirections::West);
///////* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
if ( (ValIf( X, Y+1, Z-1, 1, BlocToArenaMirror)==1) &&
(ValIf( X-1, Y, Z, 1, BlocsOk)==1) &&
(ValIf( X, Y, Z, 1, BlocsOk)==1) &&
EstVide( X, Y , Z+1) &&
EstVide( X, Y+1, Z) &&
EstVide( X+1, Y, Z) ) {
// Portion de route :
// "o" = nouvelle, "+" = ancienne :
//
// oo
// o
// +
// ++
//
//// Retirer BlocsToArena
RemoveBlock();
RemoveBlock();
PB("RoadRaceToArenaMirror", X-1, Y, Z, ::CardinalDirections::West);
PB("RoadRaceCornerOut", X, Y+1, Z, ::CardinalDirections::East);
PB("RoadRaceStraight", X, Y+1, Z-1, ::CardinalDirections::East);
/////////* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
if ( (ValIf( X, Y+1, Z, 1, BlocToArena)==1) &&
(ValIf( X-1, Y, Z, 1, BlocsOk)==1) &&
EstVide( X-1, Y , Z+1) &&
EstVide( X-1, Y , Z-1) &&
EstVide( X-1, Y+1, Z ) ) {
// Portion de route :
// "o" = nouvelle, "+" = ancienne :
//
// +++oo
//
//
// Retirer BlocsToArena
RemoveBlock();
RemoveBlock();
PB("RoadRaceStraight", X , Y+1, Z, ::CardinalDirections::North);
PB("RoadRaceToArena", X-1, Y, Z, ::CardinalDirections::West);
Reloop = True;
/////////* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
if ( (ValIf( X, Y+1, Z, 1, BlocToArena)==1) &&
/* Milieu vide : */
(ValIf( X, Y, Z-1, 1, BlocsOk)==1) &&
EstVide( X-1, Y, Z-1) &&
EstVide( X+1, Y, Z-1) &&
EstVide( X , Y+1, Z-1) ) {
// Portion de route :
// "o" = nouvelle, "+" = ancienne :
//
// +
// +
// o
// o
//
// Retirer BlocsToArena
RemoveBlock();
RemoveBlock();
PB("RoadRaceStraight", X, Y+1, Z, ::CardinalDirections::East);
PB("RoadRaceToArena", X, Y, Z-1, ::CardinalDirections::North);
Reloop = True;
/////////* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
//if ( (ValIf( X, Y+1, Z, 1, BlocToArena)==1) &&
// (ValIf( X, Y, Z-1, 1, BlocsOk)==1) &&
// EstVide( X+1, Y , Z-1) /* &&
// EstVide( X-1, Y , Z-1) */) {
// log("X : " ^ X ^ ", Y : " ^ Y ^ ", Z : " ^ Z);
//}
if ( (ValIf( X, Y+1, Z, 1, BlocToArena)==1) &&
(ValIf( X, Y+1, Z-1, 1, BlocToArenaMirror)==1) ) {
// Portion de route :
// "o" = nouvelle, "+" = ancienne :
//
// +
// o
// +
//
// Retirer BlocsToArena
RemoveBlock();
RemoveBlock();
PB("RoadRaceStraight", X, Y+1, Z, ::CardinalDirections::East);
PB("RoadRaceStraight", X, Y+1, Z-1, ::CardinalDirections::East);
/////////* (!) Voir gros commentaire sur yield juste avant cette boucle : */
yield;
}
X += 1;
}
Z += 1;
}
Y += 2;
}
}
yield;
//declare CGameCtnBlock B;
//B = GetBlock(<13,17,2>);
//if (B != Null) {
// log(B.BlockModel.Id);
//}
}
Void Pass_4_4( Integer CoordYBaseSol )
{
declare Text TxtDebug for ManialinkPage;
TxtDebug = "Pass 4/4";
declare Text[] BlocsOk =
[ "ArenaSimpleBase", "ArenaSimpleBaseNoPillar", "ArenaFloodLightBaseCeiling" ];
declare Text[] BlocsRoadRaceStraight =
[ "RoadRaceStraight" ];
declare Text[] BlocToArena =
[ "RoadRaceToArena" ];
declare Text[] BlocToArenaMirror =
[ "RoadRaceToArenaMirror" ];
declare Integer X;
declare Integer Y;
declare Integer Z;
declare Integer S;
declare Integer XMax = Map.Size[0]-2;
declare Integer YMax = Map.Size[1]-2;
declare Integer ZMax = Map.Size[2]-2;
declare Integer XDeb;
declare Integer ZDeb;
declare Integer XFin;
declare Integer ZFin;
/* (!!) Supra important : voir commentaire sur yield dans Pass_1_4() */
yield;
/* Recherche des lignes dont la longueur >= 4 */
//XMax = 10;
//YMax = CoordYBaseSol+2;
YMax = CoordYBaseSol+23;
//ZMax = 10;
Y = CoordYBaseSol;
while (Y <= YMax) {
TxtDebug = "Pass 4/4 (" ^ Y ^ "/" ^ YMax ^ ")";
yield;
Z = 1;
while (Z <= ZMax) {
X = 1;
while (X <= XMax) {
/* Test Nord Sud pour mettre le tunnel */
if ( (ValIf( X, Y+1, Z, 1, BlocsRoadRaceStraight)==1) &&
(ValIf( X, Y+1, Z+1, 1, BlocsRoadRaceStraight)==1) ) {
XDeb = X;
ZDeb = Z;
Z += 1;
while ( ValIf( X, Y+1, Z, 1, BlocsRoadRaceStraight)==1) {
Z += 1;
}
/* Si on est sorti = dernier pas valide = faire moins un : */
Z -= 1;
XFin = X;
ZFin = Z;
if ((ZFin-ZDeb)>=3) {
for(Z,ZDeb,ZFin) {
RemoveBlock( );
}
PB("RoadRaceToRoadMainA", XDeb, Y+1, ZDeb, ::CardinalDirections::West);
PB("ArenaTunnelBanktoRoad", XDeb, Y+1, ZDeb+1, ::CardinalDirections::South);
PB("ArenaTunnelBanktoRoad", XFin, Y+1, ZFin-1, ::CardinalDirections::North);
PB("RoadRaceToRoadMainMirrorA", XFin, Y+1, ZFin, ::CardinalDirections::East);
for(Z,ZDeb+2,ZFin-2) {
PB("ArenaTunnelStraight", X, Y+1, Z, ::CardinalDirections::North);
}
}
/* Reprendre là où on en était : */
X = XDeb;
Z = ZDeb;
yield;
}
/* Test Est Ouest pour mettre le tunnel */
if ( (ValIf( X, Y+1, Z, 1, BlocsRoadRaceStraight)==1) &&
(ValIf( X+1, Y+1, Z, 1, BlocsRoadRaceStraight)==1) ) {
XDeb = X;
ZDeb = Z;
X += 1;
while (ValIf( X, Y+1, Z, 1, BlocsRoadRaceStraight)==1) {
X += 1;
}
/* Si on est sorti = dernier pas valide = faire moins un : */
X -= 1;
XFin = X;
ZFin = Z;
if ((XFin-XDeb)>=3) {
for(X,XDeb,XFin) {
RemoveBlock( );
}
PB("RoadRaceToRoadMainA", XDeb, Y+1, ZDeb, ::CardinalDirections::South);
PB("ArenaTunnelBanktoRoad", XDeb+1, Y+1, ZDeb, ::CardinalDirections::East);
PB("ArenaTunnelBanktoRoad", XFin-1, Y+1, ZFin, ::CardinalDirections::West);
PB("RoadRaceToRoadMainMirrorA", XFin, Y+1, ZFin, ::CardinalDirections::North);
for(X,XDeb+2,XFin-2) {
PB("ArenaTunnelStraight", X, Y+1, ZFin, ::CardinalDirections::East);
}
}
/* Reprendre là où on en était : */
X = XDeb;
Z = ZDeb;
yield;
}
/* Recherche de lignes droites seules gauche-droite */
if ( /* Centre libre */
(ValIf( X, Y, Z, 1, BlocsOk)==1) &&
/* Au dessus il n'y a rien */
EstVide( X, Y+1, Z) &&
/* Des deux côtés c'est vide : */
EstVideOuDirt( X, Y, Z-1) &&
EstVideOuDirt( X, Y, Z+1) ) {
XDeb = X;
ZDeb = Z;
X += 1;
while (
/* Centre libre */
(ValIf( X, Y, Z, 1, BlocsOk)==1) &&
/* Au dessus il n'y a rien */
EstVide( X, Y+1, Z) &&
/* Des deux côtés c'est vide : */
EstVideOuDirt( X, Y, Z-1) &&
EstVideOuDirt( X, Y, Z+1) ) {
X += 1;
}
/* Si on est sorti = dernier pas valide = faire moins un : */
X -= 1;
XFin = X;
ZFin = Z;
if ((XFin-XDeb)>=2) {
for(X,XDeb,XFin) {
RemoveBlock( );
}
PB("ArenaTunnelToArena", XDeb, Y, ZDeb, ::CardinalDirections::West);
PB("ArenaTunnelToArena", XFin, Y, ZDeb, ::CardinalDirections::East);
for(X,XDeb+1,XFin-1) {
PB("ArenaSimpleBase", X, Y+1, ZFin, ::CardinalDirections::East);
PB("ArenaTunnelStraight", X, Y, ZFin, ::CardinalDirections::East);
}
}
/* Reprendre là où on en était : */
X = XDeb;
Z = ZDeb;
yield;
}
/* Recherche de lignes droites seules haut-bas */
if ( /* Centre libre */
(ValIf( X, Y, Z, 1, BlocsOk)==1) &&
/* Au dessus il n'y a rien */
EstVide( X, Y+1, Z) &&
/* Des deux côtés c'est vide : */
EstVideOuDirt( X-1, Y, Z) &&
EstVideOuDirt( X+1, Y, Z) ) {
XDeb = X;
ZDeb = Z;
Z += 1;
while (
/* Centre libre */
(ValIf( X, Y, Z, 1, BlocsOk)==1) &&
/* Au dessus il n'y a rien */
EstVide( X, Y+1, Z) &&
/* Des deux côtés c'est vide : */
EstVideOuDirt( X-1, Y, Z) &&
EstVideOuDirt( X+1, Y, Z) ) {
Z += 1;
}
/* Si on est sorti = dernier pas valide = faire moins un : */
Z -= 1;
XFin = X;
ZFin = Z;
if ((ZFin-ZDeb)>=2) {
log(XDeb ^ "/" ^ (Y-CoordYBaseSol) ^ "/" ^ ZDeb ^ " <=> " ^ XFin ^ "/" ^ ZFin ^ "==> " ^ ZFin-ZDeb );
for(Z,ZDeb,ZFin) {
RemoveBlock( );
}
PB("ArenaTunnelToArena", XDeb, Y, ZDeb, ::CardinalDirections::North);
PB("ArenaTunnelToArena", XDeb, Y, ZFin, ::CardinalDirections::South);
for(Z,ZDeb+1,ZFin-1) {
PB("ArenaSimpleBase", XFin, Y+1, Z, ::CardinalDirections::North);
PB("ArenaTunnelStraight", XFin, Y, Z, ::CardinalDirections::North);
}
}
/* Reprendre là où on en était : */
X = XDeb;
Z = ZDeb;
yield;
}
X += 1;
}
Z += 1;
}
Y += 2;
}
yield;
}
/////////////////////////////////////
// Place all blocks
Void PlaceBlocks()
{
declare Text TxtDebug for ManialinkPage;
declare CBlockModel BMArenaSimpleBase;
BMArenaSimpleBase <=> BlockModels["ArenaSimpleBase"];
RemoveAllBlocksAndTerrain();
ComputeShadows();
yield;
// Calculer la hauteur du sol = la hauteur minimale pour
// poser le bloc :
declare CoordYBaseSol = GetBlockGroundHeight(
BMArenaSimpleBase, 19, 19, ::CardinalDirections::East);
PB("ArenaStart", 1, CoordYBaseSol, 0, ::CardinalDirections::North);
PB("ArenaFinish", 0, CoordYBaseSol+22, 7, ::CardinalDirections::East);
// Up <=> Down slopes :
PlaceUp( 1, 2, 0, ::CardinalDirections::West, CoordYBaseSol);
PlaceUp( 1, 1, 1, ::CardinalDirections::West, CoordYBaseSol);
PlaceUp( 1, 2, 2, ::CardinalDirections::West, CoordYBaseSol);
PlaceUp( 1, 1, 3, ::CardinalDirections::North, CoordYBaseSol);
PlaceUp( 2, 1, 4, ::CardinalDirections::North, CoordYBaseSol);
PlaceUp( 1, 1, 5, ::CardinalDirections::North, CoordYBaseSol);
PlaceUp( 2, 1, 6, ::CardinalDirections::East, CoordYBaseSol);
PlaceUp( 2, 2, 7, ::CardinalDirections::East, CoordYBaseSol);
PlaceUp( 2, 1, 8, ::CardinalDirections::North, CoordYBaseSol);
PlaceUp( 1, 1, 9, ::CardinalDirections::North, CoordYBaseSol);
PlaceUp( 2, 1, 10, ::CardinalDirections::North, CoordYBaseSol);
DrawLaby(
[
// Etage 0
8, 11, 11, 2,
8, 7, 4, 1,
9, 6, 9, 7,
12, 10, 6, 4,
// Etage 1
1, 9, 11, 2,
13, 7, 12, 3,
4, 5, 8, 6,
8, 14, 10, 2,
// Etage 2
9, 10, 10, 2,
13, 2, 8, 3,
13, 3, 1, 5,
4, 12, 14, 6,
// Etage 3
9, 10, 2, 1,
13, 10, 10, 6,
5, 1, 8, 3,
12, 14, 10, 6,
// Etage 4
8, 3, 9, 3,
9, 14, 6, 5,
5, 1, 9, 7,
4, 12, 6, 4,
// Etage 5
8, 11, 11, 2,
8, 6, 12, 3,
8, 3, 1, 5,
8, 14, 14, 6,
// Etage 6
8, 11, 3, 1,
9, 6, 12, 7,
5, 1, 8, 7,
12, 6, 8, 6,
// Etage 7
9, 2, 8, 3,
13, 2, 1, 5,
13, 2, 12, 7,
12, 10, 10, 6,
// Etage 8
8, 3, 8, 3,
8, 14, 10, 7,
9, 2, 9, 7,
12, 10, 6, 4,
// Etage 9
9, 10, 10, 2,
12, 10, 10, 3,
9, 2, 1, 5,
12, 10, 14, 6,
// Etage 10
1, 9, 2, 1,
13, 14, 10, 6,
5, 1, 8, 3,
12, 14, 10, 6,
// Etage 11
8, 11, 11, 3,
8, 7, 4, 5,
1, 4, 1, 5,
12, 10, 14, 6
],
4,4,12,
CoordYBaseSol
);
Pass_1_4( CoordYBaseSol );
Pass_2_4( CoordYBaseSol );
Pass_3_4( CoordYBaseSol );
Pass_4_4( CoordYBaseSol );
log( "Done !");
TxtDebug = "Done !";
}
/////////////////////////////////////
// Main
main()
{
declare Integer NbBlocks for ManialinkPage;
declare Boolean StartPlacing for ManialinkPage;
ManialinkText = CreateManialink();
while(True) {
yield;
if(StartPlacing) {
PlaceBlocks();
StartPlacing = False;
}
}
}
/////////////////////////////////////