Warcraft III resources & community, 2003–2006 · archived

My Random Map Scripts

4 posts
#1

My Random Map Scripts

Hi, I have created a script which allows you to create a good looking random forest.

To use this script you need an Integer DataSize which have a Value like this ((2^X)+1).

Then you need a Array "Wert" (German for Value) of type Integer with the size DataSize*DataSize. This Array and the following function will be used to create a 2D Array:


function GetValue takes integer X, integer Y returns integer
  return udg_Wert[(X + (Y*(udg_DataSize-1)))]
endfunction


Ok, before you do anything else you have to fill this Array with Random Values between 1 and 1000.

Tigger:

For each (Integer A) from 0 to 1088, do (Actions)
        Set Wert[(Integer A)] = (Random integer number between 1 and 1000)


The next part is optional. I want to have no forest in the middle of my Map. So I use this (by an other programm generatet)function to change the upper Values:


function Lichtung takes integer X, integer Y returns nothing
// gernerierte Jass-Funktion
set udg_Wert[(X-2) + ( (Y+0) * (udg_DataSize-1) )] = 0
set udg_Wert[(X-1) + ( (Y-1) * (udg_DataSize-1) )] = 0
set udg_Wert[(X-1) + ( (Y+0) * (udg_DataSize-1) )] = 0
set udg_Wert[(X-1) + ( (Y+1) * (udg_DataSize-1) )] = 0
set udg_Wert[(X+0) + ( (Y-2) * (udg_DataSize-1) )] = 0
set udg_Wert[(X+0) + ( (Y-1) * (udg_DataSize-1) )] = 0
set udg_Wert[(X+0) + ( (Y+0) * (udg_DataSize-1) )] = 0
set udg_Wert[(X+0) + ( (Y+1) * (udg_DataSize-1) )] = 0
set udg_Wert[(X+0) + ( (Y+2) * (udg_DataSize-1) )] = 0
set udg_Wert[(X+1) + ( (Y-1) * (udg_DataSize-1) )] = 0
set udg_Wert[(X+1) + ( (Y+0) * (udg_DataSize-1) )] = 0
set udg_Wert[(X+1) + ( (Y+1) * (udg_DataSize-1) )] = 0
set udg_Wert[(X+2) + ( (Y+0) * (udg_DataSize-1) )] = 0
// Rand Bereich
set udg_Wert[(X-2) + ( (Y-2) * (udg_DataSize-1) )] = GetRandomInt(1, 500)
set udg_Wert[(X-2) + ( (Y-1) * (udg_DataSize-1) )] = GetRandomInt(1, 500)
set udg_Wert[(X-2) + ( (Y+1) * (udg_DataSize-1) )] = GetRandomInt(1, 500)
set udg_Wert[(X-2) + ( (Y+2) * (udg_DataSize-1) )] = GetRandomInt(1, 500)
set udg_Wert[(X-1) + ( (Y-2) * (udg_DataSize-1) )] = GetRandomInt(1, 500)
set udg_Wert[(X-1) + ( (Y+2) * (udg_DataSize-1) )] = GetRandomInt(1, 500)
set udg_Wert[(X+1) + ( (Y-2) * (udg_DataSize-1) )] = GetRandomInt(1, 500)
set udg_Wert[(X+1) + ( (Y+2) * (udg_DataSize-1) )] = GetRandomInt(1, 500)
set udg_Wert[(X+2) + ( (Y-2) * (udg_DataSize-1) )] = GetRandomInt(1, 500)
set udg_Wert[(X+2) + ( (Y-1) * (udg_DataSize-1) )] = GetRandomInt(1, 500)
set udg_Wert[(X+2) + ( (Y+1) * (udg_DataSize-1) )] = GetRandomInt(1, 500)
set udg_Wert[(X+2) + ( (Y+2) * (udg_DataSize-1) )] = GetRandomInt(1, 500)
endfunction


My DataSize Value was 65 so i called the function with:

call Lichtung(33,33)


Secondly we need a function witch replace the slow sine and cosine function.
An Integer Array called Interpolation with the size (DataSize-1) and a Integer Interpolation_Max with the Value 1000 will be used by our function.

You have to fill this Array with the Values in a tigger like this:


For each (Integer A) from 0 to 63, do (Actions)
        Set Interpolation[(Integer A)] = (Integer(((1000.00 / 2.00) x ((Cos((((Real((Integer A))) x 180.00) / (Real(Size))))) + 1.00))))


We need this Array Value for the following function:


function Interpoliere takes integer Wert1, integer Wert2, integer Nr, integer Von returns integer
  local integer Ergebnis1
  local integer Ergebnis2
  // Geprüft
  set Ergebnis1 = ( ( Wert1 * udg_Interpolation[( Nr * ( udg_Size / Von ) )] ) / udg_Interpolation_Max )
  set Ergebnis2 = ( ( Wert2 * (udg_Interpolation_Max - udg_Interpolation[( Nr * ( udg_Size / Von ) )] ) ) / udg_Interpolation_Max )

 // call DisplayTextToForce( GetPlayersAll(),"-----------------------")
 // call DisplayTextToForce( GetPlayersAll(),"Wert1:    " + I2S(Wert1))
 // call DisplayTextToForce( GetPlayersAll(),"Wert2:    " + I2S(Wert2))
 // call DisplayTextToForce( GetPlayersAll(),"Nr:       " + I2S(Nr))
 // call DisplayTextToForce( GetPlayersAll(),"Von:      " + I2S(Von))
 // call DisplayTextToForce( GetPlayersAll(),"Ergebnis1:" + I2S(Ergebnis1))
 // call DisplayTextToForce( GetPlayersAll(),"Ergebnis2:" + I2S(Ergebnis2))
 // call DisplayTextToForce( GetPlayersAll(),"Ges:" + I2S(Ergebnis1 + Ergebnis2))
 // call DisplayTextToForce( GetPlayersAll(),"-----------------------")

  return (Ergebnis1 + Ergebnis2)
endfunction


Now we have everything to calculate (german Berechne) with the following function values wicht says us what we have to place on the position X, Y.


function Berechne takes integer X, integer Y returns integer
  local integer Ergebnis
  local integer WertX0
  local integer WertX1
  local integer I_X0
  local integer I_X1
  local integer I_Y0
  local integer I_Y1
  local integer Level
  local integer Field_Size
  local integer Field_DataSize
  local integer Max
  //-----------------------

  set Level = 2
  set Max = 500

  set Field_Size = (udg_Size / Level)
  
  set Field_DataSize = ((udg_DataSize-1) / Level)

  set I_X0 = Field_DataSize*(X / Field_Size) // ok
  set I_X1 = I_X0 + Field_DataSize           // ok
  set I_Y0 = Field_DataSize*(Y / Field_Size) // ok
  set I_Y1 = I_Y0 + Field_DataSize           // ok

  //call DisplayTextToForce( GetPlayersAll(), ((("P1( " + I2S(I_X0)) + (" / " + I2S(I_Y0))+ " ) P2( ")+ (I2S(I_X1) + (" / " + (I2S(I_Y1) + " )")))))

  
  set WertX0 = Interpoliere(GetValue(I_X0,I_Y0),GetValue(I_X1,I_Y0),ModuloInteger(X , Field_Size),Field_Size)
  set WertX1 = Interpoliere(GetValue(I_X0,I_Y1),GetValue(I_X1,I_Y1),ModuloInteger(X , Field_Size),Field_Size)

  set Ergebnis = (Interpoliere(WertX0,WertX1,ModuloInteger(Y , Field_Size),Field_Size) / 2) 

  //--------------------------------------

  set Level = 4
  set Max = Max + 1000

  set Field_Size = (udg_Size / Level)
  
  set Field_DataSize = ((udg_DataSize-1) / Level)

  set I_X0 = Field_DataSize*(X / Field_Size) // ok
  set I_X1 = I_X0 + Field_DataSize           // ok
  set I_Y0 = Field_DataSize*(Y / Field_Size) // ok
  set I_Y1 = I_Y0 + Field_DataSize           // ok

  //call DisplayTextToForce( GetPlayersAll(), ((("P1( " + I2S(I_X0)) + (" / " + I2S(I_Y0))+ " ) P2( ")+ (I2S(I_X1) + (" / " + (I2S(I_Y1) + " )")))))

  
  set WertX0 = Interpoliere(GetValue(I_X0,I_Y0),GetValue(I_X1,I_Y0),ModuloInteger(X , Field_Size),Field_Size)
  set WertX1 = Interpoliere(GetValue(I_X0,I_Y1),GetValue(I_X1,I_Y1),ModuloInteger(X , Field_Size),Field_Size)

  set Ergebnis = Ergebnis + Interpoliere(WertX0,WertX1,ModuloInteger(Y , Field_Size),Field_Size) 

  //--------------------------------------

  set Level = 16
  set Max = Max + 1000

  set Field_Size = (udg_Size / Level)
  
  set Field_DataSize = ((udg_DataSize-1) / Level)

  set I_X0 = Field_DataSize*(X / Field_Size) // ok
  set I_X1 = I_X0 + Field_DataSize           // ok
  set I_Y0 = Field_DataSize*(Y / Field_Size) // ok
  set I_Y1 = I_Y0 + Field_DataSize           // ok

  //call DisplayTextToForce( GetPlayersAll(), ((("P1( " + I2S(I_X0)) + (" / " + I2S(I_Y0))+ " ) P2( ")+ (I2S(I_X1) + (" / " + (I2S(I_Y1) + " )")))))

  
  set WertX0 = Interpoliere(GetValue(I_X0,I_Y0),GetValue(I_X1,I_Y0),ModuloInteger(X , Field_Size),Field_Size)
  set WertX1 = Interpoliere(GetValue(I_X0,I_Y1),GetValue(I_X1,I_Y1),ModuloInteger(X , Field_Size),Field_Size)

  set Ergebnis = Ergebnis + Interpoliere(WertX0,WertX1,ModuloInteger(Y , Field_Size),Field_Size) 


  //--------------------------------------

  set Level = 32
  set Max = Max + 2000

  set Field_Size = (udg_Size / Level)
  
  set Field_DataSize = ((udg_DataSize-1) / Level)

  set I_X0 = Field_DataSize*(X / Field_Size) // ok
  set I_X1 = I_X0 + Field_DataSize           // ok
  set I_Y0 = Field_DataSize*(Y / Field_Size) // ok
  set I_Y1 = I_Y0 + Field_DataSize           // ok

  //call DisplayTextToForce( GetPlayersAll(), ((("P1( " + I2S(I_X0)) + (" / " + I2S(I_Y0))+ " ) P2( ")+ (I2S(I_X1) + (" / " + (I2S(I_Y1) + " )")))))

  
  set WertX0 = Interpoliere(GetValue(I_X0,I_Y0),GetValue(I_X1,I_Y0),ModuloInteger(X , Field_Size),Field_Size)
  set WertX1 = Interpoliere(GetValue(I_X0,I_Y1),GetValue(I_X1,I_Y1),ModuloInteger(X , Field_Size),Field_Size)

  set Ergebnis = Ergebnis + (2*Interpoliere(WertX0,WertX1,ModuloInteger(Y , Field_Size),Field_Size)) 

 
  return (Ergebnis*1000)/Max
