From 2f8574f62bb7731031bf950258a02756d5620bac Mon Sep 17 00:00:00 2001 From: cracker64 Date: Mon, 6 May 2013 13:30:03 -0400 Subject: [PATCH 1/3] gol2 array is static size, adding new GoL won't increase memory usage. --- src/simulation/Simulation.cpp | 30 ++++++++++++++++++++++++------ src/simulation/Simulation.h | 3 +-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index 577da9343..699a61167 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -3560,8 +3560,22 @@ void Simulation::update_particles_i(int start, int inc) rt = pmap[ady][adx]; if (!rt || (rt&0xFF)==PT_LIFE) { - gol2[ady][adx][golnum] ++; + //the total neighbor count is in 0 gol2[ady][adx][0] ++; + //insert golnum into neighbor table + for ( i=1; i<9; i++) + { + if (!gol2[ady][adx][i]) + { + gol2[ady][adx][i] = (golnum<<4)+1; + break; + } + else if((gol2[ady][adx][i]>>4)==golnum) + { + gol2[ady][adx][i]++; + break; + } + } } } } @@ -3585,21 +3599,25 @@ void Simulation::update_particles_i(int start, int inc) if (!r) { //Find which type we can try and create - for (golnum = 1; golnum<=NGOL; golnum++) + int creategol = 0xFF; + for ( i=1; i<9; i++) { - if (grule[golnum][neighbors]>=2 && gol2[ny][nx][golnum]>=(neighbors%2)+neighbors/2) + if (!gol2[ny][nx][i]) break; + golnum = (gol2[ny][nx][i]>>4); + if (grule[golnum][neighbors]>=2 && (gol2[ny][nx][i]&0xF)>=(neighbors%2)+neighbors/2) { - create_part(-1, nx, ny, PT_LIFE|((golnum-1)<<8)); - break; + if (golnum>8].tmp==grule[golnum][9]-1) parts[r>>8].tmp --; } - for ( z = 0; z<=NGOL; z++) + for ( z = 0; z<9; z++) gol2[ny][nx][z] = 0;//this improves performance A LOT compared to the memset, i was getting ~23 more fps with this. } //we still need to kill things with 0 neighbors (higher state life) diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h index 9e9424f94..5ce0d1e5a 100644 --- a/src/simulation/Simulation.h +++ b/src/simulation/Simulation.h @@ -74,10 +74,9 @@ public: int emp_decor; //Gol sim int CGOL; - int ISGOL; int GSPEED; unsigned char gol[YRES][XRES]; - unsigned char gol2[YRES][XRES][NGOL+1]; + unsigned short gol2[YRES][XRES][9]; //Air sim float (*vx)[XRES/CELL]; float (*vy)[XRES/CELL]; From 20c261826d3e0cf5c00cbd6ba9312bbed86900cd Mon Sep 17 00:00:00 2001 From: jacksonmj Date: Tue, 7 May 2013 15:01:24 +0100 Subject: [PATCH 2/3] STKM - fix jumping in the x direction in different gravity modes --- src/simulation/elements/STKM.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/simulation/elements/STKM.cpp b/src/simulation/elements/STKM.cpp index 52deee104..faeb5f912 100644 --- a/src/simulation/elements/STKM.cpp +++ b/src/simulation/elements/STKM.cpp @@ -227,7 +227,10 @@ int Element_STKM::run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { if (((int)(playerp->comm)&0x04) == 0x04 && (!sim->eval_move(t, playerp->legs[4], playerp->legs[5], NULL) || !sim->eval_move(t, playerp->legs[12], playerp->legs[13], NULL))) { + parts[i].vx -= 4*gvx; parts[i].vy -= 4*gvy; + playerp->accs[2] -= gvx; + playerp->accs[6] -= gvx; playerp->accs[3] -= gvy; playerp->accs[7] -= gvy; } From 89a0603b53b314345d93e422dd945848ea3a9938 Mon Sep 17 00:00:00 2001 From: jacksonmj Date: Tue, 7 May 2013 17:36:43 +0100 Subject: [PATCH 3/3] Rocket boots for stickman, because why not Pass through gravity wall to activate, fan wall to deactivate. Accelerate with left/up/right keys. Plasma is spawned when accelerating, and STKM is immune to plasma but not other hot elements when rocket boots are enabled. Hold left+right to slow down quickly. STKM spawn element is retained and can still be created while using rocket boots, but it may be difficult to do anything useful with the spawn element whilst spewing hot plasma everywhere. --- src/graphics/Renderer.cpp | 21 +++++ src/simulation/Simulation.cpp | 5 ++ src/simulation/Stickman.h | 1 + src/simulation/elements/STKM.cpp | 141 ++++++++++++++++++++++++++++--- 4 files changed, 157 insertions(+), 11 deletions(-) diff --git a/src/graphics/Renderer.cpp b/src/graphics/Renderer.cpp index 1f4aed872..af6826ee1 100644 --- a/src/graphics/Renderer.cpp +++ b/src/graphics/Renderer.cpp @@ -1483,6 +1483,27 @@ void Renderer::render_parts() draw_line(cplayer->legs[0], cplayer->legs[1], cplayer->legs[4], cplayer->legs[5], legr, legg, legb, 255); draw_line(nx, ny+3, cplayer->legs[8], cplayer->legs[9], legr, legg, legb, 255); draw_line(cplayer->legs[8], cplayer->legs[9], cplayer->legs[12], cplayer->legs[13], legr, legg, legb, 255); + if (cplayer->rocketBoots) + { + for (int leg=0; leg<2; leg++) + { + int nx = cplayer->legs[leg*8+4], ny = cplayer->legs[leg*8+5]; + int colr = 255, colg = 0, colb = 255; + if (((int)(cplayer->comm)&0x04) == 0x04 || (((int)(cplayer->comm)&0x01) == 0x01 && leg==0) || (((int)(cplayer->comm)&0x02) == 0x02 && leg==1)) + blendpixel(nx, ny, 0, 255, 0, 255); + else + blendpixel(nx, ny, 255, 0, 0, 255); + blendpixel(nx+1, ny, colr, colg, colb, 223); + blendpixel(nx-1, ny, colr, colg, colb, 223); + blendpixel(nx, ny+1, colr, colg, colb, 223); + blendpixel(nx, ny-1, colr, colg, colb, 223); + + blendpixel(nx+1, ny-1, colr, colg, colb, 112); + blendpixel(nx-1, ny-1, colr, colg, colb, 112); + blendpixel(nx+1, ny+1, colr, colg, colb, 112); + blendpixel(nx-1, ny+1, colr, colg, colb, 112); + } + } #endif } if(pixel_mode & PMODE_FLAT) diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index 699a61167..1ab97fdff 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -112,12 +112,14 @@ int Simulation::Load(int fullX, int fullY, GameSave * save) Element_STKM::STKM_init_legs(this, &player, i); player.spwn = 1; player.elem = PT_DUST; + player.rocketBoots = false; } else if (parts[i].type == PT_STKM2) { Element_STKM::STKM_init_legs(this, &player2, i); player2.spwn = 1; player2.elem = PT_DUST; + player2.rocketBoots = false; } else if (parts[i].type == PT_FIGH) { @@ -3052,6 +3054,7 @@ int Simulation::create_part(int p, int x, int y, int tv) Element_STKM::STKM_init_legs(this, &player, i); player.spwn = 1; player.elem = PT_DUST; + player.rocketBoots = false; } else { @@ -3073,6 +3076,7 @@ int Simulation::create_part(int p, int x, int y, int tv) Element_STKM::STKM_init_legs(this, &player2, i); player2.spwn = 1; player2.elem = PT_DUST; + player2.rocketBoots = false; } else { @@ -3108,6 +3112,7 @@ int Simulation::create_part(int p, int x, int y, int tv) Element_STKM::STKM_init_legs(this, &fighters[fcount], i); fighters[fcount].spwn = 1; fighters[fcount].elem = PT_DUST; + fighters[fcount].rocketBoots = false; fighcount++; return i; diff --git a/src/simulation/Stickman.h b/src/simulation/Stickman.h index 0e9cd3c65..a62a747f1 100644 --- a/src/simulation/Stickman.h +++ b/src/simulation/Stickman.h @@ -10,6 +10,7 @@ struct playerst float accs[8]; //accelerations char spwn; //if stick man was spawned unsigned int frames; //frames since last particle spawn - used when spawning LIGH + bool rocketBoots; }; #endif diff --git a/src/simulation/elements/STKM.cpp b/src/simulation/elements/STKM.cpp index faeb5f912..2323be328 100644 --- a/src/simulation/elements/STKM.cpp +++ b/src/simulation/elements/STKM.cpp @@ -74,6 +74,10 @@ int Element_STKM::run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { float dt = 0.9;///(FPSB*FPSB); //Delta time in square float gvx, gvy; float gx, gy, dl, dr; + float rocketBootsHeadEffect = 0.35f; + float rocketBootsFeetEffect = 0.15f; + float rocketBootsHeadEffectV = 0.3f;// stronger acceleration vertically, to counteract gravity + float rocketBootsFeetEffectV = 0.45f; if ((parts[i].ctype>0 && parts[i].ctypeelements[parts[i].ctype].Enabled && sim->elements[parts[i].ctype].Falldown>0) || parts[i].ctype==SPC_AIR || parts[i].ctype == PT_NEUT || parts[i].ctype == PT_PHOT || parts[i].ctype == PT_LIGH) playerp->elem = parts[i].ctype; @@ -123,6 +127,33 @@ int Element_STKM::run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { gvx += sim->gravx[((int)parts[i].y/CELL)*(XRES/CELL)+((int)parts[i].x/CELL)]; gvy += sim->gravy[((int)parts[i].y/CELL)*(XRES/CELL)+((int)parts[i].x/CELL)]; + float rbx = gvx; + float rby = gvy; + bool rbLowGrav = false; + float tmp = fmaxf(fabsf(rbx), fabsf(rby)); + if (tmp < 0.001f) + { + rbLowGrav = true; + rbx = -parts[i].vx; + rby = -parts[i].vy; + tmp = fmaxf(fabsf(rbx), fabsf(rby)); + } + if (tmp < 0.001f) + { + rbx = 0; + rby = 1.0f; + tmp = 1.0f; + } + float rbx1 = rbx/tmp, rby1 = rby/tmp;// scale so that the largest is 1.0 + tmp = 1.0f/sqrtf(rbx*rbx+rby*rby); + rbx *= tmp;// scale to a unit vector + rby *= tmp; + if (rbLowGrav) + { + rocketBootsHeadEffectV = rocketBootsHeadEffect; + rocketBootsFeetEffectV = rocketBootsFeetEffect; + } + parts[i].vx -= gvx*dt; //Head up! parts[i].vy -= gvy*dt; @@ -176,6 +207,7 @@ int Element_STKM::run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { //Go left if (((int)(playerp->comm)&0x01) == 0x01) { + bool moved = false; if (dl>dr) { if (!sim->eval_move(t, playerp->legs[4], playerp->legs[5], NULL)) @@ -184,6 +216,7 @@ int Element_STKM::run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { playerp->accs[3] = 3*gvx-3*gvy; playerp->accs[0] = -gvy; playerp->accs[1] = gvx; + moved = true; } } else @@ -194,6 +227,29 @@ int Element_STKM::run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { playerp->accs[7] = 3*gvx-3*gvy; playerp->accs[0] = -gvy; playerp->accs[1] = gvx; + moved = true; + } + } + if (!moved && playerp->rocketBoots) + { + parts[i].vx -= rocketBootsHeadEffect*rby; + parts[i].vy += rocketBootsHeadEffect*rbx; + playerp->accs[2] -= rocketBootsFeetEffect*rby; + playerp->accs[6] -= rocketBootsFeetEffect*rby; + playerp->accs[3] += rocketBootsFeetEffect*rbx; + playerp->accs[7] += rocketBootsFeetEffect*rbx; + for (int leg=0; leg<2; leg++) + { + if (leg==1 && (((int)(playerp->comm)&0x02) == 0x02)) + continue; + int footX = playerp->legs[leg*8+4], footY = playerp->legs[leg*8+5]; + int np = sim->create_part(-1, footX, footY, PT_PLSM); + if (np>=0) + { + parts[np].vx = parts[i].vx+rby*25; + parts[np].vy = parts[i].vy-rbx*25; + parts[np].life += 30; + } } } } @@ -201,6 +257,7 @@ int Element_STKM::run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { //Go right if (((int)(playerp->comm)&0x02) == 0x02) { + bool moved = false; if (dleval_move(t, playerp->legs[4], playerp->legs[5], NULL)) @@ -209,6 +266,7 @@ int Element_STKM::run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { playerp->accs[3] = -3*gvx-3*gvy; playerp->accs[0] = gvy; playerp->accs[1] = -gvx; + moved = true; } } else @@ -219,20 +277,75 @@ int Element_STKM::run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { playerp->accs[7] = -3*gvx-3*gvy; playerp->accs[0] = gvy; playerp->accs[1] = -gvx; + moved = true; + } + } + if (!moved && playerp->rocketBoots) + { + parts[i].vx += rocketBootsHeadEffect*rby; + parts[i].vy -= rocketBootsHeadEffect*rbx; + playerp->accs[2] += rocketBootsFeetEffect*rby; + playerp->accs[6] += rocketBootsFeetEffect*rby; + playerp->accs[3] -= rocketBootsFeetEffect*rbx; + playerp->accs[7] -= rocketBootsFeetEffect*rbx; + for (int leg=0; leg<2; leg++) + { + if (leg==0 && (((int)(playerp->comm)&0x01) == 0x01)) + continue; + int footX = playerp->legs[leg*8+4], footY = playerp->legs[leg*8+5]; + int np = sim->create_part(-1, footX, footY, PT_PLSM); + if (np>=0) + { + parts[np].vx = parts[i].vx-rby*25; + parts[np].vy = parts[i].vy+rbx*25; + parts[np].life += 30; + } } } } - //Jump - if (((int)(playerp->comm)&0x04) == 0x04 && - (!sim->eval_move(t, playerp->legs[4], playerp->legs[5], NULL) || !sim->eval_move(t, playerp->legs[12], playerp->legs[13], NULL))) + if (playerp->rocketBoots && ((int)(playerp->comm)&0x03) == 0x03) { - parts[i].vx -= 4*gvx; - parts[i].vy -= 4*gvy; - playerp->accs[2] -= gvx; - playerp->accs[6] -= gvx; - playerp->accs[3] -= gvy; - playerp->accs[7] -= gvy; + // Pressing left and right simultaneously with rocket boots on slows the stickman down + // Particularly useful in zero gravity + parts[i].vx *= 0.5f; + parts[i].vy *= 0.5f; + playerp->accs[2] = playerp->accs[6] = 0; + playerp->accs[3] = playerp->accs[7] = 0; + } + + //Jump + if (((int)(playerp->comm)&0x04) == 0x04) + { + if (playerp->rocketBoots) + { + parts[i].vx -= rocketBootsHeadEffectV*rbx; + parts[i].vy -= rocketBootsHeadEffectV*rby; + playerp->accs[2] -= rocketBootsFeetEffectV*rbx; + playerp->accs[6] -= rocketBootsFeetEffectV*rbx; + playerp->accs[3] -= rocketBootsFeetEffectV*rby; + playerp->accs[7] -= rocketBootsFeetEffectV*rby; + for (int leg=0; leg<2; leg++) + { + int footX = playerp->legs[leg*8+4], footY = playerp->legs[leg*8+5]; + int np = sim->create_part(-1, footX, footY+1, PT_PLSM); + if (np>=0) + { + parts[np].vx = parts[i].vx+rbx*30; + parts[np].vy = parts[i].vy+rby*30; + parts[np].life += 10; + } + } + } + else if (!sim->eval_move(t, playerp->legs[4], playerp->legs[5], NULL) || !sim->eval_move(t, playerp->legs[12], playerp->legs[13], NULL)) + { + parts[i].vx -= 4*gvx; + parts[i].vy -= 4*gvy; + playerp->accs[2] -= gvx; + playerp->accs[6] -= gvx; + playerp->accs[3] -= gvy; + playerp->accs[7] -= gvy; + } } //Charge detector wall if foot inside @@ -258,7 +371,8 @@ int Element_STKM::run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { || sim->elements[r&0xFF].Properties&TYPE_LIQUID || (r&0xFF) == PT_NEUT || (r&0xFF) == PT_PHOT) { - playerp->elem = r&0xFF; //Current element + if (!playerp->rocketBoots || (r&0xFF)!=PT_PLSM) + playerp->elem = r&0xFF; //Current element } if ((r&0xFF)==PT_TESC || (r&0xFF)==PT_LIGH) playerp->elem = PT_LIGH; @@ -278,7 +392,12 @@ int Element_STKM::run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { sim->kill_part(r>>8); } if (sim->bmap[(ry+y)/CELL][(rx+x)/CELL]==WL_FAN) + { + playerp->rocketBoots = false; playerp->elem = SPC_AIR; + } + else if (sim->bmap[(ry+y)/CELL][(rx+x)/CELL]==WL_GRAV && parts[i].type!=PT_FIGH) + playerp->rocketBoots = true; if ((r&0xFF)==PT_PRTI) Element_STKM::STKM_interact(sim, playerp, i, rx, ry); if (!parts[i].type)//STKM_interact may kill STKM @@ -468,7 +587,7 @@ void Element_STKM::STKM_interact(Simulation * sim, playerst* playerp, int i, int sim->parts[i].life -= (int)(rand()*20/RAND_MAX)+32; } - if (sim->elements[r&0xFF].HeatConduct && ((playerp->elem!=PT_LIGH && sim->parts[r>>8].temp>=323) || sim->parts[r>>8].temp<=243)) + if (sim->elements[r&0xFF].HeatConduct && ((playerp->elem!=PT_LIGH && sim->parts[r>>8].temp>=323) || sim->parts[r>>8].temp<=243) && (!playerp->rocketBoots || (r&0xFF)!=PT_PLSM)) { sim->parts[i].life -= 2; playerp->accs[3] -= 1;