hedgewars/uLand.pas
changeset 1776 dd5648e250e4
parent 1773 bc6ad6136675
child 1779 9d88af62a3bb
equal deleted inserted replaced
1775:c7dc2f191347 1776:dd5648e250e4
    26 
    26 
    27 var  Land: TLandArray;
    27 var  Land: TLandArray;
    28      LandPixels: TLandArray;
    28      LandPixels: TLandArray;
    29      LandTexture: PTexture = nil;
    29      LandTexture: PTexture = nil;
    30      LandDirty: TDirtyTag;
    30      LandDirty: TDirtyTag;
       
    31      hasBorder: boolean; // I'm putting this here for now.  I'd like it to be toggleable by user (so user can set a border on a non-cave map) - will turn off air attacks
       
    32      hasGirders: boolean;  // I think should be on template by template basis. some caverns might have open water and large spaces.  Some islands don't need? It might be better to tweak the girder code based upon space above.  dunno.
       
    33      playHeight, playWidth, leftX, rightX, topY: Longword;  // idea is that a template can specify height/width.  Or, a map, a height/width by the dimensions of the image.  If the map has pixels near top of image, it triggers border.  Maybe not a good idea, but, for now?  Could also be used to prevent placing a girder outside play area on maps with hasBorder = true
       
    34 
       
    35 // in your coding style, it appears to be "isXXXX" for a verb, and "FooBar" for everything else - should be PlayHeight ?
    31 
    36 
    32 procedure GenMap;
    37 procedure GenMap;
    33 function  GenPreview: TPreview;
    38 function  GenPreview: TPreview;
    34 procedure CheckLandDigest(s: shortstring);
    39 procedure CheckLandDigest(s: shortstring);
    35 procedure UpdateLandTexture(Y, Height: LongInt);
    40 procedure UpdateLandTexture(Y, Height: LongInt);
   365      begin
   370      begin
   366      pa.Count:= BasePointsCount;
   371      pa.Count:= BasePointsCount;
   367      for i:= 0 to pred(pa.Count) do
   372      for i:= 0 to pred(pa.Count) do
   368          begin
   373          begin
   369          pa.ar[i].x:= BasePoints^[i].x + LongInt(GetRandom(BasePoints^[i].w));
   374          pa.ar[i].x:= BasePoints^[i].x + LongInt(GetRandom(BasePoints^[i].w));
   370          pa.ar[i].y:= BasePoints^[i].y + LongInt(GetRandom(BasePoints^[i].h))
   375          pa.ar[i].y:= BasePoints^[i].y + LongInt(GetRandom(BasePoints^[i].h)) + LAND_HEIGHT - Template.TemplateHeight
   371          end;
   376          end;
   372 
   377 
   373      if canMirror then
   378      if canMirror then
   374         if getrandom(2) = 0 then
   379         if getrandom(2) = 0 then
   375            begin
   380            begin
   494          with FillPoints^[i] do
   499          with FillPoints^[i] do
   495               FillLand(x, y);
   500               FillLand(x, y);
   496 
   501 
   497 DrawEdge(pa, COLOR_LAND);
   502 DrawEdge(pa, COLOR_LAND);
   498 
   503 
       
   504 hasGirders:= Template.hasGirders;
       
   505 playHeight:= Template.TemplateHeight;
       
   506 playWidth:= Template.TemplateWidth;
       
   507 //TryDo(playWidth<>0, 'freakin magic man!  Why the HELL does having a TryDo here make the following calculations work?', true);
       
   508 leftX:= ((LAND_WIDTH - playWidth) div 2);
       
   509 rightX:= (playWidth + ((LAND_WIDTH - playWidth) div 2)) - 1;
       
   510 topY:= LAND_HEIGHT - playHeight;
       
   511 
   499 if (Template.canInvert and (getrandom(2) = 0)) or
   512 if (Template.canInvert and (getrandom(2) = 0)) or
   500     (not Template.canInvert and Template.isNegative) then 
   513     (not Template.canInvert and Template.isNegative) then 
       
   514     begin
       
   515     hasBorder:= true;
   501     for y:= 0 to LAND_HEIGHT - 1 do
   516     for y:= 0 to LAND_HEIGHT - 1 do
   502         for x:= 0 to LAND_WIDTH - 1 do
   517         for x:= 0 to LAND_WIDTH - 1 do
   503             if Land[y, x] = 0 then
   518             if (y < topY) or (x < leftX) or (x > rightX) then
   504                 Land[y, x]:= COLOR_LAND
   519                 Land[y, x]:= 0
   505             else if Land[y, x] = COLOR_LAND then
   520             else
   506                 Land[y, x]:= 0;
   521             begin
       
   522                if Land[y, x] = 0 then
       
   523                    Land[y, x]:= COLOR_LAND
       
   524                else if Land[y, x] = COLOR_LAND then
       
   525                    Land[y, x]:= 0;
       
   526             end;
       
   527     end;
   507 end;
   528 end;
   508 
   529 
   509 function SelectTemplate: LongInt;
   530 function SelectTemplate: LongInt;
   510 begin
   531 begin
   511 SelectTemplate:= getrandom(Succ(High(EdgeTemplates)))
   532 SelectTemplate:= getrandom(Succ(High(EdgeTemplates)))
   551 LandSurface2LandPixels(tmpsurf);
   572 LandSurface2LandPixels(tmpsurf);
   552 SDL_FreeSurface(tmpsurf);
   573 SDL_FreeSurface(tmpsurf);
   553 
   574 
   554 AddProgress;
   575 AddProgress;
   555 
   576 
   556 AddObjects;
       
   557 
       
   558 AddProgress
   577 AddProgress
   559 end;
   578 end;
   560 
   579 
   561 procedure MakeFortsMap;
   580 procedure MakeFortsMap;
   562 var tmpsurf: PSDL_Surface;
   581 var tmpsurf: PSDL_Surface;
   563 begin
   582 begin
       
   583 // For now, defining a fort's playable area as 4096x1536 - there are no tall forts.  The extra height is to avoid triggering border with current code, also if user turns on a border, it'll give a bit more maneuvering room.
       
   584 playHeight:= 1536;
       
   585 playWidth:= 4096;
       
   586 leftX:= (LAND_WIDTH - playWidth) div 2;
       
   587 rightX:= ((playWidth + (LAND_WIDTH - playWidth) div 2) - 1);
       
   588 topY:= LAND_HEIGHT - playHeight;
       
   589 
   564 WriteLnToConsole('Generating forts land...');
   590 WriteLnToConsole('Generating forts land...');
   565 
   591 
   566 tmpsurf:= LoadImage(Pathz[ptForts] + '/' + ClansArray[0]^.Teams[0]^.FortName + 'L', true, true, true);
   592 tmpsurf:= LoadImage(Pathz[ptForts] + '/' + ClansArray[0]^.Teams[0]^.FortName + 'L', true, true, true);
   567 BlitImageAndGenerateCollisionInfo(0, LAND_HEIGHT - tmpsurf^.h, tmpsurf^.w, tmpsurf);
   593 BlitImageAndGenerateCollisionInfo(0, LAND_HEIGHT - tmpsurf^.h, tmpsurf^.w, tmpsurf);
   568 SDL_FreeSurface(tmpsurf);
   594 SDL_FreeSurface(tmpsurf);
   577 begin
   603 begin
   578 WriteLnToConsole('Loading land from file...');
   604 WriteLnToConsole('Loading land from file...');
   579 AddProgress;
   605 AddProgress;
   580 tmpsurf:= LoadImage(Pathz[ptMapCurrent] + '/map', true, true, true);
   606 tmpsurf:= LoadImage(Pathz[ptMapCurrent] + '/map', true, true, true);
   581 TryDo((tmpsurf^.w <= LAND_WIDTH) and (tmpsurf^.h <= LAND_HEIGHT), 'Map dimensions too big!', true);
   607 TryDo((tmpsurf^.w <= LAND_WIDTH) and (tmpsurf^.h <= LAND_HEIGHT), 'Map dimensions too big!', true);
       
   608 
       
   609 playHeight:= tmpsurf^.h;
       
   610 playWidth:= tmpsurf^.w;
       
   611 TryDo(playWidth<>0, 'freakin magic man!  Why the HELL does having a TryDo here make the following calculations work?', true);
       
   612 leftX:= (LAND_WIDTH - playWidth) div 2;
       
   613 rightX:= (playWidth + ((LAND_WIDTH - playWidth) div 2)) - 1;
       
   614 topY:= LAND_HEIGHT - playHeight;
   582 
   615 
   583 TryDo(tmpsurf^.format^.BytesPerPixel = 4, 'Map should be 32bit', true);
   616 TryDo(tmpsurf^.format^.BytesPerPixel = 4, 'Map should be 32bit', true);
   584 
   617 
   585 BlitImageAndGenerateCollisionInfo(
   618 BlitImageAndGenerateCollisionInfo(
   586 	(LAND_WIDTH - tmpsurf^.w) div 2,
   619 	(LAND_WIDTH - tmpsurf^.w) div 2,
   589 	tmpsurf);
   622 	tmpsurf);
   590 SDL_FreeSurface(tmpsurf);
   623 SDL_FreeSurface(tmpsurf);
   591 end;
   624 end;
   592 
   625 
   593 procedure GenMap;
   626 procedure GenMap;
   594 var x, y: LongInt;
   627 var i, j, t: LongInt;
   595 	c: Longword;
   628 	x, y, w, c: Longword;
   596 	isCave: boolean;
   629 begin
   597 begin
   630 hasBorder:= false;
       
   631 hasGirders:= true;
   598 LoadThemeConfig;
   632 LoadThemeConfig;
   599 
   633 
   600 if (GameFlags and gfForts) = 0 then
   634 if (GameFlags and gfForts) = 0 then
   601    if Pathz[ptMapCurrent] <> '' then LoadMap
   635    if Pathz[ptMapCurrent] <> '' then LoadMap
   602                                 else GenLandSurface
   636                                 else GenLandSurface
   603                                else MakeFortsMap;
   637                                else MakeFortsMap;
   604 AddProgress;
   638 AddProgress;
   605 
   639 
   606 {$IFDEF DEBUGFILE}LogLandDigest;{$ENDIF}
   640 {$IFDEF DEBUGFILE}LogLandDigest;{$ENDIF}
   607 
   641 
   608 isCave:= false;
       
   609 // check for land near top
   642 // check for land near top
   610 for x:= 0 to LAND_WIDTH-1 do
   643 for y:= topY to topY + 5 do
   611 	for y:= 0 to 4 do
   644     for x:= leftX to rightX do
   612 		if Land[y, x] <> 0 then
   645 		if Land[y, x] <> 0 then
   613 			begin
   646 			begin
   614 			isCave:= true;
   647 			hasBorder:= true;
   615 			break;
   648 			break;
   616 			end;
   649 			end;
   617 
   650 
   618 if isCave then
   651 if hasBorder then
   619 	begin
   652 	begin
       
   653     for y:= 0 to LAND_HEIGHT - 1 do
       
   654         for x:= 0 to LAND_WIDTH - 1 do
       
   655             if (y < topY) or (x < leftX) or (x > rightX) then
       
   656                 Land[y, x]:= COLOR_INDESTRUCTIBLE;
   620 	// experiment hardcoding cave
   657 	// experiment hardcoding cave
   621 	for y:= 0 to LAND_HEIGHT-1 do
   658     // also try basing cave dimensions on map/template dimensions, if they exist
   622 		begin
   659     for w:= 0 to 5 do // width of 3 allowed worms to be knocked through with grenade
   623 		Land[y, 0]:= COLOR_INDESTRUCTIBLE;
   660         begin
   624 		Land[y, 1]:= COLOR_INDESTRUCTIBLE;
   661         for y:= topY to LAND_HEIGHT - 1 do
   625 		Land[y, 2]:= COLOR_INDESTRUCTIBLE;
   662             begin
   626 		Land[y, LAND_WIDTH-3]:= COLOR_INDESTRUCTIBLE;
   663             Land[y, leftX + w]:= COLOR_INDESTRUCTIBLE;
   627 		Land[y, LAND_WIDTH-2]:= COLOR_INDESTRUCTIBLE;
   664             Land[y, rightX - w]:= COLOR_INDESTRUCTIBLE;
   628 		Land[y, LAND_WIDTH-1]:= COLOR_INDESTRUCTIBLE;
   665             if y mod 32 < 16 then c:= $FF000000
   629 		if y mod 32 < 16 then c:= $FF000000
   666             else c:= $FF00FFFF;
   630 		else c:= $FF00FFFF;
   667             LandPixels[y, leftX + w]:= c;
   631 		LandPixels[y, 0]:= c;
   668             LandPixels[y, rightX - w]:= c;
   632 		LandPixels[y, 1]:= c;
   669             end;
   633 		LandPixels[y, 2]:= c;
   670 
   634 		LandPixels[y, LAND_WIDTH-3]:= c;
   671         for x:= leftX to rightX do
   635 		LandPixels[y, LAND_WIDTH-2]:= c;
   672             begin
   636 		LandPixels[y, LAND_WIDTH-1]:= c;
   673             Land[topY + w, x]:= COLOR_INDESTRUCTIBLE;
   637 		end;
   674             if x mod 32 < 16 then c:= $FF000000
   638 
   675             else c:= $FF00FFFF;
   639 	for x:= 0 to LAND_WIDTH-1 do
   676             LandPixels[topY + w, x]:= c;
   640 		begin
   677             end;
   641 		Land[0, x]:= COLOR_INDESTRUCTIBLE;
   678         end;
   642 		Land[1, x]:= COLOR_INDESTRUCTIBLE;
   679      // This is almost certainly not the right place to do this
   643 		Land[2, x]:= COLOR_INDESTRUCTIBLE;
   680      // I just want it to be disabled after a border is added, which could by by map constraints as well as player desire
   644 		if x mod 32 < 16 then c:= $FF000000
   681      t:= 0;
   645 		else c:= $FF00FFFF;
   682      while (t < cMaxTeams) and (TeamsArray[t] <> nil) do
   646 		LandPixels[0, x]:= c;
   683          begin
   647 		LandPixels[1, x]:= c;
   684          for i:= 0 to cMaxHHIndex do
   648 		LandPixels[2, x]:= c;
   685              if TeamsArray[t]^.Hedgehogs[i].Gear <> nil then
   649 		end;
   686                  begin
       
   687                  for j:= 0 to cMaxSlotAmmoIndex do
       
   688                      begin
       
   689                      TeamsArray[t]^.Hedgehogs[i].Ammo^[Ammoz[amAirAttack].Slot, j].Count:= 0;
       
   690                      TeamsArray[t]^.Hedgehogs[i].Ammo^[Ammoz[amMineStrike].Slot, j].Count:= 0;
       
   691                      TeamsArray[t]^.Hedgehogs[i].Ammo^[Ammoz[amNapalm].Slot, j].Count:= 0;
       
   692                      end;
       
   693                  end;
       
   694          inc(t);
       
   695          end;
   650 	end;
   696 	end;
       
   697 
       
   698 if ((GameFlags and gfForts) = 0) and (Pathz[ptMapCurrent] = '') then AddObjects;
   651 
   699 
   652 UpdateLandTexture(0, LAND_HEIGHT);
   700 UpdateLandTexture(0, LAND_HEIGHT);
   653 end;
   701 end;
   654 
   702 
   655 function GenPreview: TPreview;
   703 function GenPreview: TPreview;