diff --git a/src/Block.c b/src/Block.c index 4a8659505..ff7997fbe 100644 --- a/src/Block.c +++ b/src/Block.c @@ -687,182 +687,59 @@ static int FindAutoRotateType(cc_string* dir) { return -1; } -static int IsBlockVisibleInInventory(int blockID) { - int i; - for (i = 0; i < Array_Elems(Inventory.Map); i++ ) { - if (Inventory.Map[i] == blockID) { return 1; } - } - return 0; -} - -static int Block_FindIDNonHidden(const cc_string* name) { - cc_string blockName; - int block; - - for (block = BLOCK_AIR; block < BLOCK_COUNT; block++) { - blockName = Block_UNSAFE_GetName(block); - if (String_CaselessEquals(&blockName, name) && ( IsBlockVisibleInInventory(block) > 0)) { - return block; - } - } - return -1; -} - -static int Swap1AtIndexAndFind(cc_string* blockName, int index, char c) { - /* +1 to skip over the dash */ - blockName->buffer[index+1] = c; - return Block_FindIDNonHidden(blockName); -} -static int Swap2AtIndexAndFind(cc_string* blockName, int index, char c, char c2) { - /* +1 to skip over the dash */ - blockName->buffer[index + 1] = c; - blockName->buffer[index + 2] = c2; - return Block_FindIDNonHidden(blockName); -} - -static int FindMatchingCorner(cc_string* blockName, int rotIndex) { - int blockID = -1; - blockID = Swap2AtIndexAndFind(blockName, rotIndex, 'N', 'E'); - if (blockID != -1) { return blockID; } - blockID = Swap2AtIndexAndFind(blockName, rotIndex, 'N', 'W'); - if (blockID != -1) { return blockID; } - blockID = Swap2AtIndexAndFind(blockName, rotIndex, 'S', 'W'); - if (blockID != -1) { return blockID; } - blockID = Swap2AtIndexAndFind(blockName, rotIndex, 'S', 'E'); - if (blockID != -1) { return blockID; } - return -1; -} -static int FindMatchingUpDown(cc_string* blockName, int upDownIndex) { - int blockID = -1; - blockID = Swap1AtIndexAndFind(blockName, upDownIndex, 'D'); - if (blockID != -1) { return blockID; } - blockID = Swap1AtIndexAndFind(blockName, upDownIndex, 'U'); - if (blockID != -1) { return blockID; } - return -1; -} -static int FindMatchingDirection(cc_string* blockName, int rotIndex) { - int blockID = -1; - blockID = Swap1AtIndexAndFind(blockName, rotIndex, 'N'); - if (blockID != -1) { return blockID; } - blockID = Swap1AtIndexAndFind(blockName, rotIndex, 'E'); - if (blockID != -1) { return blockID; } - blockID = Swap1AtIndexAndFind(blockName, rotIndex, 'S'); - if (blockID != -1) { return blockID; } - blockID = Swap1AtIndexAndFind(blockName, rotIndex, 'W'); - if (blockID != -1) { return blockID; } - return -1; -} -static int FindMatchingPillar(cc_string* blockName, int rotIndex) { - int blockID = -1; - blockID = Swap2AtIndexAndFind(blockName, rotIndex, 'U', 'D'); - if (blockID != -1) { return blockID; } - blockID = Swap2AtIndexAndFind(blockName, rotIndex, 'W', 'E'); - if (blockID != -1) { return blockID; } - blockID = Swap2AtIndexAndFind(blockName, rotIndex, 'N', 'S'); - if (blockID != -1) { return blockID; } - return -1; -} - -BlockID AutoRotate_PickBlock(BlockID block) { - cc_string blockName; char strBuffer[STRING_SIZE * 2]; - cc_string name; - int rotated; - - /* copy name to blockName so modifying it doesn't ruin the original */ - name = Block_UNSAFE_GetName(block); - String_InitArray(blockName, strBuffer); - String_AppendString(&blockName, &name); - - int dirType = -1; - int dirType2 = -1; +static void GetAutoRotateTypes(cc_string* blockName, int* dirType, int* dirType2, int* suffixIndex) { + *dirType = -1; + *dirType2 = -1; + *suffixIndex = -1; /* index of rightmost group separated by dashes */ - int dirIndex = String_LastIndexOfAt(&blockName, 0, '-'); + int dirIndex = String_LastIndexOfAt(blockName, 0, '-'); /* not an autorotate block */ - if (dirIndex == -1) { return block; } + if (dirIndex == -1) { return; } + *suffixIndex = dirIndex; cc_string dir; - dir = String_UNSAFE_SubstringAt(&blockName, dirIndex); + dir = String_UNSAFE_SubstringAt(blockName, dirIndex); - dirType = FindAutoRotateType(&dir); + *dirType = FindAutoRotateType(&dir); /* index of next rightmost group separated by dashes */ - int dirIndex2 = String_NthIndexOfFromRight(&blockName, '-', 2); + int dirIndex2 = String_NthIndexOfFromRight(blockName, '-', 2); if (dirIndex2 != -1) { + *suffixIndex = dirIndex2; cc_string dir2; - dir2 = String_UNSAFE_SubstringAt(&blockName, dirIndex2); + dir2 = String_UNSAFE_SubstringAt(blockName, dirIndex2); /* chop off the rightmost group by subtracting its length */ dir2.length -= dir.length; - dirType2 = FindAutoRotateType(&dir2); + *dirType2 = FindAutoRotateType(&dir2); } - - /* the second-rightmost group is automatically invalid if neither group uses up/down */ - if (!(dirType == 1 || dirType2 == 1)) { - dirType2 = -1; - dirIndex2 = -1; - } - - int upDownIndex = -1; - int rotIndex = dirIndex; - int rotType = dirType; - if (dirType == 1) { - upDownIndex = dirIndex; - rotIndex = dirIndex2; - rotType = dirType2; - } - else if (dirType2 == 1) { - upDownIndex = dirIndex2; - } - - int result; - if (upDownIndex != -1 && rotIndex != -1) { /* it uses up/down and another type of rotation */ - if (rotType == 0) { - blockName.buffer[upDownIndex + 1] = 'D'; - result = FindMatchingCorner(&blockName, rotIndex); - if (result != -1) { return (BlockID)result; } - blockName.buffer[upDownIndex + 1] = 'U'; - result = FindMatchingCorner(&blockName, rotIndex); - if (result != -1) { return (BlockID)result; } - } else if (rotType == 2) { - blockName.buffer[upDownIndex + 1] = 'D'; - result = FindMatchingDirection(&blockName, rotIndex); - if (result != -1) { return (BlockID)result; } - blockName.buffer[upDownIndex + 1] = 'U'; - result = FindMatchingDirection(&blockName, rotIndex); - if (result != -1) { return (BlockID)result; } - } - else if (rotType == 3) { - blockName.buffer[upDownIndex + 1] = 'D'; - result = FindMatchingPillar(&blockName, rotIndex); - if (result != -1) { return (BlockID)result; } - blockName.buffer[upDownIndex + 1] = 'U'; - result = FindMatchingPillar(&blockName, rotIndex); - if (result != -1) { return (BlockID)result; } - } - } else if (upDownIndex == -1 ) { /* just one autorotate group and it's not up/down */ - if (rotType == 0) { - result = FindMatchingCorner(&blockName, rotIndex); - if (result != -1) { return (BlockID)result; } - } - else if (rotType == 2) { - result = FindMatchingDirection(&blockName, rotIndex); - if (result != -1) { return (BlockID)result; } - } - else if (rotType == 3) { - result = FindMatchingPillar(&blockName, rotIndex); - if (result != -1) { return (BlockID)result; } - } - } else if (rotIndex == -1) { /* only up/down autorotate */ - result = FindMatchingUpDown(&blockName, upDownIndex); - if (result != -1) { return (BlockID)result; } - } - - return block; } +cc_bool AutoRotate_BlocksShareGroup(BlockID block, BlockID blockOther) { + cc_string blockName; cc_string blockNameOther; + char strBuffer[STRING_SIZE]; char strBufferOther[STRING_SIZE]; + int suffixIndex; int suffixIndexOther; + int dirType; int dirType2; + int dirTypeOther; int dirTypeOther2; + + blockName = Block_UNSAFE_GetName(block); + GetAutoRotateTypes(&blockName, &dirType, &dirType2, &suffixIndex); + if (suffixIndex == -1) { return 0; } + + blockNameOther = Block_UNSAFE_GetName(blockOther); + GetAutoRotateTypes(&blockNameOther, &dirTypeOther, &dirTypeOther2, &suffixIndexOther); + if (suffixIndexOther == -1) { return 0; } + + if (dirType == dirTypeOther && dirType2 == dirTypeOther2) { + blockName.length += suffixIndex - blockName.length; + blockNameOther.length += suffixIndexOther - blockNameOther.length; + if (String_CaselessEquals(&blockName, &blockNameOther)) { return 1; } + } + return 0; +} /*########################################################################################################################* *----------------------------------------------------Blocks component-----------------------------------------------------* diff --git a/src/Block.h b/src/Block.h index a47ec56d7..5b3391516 100644 --- a/src/Block.h +++ b/src/Block.h @@ -156,7 +156,6 @@ extern cc_bool AutoRotate_Enabled; /* Attempts to find the rotated block based on the user's orientation and offset on selected block. */ /* If no rotated block is found, returns given block. */ BlockID AutoRotate_RotateBlock(BlockID block); -/* Attempts to pick a single consistent block from the auto-rotate set that the given block is part of */ -/* If no rotated block is found, returns given block. */ -BlockID AutoRotate_PickBlock(BlockID block); +/* Returns non 0 if both blocks belong to the same autorotate group */ +cc_bool AutoRotate_BlocksShareGroup(BlockID block, BlockID blockOther); #endif diff --git a/src/Input.c b/src/Input.c index afc5aea82..407d7ac85 100644 --- a/src/Input.c +++ b/src/Input.c @@ -738,7 +738,6 @@ static void DoPickBlock(void) { cur = World_GetBlock(pos.X, pos.Y, pos.Z); if (Blocks.Draw[cur] == DRAW_GAS) return; - if (AutoRotate_Enabled) { cur = AutoRotate_PickBlock(cur); } if (!(Blocks.CanPlace[cur] || Blocks.CanDelete[cur])) return; Inventory_PickBlock(cur); } diff --git a/src/Inventory.c b/src/Inventory.c index ed24b3fb1..7fcebdc35 100644 --- a/src/Inventory.c +++ b/src/Inventory.c @@ -46,17 +46,28 @@ void Inventory_PickBlock(BlockID block) { int i; if (!Inventory_CheckChangeSelected() || Inventory_SelectedBlock == block) return; - /* Is the currently selected block an empty slot? */ - if (Inventory_SelectedBlock == BLOCK_AIR) { - Inventory_SetSelectedBlock(block); return; - } - /* Try to replace same block */ for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR; i++) { if (Inventory_Get(i) != block) continue; Inventory_SetSelectedIndex(i); return; } + if (AutoRotate_Enabled) { + /* Try to replace existing autorotate variant */ + for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR; i++) { + if (AutoRotate_BlocksShareGroup(Inventory_Get(i), block)) { + Inventory_SetSelectedIndex(i); + Inventory_SetSelectedBlock(block); + return; + } + } + } + + /* Is the currently selected block an empty slot? */ + if (Inventory_SelectedBlock == BLOCK_AIR) { + Inventory_SetSelectedBlock(block); return; + } + /* Try to replace empty slots */ for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR; i++) { if (Inventory_Get(i) != BLOCK_AIR) continue;