Combat Vehicle changes
- new "speed" mod - small stages
This commit is contained in:
parent
b52699d370
commit
896c84c205
3 changed files with 325 additions and 141 deletions
|
|
@ -64,6 +64,7 @@ enum FurnaceCVObjectTypes {
|
|||
CV_MINE,
|
||||
CV_POWERUP_P,
|
||||
CV_POWERUP_S,
|
||||
CV_MOD_S,
|
||||
CV_EXTRA_LIFE
|
||||
};
|
||||
|
||||
|
|
@ -375,6 +376,17 @@ struct FurnaceCVPowerupS: FurnaceCVObject {
|
|||
}
|
||||
};
|
||||
|
||||
struct FurnaceCVModS: FurnaceCVObject {
|
||||
unsigned char life;
|
||||
void collision(FurnaceCVObject* other);
|
||||
void tick();
|
||||
FurnaceCVModS(FurnaceCV* p):
|
||||
FurnaceCVObject(p),
|
||||
life(255) {
|
||||
type=CV_MOD_S;
|
||||
}
|
||||
};
|
||||
|
||||
struct FurnaceCVExtraLife: FurnaceCVObject {
|
||||
unsigned char life;
|
||||
void collision(FurnaceCVObject* other);
|
||||
|
|
@ -391,10 +403,12 @@ struct FurnaceCV {
|
|||
unsigned char* prioBuf;
|
||||
DivEngine* e;
|
||||
unsigned char* tileData;
|
||||
unsigned int tick;
|
||||
|
||||
// state
|
||||
unsigned short* curStage;
|
||||
int stageWidth, stageHeight;
|
||||
int stageWidthPx, stageHeightPx;
|
||||
|
||||
const char* typeAddr;
|
||||
unsigned char typeDelay;
|
||||
|
|
@ -411,6 +425,8 @@ struct FurnaceCV {
|
|||
int hiScore;
|
||||
short lastPlayerX, lastPlayerY;
|
||||
short fxChanBase, fxInsBase;
|
||||
short speedTicks;
|
||||
float origSongRate;
|
||||
|
||||
FixedQueue<unsigned char,16> weaponStack;
|
||||
|
||||
|
|
@ -455,9 +471,12 @@ struct FurnaceCV {
|
|||
surface(NULL),
|
||||
e(NULL),
|
||||
tileData(NULL),
|
||||
tick(0),
|
||||
curStage(NULL),
|
||||
stageWidth(0),
|
||||
stageHeight(0),
|
||||
stageWidth(40),
|
||||
stageHeight(28),
|
||||
stageWidthPx(320),
|
||||
stageHeightPx(224),
|
||||
typeAddr(NULL),
|
||||
typeDelay(0),
|
||||
typeX(0),
|
||||
|
|
@ -485,6 +504,8 @@ struct FurnaceCV {
|
|||
lastPlayerY(0),
|
||||
fxChanBase(-1),
|
||||
fxInsBase(-1),
|
||||
speedTicks(0),
|
||||
origSongRate(60.0f),
|
||||
bgColor(0),
|
||||
viewX(0),
|
||||
viewY(0),
|
||||
|
|
@ -854,6 +875,7 @@ void FurnaceGUI::drawTutorial() {
|
|||
cv->loadInstruments();
|
||||
}
|
||||
}
|
||||
cv->origSongRate=cv->e->getHz();
|
||||
}
|
||||
|
||||
WAKE_UP;
|
||||
|
|
@ -866,10 +888,15 @@ void FurnaceGUI::drawTutorial() {
|
|||
e->changeSongP(0);
|
||||
e->setOrder(0);
|
||||
e->play();
|
||||
cv->origSongRate=cv->e->getHz();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cv->speedTicks>0) {
|
||||
cv->e->setSongRate(cv->origSongRate*1.5);
|
||||
}
|
||||
|
||||
cv->render(touchControls);
|
||||
|
||||
if (cv->hiScore>cvHiScore) {
|
||||
|
|
@ -1074,9 +1101,18 @@ void FurnaceCV::buildStage(int which) {
|
|||
curStage=NULL;
|
||||
}
|
||||
|
||||
curStage=new unsigned short[80*56];
|
||||
stageWidth=80;
|
||||
stageHeight=56;
|
||||
if (which>19 || which==4 || which==7 || which==9 || which==11 || which==13 || which==16 || which==17) {
|
||||
stageWidth=80;
|
||||
stageHeight=56;
|
||||
} else {
|
||||
stageWidth=40;
|
||||
stageHeight=28;
|
||||
}
|
||||
|
||||
stageWidthPx=stageWidth<<3;
|
||||
stageHeightPx=stageHeight<<3;
|
||||
|
||||
curStage=new unsigned short[stageWidth*stageHeight];
|
||||
|
||||
int floorBase=floorBases[rand()&3];
|
||||
|
||||
|
|
@ -1103,8 +1139,8 @@ void FurnaceCV::buildStage(int which) {
|
|||
for (int i=0; i<20+(which>>2); i++) {
|
||||
int tries=0;
|
||||
while (tries<20) {
|
||||
int x=rand()%40;
|
||||
int y=rand()%28;
|
||||
int x=rand()%(stageWidth>>1);
|
||||
int y=rand()%(stageHeight>>1);
|
||||
int finalX=x<<4;
|
||||
int finalY=y<<4;
|
||||
if (busy[y][x]) {
|
||||
|
|
@ -1121,8 +1157,8 @@ void FurnaceCV::buildStage(int which) {
|
|||
for (int i=0; i<20+(which>>2); i++) {
|
||||
int tries=0;
|
||||
while (tries<20) {
|
||||
int x=(rand()%40)&(~1);
|
||||
int y=(rand()%28)&(~1);
|
||||
int x=(rand()%(stageWidth>>1))&(~1);
|
||||
int y=(rand()%(stageHeight>>1))&(~1);
|
||||
int finalX=x<<4;
|
||||
int finalY=y<<4;
|
||||
if (busy[y][x]) {
|
||||
|
|
@ -1144,8 +1180,8 @@ void FurnaceCV::buildStage(int which) {
|
|||
if (which>=2) for (int i=0; i<(rand()%3)+which-2; i++) {
|
||||
int tries=0;
|
||||
while (tries<20) {
|
||||
int x=(rand()%40)&(~1);
|
||||
int y=(rand()%28)&(~1);
|
||||
int x=(rand()%(stageWidth>>1))&(~1);
|
||||
int y=(rand()%(stageHeight>>1))&(~1);
|
||||
int finalX=x<<4;
|
||||
int finalY=y<<4;
|
||||
if (busy[y][x]) {
|
||||
|
|
@ -1170,8 +1206,8 @@ void FurnaceCV::buildStage(int which) {
|
|||
if (which>=4) for (int i=0; i<(rand()%(1+which))+(which>>1); i++) {
|
||||
int tries=0;
|
||||
while (tries<20) {
|
||||
int x=rand()%40;
|
||||
int y=rand()%28;
|
||||
int x=rand()%(stageWidth>>1);
|
||||
int y=rand()%(stageHeight>>1);
|
||||
int finalX=x<<4;
|
||||
int finalY=y<<4;
|
||||
if (busy[y][x]) {
|
||||
|
|
@ -1189,8 +1225,8 @@ void FurnaceCV::buildStage(int which) {
|
|||
for (int i=0; i<7+(rand()%4)+((which&3)<<2)+(which>>1); i++) {
|
||||
int tries=0;
|
||||
while (tries<20) {
|
||||
int x=rand()%40;
|
||||
int y=rand()%28;
|
||||
int x=rand()%(stageWidth>>1);
|
||||
int y=rand()%(stageHeight>>1);
|
||||
int finalX=x<<4;
|
||||
int finalY=y<<4;
|
||||
if (busy[y][x]) {
|
||||
|
|
@ -1211,8 +1247,8 @@ void FurnaceCV::buildStage(int which) {
|
|||
for (int i=0; i<7+(rand()%18); i++) {
|
||||
int tries=0;
|
||||
while (tries<20) {
|
||||
int x=rand()%40;
|
||||
int y=rand()%28;
|
||||
int x=rand()%(stageWidth>>1);
|
||||
int y=rand()%(stageHeight>>1);
|
||||
int finalX=x<<4;
|
||||
int finalY=y<<4;
|
||||
if (busy[y][x]) {
|
||||
|
|
@ -1416,6 +1452,96 @@ void FurnaceCV::render(unsigned char joyIn) {
|
|||
tile1[0][36]=0x27f;
|
||||
putText(CV_FONTBASE_8x8,false,fmt::sprintf("*%2d",lives),37,0);
|
||||
|
||||
// arrow overlay
|
||||
bool arrowLeft=false;
|
||||
bool arrowRight=false;
|
||||
bool arrowUp=false;
|
||||
bool arrowDown=false;
|
||||
if (stageWidthPx>320 || stageHeightPx>224) {
|
||||
for (FurnaceCVObject* i: sprite) {
|
||||
if (i->type!=CV_ENEMY) continue;
|
||||
if ((i->x-viewX+(i->spriteWidth<<3))<0) {
|
||||
arrowLeft=true;
|
||||
}
|
||||
if ((i->x-viewX)>=320) {
|
||||
arrowRight=true;
|
||||
}
|
||||
if ((i->y-viewY+(i->spriteHeight<<3))<0) {
|
||||
arrowUp=true;
|
||||
}
|
||||
if ((i->y-viewY)>=224) {
|
||||
arrowDown=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (arrowLeft && !(tick&8)) {
|
||||
tile1[13][1]=0x580;
|
||||
tile1[13][2]=0x581;
|
||||
tile1[14][1]=0x5a0;
|
||||
tile1[14][2]=0x5a1;
|
||||
} else {
|
||||
tile1[13][1]=0;
|
||||
tile1[13][2]=0;
|
||||
tile1[14][1]=0;
|
||||
tile1[14][2]=0;
|
||||
}
|
||||
if (arrowRight && !(tick&8)) {
|
||||
tile1[13][37]=0x584;
|
||||
tile1[13][38]=0x585;
|
||||
tile1[14][37]=0x5a4;
|
||||
tile1[14][38]=0x5a5;
|
||||
} else {
|
||||
tile1[13][37]=0;
|
||||
tile1[13][38]=0;
|
||||
tile1[14][37]=0;
|
||||
tile1[14][38]=0;
|
||||
}
|
||||
if (arrowUp && !(tick&8)) {
|
||||
tile1[1][19]=0x582;
|
||||
tile1[1][20]=0x583;
|
||||
tile1[2][19]=0x5a2;
|
||||
tile1[2][20]=0x5a3;
|
||||
} else {
|
||||
tile1[1][19]=0;
|
||||
tile1[1][20]=0;
|
||||
tile1[2][19]=0;
|
||||
tile1[2][20]=0;
|
||||
}
|
||||
if (arrowDown && !(tick&8)) {
|
||||
tile1[25][19]=0x586;
|
||||
tile1[25][20]=0x587;
|
||||
tile1[26][19]=0x5a6;
|
||||
tile1[26][20]=0x5a7;
|
||||
} else {
|
||||
tile1[25][19]=0;
|
||||
tile1[25][20]=0;
|
||||
tile1[26][19]=0;
|
||||
tile1[26][20]=0;
|
||||
}
|
||||
|
||||
// S mod stat
|
||||
if (speedTicks>0) {
|
||||
speedTicks--;
|
||||
if ((speedTicks<120 && speedTicks&2) || speedTicks&16) {
|
||||
tile1[24][36]=0x41e;
|
||||
tile1[24][37]=0x41f;
|
||||
tile1[25][36]=0x43e;
|
||||
tile1[25][37]=0x43f;
|
||||
} else {
|
||||
tile1[24][36]=0;
|
||||
tile1[24][37]=0;
|
||||
tile1[25][36]=0;
|
||||
tile1[25][37]=0;
|
||||
}
|
||||
if (speedTicks==0) {
|
||||
e->setSongRate(origSongRate);
|
||||
}
|
||||
} else {
|
||||
tile1[24][36]=0;
|
||||
tile1[24][37]=0;
|
||||
tile1[25][36]=0;
|
||||
tile1[25][37]=0;
|
||||
}
|
||||
} else {
|
||||
if (inTransition) {
|
||||
if (--transWait<0) {
|
||||
|
|
@ -1472,6 +1598,8 @@ void FurnaceCV::render(unsigned char joyIn) {
|
|||
}
|
||||
}
|
||||
|
||||
tick++;
|
||||
|
||||
// render
|
||||
if (surface==NULL) return;
|
||||
|
||||
|
|
@ -1487,11 +1615,11 @@ void FurnaceCV::render(unsigned char joyIn) {
|
|||
for (int i=0; i<224; i++) {
|
||||
rasterH(i);
|
||||
|
||||
unsigned short x0=scrollX[0]%448;
|
||||
unsigned short x1=scrollX[1]%448;
|
||||
unsigned short x0=scrollX[0]%stageWidthPx;
|
||||
unsigned short x1=scrollX[1]%stageWidthPx;
|
||||
|
||||
y0%=448;
|
||||
y1%=448;
|
||||
y0%=stageHeightPx;
|
||||
y1%=stageHeightPx;
|
||||
|
||||
for (int j=0; j<320; j++) {
|
||||
unsigned short t0=tile0[y0>>3][x0>>3]&0xfff;
|
||||
|
|
@ -1511,8 +1639,8 @@ void FurnaceCV::render(unsigned char joyIn) {
|
|||
*pb++=0;
|
||||
}
|
||||
|
||||
if (++x0>=640) x0=0;
|
||||
if (++x1>=640) x1=0;
|
||||
if (++x0>=stageWidthPx) x0=0;
|
||||
if (++x1>=stageWidthPx) x1=0;
|
||||
}
|
||||
|
||||
y0++;
|
||||
|
|
@ -1610,6 +1738,7 @@ void FurnaceCV::unload() {
|
|||
if (fxChanBase>=0) {
|
||||
e->removeSystem(e->song.systemLen-1);
|
||||
}
|
||||
e->setSongRate(origSongRate);
|
||||
|
||||
if (curStage!=NULL) {
|
||||
delete[] curStage;
|
||||
|
|
@ -1618,13 +1747,13 @@ void FurnaceCV::unload() {
|
|||
}
|
||||
|
||||
#define IS_VISIBLE ((x-cv->viewX+(spriteWidth<<3))>=0 && (x-cv->viewX)<320 && (y-cv->viewY+(spriteHeight<<3))>=0 && (y-cv->viewY)<224)
|
||||
#define IS_IN_AREA ((x+(spriteWidth<<3))>=0 && (x)<640 && (y+(spriteHeight<<3))>=0 && (y)<448)
|
||||
#define HITS_BORDER (x<0 || y<0 || (x+(spriteWidth<<3))>=640 || (y+(spriteHeight<<3))>=448)
|
||||
#define IS_IN_AREA ((x+(spriteWidth<<3))>=0 && (x)<cv->stageWidthPx && (y+(spriteHeight<<3))>=0 && (y)<cv->stageHeightPx)
|
||||
#define HITS_BORDER (x<0 || y<0 || (x+(spriteWidth<<3))>=cv->stageWidthPx || (y+(spriteHeight<<3))>=cv->stageHeightPx)
|
||||
#define CONFINE_TO_BORDER \
|
||||
if (x<0) x=0; \
|
||||
if (y<0) y=0; \
|
||||
if ((x+(spriteWidth<<3))>=640) x=639-(spriteWidth<<3); \
|
||||
if ((y+(spriteHeight<<3))>=448) y=447-(spriteHeight<<3);
|
||||
if ((x+(spriteWidth<<3))>=cv->stageWidthPx) x=(cv->stageWidthPx-1)-(spriteWidth<<3); \
|
||||
if ((y+(spriteHeight<<3))>=cv->stageHeightPx) y=(cv->stageHeightPx-1)-(spriteHeight<<3);
|
||||
|
||||
// FurnaceCVPlayer IMPLEMENTATION
|
||||
|
||||
|
|
@ -1634,6 +1763,8 @@ void FurnaceCVPlayer::collision(FurnaceCVObject* other) {
|
|||
other->type==CV_ENEMY) {
|
||||
if (!invincible) {
|
||||
dead=true;
|
||||
cv->speedTicks=0;
|
||||
cv->e->setSongRate(cv->origSongRate);
|
||||
cv->respawnTime=48;
|
||||
if (cv->weaponStack.empty()) {
|
||||
cv->shotType=0;
|
||||
|
|
@ -1669,14 +1800,18 @@ static const int shootDirOrient[8]={
|
|||
void FurnaceCVPlayer::tick() {
|
||||
signed char sdX=0;
|
||||
signed char sdY=0;
|
||||
|
||||
int maxSpeed=(cv->speedTicks>0)?128:64;
|
||||
int maxSpeedDiagonal=(cv->speedTicks>0)?90:45;
|
||||
|
||||
if (cv->joyInput&16) {
|
||||
speedY-=12;
|
||||
sdY=-1;
|
||||
if (speedY<-64) speedY=-64;
|
||||
if (speedY<-maxSpeed) speedY=-maxSpeed;
|
||||
} else if (cv->joyInput&32) {
|
||||
speedY+=12;
|
||||
sdY=1;
|
||||
if (speedY>64) speedY=64;
|
||||
if (speedY>maxSpeed) speedY=maxSpeed;
|
||||
} else {
|
||||
if (speedY>0) {
|
||||
speedY-=12;
|
||||
|
|
@ -1689,11 +1824,11 @@ void FurnaceCVPlayer::tick() {
|
|||
if (cv->joyInput&64) {
|
||||
speedX-=12;
|
||||
sdX=-1;
|
||||
if (speedX<-64) speedX=-64;
|
||||
if (speedX<-maxSpeed) speedX=-maxSpeed;
|
||||
} else if (cv->joyInput&128) {
|
||||
speedX+=12;
|
||||
sdX=1;
|
||||
if (speedX>64) speedX=64;
|
||||
if (speedX>maxSpeed) speedX=maxSpeed;
|
||||
} else {
|
||||
if (speedX>0) {
|
||||
speedX-=12;
|
||||
|
|
@ -1706,10 +1841,10 @@ void FurnaceCVPlayer::tick() {
|
|||
|
||||
// sqrt(2)
|
||||
if (speedX && speedY) {
|
||||
if (speedX>45) speedX=45;
|
||||
if (speedX<-45) speedX=-45;
|
||||
if (speedY>45) speedY=45;
|
||||
if (speedY<-45) speedY=-45;
|
||||
if (speedX>maxSpeedDiagonal) speedX=maxSpeedDiagonal;
|
||||
if (speedX<-maxSpeedDiagonal) speedX=-maxSpeedDiagonal;
|
||||
if (speedY>maxSpeedDiagonal) speedY=maxSpeedDiagonal;
|
||||
if (speedY<-maxSpeedDiagonal) speedY=-maxSpeedDiagonal;
|
||||
}
|
||||
|
||||
subX+=speedX;
|
||||
|
|
@ -1863,9 +1998,9 @@ void FurnaceCVPlayer::tick() {
|
|||
cv->viewX=x-160+12;
|
||||
cv->viewY=y-112+12;
|
||||
if (cv->viewX<0) cv->viewX=0;
|
||||
if (cv->viewX>320) cv->viewX=320;
|
||||
if (cv->viewX>cv->stageWidthPx-320) cv->viewX=cv->stageWidthPx-320;
|
||||
if (cv->viewY<0) cv->viewY=0;
|
||||
if (cv->viewY>224) cv->viewY=224;
|
||||
if (cv->viewY>cv->stageHeightPx-224) cv->viewY=cv->stageHeightPx-224;
|
||||
cv->scrollX[0]=cv->viewX;
|
||||
cv->scrollY[0]=cv->viewY;
|
||||
}
|
||||
|
|
@ -2104,16 +2239,21 @@ void FurnaceCVEnemy1::collision(FurnaceCVObject* other) {
|
|||
if (--health<=0) {
|
||||
dead=true;
|
||||
if ((rand()%7)==0 || (enemyType>1 && (rand()%7)==3)) {
|
||||
switch (rand()%10) {
|
||||
case 0:
|
||||
switch (rand()%13) {
|
||||
case 0: // extra life
|
||||
cv->createObject<FurnaceCVExtraLife>(x+(enemyType>=2?8:0),y+(enemyType>=2?8:0));
|
||||
break;
|
||||
case 1: case 2: case 3: case 4:
|
||||
case 1: case 2: case 3: case 4: // powerup
|
||||
cv->createObject<FurnaceCVPowerupP>(x+(enemyType>=2?8:0),y+(enemyType>=2?8:0));
|
||||
break;
|
||||
case 5: case 6: case 7: case 8: case 9:
|
||||
case 5: case 6: case 7: case 8: case 9: // powerup
|
||||
cv->createObject<FurnaceCVPowerupS>(x+(enemyType>=2?8:0),y+(enemyType>=2?8:0));
|
||||
break;
|
||||
case 10: case 11: // special
|
||||
break;
|
||||
case 12: // mod
|
||||
cv->createObject<FurnaceCVModS>(x+(enemyType>=2?8:0),y+(enemyType>=2?8:0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
cv->soundEffect(SE_EXPL1);
|
||||
|
|
@ -2229,9 +2369,9 @@ void FurnaceCVEnemy1::tick() {
|
|||
|
||||
if (HITS_BORDER) {
|
||||
if (x<0) orient=0;
|
||||
if (x>=640-16) orient=2;
|
||||
if (x>=cv->stageWidthPx-16) orient=2;
|
||||
if (y<0) orient=3;
|
||||
if (y>=224-16) orient=1;
|
||||
if (y>=cv->stageHeightPx-16) orient=1;
|
||||
cv->soundEffect(SE_TANKMOVE);
|
||||
CONFINE_TO_BORDER;
|
||||
}
|
||||
|
|
@ -2873,6 +3013,34 @@ void FurnaceCVExtraLife::tick() {
|
|||
}
|
||||
}
|
||||
|
||||
// FurnaceCVModS IMPLEMENTATION
|
||||
|
||||
void FurnaceCVModS::collision(FurnaceCVObject* other) {
|
||||
if (other->type==CV_PLAYER) {
|
||||
dead=true;
|
||||
cv->soundEffect(SE_PICKUP1);
|
||||
cv->addScore(200);
|
||||
cv->speedTicks=900;
|
||||
cv->e->setSongRate(cv->origSongRate*1.5);
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceCVModS::tick() {
|
||||
if (--life==0) dead=true;
|
||||
|
||||
if (life>64 || (life&1)) {
|
||||
spriteDef[0]=0x41e;
|
||||
spriteDef[1]=0x41f;
|
||||
spriteDef[2]=0x43e;
|
||||
spriteDef[3]=0x43f;
|
||||
} else {
|
||||
spriteDef[0]=0;
|
||||
spriteDef[1]=0;
|
||||
spriteDef[2]=0;
|
||||
spriteDef[3]=0;
|
||||
}
|
||||
}
|
||||
|
||||
// FurnaceCVEnemyVortex IMPLEMENTATION
|
||||
|
||||
void FurnaceCVEnemyVortex::collision(FurnaceCVObject* other) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue