Author Topic: Danmakufu Q&A/Problem Thread  (Read 172159 times)

Re: Danmakufu Q&A/Problem Thread
« Reply #840 on: October 07, 2009, 01:20:07 AM »
Yep
a quick question about tasks, if there are these:
Bullet(x, y, v, angle)
what does this mean? its not defined in the turorial.

Nuclear Cheese

  • Relax and enjoy the danmaku.
    • My homepage
Re: Danmakufu Q&A/Problem Thread
« Reply #841 on: October 07, 2009, 01:25:49 AM »
Yep

Hint - you don't need to use tasks for object shots.  That's how I use them in the tutorial I write

Personally, I hate Danmakufu's task setup, and avoid it whenever possible.  But that's just me.
to quote Naut:
"I can see the background, there are too many safespots."
:V

Re: Danmakufu Q&A/Problem Thread
« Reply #842 on: October 07, 2009, 01:34:39 AM »
Hint - you don't need to use tasks for object shots.  That's how I use them in the tutorial I write

Personally, I hate Danmakufu's task setup, and avoid it whenever possible.  But that's just me.
lol right as i found it, that really is kind of messy how its set up, i want to try to make multiple of
them so i tried looping them and only one followed the player.

Helepolis

  • Charisma!
  • *
  • O-ojousama!?
Re: Danmakufu Q&A/Problem Thread
« Reply #843 on: October 07, 2009, 05:44:18 AM »
I have a strange urge to play Doom again...

Anyway it might've been some kind of math error? Seeing the code would be better, as well as knowing how the camera is supposed to move. Do you want it to turn when it reaches the wall or something?

I want to perform a circle inside the big room but let alone the circle, even just going straight forward messes it up. Here is the code.

Note that f++ is disabled. So the 3D objects are not scrolling.

Code: [Select]
flight+=5;

// pre stuff
WriteZBuffer(true);
      UseZBuffer(true);
SetViewTo(0,256,0);
SetViewFrom(1024+flight,270,0);
SetPerspectiveClip(0,8000);

// Normal bg
if(dc<10){SetTexture(bg);}
if(dc>=10 && dc<20){SetTexture(bg2);}
if(dc>=20 && dc<30){SetTexture(bg3);}
if(dc>=30 && dc<40){SetTexture(bg4);}
if(dc>=40 && dc<50){SetTexture(bg5);}
SetRenderState(ALPHA);
SetAlpha(255);
SetColor(255,255,255);
SetGraphicRect(0,0,768,512);
SetGraphicAngle(180,0,0);
SetGraphicScale(0.1,0.1);
DrawGraphic3D(0,gview,0);

//SetFog(0,3000,0,0,0);

makevloer(0,0,-1024+f);
makevloer(1024,0,-1024+f);
makevloer(2048,0,-1024+f);

makevloer(0,0,f);
makevloer2(1024,0,f);
makevloer(2048,0,f);

makevloer(0,0,1024+f);
makevloer(1024,0,1024+f);
makevloer(2048,0,1024+f);

// centraal plafon
makeplafoncenter(0,800,-1024+f);
makeplafoncenter(1024,800,-1024+f);
makeplafoncenter(2048,800,-1024+f);

makeplafoncenter(0,800,f);
makeplafoncenter(1024,800,f);
makeplafoncenter(2048,800,f);

makeplafoncenter(0,800,1024+f);
makeplafoncenter(1024,800,1024+f);
makeplafoncenter(2048,800,1024+f);

// links
makemuur(-512,192,-1024+f,90);
makemuur(-512,192,f,90);
makemuur(-512,192,1024+f,90);

// voor
makemuur(0,192,-1536+f,0);
makemuur(1024,192,-1536+f,0);
makemuur(2048,192,-1536+f,0);

// rechts
makemuur(2560,192,-1024+f,90);
makemuur(2560,192,f,90);
makemuur(2560,192,1024+f,90);

// achter
makemuur(0,192,1536+f,0);
makemuur(1024,192,1536+f,0);
makemuur(2048,192,1536+f,0);

// plafon links
makeplafon(-336,616,-1024+f,90);
makeplafon(-336,616,f,90);
makeplafon(-336,616,1024+f,90);

// plafon voor
makeplafon(0,616,-1352+f,0);
makeplafon(1024,616,-1352+f,0);
makeplafon(2048,616,-1352+f,0);

// plafon rechts
makeplafon(2384,616,-1024+f,270);
makeplafon(2384,616,f,270);
makeplafon(2384,616,1024+f,270);

// plafon achter
makeplafon(0,616,1352+f,180);
makeplafon(1024,616,1352+f,180);
makeplafon(2048,616,1352+f,180);

        //f++;

Lawence Codye

  • The Nine Tails of Subconscious...
  • Come & your desires shall all become reality...
Re: Danmakufu Q&A/Problem Thread
« Reply #844 on: October 07, 2009, 03:32:01 PM »
I need help bad...my player's unfocused bullets do more then her focused bullets do...can't seem to fix this...& yes, I tried but I'm new with this script type.  I get to this point & brickwall...could someone download my script below...
http://www.mediafire.com/?sharekey=388cf395c6d90a0a391d7d881749d3a7487d47f3656e0f0f4ad239450a8c1cf1
& find what's causing this possibly...please...thank you...
I am the Nine Tails of Subconscious...

Come & your greatest desires will be reality...

Re: Danmakufu Q&A/Problem Thread
« Reply #845 on: October 07, 2009, 05:08:24 PM »
Well... You're shooting 17 bullets every eight frames when unfocused versus three bullets every six frames when focused. Though the three bullets have slightly more damage per bullet (3.0 vs 2.5), you're still doing 17*2.5=42.5 damage every 8 frames when unfocused, versus 3*3=9 damage every 6 frames. That's a difference of...

(60/8)*42.5 = 318.75 dps unfocused; shotgun.

(60/6)*9 = 90 dps focused; shotgun.

Or an overall difference of 318.75/90 = 3.54167 times more damage per second.

Well that's good and all, so where did you screw up. The answer lies in your @MainLoop: the while(i<=3){} statements. For focused movement, you declare i=3 before beginning the while statement, meaning the statement is preformed once, so three bullets are fired every six frames (player and both options). For unfocused, you declare i=-3 before starting the while statement, meaning the the action is preformed seven times as i is incremented every while statement. For your options, the condition is only preformed five times since you declare i=-2 and have a while statement while(i<=2){}, meaning 17 bullets are fired every eight frames (5+5+7=17). Simply fix your negatives for the i declarations before the while statements for your player shots and both options -- this should give you relatively close dps for focused and unfocused movement, save for the damage differences between the shots (3.0 vs 2.5) as well as the different firerate (7.5 times/second vs 10 times/second).

Hopefully I explained this clearly, I didn't want to include code snippets since you only have the six while statements...

Stuffman

  • *
  • We're having a ball!
Re: Danmakufu Q&A/Problem Thread
« Reply #846 on: October 07, 2009, 05:15:49 PM »
Oh, Helepolis; I think the problem is that you want to scroll your SetViewTo rather than your SetViewFrom.

SetViewTo=what your camera is looking at
SetViewFrom=where your camera is looking at it from

You're going to want to maintain the same camera distance (probably) and just move it around so I would have your SetViewTo scale instead. I don't know if that's actually the source of your problem, it's just another thing you could try that could make it go away  :V

Note: You WILL have to change the angle on SetViewFrom when you go to add the turning.

puremrz

  • Can't stop playing Minecraft!
Re: Danmakufu Q&A/Problem Thread
« Reply #847 on: October 07, 2009, 07:27:02 PM »
Hm! I'm trying to recreate the effect of Utsuho's 2nd spell where the bullets shrink as time passes.
So far I cough this up:

Code: [Select]
if(frame%10==0 && frame>60){
shot=(Obj_Create(OBJ_EFFECT));
Obj_SetCollisionToPlayer(shot,true);
Obj_SetPosition(shot,cx+rand(-150,150),miny);
ObjEffect_SetLayer(shot,5); Obj_SetAngle(shot,90);
Obj_SetSpeed(shot,2);
ObjEffect_SetTexture(shot,GRbullet);
ObjEffect_SetPrimitiveType(shot,PRIMITIVE_TRIANGLESTRIP);
ObjEffect_CreateVertex(shot,4);
ObjEffect_SetScale(shot,1,1);
ObjEffect_SetVertexXY(shot,0,-128,-128); ObjEffect_SetVertexUV(shot,0,0,0);
ObjEffect_SetVertexXY(shot,1,128,-128); ObjEffect_SetVertexUV(shot,1,256,0);
ObjEffect_SetVertexXY(shot,2,-128,128); ObjEffect_SetVertexUV(shot,2,0,256);
ObjEffect_SetVertexXY(shot,3,128,128); ObjEffect_SetVertexUV(shot,3,256,256);
hitbox=hitbox~[shot];
}
let i=0;
while (i<length(hitbox)){
SetCollisionB(Obj_GetX(hitbox[i]),Obj_GetY(hitbox[i]),100);
if(Obj_BeDeleted(hitbox[i])){
hitbox=erase(hitbox,i);
i--;
}
else{
ObjEffect_SetScale(hitbox[i],1-?,1-?);
}
i++;
}

But I can't seem to find a way to make each individual bullet shrink over time. Any ideas?
Full Danmakufu game "Juuni Jumon - Summer Interlude" is done!
By the same person who made Koishi Hell 1,2 (except this game is serious)
Topic: http://www.shrinemaiden.org/forum/index.php/topic,9647.0.html

Helepolis

  • Charisma!
  • *
  • O-ojousama!?
Re: Danmakufu Q&A/Problem Thread
« Reply #848 on: October 07, 2009, 08:10:04 PM »
And this is why you should use tasks :V because object bullets written in task receive individual parameters when spawned.

@Stuffman,

Haven't been able to try out your suggestion. Going to bed soon. Will do it tommorow and update you about it.

Nuclear Cheese

  • Relax and enjoy the danmaku.
    • My homepage
Re: Danmakufu Q&A/Problem Thread
« Reply #849 on: October 08, 2009, 01:57:26 AM »
And this is why you should use arrays :V

Fixed that for you. :D

Sorry, I just really hate Danmakufu's tasks that much.
to quote Naut:
"I can see the background, there are too many safespots."
:V

Henry

  • The observer
  • Exploring to the new world of Danmaku
Re: Danmakufu Q&A/Problem Thread
« Reply #850 on: October 08, 2009, 02:35:56 AM »
Sorry, I just really hate Danmakufu's tasks that much.

LOL, but how can you check collision with arrays? A lot of searching is required... (but still faster than tasks?)
Old/Forgotten member.

Old Patchouli Project was outdated but new one is in progress.

Helepolis

  • Charisma!
  • *
  • O-ojousama!?
Re: Danmakufu Q&A/Problem Thread
« Reply #851 on: October 08, 2009, 06:46:00 AM »
Sorry, I just really hate Danmakufu's tasks that much.

But I love em ! And Arrays are also an option ye. But whatever floats yours boat.

puremrz

  • Can't stop playing Minecraft!
Re: Danmakufu Q&A/Problem Thread
« Reply #852 on: October 08, 2009, 06:50:49 AM »
And this is why you should use tasks :V because object bullets written in task receive individual parameters when spawned.

So you know how to fix it then? =|
Full Danmakufu game "Juuni Jumon - Summer Interlude" is done!
By the same person who made Koishi Hell 1,2 (except this game is serious)
Topic: http://www.shrinemaiden.org/forum/index.php/topic,9647.0.html

Helepolis

  • Charisma!
  • *
  • O-ojousama!?
Re: Danmakufu Q&A/Problem Thread
« Reply #853 on: October 08, 2009, 07:11:40 AM »
So you know how to fix it then? =|

I can only tell you the tasking method as I have no expirience with the array method.

