Powered pipe, based on jacob1's commits
PSCN to turn on, NSCN to turn off, INST to reverse. Differences from jacob1's commit include: flood fill function that includes 1px diagonal pipes, powered/reversed state stored in tmp instead of flags, sparks from PSCN/NSCN/INST always take effect the following frame, single pixel pipe directions are a number from 0 to 7 so "if(coords)" does not check whether one is set (store another "transfers according to 1px pipe direction" bit for reverse flow).
This commit is contained in:
parent
a4c15746b8
commit
8ec0f41fb1
@ -160,11 +160,9 @@
|
||||
#define PT_PVOD 84
|
||||
#define PT_CONV 85
|
||||
#define PT_CAUS 86
|
||||
|
||||
#define PT_LIGH 87
|
||||
#define PT_TESC 88
|
||||
#define PT_DEST 89
|
||||
|
||||
#define PT_SPNG 90
|
||||
#define PT_RIME 91
|
||||
#define PT_FOG 92
|
||||
@ -237,7 +235,8 @@
|
||||
#define PT_FIGH 158
|
||||
#define PT_FRAY 159
|
||||
#define PT_REPL 160
|
||||
#define PT_NUM 161
|
||||
#define PT_PPIP 161
|
||||
#define PT_NUM 162
|
||||
|
||||
#define R_TEMP 22
|
||||
#define MAX_TEMP 9999
|
||||
@ -352,6 +351,7 @@ int graphics_SOAP(GRAPHICS_FUNC_ARGS);
|
||||
int graphics_EXOT(GRAPHICS_FUNC_ARGS);
|
||||
int graphics_WARP(GRAPHICS_FUNC_ARGS);
|
||||
int graphics_EMBR(GRAPHICS_FUNC_ARGS);
|
||||
int graphics_BRCK(GRAPHICS_FUNC_ARGS);
|
||||
|
||||
void TRON_init_graphics();
|
||||
|
||||
@ -482,6 +482,7 @@ int update_legacy_all(UPDATE_FUNC_ARGS);
|
||||
int run_stickman(playerst* playerp, UPDATE_FUNC_ARGS);
|
||||
void STKM_init_legs(playerst* playerp, int i);
|
||||
void STKM_interact(playerst* playerp, int i, int x, int y);
|
||||
void PPIP_flood_trigger(int x, int y, int sparkedBy);
|
||||
|
||||
struct part_type
|
||||
{
|
||||
@ -759,6 +760,7 @@ extern int portal_ry[8];
|
||||
|
||||
extern int wire_placed;
|
||||
extern int force_stacking_check;
|
||||
extern int ppip_changed;
|
||||
|
||||
extern playerst player;
|
||||
extern playerst player2;
|
||||
|
@ -98,7 +98,7 @@ part_type ptypes[PT_NUM] =
|
||||
{"DYST", PIXPACK(0xBBB0A0), 0.7f, 0.02f * CFDS, 0.96f, 0.80f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 1, 20, 0, 0, 30, 0, 1, 80, SC_POWDERS, R_TEMP+0.0f +273.15f, 70, "Dead Yeast.", ST_SOLID, TYPE_PART, NULL, NULL},
|
||||
{"THRM", PIXPACK(0xA08090), 0.4f, 0.04f * CFDS, 0.94f, 0.95f, -0.1f, 0.3f, 0.00f, 0.000f * CFDS, 1, 0, 0, 2, 2, 1, 1, 90, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 211, "Thermite. Burns at extremely high temperature.", ST_SOLID, TYPE_PART, &update_THRM, NULL},
|
||||
{"GLOW", PIXPACK(0x445464), 0.3f, 0.02f * CFDS, 0.98f, 0.80f, 0.0f, 0.15f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 2, 1, 1, 40, SC_LIQUID, R_TEMP+20.0f+273.15f, 44, "Glow, Glows under pressure", ST_LIQUID, TYPE_LIQUID|PROP_LIFE_DEC, &update_GLOW, &graphics_GLOW},
|
||||
{"BRCK", PIXPACK(0x808080), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 251, "Brick, breakable building material.", ST_SOLID, TYPE_SOLID|PROP_HOT_GLOW, NULL, NULL},
|
||||
{"BRCK", PIXPACK(0x808080), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 251, "Brick, breakable building material.", ST_SOLID, TYPE_SOLID|PROP_HOT_GLOW, NULL, &graphics_BRCK},
|
||||
{"CFLM", PIXPACK(0x8080FF), 0.9f, 0.04f * CFDS, 0.97f, 0.20f, 0.0f, -0.1f, 0.00f, 0.0005f * CFDS, 1, 0, 0, 0, 1, 1, 1, 2, SC_EXPLOSIVE, 0.0f, 88, "Sub-zero flame.", ST_LIQUID, TYPE_GAS|PROP_LIFE_DEC|PROP_LIFE_KILL, NULL, &graphics_HFLM},
|
||||
{"FIRW", PIXPACK(0xFFA040), 0.2f, 0.01f * CFDS, 0.96f, 0.95f, -0.1f, 0.1f, 0.00f, 0.000f * CFDS, 1, 0, 0, 0, 30, 1, 1, 55, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 70, "Fireworks!", ST_SOLID, TYPE_PART|PROP_LIFE_DEC, &update_FIRW, &graphics_FIRW},
|
||||
{"FUSE", PIXPACK(0x0A5706), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.0f, 0.0f * CFDS, 0, 0, 0, 0, 20, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 200, "Solid. Burns slowly. Ignites at somewhat high temperatures and electricity.", ST_SOLID, TYPE_SOLID, &update_FUSE, NULL},
|
||||
@ -192,6 +192,7 @@ part_type ptypes[PT_NUM] =
|
||||
{"FIGH", PIXPACK(0xFFE0A0), 0.5f, 0.00f * CFDS, 0.2f, 1.0f, 0.0f, 0.0f, 0.0f, 0.00f * CFDS, 0, 0, 0, 0, 0, 1, 1, 50, SC_SPECIAL, R_TEMP+14.6f+273.15f, 0, "Fighter. Tries to kill stickmen.", ST_NONE, 0, &update_FIGH, &graphics_STKM},
|
||||
{"FRAY", PIXPACK(0x00BBFF), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_FORCE, 20.0f+0.0f +273.15f, 0, "Force Emitter. Push or pull objects based on temp value, use like ARAY", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, &update_FRAY, NULL},
|
||||
{"RPEL", PIXPACK(0x99CC00), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_FORCE, 20.0f+0.0f +273.15f, 0, "Repel or attract particles based on temp value.", ST_NONE, TYPE_SOLID, &update_REPL, NULL},
|
||||
{"PPIP", PIXPACK(0x444466), 0.0f, 0.00f * CFDS, 0.95f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_POWERED, 273.15f, 0, "Powered version of pipe", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, &update_PIPE, &graphics_PIPE},
|
||||
//Name Colour Advec Airdrag Airloss Loss Collid Grav Diffus Hotair Fal Burn Exp Mel Hrd M Use Weight Section H Ins Description
|
||||
};
|
||||
|
||||
@ -368,6 +369,7 @@ part_transition ptransitions[PT_NUM] =
|
||||
/* FIGH */ {IPL, NT, IPH, NT, ITL, NT, 620.0f, PT_FIRE},
|
||||
/* FRAY */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT},
|
||||
/* REPL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT},
|
||||
/* PPIP */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT},
|
||||
};
|
||||
|
||||
// This is an enthalpy values table, converted into TPT imaginary units
|
||||
@ -535,6 +537,7 @@ unsigned int platent[PT_NUM] =
|
||||
/* FIGH */ 0,
|
||||
/* FRAY */ 0,
|
||||
/* REPL */ 0,
|
||||
/* PPIP */ 0,
|
||||
};
|
||||
#undef IPL
|
||||
#undef IPH
|
||||
|
@ -514,3 +514,12 @@ int graphics_COAL(GRAPHICS_FUNC_ARGS) //Both COAL and Broken Coal
|
||||
return 0;
|
||||
}
|
||||
|
||||
int graphics_BRCK(GRAPHICS_FUNC_ARGS)
|
||||
{
|
||||
if (cpart->tmp == 1)
|
||||
{
|
||||
*pixel_mode |= PMODE_GLOW;
|
||||
*colb += 100;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,9 +17,150 @@
|
||||
|
||||
#define PFLAG_NORMALSPEED 0x00010000
|
||||
|
||||
// parts[].tmp flags
|
||||
// trigger flags to be processed this frame (trigger flags for next frame are shifted 3 bits to the left):
|
||||
#define PPIP_TMPFLAG_TRIGGER_ON 0x10000000
|
||||
#define PPIP_TMPFLAG_TRIGGER_OFF 0x08000000
|
||||
#define PPIP_TMPFLAG_TRIGGER_REVERSE 0x04000000
|
||||
#define PPIP_TMPFLAG_TRIGGERS 0x1C000000
|
||||
// current status of the pipe
|
||||
#define PPIP_TMPFLAG_PAUSED 0x02000000
|
||||
#define PPIP_TMPFLAG_REVERSED 0x01000000
|
||||
// 0x000000FF element
|
||||
// 0x00000100 is single pixel pipe
|
||||
// 0x00000200 will transfer like a single pixel pipe when in forward mode
|
||||
// 0x00001C00 forward single pixel pipe direction
|
||||
// 0x00002000 will transfer like a single pixel pipe when in reverse mode
|
||||
// 0x0001C000 reverse single pixel pipe direction
|
||||
|
||||
signed char pos_1_rx[] = {-1,-1,-1, 0, 0, 1, 1, 1};
|
||||
signed char pos_1_ry[] = {-1, 0, 1,-1, 1,-1, 0, 1};
|
||||
|
||||
int ppip_changed = 0;
|
||||
|
||||
void PPIP_flood_trigger(int x, int y, int sparkedBy)
|
||||
{
|
||||
int coord_stack_limit = XRES*YRES;
|
||||
unsigned short (*coord_stack)[2];
|
||||
int coord_stack_size = 0;
|
||||
int x1, x2;
|
||||
|
||||
// Separate flags for on and off in case PPIP is sparked by PSCN and NSCN on the same frame
|
||||
// - then PSCN can override NSCN and behaviour is not dependent on particle order
|
||||
int prop = 0;
|
||||
if (sparkedBy==PT_PSCN) prop = PPIP_TMPFLAG_TRIGGER_ON << 3;
|
||||
else if (sparkedBy==PT_NSCN) prop = PPIP_TMPFLAG_TRIGGER_OFF << 3;
|
||||
else if (sparkedBy==PT_INST) prop = PPIP_TMPFLAG_TRIGGER_REVERSE << 3;
|
||||
|
||||
if (prop==0 || (pmap[y][x]&0xFF)!=PT_PPIP || (parts[pmap[y][x]>>8].tmp & prop))
|
||||
return;
|
||||
|
||||
coord_stack = malloc(sizeof(unsigned short)*2*coord_stack_limit);
|
||||
coord_stack[coord_stack_size][0] = x;
|
||||
coord_stack[coord_stack_size][1] = y;
|
||||
coord_stack_size++;
|
||||
|
||||
do
|
||||
{
|
||||
coord_stack_size--;
|
||||
x = coord_stack[coord_stack_size][0];
|
||||
y = coord_stack[coord_stack_size][1];
|
||||
x1 = x2 = x;
|
||||
// go left as far as possible
|
||||
while (x1>=CELL)
|
||||
{
|
||||
if ((pmap[y][x1-1]&0xFF)!=PT_PPIP)
|
||||
{
|
||||
break;
|
||||
}
|
||||
x1--;
|
||||
}
|
||||
// go right as far as possible
|
||||
while (x2<XRES-CELL)
|
||||
{
|
||||
if ((pmap[y][x2+1]&0xFF)!=PT_PPIP)
|
||||
{
|
||||
break;
|
||||
}
|
||||
x2++;
|
||||
}
|
||||
// fill span
|
||||
for (x=x1; x<=x2; x++)
|
||||
{
|
||||
if (!(parts[pmap[y][x]>>8].tmp & prop))
|
||||
ppip_changed = 1;
|
||||
parts[pmap[y][x]>>8].tmp |= prop;
|
||||
}
|
||||
|
||||
// add adjacent pixels to stack
|
||||
// +-1 to x limits to include diagonally adjacent pixels
|
||||
// Don't need to check x bounds here, because already limited to [CELL, XRES-CELL]
|
||||
if (y>=CELL+1)
|
||||
for (x=x1-1; x<=x2+1; x++)
|
||||
if ((pmap[y-1][x]&0xFF)==PT_PPIP && !(parts[pmap[y-1][x]>>8].tmp & prop))
|
||||
{
|
||||
coord_stack[coord_stack_size][0] = x;
|
||||
coord_stack[coord_stack_size][1] = y-1;
|
||||
coord_stack_size++;
|
||||
if (coord_stack_size>=coord_stack_limit)
|
||||
{
|
||||
free(coord_stack);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (y<YRES-CELL-1)
|
||||
for (x=x1-1; x<=x2+1; x++)
|
||||
if ((pmap[y+1][x]&0xFF)==PT_PPIP && !(parts[pmap[y+1][x]>>8].tmp & prop))
|
||||
{
|
||||
coord_stack[coord_stack_size][0] = x;
|
||||
coord_stack[coord_stack_size][1] = y+1;
|
||||
coord_stack_size++;
|
||||
if (coord_stack_size>=coord_stack_limit)
|
||||
{
|
||||
free(coord_stack);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} while (coord_stack_size>0);
|
||||
free(coord_stack);
|
||||
}
|
||||
|
||||
void PIPE_transfer_pipe_to_part(particle *pipe, particle *part)
|
||||
{
|
||||
part->type = (pipe->tmp & 0xFF);
|
||||
part->temp = pipe->temp;
|
||||
part->life = pipe->tmp2;
|
||||
part->tmp = pipe->pavg[0];
|
||||
part->ctype = pipe->pavg[1];
|
||||
pipe->tmp &= ~0xFF;
|
||||
|
||||
part->vx = 0.0f;
|
||||
part->vy = 0.0f;
|
||||
part->tmp2 = 0;
|
||||
part->flags = 0;
|
||||
part->dcolour = 0;
|
||||
}
|
||||
|
||||
void PIPE_transfer_part_to_pipe(particle *part, particle *pipe)
|
||||
{
|
||||
pipe->tmp = (pipe->tmp&~0xFF) | part->type;
|
||||
pipe->temp = part->temp;
|
||||
pipe->tmp2 = part->life;
|
||||
pipe->pavg[0] = part->tmp;
|
||||
pipe->pavg[1] = part->ctype;
|
||||
}
|
||||
|
||||
void PIPE_transfer_pipe_to_pipe(particle *src, particle *dest)
|
||||
{
|
||||
dest->tmp = (dest->tmp&~0xFF) | (src->tmp&0xFF);
|
||||
dest->temp = src->temp;
|
||||
dest->tmp2 = src->tmp2;
|
||||
dest->pavg[0] = src->pavg[0];
|
||||
dest->pavg[1] = src->pavg[1];
|
||||
src->tmp &= ~0xFF;
|
||||
}
|
||||
|
||||
|
||||
void pushParticle(int i, int count, int original)
|
||||
{
|
||||
int rndstore, rnd, rx, ry, r, x, y, np, q, notctype=(((parts[i].ctype)%3)+2);
|
||||
@ -33,7 +174,7 @@ void pushParticle(int i, int count, int original)
|
||||
rndstore = rand();
|
||||
// RAND_MAX is at least 32767 on all platforms i.e. pow(8,5)-1
|
||||
// so can go 5 cycles without regenerating rndstore
|
||||
for (q=0; q<3; q++)//try to push twice
|
||||
for (q=0; q<3; q++)//try to push 3 times
|
||||
{
|
||||
rnd = rndstore&7;
|
||||
rndstore = rndstore>>3;
|
||||
@ -44,19 +185,25 @@ void pushParticle(int i, int count, int original)
|
||||
r = pmap[y+ry][x+rx];
|
||||
if (!r)
|
||||
continue;
|
||||
else if ((r&0xFF)==PT_PIPE && parts[r>>8].ctype!=notctype && (parts[r>>8].tmp&0xFF)==0)
|
||||
else if (((r&0xFF)==PT_PIPE || (r&0xFF) == PT_PPIP) && parts[r>>8].ctype!=notctype && (parts[r>>8].tmp&0xFF)==0)
|
||||
{
|
||||
parts[r>>8].tmp = (parts[r>>8].tmp&~0xFF) | (parts[i].tmp&0xFF);
|
||||
parts[r>>8].temp = parts[i].temp;
|
||||
parts[r>>8].tmp2 = parts[i].tmp2;
|
||||
parts[r>>8].pavg[0] = parts[i].pavg[0];
|
||||
parts[r>>8].pavg[1] = parts[i].pavg[1];
|
||||
PIPE_transfer_pipe_to_pipe(parts+i, parts+(r>>8));
|
||||
if (r>>8 > original)
|
||||
parts[r>>8].flags |= PFLAG_NORMALSPEED;//skip particle push, normalizes speed
|
||||
parts[i].tmp &= ~0xFF;
|
||||
count++;
|
||||
pushParticle(r>>8,count,original);
|
||||
}
|
||||
else if ((r&0xFF) == PT_PRTI) //Pass particles into PRTI for a pipe speed increase
|
||||
{
|
||||
int nnx;
|
||||
for (nnx=0; nnx<80; nnx++)
|
||||
if (!portalp[parts[r>>8].tmp][count][nnx].type)
|
||||
{
|
||||
PIPE_transfer_pipe_to_part(parts+i, &(portalp[parts[r>>8].tmp][count][nnx]));
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -64,24 +211,35 @@ void pushParticle(int i, int count, int original)
|
||||
{
|
||||
int coords = 7 - ((parts[i].tmp>>10)&7);
|
||||
r = pmap[y+ pos_1_ry[coords]][x+ pos_1_rx[coords]];
|
||||
if (!r)
|
||||
if (((r&0xFF)==PT_PIPE || (r&0xFF) == PT_PPIP) && parts[r>>8].ctype!=notctype && (parts[r>>8].tmp&0xFF)==0)
|
||||
{
|
||||
}
|
||||
else if ((r&0xFF)==PT_PIPE && parts[r>>8].ctype!=notctype && (parts[r>>8].tmp&0xFF)==0)
|
||||
{
|
||||
parts[r>>8].tmp = (parts[r>>8].tmp&~0xFF) | (parts[i].tmp&0xFF);
|
||||
parts[r>>8].temp = parts[i].temp;
|
||||
parts[r>>8].tmp2 = parts[i].tmp2;
|
||||
parts[r>>8].pavg[0] = parts[i].pavg[0];
|
||||
parts[r>>8].pavg[1] = parts[i].pavg[1];
|
||||
PIPE_transfer_pipe_to_pipe(parts+i, parts+(r>>8));
|
||||
if (r>>8 > original)
|
||||
parts[r>>8].flags |= PFLAG_NORMALSPEED;//skip particle push, normalizes speed
|
||||
parts[i].tmp &= ~0xFF;
|
||||
count++;
|
||||
pushParticle(r>>8,count,original);
|
||||
}
|
||||
|
||||
|
||||
else if ((r&0xFF) == PT_PRTI) //Pass particles into PRTI for a pipe speed increase
|
||||
{
|
||||
int nnx;
|
||||
for (nnx=0; nnx<80; nnx++)
|
||||
if (!portalp[parts[r>>8].tmp][count][nnx].type)
|
||||
{
|
||||
PIPE_transfer_pipe_to_part(parts+i, &(portalp[parts[r>>8].tmp][count][nnx]));
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((r&0xFF) == PT_NONE) //Move particles out of pipe automatically, much faster at ends
|
||||
{
|
||||
rx = pos_1_rx[coords];
|
||||
ry = pos_1_ry[coords];
|
||||
np = create_part(-1,x+rx,y+ry,parts[i].tmp&0xFF);
|
||||
if (np!=-1)
|
||||
{
|
||||
PIPE_transfer_pipe_to_part(parts+i, parts+np);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -89,7 +247,62 @@ void pushParticle(int i, int count, int original)
|
||||
int update_PIPE(UPDATE_FUNC_ARGS) {
|
||||
int r, rx, ry, np;
|
||||
int rnd, rndstore;
|
||||
if (parts[i].ctype>=2 && parts[i].ctype<=4)
|
||||
if (parts[i].tmp & PPIP_TMPFLAG_TRIGGERS)
|
||||
{
|
||||
int pause_changed = 0;
|
||||
if (parts[i].tmp & PPIP_TMPFLAG_TRIGGER_ON) // TRIGGER_ON overrides TRIGGER_OFF
|
||||
{
|
||||
if (parts[i].tmp & PPIP_TMPFLAG_PAUSED)
|
||||
pause_changed = 1;
|
||||
parts[i].tmp &= ~PPIP_TMPFLAG_PAUSED;
|
||||
}
|
||||
else if (parts[i].tmp & PPIP_TMPFLAG_TRIGGER_OFF)
|
||||
{
|
||||
if (!(parts[i].tmp & PPIP_TMPFLAG_PAUSED))
|
||||
pause_changed = 1;
|
||||
parts[i].tmp |= PPIP_TMPFLAG_PAUSED;
|
||||
}
|
||||
if (pause_changed)
|
||||
{
|
||||
int rx, ry, r;
|
||||
for (rx=-2; rx<3; rx++)
|
||||
for (ry=-2; ry<3; ry++)
|
||||
{
|
||||
if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry))
|
||||
{
|
||||
r = pmap[y+ry][x+rx];
|
||||
if ((r&0xFF) == PT_BRCK)
|
||||
{
|
||||
if (parts[i].tmp & PPIP_TMPFLAG_PAUSED)
|
||||
parts[r>>8].tmp = 0;
|
||||
else
|
||||
parts[r>>8].tmp = 1; //make surrounding BRCK glow
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parts[i].tmp & PPIP_TMPFLAG_TRIGGER_REVERSE)
|
||||
{
|
||||
parts[i].tmp ^= PPIP_TMPFLAG_REVERSED;
|
||||
if (parts[i].ctype == 2) //Switch colors so it goes in reverse
|
||||
parts[i].ctype = 4;
|
||||
else if (parts[i].ctype == 4)
|
||||
parts[i].ctype = 2;
|
||||
if (parts[i].tmp & 0x100) //Switch one pixel pipe direction
|
||||
{
|
||||
int coords = (parts[i].tmp>>13)&0xF;
|
||||
int coords2 = (parts[i].tmp>>9)&0xF;
|
||||
parts[i].tmp &= ~0x1FE00;
|
||||
parts[i].tmp |= coords<<9;
|
||||
parts[i].tmp |= coords2<<13;
|
||||
}
|
||||
}
|
||||
|
||||
parts[i].tmp &= ~PPIP_TMPFLAG_TRIGGERS;
|
||||
}
|
||||
|
||||
if (parts[i].ctype>=2 && parts[i].ctype<=4 && !(parts[i].tmp & PPIP_TMPFLAG_PAUSED))
|
||||
{
|
||||
if (parts[i].life==3)
|
||||
{
|
||||
@ -104,7 +317,7 @@ int update_PIPE(UPDATE_FUNC_ARGS) {
|
||||
r = pmap[y+ry][x+rx];
|
||||
if (!r)
|
||||
continue;
|
||||
if ((r&0xFF)==PT_PIPE&&parts[r>>8].ctype==1)
|
||||
if (((r&0xFF)==PT_PIPE || (r&0xFF) == PT_PPIP)&&parts[r>>8].ctype==1)
|
||||
{
|
||||
parts[r>>8].ctype = (((parts[i].ctype)%3)+2);//reverse
|
||||
parts[r>>8].life = 6;
|
||||
@ -112,11 +325,13 @@ int update_PIPE(UPDATE_FUNC_ARGS) {
|
||||
{
|
||||
parts[r>>8].tmp |= 0x200;//will transfer to a single pixel pipe
|
||||
parts[r>>8].tmp |= count<<10;//coords of where it came from
|
||||
parts[i].tmp |= ((7-count)<<14);
|
||||
parts[i].tmp |= 0x2000;
|
||||
}
|
||||
neighborcount ++;
|
||||
lastneighbor = r>>8;
|
||||
}
|
||||
else if ((r&0xFF)==PT_PIPE&&parts[r>>8].ctype!=(((parts[i].ctype-1)%3)+2))
|
||||
else if (((r&0xFF)==PT_PIPE || (r&0xFF) == PT_PPIP)&&parts[r>>8].ctype!=(((parts[i].ctype-1)%3)+2))
|
||||
{
|
||||
neighborcount ++;
|
||||
lastneighbor = r>>8;
|
||||
@ -128,7 +343,7 @@ int update_PIPE(UPDATE_FUNC_ARGS) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parts[i].flags&PFLAG_NORMALSPEED)//skip particle push to prevent particle number being higher causeing speed up
|
||||
if (parts[i].flags&PFLAG_NORMALSPEED)//skip particle push to prevent particle number being higher causing speed up
|
||||
{
|
||||
parts[i].flags &= ~PFLAG_NORMALSPEED;
|
||||
}
|
||||
@ -154,11 +369,7 @@ int update_PIPE(UPDATE_FUNC_ARGS) {
|
||||
np = create_part(-1,x+rx,y+ry,parts[i].tmp&0xFF);
|
||||
if (np!=-1)
|
||||
{
|
||||
parts[np].temp = parts[i].temp;//pipe saves temp and life now
|
||||
parts[np].life = parts[i].tmp2;
|
||||
parts[np].tmp = parts[i].pavg[0];
|
||||
parts[np].ctype = parts[i].pavg[1];
|
||||
parts[i].tmp &= ~0xFF;
|
||||
PIPE_transfer_pipe_to_part(parts+i, parts+np);
|
||||
}
|
||||
}
|
||||
//try eating particle at entrance
|
||||
@ -166,22 +377,13 @@ int update_PIPE(UPDATE_FUNC_ARGS) {
|
||||
{
|
||||
if ((r&0xFF)==PT_SOAP)
|
||||
detach(r>>8);
|
||||
parts[i].tmp = (parts[i].tmp&~0xFF) | parts[r>>8].type;
|
||||
parts[i].temp = parts[r>>8].temp;
|
||||
parts[i].tmp2 = parts[r>>8].life;
|
||||
parts[i].pavg[0] = parts[r>>8].tmp;
|
||||
parts[i].pavg[1] = parts[r>>8].ctype;
|
||||
PIPE_transfer_part_to_pipe(parts+(r>>8), parts+i);
|
||||
kill_part(r>>8);
|
||||
}
|
||||
else if ((parts[i].tmp&0xFF) == 0 && (r&0xFF)==PT_STOR && parts[r>>8].tmp && (ptypes[parts[r>>8].tmp].properties & (TYPE_PART | TYPE_LIQUID | TYPE_GAS | TYPE_ENERGY)))
|
||||
{
|
||||
parts[i].tmp = parts[r>>8].tmp;
|
||||
parts[i].temp = parts[r>>8].temp;
|
||||
parts[i].tmp2 = parts[r>>8].tmp2;
|
||||
parts[i].pavg[0] = parts[r>>8].pavg[0];
|
||||
parts[i].pavg[1] = parts[r>>8].pavg[1];
|
||||
parts[r>>8].tmp = 0;
|
||||
parts[r>>8].life = 0;
|
||||
// STOR stores properties in the same places as PIPE does
|
||||
PIPE_transfer_pipe_to_pipe(parts+(r>>8), parts+i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -217,7 +419,11 @@ int update_PIPE(UPDATE_FUNC_ARGS) {
|
||||
{
|
||||
r = pmap[y+ry][x+rx];
|
||||
if (!r)
|
||||
create_part(-1,x+rx,y+ry,PT_BRCK);//BRCK border, people didn't like DMND
|
||||
{
|
||||
int index = create_part(-1,x+rx,y+ry,PT_BRCK);//BRCK border, people didn't like DMND
|
||||
if (parts[i].type == PT_PPIP && index != -1)
|
||||
parts[index].tmp = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parts[i].life<=1)
|
||||
@ -244,7 +450,7 @@ int update_PIPE(UPDATE_FUNC_ARGS) {
|
||||
if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry))
|
||||
{
|
||||
r = pmap[y+ry][x+rx];
|
||||
if ((r&0xFF)==PT_PIPE && parts[i].ctype==1 && parts[i].life )
|
||||
if (((r&0xFF)==PT_PIPE || (r&0xFF) == PT_PPIP) && parts[i].ctype==1 && parts[i].life )
|
||||
issingle = 0;
|
||||
}
|
||||
if (issingle)
|
||||
@ -277,6 +483,7 @@ int graphics_PIPE(GRAPHICS_FUNC_ARGS)
|
||||
if (graphicscache[t].isready)
|
||||
{
|
||||
*pixel_mode = graphicscache[t].pixel_mode;
|
||||
*cola = graphicscache[t].cola;
|
||||
*colr = graphicscache[t].colr;
|
||||
*colg = graphicscache[t].colg;
|
||||
*colb = graphicscache[t].colb;
|
||||
@ -288,8 +495,8 @@ int graphics_PIPE(GRAPHICS_FUNC_ARGS)
|
||||
else
|
||||
{
|
||||
*colr = PIXR(ptypes[t].pcolors);
|
||||
*colg = PIXR(ptypes[t].pcolors);
|
||||
*colb = PIXR(ptypes[t].pcolors);
|
||||
*colg = PIXG(ptypes[t].pcolors);
|
||||
*colb = PIXB(ptypes[t].pcolors);
|
||||
if (ptypes[t].graphics_func)
|
||||
{
|
||||
(*(ptypes[t].graphics_func))(&tpart, nx, ny, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, fireb);
|
||||
|
@ -154,6 +154,11 @@ int update_SPRK(UPDATE_FUNC_ARGS) {
|
||||
else if (ct==PT_NSCN && parts[r>>8].tmp == 3) parts[r>>8].tmp = 1;
|
||||
}
|
||||
|
||||
if (rt == PT_PPIP && parts[i].life == 3 && pavg!=PT_INSL)
|
||||
{
|
||||
if (ct == PT_NSCN || ct == PT_PSCN || ct == PT_INST)
|
||||
PPIP_flood_trigger(x+rx, y+ry, ct);
|
||||
}
|
||||
|
||||
// ct = spark from material, rt = spark to material. Make conduct_sprk = 0 if conduction not allowed
|
||||
|
||||
|
@ -1896,7 +1896,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
sprintf(nametext, "Molten %s", lowername);
|
||||
}
|
||||
else if ((cr&0xFF)==PT_PIPE && (parts[cr>>8].tmp&0xFF) > 0 && (parts[cr>>8].tmp&0xFF) < PT_NUM )
|
||||
else if (((cr&0xFF)==PT_PIPE || (cr&0xFF) == PT_PPIP) && (parts[cr>>8].tmp&0xFF) > 0 && (parts[cr>>8].tmp&0xFF) < PT_NUM )
|
||||
{
|
||||
char lowername[6];
|
||||
int ix;
|
||||
@ -1909,7 +1909,7 @@ int main(int argc, char *argv[])
|
||||
else if (DEBUG_MODE)
|
||||
{
|
||||
int tctype = parts[cr>>8].ctype;
|
||||
if ((cr&0xFF)==PT_PIPE)
|
||||
if ((cr&0xFF)==PT_PIPE || (cr&0xFF) == PT_PPIP)
|
||||
{
|
||||
tctype = parts[cr>>8].tmp&0xFF;
|
||||
}
|
||||
|
17
src/powder.c
17
src/powder.c
@ -1027,6 +1027,7 @@ inline int create_part(int p, int x, int y, int tv)//the function for creating a
|
||||
parts[i].life = 100;
|
||||
break;
|
||||
case PT_PIPE:
|
||||
case PT_PPIP:
|
||||
parts[i].life = 60;
|
||||
break;
|
||||
case PT_BCOL:
|
||||
@ -1788,6 +1789,20 @@ void update_particles_i(pixel *vid, int start, int inc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ppip_changed)
|
||||
{
|
||||
for (i=0; i<=parts_lastActiveIndex; i++)
|
||||
{
|
||||
if (parts[i].type==PT_PPIP)
|
||||
{
|
||||
parts[i].tmp |= (parts[i].tmp&0xE0000000)>>3;
|
||||
parts[i].tmp &= ~0xE0000000;
|
||||
}
|
||||
}
|
||||
ppip_changed = 0;
|
||||
}
|
||||
|
||||
//game of life!
|
||||
if (ISGOL==1&&++CGOL>=GSPEED)//GSPEED is frames per generation
|
||||
{
|
||||
@ -2599,7 +2614,7 @@ killed:
|
||||
}
|
||||
r = pmap[fin_y][fin_x];
|
||||
|
||||
if ((r & 0xFF) == PT_PIPE && !(parts[r>>8].tmp&0xFF))
|
||||
if (((r&0xFF)==PT_PIPE || (r&0xFF) == PT_PPIP) && !(parts[r>>8].tmp&0xFF))
|
||||
{
|
||||
parts[r>>8].tmp = (parts[r>>8].tmp&~0xFF) | parts[i].type;
|
||||
parts[r>>8].temp = parts[i].temp;
|
||||
|
23
src/save.c
23
src/save.c
@ -56,6 +56,7 @@ int parse_save(void *save, int size, int replace, int x0, int y0, unsigned char
|
||||
return 1;
|
||||
}
|
||||
force_stacking_check = 1;//check for excessive stacking of particles next time update_particles is run
|
||||
ppip_changed = 1;
|
||||
if(saveData[0] == 'O' && saveData[1] == 'P' && saveData[2] == 'S')
|
||||
{
|
||||
return parse_save_OPS(save, size, replace, x0, y0, bmap, vx, vy, pv, fvx, fvy, signs, partsptr, pmap);
|
||||
@ -391,6 +392,11 @@ pixel *prerender_save_OPS(void *save, int size, int *width, int *height)
|
||||
if(fieldDescriptor & 0x10)
|
||||
{
|
||||
if(i++ >= partsDataLen) goto fail;
|
||||
if(fieldDescriptor & 0x1000)
|
||||
{
|
||||
if(i+1 >= partsDataLen) goto fail;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -573,7 +579,7 @@ void *build_save_OPS(int *size, int orig_x0, int orig_y0, int orig_w, int orig_h
|
||||
//Copy parts data
|
||||
/* Field descriptor format:
|
||||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|
||||
| tmp2[2] | tmp2[1] | ctype[2] | vy | vx | dcololour | ctype[1] | tmp[2] | tmp[1] | life[2] | life[1] | temp dbl len|
|
||||
tmp[3+4] | tmp2[2] | tmp2[1] | ctype[2] | vy | vx | dcololour | ctype[1] | tmp[2] | tmp[1] | life[2] | life[1] | temp dbl len|
|
||||
life[2] means a second byte (for a 16 bit field) if life[1] is present
|
||||
*/
|
||||
partsData = malloc(NPART * (sizeof(particle)+1));
|
||||
@ -634,7 +640,7 @@ void *build_save_OPS(int *size, int orig_x0, int orig_y0, int orig_w, int orig_h
|
||||
}
|
||||
}
|
||||
|
||||
//Tmp (optional), 1 to 2 bytes
|
||||
//Tmp (optional), 1, 2 or 4 bytes
|
||||
if(partsptr[i].tmp)
|
||||
{
|
||||
fieldDesc |= 1 << 3;
|
||||
@ -643,6 +649,12 @@ void *build_save_OPS(int *size, int orig_x0, int orig_y0, int orig_w, int orig_h
|
||||
{
|
||||
fieldDesc |= 1 << 4;
|
||||
partsData[partsDataLen++] = partsptr[i].tmp >> 8;
|
||||
if(partsptr[i].tmp > 65535)
|
||||
{
|
||||
fieldDesc |= 1 << 12;
|
||||
partsData[partsDataLen++] = (partsptr[i].tmp&0xFF000000)>>24;
|
||||
partsData[partsDataLen++] = (partsptr[i].tmp&0x00FF0000)>>16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1307,6 +1319,13 @@ int parse_save_OPS(void *save, int size, int replace, int x0, int y0, unsigned c
|
||||
{
|
||||
if(i >= partsDataLen) goto fail;
|
||||
partsptr[newIndex].tmp |= (((unsigned)partsData[i++]) << 8);
|
||||
//Read 3rd and 4th bytes
|
||||
if(fieldDescriptor & 0x1000)
|
||||
{
|
||||
if(i+1 >= partsDataLen) goto fail;
|
||||
partsptr[newIndex].tmp |= (((unsigned)partsData[i++]) << 24);
|
||||
partsptr[newIndex].tmp |= (((unsigned)partsData[i++]) << 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user