From 89a0603b53b314345d93e422dd945848ea3a9938 Mon Sep 17 00:00:00 2001 From: jacksonmj Date: Tue, 7 May 2013 17:36:43 +0100 Subject: 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. diff --git a/src/graphics/Renderer.cpp b/src/graphics/Renderer.cpp index 1f4aed8..af6826e 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 699a611..1ab97fd 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 0e9cd3c..a62a747 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 faeb5f9..2323be3 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; + } } } } + if (playerp->rocketBoots && ((int)(playerp->comm)&0x03) == 0x03) + { + // 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 && - (!sim->eval_move(t, playerp->legs[4], playerp->legs[5], NULL) || !sim->eval_move(t, playerp->legs[12], playerp->legs[13], NULL))) + if (((int)(playerp->comm)&0x04) == 0x04) { - 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; + 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; -- cgit v0.9.2-21-gd62e