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.
This commit is contained in:
jacksonmj 2013-05-07 17:36:43 +01:00
parent 20c261826d
commit 89a0603b53
4 changed files with 157 additions and 11 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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].ctype<PT_NUM && sim->elements[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 (dl<dr)
{
if (!sim->eval_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;