Ein Forumsmitglied namens olzii hatte mal einen Code beigesteuert, in dem er ein Anzahl von z.B. Bäumen erschafft, die je nach Bedarf vor dem Spieler positioniert werden. D.h. sie werden an einem abgelegenen Ort weit weg vom Spieler und der Kamera platziert, dann wird gefragt, ob in der Nähe des Spielers eine Position unbesetzt ist und ein Baum an seine Stelle gesetzt.
Ich klatsch den Code einfach mal in diesen Post, auch wenn er etwas verwirrend sein sollte, vor allem weil ich ihn für meine Zwecke modifiziert hatte, vielleicht hilft er weiter.
Das bedeutet aber, dass nicht dazu geeignet ist, 1 zu 1 in ein Skript eingebunden zu werden.
Im wesentlichen enthält es 2 Teile: eins, wo er die Positionen der Bäume wie sie im WED platziert wurden in eine Datei liest und speichert. Dann muß man die Bäume in WED wieder löschen.
Den Schritt könnte man dahingehend ändern, dass man die Positionen der Pixel in die Datei schreibt.
Der 2. Teil ist die eigentliche Funktion, die ein paar Bäume erschafft - deutlich weniger als Positionen!
Bei mir gab es Frameeinbrüche dann, wenn keine Positionen in der Nähe war. Wahrscheinlich, weil dann jeder nichtplatzierte Baum die Liste der positionen durchprüft, während bereits platzierte Bäume nicht nach einer leeren Position suchen.
Meine zur Verwirrung beitragenden Änderungen:
Ich habe es für Gras benutzt und dabei noch eine fx eingebunden, die das Gras weich einblendet. Die kann ich aber auch posten, wenn Du sie gebrauchen kannst.
In diesem Code speichert er nur die Positionen in der Datei, nicht aber die Winkel.
view main_cam {
layer = 2;
pos_x = 0;
pos_y = 0;
// fog_start = 1;
// fog_end = 1400;
// clip_near = 1;
// clip_far = 60000;
}
//Author:olzii//D.Ulzii-Orshikh
define T_RowN, 4;
var T_MaxN=0; //2500
var Trees[10000];
// T_RowN * 2500rows
// [0]-PointX, [1]-PointY, [2]-PointZ, [3]-IsFree
// You can change T_N depending on your level,
// if you want to see more trees at the same time increase it
define T_N, 50;// Maximum 50 trees at the time
entity* new_tree;
var tree_tmp1[3];
var tree_tmp2[3];
//first define the empty material:
material mat_gras_fading{}
//then load the fx file in a starter function
starter gras_fading_mat
{
effect_load(mat_gras_fading,"grasfading.fx");
}
function Action_Trees()
{
my.material = mat_gras_fading;
var i;
var min_dest;
var min_i;
var dst;
var ang;
my.passable=on;
while(1)
{
if(my.z!=-20000)// if i'm visible to main_cam
{
vec_set(my.skill4,main_cam.x);
vec_sub(my.skill4,my.x);
vec_to_angle(my.skill1,my.skill4);
my.skill1=((main_cam.pan-my.skill1)+360)%360; //my.skill1 = ang(main_cam.pan-my.skill1)
if((my.skill1<120)||(my.skill1>240)) // i'm invisible to main_cam & move to tree position
{//(min_dest+100<vec_dist(main_cam.x, my.x))||
my.alpha=0;
my.x=0;
my.y=0;
my.z=-20000;
Trees[T_RowN*my.skill10+3]=0;
my.skill10=0;
}
}
else // i am invisible to main_cam, lets find points near and visible to main_cam
{
i=0;
min_dest=1000;
min_i=0;
while(i<T_MaxN)
{
if(Trees[T_RowN*i+3]==0) // if this POINT is free
{
dst = vec_dist(main_cam.x,vector(Trees[T_RowN*i],Trees[T_RowN*i+1],Trees[T_RowN*i+2]));
if(dst<min_dest)
{
vec_set(my.skill4,main_cam.x);
vec_sub(my.skill4,vector(Trees[T_RowN*i],Trees[T_RowN*i+1],Trees[T_RowN*i+2]));
vec_to_angle(my.skill1,my.skill4);
my.skill1=((main_cam.pan-my.skill1)+360)%360;
if((my.skill1>120)&&(my.skill1<240))
{
min_dest=dst;
min_i=i;
} // found one position
}
}
i+=1;
my.alpha += 0.1 * time;
}
if(min_dest!=1000) // Move me to MINIMUM position
{
my.x = Trees[T_RowN*min_i];
my.y = Trees[T_RowN*min_i+1];
my.z = Trees[T_RowN*min_i+2];
Trees[T_RowN*min_i+3] = 1;
my.skill10 = min_i;
}
else
{
// sleep(3+random(2));
} // if there is not enough tree node for me then wait
}
// if(my.skill4 != 0){my.alpha = 100 / abs(my.skill4 * 0.005);}
// else{
// my.alpha = 100;
// }
wait(1);
}
}
function Create_Dummy_Trees()
{ var i=0; var sc; var pn;
while(i<T_N)
{
new_tree = ent_create("kleingrass02.mdl",vector(-20000,0,0),Action_Trees);
// sc=random(0.5)+0.7;
// pn=random(90);
// new_tree.scale_x=sc;
// new_tree.scale_y=sc;
// new_tree.scale_z=sc;
// new_tree.pan=pn;
i+=1;
}
}
string tree_ss=" ";
string tree_fname[30];
string tree_ss1;
var_nsave t_handle;
function Read_Trees_Ini()
{
var xx;
var yy;
var zz;
var eof=0;
T_MaxN=0;
t_handle = file_open_read("grass.ini"); // ("trees.ini"); //
while(eof!=-1)
{
eof=file_str_read(t_handle,tree_ss);
if(str_stri(tree_ss,"//")==1) { continue; }
if(str_stri(tree_ss,"pos")>=1)
{
str_clip(tree_ss,5);
str_cpy(tree_ss1, tree_ss);
str_trunc(tree_ss1, str_len(tree_ss1)-str_stri(tree_ss1,";")+1);
xx=str_to_num(tree_ss1);
str_clip(tree_ss, str_stri(tree_ss,";"));
str_cpy(tree_ss1, tree_ss);
str_trunc(tree_ss1, str_len(tree_ss1)-str_stri(tree_ss1,";")+1);
yy=str_to_num(tree_ss1);
str_clip(tree_ss, str_stri(tree_ss,";"));
zz=str_to_num(tree_ss);
Trees[T_RowN*T_MaxN]=xx;
Trees[T_RowN*T_MaxN+1]=yy;
Trees[T_RowN*T_MaxN+2]=zz;
Trees[T_RowN*T_MaxN+3]=0;
T_MaxN+=1;
}
}
file_close(t_handle);
Create_Dummy_Trees();
}
function Save_Trees()
{ beep;
t_handle=file_open_write ("grass.ini");//("trees.ini");//
file_str_write (t_handle,"// Grass \n");
you = ent_next (NULL); // retrieve first entity
while (you != NULL) // repeat until there are no more entities
{ str_for_entfile(tree_fname,you);
if(str_stri(tree_fname,"gras") > 0)
{ str_cpy(tree_ss,""); str_cat(tree_ss,"pos ; ");
str_for_num(tree_ss1,you.x); str_cat(tree_ss,tree_ss1); str_cat(tree_ss," ; ");
str_for_num(tree_ss1,you.y); str_cat(tree_ss,tree_ss1); str_cat(tree_ss," ; ");
str_for_num(tree_ss1,you.z); str_cat(tree_ss,tree_ss1); str_cat(tree_ss,"\n");
file_str_write (t_handle,tree_ss);
}
you = ent_next (you); // get next entity
}
file_close(t_handle);
}
//on_m = Save_Trees;
action gravity
{
my.passable = on;
// trace_mode = ignore_passable + ignore_me;
// while(1)
// {
my.z -= trace(my.x, vector(my.x, my.y, my.z - 4000));
// wait(1);
// }
}