--- a/QTfrontend/model/MapModel.h Thu Aug 29 15:28:20 2024 +0200
+++ b/QTfrontend/model/MapModel.h Thu Aug 29 17:09:39 2024 +0200
@@ -46,28 +46,30 @@
Q_OBJECT
public:
- enum MapType {
- Invalid,
- GeneratedMap,
- GeneratedMaze,
- GeneratedPerlin,
- HandDrawnMap,
- MissionMap,
- StaticMap,
- FortsMap
- };
+ enum MapType {
+ Invalid,
+ GeneratedMap,
+ GeneratedMaze,
+ GeneratedPerlin,
+ HandDrawnMap,
+ MissionMap,
+ StaticMap,
+ FortsMap,
+ WfcMap
+ };
- /// a struct for holding the attributes of a map.
- struct MapInfo
- {
- MapType type; ///< The map-type
- QString name; ///< The internal name.
- QString theme; ///< The theme to be used. (can be empty)
- quint32 limit; ///< The maximum allowed number of hedgehogs.
- QString scheme; ///< Default scheme name or "locked", for mission-maps.
- QString weapons; ///< Default weaponset name or "locked", for missions-maps.
- QString desc; ///< The brief 1-2 sentence description of the mission, for mission-maps.
- bool dlc; ///< True if this map was not packaged with the game
+ /// a struct for holding the attributes of a map.
+ struct MapInfo {
+ MapType type; ///< The map-type
+ QString name; ///< The internal name.
+ QString theme; ///< The theme to be used. (can be empty)
+ quint32 limit; ///< The maximum allowed number of hedgehogs.
+ QString scheme; ///< Default scheme name or "locked", for mission-maps.
+ QString
+ weapons; ///< Default weaponset name or "locked", for missions-maps.
+ QString desc; ///< The brief 1-2 sentence description of the mission,
+ ///< for mission-maps.
+ bool dlc; ///< True if this map was not packaged with the game
};
MapModel(MapType maptype, QObject *parent = 0);
--- a/QTfrontend/net/hwmap.h Thu Aug 29 15:28:20 2024 +0200
+++ b/QTfrontend/net/hwmap.h Thu Aug 29 17:09:39 2024 +0200
@@ -26,14 +26,14 @@
#include "tcpBase.h"
-enum MapGenerator
-{
- MAPGEN_REGULAR = 0,
- MAPGEN_MAZE = 1,
- MAPGEN_PERLIN = 2,
- MAPGEN_DRAWN = 3,
- MAPGEN_FORTS = 4,
- MAPGEN_MAP = 5
+enum MapGenerator {
+ MAPGEN_REGULAR = 0,
+ MAPGEN_MAZE = 1,
+ MAPGEN_PERLIN = 2,
+ MAPGEN_DRAWN = 3,
+ MAPGEN_FORTS = 4,
+ MAPGEN_WFC = 5,
+ MAPGEN_MAP = 6,
};
class HWMap : public TCPBase
--- a/QTfrontend/ui/widget/mapContainer.cpp Thu Aug 29 15:28:20 2024 +0200
+++ b/QTfrontend/ui/widget/mapContainer.cpp Thu Aug 29 17:09:39 2024 +0200
@@ -129,7 +129,9 @@
cType->insertItem(4, tr("Random maze"), MapModel::GeneratedMaze);
cType->insertItem(5, tr("Random perlin"), MapModel::GeneratedPerlin);
cType->insertItem(6, tr("Forts"), MapModel::FortsMap);
- connect(cType, SIGNAL(currentIndexChanged(int)), this, SLOT(mapTypeChanged(int)));
+ cType->insertItem(7, tr("WFC"), MapModel::WfcMap);
+ connect(cType, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(mapTypeChanged(int)));
m_childWidgets << cType;
/* Randomize button */
@@ -760,19 +762,23 @@
m_mapInfo.type = MapModel::FortsMap;
f = true;
break;
+ case MAPGEN_WFC:
+ m_mapInfo.type = MapModel::WfcMap;
+ f = true;
+ break;
case MAPGEN_MAP:
- switch (m_mapInfo.type)
- {
- case MapModel::GeneratedMap:
- case MapModel::GeneratedMaze:
- case MapModel::GeneratedPerlin:
- case MapModel::HandDrawnMap:
- case MapModel::FortsMap:
- m_mapInfo.type = MapModel::Invalid;
- default:
- break;
- }
- break;
+ switch (m_mapInfo.type) {
+ case MapModel::GeneratedMap:
+ case MapModel::GeneratedMaze:
+ case MapModel::GeneratedPerlin:
+ case MapModel::HandDrawnMap:
+ case MapModel::FortsMap:
+ case MapModel::WfcMap:
+ m_mapInfo.type = MapModel::Invalid;
+ default:
+ break;
+ }
+ break;
}
if(f)
@@ -948,10 +954,11 @@
case MapModel::GeneratedMap:
case MapModel::GeneratedPerlin:
case MapModel::GeneratedMaze:
- mapPreview->setWhatsThis(randomAllPrev);
- mapFeatureSize->setWhatsThis(mfsComplex);
- btnRandomize->setWhatsThis(randomAll);
- break;
+ case MapModel::WfcMap:
+ mapPreview->setWhatsThis(randomAllPrev);
+ mapFeatureSize->setWhatsThis(mfsComplex);
+ btnRandomize->setWhatsThis(randomAll);
+ break;
case MapModel::MissionMap:
case MapModel::StaticMap:
mapPreview->setWhatsThis(randomAllPrev);
@@ -1059,8 +1066,15 @@
setMapInfo(MapModel::MapInfoForts);
lblMapList->hide();
break;
+ case MapModel::WfcMap:
+ mapgen = MAPGEN_WFC;
+ setMapInfo(MapModel::MapInfoRandom);
+ lblMapList->setText(tr("Map size:"));
+ lblMapList->show();
+ generationStyles->show();
+ break;
default:
- break;
+ break;
}
// Update theme button size
--- a/hedgewars/uLand.pas Thu Aug 29 15:28:20 2024 +0200
+++ b/hedgewars/uLand.pas Thu Aug 29 17:09:39 2024 +0200
@@ -793,11 +793,12 @@
begin
WriteLnToConsole('Generating land...');
case cMapGen of
- mgRandom: GenerateTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
+ mgRandom: GenerateOutlineTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
mgMaze : begin ResizeLand(4096,2048); GenMaze; end;
mgPerlin: begin ResizeLand(4096,2048); GenPerlin; end;
mgDrawn : GenDrawnMap;
mgForts : begin GameFlags:= (GameFlags or gfDivideTeams); MakeFortsMap(); end;
+ mgWfc: GenerateWfcTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
else
OutError('Unknown mapgen', true);
end;
@@ -948,11 +949,12 @@
begin
WriteLnToConsole('Generating preview...');
case cMapGen of
- mgRandom: GenerateTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
+ mgRandom: GenerateOutlineTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
mgMaze: begin ResizeLand(4096,2048); GenMaze; end;
mgPerlin: begin ResizeLand(4096,2048); GenPerlin; end;
mgDrawn: begin GenDrawnMap; end;
mgForts: MakeFortsPreview();
+ mgWfc: GenerateWfcTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
else
OutError('Unknown mapgen', true);
end;
@@ -1007,11 +1009,12 @@
begin
WriteLnToConsole('Generating preview...');
case cMapGen of
- mgRandom: GenerateTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
+ mgRandom: GenerateOutlineTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
mgMaze: begin ResizeLand(4096,2048); GenMaze; end;
mgPerlin: begin ResizeLand(4096,2048); GenPerlin; end;
mgDrawn: begin GenDrawnMap; end;
mgForts: MakeFortsPreview;
+ mgWfc: GenerateWfcTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
else
OutError('Unknown mapgen', true);
end;
--- a/hedgewars/uLandUtils.pas Thu Aug 29 15:28:20 2024 +0200
+++ b/hedgewars/uLandUtils.pas Thu Aug 29 17:09:39 2024 +0200
@@ -2,7 +2,8 @@
interface
uses SDLh;
-procedure GenerateTemplatedLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring);
+procedure GenerateOutlineTemplatedLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring);
+procedure GenerateWfcTemplatedLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring);
procedure ResizeLand(width, height: LongWord);
procedure DisposeLand();
procedure InitWorldEdges();
@@ -35,7 +36,8 @@
procedure land_pixel_set(game_field: pointer; x, y: LongInt; value: Longword); cdecl; external;
function land_pixel_row(game_field: pointer; row: LongInt): PLongwordArray; cdecl; external;
-function generate_templated_game_field(feature_size: Longword; seed, template_type, data_path: PChar): pointer; cdecl; external;
+function generate_outline_templated_game_field(feature_size: Longword; seed, template_type, data_path: PChar): pointer; cdecl; external;
+function generate_wfc_templated_game_field(feature_size: Longword; seed, template_type, data_path: PChar): pointer; cdecl; external;
procedure apply_theme(game_field: pointer; data_path, theme_name: PChar); cdecl; external;
var gameField: pointer;
@@ -75,12 +77,37 @@
LandPixelRow:= land_pixel_row(gameField, row)
end;
-procedure GenerateTemplatedLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring);
+procedure GenerateOutlineTemplatedLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring);
begin
seed[byte(seed[0]) + 1]:= #0;
templateType[byte(templateType[0]) + 1]:= #0;
- gameField:= generate_templated_game_field(featureSize, @seed[1], @templateType[1], PChar(dataPath));
+ gameField:= generate_outline_templated_game_field(featureSize, @seed[1], @templateType[1], PChar(dataPath));
+ get_game_field_parameters(gameField, LAND_WIDTH, LAND_HEIGHT, playWidth, playHeight);
+
+ MaxHedgehogs:= 32;
+ hasGirders:= true;
+
+ leftX:= (LAND_WIDTH - playWidth) div 2;
+ rightX:= Pred(leftX + playWidth);
+ topY:= LAND_HEIGHT - playHeight;
+ cWaterLine:= LAND_HEIGHT;
+
+ // let's assume those are powers of two
+ LAND_WIDTH_MASK:= not(LAND_WIDTH-1);
+ LAND_HEIGHT_MASK:= not(LAND_HEIGHT-1);
+
+ SetLength(LandDirty, (LAND_HEIGHT div 32), (LAND_WIDTH div 32));
+
+ initScreenSpaceVars();
+end;
+
+procedure GenerateWfcTemplatedLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring);
+begin
+ seed[byte(seed[0]) + 1]:= #0;
+ templateType[byte(templateType[0]) + 1]:= #0;
+
+ gameField:= generate_wfc_templated_game_field(featureSize, @seed[1], @templateType[1], PChar(dataPath));
get_game_field_parameters(gameField, LAND_WIDTH, LAND_HEIGHT, playWidth, playHeight);
MaxHedgehogs:= 32;
--- a/hedgewars/uTypes.pas Thu Aug 29 15:28:20 2024 +0200
+++ b/hedgewars/uTypes.pas Thu Aug 29 17:09:39 2024 +0200
@@ -196,7 +196,7 @@
TStereoMode = (smNone, smRedCyan, smCyanRed, smRedBlue, smBlueRed, smRedGreen, smGreenRed, smHorizontal, smVertical);
TWorldEdge = (weNone, weWrap, weBounce, weSea, weSky);
TUIDisplay = (uiAll, uiNoTeams, uiNone);
- TMapGen = (mgRandom, mgMaze, mgPerlin, mgDrawn, mgForts);
+ TMapGen = (mgRandom, mgMaze, mgPerlin, mgDrawn, mgForts, mgWFC);
THHFont = record
--- a/rust/lib-hwengine-future/src/lib.rs Thu Aug 29 15:28:20 2024 +0200
+++ b/rust/lib-hwengine-future/src/lib.rs Thu Aug 29 17:09:39 2024 +0200
@@ -4,6 +4,7 @@
wavefront_collapse::generator::{
TemplateDescription as WfcTemplate,
},
+ outline_template_based::outline_template::OutlineTemplate,
LandGenerationParameters, LandGenerator,
};
use lfprng::LaggedFibonacciPRNG;
@@ -47,7 +48,47 @@
}
#[no_mangle]
-pub extern "C" fn generate_templated_game_field(
+pub extern "C" fn generate_outline_templated_game_field(
+ feature_size: u32,
+ seed: *const i8,
+ template_type: *const i8,
+ data_path: *const i8,
+) -> *mut GameField {
+ let data_path: &str = unsafe { CStr::from_ptr(data_path) }.to_str().unwrap();
+ let data_path = Path::new(&data_path);
+
+ let seed: &str = unsafe { CStr::from_ptr(seed) }.to_str().unwrap();
+ let template_type: &str = unsafe { CStr::from_ptr(template_type) }.to_str().unwrap();
+
+ let mut random_numbers_gen = LaggedFibonacciPRNG::new(seed.as_bytes());
+
+ let yaml_templates =
+ fs::read_to_string(data_path.join(Path::new("map_templates.yaml")).as_path())
+ .expect("Error reading map templates file");
+ let mut map_gen = MapGenerator::<OutlineTemplate>::new(data_path);
+ map_gen.import_yaml_templates(&yaml_templates);
+
+ let distance_divisor = feature_size.pow(2) / 8 + 10;
+ let params = LandGenerationParameters::new(0u16, 0x8000u16, distance_divisor, false, false);
+ let template = map_gen
+ .get_template(template_type, &mut random_numbers_gen)
+ .expect("Error reading outline templates file")
+ .clone();
+ let landgen = map_gen.build_generator(template);
+ let collision = landgen.generate_land(¶ms, &mut random_numbers_gen);
+ let size = collision.size().size();
+
+ let game_field = Box::new(GameField {
+ collision,
+ pixels: land2d::Land2D::new(&size, 0),
+ landgen_parameters: Some(params),
+ });
+
+ Box::leak(game_field)
+}
+
+#[no_mangle]
+pub extern "C" fn generate_wfc_templated_game_field(
feature_size: u32,
seed: *const i8,
template_type: *const i8,
@@ -71,7 +112,7 @@
let params = LandGenerationParameters::new(0u16, 0x8000u16, distance_divisor, false, false);
let template = map_gen
.get_template(template_type, &mut random_numbers_gen)
- .expect("Error reading templates file")
+ .expect("Error reading wfc templates file")
.clone();
let landgen = map_gen.build_generator(template);
let collision = landgen.generate_land(¶ms, &mut random_numbers_gen);