task shrinkingbullet(x,y,v,dir,graphic,delay,scale){
   let shot = Obj_Createshotect(OBJ_EFFECT);

   Obj_SetPosition(shot,x,y);
   Obj_SetSpeed(shot,v);
   ...
   etc etc... (

   <I forgot the code for the scale (please look it up on wiki, which is the starting scale.>


   while(!Obj_BeDeleted){

      < Here the code for shrinking the bullet over time >

        }

}


Now somewhere in your MainLoop you simply call: shrinkingbullet(......); and fill the parameters like where you want it to spawn, speed, dir etc etc.

And that's it.

Henry

  • The observer
  • Exploring to the new world of Danmaku
Re: Danmakufu Q&A/Problem Thread
« Reply #854 on: October 08, 2009, 02:08:06 PM »
Hi.
In the stage tutorial, a function WaitforZeroEnemy is used.
However, if the player cannot kill all the enemies, the stage stuck there.
What can be the solution to this?
Old/Forgotten member.

Old Patchouli Project was outdated but new one is in progress.

Helepolis

  • Charisma!
  • *
  • O-ojousama!?
Re: Danmakufu Q&A/Problem Thread
« Reply #855 on: October 08, 2009, 02:28:49 PM »
Hi.
In the stage tutorial, a function WaitforZeroEnemy is used.
However, if the player cannot kill all the enemies, the stage stuck there.
What can be the solution to this?

Are you using enemies that move inside the field and move out again? Like ZUN does in his most games. If you make the enemies move off the screen, it would be wise to make them vanish or delete so.

Or when the boss enters the screen you can kill off all enemies like ZUN also does.

Bullets are autodeleted off the screen, but cannot say the same about enemies.

Henry

  • The observer
  • Exploring to the new world of Danmaku
Re: Danmakufu Q&A/Problem Thread
« Reply #856 on: October 08, 2009, 02:44:09 PM »
My idea is that:
let count=2;
if(the enemy cross the border, entering the screen area){count--;}
if(the enemy cross the border, leaving the screen area){count--;}
if(count==0){VanishEnemy;}

I'll work it out.

P.S. It works, but the items are spawn anyway. This problem can be easily solved.
« Last Edit: October 08, 2009, 02:47:06 PM by Henry »
Old/Forgotten member.

Old Patchouli Project was outdated but new one is in progress.

Aphid

Re: Danmakufu Q&A/Problem Thread
« Reply #857 on: October 08, 2009, 03:25:20 PM »
It took me long enough, but I got something that does what I want it to do, it's still got one problem though, framerate. Essentially I'd like this code to run at least 400% faster than it does now. Any tips on how?;

This code is in a separate file loaded using #include_script.
In addition, in @MainLoop, there is one statement of RedAimingShots(f).
There's also an f++ in MainLoop, of course.

Currently, the code works perfectly as far as the bullet pattern is concerned.
Currently, the code slows down even a decent computer to a crawl.

Code: [Select]

task CreateShotRed(let x, let y, let speed, let angle)
{
let counter =0;
  let objr = Obj_Create(OBJ_SHOT);
  ArrayShotRed = ArrayShotRed ~ [objr];
Obj_SetX(objr, x);
Obj_SetY(objr, y);
Obj_SetSpeed(objr, speed);
Obj_SetAngle(objr, angle);
ObjShot_SetGraphic(objr, RED02);

while( !Obj_BeDeleted(objr))
{




if(counter > (GetCenterX()*speed*cos((angle))-x*speed*cos

((angle))+GetCenterY()*speed*sin((angle))-y*speed*sin((angle))+0.5*

(speed^2*(8*GetCenterX()*x-4*(x^2+y*(-2* GetCenterY()+y))+4*((GetCenterX()-

x)*cos((angle))+(GetCenterY()-y)*sin((angle)))^2))^0.5)/speed^2) {

ObjShot_Delete(objr);
break;
}
counter++;
yield;
}
let iterator = 0;
loop(length(ArrayShotRed))
{
if(ArrayShotRed[iterator] == objr)
{
ArrayShotRed = erase(ArrayShotRed, iterator);
break;
}
iterator++;
}

}
task CollisionShotsBlue(let x, let y, let speed, let angle)
{
let count=0;
let objb = Obj_Create(OBJ_SHOT);
Obj_SetX(objb, x);
Obj_SetY(objb, y);
Obj_SetSpeed(objb, speed);
Obj_SetAngle(objb, angle);
ObjShot_SetGraphic(objb, BLUE01);
ObjShot_SetDelay(objb, 0);

while( !Obj_BeDeleted(objb))
{
let iteratortwo=0;
loop(length(ArrayShotRed))
{
if(Collision_Obj_Obj(ArrayShotRed[iteratortwo],

objb) == true)
{
CreateShotA(100, x + cos(angle) * speed * count, y +

sin(angle) * speed * count, 0);
SetShotDataA(100, 0, speed * 2, -angle, 0, 0, 20,

RED01);
FireShot(100);
Obj_Delete(objb);
}
iteratortwo++;
}

if(count == 300)
{
ObjShot_FadeDelete(objb);
break;
}
count++;
yield;
}


}


task RedAimingShots(let ftwo) {
ascent(i in 0..36)
{
if(ftwo == 7860 + 60 * i)
{
CreateShotA(2, 224, 30, 0);
SetShotDataA(2, 0, 3.1415 * 210 / 52.5, 0, 180 / 52.5, 0, 20,

RED03);
SetShotDataA(2, 60, NULL, NULL, 0, 0, 20, RED03);
FireShot(2);
CreateShotA(2, 224, 30, 0);
SetShotDataA(2, 0, 3.1415 * 210 / 52.5, 180, -180 / 52.5, 0, 20,

RED03);
SetShotDataA(2, 60, NULL, NULL, 0, 0, 20, RED03);
FireShot(2);
}
ascent(k in 1..4) {
if(ftwo == 7860 + 60 * i + 15 * k) {
let Rthree =  ((GetPlayerX - GetCenterX - 210 * sin(51.428 * k))^2 +

(GetPlayerY - GetCenterY + 210 * cos(51.428 * k))^2)^0.5;
let angthree = atan2((GetPlayerY - GetCenterY + 210 * cos(51.428 *

k)),(GetPlayerX - GetCenterX - 210 * sin(51.428 * k)));
CreateShotRed(224 + 210 * cos(51.428 * k - 90), 240 + 210 * sin

(51.428 * k - 90), Rthree / 90, angthree);
let Rthree =  ((GetPlayerX - GetCenterX + 210 * sin(51.428 * k))^2 +

(GetPlayerY - GetCenterY + 210 * cos(51.428 * k))^2)^0.5;
let angthree = atan2((GetPlayerY - GetCenterY + 210 * cos(51.428 *

k)),(GetPlayerX - GetCenterX + 210 * sin(51.428 * k)));
CreateShotRed(224 - 210 * cos(51.428 * k - 90), 240 + 210 * sin

(51.428 * k - 90), Rthree / 90, angthree);

ascent(j in 0..90) {
CollisionShotsBlue(GetCenterX, GetCenterY, 1, 4 * j + k + atan2

((GetPlayerY - GetCenterY),(GetPlayerX - GetCenterX)))
}
}
}
}
}


Essentially, it uses up two arrays. Had a third array but I scrapped that idea (which was giving the angle of the blue bullets turned red the angle of the bullet that had caused that +- rand10), and simply changed it to reverse angle. The latter didn't make much of a visual diffrence but it saved me one array.

anyways, I went with larger bullets (90) and had the whole thing erase unneeded spaces from both two object bullet groups. (I.e. all bullets going outside of a circle with radius 300 or so from the centerX, centerY space are checked for deletion each frame).

As for the large formulae, here's an idea of what they do.
"         if(count == 300)"
300: The speed is 1, so that puts it outside of the circle.

((GetPlayerX - GetCenterX - 210 * sin(51.428 * k))^2 + (GetPlayerY - GetCenterY + 210 * cos(51.428 * k))^2)^0.5
Basically gives the distance between each k-th spawn point for the reds and the player.

atan2((GetPlayerY - GetCenterY + 210 * cos(51.428 * k)),(GetPlayerX - GetCenterX - 210 * sin(51.428 * k)));
Same, Angle.

if(counter > (GetCenterX()*speed*cos((angle))-x*speed*cos((angle))+GetCenterY()*speed*sin((angle))-y*speed*sin((angle))+0.5*(speed^2*(8*GetCenterX()*x-4*(x^2+y*(-2* GetCenterY()+y))+4*((GetCenterX()-x)*cos((angle))+(GetCenterY()-y)*sin((angle)))^2))^0.5)/speed^2)

Well, um... this basically calculates how long a red bullet will at most need to stay in the array. I mean, it calculates the time it would take for a red bullet to move outside of the boundary set by my circle. It's a result from a quadratic polynomial in 't'.

As for a potential hint to the solution, it seems that the speed of this script is directly proportional to:
- The amount of blue bullets onscreen ==> This is a good sign, it means that the evaluations whether or not a bullet needs to be removed to save processor power are not hogging said processor power.
- The amount of Red Bullets onscreen ==> once again, same reason.

I'm still a bit stuck here what else I can do to make it run at 60fps flat without having to change the pattern in any way.

Helepolis

  • Charisma!
  • *
  • O-ojousama!?
Re: Danmakufu Q&A/Problem Thread
« Reply #858 on: October 08, 2009, 04:28:36 PM »
@Stuffman,

Haven't been able to try out your suggestion. Going to bed soon. Will do it tommorow and update you about it.

You were right, using the SetViewTo is better, it works now and I can make a 90 degree turn and keep heading. But I just discovered I need to enlarge my disco stage because when I turn the camera is too far away I end up outside the room :V. Or adjust my SetViewFrom more closer to the center point.

=D thanks.

Re: Danmakufu Q&A/Problem Thread
« Reply #859 on: October 08, 2009, 06:26:44 PM »
Aphid, post your main file as well, I'm having trouble getting it to even run. It errors on f (so I then declared f = 0;), then on ArrayShotRed (so I declared let ArrayShotRed = []; ), then on ObjShot_Delete(objr) (so I changed it to Obj_Delete(objr); ).

Well now it runs.... But nothing happens. Yes, I have f++; and AimedRedShot(f) in @MainLoop.

So yeah, post the code, please. Or PM it if you'd rather.

puremrz

  • Can't stop playing Minecraft!
Re: Danmakufu Q&A/Problem Thread
« Reply #860 on: October 08, 2009, 07:24:50 PM »
I can only tell you the tasking method as I have no expirience with the array method.

task shrinkingbullet(x,y,v,dir,graphic,delay,scale){
   let shot = Obj_Createshotect(OBJ_EFFECT);

   Obj_SetPosition(shot,x,y);
   Obj_SetSpeed(shot,v);
   ...
   etc etc... (

   <I forgot the code for the scale (please look it up on wiki, which is the starting scale.>


   while(!Obj_BeDeleted){

      < Here the code for shrinking the bullet over time >

        }

}


Now somewhere in your MainLoop you simply call: shrinkingbullet(......); and fill the parameters like where you want it to spawn, speed, dir etc etc.

And that's it.

Putting that in my script gave both me and Danmakufu nightmares (There's something that I just can't learn about tasks. And that's getting them to work D:)
But I found my own way around it. Of course without tasks, as usual for me. (That makes us task/array rivals, bwahahah) :P

Code: [Select]
if(frame%10==0 && frame>60){
let i=0;
shot=(Obj_Create(OBJ_EFFECT));
Obj_SetCollisionToPlayer(shot,true);
Obj_SetPosition(shot,cx+rand(-150,150),rand(0,30));
ObjEffect_SetLayer(shot,4); Obj_SetAngle(shot,90);
Obj_SetSpeed(shot,3);
ObjEffect_SetTexture(shot,GRbullet);
ObjEffect_SetPrimitiveType(shot,PRIMITIVE_TRIANGLESTRIP);
ObjEffect_CreateVertex(shot,4);
ObjEffect_SetScale(shot,1,1);
ObjEffect_SetVertexXY(shot,0,-128,-128); ObjEffect_SetVertexUV(shot,0,0,0);
ObjEffect_SetVertexXY(shot,1,128,-128); ObjEffect_SetVertexUV(shot,1,256,0);
ObjEffect_SetVertexXY(shot,2,-128,128); ObjEffect_SetVertexUV(shot,2,0,256);
ObjEffect_SetVertexXY(shot,3,128,128); ObjEffect_SetVertexUV(shot,3,256,256);
ObjEffect_SetVertexColor(shot,0,200,255,255,255); ObjEffect_SetVertexColor(shot,1,200,255,255,255);
ObjEffect_SetVertexColor(shot,2,200,255,255,255); ObjEffect_SetVertexColor(shot,3,200,255,255,255);
hitbox=hitbox~[shot];
}
if(frame>50){
let i=0;
shrink=shrink~[shot];
while (i<length(hitbox)){
if(Obj_BeDeleted(hitbox[i])){
hitbox=erase(hitbox,i);
i--;
}
else{
ObjEffect_SetAngle(hitbox[i],0,0,time*5);
shrink[i]=1-(Obj_GetY(hitbox[i])/500);
SetCollisionB(Obj_GetX(hitbox[i]),Obj_GetY(hitbox[i]),shrink[i]*70);
ObjEffect_SetScale(hitbox[i],shrink[i],shrink[i]);
}
i++;
}

}

Bullets shrink as they move down (cough Utsuho 2 cough). But it depends on their Y, and not on the time spent on the field. It's probably just a minor change, but I can't think of a way to give each their own timer.


Sorry, I just really hate Danmakufu's tasks that much.

<3
Full Danmakufu game "Juuni Jumon - Summer Interlude" is done!
By the same person who made Koishi Hell 1,2 (except this game is serious)
Topic: http://www.shrinemaiden.org/forum/index.php/topic,9647.0.html

Aphid

Re: Danmakufu Q&A/Problem Thread
« Reply #861 on: October 08, 2009, 09:19:04 PM »
Aphid, post your main file as well, I'm having trouble getting it to even run. It errors on f (so I then declared f = 0;), then on ArrayShotRed (so I declared let ArrayShotRed = []; ), then on ObjShot_Delete(objr) (so I changed it to Obj_Delete(objr); ).

Well now it runs.... But nothing happens. Yes, I have f++; and AimedRedShot(f) in @MainLoop.

So yeah, post the code, please. Or PM it if you'd rather.
I'm not very surprised you didn't get it to work with just f++. f, in my code, is a long-running counter from a couple previous code sections. It's actually at like 6000 or so when the script starts so you'd be expected to see nothing for two minutes, yes. If I ever wanted an overarching theme linked to f it would be easier to implement that way. Oh and it's reducing the amount of math I have to do when calculating frames for each note's time. (the thing's linked to music  ;))

Right, if you want to make the whole thing as it is here on my pc... errhm... well you'd need a couple more files. 'neways, you'll need to call the code about the circle CIRCS.txt, the last bit from the previous post was BLUERED.txt. Oh, and you'll also need "HorizontalFamiliarCircle.txt".
I've tried to comment out all the references to extra files and/or delete those lines but there could be a couple left.

Before you try running it, make sure you do have math.h on your system's main C compiler (some extra math functions):

incoming walls of code.

Code: [Select]

/*Danmakufu Pattern No.1. Remi @ Beethoven's 8th Sonata (The "Grande Sonate Path鑼ique").*/
/*1st Movement. (first movement)*/

#TouhouDanmakufu
#include<math.h>   
#Title[Allegro Repeated]
#Text[First Movement, first fast part]
/*#Image[.\remi1.jpg]*/
/*#BackGround[User(.\bg.png, 1, 1)]*/
#PlayLevel[Phantasm]
#Player[FREE]
#ScriptVersion[2]

script_enemy_main {

#include_function "lib\SHOT_REPLACE\shot_replace.dnh";
#include_script ".\CIRCS.txt";
   
    /*let BI=GetCurrentScriptDirectory~"BIM1.jpg";
    let BCI=GetCurrentScriptDirectory~"Remi3.jpg";*/
    let f=5400;
    let g=0;
    let ang=0;
    let z=0;
    let h=0;
    let lz=0;
    let W = "STRING";
    let Q = "zero";
    let Z = "zero";
    let hg = 0;
let ArrayShotRed = [];
let ArrayShotRedTwo = [];

function GetDistance(x1, y1, x2, y2)
{
    return ((x1-x2)^2 + (y1-y2)^2)^0.5
}
function ScarletShoot(SCAX, SCAY, SCAV, SCAA, DELAY)
{
CreateShot01(SCAX, SCAY, SCAV, SCAA, RED03, DELAY);
ascent(i in 0..3) {
CreateShot02(SCAX, SCAY, SCAV - 0.1 - 0.1 * i, SCAA + rand(-15, 15), - 0.003 * i, 0.2, RED02, DELAY);
}
ascent(j in 0..24) {
CreateShot02(SCAX, SCAY, SCAV - 0.25 - 0.025 * j, SCAA + rand(-25, 25), -0.0005 * j, 0.2, RED04, DELAY);
}

}


@Initialize {

// LoadUserShotData(GetCurrentScriptDirectory~"udb2.txt");
// LoadGraphic(BI);
SetLife(1000000);
        SetDamageRate(100,0);
        SetTimer(123);
        SetInvincibility(60);
// CutIn(YOUMU, "Scarlet Sign "\""Allegro"\", BCI, 0, 0, 420, 400);
      SetScore(4320000);
        SetEnemyMarker(true);
        SetDurableSpellCard;
SetY(40);
shotinit;
}

@MainLoop {
SetCollisionA(GetX, GetY, 42);
        SetCollisionB(GetX, GetY, 42);
if(f == 5400) {

SetMovePosition02(GetCenterX, 40, 20);
ascent(q in 0..3) {
ascent(h in 1..4) {
CreateLaserB(1, 500, 20, RED01, 45);
SetLaserDataB(1, 0, 0, 0, 0, 45 * q + 15 * h, 0, 45 * q + 15 * h, 0);
SetShotKillTime(1, 120);
FireShot(1);
}
}
}
if(f == 12000) {
hg = 20; }

if(f == 5460){
HCircleFamiliar(1, BLUE03, f, 1, 0, 960);
HCircleFamiliar(1, BLUE03, f, -1,0, 960);
HCircleFamiliar(1, RED03, f, 1,90, 960);
HCircleFamiliar(1, RED03, f, -1,90, 960);
}
if(f == 6900){
HCircleFamiliar(1, BLUE03, f, 1, 0, 840);
HCircleFamiliar(1, BLUE03, f, -1,0,  840);
HCircleFamiliar(1, RED03, f, 1,90, 840);
HCircleFamiliar(1, RED03, f, -1,90, 840);
}


if (((f > 5459 && f < 6421) || (f > 6899 && f < 7741)) && round(f / 15) - f / 15 == 0)
{

ascent(q in 0..3) {
ascent(h in 0..3) {
let i = 0;
CreateShot01(GetX + 180 * sin(f / 3), GetY, 4, 58 + 24 * h + 8 * q, BLUE11, 0);
CreateShot01(GetX - 180 * sin(f / 3), GetY, 4, 58 + 24 * h + 8 * q, BLUE11, 0);
CreateShot01(GetX + 180 * sin(f / 3 + 2.5), GetY, 4, 58 + 24 * h + 8 * q, BLUE11, 7.5);
CreateShot01(GetX - 180 * sin(f / 3 + 2.5), GetY, 4, 58 + 24 * h + 8 * q, BLUE11, 7.5);
CreateShotA(1, GetX + 180 * cos(f / 3), GetY, 0);
if(q == 2) {
i = 0;
}
else {
i = 1;
}

SetShotDataA(1, 0, 3, 90, 0, 0, 3, RED02);
SetShotDataA(1, 60, 3, 70 + 20 * h, (-1)^q * 1.6 * i, 0, 10, RED01);
SetShotDataA(1, 90, NULL, NULL, 0, 0, 10, RED01);
FireShot(1);
CreateShotA(1, GetX - 180 * cos(f / 3), GetY, 0);
SetShotDataA(1, 0, 3, 90, 0, 0, 3, RED02);
SetShotDataA(1, 60, 3, 70 + 20 * h, (-1)^q * 1.6 * i, 0, 10, RED01);
SetShotDataA(1, 90, NULL, NULL, 0, 0, 10, RED01);
FireShot(1);
}
}
}
if(f == 5505 || f == 5985) {
ascent(i in 1..34) {
CreateShot02(GetX, GetY, 8, GetAngleToPlayer + 10 + 10 * i, -0.02, 4, RED02, 0);
}
}
if(f == 5520 || f == 6000) {

ascent(i in 1..34) {
CreateShot02(GetX, GetY, 8, GetAngleToPlayer + 10 + 10 * i, -0.02, 4, ORANGE02, 0);
}
}
if(f == 5535 || f == 5625 || f == 6015 || f == 6105) {

ascent(i in 1..34) {
CreateShot02(GetX, GetY, 8, GetAngleToPlayer + 10 + 10 * i, -0.02, 4, YELLOW02, 0);
}
}
if(f == 5550 || f == 5640 || f == 6030 || f == 6120) {

ascent(i in 1..34) {
CreateShot02(GetX, GetY, 8, GetAngleToPlayer + 10 + 10 * i, -0.02, 4, GREEN02, 0);
}
}
if(f == 5565 || f == 5655 || f == 6045 || f == 6135) {

ascent(i in 1..34) {
CreateShot02(GetX, GetY, 8, GetAngleToPlayer + 10 + 10 * i, -0.02, 4, AQUA02, 0);
}
}
if(f == 5580 || f == 5670 || f == 6060 || f == 6150) {

ascent(i in 1..34) {
CreateShot02(GetX, GetY, 8, GetAngleToPlayer + 10 + 10 * i, -0.02, 4, BLUE02, 0);
}
}
if(f == 5595 || f == 5685 || f == 6075 || f == 6165) {

ascent(i in 1..34) {
CreateShot02(GetX, GetY, 8, GetAngleToPlayer + 10 + 10 * i, -0.02, 4, PURPLE02, 0);
}
}

if(f == 5700 || f == 5760 || f == 5820 || f == 5880 || f == 6180 || f == 6240 || f == 6300 || f == 6360 || f == 6420) {
ascent(l in 0..5) {
ascent(k in 0..3) {
ascent(i in 0..8) {
CreateShotA(1, GetX, GetY, 0);
SetShotDataA(1, 2 * i, 4, GetAngleToPlayer - (30 + 15 * l), 2 + l, 0, 10, YELLOW11);
ascent(j in 0..10) {
SetShotDataA(1, 30 * j + 30 + 2 * i, 4, NULL, (2 + l) * (-1) ^ (j + 1), 0, 10, YELLOW11);
}
FireShot(1);
CreateShotA(1, GetX, GetY, 0);
SetShotDataA(1, 2 * i, 4, GetAngleToPlayer + (30 + 15 * l), -2 - l, 0, 10, YELLOW11);
ascent(j in 0..10) {
SetShotDataA(1, 30 * j + 30 + 2 * i, 4, NULL, (2 + l) * (-1) ^ (j), 0, 10, YELLOW11);
}
FireShot(1);
}

}
}
}

if(f == 5730 || f == 5790 || f == 5850 || f == 5910 || f == 6210 || f == 6270 || f == 6330 || f == 6420) {
ascent(m in 0..2){
ascent(l in 0..5) {
ascent(k in 0..3) {
ascent(i in 0..8) {
CreateShotA(1, GetX, GetY, 0);
SetShotDataA(1, 2 * i, 4, GetAngleToPlayer - 30 * (-1) ^ m - (30 + 15 * l), 2 + l, 0, 10, YELLOW11);
ascent(j in 0..10) {
SetShotDataA(1, 30 * j + 30 + 2 * i, 4, NULL, (2 + l) * (-1) ^ (j + 1), 0, 10, YELLOW11);
}
FireShot(1);
CreateShotA(1, GetX, GetY, 0);
SetShotDataA(1, 2 * i, 4, GetAngleToPlayer  - 30 * (-1) ^ m + (30 + 15 * l), -2 - l, 0, 10, YELLOW11);
ascent(j in 0..10) {
SetShotDataA(1, 30 * j + 30 + 2 * i, 4, NULL, (2 + l) * (-1) ^ (j), 0, 10, YELLOW11);
}
FireShot(1);
}

}
}
}
}
if (f == 6420 || f == 6435 || f == 6450 || f == 6465
||  f == 6660 || f == 6675 || f == 6690 || f == 6705)
{
ascent(i in 0..3) {
CreateShotA(62, GetX, GetY, 0);
SetShotDataA(62, 0, 2, 65 + 25 * i, 0, 0, 5, RED02);
ascent(k in 0..2) {
ascent(l in 0..12) {
ascent(m in 0..3) {
CreateShotA(63, 0, 0, 0);
SetShotDataA(63, 0, 1.5 + 0.5 * m, l * 30 + 65 + 25 * i + f * 0.5, 2 * -1 ^ k, 0.01, 5, RED12);
SetShotDataA(63, 15, NULL, NULL, 0, 0.01, 5, RED12);
SetShotKillTime(63, 360);
AddShot(60, 62, 63, 0);
}
}
}
FireShot(62);
}
}
if(f == 6780 || f == 6540) {
ascent(i in 0..4) {
CreateShot01(GetX, GetY, 3, 90 * i, RED03, 0);
}
}
if(f == 6390 || f == 6630) {
ascent(i in 0..6) {
ascent(j in 0..6) {
CreateLaserA(65, 210 + 180 * cos(60 * i), 240 + 180 * sin(60 * i), 400, 15, YELLOW01, 60);
SetLaserDataA(65, 0, 60 * j, 0, 0, 0, 0);
SetShotKillTime(65, 120);
ascent(k in 0..6) {
CreateShotA(66, 0, 0, 0);
SetShotDataA(66, 0, 1.5, 60 * j + 10 * k, 0.5, 0.02, 6, AQUA04);
AddShot(90, 65, 66, 0);
}
FireShot(65);
}
}
}


if(f == 6450 || f == 6690) {
ascent(i in 0..6) {
ascent(j in 0..6) {
CreateLaserA(65, 210 + 180 * cos(60 * i + 30), 240 + 180 * sin(60 * i + 30), 400, 15, YELLOW01, 60);
SetLaserDataA(65, 0, 60 * j + 30, 0, 0, 0, 0);
SetShotKillTime(65, 120);
ascent(k in 0..6) {
CreateShotA(66, 0, 0, 0);
SetShotDataA(66, 0, 1.5, 60 * j + 10 * k + 30, -0.5, 0.02, 6, AQUA04);
AddShot(90, 65, 66, 0);
}
FireShot(65);
}
}
}
if(f == 6540 || f == 6780) {
ascent(n in 0..2) {
ascent(i in 0..7) {
CreateShot01(GetX, GetY, 2 + n, 51 * i, RED02, 0);
CreateShot01(GetX, GetY, 2 + n, 51 * i, RED02, 0);
ascent(j in 0..10) {
CreateShotA(67, GetX, GetY, 7.5 * i);
SetShotDataA(67, 0, 1.2, 36 * j + 0.5 * i ^ 2, -1 ^ n, 0.02, 2, RED12);
SetShotDataA(67, 15 + i * 15, 2, NULL, 0, 0.05, 5, RED12);
ascent(l in 0..16) {
CreateShotA(68, 0, 0, 0);
SetShotDataA(68, 0, 2 + 0.1 * j, j * 5 + i * 30 + n * 180, 0, 0, 6, RED05);
AddShot(7.5 * l, 67, 68, 0);
}
FireShot(67);
}
}
}
}
ascent(j in 0..9) {
if(f == 6900 + 15 * j)
{
ascent(i in 0..40) {
ascent(j in 0..2) {
CreateShotA(70, GetX, GetY, 0);
SetShotDataA(70, 0, 3.5, 9 * i + GetAngleToPlayer, j, 0, 5, RED23);
SetShotDataA(70, 15, NULL, NULL, 0, 0, 5, RED23);
FireShot(70)
}
CreateShot01(GetX, GetY, 3.5,  9 * i + GetAngleToPlayer, RED32, 0);
}
}

if (f == 7140 + 15 * j)
{
ascent(i in 0..40) {
ascent(j in 0..2) {
CreateShotA(70, GetX, GetY, 0);
SetShotDataA(70, 0, 3.5, 9 * i + GetAngleToPlayer, j, 0, 5, RED23);
SetShotDataA(70, 15, NULL, NULL, 0, 0, 5, RED23);
FireShot(70)
}
CreateShot01(GetX, GetY, 3.5,  9 * i + GetAngleToPlayer, RED32, 0);
}
}

if (f == 7380 + 15 * j)
{
ascent(i in 0..40) {
ascent(j in 0..2) {
CreateShotA(70, GetX, GetY, 0);
SetShotDataA(70, 0, 3.5, 9 * i + GetAngleToPlayer, j, 0, 5, RED23);
SetShotDataA(70, 15, NULL, NULL, 0, 0, 5, RED23);
FireShot(70)
}
CreateShot01(GetX, GetY, 3.5,  9 * i + GetAngleToPlayer, RED32, 0);
}
}
}

if(f == 7530) {
ascent(i in 0..5) {
ascent(j in 0..4) {
ascent(k in 0..5) {
CreateShotA(7, GetX, GetY, 0);
SetShotDataA(7, 0, 1, 45 * i - 22.5, 0, 0, 10, BLUE03);
SetShotDataA(7, 30,  2 + j, NULL, sin(f) + 0.3 * (k - 3), 0, 10, PURPLE03);
SetShotDataA(7, 60, NULL, NULL, 0, 0.05, 10, BLUE03);
FireShot(7);
}
}
}
}

if(f == 7590) {

ascent(i in 0..5) {
ascent(j in 0..4) {
ascent(k in 0..5) {
CreateShotA(7, GetX, GetY, 0);
SetShotDataA(7, 0, 1, 45 * i - 22.5, 0, 0, 10, WHITE03);
SetShotDataA(7, 30,  2 + j, NULL, sin(f) + 0.3 * (k - 3), 0, 10, AQUA03);
SetShotDataA(7, 60, NULL, NULL, 0, 0.05, 10, WHITE03);
FireShot(7);
}
}
}
}
if(f == 7650)
{
ascent(i in 0..5) {
ascent(j in 0..4) {
ascent(k in 0..5) {
CreateShotA(7, GetX, GetY, 0);
SetShotDataA(7, 0, 1, 45 * i - 22.5, 0, 0, 10, YELLOW03);
SetShotDataA(7, 30,  2 + j, NULL, sin(f) + 0.3 * (k - 3), 0, 10, GREEN03);
SetShotDataA(7, 60, NULL, NULL, 0, 0.05, 10, YELLOW03);
FireShot(7);
}
}
}
}
if(f == 7710) {
ascent(i in 0..5) {
ascent(j in 0..4) {
ascent(k in 0..5) {
CreateShotA(7, GetX, GetY, 0);
SetShotDataA(7, 0, 1, 45 * i - 22.5, 0, 0, 10, RED03);
SetShotDataA(7, 30,  2 + j, NULL, sin(f) + 0.3 * (k - 3), 0, 10, ORANGE03);
SetShotDataA(7, 60, NULL, NULL, 0, 0.05, 10, RED03);
FireShot(7);
}
}
}
}

if(7800 < f) {
if(f < 10000) {
RedAimingShots(f);
}}


if(f == 9330 || f == 9570 || f == 9870)
{
ascent(i in 0..2) {
ascent(k in 0..2) {
ascent(j in 0..32) {
CreateShotA(9, 10, 10, 0);
SetShotDataA(9, 0, 2 + 0.1 * j, 20 * j, 0.2 * (-1 ^ k), 0.02 * (-1 ^ i), 3, RED04);
SetShotDataA(9, 60, 3, NULL, 0, 0, 3, RED04);
CreateShotA(10, 10, 410, 0);
SetShotDataA(10, 0, 2 + 0.1 * j, 20 * j, 0.2 * (-1 ^ k), 0.02 * (-1 ^ i), 3, RED04);
SetShotDataA(10, 60, 3, NULL, 0, 0, 3, RED04);
CreateShotA(11, 450, 410, 0);
SetShotDataA(11, 0, 2 + 0.1 * j, 20 * j, 0.2 * (-1 ^ k), 0.02 * (-1 ^ i), 3, RED04);
SetShotDataA(11, 60, 3, NULL, 0, 0, 3, RED04);
CreateShotA(12, 450, 10, 0);
SetShotDataA(12, 0, 2 + 0.1 * j, 20 * j, 0.2 * (-1 ^ k), 0.02 * (-1 ^ i), 3, RED04);
SetShotDataA(12, 60, 3, NULL, 0, 0, 3, RED04);
FireShot(9);
FireShot(10);
FireShot(11);
FireShot(12); }
}
}
}
if(f == 8220 || f == 8700 || f == 9180 || f == 9420 || f == 9660 || f == 9780 || f == 9900 || f == 10020)
{
CreateShot01(GetX, GetY, 3, 0, RED02, 0);
CreateShot01(GetX, GetY, 3, 0, RED02, 7.5);
CreateShot01(GetX, GetY, 3, 0, RED02, 15);
CreateShot01(GetX, GetY, 3, 180, RED02, 0);
CreateShot01(GetX, GetY, 3, 180, RED02, 7.5);
CreateShot01(GetX, GetY, 3, 180, RED02, 15);
}
if(f == 8250 || f == 8730 || f == 9210 || f == 9450 || f == 9690 || f == 9810 || f == 9930 || f == 10080)
{
CreateShot01(GetX, GetY, 3, 0, RED02, 0);
CreateShot01(GetX, GetY, 3, 0, RED02, 7.5);
CreateShot01(GetX, GetY, 3, 0, RED02, 15);
CreateShot01(GetX, GetY, 3, 180, RED02, 0);
CreateShot01(GetX, GetY, 3, 180, RED02, 7.5);
CreateShot01(GetX, GetY, 3, 180, RED02, 15);
}
if(f == 8280 || f == 8760 || f == 9240 || f == 9480 || f == 9720 || f == 9840 || f == 9960)
{

CreateShot01(GetX, GetY, 3, 0, RED02, 0);
CreateShot01(GetX, GetY, 3, 0, RED02, 7.5);
CreateShot01(GetX, GetY, 3, 0, RED02, 15);
CreateShot01(GetX, GetY, 3, 180, RED02, 0);
CreateShot01(GetX, GetY, 3, 180, RED02, 7.5);
CreateShot01(GetX, GetY, 3, 180, RED02, 15);
}
if(f == 9990) {
CreateShot01(GetX, GetY, 3, 0, RED02, 0);
CreateShot01(GetX, GetY, 3, 0, RED02, 7.5);
CreateShot01(GetX, GetY, 3, 0, RED02, 15);
CreateShot01(GetX, GetY, 3, 180, RED02, 0);
CreateShot01(GetX, GetY, 3, 180, RED02, 7.5);
CreateShot01(GetX, GetY, 3, 180, RED02, 15);
}
ascent(k in 0..3) {
if(f == 8310 + 15 * k|| f == 8790 + 15 * k || f == 9270 + 15 * k || f == 9510 + 15 * k || f == 9750 + 15 * k || f == 9870 + 15 * k || f == 10050 + k || f == 10110 + k)
{
CreateShot01(GetX, GetY, 3, 0, RED02, 0);
CreateShot01(GetX, GetY, 3, 0, RED02, 15);
CreateShot01(GetX, GetY, 3, 180, RED02, 0);
CreateShot01(GetX, GetY, 3, 180, RED02, 15);
}
}
if(f == 10140 || f == 10860) {
CreateShotA(11, 110, 130, 0);
SetShotDataA(11, 0, -3.887522571, 135, 1.5, 0, 20, RED03);
SetShotKillTime(11, 120);

CreateShotA(12, 110, 340, 0);
SetShotDataA(12, 0, -3.887522571, 45, 1.5, 0, 20, RED03);
SetShotKillTime(12, 120);

CreateShotA(13, 320, 340, 0);
SetShotDataA(13, 0, -3.887522571, -45, 1.5, 0, 20, RED03);
SetShotKillTime(13, 120);

CreateShotA(14, 320, 130, 0);
SetShotDataA(14, 0, -3.887522571, -135, 1.5, 0, 20, RED03);
SetShotKillTime(14, 120);

ascent(i in 0..4) {
ascent(j in 0..16) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (7.5 * j), 1.5 * (k - 2), 0, 20, GREEN21);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, GREEN21);
AddShot(7.5 * j, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (7.5 * j), 3, 0, 20, GREEN21);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, GREEN21);
AddShot(7.5 * j, 11 + i, 15, 0);
}

}
}
}

ascent(i in 0..4) {
ascent(j in 0..32) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (7.5 * j + 3.75), 1.5 * (k - 2), 0, 20, RED21);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, RED21);
AddShot(3.75 + 7.5 * j, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (7.5 * j + 3.75), 3, 0, 20, RED21);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, RED21);
AddShot(3.75 + 7.5 * j, 11 + i, 15, 0);
}

}
}
}
FireShot(11);
FireShot(12);
FireShot(13);
FireShot(14);
}
if(f == 10260 || f == 10980) {
CreateShotA(11, 110, 130, 0);
SetShotDataA(11, 0, -3.887522571, -45, -1.5, 0, 20, BLUE03);
SetShotKillTime(11, 120);

CreateShotA(12, 110, 340, 0);
SetShotDataA(12, 0, -3.887522571, -135, -1.5, 0, 20, BLUE03);
SetShotKillTime(12, 120);

CreateShotA(13, 320, 340, 0);
SetShotDataA(13, 0, -3.887522571, 135, -1.5, 0, 20, BLUE03);
SetShotKillTime(13, 120);

CreateShotA(14, 320, 130, 0);
SetShotDataA(14, 0, -3.887522571, 45, -1.5, 0, 20, BLUE03);
SetShotKillTime(14, 120);

ascent(i in 0..4) {
ascent(j in 0..16) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, -45 + 90 * i - 1.5 * (7.5 * j), 1.5 * (k - 2), 0, 20, YELLOW21);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, YELLOW21);
AddShot(7.5 * j, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, -45 + 90 * i - 1.5 * (7.5 * j), 3, 0, 20, YELLOW21);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, YELLOW21);
AddShot(7.5 * j, 11 + i, 15, 0);
}
}
}
}

ascent(i in 0..4) {
ascent(j in 0..32) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, -45 + 90 * i - 1.5 * (7.5 * j + 3.75), 1.5 * (k - 2), 0, 20, BLUE21);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, BLUE21);
AddShot(3.75 + 7.5 * j, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, -45 + 90 * i - 1.5 * (7.5 * j + 3.75), 3, 0, 20, BLUE21);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, BLUE21);
AddShot(3.75 + 7.5 * j, 11 + i, 15, 0);
}
}
}
}
FireShot(11);
FireShot(12);
FireShot(13);
FireShot(14);
}
if(f == 10380 || f == 11100)
{
CreateShotA(11, 110, 130, 0);
SetShotDataA(11, 0, -3.887522571, 135, 1.5, 0, 20, RED03);
SetShotKillTime(11, 360);

CreateShotA(12, 110, 340, 0);
SetShotDataA(12, 0, -3.887522571, 45, 1.5, 0, 20, RED03);
SetShotKillTime(12, 360);

CreateShotA(13, 320, 340, 0);
SetShotDataA(13, 0, -3.887522571, -45, 1.5, 0, 20, RED03);
SetShotKillTime(13, 360);

CreateShotA(14, 320, 130, 0);
SetShotDataA(14, 0, -3.887522571, -135, 1.5, 0, 20, RED03);
SetShotKillTime(14, 360);

ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, RED21);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, RED21);
AddShot(3.75 * j, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (3.75 * j), -3, 0, 20, RED21);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, RED21);
AddShot(3.75 * j, 11 + i, 15, 0);
}

}
}
}
ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 + 90 * i + 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, ORANGE21);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, ORANGE21);
AddShot(3.75 * j + 30, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 + 90 * i + 1.5 * (3.75 * j), -3, 0, 20, ORANGE21);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, ORANGE21);
AddShot(3.75 * j + 30, 11 + i, 15, 0);
}

}
}
}
ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, YELLOW21);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, YELLOW21);
AddShot(3.75 * j + 60, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (3.75 * j), -3, 0, 20, YELLOW21);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, YELLOW21);
AddShot(3.75 * j + 60, 11 + i, 15, 0);
}

}
}
}
ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 + 90 * i + 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, GREEN21);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, YELLOW21);
AddShot(3.75 * j + 90, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 + 90 * i + 1.5 * (3.75 * j), -3, 0, 20, GREEN21);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, YELLOW21);
AddShot(3.75 * j + 90, 11 + i, 15, 0);
}

}
}
}
ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, BLUE21);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, BLUE21);
AddShot(3.75 * j + 120, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (3.75 * j), -3, 0, 20, BLUE21);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, BLUE21);
AddShot(3.75 * j + 120, 11 + i, 15, 0);
}

}
}
}
ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 + 90 * i + 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, PURPLE21);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, PURPLE21);
AddShot(3.75 * j + 150, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 + 90 * i + 1.5 * (3.75 * j), -3, 0, 20, PURPLE21);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, PURPLE21);
AddShot(3.75 * j + 150, 11 + i, 15, 0);
}

}
}
}

ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, RED01);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, RED01);
AddShot(3.75 * j + 180, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (3.75 * j), -3, 0, 20, RED01);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, RED01);
AddShot(3.75 * j + 180, 11 + i, 15, 0);
}

}
}
}
ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 + 90 * i + 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, ORANGE01);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, ORANGE01);
AddShot(3.75 * j + 210, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 + 90 * i + 1.5 * (3.75 * j), -3, 0, 20, ORANGE01);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, ORANGE01);
AddShot(3.75 * j + 210, 11 + i, 15, 0);
}

}
}
}
ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, YELLOW01);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, YELLOW01);
AddShot(3.75 * j + 240, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (3.75 * j), -3, 0, 20, YELLOW01);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, YELLOW01);
AddShot(3.75 * j + 240, 11 + i, 15, 0);
}

}
}
}
ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 + 90 * i + 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, GREEN01);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, YELLOW01);
AddShot(3.75 * j + 270, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 + 90 * i + 1.5 * (3.75 * j), -3, 0, 20, GREEN01);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, YELLOW01);
AddShot(3.75 * j + 270, 11 + i, 15, 0);
}

}
}
}
ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, BLUE01);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, BLUE01);
AddShot(3.75 * j + 300, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 135 + 90 * i + 1.5 * (3.75 * j), -3, 0, 20, BLUE01);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, BLUE01);
AddShot(3.75 * j + 300, 11 + i, 15, 0);
}

}
}
}
ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 + 90 * i + 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, PURPLE01);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, PURPLE01);
AddShot(3.75 * j + 330, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 + 90 * i + 1.5 * (3.75 * j), -3, 0, 20, PURPLE01);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, PURPLE01);
AddShot(3.75 * j + 330, 11 + i, 15, 0);
}

}
}
}
FireShot(11);
FireShot(12);
FireShot(13);
FireShot(14);
}
if(f == 10740 || f == 11460) {
CreateShotA(11, 110, 130, 0);
SetShotDataA(11, 0, -3.887522571, -45, -1.5, 0, 20, BLUE03);
SetShotKillTime(11, 120);

CreateShotA(12, 110, 340, 0);
SetShotDataA(12, 0, -3.887522571, -135, -1.5, 0, 20, BLUE03);
SetShotKillTime(12, 120);

CreateShotA(13, 320, 340, 0);
SetShotDataA(13, 0, -3.887522571, 135, -1.5, 0, 20, BLUE03);
SetShotKillTime(13, 120);

CreateShotA(14, 320, 130, 0);
SetShotDataA(14, 0, -3.887522571, 45, -1.5, 0, 20, BLUE03);
SetShotKillTime(14, 120);

ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, -45 + 90 * i - 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, BLUE01);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, BLUE01);
AddShot(3.75 * j, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, -45 + 90 * i - 1.5 * (3.75 * j), 3, 0, 20, BLUE01);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, BLUE01);
AddShot(3.75 * j, 11 + i, 15, 0);
}

}
}
}

ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 * i - 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, GREEN01);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, GREEN01);
AddShot(3.75 * j, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 * i - 1.5 * (3.75 * j), 3, 0, 20, GREEN01);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, GREEN01);
AddShot(3.75 * j, 11 + i, 15, 0);
}

}
}
}


ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, -45 + 90 * i - 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, YELLOW01);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, YELLOW01);
AddShot(3.75 * j, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, -45 + 90 * i - 1.5 * (3.75 * j), 3, 0, 20, YELLOW01);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, YELLOW01);
AddShot(3.75 * j, 11 + i, 15, 0);
}

}
}
}


