mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 11:06:06 -04:00
New behavior for pick block:
If you are holding air and the block you're picking exists in your hotbar, your selector moves there instead of the block being brought to the air spot. If auto rotate is on, when you pick an autorotate block, if a block from the same group already existed in your hotbar, it goes to that spot and replaces the old rotation variant with the new one you picked
This commit is contained in:
parent
52032a5a21
commit
9c4ce31386
193
src/Block.c
193
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-----------------------------------------------------*
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user