// 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( float offsetX_uf, offsetY_uf, float offsetX_f, offsetY_f, float ang_uf, ang_f ){ // Option int option = PlayerOption_LinearMove( offsetX_uf, offsetY_uf, offsetX_f, offsetY_f, true, ang_uf, ang_f, plimg, OPTION, 0.5, 39, 128, 1, 1, false, false, 1, false, false ); return option; } // CALL THIS TASK FIRST task InitiateOptions(){ // Far left, left, right, far right float[][] offsetArr = [ [-offsetX * 1.5, offsetY * 1.25, -offsetX * 1, offsetY * 0.75], [-offsetX * 1, 0, -offsetX * 0.75, -offsetY * 0.4], [offsetX * 1, 0, offsetX * 0.75, -offsetY * 0.4], [offsetX * 1.5, offsetY * 1.25, offsetX * 1, offsetY * 0.75], ]; int count = 0; for each (float[] entry in ref offsetArr){ int option = CreateOption( offsetArr[count][0], offsetArr[count][1], offsetArr[count][2], offsetArr[count][3], angStartUF[count], angStartF[count] ); optionArr = optionArr ~ [option]; ShotType(option, angStartUFAlt[count], angStartF[count], bulletNum[count]); SpecialWeapon(option, angStartUFAlt[count], angStartF[count], bulletNum[count]); count++; } } task BaseShot(){ int angMultiplier = 0; while(true){ if(GetVirtualKeyState(VK_SHOT) != KEY_FREE && GetVirtualKeyState(VK_USER1) == KEY_FREE &&IsPermitPlayerShot && !ripplayer){ if(shotspeed % 4 == 0){ ObjSound_Play(Base3); let shotA = CreatePlayerShotA1(playerX, playerY, 52, 270, shotDamage*2, 1.2, FIRE_BASE); _BulletRescalePlayer(shotA, shotScale1, true, 1); ObjRender_SetAlpha(shotA, shotAlpha); Obj_SetRenderPriorityI(shotA, 41); } } yield; } } task ShotType(int ID, float startAngUF, startAngF, int bulletNum){ int angMultiplier = 0; while(true){ if(GetVirtualKeyState(VK_SHOT) != KEY_FREE && GetVirtualKeyState(VK_USER1) == KEY_FREE &&IsPermitPlayerShot && !ripplayer){ if(shotspeed % 3*(bulletNum+1) == 0){ float x = ObjMove_GetX(ID); float y = ObjMove_GetY(ID); int multiplier = 1; if(x-playerX > 0){multiplier = 1;} else{multiplier = -1;} //ObjSound_Play(Base3); loop(bulletNum){ if(GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE){ let shotA = CreatePlayerShotA1(x, y, 45, startAngF+angSpace*multiplier*angMultiplier, shotDamage, 1.1, FIRE_NORMAL); _BulletRescalePlayer(shotA, shotScale1, true, 1); ObjRender_SetAlpha(shotA, shotAlpha); Obj_SetRenderPriorityI(shotA, 41); } else{ let shotA = CreatePlayerShotA1(x, y, 45, startAngUF+angSpace*multiplier*angMultiplier, shotDamage, 1.1, FIRE_NORMAL); _BulletRescalePlayer(shotA, shotScale1, true, 1); ObjRender_SetAlpha(shotA, shotAlpha); Obj_SetRenderPriorityI(shotA, 41); } angMultiplier ++; wait(2); } angMultiplier = 0; } } yield; } } task SpecialWeapon(int ID, float startAngUF, startAngF, int bulletNum){ int angMultiplier = 0; while(true){ if(GetVirtualKeyState(VK_USER1) != KEY_FREE && GetCommonDataPtr(POINTER_SPECIALAMMO, 100) > 0 && IsPermitPlayerShot && !ripplayer){ SetCommonDataPtr(POINTER_SPECIALCHECK, true); SetCommonDataPtr(POINTER_CHAINCHECK, true); // 15 ammo per second if(shotspeed % 4 == 0){ float x = ObjMove_GetX(ID); float y = ObjMove_GetY(ID); SetCommonDataPtr(POINTER_SPECIALAMMO, max(0, GetCommonDataPtr(POINTER_SPECIALAMMO, 100)-(15/60))); // 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*4), GetCommonData("MinRank", 1), GetCommonData("MaxRank", 12))); int multiplier = 1; if(x-playerX > 0){multiplier = 1;} else{multiplier = -1;} ObjSound_Play(Base2); loop(1){ let shotA = CreatePlayerShotA1(x, y, 45, startAngF+rand(-1, 1), shotDamageSpecial, 1.1, FIRE_SPECIAL); _BulletRescalePlayer(shotA, shotScale1*2, true, 1); _HomeShot(shotA); ObjRender_SetAlpha(shotA, shotAlpha); Obj_SetRenderPriorityI(shotA, 41); angMultiplier ++; } angMultiplier = 0; } } else{ SetCommonDataPtr(POINTER_CHAINCHECK, false); if(GetCommonDataPtr(POINTER_CHAINGAUGE, 0) <= 0){SetCommonDataPtr(POINTER_SPECIALCHECK, false);} } yield; } } // Bomb // Yassbong explosion