hedgewars/uLandGenTemplateBased.pas
changeset 10208 f04fdb35fc33
parent 10207 9dd3a44805a1
child 10209 76316652ef26
equal deleted inserted replaced
10207:9dd3a44805a1 10208:f04fdb35fc33
    93         RandomizePoints(pa);
    93         RandomizePoints(pa);
    94     BezierizeEdge(pa, _0_1);
    94     BezierizeEdge(pa, _0_1);
    95 end;
    95 end;
    96 
    96 
    97 procedure FindPoint(si, fillPointsCount: LongInt; var newPoint: TPoint; var pa: TPixAr);
    97 procedure FindPoint(si, fillPointsCount: LongInt; var newPoint: TPoint; var pa: TPixAr);
    98 const mapBorderMargin = 30;
    98 const mapBorderMargin = 40;
    99     minDistance = 32; // adjust/parametrize this for different details size
    99     minDistance = 32; // adjust/parametrize this for different details size
   100 var p1, p2, p4, fp, mp: TPoint;
   100 var p1, p2, p4, fp, mp: TPoint;
   101     i, t1, t2, a, b, p, q, iy, ix, aqpb: LongInt;
   101     i, t1, t2, a, b, p, q, iy, ix, aqpb: LongInt;
   102     dab, d, distL, distR: LongInt;
   102     dab, d, distL, distR: LongInt;
   103 begin
   103 begin
   124     mp.y:= (p1.y + p2.y) div 2;
   124     mp.y:= (p1.y + p2.y) div 2;
   125 
   125 
   126     // don't process too short segments or those which are too close to map borders
   126     // don't process too short segments or those which are too close to map borders
   127     if (p1.x = NTPX)
   127     if (p1.x = NTPX)
   128             or (dab < minDistance * 3) 
   128             or (dab < minDistance * 3) 
   129             or (mp.x < mapBorderMargin)
   129             or (mp.x < leftX + mapBorderMargin)
   130             or (mp.x > LAND_WIDTH - mapBorderMargin)
   130             or (mp.x > rightX - mapBorderMargin)
   131             or (mp.y < mapBorderMargin)
   131             or (mp.y < topY + mapBorderMargin)
   132             or (mp.y > LAND_HEIGHT - mapBorderMargin)
   132             or (mp.y > LAND_HEIGHT - mapBorderMargin)
   133     then
   133     then
   134     begin
   134     begin
   135         newPoint:= p1;
   135         newPoint:= p1;
   136         exit;
   136         exit;
   138 
   138 
   139     // find distances to map borders
   139     // find distances to map borders
   140     if a <> 0 then
   140     if a <> 0 then
   141     begin
   141     begin
   142         // left border
   142         // left border
   143         iy:= (mapBorderMargin - mp.x) * b div a + mp.y;
   143         iy:= (leftX + mapBorderMargin - mp.x) * b div a + mp.y;
   144         d:= DistanceI(mp.x - mapBorderMargin, mp.y - iy).Round;
   144         d:= DistanceI(mp.x - leftX - mapBorderMargin, mp.y - iy).Round;
   145         t1:= a * (mp.x - mapBorderMargin) + b * (mp.y - iy);
   145         t1:= a * (mp.x - mapBorderMargin) + b * (mp.y - iy);
   146         if t1 > 0 then distL:= d else distR:= d;
   146         if t1 > 0 then distL:= d else distR:= d;
   147 
   147 
   148         // right border
   148         // right border
   149         iy:= (LAND_WIDTH - mapBorderMargin - mp.x) * b div a + mp.y;
   149         iy:= (rightX - mapBorderMargin - mp.x) * b div a + mp.y;
   150         d:= DistanceI(mp.x - LAND_WIDTH + mapBorderMargin, mp.y - iy).Round;
   150         d:= DistanceI(mp.x - rightX + mapBorderMargin, mp.y - iy).Round;
   151         if t1 > 0 then distR:= d else distL:= d;
   151         if t1 > 0 then distR:= d else distL:= d;
   152     end;
   152     end;
   153 
   153 
   154     if b <> 0 then
   154     if b <> 0 then
   155     begin
   155     begin
   156         // top border
   156         // top border
   157         ix:= (mapBorderMargin - mp.y) * a div b + mp.x;
   157         ix:= (topY + mapBorderMargin - mp.y) * a div b + mp.x;
   158         d:= DistanceI(mp.y - mapBorderMargin, mp.x - ix).Round;
   158         d:= DistanceI(mp.y - topY - mapBorderMargin, mp.x - ix).Round;
   159         t2:= b * (mp.y - mapBorderMargin) + a * (mp.x - ix);
   159         t2:= b * (mp.y - mapBorderMargin) + a * (mp.x - ix);
   160         if t2 > 0 then distL:= min(d, distL) else distR:= min(d, distR);
   160         if t2 > 0 then distL:= min(d, distL) else distR:= min(d, distR);
   161 
   161 
   162         // bottom border
   162         // bottom border
   163         ix:= (LAND_HEIGHT - mapBorderMargin - mp.y) * a div b + mp.x;
   163         ix:= (LAND_HEIGHT - mapBorderMargin - mp.y) * a div b + mp.x;
   329     fps:=Template.FillPoints^;
   329     fps:=Template.FillPoints^;
   330     ResizeLand(Template.TemplateWidth, Template.TemplateHeight);
   330     ResizeLand(Template.TemplateWidth, Template.TemplateHeight);
   331     for y:= 0 to LAND_HEIGHT - 1 do
   331     for y:= 0 to LAND_HEIGHT - 1 do
   332         for x:= 0 to LAND_WIDTH - 1 do
   332         for x:= 0 to LAND_WIDTH - 1 do
   333             Land[y, x]:= lfBasic;
   333             Land[y, x]:= lfBasic;
       
   334             
       
   335     MaxHedgehogs:= Template.MaxHedgehogs;
       
   336     hasGirders:= Template.hasGirders;
       
   337     playHeight:= Template.TemplateHeight;
       
   338     playWidth:= Template.TemplateWidth;
       
   339     leftX:= (LAND_WIDTH - playWidth) div 2;
       
   340     rightX:= leftX + playWidth - 1;
       
   341     topY:= LAND_HEIGHT - playHeight;
       
   342     
   334     {$HINTS OFF}
   343     {$HINTS OFF}
   335     SetPoints(Template, pa, @fps);
   344     SetPoints(Template, pa, @fps);
   336     {$HINTS ON}
   345     {$HINTS ON}
   337 
   346 
   338     Distort2(Template, @fps, pa);
   347     Distort2(Template, @fps, pa);
   343         for i:= 0 to pred(FillPointsCount) do
   352         for i:= 0 to pred(FillPointsCount) do
   344             with fps[i] do
   353             with fps[i] do
   345                 FillLand(x, y, 0, 0);
   354                 FillLand(x, y, 0, 0);
   346 
   355 
   347     DrawEdge(pa, lfBasic);
   356     DrawEdge(pa, lfBasic);
   348 
       
   349     MaxHedgehogs:= Template.MaxHedgehogs;
       
   350     hasGirders:= Template.hasGirders;
       
   351     playHeight:= Template.TemplateHeight;
       
   352     playWidth:= Template.TemplateWidth;
       
   353     leftX:= ((LAND_WIDTH - playWidth) div 2);
       
   354     rightX:= (playWidth + ((LAND_WIDTH - playWidth) div 2)) - 1;
       
   355     topY:= LAND_HEIGHT - playHeight;
       
   356 
   357 
   357     // HACK: force to only cavern even if a cavern map is invertable if cTemplateFilter = 4 ?
   358     // HACK: force to only cavern even if a cavern map is invertable if cTemplateFilter = 4 ?
   358     if (cTemplateFilter = 4)
   359     if (cTemplateFilter = 4)
   359     or (Template.canInvert and (getrandom(2) = 0))
   360     or (Template.canInvert and (getrandom(2) = 0))
   360     or (not Template.canInvert and Template.isNegative) then
   361     or (not Template.canInvert and Template.isNegative) then