ascent(i in 0..4) {
ascent(j in 0..9) {
ascent(k in 0..6) {
if(k < 4) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 * i - 1.5 * (3.75 * j), 1.5 * (k - 2), 0, 20, ORANGE01);
SetShotDataA(15, 60, NULL, NULL, 0, 0, 20, ORANGE01);
AddShot(3.75 * j + 90, 11 + i, 15, 0);
}
if(k > 3) {
CreateShotA(15, 0, 0, 0);
SetShotDataA(15, 0, 3.887522571, 90 * i - 1.5 * (3.75 * j), 3, 0, 20, ORANGE01);
SetShotDataA(15, 60 * k - 180, NULL, NULL, 0, 0, 20, ORANGE01);
AddShot(3.75 * j + 90, 11 + i, 15, 0);
}

}
}
FireShot(11);
FireShot(12);
FireShot(13);
FireShot(14);
}
}

ascent(i in 0..48) {
if(f == 10140 + i * 30) {
ascent(k in 0..32) {
if(f == 10260 || f == 10290 || f == 10320 || f == 10350 || f == 10740 || f == 10770 || f == 10800 || f == 10830
|| f == 10980 || f == 11010 || f == 11040 || f == 11070 || f == 11460 || f == 11490 || f == 11520 || f == 11550)
{
Z = "BLUE12"
}
else
{
Z = "RED12"
}

CreateShotA(16, GetX, GetY, 0);
SetShotDataA(16, 0, 1.94, 10 * k + GetAngleToPlayer, -0.8, 0.01, 10, Z);
FireShot(16);
CreateShotA(17, GetX, GetY, 0);
SetShotDataA(17, 0, 1.94, 10 * k + GetAngleToPlayer, 0.8, 0.01, 10, Z);
FireShot(17);
}
}
}

ascent (i in 0..8) {
if(f == 11520 + 60 * i) {
SetMovePosition02(GetPlayerX, GetPlayerY, 60);
ascent(k in 0..30) {
CreateShot02(GetX, GetY, 0.4, 12 * k, 0.01, 3, RED01, 60);
}
}
}

if(f == 11490 || f == 11730) {
SetCircleLocationA(1, GetX, GetY, 1, 255, 30);
MoveCircleA01(1, GetCenterX, GetCenterY, 30, 30);
}
if(f == 11700 || f == 11940) {
FadeCircleA(1, 120);
}
if(f == 11460 || f == 11700){
ascent(i in 0..8) {
ascent(j in 0..8) {
CreateLaserC(21, GetCenterX, GetCenterY, 8, 30, RED04, 0);
SetLaserDataC(21, 0, 6, 45 + 45 * i, 0, 0, 25);
SetLaserDataC(21, 6 * j + 6, 3 * 3.1415 * (2 * j + 2) / 30, 135 + 45 * i, 1, 0, 25);
SetShotKillTime(21, 120);
FireShot(21);
} }
}

if(f == 11580 || f == 11820) {
ascent(i in 0..8) {
CreateShotA(18, GetCenterX, GetCenterY, 0);
SetShotDataA(18, 0, 18, 45 + 45 * i, 0, 0, 18, RED03);
SetShotDataA(18, 15, 10, -90 + 45 * i, 0, 0, 18, RED03);
ascent(j in 0..10) {
CreateShotA(19, 0, 0, 0);
SetShotDataA(19, 0, 9 * 3.1415 * (2 * j + 2) / 30, 135 + 45 * i, 3, 0, 25, RED04);
SetShotDataA(19, 15, NULL, NULL, 0, 0, 25, RED04);
ascent(k in 0..30) {
CreateShotA(20, 0, 0, 0);
SetShotDataA(20, 0, 0, -135 + 45 * i + 1.5 * k, 0, 0, 10, RED01);
SetShotDataA(20, 7.5 * k, NULL, NULL, 0.02 * (-1 ^ j), 0.02, 20, PURPLE01);
SetShotKillTime(20, 7.5 * k + 30 * 2 ^ 0.5 * (j + 2)^0.5);
AddShot(0.5 * k, 19, 20, 0); }
AddShot(2 * j + 2, 18, 19, 0);

}
FireShot(18);

}
}
if(f == 11980) {
SetMovePosition02(GetCenterX, 40, 20);
}
if(f == 12060) {
ScarletShoot(GetX, GetY, 3, GetAngleToPlayer, 0);
SetCircleLocationA(1, GetX, GetY, 1, 255, 30);
SetCircleLocationA(2, GetX, GetY, 1, 255, 30);
}
if(f == 12180) {
ScarletShoot(GetX, GetY, 3, GetAngleToPlayer, 0);
}
ascent(i in 0..10) {
if(f == 12060 + 180 * i) {
MoveCircleA01(1, GetCenterX - 140, 200 + 150 * -1 ^ i, 30, 0);
MoveCircleA01(2, GetCenterX + 140, 200 + 150 * -1 ^ i, 30, 0);
}
}
if(f == 12075 || f == 12195) {
ScarletShoot(GetX, GetY, 3, GetAngleToPlayer + 30, 0);
ScarletShoot(GetX, GetY, 3, GetAngleToPlayer - 30, 0);
}

ascent(j in 0..5) {
if(f == 12105 + 15 * j || f == 12225 + 15 * j)
{
ScarletShoot(GetX, GetY, 3, 2 * f + 30, 0);
ScarletShoot(GetX, GetY, 3, 2 * f - 30, 0);

}
}
ascent(j in 0..4) {
if(f == 12300 + 120 * j) {

if(j ==0 || j == 2) {
ScarletShoot(GetX, GetY, 3, 90, 0);
ScarletShoot(GetX, GetY, 3.2, 75, 0);
ScarletShoot(GetX, GetY, 3.5, 60, 0);
ScarletShoot(GetX, GetY, 3.2, 75, 0);
ScarletShoot(GetX, GetY, 3, 90, 0);
}

if(j == 1 || j == 3) {
ScarletShoot(GetX, GetY, 3, GetAngleToPlayer, 0);
ScarletShoot(GetX, GetY, 3.2, GetAngleToPlayer + 10, 0);
ScarletShoot(GetX, GetY, 3.2, GetAngleToPlayer - 10, 0);
}
}
}
if(f == 12300 || f == 12420 || f == 12540)
{
ascent(i in 0..10) {
ascent(j in 0..2) {
CreateLaserA(21, CAX[j + 1], CAY[j + 1], 600, 12, RED02, 60);
SetLaserDataA(21, 0, 20 * i, 0, 0, 0, 0);
ascent(k in 0..16) {
if(k != i && k != i + 180 && k != i - 180) {
ascent(l in 0..6) {
CreateShotA(22, 0, 0, 0);
SetShotDataA(22, 0, 1, 60 * l, 0.5 * (-1) ^ i, 0.01, 20, RED31);
AddShot(60, 21, 22, 280 * sin(180 - 20 * k) / sin(20 * k - (40 * i * (0.5 - j) + 180 * j)));
}
}
}
SetShotKillTime(21, 120);
FireShot(21);
}
}
}
if(f == 12660)
{

SetMovePosition02(GetCenterX, 40, 20);
ascent(i in 0..10) {
ascent(j in 0..2) {
CreateLaserA(21, CAX[j + 1], CAY[j + 1], 600, 12, BLUE02, 60);
SetLaserDataA(21, 0, 20 * i, 0, 0, 0, 0);
ascent(k in 0..16) {
if(k != i && k != i + 180 && k != i - 180) {
ascent(l in 0..15) {
CreateShotA(22, 0, 0, 0);
SetShotDataA(22, 0, 0.5, 24 * l, 0.5 * (-1) ^ i, 0.01, 20, BLUE31);
AddShot(60, 21, 22, 280 * sin(180 - 20 * k) / sin(20 * k - (40 * i * (0.5 - j) + 180 * j)));
}
}
}
SetShotKillTime(21, 120);
FireShot(21);
}
}
}
if(f > 12000 && f < 12660) {
SetMovePosition01(GetPlayerX, 40 + 100 * (sin((f - 12000) / 80)) ^ 2, 0.7);
}


/* Scoring Function: 2000 points per graze plus 75 points per life point of the boss taken off.*/
if(f > 10) {
AddScore(75 * (1000000 - GetLife() - h));
h = 1000000 - GetLife();
AddScore(2000 * (GetGraze - g));
g = GetGraze();
}
/* Count the counter up 1*/
f++;
/*yield*/
yield;

}
        @DrawLoop {
SetGraphicRect(1,1,64,64);
SetAlpha(255);
SetTexture(BI);
SetGraphicScale(1, 1);
SetGraphicAngle(0, 0, 0);
DrawGraphic(GetX(),GetY());
// CircleDraw;
/* Yield inside the Draw Loop yield;*/
}
@Finalize {
}

#include_script ".\BLUERED.txt";
#include_script ".\HorizontalFamiliarCircle.txt";

@Background {
}
}





Here is CIRCS.TXT.

Code: [Select]
/* Allow for 9 circles to be placed at the same time of one type (should be more than enough). */
/* This code will also not work on spell cards or battles longer than 60 million frames
(which is one million seconds, or uhm... some 100 something days, never mind that. */
/*You can assign any picture to the circles by adding let CIRCLEA = (...) into the
main variable initialization. Add the path to the image into (...).*/
/* Used circles are 80 x 80 pixels and are given a collision detection equal to that */
/* Put code link in function declaration part */

/*
    let CIRCLEA = GetCurrentScriptDirectory~"06_0313.jpg";
    let CIRCLEB = GetCurrentScriptDirectory~"06_0466.jpg";

LoadGraphic(CIRCLEA);
LoadGraphic(CIRCLEB);*/

let CAX = [0,0,0,0,0,0,0,0,0,0];
let CAY= [0,0,0,0,0,0,0,0,0,0];

let CBX= [0,0,0,0,0,0,0,0,0,0];
let CBY= [0,0,0,0,0,0,0,0,0,0];

let CAR= [0,0,0,0,0,0,0,0,0,0];
let CBR= [0,0,0,0,0,0,0,0,0,0];

let CAO= [0,0,0,0,0,0,0,0,0,0];
let CBO= [0,0,0,0,0,0,0,0,0,0];

let StoreFadeStartTimeCircleA = [60000000,60000000,60000000,60000000,60000000,60000000,60000000,60000000,60000000,60000000, 60000000];
let StoreFadeStartTimeCircleB = [60000000,60000000,60000000,60000000,60000000,60000000,60000000,60000000,60000000,60000000, 60000000];
let FadeTimeCircleA= [0,0,0,0,0,0,0,0,0,0];
let FadeTimeCircleB= [0,0,0,0,0,0,0,0,0,0];

let VXCA= [0,0,0,0,0,0,0,0,0,0];
let VYCA= [0,0,0,0,0,0,0,0,0,0];
let StopMoveA= [0,0,0,0,0,0,0,0,0,0];
let StartMoveA= [0,0,0,0,0,0,0,0,0,0];

let VXCB= [0,0,0,0,0,0,0,0,0,0];
let VYCB= [0,0,0,0,0,0,0,0,0,0];
let StopMoveB= [0,0,0,0,0,0,0,0,0,0];
let StartMoveB= [0,0,0,0,0,0,0,0,0,0];

let VCA= [0,0,0,0,0,0,0,0,0,0];
let AngA= [0,0,0,0,0,0,0,0,0,0];
let ACA= [0,0,0,0,0,0,0,0,0,0];
let AACA= [0,0,0,0,0,0,0,0,0,0];

let VCB= [0,0,0,0,0,0,0,0,0,0];
let AngB= [0,0,0,0,0,0,0,0,0,0];
let ACB= [0,0,0,0,0,0,0,0,0,0];
let AACB= [0,0,0,0,0,0,0,0,0,0];

let VXCA= [0,0,0,0,0,0,0,0,0,0];
let VYCA= [0,0,0,0,0,0,0,0,0,0];
let AXCA= [0,0,0,0,0,0,0,0,0,0];
let AYCA= [0,0,0,0,0,0,0,0,0,0];

let VXCB= [0,0,0,0,0,0,0,0,0,0];
let VYCB= [0,0,0,0,0,0,0,0,0,0];
let AXCB= [0,0,0,0,0,0,0,0,0,0];
let AYCB= [0,0,0,0,0,0,0,0,0,0];

let FADECA= [0,0,0,0,0,0,0,0,0,0];
let FADECB= [0,0,0,0,0,0,0,0,0,0];

let EXISTCA= [0,0,0,0,0,0,0,0,0,0];
let EXISTCB= [0,0,0,0,0,0,0,0,0,0];

let APPEARCA= [0,0,0,0,0,0,0,0,0,0];
let APPEARCB= [0,0,0,0,0,0,0,0,0,0];

let SCALECA= [0,0,0,0,0,0,0,0,0,0];
let SCALECB= [0,0,0,0,0,0,0,0,0,0];




let circledrawcount = 0;
/* Define a function which enables the use of the circle, with ID of 'CIRCLEIDA'.
Variables have long names, don't use these somewhere else. */

/* This function allows you to change the location of the circle and the rotational speed. */
/* The speed is in rotations per second, pick low numbers (i.e. surely <10.)*/
/* The opacity is between 0 and 255 (solid), the see-through of the circle */
/* The scaling duration is how long it will take before the circle has full (80x80) size. */


function SetCircleLocationA(CIRCLEIDA, XCIRCLEA, YCIRCLEA, VRCIRCLEA, OPACITYA, SCALEDURA) {
CAX[CIRCLEIDA] = XCIRCLEA;
CAY[CIRCLEIDA] = YCIRCLEA;
CAR[CIRCLEIDA] = VRCIRCLEA;
CAO[CIRCLEIDA] = OPACITYA;
EXISTCA[CIRCLEIDA] = 1;
SCALECA[CIRCLEIDA] = SCALEDURA;
APPEARCA[CIRCLEIDA] = circledrawcount;
}

function SetCircleLocationB(CIRCLEIDB, XCIRCLEB, YCIRCLEB, VRCIRCLEB, OPACITYB, SCALEDURB) {
CBX[CIRCLEIDB] = XCIRCLEB;
CBY[CIRCLEIDB] = YCIRCLEB;
CBR[CIRCLEIDB] = VRCIRCLEB;
CAO[CIRCLEIDB] = OPACITYB;
EXISTCB[CIRCLEIDB] = 1;
SCALECB[CIRCLEIDB] = SCALEDURB;
APPEARCB[CIRCLEIDB] = circledrawcount; }

/*
01 = function for moving the circle to some other place in a straight line in a defined time
Never fill in 0 for the time or you'll crash the program (Dividing by 0...).

02 = function for moving the circle a la CreateShotA, with angle and rotational accelleration,
velocity and accelleration specified.

03 = function for moving the circle a la CreateShotA_XY, with X and Y velocities and accellerations.

Note that the movement functions also have MOVETIME, which is the time it'll move (never to 0!),
and DELAY, which is self-explanatory.

Note: Multiple movement functions used together will cause unwanted results. Don't do.
*/

function MoveCircleA01(CIRCLEIDA, XMCIRCLEA, YMCIRCLEA, MOVETIME, DELAY){

VXCA[CIRCLEIDA] = (XMCIRCLEA - CAX[CIRCLEIDA]) / MOVETIME;
VYCA[CIRCLEIDA] = (YMCIRCLEA - CAY[CIRCLEIDA]) / MOVETIME;
StopMoveA[CIRCLEIDA] = circledrawcount + MOVETIME + DELAY;
StartMoveA[CIRCLEIDA] = circledrawcount + DELAY;
}
function MoveCircleA02(CIRCLEIDA, VA, ANGA, AANGA, AA, MOVETIME, DELAY) {

VCA[CIRCLEIDA] = VA;
AngA[CIRCLEIDA] = ANGA;
ACA[CIRCLEIDA] = AA;
AACA[CIRCLEIDA] = AANGA;
StopMoveA[CIRCLEIDA] = circledrawcount + MOVETIME + DELAY;
StartMoveA[CIRCLEIDA] = circledrawcount + DELAY;
}
function MoveCircleA03(CIRCLEIDA, VXA, VYA, AXA, AYA, MOVETIME, DELAY) {

VXCA[CIRCLEIDA] = VXA;
VYCA[CIRCLEIDA] = VYA;
AXCA[CIRCLEIDA] = AXA;
AYCA[CIRCLEIDA] = AYA;
StopMoveA[CIRCLEIDA] = circledrawcount + MOVETIME + DELAY;
StartMoveA[CIRCLEIDA] = circledrawcount + DELAY;
}
function MoveCircleB01(CIRCLEIDB, XMCIRCLEB, YMCIRCLEB, MOVETIME, DELAY){

VXCB[CIRCLEIDB] = (XMCIRCLEB - CBX[CIRCLEIDB]) / MOVETIME;
VYCB[CIRCLEIDB] = (YMCIRCLEB - CBY[CIRCLEIDB]) / MOVETIME;
StopMoveB[CIRCLEIDB] = circledrawcount + MOVETIME + DELAY;
StartMoveB[CIRCLEIDB] = circledrawcount + DELAY;
}
function MoveCircleB02(CIRCLEIDB, VB, ANGB, AANGB, AB, MOVETIME, DELAY) {

VCB[CIRCLEIDB] = VB;
AngB[CIRCLEIDB] = ANGB;
ACB[CIRCLEIDB] = AB;
AACB[CIRCLEIDB] = AANGB;
StopMoveB[CIRCLEIDB] = circledrawcount + MOVETIME + DELAY;
StartMoveB[CIRCLEIDB] = circledrawcount + DELAY;
}
function MoveCircleB03(CIRCLEIDB, VXB, VYB, AXB, AYB, MOVETIME, DELAY) {

VXCA[CIRCLEIDB] = VXB;
VYCA[CIRCLEIDB] = VYB;
AXCA[CIRCLEIDB] = AXB;
AYCA[CIRCLEIDB] = AYB;
StopMoveA[CIRCLEIDB] = circledrawcount + MOVETIME + DELAY;
StartMoveA[CIRCLEIDB] = circledrawcount + DELAY;
}
function FadeCircleA(CircleIDA, FADETIME) {

StoreFadeStartTimeCircleA[CircleIDA] = circledrawcount;
FADECA[CircleIDA] = CAO[CircleIDA] / FADETIME;
FadeTimeCircleA[CircleIDA] = FADETIME + 1;
}
function FadeCircleB(CircleIDB, FADETIME) {

StoreFadeStartTimeCircleB[CircleIDB] = circledrawcount;
FADECB[CircleIDB] = CAO[CircleIDB] / FADETIME;
FadeTimeCircleB[CircleIDB] = FADETIME + 1; }

/* This task must be included within the Draw Loop or this code will all have no effect but
computer slowdown. It does the following, in order:

1: Remove all faded circles and all circles moved off-board from play.
2: Check if circle 'n' exists.
3: If so, check if it's moving.
4: If so, add accellerations to velocities, and
5: add angular accellerations to the angle, and
6: add velocities to X- and Y- coordinations, transposed for angle if need be.
7: End of the bit within the movement check,
8: Check if the circle is fading,
9: if so, substract fade speed from opacity.
10: Note that you can fade partially by setting the circle again during the fade. Use CAX[n]
as X-coordinate to keep it positioned the same.
11: now draw the circle(s). 
12: Repeat the process for the B-Circles.
*/

task CircleDraw {


ascent(n in 0..9) {


if(CAO[n] < 1 || CAX[n] < 0 || CAX[n] > 500 || CAY[n] < 0 || CAY[n] > 500) {
EXISTCA[n]= 0;
}
if(CBO[n] < 1 || CBX[n] < 0 || CBX[n] > 500 || CBY[n] < 0 || CBY[n] > 500) {
EXISTCB[n]= 0;
}

if(EXISTCA[n] == 1) {

if(circledrawcount < StopMoveA[n] && circledrawcount > StartMoveA[n]) {
VCA[n] = VCA[n] + ACA[n];
AngA[n] = AngA[n] + AACA[n];
VXCA[n] = VXCA[n] + AXCA[n];
VYCA[n] = VYCA[n] + AYCA[n];
CAX[n] = CAX[n] + VCA[n] * cos(AngA[n]) + VXCA[n];
CAY[n] = CAY[n] + VCA[n] * sin(AngA[n]) + VYCA[n];
}
if(circledrawcount > StoreFadeStartTimeCircleA[n] && circledrawcount < FadeTimeCircleA[n] + StoreFadeStartTimeCircleA[n] + 1)
{
CAO[n] = CAO[n] - FADECA[n]
}
SetTexture(CIRCLEA);
SetGraphicRect(0, 0, 128, 128);
SetAlpha(CAO[n]);
SetGraphicAngle(0, 0, 180 + (circledrawcount - APPEARCA[n]) * CAR[n]);

if(circledrawcount > APPEARCA[n] + SCALECA[n]) {
SetGraphicScale(1, 1);
}
else {
SetGraphicScale((circledrawcount - APPEARCA[n]) / SCALECA[n], (circledrawcount - APPEARCA[n]) / SCALECA[n]);
}
DrawGraphic (CAX[n], CAY[n]);
SetCollisionA(CAX[n], CAY[n], 60);
}
if(EXISTCB[n] == 1) {

if(circledrawcount < StopMoveB[n] && circledrawcount > StartMoveB[n]) {
VCB[n] = VCB[n] + ACB[n];
AngB[n] = AngB[n] + AACB[n];
VXCB[n] = VXCB[n] + AXCB[n];
VYCB[n] = VYCB[n] + AYCB[n];
CBX[n] = CBX[n] + VCB[n] * cos(AngB[n]) + VXCB[n];
CBY[n] = CBY[n] + VCB[n] * sin(AngB[n]) + VYCB[n];
}
if(circledrawcount > StoreFadeStartTimeCircleB[n] && circledrawcount < FadeTimeCircleB[n] + StoreFadeStartTimeCircleB[n] + 1)
{
CBO[n] = CBO[n] - FADECB[n]
}
SetTexture(CIRCLEB);
SetGraphicRect(0, 0, 128, 128);
SetAlpha(CBO[n]);
SetGraphicAngle(0, 0, 180 + (circledrawcount - APPEARCB[n]) * CBR[n]);

if(circledrawcount > APPEARCB[n] + SCALECB[n]) {
SetGraphicScale(1, 1);
}
else {
SetGraphicScale((circledrawcount - APPEARCA[n]) / SCALECA[n], (circledrawcount - APPEARCA[n]) / SCALECA[n]);
}
DrawGraphic (CBX[n], CBY[n]);
SetCollisionA(CBX[n], CBY[n], 60);
}
}
circledrawcount++
}


and here is HorizontalFamiliarCircle.

Code: [Select]
task HCircleFamiliar(let num, let grf, let fc, let mult, let ang, let len)
{
let obj = Obj_Create(OBJ_SHOT);
Obj_SetX(obj, GetX);
Obj_SetY(obj, GetY);
ObjShot_SetGraphic(obj, grf);
ObjShot_SetDelay(obj, 0);
let fch = fc;
while( !Obj_BeDeleted(obj) )
{
fc++;
Obj_SetX(obj, GetX + mult * 180 * sin(f / 3 + ang));
if(fc - fch > len){
ObjShot_FadeDelete(obj);
break;
}
yield;
}
}




I'm glad I didn't add any sounds yet  ;D

As you can see a bit of a work in progress, still doing the shotdata.
By the way, I've tried to comment out any extra file entries. It should work like this.


« Last Edit: October 08, 2009, 10:14:02 PM by Aphid »

Nimono

  • wat
Re: Danmakufu Q&A/Problem Thread
« Reply #862 on: October 08, 2009, 10:35:28 PM »
I'm trying to recreate MoF MarisaA's star shots, the ones that pulse in and out and make those explosions when they hit an enemy. I'm having trouble with the explosion itself...

I cannot make the thing grow and shrink without either making an effect object or manually editing the graphics to make MORE versions of the explosion that are larger or smaller. Problem with the effect object is, I CAN'T MAKE IT DEAL DAMAGE TO THE ENEMY! I need help with this, please! It's extremely annoying, and since it's a player shot, not a spellcard object, I can't use a spell object...

The code for the objects:

Code: [Select]
task CreatePlayerShot03(x, y, speed, angle, power, ShotG, ShotA, epower, EffectA, EffectTime)
{
let EffectX = 0;
let EffectY = 0;
let Shot = Obj_Create(OBJ_SHOT);
Obj_SetPosition(Shot, x, y);
ObjShot_SetDamage(Shot, power);
ObjShot_SetPenetration(Shot, 1);
ObjShot_SetGraphic(Shot, ShotG);
Obj_SetSpeed(Shot, speed);
Obj_SetAngle(Shot, angle);
Obj_SetAlpha(Shot, ShotA);
while(!Obj_BeDeleted(Shot))
{
EffectX = Obj_GetX(Shot);
EffectY = Obj_GetY(Shot);
yield;
}
if(Obj_BeDeleted(Shot) && EffectX >= 0 && EffectY >= 0 && EffectX <= GetClipMaxX && EffectY <= GetClipMaxY)
{
let size = 30;
let grow = true;
let Effect = Obj_Create(OBJ_EFFECT);
ObjEffect_SetTexture(Effect,imgPlayer);
ObjEffect_SetRenderState(Effect,ALPHA);
ObjEffect_CreateVertex(Effect,4);
Obj_SetAlpha(Effect, EffectA);
ObjShot_SetDamage(Effect, epower);
ObjEffect_CreateVertex(Effect,4);
ObjEffect_SetPrimitiveType(Effect,PRIMITIVE_TRIANGLEFAN);
while(size > 0)
{
if(grow)
{
size+=5;
}
if(!grow)
{
size-=5;
}
if(size>=50)
{
grow = false;
}
ObjEffect_SetVertexUV(Effect,0,1,193);
ObjEffect_SetVertexUV(Effect,1,62,193);
ObjEffect_SetVertexUV(Effect,2,62,254);
ObjEffect_SetVertexUV(Effect,3,1,254);

ObjEffect_SetVertexXY(Effect,0,EffectX+(size*cos(135+270)),EffectY+(size*sin(135+270)));
ObjEffect_SetVertexXY(Effect,1,EffectX+(size*cos(225+270)),EffectY+(size*sin(225+270)));
ObjEffect_SetVertexXY(Effect,2,EffectX+(size*cos(315+270)),EffectY+(size*sin(315+270)));
ObjEffect_SetVertexXY(Effect,3,EffectX+(size*cos(45+270)),EffectY+(size*sin(45+270)));
yield;
}
Obj_Delete(Effect);
}
}

...also I cannot seem to make it look anything like the one in MoF. MoF's is very faded, but this is just...ugh.

It looks like this.

Henry

  • The observer
  • Exploring to the new world of Danmaku
Re: Danmakufu Q&A/Problem Thread
« Reply #863 on: October 09, 2009, 02:49:34 AM »
Is there anyway I can change the background music sometime in a stage?

If I used a #BGM[] block and I use PlayMusic(), the music in Playmusic() will be played instead of the music in BGM?

Also,

Code: [Select]
script_enemy_main
{
   let frame=0;
   let frame2=0;
   let count=2;
   let count2=1;
   let i;
   let j;
   let ytemp;
   let random;
   #include_function ".\enemydrawing.txt"
   LoadUserShotData(GetCurrentScriptDirectory~"images\shot_All.txt");
   @Initialize
   {
      SetLife(100);
      SetGraphicRect(0,0,32,32);
   }
   @MainLoop
   {
      SetCollisionA(GetX, GetY, 32);
      SetCollisionB(GetX, GetY, 16);
ytemp=rand(GetClipMinY+60, GetCenterY-30);
if(frame==0){
    SetMovePosition03(GetX, ytemp, 1, 3);
}
if(GetY==ytemp){
    frame2++;
}
if(frame2>60&&count2==1){
    SetMovePosition03(GetX, GetClipMinY-40, 1, 3);
    count2--;
}
if(frame%60>=40&&frame%3==0){
    CreateShot01(GetX, GetY, 5, GetAngleToPlayer, 9, 10);
}
      frame++;
      if((GetX-GetClipMinX)^2<=(GetSpeed/2)||(GetX-GetClipMaxX)^2<=(GetSpeed/2)||(GetY-GetClipMinY)^2<=(GetSpeed/2)||(GetY-GetClipMaxY)^2<=(GetSpeed/2)){
         count--;
      }
      if(count==0){
VanishEnemy;
      }
   }
   @DrawLoop{drawenemy(1);}
   @Finalize{
      if(count!=0){
         loop(8){
    CreateItem(ITEM_SCORE,GetX+rand(-80,80),GetY+rand(-80,80));
         }
      }
   }
}

Why doesn't the enemy go up after a period of time?
« Last Edit: October 09, 2009, 03:34:04 AM by Henry »
Old/Forgotten member.

Old Patchouli Project was outdated but new one is in progress.

