#include "./Player_Function_Laser.dnh" // Shot Type int[] optionArr = []; float angSpace = 2.5; float[] angStartArr = []; // Far left, left, right, far right float[] angStartUF = [230, 270, 270, 310]; float[] angStartUFAlt = [230, 275, 265, 310]; float[] angStartF = [250, 280, 260, 290]; float offsetX = 125; float offsetY = 75; int[] bulletNum = [4, 3, 3, 4]; task _HomeShot(int shot_) { float duration = 55; bool homingBool = false; float basepenetrate = ObjShot_GetPenetration(shot_); float basedmg = ObjShot_GetDamage(shot_); // for (int t = 0i; t < duration && !Obj_IsDeleted(shot_); t++) { // Checks if enemies are on screen. If enemies are visible, enable homing for the shots. // _enemyArray is an array containing all enemy IDs, and is constantly updated in @MainLoop. if (0 < length(_enemyArray)) { float targetDist = 2000; // Arbitrary number (???) int targetID = 0; // Checks distance of every enemy on screen. for each (int enemy in ref _enemyArray) { float enemyX = ObjMove_GetX(enemy); float enemyY = ObjMove_GetY(enemy); if (0 < enemyX && enemyX < maxX && 0 < enemyY && enemyY < maxY) { // Returns the hypotenuse of the triangle formed by the x & y distances between the shot and the enemy. float shotDist = hypot(enemyX - ObjMove_GetX(shot_), enemyY - ObjMove_GetY(shot_)); // Locks the shot onto the enemy. if (shotDist < targetDist) { targetDist = shotDist; targetID = enemy; homingBool = true; } } } // Code to handle the actual homing. if (homingBool) { for (int f = 0; t < duration && !Obj_IsDeleted(shot_) && !Obj_IsDeleted(targetID) && ObjEnemy_GetInfo(targetID, INFO_LIFE) != 0 && !ObjCol_IsIntersected(shot_); t++) { ObjShot_SetAutoDelete(shot_, false); float shotAngle = NormalizeAngle(ObjMove_GetAngle(shot_)); // Angle of the player shot float targetAngle = NormalizeAngle(atan2(ObjMove_GetY(targetID) - ObjMove_GetY(shot_), ObjMove_GetX(targetID) - ObjMove_GetX(shot_))); // Returns angle from the shot to the enemy. float angleDistance = AngularDistance(shotAngle, targetAngle); // Angular distance between enemy and player shot float homeRate = Interpolate_Decelerate(0, 0.8, min(45, f) / 45); // Homing speed? ObjMove_SetAngle(shot_, Interpolate_Accelerate(shotAngle, shotAngle + angleDistance, homeRate)); // Interpolate_Necko f++; yield; } ObjShot_SetAutoDelete(shot_, true); ObjMove_SetAngularVelocity(shot_, 0); homingBool = false; } } yield; } } task UpdateAng(){ while(true){ if(GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE){ angStartArr = angStartF; angSpace = 9; } else{ angStartArr = angStartUF; angSpace = 18; } yield; } } task ShotType(){ } function CreateOption(distX, distY, startang, wvel, counterspin){ //let shot = CreatePlayerShotA1(playerX+x, playerY-150+y, 0, startang, 0, 99999, KEV_OPTION); let dummy = CreatePlayerShotA1(playerX, playerY-180, 0, startang, 0, 99999, 0); bool visible = true; int shotspeedhome = 0; float counter = 0; float scythex = 0; float scythey = 0; float offset = 0; float dummyX = ObjMove_GetX(dummy); float dummyY = ObjMove_GetY(dummy); let shot = CreatePlayerShotA1(dummyX, dummyY, 0, startang, 0, 99999, OPTION); float spaceX = 0, spaceY = 0; float shotang = startang; //ObjShot_SetSpinAngularVelocity(shot, wvel); ObjShot_SetAutoDelete(shot, false); ObjShot_SetAutoDelete(dummy, false); _BulletRescalePlayer(shot, 1, true, 1); ObjRender_SetBlendType(shot, BLEND_ALPHA); ObjRender_SetAlpha(shot, 255); float shotX = ObjMove_GetX(shot); float shotY = ObjMove_GetY(shot); // Handles the spinning and shooting of the options. async{ //SetShotAutoDeleteClip(-500, 128, -500, -500); //int i = 0; loop{ shotX = ObjMove_GetX(shot); shotY = ObjMove_GetY(shot); ObjRender_SetAngleZ(shot, 0); if(!IsPermitPlayerShot || ripplayer){ //spaceX = clamp(spaceX-2, 0, x); //Obj_SetVisible(shot, false); Obj_SetVisible(dummy, false); visible = false; shotspeedhome = 0; } else{ //spaceX = min(x, spaceX+x/45); //spaceY = min(y, spaceY+y/45); Obj_SetVisible(shot, true); visible = true; Obj_SetVisible(dummy, true); if(shotspeedhome % 4 == 0 && GetVirtualKeyState(VK_USER1) == KEY_FREE && GetVirtualKeyState(VK_SHOT) != KEY_FREE){ let bullet = CreatePlayerShotA1(shotX, shotY, 50, 270, shotDamageOption, 1.5, FIRE_OPTION); //let water2 = CreatePlayerShotA1(shotx+25, shoty, 15, shotang+180, 1.82, 1.25, KEV_OPTIONSHOT); ObjShot_SetAutoDelete(bullet, false); _HandleDeletion(bullet); ObjRender_SetAlpha(bullet, shotAlpha); _BulletRescalePlayer(bullet, shotScaleOption, true, 1); //ObjMove_SetAngularVelocity(water, [0, 0.2][typeGun]); //ObjMove_SetAngularVelocity(water2, [0, 0.2][typeGun]); Obj_SetRenderPriorityI(bullet, plrender-1); ObjSound_Play(Base2); } shotspeedhome++; //counter; } yield; } } task _HandleDeletion(int target){ while(ObjMove_GetY(target) > -96){ if(Obj_IsDeleted(target)){break;} yield; } Obj_Delete(target); return; } // Having the options move with Kevin if not shooting and/or focused. async{ float angmove = 0; loop{ ObjMove_SetPosition(shot, playerX+counterspin*spaceX*cos(shotang), playerY-offset+counterspin*spaceY*sin(shotang)); shotang += 3*counterspin; ObjMove_SetPosition(dummy, playerX, playerY); // If under player: render above if(shotY > playerY){Obj_SetRenderPriorityI(shot, plrender+1);} else{Obj_SetRenderPriorityI(shot, plrender-1);} if(GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE){ spaceX = max(distX*0.6, spaceX-distX*1/15); spaceY = max(distY*0.6, spaceY-distY*1/15); } else{ spaceX = min(distX*1, spaceX+distX*1/15); spaceY = min(distY*1, spaceY+distY*1/15); } yield; } } async{ loop{ if(visible == true){ObjShot_SetIntersectionEnable(shot, true); ObjShot_SetIntersectionEnable(dummy, true); counter += (1/240); counter = min(counter, 1);} else if (visible != true && GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE){ObjShot_SetIntersectionEnable(shot, false); ObjShot_SetIntersectionEnable(dummy, false);} else {ObjShot_SetIntersectionEnable(shot, false); ObjShot_SetIntersectionEnable(dummy, false); counter = 0;} yield; } } return shot; } // CALL THIS TASK FIRST task InitiateOptions(){ // Far left, left, right, far right float distX = 175; float distY = 175; float[] angArr = [0, 90, 180, 270]; int count = 0; for each (float entry in ref angArr){ int option = CreateOption(distX, distY, angArr[count], 1, -1); optionArr = optionArr ~ [option]; count++; } SpecialWeapon(objPlayer); } task BaseShot(){ int angMultiplier = 0; // lASER!!! _RenderLaser(objPlayer, 0, 300, GetStgFrameHeight()*1.5, 64, 0, shotDamageLaser); } task SpecialWeapon(int ID){ int angMultiplier = 0; float angFlux = 10; float ang1 = 180; float ang2 = 180; float[] angFire = [270-20, 270+20]; while(true){ if(GetVirtualKeyState(VK_USER1) != KEY_FREE && GetCommonDataPtr(POINTER_SPECIALAMMO, 100) > 0 && IsPermitPlayerShot && !ripplayer){ SetCommonDataPtr(POINTER_SPECIALCHECK, true); SetCommonDataPtr(POINTER_CHAINCHECK, true); // (Approx.) 20 ammo per second SetCommonDataPtr(POINTER_SPECIALAMMO, max(0, GetCommonDataPtr(POINTER_SPECIALAMMO, 100)-(20/60))); if(shotspeed % 4 == 0){ float x = ObjMove_GetX(ID); float y = ObjMove_GetY(ID); // Minimal rank boost -> +0.5 rank for every 10 seconds of the wpn being used -> 1/20 rank every sec -> 1/300 rank every 4 frames SetCommonData("Rank", clamp(GetCommonData("Rank", 1) + 1/300, GetCommonData("MinRank", 1), GetCommonData("MaxRank", 12))); angFire[0] = 270 + angFlux * sin(ang1) + rand(-5, 5); angFire[1] = 270 + angFlux * sin(ang2) + rand(-5, 5); // YASS FIRE THOSE BITCH KILLER SLASHES FireSlash(angFire[0], 50, 35, 45); FireSlash(angFire[1], 50, 35, 45); ang1 += 25; ang2 -= 25; } } else{ SetCommonDataPtr(POINTER_CHAINCHECK, false); if(GetCommonDataPtr(POINTER_CHAINGAUGE, 0) <= 0){SetCommonDataPtr(POINTER_SPECIALCHECK, false);} } yield; } } task FireSlash( float angle, baseSpd, int decelTime, lifeTime ){ int slash = CreatePlayerShotA1(playerX, playerY, baseSpd, angle, shotDamageSpecial, 8, FIRE_SPECIAL); ObjShot_SetPenetrateShotEnable(slash, false); _BulletRescalePlayer(slash, shotScaleSpecial, true, 1); Obj_SetRenderPriorityI(slash, plrender-1); //ObjRender_SetBlendType(slash, BLEND_ADD_ARGB); ObjSound_Play(Base5); ObjShot_SetEraseShot(slash, true); async{ ascent(i in 0..3){ int slashA = CreatePlayerShotA1(playerX, playerY, baseSpd, angle, shotDamageSpecial/5, 32, FIRE_SPECIAL); _BulletRescalePlayer(slashA, shotScaleSpecial/2, true, 1); //ObjRender_SetBlendType(slashA, BLEND_ADD_ARGB); ObjShot_SetPenetrateShotEnable(slashA, false); Obj_SetRenderPriorityI(slashA, plrender-1); Fade(slashA); wait(10); } } task Fade(int ID){ ObjMove_AddPatternA2(ID, 0, baseSpd/2, [rand(180, 230), rand(-50, 30)][rand_int(0, 1)], (-baseSpd/2)/(decelTime), 2, 0); ascent(i in 0..(decelTime)){ ObjRender_SetAlpha(ID, Interpolate_Accelerate(shotAlpha, 0, i/(decelTime))); yield; } Obj_Delete(ID); } async{ ObjMove_SetAcceleration(slash, -baseSpd/decelTime); ObjMove_SetMaxSpeed(slash, baseSpd/50); ObjRender_SetAlpha(slash, shotAlpha); ascent(i in 0..decelTime){ ObjRender_SetScaleXYZ(slash, Interpolate_Accelerate(shotScaleSpecial/1.25, shotScaleSpecial, i/decelTime)); yield; } ascent(i in 0..(lifeTime-decelTime)){ ObjRender_SetAlpha(slash, Interpolate_Accelerate(shotAlpha, 0, i/(lifeTime-decelTime))); yield; } Obj_Delete(slash); } } // Bomb // Holy fuck its literally YoumuA IBP