- Joined
- Jun 15, 2005
- Messages
- 4
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:
Ok, before you do anything else you have to fill this Array with Random Values between 1 and 1000.
Tigger:
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:
My DataSize Value was 65 so i called the function with:
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:
We need this Array Value for the following function:
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.
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:
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]
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:
JASS:
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:
Code:
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:
JASS:
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:
JASS:
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:
Code:
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:
JASS:
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.
JASS:
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:
Code:
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]