Add existing file
This commit is contained in:
parent
9bedcb263d
commit
d6a4b8bf20
320 changed files with 20855 additions and 0 deletions
BIN
script/player/default_player/Default_Player_MagicCircle.png
Normal file
BIN
script/player/default_player/Default_Player_MagicCircle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
BIN
script/player/default_player/Default_Player_Rumia.png
Normal file
BIN
script/player/default_player/Default_Player_Rumia.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
script/player/default_player/Default_Player_Rumia.txt
Normal file
BIN
script/player/default_player/Default_Player_Rumia.txt
Normal file
Binary file not shown.
BIN
script/player/default_player/Default_Player_RumiaShot.png
Normal file
BIN
script/player/default_player/Default_Player_RumiaShot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
BIN
script/player/default_player/Default_Player_RumiaShotData.txt
Normal file
BIN
script/player/default_player/Default_Player_RumiaShotData.txt
Normal file
Binary file not shown.
BIN
script/player/default_player/Default_Player_RumiaSpell.png
Normal file
BIN
script/player/default_player/Default_Player_RumiaSpell.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
BIN
script/player/default_player/Default_Player_Rumia_Select.png
Normal file
BIN
script/player/default_player/Default_Player_Rumia_Select.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
BIN
script/player/default_player/laser_fx.png
Normal file
BIN
script/player/default_player/laser_fx.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
322
script/player/default_player/lasers.dnh
Normal file
322
script/player/default_player/lasers.dnh
Normal file
|
@ -0,0 +1,322 @@
|
|||
// Lasers that don't penetrate
|
||||
// Can be pasted into default player Rumia by adding `TLasers();` to @Initialize
|
||||
// Activation logic is focused-shooting with a slight delay, similar to CAVE games.
|
||||
// "RemovePLaserGfx()" can go into shutting-down (probably not necessary).
|
||||
// Made by razzy
|
||||
|
||||
task TLasers{
|
||||
|
||||
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 to 0.
|
||||
|
||||
let laserLimit = 15;
|
||||
let laserMode=-laserLimit;
|
||||
|
||||
loop{
|
||||
if(IsPermitPlayerShot
|
||||
&& GetPlayerState!=STATE_HIT
|
||||
&& GetPlayerState!=STATE_DOWN
|
||||
&& GetPlayerState!=STATE_END
|
||||
&& (GetVirtualKeyState(VK_SHOT)==KEY_PUSH || GetVirtualKeyState(VK_SHOT)==KEY_HOLD)
|
||||
){
|
||||
if(GetVirtualKeyState(VK_SLOWMOVE)==KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE)==KEY_HOLD){
|
||||
laserMode=min(0,laserMode+1);
|
||||
}
|
||||
else{
|
||||
// reset laser delay when slowmove is let go
|
||||
laserMode=-laserLimit;
|
||||
}
|
||||
|
||||
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, 2, true, 2, 2);
|
||||
}
|
||||
odd=-odd;
|
||||
}
|
||||
//PlaySnd(SND_p_shot, 93);
|
||||
}
|
||||
}
|
||||
else{
|
||||
// reset laser delay when fire is let go
|
||||
// KEV: Unnecessary if the laser fires immediately
|
||||
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, IsStrongLaser, 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: 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.
|
||||
let damager = ObjShot_Create(OBJ_STRAIGHT_LASER);
|
||||
ObjShot_SetGraphic(damager, 1);
|
||||
Obj_SetVisible(damager, false);
|
||||
ObjShot_Regist(damager);
|
||||
ObjShot_SetDamage(damager, dmg);
|
||||
ObjShot_SetPenetration(damager, 8);
|
||||
ObjLaser_SetLength(damager, 0);
|
||||
ObjLaser_SetIntersectionWidth(damager, 64*width);
|
||||
ObjLaser_SetRenderWidth(damager, 64*vwidth);
|
||||
ObjStLaser_SetAngle(damager, ang);
|
||||
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(!Obj_IsDeleted(damager) // KEV: The four following states can be reduced to !ripplayer in my player scripts
|
||||
&& IsPermitPlayerShot
|
||||
&& GetPlayerState!=STATE_HIT
|
||||
&& GetPlayerState!=STATE_DOWN
|
||||
&& GetPlayerState!=STATE_END // Reduce these below to != KEY_FREE
|
||||
&& (GetVirtualKeyState(VK_SHOT)==KEY_PUSH || GetVirtualKeyState(VK_SHOT)==KEY_HOLD)
|
||||
&& (GetVirtualKeyState(VK_SLOWMOVE)==KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE)==KEY_HOLD)
|
||||
){
|
||||
CheckLaserIntersection;
|
||||
|
||||
// Set the laser's position and length
|
||||
ObjMove_SetPosition(damager, ObjRender_GetX(obj)+xoff,ObjRender_GetY(obj)+yoff);
|
||||
len = min(maxLen, len+spd);
|
||||
ObjLaser_SetLength(damager, len);
|
||||
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>8){
|
||||
MakeLaserGfxFrame;
|
||||
len=max(0,len-spd);
|
||||
ObjLaser_SetLength(damager, len);
|
||||
CheckLaserIntersection;
|
||||
yield;
|
||||
}
|
||||
Obj_Delete(damager);
|
||||
|
||||
function MakeLaserGfxFrame(){
|
||||
let hyper=0;
|
||||
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.
|
||||
|
||||
(The color values should be unnecessary.)
|
||||
|
||||
*/
|
||||
|
||||
// ObjStLaser_SetEndGraphic (ph3sx) may come in handy for the base/tips.
|
||||
|
||||
// !IsStrongLaser = 0, IsStrongLaser = 1
|
||||
|
||||
PLaserGfxFrameLaser(lasGfxObj[0], 32+hyper*32+!IsStrongLaser*64, scroll, 63+hyper*32+!IsStrongLaser*64, (len-1)/4+scroll, 64, ObjMove_GetX(damager)+cosine*24, ObjMove_GetY(damager)+sine*24, ang+90, vwidth*rand(0.75,1.0),gLen/64, 255, 255, 255, 255);
|
||||
|
||||
PLaserGfxFrameLaser(lasGfxObj[1], 32+hyper*32+!IsStrongLaser*64, scroll, 63+hyper*32+!IsStrongLaser*64, (len-1)/4+scroll, 64, ObjMove_GetX(damager)+cosine*24, ObjMove_GetY(damager)+sine*24, ang+90, vwidth*rand(0.75,1.0), gLen/64, 255, 255, 255, 48);
|
||||
|
||||
PLaserGfxFrame(lasGfxObj[2], 160, 0, 191, 31, ObjMove_GetX(damager)+cosine*24, ObjMove_GetY(damager)+sine*24, ang+90, vwidth+rand(0.4, 0.5), 6, 255,255,255, 255); // Base of laser
|
||||
|
||||
PLaserGfxFrame(lasGfxObj[2], 160, 32, 191, 63, ObjMove_GetX(damager)+cosine*gLen2, ObjMove_GetY(damager)+sine*gLen2, ang+90, vwidth+rand(0.4, 0.5), 6, 255, 255, 255, 255);// Tip of laser
|
||||
|
||||
scroll += 3; // Scrolls the laser's graphic.
|
||||
|
||||
}
|
||||
|
||||
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(!IsStrongLaser || 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.
|
||||
|
||||
(I don't know the order the hitboxes will be sorted in the array, though. For all I know, coords[0][1] may be the second hitbox's y (32)...?)
|
||||
|
||||
*/
|
||||
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
|
||||
|
||||
if(length(closest) > 0){
|
||||
let dist=closest[2]-16;
|
||||
len=max(0,dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // 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() ~ "laser_fx.png";
|
||||
LoadTexture(imgLaser);
|
||||
|
||||
ascent(i in 0..3){
|
||||
let gfx = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
|
||||
ObjPrim_SetTexture(gfx, imgLaser);
|
||||
Obj_SetRenderPriorityI(gfx, 41);
|
||||
lasGfxObj = lasGfxObj~[gfx];
|
||||
}
|
||||
ObjRender_SetBlendType(lasGfxObj[1], BLEND_ADD_ARGB);
|
||||
Obj_SetRenderPriorityI(lasGfxObj[2], 42);
|
||||
|
||||
while(true){
|
||||
ascent(i in 0..length(lasGfxObj)){
|
||||
ObjSpriteList2D_ClearVertexCount(lasGfxObj[i]);
|
||||
}
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
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(gfxObj, u, v, u2, v2, x, y, ang, sx, sy, rd, gn, bl, al){
|
||||
if(gfxObj==ID_INVALID){return;}
|
||||
|
||||
ObjRender_SetPosition(gfxObj, x, y, 0);
|
||||
ObjRender_SetAngleZ(gfxObj, ang);
|
||||
ObjRender_SetScaleXYZ(gfxObj, sx, sy, 1);
|
||||
ObjRender_SetColor(gfxObj, rd, gn, bl);
|
||||
ObjRender_SetAlpha(gfxObj, al);
|
||||
ObjSpriteList2D_SetSourceRect(gfxObj, u, v, u2, v2);
|
||||
ObjSpriteList2D_SetDestCenter(gfxObj);
|
||||
ObjSpriteList2D_AddVertex(gfxObj);
|
||||
}
|
||||
|
||||
task PLaserGfxFrameLaser(gfxObj, u, v, u2, v2, ry, x, y, ang, sx, sy, rd, gn, bl, al){
|
||||
if(gfxObj==ID_INVALID){return;}
|
||||
|
||||
ObjRender_SetPosition(gfxObj, x,y,0);
|
||||
ObjRender_SetAngleZ(gfxObj, ang);
|
||||
ObjRender_SetScaleXYZ(gfxObj, sx ,sy, 1);
|
||||
ObjRender_SetColor(gfxObj, rd,gn,bl);
|
||||
ObjRender_SetAlpha(gfxObj, al);
|
||||
ObjSpriteList2D_SetSourceRect(gfxObj, u, v, u2, v2);
|
||||
let rx=(u2-u)/2;
|
||||
ObjSpriteList2D_SetDestRect(gfxObj, -rx,0,rx,-ry);
|
||||
ObjSpriteList2D_AddVertex(gfxObj);
|
||||
}
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue