Some scripts and ideas from the quest "Grikarugun".
The whole game is a work in progress, but some definative concepts on how to go about making everything work together have emerged for me, and I pretty much have a kind of set Archtype I follow for certain things, plus there's some cool scripts too! 😛 I'm going to try and post all of these at some point and in a cohesive manner..(at some point also 😛)
Some pretty sweet functions to start:
void spawn(int data, int x, int y, int spawned_ffc){ ffc F = Screen->LoadFFC(spawned_ffc);
F->Data = data;
F->X = x; F->Y = y;
}
Use by: spawn(data,x,y,ffc_number); To gain control over that ffc and move it around fast.
void Homing(int speed, int ffc_num, int target_x, int target_y){
ffc F=Screen->LoadFFC(ffc_num);
int dx = target_x - F->X;
int dy = target_x - F->Y;
float norm = Sqrt(dx*dx+dy*dy);
if(norm > 0){
F->Vx = dx/norm*speed;
F->Vy = dy/norm*speed;
}
}Turns an ffc into a homing missile. 'Nuff said. 😎 Call to it once for a fireball effect, or every frame for unavoidable death.
int getFFC(int min, int max){
ffc F;int i=min-1;
while(i++ < max){
F=Screen->LoadFFC(i);
if(F->Data<=1){return i;i=max;}
else if(i==max)return 0;
}
}Returns an unused ffc. INVALUABLE. Huge space saver to boot. use it by:
FFC = Screen->LoadFFC(getFFC(1,32));int nearest_enemy(int x, int y){
int d;int p=9999;int e;
int e_num = Screen->NumNPCs();
for(int i = e_num; i>0; i--){
npc enemy = Screen->LoadNPC(i);
if(enemy->X>-4){
int ex = enemy->X;int ey = enemy->Y;
d = Distance(x,y,ex,ey);
if(p>d){p=d;e=i;}
}
}
return e;
}Returns the nearest enemy to inputted x,y locations. Or:
int nearest_enemy(int x, int y){
int d;int p=9999;int e;
int e_num = Screen->NumNPCs();
for(int i = e_num; i>0; i--){
npc enemy = Screen->LoadNPC(i);
int ex = enemy->X;int ey = enemy->Y;
d = Distance(x,y,ex,ey);
if(p>d){p=d;e=i;}
}
return e;
}Use this if you're not hiding enemies off-screen.
Bullets: :heart:
void HomingShot(int lx, int ly, int tx, int ty){ eweapon laser;
laser = Screen->CreateEWeapon(EW_MAGIC);laser->ColWidth=6;laser->ColHeight=6;
laser->X=tx;laser->Y=ty;laser->Step=2;laser->Damage=2;laser->CSet=0;
laser->Angular=true;laser->Angle = ArcTan(lx-tx,ly-ty);
}
Just like a fire statue, but smaller.
void ClusterBomb(int tx, int ty){ eweapon laser;
for(int i;i<30;i++){
laser = Screen->CreateEWeapon(EW_MAGIC);laser->ColWidth=6;laser->ColHeight=6;
laser->X=tx;laser->Y=ty;laser->Step=1;laser->Damage=2;laser->CSet=0;
laser->Angular=true;laser->Angle = (i*12)*(PI/180);
}
//Game->PlaySound(SFX_BOMB2);
}
Explodes into a perfect cluster of death.
target=Screen->LoadNPC(nearest_enemy(m1->X,m1->Y));
missile_angle=ArcTan(target->X-m1->X,target->Y-m1->Y);
if(m->Angle>missile_angle)m->Angle-=0.4;
else m1->Angle+=0.4;Homing sprites..still a bit buggy, but I'm working on them.
For backgrounds this works great:
ffc script Bg_stars{ void run(){
int delay = 0; int cset = 0;
this->X = 0; this->Y = -16;
int t = 38460;
while(true){
Waitframe();
int tx = this->X; int ty = this->Y;
Screen->DrawTile(0,tx,ty,t,16,13,cset,1,0,0,0,0,true,128);
delay++;
if(delay >= 4){ this->Y++; delay=0;}
if(this->Y >= 0){this->Y = -16; t -= 20;}
if(t < 37700)t=38460;
}
}
}
Also basic code for the option:
int save_link_x[40];
int save_link_y[40]; n=1;
int init_pos=0;
while(init_pos++<=40){
save_link_x[init_pos]=lx;
save_link_y[init_pos]=ly;
}
if(n>40)n=1;
if(input_up){save_link_x[n]=lx;save_link_y[n]=ly;n++;}
else if(input_down){save_link_x[n]=lx;save_link_y[n]=ly;n++;}
else if(input_left){save_link_x[n]=lx;save_link_y[n]=ly;n++;}
else if(input_right){save_link_x[n]=lx;save_link_y[n]=ly;n++;}
int ns;
if(n>20)ns=n-20;
else ns=n+20;
shield->X=save_link_x[ns];shield->Y=save_link_y[ns];
Will follow behind the player by 20 frames. It's controlled by the Global script which is why it may look akward, and that may be true, but the ffcs are multitasking! Also "shield" is referring to FFC 7.
Also, I apologize for right now, as you'd have to have some scripting knowledge to use these, but we're making progress!
Also worth mentioning are some early crappy versions of the scripts from This Post. And the early bullet code I made before jman2050 gave us sprite weapons. thanks jman!
Don't use this script! it sucks....😞
const int CIRCLE=0;
const int CIR_ROTATE=99;
const int SPREAD_D=0;
ffc script bullet{ void run(){
int b_enemy=38;
int delay=0;
bool init;
int rand = Rand(20);
//========================================
// ~BULLET DATA~
//========================================
int a1x; int a1y; int a2x; int a2y;
int a3x; int a3y; int a4x; int a4y;
int a5x; int a5y; int a6x; int a6y;
int a7x; int a7y; int a8x; int a8y;
int a9x; int a9y; int a10x; int a10y;
int a11x; int a11y; int a12x; int a12y;
int a13x; int a13y; int a14x; int a14y;
int a15x; int a15y; int a16x; int a16y;
npc e1; npc e2; npc e3; npc e4;
npc e5; npc e6; npc e7; npc e8;
npc e9; npc e10; npc e11; npc e12;
npc e13; npc e14; npc e15; npc e16;
bool init_bullet;int bullet_delay;int slow_lag;int bullet=0;
while(true){
Waitframe();
int tx = this->X; int ty = this->Y;
int lx = Link->X; int ly = Link->Y;
//=======================
// ~ENEMY CREATION~
//=======================
if(!init_bullet){
Waitframes(6);
e1 = Screen->CreateNPC(b_enemy);
e2 = Screen->CreateNPC(b_enemy);
e3 = Screen->CreateNPC(b_enemy);
e4 = Screen->CreateNPC(b_enemy);
e5 = Screen->CreateNPC(b_enemy);
e6 = Screen->CreateNPC(b_enemy);
e7 = Screen->CreateNPC(b_enemy);
e8 = Screen->CreateNPC(b_enemy);
e9 = Screen->CreateNPC(b_enemy);
e10 = Screen->CreateNPC(b_enemy);
e11 = Screen->CreateNPC(b_enemy);
e12 = Screen->CreateNPC(b_enemy);
e13 = Screen->CreateNPC(b_enemy);
e14 = Screen->CreateNPC(b_enemy);
e15 = Screen->CreateNPC(b_enemy);
e16 = Screen->CreateNPC(b_enemy);
e1->X=-48; e1->Y=-48;e2->X=-48; e2->Y=-48;
e3->X=-48; e3->Y=-48;e4->X=-48; e4->Y=-48;
e5->X=-48; e5->Y=-48;e6->X=-48; e6->Y=-48;
e7->X=-48; e7->Y=-48;e8->X=-48; e8->Y=-48;
e9->X=-48; e9->Y=-48;e10->X=-48; e10->Y=-48;
e11->X=-48; e11->Y=-48;e12->X=-48; e12->Y=-48;
e13->X=-48; e13->Y=-48;e14->X=-48; e14->Y=-48;
e15->X=-48; e15->Y=-48;e16->X=-48; e16->Y=-48;
init_bullet = true;
}
//=======================
// ~BULLET HANDLING~
//=======================
if(this->Data>1){
if(!init){
a1x=tx;a1y=ty;a2x=tx;a2y=ty;a3x=tx;a3y=ty;a4x=tx;a4y=ty;
a5x=tx;a5y=ty;a6x=tx;a6y=ty;a7x=tx;a7y=ty;a8x=tx;a8y=ty;
a9x=tx;a9y=ty;a10x=tx;a10y=ty;a11x=tx;a11y=ty;a12x=tx;a12y=ty;
a13x=tx;a13y=ty;a14x=tx;a14y=ty;a15x=tx;a15y=ty;a16x=tx;a16y=ty;
init=true;
}
if(this->Data==CIRCLE){ //8way
a1y++;
a2x-=0.35; a2y+=0.85;
a3x-=0.7; a3y+=0.7;
a4x-=0.85; a4y+=0.35;
a5x--;
a6x-=0.85; a6y-=0.35;
a7x-=0.7; a7y-=0.7;
a8x-=0.35; a8y-=0.85;
a9y--;
a10x+=0.35; a10y-=0.85;
a11x+=0.7; a11y-=0.7;
a12x+=0.85; a12y-=0.35;
a13x++;
a14x+=0.85; a14y+=0.35;
a15x+=0.7; a15y+=0.7;
a16x+=0.35; a16y+=0.85;
}
else if(this->Data==CIR_ROTATE){ //rotating circle
a1y++;
if(delay>2){ a2x-=0.4; a2y+=0.85;}
if(delay>4){ a3x-=0.7; a3y+=0.7;}
if(delay>6){ a4x-=0.85; a4y+=0.4;}
if(delay>8){ a5x--; }
if(delay>10){ a6x-=0.85; a6y-=0.4; }
if(delay>12){ a7x-=0.7; a7y-=0.7;}
if(delay>14){ a8x-=0.4; a8y-=0.85;}
if(delay>16){ a9y--; }
if(delay>18){ a10x+=0.4; a10y-=0.85;}
if(delay>20){ a11x+=0.7; a11y-=0.7;}
if(delay>22){ a12x+=0.85; a12y-=0.4; }
if(delay>24){ a13x++; }
if(delay>28){ a14x+=0.85; a14y+=0.4; }
if(delay>30){ a15x+=0.7; a15y+=0.7;}
if(delay>32){ a16x+=0.4; a16y+=0.85;}
delay++;
}
else if(this->Data==SPREAD_D){ //downward spread
a1y++; a1x-=0.18; a2y++; a2x+=0.18;
a3x--; a4x++;
a5x-=0.8; a5y+=0.35; a6x+=0.8; a6y+=0.35;
a7x-=0.7; a7y+=0.7; a8x+=0.7; a8y+=0.7;
}
//=======================
// ~ENEMY MAINTENANCE~
//=======================
bullet_delay++;
if(bullet_delay>60){
if(a1x>270)a1x=270; else if(a1x<-20)a1x=-20; if(a1y>180)a1y=180; else if(a1y<-20)a1y=-20;
if(a2x>270)a2x=270; else if(a2x<-20)a2x=-20; if(a2y>180)a2y=180; else if(a2y<-20)a2y=-20;
if(a3x>270)a3x=270; else if(a3x<-20)a3x=-20; if(a3y>180)a3y=180; else if(a3y<-20)a3y=-20;
if(a4x>270)a4x=270; else if(a4x<-20)a4x=-20; if(a4y>180)a4y=180; else if(a4y<-20)a4y=-20;
if(a5x>270)a5x=270; else if(a5x<-20)a5x=-20; if(a5y>180)a5y=180; else if(a5y<-20)a5y=-20;
if(a6x>270)a6x=270; else if(a6x<-20)a6x=-20; if(a6y>180)a6y=180; else if(a6y<-20)a6y=-20;
if(a7x>270)a7x=270; else if(a7x<-20)a7x=-20; if(a7y>180)a7y=180; else if(a7y<-20)a7y=-20;
if(a8x>270)a8x=270; else if(a8x<-20)a8x=-20; if(a8y>180)a8y=180; else if(a8y<-20)a8y=-20;
if(a9x>270)a9x=270; else if(a9x<-20)a9x=-20; if(a9y>180)a9y=180; else if(a9y<-20)a9y=-20;
if(a10x>270)a10x=270; else if(a10x<-20)a10x=-20; if(a10y>180)a10y=180; else if(a10y<-20)a10y=-20;
if(a11x>270)a11x=270; else if(a11x<-20)a11x=-20; if(a11y>180)a11y=180; else if(a11y<-20)a11y=-20;
if(a12x>270)a12x=270; else if(a12x<-20)a12x=-20; if(a12y>180)a12y=180; else if(a12y<-20)a12y=-20;
if(a13x>270)a13x=270; else if(a13x<-20)a13x=-20; if(a13y>180)a13y=180; else if(a13y<-20)a13y=-20;
if(a14x>270)a14x=270; else if(a14x<-20)a14x=-20; if(a14y>180)a14y=180; else if(a14y<-20)a14y=-20;
if(a15x>270)a15x=270; else if(a15x<-20)a15x=-20; if(a15y>180)a15y=180; else if(a15y<-20)a15y=-20;
if(a16x>270)a16x=270; else if(a16x<-20)a16x=-20; if(a16y>180)a16y=180; else if(a16y<-20)a16y=-20;
bullet_delay=0;
}
e1->X=a1x; e1->Y=a1y;
e2->X=a2x; e2->Y=a2y;
e3->X=a3x; e3->Y=a3y;
e4->X=a4x; e4->Y=a4y;
e5->X=a5x; e5->Y=a5y;
e6->X=a6x; e6->Y=a6y;
e7->X=a7x; e7->Y=a7y;
e8->X=a8x; e8->Y=a8y;
e9->X=a9x; e9->Y=a9y;
e10->X=a10x; e10->Y=a10y;
e11->X=a11x; e11->Y=a11y;
e12->X=a12x; e12->Y=a12y;
e13->X=a13x; e13->Y=a13y;
e14->X=a14x; e14->Y=a14y;
e15->X=a15x; e15->Y=a15y;
e16->X=a16x; e16->Y=a16y;
}
else{
slow_lag++;init=false;
if(slow_lag>100+rand){
e1->X=-48; e1->Y=-48;e2->X=-48; e2->Y=-48;
e3->X=-48; e3->Y=-48;e4->X=-48; e4->Y=-48;
e5->X=-48; e5->Y=-48;e6->X=-48; e6->Y=-48;
e7->X=-48; e7->Y=-48;e8->X=-48; e8->Y=-48;
e9->X=-48; e9->Y=-48;e10->X=-48; e10->Y=-48;
e11->X=-48; e11->Y=-48;e12->X=-48; e12->Y=-48;
e13->X=-48; e13->Y=-48;e14->X=-48; e14->Y=-48;
e15->X=-48; e15->Y=-48;e16->X=-48; e16->Y=-48;
slow_lag=0;
}
}
}
}
}
Man, it's come a long way.