One way to consider implementing lighting patterns without delays is to create a function for each block of code in between the delays. Then create an array of function pointers containing all these and an array with the delay values. Example:
void allOn() { // code here }
void allOff() { // code here }
void halfOn() { // code here }
void halfOff() { // code here }
// Create an array of function pointers
void (*steps[4]) () = { allOn, allOff, halfOn, halfOff };
// Create an array of interval times
unsigned long intervals[4] = { 0, 50, 50, 50 };
You then need a variable to keep track of where you are in your arrays and last time you moved on:
int t=0;
unsigned long lastChange=0;
Then in your loop, you check if it's been long enough:
if (millis() - lastChange > intervals[t]) {
...
}
Then you simple have to reset the timer, run the appropriately indexed function, and increment your index. Of course, you'll also have to check if the index goesd above your bounds and reset it to 0. Completely untested, but this should give you a good template to use as it is organized, uses no delays, and scales up very easily.