From 9a57c590cd99d7ff9871849fb8ce3017570c1c2a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 21 Jun 2014 20:17:17 +0200 Subject: Fixed a caching bug in GridStructGen. The elements in cache were queried wrong, so sometimes they wouldn't be used even if they were the ones to use. --- src/Generating/GridStructGen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Generating/GridStructGen.cpp b/src/Generating/GridStructGen.cpp index 2931df3eb..95f8c38bc 100644 --- a/src/Generating/GridStructGen.cpp +++ b/src/Generating/GridStructGen.cpp @@ -88,8 +88,8 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur for (cStructurePtrs::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;) { if ( - ((*itr)->m_OriginX >= MinX) && ((*itr)->m_OriginX < MaxX) && - ((*itr)->m_OriginZ >= MinZ) && ((*itr)->m_OriginZ < MaxZ) + ((*itr)->m_GridX >= MinX) && ((*itr)->m_GridX < MaxX) && + ((*itr)->m_GridZ >= MinZ) && ((*itr)->m_GridZ < MaxZ) ) { // want -- cgit v1.2.3 From 0a95d04ab38b81f87d4fa421601d25f37df1f6a1 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 21 Jun 2014 20:19:44 +0200 Subject: Added a TestRails generator. This is for debugging purposes only. --- src/Generating/ComposableGenerator.cpp | 5 + src/Generating/Prefabs/TestRailsPrefabs.cpp | 484 ++++++++++++++++++++++++++++ src/Generating/Prefabs/TestRailsPrefabs.h | 15 + src/Generating/TestRailsGen.cpp | 116 +++++++ src/Generating/TestRailsGen.h | 47 +++ 5 files changed, 667 insertions(+) create mode 100644 src/Generating/Prefabs/TestRailsPrefabs.cpp create mode 100644 src/Generating/Prefabs/TestRailsPrefabs.h create mode 100644 src/Generating/TestRailsGen.cpp create mode 100644 src/Generating/TestRailsGen.h diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 22941dcbe..7b6234161 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -26,6 +26,7 @@ #include "POCPieceGenerator.h" #include "RainbowRoadsGen.h" #include "Ravines.h" +#include "TestRailsGen.h" #include "UnderwaterBaseGen.h" #include "VillageGen.h" @@ -414,6 +415,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed)); } + else if (NoCaseCompare(*itr, "TestRails") == 0) + { + m_FinishGens.push_back(new cTestRailsGen(Seed, 100, 1, 7, 50)); + } else if (NoCaseCompare(*itr, "Trees") == 0) { m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); diff --git a/src/Generating/Prefabs/TestRailsPrefabs.cpp b/src/Generating/Prefabs/TestRailsPrefabs.cpp new file mode 100644 index 000000000..3444cb1fa --- /dev/null +++ b/src/Generating/Prefabs/TestRailsPrefabs.cpp @@ -0,0 +1,484 @@ + +// TestRailsPrefabs.cpp + +// Defines the prefabs in the group TestRails + +// NOTE: This file has been generated automatically by GalExport! +// Any manual changes will be overwritten by the next automatic export! + +#include "Globals.h" +#include "TestRailsPrefabs.h" + + + + + +const cPrefab::sDef g_TestRailsPrefabs[] = +{ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // ActivatorRail: + // The data has been exported from the gallery Plains, area index 251, ID 746, created by Aloe_vera + { + // Size: + 7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 6, 2, 6, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 1: 0\n" /* stone */ + "b: 5: 0\n" /* wood */ + "c:157: 0\n" /* activatorrail */ + "d:157: 2\n" /* activatorrail */ + "e:157: 3\n" /* activatorrail */ + "f:157: 5\n" /* activatorrail */ + "g: 50: 5\n" /* torch */ + "h:157: 4\n" /* activatorrail */ + "i:157: 1\n" /* activatorrail */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 0 + /* z\x* 0123456 */ + /* 0 */ "aaab..." + /* 1 */ "abbbbb." + /* 2 */ "abbb.b." + /* 3 */ "bbbb.bb" + /* 4 */ ".b...b." + /* 5 */ ".bbbbb." + /* 6 */ "...b..." + + // Level 1 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".cdbec." + /* 2 */ ".fg..f." + /* 3 */ ".b.g.b." + /* 4 */ ".h...h." + /* 5 */ ".cdbec." + /* 6 */ "......." + + // Level 2 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ "...i..." + /* 2 */ "......." + /* 3 */ ".c...c." + /* 4 */ "......." + /* 5 */ "...i..." + /* 6 */ ".......", + + // Connectors: + "1: 6, 1, 3: 5\n" /* Type 1, direction X+ */ + "-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */ + "1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */ + "-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */ + "1: 0, 1, 3: 4\n" /* Type 1, direction X- */ + "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */ + "1: 3, 1, 0: 2\n" /* Type 1, direction Z- */ + "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + false, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + + // MoveToGround: + false, + }, // ActivatorRail + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // DetectorRail: + // The data has been exported from the gallery Plains, area index 250, ID 745, created by Aloe_vera + { + // Size: + 7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 6, 2, 6, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 1: 0\n" /* stone */ + "b: 5: 0\n" /* wood */ + "c: 28: 0\n" /* detectorrail */ + "d: 28: 2\n" /* detectorrail */ + "e: 28: 3\n" /* detectorrail */ + "f: 28: 5\n" /* detectorrail */ + "g: 50: 5\n" /* torch */ + "h: 28: 4\n" /* detectorrail */ + "i: 28: 1\n" /* detectorrail */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 0 + /* z\x* 0123456 */ + /* 0 */ "aaab..." + /* 1 */ "abbbbb." + /* 2 */ "abbb.b." + /* 3 */ "bbbb.bb" + /* 4 */ ".b...b." + /* 5 */ ".bbbbb." + /* 6 */ "...b..." + + // Level 1 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".cdbec." + /* 2 */ ".fg..f." + /* 3 */ ".b.g.b." + /* 4 */ ".h...h." + /* 5 */ ".cdbec." + /* 6 */ "......." + + // Level 2 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ "...i..." + /* 2 */ "......." + /* 3 */ ".c...c." + /* 4 */ "......." + /* 5 */ "...i..." + /* 6 */ ".......", + + // Connectors: + "1: 6, 1, 3: 5\n" /* Type 1, direction X+ */ + "-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */ + "1: 3, 1, 0: 2\n" /* Type 1, direction Z- */ + "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */ + "1: 0, 1, 3: 4\n" /* Type 1, direction X- */ + "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */ + "1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */ + "-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + false, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + + // MoveToGround: + false, + }, // DetectorRail + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PowerRail: + // The data has been exported from the gallery Plains, area index 248, ID 743, created by Aloe_vera + { + // Size: + 7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 6, 2, 6, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 1: 0\n" /* stone */ + "b: 5: 0\n" /* wood */ + "c: 27: 0\n" /* poweredrail */ + "d: 27: 2\n" /* poweredrail */ + "e: 27: 3\n" /* poweredrail */ + "f: 27: 5\n" /* poweredrail */ + "g: 50: 5\n" /* torch */ + "h: 27: 4\n" /* poweredrail */ + "i: 27: 1\n" /* poweredrail */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 0 + /* z\x* 0123456 */ + /* 0 */ "aaab..." + /* 1 */ "abbbbb." + /* 2 */ "abbb.b." + /* 3 */ "bbbb.bb" + /* 4 */ ".b...b." + /* 5 */ ".bbbbb." + /* 6 */ "...b..." + + // Level 1 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".cdbec." + /* 2 */ ".fg..f." + /* 3 */ ".b.g.b." + /* 4 */ ".h...h." + /* 5 */ ".cdbec." + /* 6 */ "......." + + // Level 2 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ "...i..." + /* 2 */ "......." + /* 3 */ ".c...c." + /* 4 */ "......." + /* 5 */ "...i..." + /* 6 */ ".......", + + // Connectors: + "1: 6, 1, 3: 5\n" /* Type 1, direction X+ */ + "-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */ + "1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */ + "-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */ + "1: 0, 1, 3: 4\n" /* Type 1, direction X- */ + "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */ + "1: 3, 1, 0: 2\n" /* Type 1, direction Z- */ + "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */ + "1: 6, 1, 3: 5\n" /* Type 1, direction X+ */ + "-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + false, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + + // MoveToGround: + false, + }, // PowerRail + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // RegularRail: + // The data has been exported from the gallery Plains, area index 247, ID 742, created by Aloe_vera + { + // Size: + 7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 6, 2, 6, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 1: 0\n" /* stone */ + "b: 5: 0\n" /* wood */ + "c: 66: 6\n" /* tracks */ + "d: 66: 2\n" /* tracks */ + "e: 66: 3\n" /* tracks */ + "f: 66: 7\n" /* tracks */ + "g: 66: 5\n" /* tracks */ + "h: 50: 5\n" /* torch */ + "i: 66: 4\n" /* tracks */ + "j: 66: 9\n" /* tracks */ + "k: 66: 8\n" /* tracks */ + "l: 66: 1\n" /* tracks */ + "m: 19: 0\n" /* sponge */ + "n: 66: 0\n" /* tracks */, + + // Block data: + // Level 0 + /* z\x* 0123456 */ + /* 0 */ "aaab..." + /* 1 */ "abbbbb." + /* 2 */ "abbb.b." + /* 3 */ "bbbb.bb" + /* 4 */ ".b...b." + /* 5 */ ".bbbbb." + /* 6 */ "...b..." + + // Level 1 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".cdbef." + /* 2 */ ".gh..g." + /* 3 */ ".b.h.b." + /* 4 */ ".i...i." + /* 5 */ ".jdbek." + /* 6 */ "......." + + // Level 2 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ "...l..." + /* 2 */ "......." + /* 3 */ ".n...n." + /* 4 */ "......." + /* 5 */ "...l..." + /* 6 */ ".......", + + // Connectors: + "1: 6, 1, 3: 5\n" /* Type 1, direction X+ */ + "-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */ + "1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */ + "-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */ + "1: 0, 1, 3: 4\n" /* Type 1, direction X- */ + "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */ + "1: 3, 1, 0: 2\n" /* Type 1, direction Z- */ + "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + false, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + + // MoveToGround: + false, + }, // RegularRail +}; // g_TestRailsPrefabs + + + + + + +const cPrefab::sDef g_TestRailsStartingPrefabs[] = +{ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // CentralPiece: + // The data has been exported from the gallery Plains, area index 249, ID 744, created by Aloe_vera + { + // Size: + 6, 3, 6, // SizeX = 6, SizeY = 3, SizeZ = 6 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 5, 2, 5, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 1: 0\n" /* stone */ + "b: 5: 0\n" /* wood */ + "c: 66: 6\n" /* tracks */ + "d: 66: 2\n" /* tracks */ + "e: 66: 3\n" /* tracks */ + "f: 66: 7\n" /* tracks */ + "g: 66: 5\n" /* tracks */ + "h: 50: 5\n" /* torch */ + "i: 66: 4\n" /* tracks */ + "j: 66: 9\n" /* tracks */ + "k: 66: 8\n" /* tracks */ + "l: 66: 1\n" /* tracks */ + "m: 19: 0\n" /* sponge */ + "n: 66: 0\n" /* tracks */, + + // Block data: + // Level 0 + /* z\x* 012345 */ + /* 0 */ "aaab.." + /* 1 */ "abbbbb" + /* 2 */ "abbb.b" + /* 3 */ "bbbb.b" + /* 4 */ ".b...b" + /* 5 */ ".bbbbb" + + // Level 1 + /* z\x* 012345 */ + /* 0 */ "......" + /* 1 */ ".cdbef" + /* 2 */ ".gh..g" + /* 3 */ ".b.h.b" + /* 4 */ ".i...i" + /* 5 */ ".jdbek" + + // Level 2 + /* z\x* 012345 */ + /* 0 */ "......" + /* 1 */ "...l.." + /* 2 */ "......" + /* 3 */ ".n...n" + /* 4 */ "......" + /* 5 */ "...l..", + + // Connectors: + "1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */ + "1: 0, 1, 3: 4\n" /* Type 1, direction X- */ + "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */ + "-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */ + "1: 6, 1, 3: 5\n" /* Type 1, direction X+ */ + "-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */ + "1: 3, 1, 0: 2\n" /* Type 1, direction Z- */ + "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + + // MoveToGround: + false, + }, // CentralPiece +}; + + + + + +// The prefab counts: + +const size_t g_TestRailsPrefabsCount = ARRAYCOUNT(g_TestRailsPrefabs); + +const size_t g_TestRailsStartingPrefabsCount = ARRAYCOUNT(g_TestRailsStartingPrefabs); + diff --git a/src/Generating/Prefabs/TestRailsPrefabs.h b/src/Generating/Prefabs/TestRailsPrefabs.h new file mode 100644 index 000000000..24b84de74 --- /dev/null +++ b/src/Generating/Prefabs/TestRailsPrefabs.h @@ -0,0 +1,15 @@ + +// TestRailsPrefabs.h + +// Declares the prefabs in the group TestRails + +#include "../Prefab.h" + + + + + +extern const cPrefab::sDef g_TestRailsPrefabs[]; +extern const cPrefab::sDef g_TestRailsStartingPrefabs[]; +extern const size_t g_TestRailsPrefabsCount; +extern const size_t g_TestRailsStartingPrefabsCount; diff --git a/src/Generating/TestRailsGen.cpp b/src/Generating/TestRailsGen.cpp new file mode 100644 index 000000000..c40c1a9b6 --- /dev/null +++ b/src/Generating/TestRailsGen.cpp @@ -0,0 +1,116 @@ + +// TestRailsGen.cpp + +// Implements the cTestRailsGen class representing the testing rails generator + +#include "Globals.h" +#include "TestRailsGen.h" +#include "Prefabs/TestRailsPrefabs.h" +#include "PieceGenerator.h" + + + + + +static cPrefabPiecePool g_TestRails(g_TestRailsPrefabs, g_TestRailsPrefabsCount, g_TestRailsStartingPrefabs, g_TestRailsStartingPrefabsCount); + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cTestRailsGen::cTestRails: + +class cTestRailsGen::cTestRails : + public cGridStructGen::cStructure +{ + typedef cGridStructGen::cStructure super; + +public: + cTestRails( + int a_Seed, + int a_GridX, int a_GridZ, + int a_OriginX, int a_OriginZ, + int a_MaxDepth, + int a_MaxSize + ) : + super(a_GridX, a_GridZ, a_OriginX, a_OriginZ), + m_Seed(a_Seed), + m_Noise(a_Seed), + m_MaxSize(a_MaxSize), + m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, 255, a_OriginZ + a_MaxSize) + { + // Generate the pieces for this test: + cBFSPieceGenerator pg(g_TestRails, a_Seed); + pg.PlacePieces(a_OriginX, 150, a_OriginZ, a_MaxDepth, m_Pieces); + if (m_Pieces.empty()) + { + return; + } + } + + ~cTestRails() + { + cPieceGenerator::FreePieces(m_Pieces); + } + +protected: + /** Seed for the random functions */ + int m_Seed; + + /** The noise used as a pseudo-random generator */ + cNoise m_Noise; + + /** Maximum size, in X/Z blocks, of the structure (radius from the origin) */ + int m_MaxSize; + + /** Borders of the structure - no item may reach out of this cuboid. */ + cCuboid m_Borders; + + /** The rails pieces, placed by the generator. */ + cPlacedPieces m_Pieces; + + + // cGridStructGen::cStructure overrides: + virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override + { + for (cPlacedPieces::iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr) + { + cPrefab & Prefab = (cPrefab &)((*itr)->GetPiece()); + Prefab.Draw(a_Chunk, *itr); + } // for itr - m_PlacedPieces[] + } +} ; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cTestRailsGen: + + + + + +cTestRailsGen::cTestRailsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize) : + super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100), + m_Noise(a_Seed + 1000), + m_MaxDepth(a_MaxDepth), + m_MaxSize(a_MaxSize) +{ +} + + + + + +cGridStructGen::cStructurePtr cTestRailsGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) +{ + // Create a base based on the chosen prefabs: + return cStructurePtr(new cTestRails(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize)); +} + + + + diff --git a/src/Generating/TestRailsGen.h b/src/Generating/TestRailsGen.h new file mode 100644 index 000000000..5b0ce95f4 --- /dev/null +++ b/src/Generating/TestRailsGen.h @@ -0,0 +1,47 @@ + +// TestRailsGen.h + +// Declares the cTestRailsGen class representing the testing rails generator + + + + + +#pragma once + +#include "GridStructGen.h" +#include "PrefabPiecePool.h" + + + + + +class cTestRailsGen : + public cGridStructGen +{ + typedef cGridStructGen super; + +public: + cTestRailsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize); + +protected: + class cTestRails; // fwd: TestRailsGen.cpp + + + /** The noise used for generating random numbers */ + cNoise m_Noise; + + /** Maximum depth of the generator tree*/ + int m_MaxDepth; + + /** Maximum size, in X/Z blocks, of the base (radius from the origin) */ + int m_MaxSize; + + + // cGridStructGen overrides: + virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override; +} ; + + + + -- cgit v1.2.3