Re: Danmakufu Q&A/Problem Thread
« Reply #864 on: October 09, 2009, 04:43:11 AM »
It's just an endless shitstorm of questions!
@Aphid:
After quite a while of thought, it occurred to me that the problem lies in the fundamental action you're taking: collision between two bullets. Not only that, but on such a large scale. Unfortunately, Danmakufu fails at manual collision detection on a large scale (or at least how we code it) so as far as I know, there is nothing you can do to improve the speed of your script by any significant degree. Granted, you are spawning an ass-tonne of object bullets, so yeah. Best advice I can give is to cut back on the collision between bullets. Your script looks fucking amazing, but if it takes my computer twice the amount of time to process a frame than is alotted, then what you're doing is probably a bit excessive (re: spawn less bullets).

Something you could ponder on: if all the bullets change action (spawn the CreateShotA in the same frame and delete themselves, as opposed to over the course of many frames) the fps lag is not as noticable. This only works for collision between bullets as far as I can tell, since normally spawning many bullets in one frame is frowned upon. The logic I suppose is that it doesn't cause your framerate to drop on average, instead you just see a brief pause. Anyway, I'm only mentioning this because when I sit in the middle of the screen during that part (thus causing the RED02's to hit the BLUE01's during the same frame or so) the fps lag is far less noticable than when I'm somewhere else on the screen and the RED02's are hitting BLUE01's nearly every frame. Perhaps it's a different direction you could go with for this section of the script, not to discourage what you've made so far. Which, by the way, is fucking awesome.


@pikaguy900:
For the faded transparency issue, use ObjEffect_SetVertexColor(Effect, [0-3], 100, 255, 255, 255); the last third parameter is the alpha value of the object. Repeat for all four verticies, of course. As for the pulsing issue, you have a few options. Firstly, you could do as you said -- make AnimationData for a bigger and smaller star, which unfortunately means dicking around with the graphics. Another option is to spawn an ObjEffect on top of the ObjShot, which you can make pulse rather easily using verticies. Make it update it's position every frame and get deleted as the ObjShot is. The latter option sounds easier to me, and shouldn't cause much slowdown since you're not spawning that many ObjEffects (to compare, my Sanae B's Wily Toad bomb spawns hundreds of effect objects which make up the green electricity. So far, from everybody I've asked, nobody has noticed any slowdown. You should be fine to spawn an ObjEffect on each shot).


@Henry:
PlayMusic() will override #BGM, yes. Might I suggest playing a mute file for your #BGM and just manually starting the music in your script anyway, since how fast people's computers load the script will affect how far into the song they are while they play, since the song in #BGM starts playing before @Initialize. Where as if you delcared PlayMusic pretty much anywhere, the music would start playing after everything is loaded and the fps spike has passed.

For your second question, you use the function rand which will generate a random floating point number between the two values you've assigned. The number will have many many decimal points. The enemy does not move because she will never be specifically on that point, to the decimal place, even if you tell her to move there. This is because Danmakufu has a nasty habit of rounding numbers off when all is said and done. A more accurate function to use would be rand_int, which pulls a random integer from between the assigned values, just as rand pulls a random real number. It is far more likely that the enemy will move to a point (0, 10) rather than (0, 10.37178592). Granted, you might want to get rid of the decimals when pulling the boss' coordinates anyways, since, for the very reason I just explained, it might be unlikely for the boss to be on those specific coordinates. I haven't tested that yet, but just in case, try using:
Code: [Select]
if(round(GetY)==round(ytemp)){
    frame2++;
}

Instead of your current code:
Code: [Select]
    if(GetY==ytemp){
       frame2++;
    }

That should get things working.

EDIT: Fixed my poor memory
« Last Edit: October 09, 2009, 02:08:07 PM by Naut »

Kylesky

  • *The Unknown*
  • Local Unbalanced Danmakufu Idiot Scripter
    • My useless youtube account... (will be useful in the future *I promise*)
Re: Danmakufu Q&A/Problem Thread
« Reply #865 on: October 09, 2009, 12:07:23 PM »
Question...  ;D sorry if this seems stupid but...

If I used the "#BackGround[User(put whatever here)]" for a background at the start of the script... then combine 2 or more spell cards that use this in one plural or stage file, but each card uses a different picture... is it possible to still load the backgrounds, or do I have to put all the backgrounds in the @DrawLoop? because I can't seem to figure out how to scroll the image, tiling it as it goes, like how #BackGround does it, in @DrawLoop...
Danmakufu Script Thread :V Latest Script: Intertwining Mechanical Intervention (temp name)

Yooooouuutuuuubeeee Channel Latest Video: Contest #8 Entry

Nimono

  • wat
Re: Danmakufu Q&A/Problem Thread
« Reply #866 on: October 09, 2009, 01:04:12 PM »
@pikaguy900:
For the faded transparency issue, use ObjEffect_SetVertexColor(Effect, [0-3], 255, 255, 255, 100); the last parameter is the alpha value of the object. Repeat for all four verticies, of course. As for the pulsing issue, you have a few options. Firstly, you could do as you said -- make AnimationData for a bigger and smaller star, which unfortunately means dicking around with the graphics. Another option is to spawn an ObjEffect on top of the ObjShot, which you can make pulse rather easily using verticies. Make it update it's position every frame and get deleted as the ObjShot is. The latter option sounds easier to me, and shouldn't cause much slowdown since you're not spawning that many ObjEffects (to compare, my Sanae B's Wily Toad bomb spawns hundreds of effect objects which make up the green electricity. So far, from everybody I've asked, nobody has noticed any slowdown. You should be fine to spawn an ObjEffect on each shot).

I didn't know SetVertexColor set an alpha, too... I'll use that, thanks.

I'm not really sure the ObjShot thing would help for the EXPLOSION. It'd definitely help with the STAR, yeah, but the EXPLOSION the star creates... Uhh... I don't really know if ZUN made its hitbox grow and shrink with the graphics, but I'd assume he did... I know it'd give it a hitbox, though, and at that is at least SOMETHING I want...

Of course, another alternative I have is to see if I can call a Spell script without actually triggering spell functions. I'm 99.99999999999999999999999999999999999999999% sure I can...and I'm 100% sure it'd solve all my problems.

EDIT: Naut, it was the FIRST parameter after the Vertex index, not the LAST. :P It still doesn't look right, for some reason. I don't get why it won't look anything like what it does in-game in MoF... What the heck did he do to it...
« Last Edit: October 09, 2009, 01:15:17 PM by pikaguy900 »

Aphid

Re: Danmakufu Q&A/Problem Thread
« Reply #867 on: October 09, 2009, 02:15:12 PM »
@naut.

I've also found out something while making a diffrent script yesterday. If I could replace the task in the script I presented then with a function it could probably solve everything. For example, here is a master script with two slave scripts. The second slave runs significantly slower than the primary (which I'm using now) whilst what I'm doing is exactly the same. The cinch? I used a task. Seems NuclearCheese was right about those tasks being poorly coded  :).

Remember talking about those roses? Many math functions for interesting patterns want numbers out of Q, the set of fractions (better yet, R, but that's kind of impossible), while doing ascent(...) or loop(f++) constructions leaves us with something from N. So if I want to get a large possible pattern choice with them all very diffrent and I'm using some kind of sine based function (like, a rose curve like here), or a Fourier series or something similar, it's a very good idea to essentially make some kind of algorithm that does that. So I did

This script has two interesting math functions worth a look at.
gcd(a,b) provides the greatest common denominator for a and b.
NtoQ(N) provides you with a number from the set Q of fractions as a two-value array for each number out of the set N of whole numbers. WARNING: do not put in Large or Very Large numbers, this will crash your pc. Don't try anything over one million, seriously (dorh, it will loop more than one billion times or so).  Basically, have a look at this diagram;

1-A2-B3-F4-G
1/2-C2/2-E3/2-H4/2
1/3-D2/3-I3/34/3
1/4-J2/43/44/4

Following A-B-C-D-E-F-G-H-I-J-... you can see what I mean. If you continue 'walking' through the two-dimensional matrix like that you'll eventually reach every number in the (positive part of) Q. So this nice little table maps N on Q. It's just that there's a whole lot of double values. So essentially, I made an algorithm that does the same little walk (the trick is to think modulus 2), and then provide some conditionals. There's some annotiations that explain the steps in more detail. Interestingly, doing just this doesn't get rid of the doubles. How do I get rid of such numbers as 2/4, 6/8, 12/14, which have already appeared before as 1/2, 3/4, and 6/7? They all have one thing in common though, their gcd is not equal to one. For all the other numbers the gcd is one. So I made a simple change to the script, which had a while-loop that basically counted the number of loops remaining until we've 'used up' N (so it loops N times), while doing one step of the diagram each loop. Each time the gcd would be non-equal one I'd add one to W, the remainder counter. Essentially it means that the code effectively 'skipped' these parts of the diagram. (The gcd thing I made is just Euclid's algorithm.).

That together with the polar parametrization of a rose curve, adjusted to do one whole loop in a set six seconds, made it possible to make this card. It is infinitely long and has a near-infinite amount of patterns (like 10^(10^6), or in other words leave it running until the end of time and it will STILL not very likely generate two identical patterns). On my PC, the version using a function and CreateShotA for the small bullets runs at over 200 fps, while the version using object bullets has problems passing 30 (unacceptable).

Master & Slave (high-efficiency), EDIT: made some aesthetic changes to make the pattern more easily viewable by colouring.

Code: [Select]
/*Danmakufu Pattern No.2. Roses.
(c) Aphid, ZUN, CtC team. */
#TouhouDanmakufu
#include<math.h>   
#Title[Roses]
#Text[Roses]
#Image[.\ykari.jpg]
/*#BackGround[User(.\bg.png, 1, 1)]*/
#PlayLevel[Phantasm]
#Player[FREE]
#ScriptVersion[3]
script_enemy_main {
#include_function "lib\SHOT_REPLACE\shot_replace.dnh";
#include_script ".\RosisRosis.txt";
    let BI=GetCurrentScriptDirectory~"boss_yukari.png";
    let BCI=GetCurrentScriptDirectory~"Yukari.png";
    let f=1000;
    let g=0;
    let ang=0;
    let z=0;
    let h=0;
    let lz=0;
    let W = "STRING";
    let Q = "zero";
    let Z = "zero";
@Initialize {
shotinit;
LoadGraphic(BI);
SetLife(1000000);
        SetDamageRate(0,0);
        SetInvincibility(60);
CutIn(YOUMU, "Infinite multiple Boundary "\""Roses"\", BCI,

0, 0, 420, 400);
      SetScore(4320000);
        SetEnemyMarker(true);
        SetDurableSpellCard;
SetY(60);
}
@MainLoop {
SetCollisionA(GetX, GetY, 42);
        SetCollisionB(GetX, GetY, 42);
if(f == 1080) {
RosisRosis(GetCenterX, GetCenterY, 0, f, PURPLE03, RED23,

ORANGE23, YELLOW23, GREEN23, AQUA23, BLUE23 ,1,1080, 1, 1);
RosisRosis(GetCenterX, GetCenterY, 0, f,  PURPLE03, RED23,

ORANGE23, YELLOW23, GREEN23, AQUA23, BLUE23 ,1,1080, 1, -1);
}
if(f%180 == 120){
ascent(i in 0..8){
ascent(j in 0..10){
CreateShotA(1, (GetCenterX + (200 + 12 * j) * cos(60*i+30)),

GetCenterY + (200 + 12*j) * sin(60*i+30), 60);
SetShotDataA(1, 0, (200 + 12*j) * 2 * 3.1415 / 180, 60 * i +

120, 2, 0, 50, PURPLE04);
SetShotKillTime(1, 180);
FireShot(1);
}}}
if(f%1080 == 0){
SetMovePositionRandom01(65, 20, 10, 50, 50, GetClipMaxX -

50, GetClipMinY + 170);
}
/* Scoring Function: 2000 points per graze plus 75 points per life point of

the boss taken off.*/
if(f > 10) {
AddScore(75 * (1000000 - GetLife() - h));
h = 1000000 - GetLife();
AddScore(2000 * (GetGraze - g));
g = GetGraze();
}
yield;
/* Count the counter up 1*/
f++
}
        @DrawLoop {
SetTexture(BI);
if(f%32 >= 0 && f%32 < 8)
{
if(GetSpeedX()==0)
{
SetGraphicRect(31,31,95,94);
}
else if(GetSpeedX()>0)
{
SetGraphicRect(286,415,352,478);
}
else if(GetSpeedX()<0)
{
SetGraphicRect(286,159,348,222);
}
}
if(f%32 >= 8 && f%32 < 16)
{
if(GetSpeedX()==0)
{
SetGraphicRect(31,159,95,222);
}
else if(GetSpeedX()>0)
{
SetGraphicRect(286,415,352,478);
}
else if(GetSpeedX()<0)
{
SetGraphicRect(286,159,348,222);
}
}
if(f%32 >= 16 && f%32 < 24)
{
if(GetSpeedX()==0)
{
SetGraphicRect(31,287,95,350);
}
else if(GetSpeedX()>0)
{
SetGraphicRect(286,415,352,478);
}
else if(GetSpeedX()<0)
{
SetGraphicRect(286,159,348,222);
}
}
if(f%32 >= 24 && f%32 < 32)
{
if(GetSpeedX()==0)
{
SetGraphicRect(543,31,607,94);
}
else if(GetSpeedX()>0)
{
SetGraphicRect(286,415,352,478);
}
else if(GetSpeedX()<0)
{
SetGraphicRect(286,159,348,222);
}
}
DrawGraphic(GetX(),GetY());
DrawText("WAVE:"~inttostring(floor(f/1080)), 40, 30, 20, 255)
}
@Finalize {
}
@Background {
}
function inttostring(number)
{
   let str = ToString(number);
   let str2 = "";
   let i = 0;
   while (str[i] != '.')
   {
      str2 = str2 ~ [str[i]];
      i++;
   }
   return(str2);
}
}

Code: [Select]
/* RosisRosis functions. Math & Bullet, Aphid  Ver IV*/

