commit 1
This commit is contained in:
commit
d3ada59252
391 changed files with 25819 additions and 0 deletions
489
script/player/Chimata/Chimata_Function.dnh
Normal file
489
script/player/Chimata/Chimata_Function.dnh
Normal file
|
@ -0,0 +1,489 @@
|
|||
|
||||
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
|
||||
){
|
||||
|
||||
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{
|
||||
int[] 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){ /* */
|
||||
|
||||
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, 9999999, 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, 240,
|
||||
0.14
|
||||
);
|
||||
|
||||
// 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(Fire);}
|
||||
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); yield;}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// After shot key is released, let the laser leave and then delete it.
|
||||
|
||||
return laser;
|
||||
}
|
||||
|
||||
|
||||
task _Follow(follower, followed){
|
||||
|
||||
while(!Obj_IsDeleted(follower)){
|
||||
float x = ObjRender_GetX(followed);
|
||||
float y = ObjRender_GetY(followed);
|
||||
ObjMove_SetPosition(follower, x, y);
|
||||
yield;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Special functions for Tenshi's CAVE laser shottype.
|
||||
// Original code by Razzy/Razzly, edited and tweaked by Kevinmonitor
|
||||
|
||||
// DEBUG
|
||||
|
||||
float LaserAlpha = 0; // Not used
|
||||
|
||||
task _CAVELaser(){
|
||||
|
||||
InitPLaserGfx(); // Probably effects that occur when the laser reaches an enemy? (KEV)
|
||||
|
||||
let lasers0 = [ID_INVALID,ID_INVALID,ID_INVALID,ID_INVALID,ID_INVALID,ID_INVALID,ID_INVALID,ID_INVALID,ID_INVALID];
|
||||
|
||||
// this delays when the laser fires
|
||||
// laser fires when laserMode==0
|
||||
// laserMode increments by 1 per frame
|
||||
// so laser fires after 15 frames
|
||||
|
||||
// KEV: To fire the laser immediately, just set laserMode/laserLimit to 0.
|
||||
|
||||
let laserLimit = 0;
|
||||
let laserMode=-laserLimit;
|
||||
|
||||
loop{
|
||||
if(
|
||||
GetPlayerState!=STATE_HIT
|
||||
&& GetPlayerState!=STATE_DOWN
|
||||
&& GetPlayerState!=STATE_END
|
||||
&& (GetVirtualKeyState(VK_SHOT)==KEY_PUSH || GetVirtualKeyState(VK_SHOT)==KEY_HOLD)
|
||||
){
|
||||
|
||||
if(IsPlayerSpellActive()){
|
||||
laserMode=min(0,laserMode+1);
|
||||
}
|
||||
|
||||
else{
|
||||
// reset laser delay when slowmove is let go
|
||||
laserMode=-laserLimit;
|
||||
}
|
||||
|
||||
laserMode=min(0,laserMode+1);
|
||||
|
||||
if(laserMode>=0){
|
||||
let odd = 1;
|
||||
|
||||
//NonPenetrationLaser(obj, xoff, yoff, ang, spd, maxLen, dmg, IsStrongLaser, width, vwidth)
|
||||
// KEV: Ascent loop determines the number of lasers that will be spawned.
|
||||
|
||||
ascent(i in 0..1){
|
||||
let las = lasers0[i];
|
||||
if(Obj_IsValueExists(las,"DEL") || Obj_IsDeleted(las)){
|
||||
let magnitude = 1;
|
||||
lasers0[i]=NonPenetrationLaser(objPlayer, 0, -36, 270, 40, GetStgFrameHeight()*1.5, 7, 1.25, 1);
|
||||
}
|
||||
odd=-odd;
|
||||
}
|
||||
//PlaySnd(SND_p_shot, 93);
|
||||
}
|
||||
|
||||
else{
|
||||
// reset laser delay when fire is let go
|
||||
// KEV: Unnecessary if the laser fires immediately
|
||||
RemovePLaserGfx();
|
||||
LaserAlpha = 0;
|
||||
laserMode=-laserLimit;
|
||||
}
|
||||
|
||||
}
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
// of an array of 2d coords, return the one closest to (sx,sy). Also returns the distance from (sx,sy) as the third value.
|
||||
function GetClosestCoord(coords, sx,sy){
|
||||
let closest=[];
|
||||
let last_dist=99999;
|
||||
let arrayLen=length(coords);
|
||||
if(arrayLen==1){
|
||||
let cur_dist;
|
||||
if(length(coords[0])==3){ cur_dist=coords[0][2]; }
|
||||
else{ cur_dist=((coords[0][0]-sx)^2+(coords[0][1]-sy)^2)^0.5; }
|
||||
closest=[coords[0][0],coords[0][1], cur_dist];
|
||||
}
|
||||
else{
|
||||
ascent(i in 0..arrayLen){
|
||||
let cur_dist;
|
||||
if(length(coords[i])==3){ cur_dist=(coords[i][2]); }
|
||||
else{ cur_dist=((coords[i][0]-sx)^2+(coords[i][1]-sy)^2)^0.5; }
|
||||
if(cur_dist < last_dist){
|
||||
last_dist=cur_dist;
|
||||
closest=[coords[i][0], coords[i][1], cur_dist];
|
||||
}
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
|
||||
// non-penetrating laser object
|
||||
function NonPenetrationLaser(obj, xoff, yoff, ang, spd, maxLen, dmg, width, vwidth){
|
||||
|
||||
//KEV: Parameter explanations:
|
||||
|
||||
//obj: Where the laser is fired from
|
||||
//xoff/yoff: x and y offsets relative to the object
|
||||
//ang, spd: Self-explanatory
|
||||
//maxLen: max length of the laser, DON'T SET THIS TOO HIGH! GetStgFrameHeight() + a generous number should be enough
|
||||
//dmg: Self-explanatory
|
||||
//IsStrongLaser (REMOVED HERE): use this if you want to differentiate between strong and weak lasers I guess, I don't play CAVE games so idk
|
||||
//width, vwidth: intersection & render width of laser
|
||||
|
||||
// KEV: Defines the laser object.
|
||||
|
||||
int a = 0;
|
||||
|
||||
let damager = ObjShot_Create(OBJ_STRAIGHT_LASER);
|
||||
|
||||
ObjShot_SetGraphic(damager, 0);
|
||||
Obj_SetVisible(damager, true);
|
||||
ObjShot_Regist(damager);
|
||||
ObjShot_SetDamage(damager, dmg);
|
||||
ObjShot_SetPenetration(damager, 9999);
|
||||
ObjShot_SetEraseShot(damager, true);
|
||||
ObjLaser_SetLength(damager, 0);
|
||||
ObjLaser_SetIntersectionWidth(damager, 256*width);
|
||||
ObjLaser_SetRenderWidth(damager, 256*vwidth);
|
||||
ObjStLaser_SetAngle(damager, ang); ObjShot_SetAutoDelete(damager, false);
|
||||
ObjShot_SetIntersectionEnable(damager, true);
|
||||
TNonPenetrationLaser();
|
||||
|
||||
return damager;
|
||||
|
||||
task TNonPenetrationLaser(){
|
||||
|
||||
let scroll=rand(0,64);
|
||||
let len=0; // the length of the laser (increased until maxLen)
|
||||
let cosine=cos(ang); // grab this value for placement of the tip. **this assumes the laser never changes angle**
|
||||
let sine=sin(ang); // grab this value for placement of the tip. **this assumes the laser never changes angle**
|
||||
|
||||
// **for lasers that change angle, cosine and sine will need to be updated**
|
||||
|
||||
// Laser is now firing
|
||||
while(
|
||||
IsPlayerSpellActive()
|
||||
&& !Obj_IsDeleted(damager) // KEV: The four following states can be reduced to !ripplayer in my player scripts
|
||||
&& !ripplayer
|
||||
&& (GetVirtualKeyState(VK_SHOT) != KEY_FREE)
|
||||
){
|
||||
|
||||
a++;
|
||||
if(a % 5 == 0){ObjSound_Play(Fire);}
|
||||
CheckLaserIntersection;
|
||||
// Set the laser's position and length
|
||||
ObjMove_SetPosition(damager, ObjMove_GetX(obj)+xoff,ObjMove_GetY(obj)+yoff);
|
||||
len = min(maxLen, len+spd);
|
||||
ObjLaser_SetLength(damager, len);
|
||||
//ObjShot_SetIntersectionLine(damager, ObjMove_GetX(obj), ObjMove_GetY(obj)+yoff, ObjMove_GetX(obj), -len, 128*width);
|
||||
MakeLaserGfxFrame;
|
||||
yield;
|
||||
|
||||
}
|
||||
|
||||
// This laser isn't deleted just yet. I let it fly away first.
|
||||
// This value lets other tasks check when this happens.
|
||||
Obj_SetValue(damager, "DEL", true);
|
||||
|
||||
// Laser is now leaving
|
||||
ObjMove_SetAngle(damager, ObjStLaser_GetAngle(damager));
|
||||
ObjMove_SetSpeed(damager, spd);
|
||||
while(!Obj_IsDeleted(damager) && len > 128){
|
||||
MakeLaserGfxFrame;
|
||||
len=max(0,len-spd);
|
||||
ObjLaser_SetLength(damager, len);
|
||||
CheckLaserIntersection;
|
||||
yield;
|
||||
}
|
||||
Obj_Delete(damager);
|
||||
|
||||
function MakeLaserGfxFrame(){
|
||||
//let hyper=0;
|
||||
|
||||
// Values related to graphic lengths
|
||||
|
||||
let gLen = max(0, len-32-24);
|
||||
let gLen2 = max(0, len-32);
|
||||
|
||||
// add sprites to the per-frame sprite list
|
||||
|
||||
// KEV: Function reference: PLaserGfxFrameLaser(gfxObj, u, v, u2, v2, ry, x, y, ang, sx, sy, rd, gn, bl, al)
|
||||
|
||||
//KEV: Function description:
|
||||
|
||||
//Adds a vertex to the attached gfxObj sprite list. Uses u, v, u2, v2 as coordinates for the SourceRect, ry for DestRect (rx is calculated in the function), x & y for vertex position, sx & sy for the scaling, rd, gn and bl for colors, and al for alpha.
|
||||
|
||||
//PLaserGfxFrame is similar but is used for the base and tip of the laser. The ry (and by extension rx) parameters are removed.
|
||||
|
||||
//(rd, gn, bl values have been removed)
|
||||
|
||||
// ObjStLaser_SetEndGraphic (ph3sx) may come in handy for the base/tips.
|
||||
|
||||
// After reaching the bottom rect, value loops back to the top.
|
||||
|
||||
PLaserGfxFrameLaser(lasGfxObj[0], 512, scroll, 1024, scroll*512, 64, ObjMove_GetX(damager)+cosine*24, ObjMove_GetY(damager)+sine*24, ang+90, vwidth*rand(1.0, 1.05), gLen/64, 255);
|
||||
|
||||
PLaserGfxFrameLaser(lasGfxObj[1], 512, scroll, 1024, scroll*512, 64, ObjMove_GetX(damager)+cosine*24, ObjMove_GetY(damager)+sine*24, ang+90, vwidth*rand(1.4, 1.5), gLen/64, 60); // Glow effect
|
||||
|
||||
PLaserGfxFrame(lasGfxObj[2], 512, 768, 1024, 1280, ObjMove_GetX(damager)+cosine*24, ObjMove_GetY(damager)+sine*24-20, ang+90, 1.15*vwidth+rand(0.2, 0.3), 1.15+rand(0.2, 0.3), 255); // Base of laser
|
||||
|
||||
PLaserGfxFrame(lasGfxObj[3], 1024, 0, 1536, 512, ObjMove_GetX(damager)+cosine*gLen2, 10+ObjMove_GetY(damager)+sine*gLen2, ang+90, 0.6*width+rand(0.2, 0.3), 0.8, 255);// Tip of laser
|
||||
|
||||
ObjRender_SetAngleZ(lasGfxObj[2], ObjRender_GetAngleZ(lasGfxObj[2])+10);
|
||||
//WriteLog([ObjMove_GetX(damager), ObjMove_GetY(damager)]);
|
||||
|
||||
scroll += 0.05; // Scrolls the laser's graphic.
|
||||
if (scroll >= 1) {scroll = 0.1;}
|
||||
|
||||
}
|
||||
|
||||
function CheckLaserIntersection(){
|
||||
// ------------------ Check for enemy collisions ------------------
|
||||
let enemies=ObjCol_GetListOfIntersectedEnemyID(damager); // Get enemy array
|
||||
let closest=[];
|
||||
let arrayLen=length(enemies);
|
||||
// Check all enemies hit (if any)
|
||||
if(arrayLen>0){
|
||||
let enm_pos=[]; // will be a 2-dimensional array
|
||||
|
||||
// KEV: If there is no strong/weak laser differentiation, this ascent loop can be removed entirely(?)
|
||||
|
||||
ascent(i in 0..arrayLen){ // go through the enemies list
|
||||
// Weaker lasers get pushed back by "popcorn" enemies.
|
||||
|
||||
// KEV: I don't really want to implement strong/weak laser differentiations...
|
||||
|
||||
if(ObjEnemy_GetInfo(enemies[i], INFO_LIFE) > 1){
|
||||
// There are multiple collisions per enemy to check as well
|
||||
// It's rare that there's more than one, but it's allowed
|
||||
|
||||
let pos=GetEnemyIntersectionPositionByIdA1(enemies[i]); // KEV: Returns the multiple hitboxes of the enemy as a 2D array, format is [index][x, y of hitbox].
|
||||
|
||||
//KEV: Further explanation (rough and probably incorrect);
|
||||
|
||||
//An enemy has 2 hitboxes, one at coords [16, 16] and one at [32, 32].
|
||||
|
||||
//You get a 2D array named "coords" containing the coordinates of these 2 hitboxes by using GetEnemyIntersectionPositionByIdA1.
|
||||
|
||||
//You then write this line "float num = coords[0][1];" and WriteLog() the value of num.
|
||||
|
||||
//coords[0][1] corresponds to the y coordinate of the first hitbox, which would give you a num value of 16.
|
||||
|
||||
let closest2=GetClosestCoord(pos, ObjMove_GetX(damager),ObjMove_GetY(damager));
|
||||
if(closest2[0]!=-1234){
|
||||
enm_pos=enm_pos~[closest2];
|
||||
}
|
||||
}
|
||||
}
|
||||
closest = GetClosestCoord(enm_pos, ObjMove_GetX(damager),ObjMove_GetY(damager));
|
||||
}
|
||||
// ------------------ ------------------ ------------------
|
||||
|
||||
// There has been a collision, dial back laser length to (roughly) the point of collision.
|
||||
// (Roughly) because we can't get the exact location, and doing it ourselves requires finding the hitbox dimensions.
|
||||
|
||||
// KEV: Getting the hitbox dimensions/locations should be perfectly possible with ph3sx's intersection-obtaining functions. Will need re-examining
|
||||
|
||||
// Set the damage of the laser.
|
||||
|
||||
float dmgBase = 12;
|
||||
float dmgMax = 12;
|
||||
|
||||
if(length(closest) > 0){
|
||||
let dist=closest[2]-16;
|
||||
len=max(0,dist);
|
||||
|
||||
// The laser deals higher damage the closer it is to the enemy.
|
||||
|
||||
float ratioDist = 120/closest[2];
|
||||
|
||||
ObjShot_SetDamage(damager, Interpolate_Decelerate(dmgBase, dmgMax, min(1, ratioDist)));
|
||||
|
||||
// The laser changes colours depending on distance.
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} // NonPenetrationLaser
|
||||
|
||||
|
||||
let lasGfxObj=[]; // KEV: An array that will contain three sprite lists, rendering three different parts of the laser (base, body, tip).
|
||||
|
||||
// KEV: Creates the sprite lists, assigns the texture to them, and adds them as indexes into lasGfxObj.
|
||||
|
||||
task InitPLaserGfx(){
|
||||
|
||||
let imgLaser = GetCurrentScriptDirectory() ~ "./playerlib/Chimata_Sheet.png";
|
||||
|
||||
LoadTextureEx(imgLaser, true, true); // Loaded in main script
|
||||
|
||||
ascent(i in 0..4){
|
||||
let gfx = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
|
||||
ObjSpriteList2D_SetAutoClearVertexCount(gfx, true);
|
||||
ObjPrim_SetTexture(gfx, imgLaser);
|
||||
Obj_SetRenderPriorityI(gfx, 41);
|
||||
lasGfxObj = lasGfxObj~[gfx];
|
||||
//ObjRender_SetBlendType(lasGfxObj[i-1], BLEND_ADD_ARGB);
|
||||
}
|
||||
|
||||
async{
|
||||
while(length(lasGfxObj) >= 3){
|
||||
ObjRender_SetAngleZ(lasGfxObj[2], ObjRender_GetAngleZ(lasGfxObj[2])+10);
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
//ObjRender_SetBlendType(lasGfxObj[2], BLEND_ADD_ARGB);
|
||||
Obj_SetRenderPriorityI(lasGfxObj[2], 42);
|
||||
|
||||
}
|
||||
|
||||
task RemovePLaserGfx{
|
||||
let imgLaser = GetCurrentScriptDirectory() ~ "laser_fx.png";
|
||||
RemoveTexture(imgLaser);
|
||||
|
||||
ascent(i in 0..length(lasGfxObj)){
|
||||
Obj_Delete(lasGfxObj[i]);
|
||||
lasGfxObj[i]=ID_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
// See the non-penetrating laser object task for information on these tasks.
|
||||
|
||||
task PLaserGfxFrame(
|
||||
int gfxObj,
|
||||
float rectLeft, float rectTop, float rectRight, float rectBottom,
|
||||
float posX, float posY,
|
||||
float ang,
|
||||
float scaleX, float scaleY,
|
||||
float alpha){
|
||||
|
||||
if(gfxObj==ID_INVALID){return;}
|
||||
|
||||
//ObjRender_SetBlendType(gfxObj, BLEND_ADD_ARGB);
|
||||
ObjRender_SetPosition(gfxObj, posX, posY, 0);
|
||||
ObjRender_SetAngleZ(gfxObj, ang);
|
||||
ObjRender_SetScaleXYZ(gfxObj, scaleX, scaleY, 1);
|
||||
ObjSpriteList2D_SetSourceRect(gfxObj, rectLeft, rectTop, rectRight, rectBottom);
|
||||
ObjSpriteList2D_SetDestCenter(gfxObj);
|
||||
ObjSpriteList2D_AddVertex(gfxObj);
|
||||
ObjRender_SetAlpha(gfxObj, alpha);
|
||||
|
||||
}
|
||||
|
||||
task PLaserGfxFrameLaser(
|
||||
int gfxObj,
|
||||
float rectLeft, float rectTop, float rectRight, float rectBottom,
|
||||
float destY,
|
||||
float posX, float posY,
|
||||
float ang,
|
||||
float scaleX, float scaleY,
|
||||
float alpha){
|
||||
|
||||
if(gfxObj==ID_INVALID){return;}
|
||||
|
||||
//ObjRender_SetBlendType(gfxObj, BLEND_ADD_ARGB);
|
||||
ObjRender_SetPosition(gfxObj, posX, posY,0);
|
||||
ObjRender_SetAngleZ(gfxObj, ang);
|
||||
ObjRender_SetScaleXYZ(gfxObj, scaleX, scaleY, 1);
|
||||
ObjRender_SetAlpha(gfxObj, alpha);
|
||||
ObjSpriteList2D_SetSourceRect(gfxObj, rectLeft, rectTop, rectRight, rectBottom);
|
||||
let destX = (rectRight - rectLeft)/2;
|
||||
ObjSpriteList2D_SetDestRect(gfxObj, -destX, 0, destX, -destY);
|
||||
ObjSpriteList2D_AddVertex(gfxObj);
|
||||
|
||||
}
|
634
script/player/Chimata/Chimata_Main.dnh
Normal file
634
script/player/Chimata/Chimata_Main.dnh
Normal file
|
@ -0,0 +1,634 @@
|
|||
#TouhouDanmakufu[Player]
|
||||
#ScriptVersion[3]
|
||||
#ID["Flandre"]
|
||||
#Title["Flandre"]
|
||||
#Text["E"]
|
||||
|
||||
//#Image["./mariremi_lib/mariremi_illust.png"]
|
||||
|
||||
#ReplayName["Flandre"]
|
||||
|
||||
#include "script/KevinSystem/kevin_system/Lib_Const.dnh"
|
||||
|
||||
#include "script/KevinSystem/Kevin_PlayerLib.txt"
|
||||
#include "script/KevinSystem/PlayerSoundLib.dnh"
|
||||
|
||||
#include "./Chimata_Function.dnh"
|
||||
#include "./Chimata_ShotConst.dnh"
|
||||
|
||||
#include "script/KevinSystem/kevin_system/Kevin_ItemConst.txt"
|
||||
#include "script/KevinSystem/kevin_system/Kevin_ItemLib.txt"
|
||||
|
||||
float shotDamage = 2.4+(GetCommonData("Rank", 1)*0.3);
|
||||
float shotScale = 0.6+(GetCommonData("Rank", 1)*0.125);
|
||||
float shotSpeed = 50+(GetCommonData("Rank", 1)*1.5);
|
||||
|
||||
let csd = GetCurrentScriptDirectory();
|
||||
|
||||
// Global Variables
|
||||
|
||||
float maxX = GetStgFrameWidth();
|
||||
float maxY = GetStgFrameHeight();
|
||||
|
||||
// Images & Sound
|
||||
|
||||
let teamimg = csd ~ "./playerlib/Flan_Sheet.png";
|
||||
LoadTextureEx(teamimg, true, true);
|
||||
//ObjRender_SetTextureFilterMip(teamimg, FILTER_LINEAR);
|
||||
|
||||
let sndpath = csd ~ "./sound";
|
||||
|
||||
// Other stuff
|
||||
|
||||
float playerX = 0;
|
||||
float playerY = 0;
|
||||
|
||||
let objPlayer = GetPlayerObjectID();
|
||||
int plrender = Obj_GetRenderPriorityI(objPlayer);
|
||||
|
||||
bool ripplayer = false;
|
||||
float shotspeed = 0;
|
||||
float bombrand = 0;
|
||||
|
||||
bool bombenable = false;
|
||||
bool focusactive = false;
|
||||
bool ishoming = false;
|
||||
|
||||
bool isChain = false;
|
||||
|
||||
int[] _enemyArray = []; // Prepare an array to store enemy IDs for Kouda's homing shot
|
||||
int[] _existArray = [];
|
||||
int[] _shotArray = [];
|
||||
|
||||
int grazecounter = 0; // For basic graze = PIV mechanic
|
||||
|
||||
int shotAlpha = (GetAreaCommonData("Config", "PlayerShotOpacity", 60)*0.01)*255;
|
||||
float[] PlayerSpd = [15.5, 7.5];
|
||||
|
||||
// Custom events for scoring mechanic
|
||||
|
||||
const EV_PIV_100 = EV_USER + 100i; // Normal enemies and nons
|
||||
const EV_PIV_250 = EV_USER + 101i; // Spells
|
||||
const EV_PIV_500 = EV_USER + 102i; // Last Spells
|
||||
const EV_PIV_2000 = EV_USER + 103i; // What.
|
||||
|
||||
@Initialize{
|
||||
|
||||
if(!IsCommonDataAreaExists("PIV")){
|
||||
CreateCommonDataArea("PIV");
|
||||
SetAreaCommonData("PIV", "currentvalue", 10000);
|
||||
SetAreaCommonData("PIV", "ChainAmount", 1);
|
||||
}
|
||||
else{}
|
||||
|
||||
SetPlayerStateEndEnable(true);
|
||||
|
||||
// Stuff
|
||||
parameterrender();
|
||||
playerrender();
|
||||
Obj_SetRenderPriorityI(objPlayer, 43);
|
||||
plrender = Obj_GetRenderPriorityI(objPlayer);
|
||||
_SoundTask();
|
||||
|
||||
//SetIntersectionVisualization(true); // Debug
|
||||
|
||||
_Mechanic(ripplayer, _enemyArray, _existArray, GetStgFrameWidth(), GetStgFrameHeight(), objPlayer, GetEnemyBossSceneObjectID(), 5, 2, 80);
|
||||
_ShowChain();
|
||||
|
||||
_HitboxRender(ripplayer, objPlayer, teamimg, teamimg, 1280, 512, 1408, 640, 1536, 896, 2048, 1408, 0.3, 0.65);
|
||||
SetShotAutoDeleteClip(256, 256, 256, 256);
|
||||
|
||||
// Shot functions
|
||||
|
||||
//SetPlayerSpell(99);
|
||||
|
||||
_Countdown();
|
||||
_CAVELaser();
|
||||
_ShotType();
|
||||
//UniversalAlphaHandle(_shotArray);
|
||||
|
||||
// Shot data loading
|
||||
LoadPlayerShotData(csd ~ "./Chimata_ShotData.dnh");
|
||||
}
|
||||
|
||||
@MainLoop{
|
||||
_enemyArray = GetIntersectionRegistedEnemyID;
|
||||
shotspeed += 1; // Managing the shot rate
|
||||
//_shotArray = GetAllShotID(TARGET_PLAYER);
|
||||
//UniversalAlphaHandle(_shotArray);
|
||||
playerX = ObjMove_GetX(objPlayer);
|
||||
playerY = ObjMove_GetY(objPlayer);
|
||||
yield;
|
||||
}
|
||||
|
||||
@Event{
|
||||
alternative(GetEventType)
|
||||
|
||||
// Delete effect
|
||||
case(EV_DELETE_SHOT_PLAYER){
|
||||
|
||||
if(GetCommonDataPtr(EFFECTCUT_PTR, 0) >= 3){}
|
||||
|
||||
else{
|
||||
let graphic = GetEventArgument(2);
|
||||
float[] position = GetEventArgument(1);
|
||||
let obj = CreatePlayerShotA1(position[0], position[1], 0, ObjMove_GetAngle(GetEventArgument(0)), 0, 99999, graphic);
|
||||
ObjShot_SetIntersectionEnable(obj, false); _DeleteEffect(obj, shotScale);
|
||||
}
|
||||
//if(graphic == ELECTRIC_FIRE_ALT) {_DeleteEffectAlt(obj);}
|
||||
//else{_DeleteEffect(obj);}
|
||||
}
|
||||
|
||||
// PIV-item spawning events
|
||||
case(EV_PIV_100){
|
||||
let arg = GetEventArgument(0);
|
||||
CreatePIVItem(PIV_100, arg[0], arg[1]);
|
||||
}
|
||||
|
||||
case(EV_PIV_250){
|
||||
let arg = GetEventArgument(0);
|
||||
CreatePIVItem(PIV_250, arg[0], arg[1]);
|
||||
}
|
||||
|
||||
case(EV_PIV_500){
|
||||
let arg = GetEventArgument(0);
|
||||
CreatePIVItem(PIV_500, arg[0], arg[1]);
|
||||
}
|
||||
|
||||
// Basic functionality events
|
||||
case(EV_REQUEST_SPELL){
|
||||
let bomb = GetPlayerSpell();
|
||||
|
||||
if (bomb >= 1){
|
||||
SetScriptResult(true);
|
||||
SetPlayerSpell(bomb - 1);
|
||||
_Bomb();
|
||||
SetCommonData("Rank", max(1, GetCommonData("Rank", 1)-1));
|
||||
_SigilCall(false, teamimg, 768+256, 512, 768+512, 768, objPlayer, GetPlayerInvincibilityFrame());
|
||||
}
|
||||
|
||||
else {
|
||||
SetScriptResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
case(EV_HIT){
|
||||
ObjSound_Play(PlayerHit);
|
||||
_DeathbombWarning(teamimg, [1536, 384, 1536+512, 384+512], 15, 0.75);
|
||||
}
|
||||
|
||||
case(EV_CHAIN_MAX){
|
||||
|
||||
if(!isChain){
|
||||
ObjSound_Play(Shine);
|
||||
isChain = true;
|
||||
}
|
||||
else{}
|
||||
|
||||
}
|
||||
|
||||
case(EV_CHAIN_RELEASE){
|
||||
|
||||
}
|
||||
|
||||
case(EV_CHAIN_END){
|
||||
SetAreaCommonData("PIV", "ChainAmount", 1);
|
||||
isChain = false;
|
||||
}
|
||||
|
||||
case(EV_PLAYER_SHOOTDOWN){
|
||||
ObjSound_Play(PlayerDie2);
|
||||
BombRefund();
|
||||
ripplayer = true;
|
||||
DeleteShotAll(TYPE_SHOT, TYPE_ITEM);
|
||||
SetCommonData("Rank", max(1, round(GetCommonData("Rank", 1)/2)));
|
||||
_SigilCall(true, teamimg, 768, 512, 768+256, 768, objPlayer, 60);
|
||||
}
|
||||
|
||||
case(EV_PLAYER_REBIRTH){
|
||||
ripplayer = false;
|
||||
SetPlayerInvincibilityFrame(180);
|
||||
//_Countdown();
|
||||
_SigilCall(false, teamimg, 768+256, 512, 768+512, 768, objPlayer, 150);
|
||||
|
||||
}
|
||||
|
||||
case(EV_GRAZE){
|
||||
grazecounter += GetEventArgument(0);
|
||||
ObjSound_Play(Graze);
|
||||
while(grazecounter >= 10){
|
||||
SetAreaCommonData("PIV", "currentvalue", GetAreaCommonData("PIV", "currentvalue")+10);
|
||||
grazecounter -= 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Finalize{
|
||||
|
||||
}
|
||||
|
||||
// Homing
|
||||
task BombRefund(){
|
||||
SetPlayerSpell(GetPlayerSpell()+[1, 2, 3, 3][clamp((GetCommonData("Rank", 1)/2)-1, 0, 3)]);
|
||||
}
|
||||
|
||||
task _SwingBehaviour(target){
|
||||
float ang = 0;
|
||||
Obj_SetRenderPriorityI(target, 42);
|
||||
while(true){
|
||||
ObjRender_SetAngleZ(target, 0+20*sin(ang));
|
||||
ang += 360/120;
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
task _ShotType(){
|
||||
|
||||
_Option(125, 0, 0, 1);
|
||||
_Option(125, 90, 0, 1);
|
||||
_Option(125, 180, 0, 1);
|
||||
_Option(125, 270, 0, 1);
|
||||
|
||||
// Rank
|
||||
|
||||
while(true){
|
||||
|
||||
shotDamage = 2.4+(GetCommonData("Rank", 1)*0.2);
|
||||
shotScale = 0.6+(GetCommonData("Rank", 1)*0.1);
|
||||
shotSpeed = 50+(GetCommonData("Rank", 1)*2);
|
||||
|
||||
wait(30);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function _Option(dist, 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, 0.25, true, 1);
|
||||
ObjRender_SetBlendType(shot, BLEND_ALPHA);
|
||||
ObjRender_SetAlpha(shot, 255);
|
||||
Obj_SetRenderPriorityI(shot, plrender-1);
|
||||
|
||||
// Handles the spinning and shooting of the options.
|
||||
async{
|
||||
|
||||
//SetShotAutoDeleteClip(-500, 128, -500, -500);
|
||||
|
||||
//int i = 0;
|
||||
|
||||
loop{
|
||||
|
||||
float shotx = ObjMove_GetX(shot);
|
||||
float 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_SHOT) != KEY_FREE){
|
||||
|
||||
let water = CreatePlayerShotA1(shotx, shoty, 50, 270, 4, 1.5, FIRE);
|
||||
|
||||
//let water2 = CreatePlayerShotA1(shotx+25, shoty, 15, shotang+180, 1.82, 1.25, KEV_OPTIONSHOT);
|
||||
|
||||
ObjShot_SetAutoDelete(water, false);
|
||||
|
||||
ObjRender_SetAlpha(water, shotAlpha);
|
||||
|
||||
_HandleDeletion(water);
|
||||
|
||||
_BulletRescalePlayer(water, shotScale, true, 1);
|
||||
|
||||
//ObjMove_SetAngularVelocity(water, [0, 0.2][typeGun]);
|
||||
//ObjMove_SetAngularVelocity(water2, [0, 0.2][typeGun]);
|
||||
|
||||
Obj_SetRenderPriorityI(water, plrender-1);
|
||||
|
||||
ObjSound_Play(Base2);
|
||||
}
|
||||
shotspeedhome++;
|
||||
//counter;
|
||||
}
|
||||
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
task _HandleDeletion(int target){
|
||||
|
||||
while(ObjMove_GetY(target) > -128){
|
||||
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.5*counterspin;
|
||||
|
||||
ObjMove_SetPosition(dummy, playerX, playerY);
|
||||
|
||||
if(GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE){
|
||||
|
||||
spaceX = max(dist*0.75, spaceX-dist*1.5/15);
|
||||
spaceY = max(dist*0.75, spaceY-dist*1.5/15);
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
spaceX = min(dist*1.5, spaceX+dist*1.5/15);
|
||||
spaceY = min(dist*1.5, spaceY+dist*1.5/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;
|
||||
|
||||
}
|
||||
|
||||
// Basic player parameters
|
||||
|
||||
task parameterrender(){
|
||||
|
||||
SetPlayerItemScope(120);
|
||||
SetPlayerLife(9); // Debug
|
||||
SetPlayerSpell(2);
|
||||
SetPlayerSpeed(PlayerSpd[0], PlayerSpd[1]); // (original: 5.25/2.0)
|
||||
SetPlayerRebirthFrame(15);
|
||||
SetPlayerDownStateFrame(60);
|
||||
SetPlayerAutoItemCollectLine(GetStgFrameHeight/3);
|
||||
SetPlayerRebirthLossFrame(0);
|
||||
ObjPlayer_AddIntersectionCircleA1(objPlayer, 0, 0, 0, 40);
|
||||
|
||||
}
|
||||
|
||||
// Renders the shottype
|
||||
// Player sprites
|
||||
|
||||
task playerrender(){
|
||||
|
||||
// Why is this movement code so cursed jesus fucking christ
|
||||
|
||||
float scale = 0.4; // Scalies
|
||||
int frame = 0;
|
||||
|
||||
ObjPrim_SetTexture(objPlayer, teamimg);
|
||||
ObjSprite2D_SetSourceRect(objPlayer, 0, 0, 512, 384);
|
||||
ObjSprite2D_SetDestCenter(objPlayer);
|
||||
Obj_SetRenderPriorityI(objPlayer, 42);
|
||||
//ObjRender_SetTextureFilterMin(objPlayer, FILTER_ANISOTROPIC);
|
||||
ObjRender_SetScaleXYZ(objPlayer, scale, scale, 1);
|
||||
|
||||
// Lower "speed" parameter = FASTER SPEED
|
||||
|
||||
// FOR WHEN ONLY IDLE SPRITES ARE DONE
|
||||
|
||||
loop{
|
||||
//frame++;
|
||||
_RenderPlayerMovement(objPlayer, frame, 0, 0, 512, 384, scale, 4, 6);
|
||||
//if (frame >= (1*4-1)){frame = 0;}
|
||||
yield;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
task PointblankPlacebo(target, scale, multiplier){
|
||||
int len = 10;
|
||||
while(GetObjectDistance(target, objPlayer) < 90){
|
||||
_BulletRescalePlayer(target, scale*multiplier, true, multiplier); // Pointblank
|
||||
yield;
|
||||
}
|
||||
ascent(i in 0..len){
|
||||
_BulletRescalePlayer(target, Interpolate_Decelerate(scale*multiplier, scale, i/len), true, Interpolate_Decelerate(multiplier, 1, i/len));
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
task Fadein(target, len){
|
||||
ascent(i in 0..len){
|
||||
_BulletRescalePlayer(target, Interpolate_Decelerate(0.4, 0.7, i/len), true, Interpolate_Decelerate(0.4, 0.7, i/len));
|
||||
//ObjRender_SetBlendType(target, BLEND_ADD_ARGB);
|
||||
yield;
|
||||
}
|
||||
ObjRender_SetBlendType(target, BLEND_ALPHA);
|
||||
}
|
||||
|
||||
task Fadein(target, len, targetscale, targetscalehitbox){
|
||||
ascent(i in 0..len){
|
||||
_BulletRescalePlayer(target, Interpolate_Decelerate(0.1, targetscale, i/len), true, Interpolate_Decelerate(1, targetscalehitbox, i/len));
|
||||
//ObjRender_SetBlendType(target, BLEND_ADD_ARGB);
|
||||
yield;
|
||||
}
|
||||
ObjRender_SetBlendType(target, BLEND_ALPHA);
|
||||
}
|
||||
|
||||
// Handling of bomb
|
||||
|
||||
task _Bomb(){
|
||||
|
||||
// Preparation
|
||||
|
||||
SetAreaCommonData("ChainChecks", "IsChaining", true);
|
||||
|
||||
SetForbidPlayerShot(true);
|
||||
SetForbidPlayerSpell(true);
|
||||
SetPlayerInvincibilityFrame(270);
|
||||
// Spell object
|
||||
let manageObj = GetSpellManageObject(); // SPELL BEGINS
|
||||
ObjSpell_Regist(manageObj);
|
||||
//ObjSound_Play(bombsfx);
|
||||
SetPlayerSpeed(PlayerSpd[0]*2, PlayerSpd[1]*2);
|
||||
|
||||
// 180 seconds DEATH LASER
|
||||
|
||||
//SetCommonData("IsBomb", true);
|
||||
|
||||
//_Countdown(270);
|
||||
|
||||
async{
|
||||
loop(90){
|
||||
Fire();
|
||||
Fire();
|
||||
wait(2);
|
||||
}
|
||||
}
|
||||
|
||||
function Fire(){
|
||||
let shotA = CreatePlayerShotA1(playerX, playerY, 25, rand(-15, 195), shotDamage/2, 25, FIRE);
|
||||
_BulletRescalePlayer(shotA, 1.25, true, 1);
|
||||
ObjRender_SetAlpha(shotA, 255);
|
||||
Fading(shotA);
|
||||
ObjRender_SetBlendType(shotA, BLEND_ADD_ARGB);
|
||||
Obj_SetRenderPriorityI(shotA, 41);
|
||||
ObjShot_SetPenetrateShotEnable(shotA, false);
|
||||
//ObjShot_SetEnemyIntersectionInvalidFrame(shotA, 5); // CURRENTLY BUGGED AS OF PH3SX 1.32B
|
||||
ObjShot_SetSpellFactor(shotA, true);
|
||||
ObjShot_SetEraseShot(shotA, true);
|
||||
}
|
||||
|
||||
loop(30){
|
||||
if(GetVirtualKeyState(VK_SHOT) != KEY_FREE){ObjSound_Play(Fire);}
|
||||
wait(6);
|
||||
}
|
||||
|
||||
task Fading(shot){
|
||||
ObjMove_SetAcceleration(shot, -1.5);
|
||||
ObjMove_SetMaxSpeed(shot, 3);
|
||||
ascent(i in 0..40){
|
||||
ObjRender_SetAlpha(shot, Interpolate_Decelerate(255, 0, i/40));
|
||||
yield;
|
||||
}
|
||||
Obj_Delete(shot);
|
||||
}
|
||||
|
||||
SetPlayerSpeed(PlayerSpd[0], PlayerSpd[1]);
|
||||
SetForbidPlayerShot(false);
|
||||
Obj_Delete(manageObj); // !!! IMPORTANT !!!
|
||||
|
||||
SetAreaCommonData("ChainChecks", "IsChaining", false);
|
||||
NotifyEventOwn(EV_CHAIN_END, 0);
|
||||
|
||||
wait(60);
|
||||
SetForbidPlayerSpell(false);
|
||||
|
||||
}
|
||||
|
||||
// Screenshake function for bomb's duration - adapted from Sparen's tutorials
|
||||
|
||||
task _Countdown(){
|
||||
|
||||
//int timer = time;
|
||||
int counter = CreateTextObject(
|
||||
playerX, playerY, 58,
|
||||
"", "Origami Mommy",
|
||||
0xFFFFFF, 0xFFFFFF,
|
||||
0x1AEC8C, 10,
|
||||
Obj_GetRenderPriorityI(objPlayer)+1
|
||||
);
|
||||
|
||||
ObjText_SetHorizontalAlignment(counter, ALIGNMENT_CENTER);
|
||||
|
||||
while(true){
|
||||
|
||||
if(GetPlayerInvincibilityFrame() <= 0){Obj_SetVisible(counter, false);}
|
||||
else{Obj_SetVisible(counter, true);}
|
||||
ObjRender_SetPosition(counter, playerX, playerY - 140, 1);
|
||||
ObjText_SetText(counter, IntToString(GetPlayerInvincibilityFrame()));
|
||||
yield;
|
||||
|
||||
}
|
||||
|
||||
//Obj_Delete(counter);
|
||||
|
||||
}
|
||||
|
||||
task _BombShake(shaketime, intensity){
|
||||
|
||||
float baseintensity = intensity;
|
||||
float shakeno = shaketime;
|
||||
|
||||
ascent(i in 0..shakeno){
|
||||
Set2DCameraFocusX(GetStgFrameWidth/2 + rand(-intensity, intensity));
|
||||
Set2DCameraFocusY(GetStgFrameHeight/2 + rand(-intensity, intensity));
|
||||
intensity = Interpolate_Decelerate(0, baseintensity, 1-i/shakeno);
|
||||
shaketime--;
|
||||
yield;
|
||||
}
|
||||
|
||||
while(shaketime > 0){yield;}
|
||||
|
||||
Set2DCameraFocusX(GetStgFrameWidth/2);
|
||||
Set2DCameraFocusY(GetStgFrameHeight/2);
|
||||
yield;
|
||||
}
|
||||
|
||||
function CreateTextObject(
|
||||
float mx, my, size,
|
||||
string text, font,
|
||||
int colorTop, colorBottom,
|
||||
int borderColor, borderWidth,
|
||||
int renderPriority
|
||||
){
|
||||
|
||||
let obj = ObjText_Create();
|
||||
ObjText_SetText(obj, text);
|
||||
ObjText_SetFontSize(obj, size);
|
||||
ObjText_SetFontType(obj, font);
|
||||
ObjText_SetFontColorTop(obj, colorTop);
|
||||
ObjText_SetFontColorBottom(obj, colorBottom);
|
||||
ObjText_SetFontBorderType(obj, BORDER_FULL);
|
||||
ObjText_SetFontBorderColor(obj, borderColor);
|
||||
ObjText_SetFontBorderWidth(obj, borderWidth);
|
||||
Obj_SetRenderPriorityI(obj, renderPriority);
|
||||
ObjRender_SetX(obj, mx);
|
||||
ObjRender_SetY(obj, my);
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
9
script/player/Chimata/Chimata_ShotConst.dnh
Normal file
9
script/player/Chimata/Chimata_ShotConst.dnh
Normal file
|
@ -0,0 +1,9 @@
|
|||
let current = GetCurrentScriptDirectory();
|
||||
let path = current ~ "Chimata_ShotData.dnh";
|
||||
LoadPlayerShotData(path);
|
||||
// -----
|
||||
|
||||
const FIRE = 1;
|
||||
const OPTION = 2;
|
||||
|
||||
|
30
script/player/Chimata/Chimata_ShotData.dnh
Normal file
30
script/player/Chimata/Chimata_ShotData.dnh
Normal file
|
@ -0,0 +1,30 @@
|
|||
shot_image = "./playerlib/Flan_Sheet.png"
|
||||
|
||||
ShotData{
|
||||
id = 0 // Dummy
|
||||
rect = (0,0,0,0)
|
||||
render = ALPHA
|
||||
alpha = 0
|
||||
collision = 32
|
||||
}
|
||||
|
||||
// Fire
|
||||
|
||||
ShotData{
|
||||
id = 1
|
||||
rect = (1024, 0, 1152, 256)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
collision = 128 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
||||
|
||||
// Option
|
||||
|
||||
ShotData{
|
||||
id = 2
|
||||
rect = (512, 0, 1024, 384)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
fixed_angle = true
|
||||
collision = 0 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
0
script/player/Chimata/desc.txt
Normal file
0
script/player/Chimata/desc.txt
Normal file
BIN
script/player/Chimata/playerlib/Chimata_Sheet.png
Normal file
BIN
script/player/Chimata/playerlib/Chimata_Sheet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1 MiB |
BIN
script/player/Chimata/playerlib/Flan_Sheet.png
Normal file
BIN
script/player/Chimata/playerlib/Flan_Sheet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 640 KiB |
BIN
script/player/Chimata/playerlib/Sheet.mdp
Normal file
BIN
script/player/Chimata/playerlib/Sheet.mdp
Normal file
Binary file not shown.
BIN
script/player/Chimata/playerlib/Sheet2.mdp
Normal file
BIN
script/player/Chimata/playerlib/Sheet2.mdp
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/CK Music Factory/air01.wav
Normal file
BIN
script/player/Chimata/sound/CK Music Factory/air01.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/CK Music Factory/air02.wav
Normal file
BIN
script/player/Chimata/sound/CK Music Factory/air02.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/CK Music Factory/laser01.wav
Normal file
BIN
script/player/Chimata/sound/CK Music Factory/laser01.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/CK Music Factory/slash01.wav
Normal file
BIN
script/player/Chimata/sound/CK Music Factory/slash01.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/CK Music Factory/wind01.wav
Normal file
BIN
script/player/Chimata/sound/CK Music Factory/wind01.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/TAM Music Factory/se04.wav
Normal file
BIN
script/player/Chimata/sound/TAM Music Factory/se04.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/TAM Music Factory/status4.wav
Normal file
BIN
script/player/Chimata/sound/TAM Music Factory/status4.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/TAM Music Factory/tama2.wav
Normal file
BIN
script/player/Chimata/sound/TAM Music Factory/tama2.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/bfxr_scythecall.wav
Normal file
BIN
script/player/Chimata/sound/bfxr_scythecall.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/bfxr_splash.wav
Normal file
BIN
script/player/Chimata/sound/bfxr_splash.wav
Normal file
Binary file not shown.
1
script/player/Chimata/sound/bfxr_teleporthigh.wav
Normal file
1
script/player/Chimata/sound/bfxr_teleporthigh.wav
Normal file
|
@ -0,0 +1 @@
|
|||
2,0.57,,0.3442,,0.2691,0.3,0.2179,,0.3445,,,,,,,,,,,0.2992,,0.5139,,,1,,,,,,,masterVolume
|
BIN
script/player/Chimata/sound/bfxr_teleportlow.wav
Normal file
BIN
script/player/Chimata/sound/bfxr_teleportlow.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/bfxr_watershoot.wav
Normal file
BIN
script/player/Chimata/sound/bfxr_watershoot.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/birdcall05.wav
Normal file
BIN
script/player/Chimata/sound/birdcall05.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/hit01.wav
Normal file
BIN
script/player/Chimata/sound/hit01.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/laser01.wav
Normal file
BIN
script/player/Chimata/sound/laser01.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/magic21.wav
Normal file
BIN
script/player/Chimata/sound/magic21.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/retrolaser.wav
Normal file
BIN
script/player/Chimata/sound/retrolaser.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/slash01.wav
Normal file
BIN
script/player/Chimata/sound/slash01.wav
Normal file
Binary file not shown.
BIN
script/player/Chimata/sound/tama2.wav
Normal file
BIN
script/player/Chimata/sound/tama2.wav
Normal file
Binary file not shown.
415
script/player/Kouryuu/Player_Function.dnh
Normal file
415
script/player/Kouryuu/Player_Function.dnh
Normal file
|
@ -0,0 +1,415 @@
|
|||
#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
|
232
script/player/Kouryuu/Player_Function_Laser.dnh
Normal file
232
script/player/Kouryuu/Player_Function_Laser.dnh
Normal file
|
@ -0,0 +1,232 @@
|
|||
|
||||
// Particle list for laser effect
|
||||
|
||||
int LaserEffect = ObjParticleList_Create(OBJ_PARTICLE_LIST_2D);
|
||||
int[] rect = [704, 192, 768, 256];
|
||||
|
||||
ObjPrim_SetTexture(LaserEffect, "script/player/Kouryuu/playerlib/PlSheet_Kouryuu.png");
|
||||
|
||||
Obj_SetRenderPriorityI(LaserEffect, 41);
|
||||
ObjPrim_SetPrimitiveType(LaserEffect, PRIMITIVE_TRIANGLELIST);
|
||||
ObjPrim_SetVertexCount(LaserEffect, 4);
|
||||
|
||||
ObjRender_SetBlendType(LaserEffect, BLEND_ADD_ARGB);
|
||||
|
||||
// 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(1, 0.5, 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);
|
||||
|
||||
float scaleXBoost = 0;
|
||||
float scaleXBoostMax = 0.05;
|
||||
float ang = 180;
|
||||
|
||||
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{
|
||||
|
||||
if(GetVirtualKeyState(VK_SHOT) != 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+scaleXBoost, ObjRender_GetScaleX(lasersprite) + scaleSpeed));
|
||||
scaleXBoost = scaleXBoostMax * sin(ang);
|
||||
|
||||
ObjRender_SetAlpha(lasersprite, min(alpha, ObjRender_GetAlpha(lasersprite)+alpha/5));
|
||||
ObjRender_SetAngleZ(lasersprite, targetAng);
|
||||
ObjRender_SetPosition(lasersprite, targetx, targety, 1);
|
||||
|
||||
ang += 25;
|
||||
|
||||
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, plrender-1);
|
||||
_Follow(laser, target);
|
||||
|
||||
_LaserSpriteRender(
|
||||
plimg, laser, ang,
|
||||
256, 192, 384, 384,
|
||||
1, 20, plrender-1, shotAlpha,
|
||||
0.1
|
||||
);
|
||||
|
||||
// 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 && !ripplayer && IsPermitPlayerShot){
|
||||
|
||||
if(shotspeed % 5 == 0){
|
||||
ObjSound_Play(Base2);
|
||||
}
|
||||
|
||||
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){
|
||||
|
||||
async{
|
||||
loop{
|
||||
EnemyList = ObjCol_GetListOfIntersectedEnemyID(target);
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
// 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(6, 9));
|
||||
}
|
||||
}
|
||||
|
||||
// Damage effects
|
||||
|
||||
}
|
||||
task _Follow(follower, followed){
|
||||
|
||||
while(!Obj_IsDeleted(follower)){
|
||||
float x = ObjRender_GetX(followed);
|
||||
float y = ObjRender_GetY(followed);
|
||||
ObjMove_SetPosition(follower, x, y);
|
||||
yield;
|
||||
}
|
||||
|
||||
}
|
374
script/player/Kouryuu/Player_Main.dnh
Normal file
374
script/player/Kouryuu/Player_Main.dnh
Normal file
|
@ -0,0 +1,374 @@
|
|||
#TouhouDanmakufu[Player]
|
||||
#ScriptVersion[3]
|
||||
#ID["PL2_KOURYUU"]
|
||||
#Title["Kouryuu Eikankaku"]
|
||||
#Text["Player 2"]
|
||||
|
||||
//#Image["./mariremi_lib/mariremi_illust.png"]
|
||||
|
||||
#ReplayName["Kouryuu"]
|
||||
|
||||
#include "script/KevinSystem/kevin_system/Lib_Const.dnh"
|
||||
|
||||
#include "script/KevinSystem/Kevin_PlayerLib.txt"
|
||||
#include "script/KevinSystem/PlayerSoundLib.dnh"
|
||||
|
||||
#include "./Player_Function.dnh"
|
||||
#include "./Player_ShotConst.dnh"
|
||||
|
||||
#include "script/KevinSystem/kevin_system/Kevin_ItemConst.txt"
|
||||
#include "script/KevinSystem/kevin_system/Kevin_ItemLib.txt"
|
||||
|
||||
let csd = GetCurrentScriptDirectory();
|
||||
|
||||
|
||||
// Global Variables
|
||||
|
||||
float maxX = GetStgFrameWidth();
|
||||
float maxY = GetStgFrameHeight();
|
||||
|
||||
// Images & Sound
|
||||
|
||||
let teamimg = csd ~ "./playerlib/Player_Sheet.png";
|
||||
LoadTextureEx(teamimg, true, true);
|
||||
//ObjRender_SetTextureFilterMip(teamimg, FILTER_LINEAR);
|
||||
|
||||
let plimg = csd ~ "./playerlib/PlSheet_Kouryuu.png";
|
||||
LoadTextureEx(plimg, true, true);
|
||||
ObjRender_SetTextureFilter(plimg, FILTER_NONE, FILTER_NONE, FILTER_NONE);
|
||||
|
||||
let sndpath = csd ~ "./sound";
|
||||
|
||||
int[] _enemyArray = [];
|
||||
int[] _existArray = [];
|
||||
int[] _shotArray = [];
|
||||
|
||||
bool isChain = false;
|
||||
bool isUseSpecialWpn = false;
|
||||
float curChain = 0;
|
||||
|
||||
// Other stuff
|
||||
|
||||
float playerX = 0;
|
||||
float playerY = 0;
|
||||
|
||||
let objPlayer = GetPlayerObjectID();
|
||||
int plrender = 42;
|
||||
|
||||
bool ripplayer = false;
|
||||
float shotspeed = 0;
|
||||
float bombrand = 0;
|
||||
|
||||
int grazecounter = 0; // For basic graze = PIV mechanic
|
||||
|
||||
int shotAlpha = (GetAreaCommonData("Config", "PlayerShotOpacity", 60)*0.01)*255;
|
||||
|
||||
float shotDamageOption = 4.8;
|
||||
float shotScaleOption = 1;
|
||||
|
||||
float shotDamageLaser = 2;
|
||||
float shotScaleLaser = 1;
|
||||
|
||||
float shotDamageSpecial = 4.5;
|
||||
float shotScaleSpecial = 2;
|
||||
|
||||
float[] PlayerSpd = [15, 7.5];
|
||||
|
||||
// Custom events for scoring mechanic
|
||||
|
||||
const EV_PIV_100 = EV_USER + 100i; // Normal enemies and nons
|
||||
const EV_PIV_250 = EV_USER + 101i; // Spells
|
||||
const EV_PIV_500 = EV_USER + 102i; // Last Spells
|
||||
const EV_PIV_2000 = EV_USER + 103i; // What.
|
||||
|
||||
@Initialize{
|
||||
|
||||
if(!IsCommonDataAreaExists("PIV")){
|
||||
CreateCommonDataArea("PIV");
|
||||
SetAreaCommonData("PIV", "currentvalue", 10000);
|
||||
SetAreaCommonData("PIV", "ChainAmount", 1);
|
||||
}
|
||||
else{}
|
||||
|
||||
SetPlayerStateEndEnable(true);
|
||||
|
||||
// Stuff
|
||||
Parameter();
|
||||
RenderPlayer();
|
||||
|
||||
UpdateAng();
|
||||
BaseShot();
|
||||
InitiateOptions();
|
||||
|
||||
Obj_SetRenderPriorityI(objPlayer, 43);
|
||||
plrender = Obj_GetRenderPriorityI(objPlayer);
|
||||
_SoundTask();
|
||||
|
||||
//SetIntersectionVisualization(true); // Debug
|
||||
|
||||
_Mechanic(ripplayer, _enemyArray, _existArray, GetStgFrameWidth(), GetStgFrameHeight(), objPlayer, GetEnemyBossSceneObjectID(), 1, 2, 80);
|
||||
|
||||
_ShowChain();
|
||||
_HandleChainGauge();
|
||||
|
||||
_HitboxRender(ripplayer, objPlayer, plimg, teamimg, 768, 192, 832, 256, 1536, 896, 2048, 1408, 0.5, 0.65);
|
||||
SetShotAutoDeleteClip(256, 256, 256, 256);
|
||||
|
||||
_Countdown();
|
||||
|
||||
// Shot data loading
|
||||
LoadPlayerShotData(csd ~ "./Player_ShotData.dnh");
|
||||
}
|
||||
|
||||
@MainLoop{
|
||||
_enemyArray = GetIntersectionRegistedEnemyID;
|
||||
shotspeed += 1; // Managing the shot rate
|
||||
//_shotArray = GetAllShotID(TARGET_PLAYER);
|
||||
//UniversalAlphaHandle(_shotArray);
|
||||
plrender = Obj_GetRenderPriorityI(objPlayer);
|
||||
playerX = ObjMove_GetX(objPlayer);
|
||||
playerY = ObjMove_GetY(objPlayer);
|
||||
yield;
|
||||
}
|
||||
|
||||
@Event{
|
||||
alternative(GetEventType)
|
||||
|
||||
// Delete effect
|
||||
case(EV_DELETE_SHOT_PLAYER){
|
||||
|
||||
if(GetCommonDataPtr(EFFECTCUT_PTR, 0) >= 3){}
|
||||
|
||||
else{
|
||||
|
||||
let graphic = GetEventArgument(2);
|
||||
float[] position = GetEventArgument(1);
|
||||
|
||||
let obj = CreatePlayerShotA1(position[0], position[1], 0, ObjMove_GetAngle(GetEventArgument(0)), 0, 99999, graphic);
|
||||
|
||||
ObjShot_SetIntersectionEnable(obj, false); _DeleteEffect(obj, graphic == FIRE_SPECIAL ? 2 : 1);
|
||||
|
||||
}
|
||||
//if(graphic == ELECTRIC_FIRE_ALT) {_DeleteEffectAlt(obj);}
|
||||
//else{_DeleteEffect(obj);}
|
||||
}
|
||||
|
||||
// PIV-item spawning events
|
||||
case(EV_PIV_100){
|
||||
let arg = GetEventArgument(0);
|
||||
CreatePIVItem(PIV_100, arg[0], arg[1]);
|
||||
}
|
||||
|
||||
case(EV_PIV_250){
|
||||
let arg = GetEventArgument(0);
|
||||
CreatePIVItem(PIV_250, arg[0], arg[1]);
|
||||
}
|
||||
|
||||
case(EV_PIV_500){
|
||||
let arg = GetEventArgument(0);
|
||||
CreatePIVItem(PIV_500, arg[0], arg[1]);
|
||||
}
|
||||
|
||||
// Basic functionality events
|
||||
case(EV_REQUEST_SPELL){
|
||||
let bomb = GetPlayerSpell();
|
||||
|
||||
if (bomb >= 1){
|
||||
SetScriptResult(true);
|
||||
SetPlayerSpell(bomb - 1);
|
||||
_Bomb();
|
||||
SetCommonData("Rank", clamp(max(1, GetCommonData("Rank", 1)-0.25), GetCommonData("MinRank", 1), GetCommonData("MaxRank", 12)));
|
||||
_SigilCall(false, teamimg, 768+256, 512, 768+512, 768, objPlayer, GetPlayerInvincibilityFrame());
|
||||
}
|
||||
|
||||
else {
|
||||
SetScriptResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
case(EV_HIT){
|
||||
ObjSound_Play(PlayerHit);
|
||||
_DeathbombWarning(plimg, [832, 0, 1088, 256], 20, 3);
|
||||
}
|
||||
|
||||
case(EV_CHAIN_MAX){
|
||||
|
||||
if(!isChain){
|
||||
ObjSound_Play(Shine);
|
||||
isChain = true;
|
||||
curChain = GetCommonDataPtr(POINTER_CHAIN, 1);
|
||||
}
|
||||
else{}
|
||||
|
||||
}
|
||||
|
||||
case(EV_CHAIN_RELEASE){
|
||||
|
||||
}
|
||||
|
||||
case(EV_CHAIN_END){
|
||||
|
||||
SetAreaCommonData("PIV", "ChainAmount", 1);
|
||||
isChain = false;
|
||||
|
||||
// Increase rank depending on curChain (>= 32), then reset curChain. MAX CHAIN increases rank by 0.4.
|
||||
|
||||
if(curChain >= 32){
|
||||
SetCommonData("Rank", clamp(GetCommonData("Rank", 1) + Interpolate_Linear(0.25, 0.5, curChain/64), GetCommonData("MinRank", 1), GetCommonData("MaxRank", 12)));
|
||||
}
|
||||
|
||||
curChain = 1;
|
||||
|
||||
}
|
||||
|
||||
case(EV_PLAYER_SHOOTDOWN){
|
||||
ObjSound_Play(PlayerDie2);
|
||||
SetPlayerSpell(GetPlayerSpell()+2);
|
||||
ripplayer = true;
|
||||
DeleteShotAll(TYPE_SHOT, TYPE_ITEM);
|
||||
SetCommonData("Rank", clamp(GetCommonData("Rank", 1) * 0.75, GetCommonData("MinRank", 1), GetCommonData("MaxRank", 12)));
|
||||
_SigilCall(true, teamimg, 768, 512, 768+256, 768, objPlayer, 60);
|
||||
}
|
||||
|
||||
case(EV_PLAYER_REBIRTH){
|
||||
ripplayer = false;
|
||||
SetPlayerInvincibilityFrame(180);
|
||||
//_Countdown();
|
||||
_SigilCall(false, teamimg, 768+256, 512, 768+512, 768, objPlayer, 150);
|
||||
|
||||
}
|
||||
|
||||
case(EV_GRAZE){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Finalize{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Basic player parameters
|
||||
|
||||
task Parameter(){
|
||||
|
||||
// im trying to not be collected by the player but their item scope is dummy thicc and im alerted by its cheek
|
||||
SetPlayerItemScope(360);
|
||||
|
||||
SetPlayerLife(9); // Debug
|
||||
SetPlayerSpell(2);
|
||||
SetPlayerSpeed(PlayerSpd[0], PlayerSpd[1]); // (original: 5.25/2.0)
|
||||
SetPlayerRebirthFrame(20);
|
||||
SetPlayerDownStateFrame(60);
|
||||
SetPlayerAutoItemCollectLine(GetStgFrameHeight/3);
|
||||
SetPlayerRebirthLossFrame(0);
|
||||
ObjPlayer_AddIntersectionCircleA1(objPlayer, 0, 0, 0, 40);
|
||||
|
||||
}
|
||||
|
||||
// Player render
|
||||
|
||||
task RenderPlayer(){
|
||||
|
||||
// Why is this movement code so cursed jesus fucking christ
|
||||
|
||||
float scale = 1; // Scalies
|
||||
int frame = 0;
|
||||
|
||||
ObjPrim_SetTexture(objPlayer, plimg);
|
||||
ObjSprite2D_SetSourceRect(objPlayer, 0, 0, 128, 192);
|
||||
ObjSprite2D_SetDestCenter(objPlayer);
|
||||
Obj_SetRenderPriorityI(objPlayer, plrender);
|
||||
//ObjRender_SetTextureFilterMin(objPlayer, FILTER_ANISOTROPIC);
|
||||
ObjRender_SetScaleXYZ(objPlayer, scale, scale, 1);
|
||||
|
||||
// Lower "speed" parameter = FASTER SPEED
|
||||
|
||||
// FOR WHEN ONLY IDLE SPRITES ARE DONE
|
||||
|
||||
loop{
|
||||
frame++;
|
||||
_RenderPlayerMovement(objPlayer, frame, 0, 0, 128, 192, scale, 3, 6);
|
||||
if (frame >= (3*6-1)){frame = 0;}
|
||||
yield;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Handling of bomb
|
||||
|
||||
task _Bomb(){
|
||||
|
||||
// 180 frames
|
||||
|
||||
// Preparation
|
||||
|
||||
SetForbidPlayerShot(true);
|
||||
SetForbidPlayerSpell(true);
|
||||
SetPlayerInvincibilityFrame(180);
|
||||
// Spell object
|
||||
let manageObj = GetSpellManageObject(); // SPELL BEGINS
|
||||
ObjSpell_Regist(manageObj);
|
||||
|
||||
// Fully refills chain gauge for 120 frames
|
||||
// Activates chain but not FUN MODE
|
||||
|
||||
async{
|
||||
loop(90){
|
||||
SetCommonDataPtr(POINTER_CHAINCHECK, true);
|
||||
SetCommonDataPtr(POINTER_CHAINGAUGE, 100);
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
task CreateFireRing(x, y){
|
||||
|
||||
float startAng = rand(0, 360);
|
||||
|
||||
ascent(i in 0..8){
|
||||
int slash = CreatePlayerShotA1(x, y, 35, startAng + i * 360/8, shotDamageSpecial/4, 64, FIRE_SPECIAL);
|
||||
ObjShot_SetPenetrateShotEnable(slash, false);
|
||||
ObjRender_SetColorHSV(slash, 180, 255, 255);
|
||||
_BulletRescalePlayer(slash, shotScaleSpecial/1.75, true, 1);
|
||||
ObjShot_SetSpellFactor(slash, true);
|
||||
ObjShot_SetEraseShot(slash, true);
|
||||
Obj_SetRenderPriorityI(slash, plrender-1);
|
||||
//ObjRender_SetBlendType(slash, BLEND_ADD_ARGB);
|
||||
Fade(slash);
|
||||
}
|
||||
|
||||
ObjSound_Play(Explosion2);
|
||||
|
||||
}
|
||||
|
||||
task Fade(int ID){
|
||||
|
||||
ObjRender_SetAlpha(ID, 255);
|
||||
ObjMove_AddPatternA2(ID, 0, 36, NO_CHANGE, -36/15, 2, 0);
|
||||
|
||||
wait(15);
|
||||
|
||||
ascent(i in 0..15){
|
||||
ObjRender_SetAlpha(ID, Interpolate_Accelerate(255, 0, i/15));
|
||||
yield;
|
||||
}
|
||||
|
||||
Obj_Delete(ID);
|
||||
|
||||
}
|
||||
|
||||
float bombX = playerX;
|
||||
|
||||
ascent(i in 0..18){
|
||||
CreateFireRing(rand(bombX - 96, bombX + 96), Interpolate_Linear(STG_HEIGHT+128, -128, i/18));
|
||||
wait(4);
|
||||
}
|
||||
|
||||
SetPlayerSpeed(PlayerSpd[0], PlayerSpd[1]);
|
||||
SetForbidPlayerShot(false);
|
||||
Obj_Delete(manageObj); // !!! IMPORTANT !!!
|
||||
|
||||
wait(60);
|
||||
SetForbidPlayerSpell(false);
|
||||
|
||||
}
|
12
script/player/Kouryuu/Player_ShotConst.dnh
Normal file
12
script/player/Kouryuu/Player_ShotConst.dnh
Normal file
|
@ -0,0 +1,12 @@
|
|||
let current = GetCurrentScriptDirectory();
|
||||
let path = current ~ "Player_ShotData.dnh";
|
||||
LoadPlayerShotData(path);
|
||||
// -----
|
||||
|
||||
const OPTION = 1;
|
||||
const FIRE_OPTION = 2;
|
||||
const FIRE_BASE = 3;
|
||||
const FIRE_BASE_B = 4;
|
||||
const FIRE_SPECIAL = 5;
|
||||
|
||||
|
60
script/player/Kouryuu/Player_ShotData.dnh
Normal file
60
script/player/Kouryuu/Player_ShotData.dnh
Normal file
|
@ -0,0 +1,60 @@
|
|||
shot_image = "./playerlib/PlSheet_Kouryuu.png"
|
||||
|
||||
ShotData{
|
||||
id = 0 // Dummy
|
||||
rect = (0,0,0,0)
|
||||
render = ALPHA
|
||||
alpha = 0
|
||||
collision = 32
|
||||
}
|
||||
|
||||
// Option
|
||||
|
||||
ShotData{
|
||||
id = 1
|
||||
rect = (0, 192, 128, 384)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
fixed_angle = true
|
||||
collision = 0 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
||||
|
||||
// Fire
|
||||
|
||||
ShotData{
|
||||
id = 2
|
||||
rect = (128, 192, 256, 384)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
collision = 64 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
||||
|
||||
// Laser
|
||||
|
||||
ShotData{
|
||||
id = 3
|
||||
rect = (256, 192, 384, 384)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
collision = 64 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
||||
|
||||
// Laser 2
|
||||
|
||||
ShotData{
|
||||
id = 4
|
||||
rect = (384, 192, 512, 384)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
collision = 64 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
||||
|
||||
// Slash
|
||||
|
||||
ShotData{
|
||||
id = 5
|
||||
rect = (512, 192, 640, 384)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
collision = 64 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
0
script/player/Kouryuu/desc.txt
Normal file
0
script/player/Kouryuu/desc.txt
Normal file
BIN
script/player/Kouryuu/playerlib/PlSheet_Kouryuu.png
Normal file
BIN
script/player/Kouryuu/playerlib/PlSheet_Kouryuu.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
BIN
script/player/Kouryuu/playerlib/RAW/KouryuuPalette.aseprite
Normal file
BIN
script/player/Kouryuu/playerlib/RAW/KouryuuPalette.aseprite
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/playerlib/RAW/soGay.aseprite
Normal file
BIN
script/player/Kouryuu/playerlib/RAW/soGay.aseprite
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/playerlib/RAW/soTrue.aseprite
Normal file
BIN
script/player/Kouryuu/playerlib/RAW/soTrue.aseprite
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/CK Music Factory/air01.wav
Normal file
BIN
script/player/Kouryuu/sound/CK Music Factory/air01.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/CK Music Factory/air02.wav
Normal file
BIN
script/player/Kouryuu/sound/CK Music Factory/air02.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/CK Music Factory/laser01.wav
Normal file
BIN
script/player/Kouryuu/sound/CK Music Factory/laser01.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/CK Music Factory/slash01.wav
Normal file
BIN
script/player/Kouryuu/sound/CK Music Factory/slash01.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/CK Music Factory/wind01.wav
Normal file
BIN
script/player/Kouryuu/sound/CK Music Factory/wind01.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/TAM Music Factory/se04.wav
Normal file
BIN
script/player/Kouryuu/sound/TAM Music Factory/se04.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/TAM Music Factory/status4.wav
Normal file
BIN
script/player/Kouryuu/sound/TAM Music Factory/status4.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/TAM Music Factory/tama2.wav
Normal file
BIN
script/player/Kouryuu/sound/TAM Music Factory/tama2.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/bfxr_scythecall.wav
Normal file
BIN
script/player/Kouryuu/sound/bfxr_scythecall.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/bfxr_splash.wav
Normal file
BIN
script/player/Kouryuu/sound/bfxr_splash.wav
Normal file
Binary file not shown.
1
script/player/Kouryuu/sound/bfxr_teleporthigh.wav
Normal file
1
script/player/Kouryuu/sound/bfxr_teleporthigh.wav
Normal file
|
@ -0,0 +1 @@
|
|||
2,0.57,,0.3442,,0.2691,0.3,0.2179,,0.3445,,,,,,,,,,,0.2992,,0.5139,,,1,,,,,,,masterVolume
|
BIN
script/player/Kouryuu/sound/bfxr_teleportlow.wav
Normal file
BIN
script/player/Kouryuu/sound/bfxr_teleportlow.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/bfxr_watershoot.wav
Normal file
BIN
script/player/Kouryuu/sound/bfxr_watershoot.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/birdcall05.wav
Normal file
BIN
script/player/Kouryuu/sound/birdcall05.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/hit01.wav
Normal file
BIN
script/player/Kouryuu/sound/hit01.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/laser01.wav
Normal file
BIN
script/player/Kouryuu/sound/laser01.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/magic21.wav
Normal file
BIN
script/player/Kouryuu/sound/magic21.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/retrolaser.wav
Normal file
BIN
script/player/Kouryuu/sound/retrolaser.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/slash01.wav
Normal file
BIN
script/player/Kouryuu/sound/slash01.wav
Normal file
Binary file not shown.
BIN
script/player/Kouryuu/sound/tama2.wav
Normal file
BIN
script/player/Kouryuu/sound/tama2.wav
Normal file
Binary file not shown.
299
script/player/Lavender/Player_Function.dnh
Normal file
299
script/player/Lavender/Player_Function.dnh
Normal file
|
@ -0,0 +1,299 @@
|
|||
// 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 <int> 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
|
364
script/player/Lavender/Player_Main.dnh
Normal file
364
script/player/Lavender/Player_Main.dnh
Normal file
|
@ -0,0 +1,364 @@
|
|||
#TouhouDanmakufu[Player]
|
||||
#ScriptVersion[3]
|
||||
#ID["PL1_LAVENDER"]
|
||||
#Title["Lavender Mushihime"]
|
||||
#Text["Player 1"]
|
||||
|
||||
//#Image["./mariremi_lib/mariremi_illust.png"]
|
||||
|
||||
#ReplayName["Lavender"]
|
||||
|
||||
#include "script/KevinSystem/kevin_system/Lib_Const.dnh"
|
||||
|
||||
#include "script/KevinSystem/Kevin_PlayerLib.txt"
|
||||
#include "script/KevinSystem/PlayerSoundLib.dnh"
|
||||
|
||||
#include "./Player_Function.dnh"
|
||||
#include "./Player_ShotConst.dnh"
|
||||
|
||||
#include "script/KevinSystem/kevin_system/Kevin_ItemConst.txt"
|
||||
#include "script/KevinSystem/kevin_system/Kevin_ItemLib.txt"
|
||||
|
||||
let csd = GetCurrentScriptDirectory();
|
||||
|
||||
|
||||
// Global Variables
|
||||
|
||||
float maxX = GetStgFrameWidth();
|
||||
float maxY = GetStgFrameHeight();
|
||||
|
||||
// Images & Sound
|
||||
|
||||
let teamimg = csd ~ "./playerlib/Player_Sheet.png";
|
||||
LoadTextureEx(teamimg, true, true);
|
||||
//ObjRender_SetTextureFilterMip(teamimg, FILTER_LINEAR);
|
||||
|
||||
let plimg = csd ~ "./playerlib/PlSheet_Lavender.png";
|
||||
LoadTextureEx(plimg, true, true);
|
||||
ObjRender_SetTextureFilter(plimg, FILTER_NONE, FILTER_NONE, FILTER_NONE);
|
||||
|
||||
let sndpath = csd ~ "./sound";
|
||||
|
||||
int[] _enemyArray = [];
|
||||
int[] _existArray = [];
|
||||
int[] _shotArray = [];
|
||||
|
||||
bool isChain = false;
|
||||
bool isUseSpecialWpn = false;
|
||||
float curChain = 0;
|
||||
|
||||
// Other stuff
|
||||
|
||||
float playerX = 0;
|
||||
float playerY = 0;
|
||||
|
||||
let objPlayer = GetPlayerObjectID();
|
||||
int plrender = Obj_GetRenderPriorityI(objPlayer);
|
||||
|
||||
bool ripplayer = false;
|
||||
float shotspeed = 0;
|
||||
float bombrand = 0;
|
||||
|
||||
int grazecounter = 0; // For basic graze = PIV mechanic
|
||||
|
||||
int shotAlpha = (GetAreaCommonData("Config", "PlayerShotOpacity", 60)*0.01)*255;
|
||||
float shotDamage = 3.1;
|
||||
float shotDamageSpecial = 6.25;
|
||||
float shotScale1 = 1;
|
||||
|
||||
float[] PlayerSpd = [13, 6.5];
|
||||
|
||||
// Custom events for scoring mechanic
|
||||
|
||||
const EV_PIV_100 = EV_USER + 100i; // Normal enemies and nons
|
||||
const EV_PIV_250 = EV_USER + 101i; // Spells
|
||||
const EV_PIV_500 = EV_USER + 102i; // Last Spells
|
||||
const EV_PIV_2000 = EV_USER + 103i; // What.
|
||||
|
||||
@Initialize{
|
||||
|
||||
if(!IsCommonDataAreaExists("PIV")){
|
||||
CreateCommonDataArea("PIV");
|
||||
SetAreaCommonData("PIV", "currentvalue", 10000);
|
||||
SetAreaCommonData("PIV", "ChainAmount", 1);
|
||||
}
|
||||
else{}
|
||||
|
||||
SetPlayerStateEndEnable(true);
|
||||
|
||||
// Stuff
|
||||
Parameter();
|
||||
RenderPlayer();
|
||||
|
||||
UpdateAng();
|
||||
BaseShot();
|
||||
InitiateOptions();
|
||||
|
||||
Obj_SetRenderPriorityI(objPlayer, 43);
|
||||
plrender = Obj_GetRenderPriorityI(objPlayer);
|
||||
_SoundTask();
|
||||
|
||||
//SetIntersectionVisualization(true); // Debug
|
||||
|
||||
_Mechanic(ripplayer, _enemyArray, _existArray, GetStgFrameWidth(), GetStgFrameHeight(), objPlayer, GetEnemyBossSceneObjectID(), 1, 2, 80);
|
||||
|
||||
_ShowChain();
|
||||
_HandleChainGauge();
|
||||
|
||||
_HitboxRender(ripplayer, objPlayer, plimg, teamimg, 768, 192, 832, 256, 1536, 896, 2048, 1408, 0.5, 0.65);
|
||||
SetShotAutoDeleteClip(256, 256, 256, 256);
|
||||
|
||||
_Countdown();
|
||||
|
||||
// Shot data loading
|
||||
LoadPlayerShotData(csd ~ "./Player_ShotData.dnh");
|
||||
}
|
||||
|
||||
@MainLoop{
|
||||
_enemyArray = GetIntersectionRegistedEnemyID;
|
||||
shotspeed += 1; // Managing the shot rate
|
||||
//_shotArray = GetAllShotID(TARGET_PLAYER);
|
||||
//UniversalAlphaHandle(_shotArray);
|
||||
playerX = ObjMove_GetX(objPlayer);
|
||||
playerY = ObjMove_GetY(objPlayer);
|
||||
yield;
|
||||
}
|
||||
|
||||
@Event{
|
||||
alternative(GetEventType)
|
||||
|
||||
// Delete effect
|
||||
case(EV_DELETE_SHOT_PLAYER){
|
||||
|
||||
if(GetCommonDataPtr(EFFECTCUT_PTR, 0) >= 3){}
|
||||
|
||||
else{
|
||||
let graphic = GetEventArgument(2);
|
||||
float[] position = GetEventArgument(1);
|
||||
let obj = CreatePlayerShotA1(position[0], position[1], 0, ObjMove_GetAngle(GetEventArgument(0)), 0, 99999, graphic);
|
||||
ObjShot_SetIntersectionEnable(obj, false); _DeleteEffect(obj, graphic == FIRE_SPECIAL ? shotScale1 * 2 : shotScale1);
|
||||
}
|
||||
//if(graphic == ELECTRIC_FIRE_ALT) {_DeleteEffectAlt(obj);}
|
||||
//else{_DeleteEffect(obj);}
|
||||
}
|
||||
|
||||
// PIV-item spawning events
|
||||
case(EV_PIV_100){
|
||||
let arg = GetEventArgument(0);
|
||||
CreatePIVItem(PIV_100, arg[0], arg[1]);
|
||||
}
|
||||
|
||||
case(EV_PIV_250){
|
||||
let arg = GetEventArgument(0);
|
||||
CreatePIVItem(PIV_250, arg[0], arg[1]);
|
||||
}
|
||||
|
||||
case(EV_PIV_500){
|
||||
let arg = GetEventArgument(0);
|
||||
CreatePIVItem(PIV_500, arg[0], arg[1]);
|
||||
}
|
||||
|
||||
// Basic functionality events
|
||||
case(EV_REQUEST_SPELL){
|
||||
let bomb = GetPlayerSpell();
|
||||
|
||||
if (bomb >= 1){
|
||||
SetScriptResult(true);
|
||||
SetPlayerSpell(bomb - 1);
|
||||
_Bomb();
|
||||
SetCommonData("Rank", clamp(max(1, GetCommonData("Rank", 1)-0.25), GetCommonData("MinRank", 1), GetCommonData("MaxRank", 12)));
|
||||
|
||||
_SigilCall(false, teamimg, 768+256, 512, 768+512, 768, objPlayer, GetPlayerInvincibilityFrame());
|
||||
}
|
||||
|
||||
else {
|
||||
SetScriptResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
case(EV_HIT){
|
||||
ObjSound_Play(PlayerHit);
|
||||
_DeathbombWarning(plimg, [832, 0, 1088, 256], 20, 3);
|
||||
}
|
||||
|
||||
case(EV_CHAIN_MAX){
|
||||
|
||||
if(!isChain){
|
||||
ObjSound_Play(Shine);
|
||||
isChain = true;
|
||||
curChain = GetCommonDataPtr(POINTER_CHAIN, 1);
|
||||
}
|
||||
else{}
|
||||
|
||||
}
|
||||
|
||||
case(EV_CHAIN_RELEASE){
|
||||
|
||||
}
|
||||
|
||||
case(EV_CHAIN_END){
|
||||
|
||||
SetAreaCommonData("PIV", "ChainAmount", 1);
|
||||
isChain = false;
|
||||
|
||||
// Increase rank depending on curChain (>= 32), then reset curChain. MAX CHAIN increases rank by 0.4.
|
||||
|
||||
if(curChain >= 32){
|
||||
SetCommonData("Rank", clamp(GetCommonData("Rank", 1) + Interpolate_Linear(0.25, 0.5, curChain/64), GetCommonData("MinRank", 1), GetCommonData("MaxRank", 12)));
|
||||
}
|
||||
|
||||
curChain = 1;
|
||||
|
||||
}
|
||||
|
||||
case(EV_PLAYER_SHOOTDOWN){
|
||||
ObjSound_Play(PlayerDie2);
|
||||
SetPlayerSpell(GetPlayerSpell()+2);
|
||||
ripplayer = true;
|
||||
DeleteShotAll(TYPE_SHOT, TYPE_ITEM);
|
||||
|
||||
// Decrease rank by 1/4
|
||||
|
||||
SetCommonData("Rank", clamp(GetCommonData("Rank", 1) * 0.75, GetCommonData("MinRank", 1), GetCommonData("MaxRank", 12)));
|
||||
|
||||
_SigilCall(true, teamimg, 768, 512, 768+256, 768, objPlayer, 60);
|
||||
}
|
||||
|
||||
case(EV_PLAYER_REBIRTH){
|
||||
ripplayer = false;
|
||||
SetPlayerInvincibilityFrame(180);
|
||||
//_Countdown();
|
||||
_SigilCall(false, teamimg, 768+256, 512, 768+512, 768, objPlayer, 150);
|
||||
|
||||
}
|
||||
|
||||
case(EV_GRAZE){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Finalize{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Basic player parameters
|
||||
|
||||
task Parameter(){
|
||||
|
||||
// im trying to not be collected by the player but their item scope is dummy thicc and im alerted by its cheek
|
||||
SetPlayerItemScope(360);
|
||||
|
||||
SetPlayerLife(9); // Debug
|
||||
SetPlayerSpell(2);
|
||||
SetPlayerSpeed(PlayerSpd[0], PlayerSpd[1]); // (original: 5.25/2.0)
|
||||
SetPlayerRebirthFrame(20);
|
||||
SetPlayerDownStateFrame(60);
|
||||
SetPlayerAutoItemCollectLine(GetStgFrameHeight/3);
|
||||
SetPlayerRebirthLossFrame(0);
|
||||
ObjPlayer_AddIntersectionCircleA1(objPlayer, 0, 0, 0, 40);
|
||||
|
||||
}
|
||||
|
||||
// Player render
|
||||
|
||||
task RenderPlayer(){
|
||||
|
||||
// Why is this movement code so cursed jesus fucking christ
|
||||
|
||||
float scale = 1; // Scalies
|
||||
int frame = 0;
|
||||
|
||||
ObjPrim_SetTexture(objPlayer, plimg);
|
||||
ObjSprite2D_SetSourceRect(objPlayer, 0, 0, 128, 192);
|
||||
ObjSprite2D_SetDestCenter(objPlayer);
|
||||
Obj_SetRenderPriorityI(objPlayer, 42);
|
||||
//ObjRender_SetTextureFilterMin(objPlayer, FILTER_ANISOTROPIC);
|
||||
ObjRender_SetScaleXYZ(objPlayer, scale, scale, 1);
|
||||
|
||||
// Lower "speed" parameter = FASTER SPEED
|
||||
|
||||
loop{
|
||||
frame++;
|
||||
_RenderPlayerMovement(objPlayer, frame, 0, 0, 128, 192, scale, 3, 6);
|
||||
if (frame >= (3*6-1)){frame = 0;}
|
||||
yield;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Handling of bomb
|
||||
|
||||
task _Bomb(){
|
||||
|
||||
// Fire rings explode in a straight line, bomb lasts 90 frames with 240-frame total invincibility
|
||||
|
||||
// Preparation
|
||||
|
||||
SetForbidPlayerShot(true);
|
||||
SetForbidPlayerSpell(true);
|
||||
SetPlayerInvincibilityFrame(120);
|
||||
// Spell object
|
||||
let manageObj = GetSpellManageObject(); // SPELL BEGINS
|
||||
ObjSpell_Regist(manageObj);
|
||||
|
||||
// Fully refills chain gauge for 120 frames
|
||||
// Activates chain but not FUN MODE
|
||||
|
||||
async{
|
||||
loop(60){
|
||||
SetCommonDataPtr(POINTER_CHAINCHECK, true);
|
||||
SetCommonDataPtr(POINTER_CHAINGAUGE, 100);
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
task CreateFireRing(x, y){
|
||||
|
||||
float startAng = rand(0, 360);
|
||||
|
||||
ascent(i in 0..16){
|
||||
int slash = CreatePlayerShotA1(x, y, 35, startAng + i * 360/16, shotDamageSpecial/8, 64, FIRE_SPECIAL);
|
||||
ObjShot_SetPenetrateShotEnable(slash, false);
|
||||
ObjRender_SetColorHSV(slash, 180, 255, 255);
|
||||
_BulletRescalePlayer(slash, shotScale1*2.5, true, 1);
|
||||
ObjShot_SetSpellFactor(slash, true);
|
||||
ObjShot_SetEraseShot(slash, true);
|
||||
Obj_SetRenderPriorityI(slash, plrender-1);
|
||||
//ObjRender_SetBlendType(slash, BLEND_ADD_ARGB);
|
||||
Fade(slash);
|
||||
}
|
||||
|
||||
ObjSound_Play(Explosion2);
|
||||
|
||||
}
|
||||
|
||||
task Fade(int ID){
|
||||
|
||||
ObjRender_SetAlpha(ID, 255);
|
||||
ObjMove_AddPatternA2(ID, 0, 40, NO_CHANGE, -40/25, 15, 0);
|
||||
|
||||
ascent(i in 0..15){
|
||||
ObjRender_SetAlpha(ID, Interpolate_Accelerate(255, 0, i/15));
|
||||
yield;
|
||||
}
|
||||
|
||||
Obj_Delete(ID);
|
||||
|
||||
}
|
||||
|
||||
float bombX = playerX;
|
||||
|
||||
ascent(i in 0..15){
|
||||
CreateFireRing(rand(0, STG_WIDTH), rand(0, STG_HEIGHT));
|
||||
wait(4);
|
||||
}
|
||||
|
||||
SetPlayerSpeed(PlayerSpd[0], PlayerSpd[1]);
|
||||
SetForbidPlayerShot(false);
|
||||
Obj_Delete(manageObj); // !!! IMPORTANT !!!
|
||||
|
||||
wait(60);
|
||||
SetForbidPlayerSpell(false);
|
||||
|
||||
}
|
11
script/player/Lavender/Player_ShotConst.dnh
Normal file
11
script/player/Lavender/Player_ShotConst.dnh
Normal file
|
@ -0,0 +1,11 @@
|
|||
let current = GetCurrentScriptDirectory();
|
||||
let path = current ~ "Player_ShotData.dnh";
|
||||
LoadPlayerShotData(path);
|
||||
// -----
|
||||
|
||||
const OPTION = 1;
|
||||
const FIRE_NORMAL = 2;
|
||||
const FIRE_SPECIAL = 3;
|
||||
const FIRE_BASE = 4;
|
||||
|
||||
|
49
script/player/Lavender/Player_ShotData.dnh
Normal file
49
script/player/Lavender/Player_ShotData.dnh
Normal file
|
@ -0,0 +1,49 @@
|
|||
shot_image = "./playerlib/PlSheet_Lavender.png"
|
||||
|
||||
ShotData{
|
||||
id = 0 // Dummy
|
||||
rect = (0,0,0,0)
|
||||
render = ALPHA
|
||||
alpha = 0
|
||||
collision = 32
|
||||
}
|
||||
|
||||
// Option
|
||||
|
||||
ShotData{
|
||||
id = 1
|
||||
rect = (0, 192, 128, 384)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
collision = 0 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
||||
|
||||
// Fire1
|
||||
|
||||
ShotData{
|
||||
id = 2
|
||||
rect = (128, 192, 256, 384)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
collision = 64 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
||||
|
||||
// Fire2
|
||||
|
||||
ShotData{
|
||||
id = 3
|
||||
rect = (512, 192, 640, 384)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
collision = 64 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
||||
|
||||
// Fire0
|
||||
|
||||
ShotData{
|
||||
id = 4
|
||||
rect = (384, 192, 512, 384)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
collision = 64 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
0
script/player/Lavender/desc.txt
Normal file
0
script/player/Lavender/desc.txt
Normal file
BIN
script/player/Lavender/playerlib/PlSheet_Lavender.png
Normal file
BIN
script/player/Lavender/playerlib/PlSheet_Lavender.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
BIN
script/player/Lavender/playerlib/RAW/LavenderPalette.aseprite
Normal file
BIN
script/player/Lavender/playerlib/RAW/LavenderPalette.aseprite
Normal file
Binary file not shown.
BIN
script/player/Lavender/playerlib/RAW/soTrue.aseprite
Normal file
BIN
script/player/Lavender/playerlib/RAW/soTrue.aseprite
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/CK Music Factory/air01.wav
Normal file
BIN
script/player/Lavender/sound/CK Music Factory/air01.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/CK Music Factory/air02.wav
Normal file
BIN
script/player/Lavender/sound/CK Music Factory/air02.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/CK Music Factory/laser01.wav
Normal file
BIN
script/player/Lavender/sound/CK Music Factory/laser01.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/CK Music Factory/slash01.wav
Normal file
BIN
script/player/Lavender/sound/CK Music Factory/slash01.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/CK Music Factory/wind01.wav
Normal file
BIN
script/player/Lavender/sound/CK Music Factory/wind01.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/TAM Music Factory/se04.wav
Normal file
BIN
script/player/Lavender/sound/TAM Music Factory/se04.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/TAM Music Factory/status4.wav
Normal file
BIN
script/player/Lavender/sound/TAM Music Factory/status4.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/TAM Music Factory/tama2.wav
Normal file
BIN
script/player/Lavender/sound/TAM Music Factory/tama2.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/bfxr_scythecall.wav
Normal file
BIN
script/player/Lavender/sound/bfxr_scythecall.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/bfxr_splash.wav
Normal file
BIN
script/player/Lavender/sound/bfxr_splash.wav
Normal file
Binary file not shown.
1
script/player/Lavender/sound/bfxr_teleporthigh.wav
Normal file
1
script/player/Lavender/sound/bfxr_teleporthigh.wav
Normal file
|
@ -0,0 +1 @@
|
|||
2,0.57,,0.3442,,0.2691,0.3,0.2179,,0.3445,,,,,,,,,,,0.2992,,0.5139,,,1,,,,,,,masterVolume
|
BIN
script/player/Lavender/sound/bfxr_teleportlow.wav
Normal file
BIN
script/player/Lavender/sound/bfxr_teleportlow.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/bfxr_watershoot.wav
Normal file
BIN
script/player/Lavender/sound/bfxr_watershoot.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/birdcall05.wav
Normal file
BIN
script/player/Lavender/sound/birdcall05.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/hit01.wav
Normal file
BIN
script/player/Lavender/sound/hit01.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/laser01.wav
Normal file
BIN
script/player/Lavender/sound/laser01.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/magic21.wav
Normal file
BIN
script/player/Lavender/sound/magic21.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/retrolaser.wav
Normal file
BIN
script/player/Lavender/sound/retrolaser.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/slash01.wav
Normal file
BIN
script/player/Lavender/sound/slash01.wav
Normal file
Binary file not shown.
BIN
script/player/Lavender/sound/tama2.wav
Normal file
BIN
script/player/Lavender/sound/tama2.wav
Normal file
Binary file not shown.
245
script/player/Narumi/Player_Function.dnh
Normal file
245
script/player/Narumi/Player_Function.dnh
Normal file
|
@ -0,0 +1,245 @@
|
|||
#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 ShotType(){
|
||||
}
|
||||
|
||||
task BaseShot(){
|
||||
|
||||
// 5 way shot
|
||||
float[] angDist = [10, 5];
|
||||
float ang = -7.5;
|
||||
float ang2 = -22.5;
|
||||
|
||||
while(true){
|
||||
|
||||
if(GetVirtualKeyState(VK_SPELL) == KEY_FREE && IsPermitPlayerShot && !ripplayer){
|
||||
|
||||
// C for alt shot
|
||||
if(GetVirtualKeyState(VK_USER1) != KEY_FREE){
|
||||
|
||||
if(shotspeed % 4 == 0){
|
||||
|
||||
ObjSound_Play(Base3);
|
||||
|
||||
ascent(i in 0..3){
|
||||
|
||||
let shotA = CreatePlayerShotA1(playerX, playerY, 52, ang2 - ang2 * (i * 1), shotDamageOption, 1.5, AMULET);
|
||||
_BulletRescalePlayer(shotA, shotScaleOption, true, 1);
|
||||
ObjRender_SetAlpha(shotA, shotAlpha);
|
||||
Obj_SetRenderPriorityI(shotA, 41);
|
||||
|
||||
}
|
||||
|
||||
ascent(i in 0..3){
|
||||
|
||||
let shotB = CreatePlayerShotA1(playerX, playerY, 52, ang2 - ang2 * (i * 1) + 180, shotDamageOption, 1.5, AMULET);
|
||||
_BulletRescalePlayer(shotB, shotScaleOption, true, 1);
|
||||
ObjRender_SetAlpha(shotB, shotAlpha);
|
||||
Obj_SetRenderPriorityI(shotB, 41);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Z/Z+C for normal shot
|
||||
|
||||
else if(GetVirtualKeyState(VK_SHOT) != KEY_FREE && GetVirtualKeyState(VK_USER1) == KEY_FREE){
|
||||
|
||||
if(shotspeed % 4 == 0){
|
||||
|
||||
ObjSound_Play(Base3);
|
||||
|
||||
ascent(b in -2..3){
|
||||
|
||||
let shotC = CreatePlayerShotA1(playerX, playerY, 52, 0 + ang * b, shotDamageOption, 1.5, AMULET);
|
||||
_BulletRescalePlayer(shotC, shotScaleOption, true, 1);
|
||||
ObjRender_SetAlpha(shotC, shotAlpha);
|
||||
Obj_SetRenderPriorityI(shotC, 41);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else{}
|
||||
|
||||
}
|
||||
|
||||
yield;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
task SpecialWeapon(){
|
||||
|
||||
// Create projectile, but disable hitbox & visibility
|
||||
|
||||
int golem = CreatePlayerShotA1(playerX+128, playerY, 0, 0, shotDamageSpecial * 5.25, 999999, GOLEM);
|
||||
ObjShot_SetAutoDelete(golem, false);
|
||||
ObjShot_SetEraseShot(golem, true);
|
||||
ObjShot_SetPenetrateShotEnable(golem, true);
|
||||
ObjShot_SetIntersectionEnable(golem, false);
|
||||
Obj_SetVisible(golem, false);
|
||||
ObjRender_SetAlpha(golem, 0);
|
||||
ObjShot_SetSpellFactor(golem, true);
|
||||
_BulletRescalePlayer(golem, 1.5, true, 1);
|
||||
ObjShot_SetSpinAngularVelocity(golem, 6);
|
||||
|
||||
float i = 0;
|
||||
|
||||
while(true){
|
||||
|
||||
if(GetVirtualKeyState(VK_SPELL) != KEY_FREE && GetCommonDataPtr(POINTER_SPECIALAMMO, 100) > 0 && !ripplayer){
|
||||
|
||||
if(shotspeed % 4 == 0){ObjSound_Play(Fire);}
|
||||
|
||||
i = min(210, i+210/10);
|
||||
ObjMove_SetPosition(golem, playerX + i, playerY);
|
||||
ObjRender_SetAlpha(golem, min(255, ObjRender_GetAlpha(golem)+255/10));
|
||||
|
||||
//SetCommonDataPtr(POINTER_SPECIALCHECK, true);
|
||||
SetCommonDataPtr(POINTER_CHAINCHECK, true);
|
||||
SetPlayerSpeed(PlayerSpd[0]*1.5, PlayerSpd[1]*1.5);
|
||||
// (Approx.) 20 ammo per second
|
||||
|
||||
SetCommonDataPtr(POINTER_SPECIALAMMO, max(0, GetCommonDataPtr(POINTER_SPECIALAMMO, 100)-(20/60)));
|
||||
ObjShot_SetIntersectionEnable(golem, true);
|
||||
Obj_SetVisible(golem, true);
|
||||
|
||||
// +1 rank per 10 seconds of use
|
||||
|
||||
SetCommonData("Rank", clamp(GetCommonData("Rank", 1)+1/600, 1, GetCommonData("MaxRank", 6)));
|
||||
|
||||
/*
|
||||
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{
|
||||
|
||||
// Refills 5 ammo per second
|
||||
|
||||
i = max(0, i-210/10);
|
||||
ObjMove_SetPosition(golem, playerX + i, playerY);
|
||||
ObjRender_SetAlpha(golem, max(0, ObjRender_GetAlpha(golem)-255/10));
|
||||
|
||||
SetPlayerSpeed(PlayerSpd[0], PlayerSpd[1]);
|
||||
SetCommonDataPtr(POINTER_SPECIALAMMO, min(100, GetCommonDataPtr(POINTER_SPECIALAMMO, 100)+(5/60)));
|
||||
SetCommonDataPtr(POINTER_CHAINCHECK, false);
|
||||
ObjShot_SetIntersectionEnable(golem, 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, 1);
|
||||
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, 1);
|
||||
_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
|
232
script/player/Narumi/Player_Function_Laser.dnh
Normal file
232
script/player/Narumi/Player_Function_Laser.dnh
Normal file
|
@ -0,0 +1,232 @@
|
|||
|
||||
// Particle list for laser effect
|
||||
|
||||
int LaserEffect = ObjParticleList_Create(OBJ_PARTICLE_LIST_2D);
|
||||
int[] rect = [704, 192, 768, 256];
|
||||
|
||||
ObjPrim_SetTexture(LaserEffect, "script/player/Kouryuu/playerlib/PlSheet_Kouryuu.png");
|
||||
|
||||
Obj_SetRenderPriorityI(LaserEffect, 41);
|
||||
ObjPrim_SetPrimitiveType(LaserEffect, PRIMITIVE_TRIANGLELIST);
|
||||
ObjPrim_SetVertexCount(LaserEffect, 4);
|
||||
|
||||
ObjRender_SetBlendType(LaserEffect, BLEND_ADD_ARGB);
|
||||
|
||||
// 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(1, 0.5, 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);
|
||||
|
||||
float scaleXBoost = 0;
|
||||
float scaleXBoostMax = 0.05;
|
||||
float ang = 180;
|
||||
|
||||
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{
|
||||
|
||||
if(GetVirtualKeyState(VK_SHOT) != 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+scaleXBoost, ObjRender_GetScaleX(lasersprite) + scaleSpeed));
|
||||
scaleXBoost = scaleXBoostMax * sin(ang);
|
||||
|
||||
ObjRender_SetAlpha(lasersprite, min(alpha, ObjRender_GetAlpha(lasersprite)+alpha/5));
|
||||
ObjRender_SetAngleZ(lasersprite, targetAng);
|
||||
ObjRender_SetPosition(lasersprite, targetx, targety, 1);
|
||||
|
||||
ang += 25;
|
||||
|
||||
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, plrender-1);
|
||||
_Follow(laser, target);
|
||||
|
||||
_LaserSpriteRender(
|
||||
plimg, laser, ang,
|
||||
256, 192, 384, 384,
|
||||
1, 20, plrender-1, shotAlpha,
|
||||
0.1
|
||||
);
|
||||
|
||||
// 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 && !ripplayer && IsPermitPlayerShot){
|
||||
|
||||
if(shotspeed % 5 == 0){
|
||||
ObjSound_Play(Base2);
|
||||
}
|
||||
|
||||
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){
|
||||
|
||||
async{
|
||||
loop{
|
||||
EnemyList = ObjCol_GetListOfIntersectedEnemyID(target);
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
// 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(6, 9));
|
||||
}
|
||||
}
|
||||
|
||||
// Damage effects
|
||||
|
||||
}
|
||||
task _Follow(follower, followed){
|
||||
|
||||
while(!Obj_IsDeleted(follower)){
|
||||
float x = ObjRender_GetX(followed);
|
||||
float y = ObjRender_GetY(followed);
|
||||
ObjMove_SetPosition(follower, x, y);
|
||||
yield;
|
||||
}
|
||||
|
||||
}
|
354
script/player/Narumi/Player_Main.dnh
Normal file
354
script/player/Narumi/Player_Main.dnh
Normal file
|
@ -0,0 +1,354 @@
|
|||
#TouhouDanmakufu[Player]
|
||||
#ScriptVersion[3]
|
||||
#ID["PL_NARUMI"]
|
||||
#Title["Narumi Yatadera"]
|
||||
#Text["Player 0"]
|
||||
|
||||
//#Image["./mariremi_lib/mariremi_illust.png"]
|
||||
|
||||
#ReplayName["Narumi"]
|
||||
|
||||
#include "script/KevinSystem/kevin_system/Lib_Const.dnh"
|
||||
|
||||
#include "script/KevinSystem/Kevin_PlayerLib.txt"
|
||||
#include "script/KevinSystem/PlayerSoundLib.dnh"
|
||||
|
||||
#include "./Player_Function.dnh"
|
||||
#include "./Player_ShotConst.dnh"
|
||||
|
||||
#include "script/KevinSystem/kevin_system/Kevin_ItemConst.txt"
|
||||
#include "script/KevinSystem/kevin_system/Kevin_ItemLib.txt"
|
||||
|
||||
let csd = GetCurrentScriptDirectory();
|
||||
|
||||
// Global Variables
|
||||
|
||||
float maxX = GetStgFrameWidth();
|
||||
float maxY = GetStgFrameHeight();
|
||||
|
||||
// Images & Sound
|
||||
|
||||
let teamimg = csd ~ "./playerlib/Player_Sheet.png";
|
||||
LoadTextureEx(teamimg, true, true);
|
||||
//ObjRender_SetTextureFilterMip(teamimg, FILTER_LINEAR);
|
||||
|
||||
let plimg = csd ~ "./playerlib/PlSheet_Narumi.png";
|
||||
LoadTextureEx(plimg, true, true);
|
||||
ObjRender_SetTextureFilter(plimg, FILTER_NONE, FILTER_NONE, FILTER_NONE);
|
||||
|
||||
let sndpath = csd ~ "./sound";
|
||||
|
||||
int[] _enemyArray = [];
|
||||
int[] _existArray = [];
|
||||
int[] _shotArray = [];
|
||||
|
||||
bool isChain = false;
|
||||
bool isUseSpecialWpn = false;
|
||||
float curChain = 0;
|
||||
|
||||
// Other stuff
|
||||
|
||||
float playerX = 0;
|
||||
float playerY = 0;
|
||||
|
||||
let objPlayer = GetPlayerObjectID();
|
||||
int plrender = 42;
|
||||
|
||||
bool ripplayer = false;
|
||||
float shotspeed = 0;
|
||||
float bombrand = 0;
|
||||
|
||||
int grazecounter = 0; // For basic graze = PIV mechanic
|
||||
|
||||
int shotAlpha = (GetAreaCommonData("Config", "PlayerShotOpacity", 255)*0.01)*255;
|
||||
|
||||
float shotDamageOption = 4;
|
||||
float shotScaleOption = 1;
|
||||
|
||||
float shotDamageLaser = 2;
|
||||
float shotScaleLaser = 1;
|
||||
|
||||
float shotDamageSpecial = 5;
|
||||
float shotScaleSpecial = 1;
|
||||
|
||||
float[] PlayerSpd = [12, 6];
|
||||
|
||||
// Custom events for scoring mechanic
|
||||
|
||||
const EV_PIV_100 = EV_USER + 100i; // Normal enemies and nons
|
||||
const EV_PIV_250 = EV_USER + 101i; // Spells
|
||||
const EV_PIV_500 = EV_USER + 102i; // Last Spells
|
||||
const EV_PIV_2000 = EV_USER + 103i; // What.
|
||||
|
||||
@Initialize{
|
||||
|
||||
if(!IsCommonDataAreaExists("PIV")){
|
||||
CreateCommonDataArea("PIV");
|
||||
SetAreaCommonData("PIV", "currentvalue", 10000);
|
||||
SetAreaCommonData("PIV", "ChainAmount", 1);
|
||||
}
|
||||
else{}
|
||||
|
||||
SetPlayerStateEndEnable(true);
|
||||
|
||||
// Stuff
|
||||
Parameter();
|
||||
RenderPlayer();
|
||||
BaseShot();
|
||||
SpecialWeapon();
|
||||
|
||||
Obj_SetRenderPriorityI(objPlayer, 43);
|
||||
plrender = Obj_GetRenderPriorityI(objPlayer);
|
||||
_SoundTask();
|
||||
|
||||
//SetIntersectionVisualization(true); // Debug
|
||||
|
||||
_Mechanic(ripplayer, _enemyArray, _existArray, GetStgFrameWidth(), GetStgFrameHeight(), objPlayer, GetEnemyBossSceneObjectID(), 1, 2, 80);
|
||||
|
||||
_ShowChain();
|
||||
//_HandleChainGauge();
|
||||
|
||||
//_HitboxRender(ripplayer, objPlayer, plimg, teamimg, 768, 192, 832, 256, 1536, 896, 2048, 1408, 0.5, 0.65);
|
||||
SetShotAutoDeleteClip(96, 84, 96, 84);
|
||||
|
||||
_Countdown();
|
||||
|
||||
// Shot data loading
|
||||
LoadPlayerShotData(csd ~ "./Player_ShotData.dnh");
|
||||
}
|
||||
|
||||
@MainLoop{
|
||||
_enemyArray = GetIntersectionRegistedEnemyID;
|
||||
shotspeed += 1; // Managing the shot rate
|
||||
//_shotArray = GetAllShotID(TARGET_PLAYER);
|
||||
//UniversalAlphaHandle(_shotArray);
|
||||
plrender = Obj_GetRenderPriorityI(objPlayer);
|
||||
playerX = ObjMove_GetX(objPlayer);
|
||||
playerY = ObjMove_GetY(objPlayer);
|
||||
yield;
|
||||
}
|
||||
|
||||
@Event{
|
||||
alternative(GetEventType)
|
||||
|
||||
// Delete effect
|
||||
case(EV_DELETE_SHOT_PLAYER){
|
||||
|
||||
if(GetCommonDataPtr(EFFECTCUT_PTR, 0) >= 3){}
|
||||
|
||||
else{
|
||||
|
||||
let graphic = GetEventArgument(2);
|
||||
float[] position = GetEventArgument(1);
|
||||
|
||||
let obj = CreatePlayerShotA1(position[0], position[1], 0, ObjMove_GetAngle(GetEventArgument(0))+rand(-15, 15), 0, 99999, graphic);
|
||||
|
||||
ObjShot_SetIntersectionEnable(obj, false);
|
||||
_DeleteEffect(obj, 1);
|
||||
|
||||
}
|
||||
//if(graphic == ELECTRIC_FIRE_ALT) {_DeleteEffectAlt(obj);}
|
||||
//else{_DeleteEffect(obj);}
|
||||
}
|
||||
|
||||
// PIV-item spawning events
|
||||
case(EV_PIV_100){
|
||||
let arg = GetEventArgument(0);
|
||||
CreatePIVItem(PIV_100, arg[0], arg[1]);
|
||||
}
|
||||
|
||||
case(EV_PIV_250){
|
||||
let arg = GetEventArgument(0);
|
||||
CreatePIVItem(PIV_250, arg[0], arg[1]);
|
||||
}
|
||||
|
||||
case(EV_PIV_500){
|
||||
let arg = GetEventArgument(0);
|
||||
CreatePIVItem(PIV_500, arg[0], arg[1]);
|
||||
}
|
||||
|
||||
// Basic functionality events
|
||||
case(EV_REQUEST_SPELL){
|
||||
SetScriptResult(false);
|
||||
}
|
||||
|
||||
case(EV_HIT){
|
||||
|
||||
}
|
||||
|
||||
case(EV_CHAIN_MAX){
|
||||
|
||||
if(!isChain){
|
||||
ObjSound_Play(Shine);
|
||||
isChain = true;
|
||||
curChain = GetCommonDataPtr(POINTER_CHAIN, 1);
|
||||
}
|
||||
else{}
|
||||
|
||||
}
|
||||
|
||||
case(EV_CHAIN_RELEASE){
|
||||
|
||||
}
|
||||
|
||||
case(EV_CHAIN_END){
|
||||
|
||||
SetAreaCommonData("PIV", "ChainAmount", 1);
|
||||
isChain = false;
|
||||
|
||||
// Increase rank depending on curChain (>= 32), then reset curChain. MAX CHAIN increases rank by 0.4.
|
||||
|
||||
if(curChain >= 32){
|
||||
SetCommonData("Rank", clamp(GetCommonData("Rank", 1) + Interpolate_Linear(0.25, 0.5, curChain/64), GetCommonData("MinRank", 1), GetCommonData("MaxRank", 12)));
|
||||
}
|
||||
|
||||
curChain = 1;
|
||||
|
||||
}
|
||||
|
||||
case(EV_PLAYER_SHOOTDOWN){
|
||||
|
||||
ObjSound_Play(PlayerDie2);
|
||||
SetPlayerSpell(0);
|
||||
ripplayer = true;
|
||||
DeleteShotAll(TYPE_SHOT, TYPE_ITEM);
|
||||
SetCommonData("Rank", clamp(GetCommonData("Rank", 1) * 0.75, GetCommonData("MinRank", 1), GetCommonData("MaxRank", 12)));
|
||||
_DeathMove();
|
||||
|
||||
}
|
||||
|
||||
case(EV_PLAYER_REBIRTH){
|
||||
ripplayer = false;
|
||||
SetPlayerInvincibilityFrame(180);
|
||||
//_Countdown();
|
||||
_SigilCall(false, teamimg, 768+256, 512, 768+512, 768, objPlayer, 150);
|
||||
|
||||
}
|
||||
|
||||
case(EV_GRAZE){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Finalize{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Basic player parameters
|
||||
|
||||
task Parameter(){
|
||||
|
||||
// im trying to not be collected by the player but their item scope is dummy thicc and im alerted by its cheek
|
||||
SetPlayerItemScope(360);
|
||||
|
||||
SetPlayerLife(9); // Debug
|
||||
SetPlayerSpell(0);
|
||||
SetPlayerSpeed(PlayerSpd[0], PlayerSpd[1]); // (original: 5.25/2.0)
|
||||
SetPlayerRebirthFrame(0); // No bombs
|
||||
SetPlayerDownStateFrame(90);
|
||||
SetPlayerAutoItemCollectLine(GetStgFrameHeight/3);
|
||||
SetPlayerRebirthLossFrame(0);
|
||||
ObjPlayer_AddIntersectionCircleA1(objPlayer, 0, 0, 2, 40);
|
||||
|
||||
}
|
||||
|
||||
// Player render
|
||||
|
||||
task RenderPlayer(){
|
||||
|
||||
// Why is this movement code so cursed jesus fucking christ
|
||||
|
||||
float scale = 1; // Scalies
|
||||
int frame = 0;
|
||||
int spd = 12;
|
||||
int frame_hbox = 0;
|
||||
|
||||
ObjPrim_SetTexture(objPlayer, plimg);
|
||||
ObjSprite2D_SetSourceRect(objPlayer, 0, 0, 192, 192);
|
||||
ObjSprite2D_SetDestCenter(objPlayer);
|
||||
Obj_SetRenderPriorityI(objPlayer, plrender);
|
||||
ObjRender_SetScaleXYZ(objPlayer, scale, scale, 1);
|
||||
|
||||
int hitbox = ObjPrim_Create(OBJ_SPRITE_2D);
|
||||
|
||||
ObjPrim_SetTexture(hitbox, plimg);
|
||||
ObjSprite2D_SetSourceRect(hitbox, 384, 0, 448, 64);
|
||||
ObjSprite2D_SetDestCenter(hitbox);
|
||||
ObjRender_SetScaleXYZ(hitbox, scale, scale, 1);
|
||||
ObjRender_SetBlendType(hitbox, BLEND_ALPHA);
|
||||
Obj_SetRenderPriorityI(hitbox, 79);
|
||||
|
||||
Obj_SetVisible(hitbox, false);
|
||||
|
||||
// Lower "speed" parameter = FASTER SPEED
|
||||
|
||||
// FOR WHEN ONLY IDLE SPRITES ARE DONE
|
||||
|
||||
while(true){
|
||||
|
||||
frame++;
|
||||
frame_hbox++;
|
||||
|
||||
ObjRender_SetPosition(hitbox, playerX, playerY, 1);
|
||||
|
||||
if(ripplayer){
|
||||
ObjSprite2D_SetSourceRect(objPlayer, 0, 384, 192, 576);
|
||||
Obj_SetVisible(hitbox, false);
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
if(GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE){
|
||||
|
||||
ObjSprite2D_SetSourceRect(hitbox, 384+64*floor(frame_hbox/9), 0, 64+384+64*floor(frame_hbox/9), 64);
|
||||
Obj_SetVisible(hitbox, true);
|
||||
|
||||
_RenderPlayerMovement(objPlayer, frame, 0, 192, 192, 192, scale, 2, spd);
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
_RenderPlayerMovement(objPlayer, frame, 0, 0, 192, 192, scale, 2, spd);
|
||||
|
||||
Obj_SetVisible(hitbox, false);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (frame >= (2*spd-1)){frame = 0;}
|
||||
if (frame_hbox >= (3*9-1)){frame_hbox = 0;}
|
||||
|
||||
yield;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
task _DeathMove(){
|
||||
|
||||
int afterimage = ObjPrim_Create(OBJ_SPRITE_2D);
|
||||
|
||||
ObjPrim_SetTexture(afterimage, plimg);
|
||||
ObjSprite2D_SetSourceRect(afterimage, 0, 384, 192, 576);
|
||||
ObjSprite2D_SetDestCenter(afterimage);
|
||||
ObjRender_SetBlendType(afterimage, BLEND_ALPHA);
|
||||
Obj_SetRenderPriorityI(afterimage, 40);
|
||||
|
||||
float[] curdest = [playerX, playerY];
|
||||
float[] dest = [clamp(playerX-256, 0, GetStgFrameWidth()), playerY];
|
||||
|
||||
SetPlayerRebirthPosition(dest[0], dest[1]);
|
||||
|
||||
ascent(i in 0..30){
|
||||
ObjRender_SetPosition(afterimage, Interpolate_Decelerate(curdest[0], dest[0], i/30), playerY, 1);
|
||||
yield;
|
||||
}
|
||||
|
||||
wait(60);
|
||||
|
||||
Obj_Delete(afterimage);
|
||||
|
||||
}
|
9
script/player/Narumi/Player_ShotConst.dnh
Normal file
9
script/player/Narumi/Player_ShotConst.dnh
Normal file
|
@ -0,0 +1,9 @@
|
|||
let current = GetCurrentScriptDirectory();
|
||||
let path = current ~ "Player_ShotData.dnh";
|
||||
LoadPlayerShotData(path);
|
||||
// -----
|
||||
|
||||
const AMULET = 1;
|
||||
const GOLEM = 2;
|
||||
|
||||
|
29
script/player/Narumi/Player_ShotData.dnh
Normal file
29
script/player/Narumi/Player_ShotData.dnh
Normal file
|
@ -0,0 +1,29 @@
|
|||
shot_image = "./playerlib/PlSheet_Narumi.png"
|
||||
|
||||
ShotData{
|
||||
id = 0 // Dummy
|
||||
rect = (0,0,0,0)
|
||||
render = ALPHA
|
||||
alpha = 0
|
||||
collision = 32
|
||||
}
|
||||
|
||||
// Fire
|
||||
|
||||
ShotData{
|
||||
id = 1
|
||||
rect = (640, 256, 768, 384)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
collision = 64 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
||||
|
||||
// Golem
|
||||
|
||||
ShotData{
|
||||
id = 2
|
||||
rect = (640, 0, 896, 256)
|
||||
render = ALPHA
|
||||
alpha = 255
|
||||
collision = 128 // Hitbox of arrows is not centered on the sprite
|
||||
}
|
0
script/player/Narumi/desc.txt
Normal file
0
script/player/Narumi/desc.txt
Normal file
BIN
script/player/Narumi/playerlib/PlSheet_Kouryuu.png
Normal file
BIN
script/player/Narumi/playerlib/PlSheet_Kouryuu.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
BIN
script/player/Narumi/playerlib/PlSheet_Narumi.png
Normal file
BIN
script/player/Narumi/playerlib/PlSheet_Narumi.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
BIN
script/player/Narumi/playerlib/RAW/KouryuuPalette.aseprite
Normal file
BIN
script/player/Narumi/playerlib/RAW/KouryuuPalette.aseprite
Normal file
Binary file not shown.
BIN
script/player/Narumi/playerlib/RAW/soGay.aseprite
Normal file
BIN
script/player/Narumi/playerlib/RAW/soGay.aseprite
Normal file
Binary file not shown.
BIN
script/player/Narumi/playerlib/RAW/soTrue.aseprite
Normal file
BIN
script/player/Narumi/playerlib/RAW/soTrue.aseprite
Normal file
Binary file not shown.
BIN
script/player/Narumi/sound/CK Music Factory/air01.wav
Normal file
BIN
script/player/Narumi/sound/CK Music Factory/air01.wav
Normal file
Binary file not shown.
BIN
script/player/Narumi/sound/CK Music Factory/air02.wav
Normal file
BIN
script/player/Narumi/sound/CK Music Factory/air02.wav
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue