mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 09:35:23 -04:00
If auto rotate is on, only pick one block variant out of the set when using pick block
This commit is contained in:
parent
18b98c8236
commit
37e42233e7
196
src/Block.c
196
src/Block.c
@ -667,6 +667,202 @@ BlockID AutoRotate_RotateBlock(BlockID block) {
|
|||||||
return rotated == -1 ? block : (BlockID)rotated;
|
return rotated == -1 ? block : (BlockID)rotated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int FindAutoRotateType(cc_string* dir) {
|
||||||
|
char dir0, dir1;
|
||||||
|
|
||||||
|
dir0 = dir->length > 1 ? dir->buffer[1] : '\0'; Char_MakeLower(dir0);
|
||||||
|
dir1 = dir->length > 2 ? dir->buffer[2] : '\0'; Char_MakeLower(dir1);
|
||||||
|
if (AR_EQ2(dir, 'n', 'w') || AR_EQ2(dir, 'n', 'e') || AR_EQ2(dir, 's', 'w') || AR_EQ2(dir, 's', 'e')) {
|
||||||
|
return 0; /* corner */
|
||||||
|
}
|
||||||
|
else if (AR_EQ1(dir, 'u') || AR_EQ1(dir, 'd')) {
|
||||||
|
return 1; /* up/down */
|
||||||
|
}
|
||||||
|
else if (AR_EQ1(dir, 'n') || AR_EQ1(dir, 'w') || AR_EQ1(dir, 's') || AR_EQ1(dir, 'e')) {
|
||||||
|
return 2; /* directional */
|
||||||
|
}
|
||||||
|
else if (AR_EQ2(dir, 'u', 'd') || AR_EQ2(dir, 'w', 'e') || AR_EQ2(dir, 'n', 's')) {
|
||||||
|
return 3; /* pillar */
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* index of rightmost group separated by dashes */
|
||||||
|
int dirIndex = String_LastIndexOfAt(&blockName, 0, '-');
|
||||||
|
|
||||||
|
/* not an autorotate block */
|
||||||
|
if (dirIndex == -1) { return block; }
|
||||||
|
|
||||||
|
cc_string dir;
|
||||||
|
dir = String_UNSAFE_SubstringAt(&blockName, dirIndex);
|
||||||
|
|
||||||
|
dirType = FindAutoRotateType(&dir);
|
||||||
|
|
||||||
|
/* index of next rightmost group separated by dashes */
|
||||||
|
int dirIndex2 = String_NthIndexOfFromRight(&blockName, '-', 2);
|
||||||
|
|
||||||
|
if (dirIndex2 != -1) {
|
||||||
|
cc_string dir2;
|
||||||
|
dir2 = String_UNSAFE_SubstringAt(&blockName, dirIndex2);
|
||||||
|
/* chop off the rightmost group by subtracting its length */
|
||||||
|
dir2.length -= dir.length;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*----------------------------------------------------Blocks component-----------------------------------------------------*
|
*----------------------------------------------------Blocks component-----------------------------------------------------*
|
||||||
|
@ -738,6 +738,7 @@ static void DoPickBlock(void) {
|
|||||||
|
|
||||||
cur = World_GetBlock(pos.X, pos.Y, pos.Z);
|
cur = World_GetBlock(pos.X, pos.Y, pos.Z);
|
||||||
if (Blocks.Draw[cur] == DRAW_GAS) return;
|
if (Blocks.Draw[cur] == DRAW_GAS) return;
|
||||||
|
if (AutoRotate_Enabled) { cur = AutoRotate_PickBlock(cur); }
|
||||||
if (!(Blocks.CanPlace[cur] || Blocks.CanDelete[cur])) return;
|
if (!(Blocks.CanPlace[cur] || Blocks.CanDelete[cur])) return;
|
||||||
Inventory_PickBlock(cur);
|
Inventory_PickBlock(cur);
|
||||||
}
|
}
|
||||||
|
16
src/String.c
16
src/String.c
@ -291,6 +291,22 @@ int String_LastIndexOfAt(const cc_string* str, int offset, char c) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int String_NthIndexOfFromRight(const cc_string* str, char c, int number) {
|
||||||
|
int nth = 1;
|
||||||
|
int i;
|
||||||
|
for (i = (str->length - 1); i >= 0; i--) {
|
||||||
|
if (str->buffer[i] == c) {
|
||||||
|
if (number == nth) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nth++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void String_InsertAt(cc_string* str, int offset, char c) {
|
void String_InsertAt(cc_string* str, int offset, char c) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user