function gcd(a, b){
let array = [a, b];
let arrayb = [0];
let swap = 0;
/* first check if a > b. If not, swap 'em. */
if(a < b){
swap = a;
a = b;
b = swap;
}
let a = absolute(trunc(a));
let b = absolute(trunc(b)); /* if you add non-positive integers this thing otherwise crashes your pc's.*/
let count = 0;
loop{
count++; /* keep a count on the amount of elements in the array.*/
arrayb[0] = array[count-1] % array[count];
array=array~arrayb;
if (array[count+1] == 0){
break; /*apply the euclidian algorithm (don't keep track of stuff though that's too hard on the pc */
}
}
let G = array[count];
return G
}

function NtoQ(N){
let W = N - 1;
if (N > 0) {
W = trunc(N) - 1;
} else {
W = trunc(N * -1) - 1;}
let a = 1;
let b = 1;
while(W > 0){
/* if W is zero, we're done with the diagram!*/
/* determine if we go to the right in the diagram.*/
if (b == 1 && a%2 == 1){
W=W-1;
a++;
}
/* now determine if we go down in the diagram.*/
else if (a == 1 && (b%2 == 2 || b%2 == 0)){
W=W-1;
b++;
}
/* now determine whether we're going down-left.*/
else if ((a + b) % 2 == 1){
W=W-1;
b++;
a=a-1;
}
/* well, we're going up-right now.*/
else if ((a + b) % 2 != 1){
W=W-1;
a++;
b=b-1;
}
/* now determine whether or not we've hit a double number. For example, 4/2 = 2/1 so we want to skip those numbers. These numbers have in common that their greatest

common denominator is greater than one so we sort by that. If that is so, we will have to 'skip' this number, in other words ADD one to W.
*/
if(gcd(a, b) != 1){
W++;
}
}
let Q = [a, b];
return Q
}

function Accbullet(x, y, ang, grf, grf2, grf3, grf4, grf5, grf6, invspeed, vel){
CreateShotA(1, x, y, 0);
SetShotDataA(1, 0, 0, ang, 0, 0, 0, grf);
SetShotDataA(1, 80, 0, ang, 0, 0, 0, grf2);
SetShotDataA(1, 160, 0, ang, 0, 0, 0, grf3);
SetShotDataA(1, 240 / invspeed, NULL, NULL, 0, vel * 120 / 46200, 20, grf4);
SetShotDataA(1, 360 / invspeed, NULL, NULL, 0, vel * 120 / 46200, 20, grf5);
SetShotDataA(1, 480 / invspeed, NULL, NULL, 0, 0, 20, grf6);
FireShot(1);
}

task RosisRosis(let x, let y, let ang, let fc, let grf, let accgrf, let accgrf2, let accgrf3, accgrf4, accgrf5, accgrf6, let speed, let len, let accspd, let inv){
let obj = Obj_Create(OBJ_SHOT);
Obj_SetX(obj, x);
Obj_SetY(obj, y);
ObjShot_SetGraphic(obj, grf);
let fch = fc;
let u = trunc((fch - fc) / len);
let uold = 0;
let k = [1,1];
let theta = ang;
let Xpre = 0;
let Ypre = 0;
let newX = 0;
let newY = 0;
let Xaft = 0;
let strings = "";
let Yaft = 0;
let Angtrav = 0;
let radius = 1;
loop
{
if(Obj_GetY(obj) < 1){
obj = Obj_Create(OBJ_SHOT);
ObjShot_SetGraphic(obj, grf);
}

fch++;
Xpre = Obj_GetX(obj);
Ypre = Obj_GetY(obj);
theta = speed * (fch - fc) / 1.5 + ang;
if(fch%len == 1){
u++;
k = NtoQ(u);
}
radius = cos(theta * (k[0]));
newX = 200 * inv * radius * cos(theta * k[1]) + x;
newY = 200 * inv * radius * sin(theta * k[1]) + y;
Obj_SetX(obj, newX);
Obj_SetY(obj, newY);
Xaft = Obj_GetX(obj);
Yaft = Obj_GetY(obj);
Angtrav = atan2((Yaft - Ypre), (Xaft - Xpre));
Accbullet(Xaft, Yaft, Angtrav + 90, accgrf, accgrf2, accgrf3, accgrf4, accgrf5, accgrf6, accspd, fch%4+1);
Accbullet(Xaft + (Xaft - Xpre)/2, Yaft + (Yaft - Ypre)/2, Angtrav - 90, accgrf, accgrf2, accgrf3, accgrf4, accgrf5, accgrf6,  accspd, fch%4+1);
yield;
}
}







And the less efficient version for those who want to test it:
Master Code;

Code: [Select]
/*Danmakufu Pattern No.2. Roses.
(c) Aphid, ZUN, CtC team. */
#TouhouDanmakufu
#include<math.h>   
#Title[Roses]
#Text[Roses]
#Image[.\ykari.jpg]
/*#BackGround[User(.\bg.png, 1, 1)]*/
#PlayLevel[Phantasm]
#Player[FREE]
#ScriptVersion[2]
script_enemy_main {
#include_function "lib\SHOT_REPLACE\shot_replace.dnh";
#include_script ".\RosisRosis.txt";
    let BI=GetCurrentScriptDirectory~"boss_yukari.png";
    let BCI=GetCurrentScriptDirectory~"Yukari.png";
    let f=1000;
    let g=0;
    let ang=0;
    let z=0;
    let h=0;
    let lz=0;
    let W = "STRING";
    let Q = "zero";
    let Z = "zero";
@Initialize {
shotinit;
LoadGraphic(BI);
SetLife(1000000);
        SetDamageRate(0,0);
        SetInvincibility(60);
CutIn(YOUMU, "Infinite multiple Boundary "\""Roses"\", BCI,

0, 0, 420, 400);
      SetScore(4320000);
        SetEnemyMarker(true);
        SetDurableSpellCard;
SetY(60);
}
@MainLoop {
SetCollisionA(GetX, GetY, 42);
        SetCollisionB(GetX, GetY, 42);
if(f == 1080) {
RosisRosis(GetCenterX, GetCenterY, 0, f, PURPLE03,

GREEN23,1,1080, 1, 1);
RosisRosis(GetCenterX, GetCenterY, 0, f, PURPLE03,

BLUE23,1,1080, 1, -1);
}
if(f%180 == 120){
ascent(i in 0..8){
ascent(j in 0..10){
CreateShotA(1, (GetCenterX + (200 + 12 * j) * cos(60*i+30)),

GetCenterY + (200 + 12*j) * sin(60*i+30), 60);
SetShotDataA(1, 0, (200 + 12*j) * 2 * 3.1415 / 180, 60 * i +

120, 2, 0, 50, PURPLE04);
SetShotKillTime(1, 180);
FireShot(1);
}}}
if(f%1080 == 0){
SetMovePositionRandom01(65, 20, 10, 50, 50, GetClipMaxX -

50, GetClipMinY + 170);
}
/* Scoring Function: 2000 points per graze plus 75 points per life point of

the boss taken off.*/
if(f > 10) {
AddScore(75 * (1000000 - GetLife() - h));
h = 1000000 - GetLife();
AddScore(2000 * (GetGraze - g));
g = GetGraze();
}
yield;
/* Count the counter up 1*/
f++
}
        @DrawLoop {
SetTexture(BI);
if(f%32 >= 0 && f%32 < 8)
{
if(GetSpeedX()==0)
{
SetGraphicRect(31,31,95,94);
}
else if(GetSpeedX()>0)
{
SetGraphicRect(286,415,352,478);
}
else if(GetSpeedX()<0)
{
SetGraphicRect(286,159,348,222);
}
}
if(f%32 >= 8 && f%32 < 16)
{
if(GetSpeedX()==0)
{
SetGraphicRect(31,159,95,222);
}
else if(GetSpeedX()>0)
{
SetGraphicRect(286,415,352,478);
}
else if(GetSpeedX()<0)
{
SetGraphicRect(286,159,348,222);
}
}
if(f%32 >= 16 && f%32 < 24)
{
if(GetSpeedX()==0)
{
SetGraphicRect(31,287,95,350);
}
else if(GetSpeedX()>0)
{
SetGraphicRect(286,415,352,478);
}
else if(GetSpeedX()<0)
{
SetGraphicRect(286,159,348,222);
}
}
if(f%32 >= 24 && f%32 < 32)
{
if(GetSpeedX()==0)
{
SetGraphicRect(543,31,607,94);
}
else if(GetSpeedX()>0)
{
SetGraphicRect(286,415,352,478);
}
else if(GetSpeedX()<0)
{
SetGraphicRect(286,159,348,222);
}
}
DrawGraphic(GetX(),GetY());
}
@Finalize {
}
@Background {
}
}




Code: [Select]
function gcd(a, b){
let array = [a, b];
let arrayb = [0];
let swap = 0;
/* first check if a > b. If not, swap 'em. */
if(a < b){
swap = a;
a = b;
b = swap;
}
let a = absolute(trunc(a));
let b = absolute(trunc(b)); /* if you add non-positive integers this thing otherwise crashes your pc's.*/
let count = 0;
loop{
count++; /* keep a count on the amount of elements in the array.*/
arrayb[0] = array[count-1] % array[count];
array=array~arrayb;
if (array[count+1] == 0){
break; /*apply the euclidian algorithm (don't keep track of stuff though that's too hard on the pc */
}
}
let G = array[count];
return G
}

function NtoQ(N){
let W = N - 1;
if (N > 0) {
W = trunc(N) - 1;
} else {
W = trunc(N * -1) - 1;}
let a = 1;
let b = 1;
while(W > 0){
/* if W is zero, we're done with the diagram!*/
/* determine if we go to the right in the diagram.*/
if (b == 1 && a%2 == 1){
W=W-1;
a++;
}
/* now determine if we go down in the diagram.*/
else if (a == 1 && (b%2 == 2 || b%2 == 0)){
W=W-1;
b++;
}
/* now determine whether we're going down-left.*/
else if ((a + b) % 2 == 1){
W=W-1;
b++;
a=a-1;
}
/* well, we're going up-right now.*/
else if ((a + b) % 2 != 1){
W=W-1;
a++;
b=b-1;
}
/* now determine whether or not we've hit a double number. For example, 4/2 = 2/1 so we want to skip those numbers. These numbers have in common that their greatest common denominator is greater than one so we sort by that. If that is so, we will have to 'skip' this number, in other words ADD one to W.
*/
if(gcd(a, b) != 1){
W++;
}
}
let Q = [a, b];
return Q
}

task Accbullet(x, y, ang, grf, invspeed, vel){
let obj = Obj_Create(OBJ_SHOT);
let Dist = 0;
let angle = ang;
let newx = 0;
let newy = 0;
Obj_SetX(obj, x);
Obj_SetY(obj, y);
Obj_SetAngle(obj, ang);
ObjShot_SetGraphic(obj, grf);
let counter = 0;
while( !Obj_BeDeleted(obj))
{
counter++;
angle = atan2(Obj_GetY(obj) - GetCenterY, Obj_GetX(obj) - GetCenterX);
Dist = ((Obj_GetX(obj) - GetCenterX)^2+(Obj_GetY(obj) - GetCenterY)^2)^0.5;
if(240 * invspeed < counter && counter < 480 * invspeed){
Obj_SetSpeed(obj, Obj_GetSpeed(obj) + vel * 120 / 46200);
}
else if (counter > 479 * invspeed) {
Obj_SetSpeed(obj, vel);
}
yield;
}}

task RosisRosis(let x, let y, let ang, let fc, let grf, let accgrf, let speed, let len, let accspd, let inv){
let obj = Obj_Create(OBJ_SHOT);
Obj_SetX(obj, x);
Obj_SetY(obj, y);
ObjShot_SetGraphic(obj, grf);
let fch = fc;
let u = trunc((fch - fc) / len);
let uold = 0;
let k = [1,1];
let theta = ang;
let Xpre = 0;
let Ypre = 0;
let newX = 0;
let newY = 0;
let Xaft = 0;
let strings = "";
let Yaft = 0;
let Angtrav = 0;
let radius = 1;
loop
{
if(Obj_GetY(obj) < 1){
obj = Obj_Create(OBJ_SHOT);
ObjShot_SetGraphic(obj, grf);
}

fch++;
Xpre = Obj_GetX(obj);
Ypre = Obj_GetY(obj);
theta = speed * (fch - fc) / 1.5 + ang;
if(fch%len == 1){
u++;
k = NtoQ(u);
}
radius = cos(theta * (k[0]));
newX = 200 * inv * radius * cos(theta * k[1]) + x;
newY = 200 * inv * radius * sin(theta * k[1]) + y;
Obj_SetX(obj, newX);
Obj_SetY(obj, newY);
Xaft = Obj_GetX(obj);
Yaft = Obj_GetY(obj);
Angtrav = atan2((Yaft - Ypre), (Xaft - Xpre));
Accbullet(Xaft, Yaft, Angtrav + 90, accgrf, accspd, fch%4+1);
Accbullet(Xaft, Yaft, Angtrav - 90, accgrf, accspd, fch%4+1);
yield;
}
}

Lesson of the day: Don't use Tasks if you don't have to. Same with object bullets.

By the way, the offending section in my code with the blue & red bullets could be changed so that there's no object collision detection in the sense that the program physically checks all the pixels each frame. There's an analytical solution to determine the time each induvidual blue bullet takes to be hit by a red bullet given their velocities. It's only for pre-spawned ones of course but that's not that big a problem. The bigger problem? The formula my computer gave me was 260MB of complex numbers   :-[... uhm scrap that. Running that 60.000ish times per second is going to take a tiny bit more processing power than collision detection  :D.

Edit: It needs sound. Just put on necrofantasia or something while running it.
By the way, for those who want some interesting food for thought: How many petals does the rose have you see 216000 (one hour) frames after the start of the spell?

« Last Edit: October 09, 2009, 04:27:57 PM by Aphid »

Re: Danmakufu Q&A/Problem Thread
« Reply #868 on: October 10, 2009, 12:51:10 AM »
For some reason @Missed only works once. I set it to play a sfx when I die, but it only plays the first time I die.

Lawence Codye

  • The Nine Tails of Subconscious...
  • Come & your desires shall all become reality...
Re: Danmakufu Q&A/Problem Thread
« Reply #869 on: October 10, 2009, 09:57:14 AM »
@Naut

Thanks, that solved the problem...

now...another question, anybody.  Is there a way to have 4 options on screen instead of just 2...cause if so, I need to ask how to go about doing this?
I am the Nine Tails of Subconscious...

Come & your greatest desires will be reality...