Having trouble effectively wrapping int value

I’m working on a routine which lets the player scroll through his item array, and I’m effectively trying to clamp the value in a way that makes it wrap around: every keypress increments or decrements the item ID by one, and every time it changes I run it through the following function, which is supposed to catch out-of-range values and wrap them around:

int32 UCharacterInventory::RollInventoryID(int32 ID){
	int32 desiredSlot = ID;
	
	if (characterInventory.generalItems.Num() == 0 && ID > characterInventory.generalItems.Num()){ //If there aren't any items in the array, or the ID is higher than the number of items, wrap around to 0
		desiredSlot = 0;
	}
	else if (ID < 0){
		desiredSlot = characterInventory.generalItems.Num() - 1; //If the ID is negative, wrap around to the highest index in the array
	}
	return desiredSlot; //If neither of the above conditions have been met, return the number you started with
}

However, this isn’t working at all- whenever it runs, incrementing or decrementing the value will always alternate between two items, and skip all of the others. Is there an obvious problem my eyes are skipping over?

What value are you passing into the function? How does in/decreasing the ID work?

Sorry, I should’ve been more articulate. :slight_smile: The core inventory object is a single TArray, and the int ID refers to the index of that array that a given item resides in. Flipping through items is done with two arbitrary keys (I used left and right mousewheel), one key is arbitrarily labelled as Increment and one as Decrement.

The main logic, which works without problems, is to fire an event whenever either key is hit. Increment just executes ID = FMath::Clamp(ID, 0, ItemArray.Num()-1) +1, and Decrement executes ID = FMath::Clamp(ID, 0, ItemArray.Num()-1)- 1. The resulting behavior is that repeatedly hitting Increment will scroll through items until I’m at the last entry of the array, likewise Decrement scrolls back up.

What I’m trying to do with the rollback function I pasted in the first post is make it so if you hit Increment, and you’re already at the last entry, instead of just staying there, it will reset the ID to 0, and effectively send you back to the top of the list, and likewise hitting Decrement at 0 will set the ID to array.Num()-1, the bottom of the list, effectively making item selection a circle instead of a straight line.

Hey HInoue-

If the array is empty then attempting to loop to the first element will fail since the element doesn’t exist. You would likely want to check this before entering the function posted. Alternatively, if there is nothing in the array you can add an empty actor to it to have at least one element present, you would still want to do this before this function call though. In that case your if() statement would only need to check the second condition of if you are already at the last element of the array.

Cheers

Hmm okay… is there a reason based on what you see for this to fail with a full array, though? That’s what’s really weird. When I run it with any number of indexes over 2, it will always flip between the first and last index, and never cover the ones in-between.

Rather than trying to increment/decrement the result of your Clamp you should preform the increment/decrement first and then clamp that result to make sure you’re within the bounds of your array.

Alrighty, thank you very much :slight_smile:

On line 4, did you mean || instead of &&?