// Particle list for laser effect int LaserEffect = ObjParticleList_Create(OBJ_PARTICLE_LIST_2D); int[] rect = [2816, 0, 2816+256, 0+256]; ObjPrim_SetTexture(LaserEffect, "script/player/PrideJam_ByakMiko/playerlib/ByakMiko_Sheet.png"); Obj_SetRenderPriorityI(LaserEffect, 39); ObjPrim_SetPrimitiveType(LaserEffect, PRIMITIVE_TRIANGLELIST); ObjPrim_SetVertexCount(LaserEffect, 4); ObjRender_SetBlendType(LaserEffect, BLEND_ALPHA); // Left-top, right-top, left-bottom, right-bottom ObjPrim_SetVertexUVT(LaserEffect, 0, rect[0], rect[1]); ObjPrim_SetVertexUVT(LaserEffect, 1, rect[2], rect[1]); ObjPrim_SetVertexUVT(LaserEffect, 2, rect[0], rect[3]); ObjPrim_SetVertexUVT(LaserEffect, 3, rect[2], rect[3]); // Vertex positions are offset with deltas so that the sprite is centered float dU = (rect[2] - rect[0])/2; float dV = (rect[3] - rect[1])/2; ObjPrim_SetVertexPosition(LaserEffect, 0, -dU, -dV, 1); ObjPrim_SetVertexPosition(LaserEffect, 1, dU, -dV, 1); ObjPrim_SetVertexPosition(LaserEffect, 2, -dU, dV, 1); ObjPrim_SetVertexPosition(LaserEffect, 3, dU, dV, 1); ObjPrim_SetVertexIndex(LaserEffect, [0, 1, 2, 1, 2, 3]); task _CreateLaserParticle(float x, float y, float spdX, float spdY, float baseAng){ int effectLength = 45; let x_speed = spdX; let y_speed = spdY; let z_add = rand(-5, 5); ascent(i in 0..effectLength){ _PetalMovement(Interpolate_Decelerate(0.5, 0.2, i/effectLength), Interpolate_Decelerate(255, 0, i/effectLength)); yield; } task _PetalMovement(scale, alpha){ ObjParticleList_SetScale(LaserEffect, scale); ObjParticleList_SetAngleZ(LaserEffect, baseAng); ObjParticleList_SetPosition(LaserEffect, x, y, 1); ObjParticleList_SetAlpha(LaserEffect, alpha); //Submits the current data to an instance, cleared every frame. ObjParticleList_AddInstance(LaserEffect); x += x_speed; y += y_speed; baseAng += z_add; yield; } } // task _LaserSpriteRender( img, int target, float targetAng, int rectLeft, int rectTop, int rectRight, int rectBottom, float scaleX, float scaleY, int renderPriority, float alpha, float scaleSpeed ){ int[] EnemyList = []; let lasersprite = ObjPrim_Create(OBJ_SPRITE_2D); ObjPrim_SetTexture(lasersprite, img); ObjSprite2D_SetSourceRect(lasersprite, rectLeft, rectTop, rectRight, rectBottom); ObjRender_SetScaleXYZ(lasersprite, 0, scaleY, 1); ObjSprite2D_SetDestRect(lasersprite, -(rectRight-rectLeft)/2, 0, (rectRight-rectLeft)/2, rectTop-rectBottom); Obj_SetRenderPriorityI(lasersprite, renderPriority); ObjRender_SetAlpha(lasersprite, 0); ObjRender_SetBlendType(lasersprite, BLEND_ADD_ARGB); async{ loop{ EnemyList = ObjCol_GetListOfIntersectedEnemyID(target); if(GetVirtualKeyState(VK_SHOT) != KEY_FREE && GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE && !ripplayer && IsPermitPlayerShot){ // Assumes the intersecting color is right next to the right of the original color if (length(EnemyList) > 0) {ObjSprite2D_SetSourceRect(lasersprite, rectRight, rectTop, rectRight+(rectRight-rectLeft), rectBottom);} else{ObjSprite2D_SetSourceRect(lasersprite, rectLeft, rectTop, rectRight, rectBottom);} float targetx = ObjRender_GetX(target); float targety = ObjRender_GetY(target); ObjRender_SetScaleX(lasersprite, min(scaleX+rand(-0.025, 0.025), ObjRender_GetScaleX(lasersprite) + scaleSpeed)); ObjRender_SetAlpha(lasersprite, min(alpha, ObjRender_GetAlpha(lasersprite)+alpha/5)); ObjRender_SetAngleZ(lasersprite, targetAng); ObjRender_SetPosition(lasersprite, targetx, targety, 1); yield; } else{ ObjRender_SetScaleX(lasersprite, max(0, ObjRender_GetScaleX(lasersprite) - scaleSpeed)); ObjRender_SetAlpha(lasersprite, max(0, ObjRender_GetAlpha(lasersprite)-alpha/5)); yield; } yield; } } } function _RenderLaser(target, float ang, float maxintersectX, float maxLength, float width, float speedLength, float dmg){ /* */ int[] EnemyList = []; float angRender = asin(maxintersectX/absolute(maxLength)); //int laser = CreatePlayerShotA1(ObjRender_GetX(target), ObjRender_GetY(target), 0, ang, dmg, 9999999, 0); int laser = CreateStraightLaserA1(ObjRender_GetX(target), ObjRender_GetY(target), ang-90, maxLength, width, 99999999, 0, 1); ObjLaser_SetInvalidLength(laser, 0, 0); //ObjShot_SetDamage(laser, dmg); ObjShot_SetAutoDelete(laser, false); Obj_SetRenderPriorityI(laser, 38); _Follow(laser, target); _LaserSpriteRender( teamimg, laser, ang, 3072, 0, 3072+256, 256, 0.45, 20, 38, 200, 0.14 ); // This also affects damage of the laser, not just effects LaserHitEffect(EnemyList, laser, dmg); // When shot key is being held, create a line intersection that stretches across the laser. /* Calculations: startx: x of target starty: y of target endx: x of laser endy: maxLength width = width of laser */ async{ loop{ if(GetVirtualKeyState(VK_SHOT) != KEY_FREE && GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE && !ripplayer && IsPermitPlayerShot){ if(shotspeed % 5 == 0){ ObjSound_Play(inferno); } ObjShot_SetIntersectionEnable(laser, true); //ObjShot_SetIntersectionLine(laser, ObjRender_GetX(target), ObjRender_GetY(target), ObjRender_GetX(target)+maxintersectX, -maxLength, width); //WriteLog(ObjMove_GetX(laserfwd)); yield; } else{ ObjShot_SetIntersectionEnable(laser, false); ObjShot_SetPenetration(laser, 99999999); yield; } } } // After shot key is released, let the laser leave and then delete it. return laser; } task LaserHitEffect(int[] EnemyList, int target, float basedmg){ int[] ResortList = []; // Debugging: gets distance from player to the laser, appends it into an array task Resort(){ for each(int enm in EnemyList){ ResortList = append(ResortList, GetObjectDistance(enm, target)); } WriteLog(ResortList); ResortList = []; } async{ loop{ EnemyList = ObjCol_GetListOfIntersectedEnemyID(target); yield; } } async{ loop{ Resort(); wait(60); } } // Particle effects async{ loop{ ascent(i in -1..length(EnemyList)-1){ _CreateLaserParticle(ObjMove_GetX(EnemyList[i])+prand(-30, 30), ObjMove_GetY(EnemyList[i])+prand(-30, 30), [prand(-8, -5), prand(-4, 4), prand(5, 8)][prand_int(0, 2)], [prand(-8, -6), prand(6, 8)][prand_int(0, 1)], rand(0, 360)); } //Resort; //WriteLog(EnemyList); wait(rand_int(9, 11)); } } // Damage effects async{ loop{ ascent(i in -1..length(EnemyList)-1){ float dmgCalc = max(1, basedmg - (basedmg * 0.2 * i)); ObjEnemy_SetLife(EnemyList[i], ObjEnemy_GetInfo(EnemyList[i], INFO_LIFE) - dmgCalc); } yield; } } } task _Follow(follower, followed){ while(!Obj_IsDeleted(follower)){ float x = ObjRender_GetX(followed); float y = ObjRender_GetY(followed); ObjMove_SetPosition(follower, x, y); yield; } }