endfunction


These function works with "Perlin noise" i may will explain later how it works.

These Valus which you get from the function Berechne have a Range between 0 and 1000. You can use this to decide if you want to create a Tree on the position (X,Y) or not.(higher than 500 -> create tree near this position) You also can change the kind of ground at this position.

like this in a loop:

    Set ErstellugnsOrt = ((Center of Nullpunkt <gen>) offset by (((140.00 x (Real(SpalteNr))) + (Random real number between -50.00 and 50.00)), ((140.00 x (Real((Integer B)))) + (Random real number between -50.00 and 50.00))))
    Custom script:   set udg_Berechneter_Wert =  Berechne(udg_SpalteNr,bj_forLoopBIndex)
    Custom script:   if udg_Berechneter_Wert > 450 then
    Umgebung - Change terrain type at ErstellugnsOrt to Lordaeron-Sommer - Dunkles Gras using variation -1 in an area 2 and shape Kreis
    Custom script:   if udg_Berechneter_Wert > 700 then
    If (95 Größer gleich (Random integer number between 1 and 100)) then do (Zerstörbar - Create a Ashenvale at ErstellugnsOrt facing (Random angle) with scale (Random real number between 0.70 and 1.10) and variation (Random integer number between 0 and 9)) else do (Do nothing)
    Custom script:   else
    If (80 Größer gleich (Random integer number between 1 and 100)) then do (Zerstörbar - Create a Sommerbaumwand at ErstellugnsOrt facing (Random angle) with scale (Random real number between 0.70 and 1.10) and variation (Random integer number between 0 and 9)) else do (Do nothing)
    Custom script:   endif
    Custom script:   endif


There is only one problem. Warcraft 3 cancel functions which takes too long. To avoid this problem we create for each column an new instance of a tigger which create a column of ouer forest. After a tigger has finished he remove himself from the tigger queue and increase the column number (in my example SpalteNr).

I hope you will have fun with my script. Where can i upload my german Map Unsichtbar which use this script?

See you in the european Battle.net!
Editor-Fan[InF]
#2
Nice script.. Upload the script to the Jass section (please upload it at The Jass Vault as well).. If the map is a demo map, I guess the spells section must be the rigth place.. If it's a real map, go to the maps section..

Blade

Edit: When posting GUI, please do it in english more people will understand it then :) ..
#3
Ok, i have upload the map here:
http://www.wc3sear.ch/?p=Maps&ID=5233

It also Incude Tiggers which create Pathes. They use four Points to define a curve.

What should I upload to the JASS section?

Editor-Fan
#4
I'm not sure you've undestood me correctly, but if it isn't a real map (haven't tested) it, you should delete it else, fine.

And you should of course upload the script you showed in the first post..

~Blade