737 lines
20 KiB
Plaintext
737 lines
20 KiB
Plaintext
|
#TouhouDanmakufu[Player]
|
||
|
#ScriptVersion[3]
|
||
|
#ID["Chimata"]
|
||
|
#Title["Chimata Tenkyuu"]
|
||
|
#Text["Shot Type: Blank Card Set[r]Spell Card: Shield of Market Regulation"]
|
||
|
|
||
|
//#Image["./mariremi_lib/mariremi_illust.png"]
|
||
|
|
||
|
#ReplayName["Chimata"]
|
||
|
|
||
|
#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"
|
||
|
|
||
|
let csd = GetCurrentScriptDirectory();
|
||
|
|
||
|
// Global Variables
|
||
|
|
||
|
float maxX = GetStgFrameWidth();
|
||
|
float maxY = GetStgFrameHeight();
|
||
|
|
||
|
// Images & Sound
|
||
|
|
||
|
let teamimg = csd ~ "./playerlib/Chimata_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;
|
||
|
|
||
|
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
|
||
|
|
||
|
float[] PlayerSpd = [10, 5.35];
|
||
|
|
||
|
// 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);
|
||
|
}
|
||
|
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);
|
||
|
|
||
|
_HitboxRender(ripplayer, objPlayer, teamimg, teamimg, 1280, 512, 1408, 640, 1536, 896, 2048, 1408, 0.3, 0.65);
|
||
|
SetShotAutoDeleteClip(256, 256, 256, 256);
|
||
|
|
||
|
// Shot functions
|
||
|
|
||
|
//_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){
|
||
|
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);
|
||
|
//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();
|
||
|
_SigilCall(false, teamimg, 768+256, 512, 768+512, 768, objPlayer, GetPlayerInvincibilityFrame());
|
||
|
}
|
||
|
|
||
|
else {
|
||
|
SetScriptResult(false);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
case(EV_HIT){
|
||
|
ObjSound_Play(predeathsfx);
|
||
|
_DeathbombWarning(teamimg, [1536, 384, 1536+512, 384+512], 15, 0.75);
|
||
|
}
|
||
|
|
||
|
case(EV_PLAYER_SHOOTDOWN){
|
||
|
ObjSound_Play(deathsfx);
|
||
|
ripplayer = true;
|
||
|
_SigilCall(true, teamimg, 768, 512, 768+256, 768, objPlayer, 120);
|
||
|
}
|
||
|
|
||
|
case(EV_PLAYER_REBIRTH){
|
||
|
ripplayer = false;
|
||
|
SetPlayerInvincibilityFrame(180);
|
||
|
_SigilCall(false, teamimg, 768+256, 512, 768+512, 768, objPlayer, 150);
|
||
|
SetPlayerSpell( max(2,GetPlayerSpell()) );
|
||
|
}
|
||
|
|
||
|
case(EV_GRAZE){
|
||
|
grazecounter += GetEventArgument(0);
|
||
|
ObjSound_Play(grazesfx);
|
||
|
while(grazecounter >= 10){
|
||
|
SetAreaCommonData("PIV", "currentvalue", GetAreaCommonData("PIV", "currentvalue")+10);
|
||
|
grazecounter -= 10;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Finalize{
|
||
|
|
||
|
}
|
||
|
|
||
|
// Homing
|
||
|
|
||
|
task _HomeShot(int option_) {
|
||
|
|
||
|
int shot_ = 0;
|
||
|
|
||
|
float duration = 1;
|
||
|
float durationOption = 99999;
|
||
|
|
||
|
bool homingBool = false;
|
||
|
|
||
|
float basepenetrate = ObjShot_GetPenetration(shot_);
|
||
|
float basedmg = ObjShot_GetDamage(shot_);
|
||
|
|
||
|
//
|
||
|
|
||
|
for (int t = 0i; t < durationOption && !Obj_IsDeleted(option_); 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(objPlayer), enemyY - ObjMove_GetY(objPlayer));
|
||
|
|
||
|
// 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 < durationOption && !Obj_IsDeleted(option_) && !Obj_IsDeleted(targetID) && ObjEnemy_GetInfo(targetID, INFO_LIFE) != 0 && GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE; t++) {
|
||
|
|
||
|
ObjShot_SetAutoDelete(option_, false);
|
||
|
|
||
|
float shotAngle = NormalizeAngle(ObjMove_GetAngle(option_)); // Angle of the player shot
|
||
|
float targetAngle = NormalizeAngle(atan2(ObjMove_GetY(targetID) - ObjMove_GetY(option_), ObjMove_GetX(targetID) - ObjMove_GetX(option_))); // 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.75, min(15, f) / 15);
|
||
|
// Homing speed?
|
||
|
ObjMove_SetAngle(option_, Interpolate_Decelerate(shotAngle, shotAngle + angleDistance, homeRate)); // Interpolate_Necko
|
||
|
f++;
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*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.75, min(60, f) / 60);
|
||
|
// Homing speed?
|
||
|
ObjMove_SetAngle(shot_, Interpolate_Accelerate(shotAngle, shotAngle + angleDistance, 1)); // Interpolate_Necko
|
||
|
f++;
|
||
|
yield;
|
||
|
}
|
||
|
ObjShot_SetAutoDelete(shot_, true);
|
||
|
ObjMove_SetAngularVelocity(shot_, 0);
|
||
|
homingBool = false;
|
||
|
}*/
|
||
|
}
|
||
|
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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(){
|
||
|
|
||
|
// Offsets for 4 front options
|
||
|
|
||
|
// Alternative player option function
|
||
|
|
||
|
function PlayerOption(
|
||
|
float offsetx, float offsety,
|
||
|
texture,
|
||
|
int left, int top, int right, int bottom, float scale,
|
||
|
int width, int animdelay, int frameno, bool triggeranimation,
|
||
|
bool triggerspin, float spinspeed,
|
||
|
bool onlyFocus, bool onlyUnfocus
|
||
|
){
|
||
|
// IMPORTANT!
|
||
|
let option = ObjShot_Create(OBJ_SHOT);
|
||
|
ObjShot_Regist(option);
|
||
|
ObjShot_SetAutoDelete(option, false);
|
||
|
ObjShot_SetGraphic(option, 3);
|
||
|
ObjShot_SetPenetration(option, 9999^9999);
|
||
|
ObjShot_SetDamage(option, 0);
|
||
|
ObjShot_SetIntersectionEnable(option, false);
|
||
|
ObjMove_SetAngle(option, 270);
|
||
|
//
|
||
|
|
||
|
bool visible;
|
||
|
int animate = 0;
|
||
|
float optx;
|
||
|
float opty;
|
||
|
|
||
|
ObjRender_SetScaleXYZ(option, scale);
|
||
|
ObjRender_SetBlendType(option, BLEND_ALPHA);
|
||
|
ObjRender_SetAlpha(option, 225);
|
||
|
Obj_SetRenderPriorityI(option, 41);
|
||
|
ObjRender_SetPosition(option, offsetx, offsety, 1);
|
||
|
|
||
|
// Animation
|
||
|
async{
|
||
|
while(triggeranimation){
|
||
|
ObjSprite2D_SetSourceRect(option, left+width*floor(animate/animdelay), top, right+width*floor(animate/animdelay)-1, bottom-1);
|
||
|
animate++;
|
||
|
if (animate >= animdelay*frameno){animate = 0;}
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Rotation
|
||
|
async{
|
||
|
float i = 0;
|
||
|
while(triggerspin){
|
||
|
//ObjRender_SetPosition(option, GetPlayerX()+offsetx, GetPlayerY()+offsety, 1);
|
||
|
ObjRender_SetAngleZ(option, i);
|
||
|
i += spinspeed;
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Follow
|
||
|
async{
|
||
|
while(true){
|
||
|
ObjMove_SetPosition(option, GetPlayerX()+offsetx, GetPlayerY()+offsety);
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Visibility
|
||
|
async{
|
||
|
// Always visible
|
||
|
if((onlyFocus && onlyUnfocus) || (!onlyFocus && !onlyUnfocus)) {
|
||
|
loop
|
||
|
{
|
||
|
if(GetPlayerState != STATE_NORMAL && GetPlayerState != STATE_HIT){ObjRender_SetAlpha(option, max(0, ObjRender_GetAlpha(option)-15)); visible = false;}
|
||
|
else {ObjRender_SetAlpha(option, min(225, ObjRender_GetAlpha(option)+15)); visible = true;}
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
// Visible when focused only
|
||
|
else if(onlyFocus && !onlyUnfocus){
|
||
|
loop
|
||
|
{
|
||
|
if((GetPlayerState != STATE_NORMAL && GetPlayerState != STATE_HIT) || GetVirtualKeyState(VK_SLOWMOVE) == KEY_FREE){ObjRender_SetAlpha(option, max(0, ObjRender_GetAlpha(option)-15)); visible = false;}
|
||
|
else {ObjRender_SetAlpha(option, min(225, ObjRender_GetAlpha(option)+15)); visible = true;}
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
// Visible when unfocused only
|
||
|
else if(!onlyFocus && onlyUnfocus){
|
||
|
loop
|
||
|
{
|
||
|
if((GetPlayerState != STATE_NORMAL && GetPlayerState != STATE_HIT) || GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE){ObjRender_SetAlpha(option, max(0, ObjRender_GetAlpha(option)-15)); visible = false;}
|
||
|
else {ObjRender_SetAlpha(option, min(225, ObjRender_GetAlpha(option)+15)); visible = true;}
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function _FadeIn(){
|
||
|
ascent(i in 0..15){
|
||
|
ObjRender_SetAlpha(option, Interpolate_Decelerate(0, 225, i/15));
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function _FadeOut(){
|
||
|
ascent(i in 0..15){
|
||
|
ObjRender_SetAlpha(option, Interpolate_Decelerate(225, 0, i/15));
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return option;
|
||
|
|
||
|
}
|
||
|
|
||
|
float offsetX1 = 125;
|
||
|
float offsetX2 = offsetX1 * 2;
|
||
|
float offsetY1 = 75;
|
||
|
|
||
|
// Array that contains static/unchanging values for the PlayerOption
|
||
|
|
||
|
let val = [0, 512, 256, 768, 0.3, 256, 1, 1, false, false, 0, true, true];
|
||
|
|
||
|
// Option handling (right -> rightmost -> left -> leftmost)
|
||
|
|
||
|
float[][] offsetArray = [[offsetX1, offsetY1], [offsetX2, 0], [-offsetX1, offsetY1], [-offsetX2, 0]];
|
||
|
|
||
|
int opt1 = PlayerOption(
|
||
|
offsetArray[0][0], offsetArray[0][1],
|
||
|
teamimg,
|
||
|
val[0], val[1], val[2], val[3], val[4],
|
||
|
val[5], val[6], val[7], val[8],
|
||
|
val[9], val[10],
|
||
|
val[11], val[12]);
|
||
|
|
||
|
int opt2 = PlayerOption(
|
||
|
offsetArray[1][0], offsetArray[1][1],
|
||
|
teamimg,
|
||
|
val[0], val[1], val[2], val[3], val[4],
|
||
|
val[5], val[6], val[7], val[8],
|
||
|
val[9], val[10],
|
||
|
val[11], val[12]);
|
||
|
|
||
|
int opt3 = PlayerOption(
|
||
|
offsetArray[2][0], offsetArray[2][1],
|
||
|
teamimg,
|
||
|
val[0], val[1], val[2], val[3], val[4],
|
||
|
val[5], val[6], val[7], val[8],
|
||
|
val[9], val[10],
|
||
|
val[11], val[12]);
|
||
|
|
||
|
int opt4 = PlayerOption(
|
||
|
offsetArray[3][0], offsetArray[3][1],
|
||
|
teamimg,
|
||
|
val[0], val[1], val[2], val[3], val[4],
|
||
|
val[5], val[6], val[7], val[8],
|
||
|
val[9], val[10],
|
||
|
val[11], val[12]);
|
||
|
|
||
|
int[] optArray = [opt1, opt2, opt3, opt4];
|
||
|
|
||
|
_HomingStars(optArray[0], 0); _HomeShot(optArray[0]);
|
||
|
_HomingStars(optArray[1], 1); _HomeShot(optArray[1]);
|
||
|
_HomingStars(optArray[2], 2); _HomeShot(optArray[2]);
|
||
|
_HomingStars(optArray[3], 3); _HomeShot(optArray[3]);
|
||
|
|
||
|
task _HomingStars(option, value){
|
||
|
|
||
|
loop{
|
||
|
|
||
|
if(GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE){
|
||
|
|
||
|
async{
|
||
|
|
||
|
if(value == 0){
|
||
|
|
||
|
ascent(i in 0..15){
|
||
|
ObjMove_SetX(option, Interpolate_Decelerate(ObjMove_GetX(option), playerX+offsetX1, i/15));
|
||
|
ObjMove_SetY(option, Interpolate_Decelerate(ObjMove_GetY(option), playerY+offsetY1, i/15));
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
else if(value == 1){
|
||
|
|
||
|
ascent(i in 0..15){
|
||
|
ObjMove_SetX(option, Interpolate_Decelerate(ObjMove_GetX(option), playerX+offsetX1*2, i/15));
|
||
|
ObjMove_SetY(option, Interpolate_Decelerate(ObjMove_GetY(option), playerY, i/15));
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
else if(value == 2){
|
||
|
|
||
|
ascent(i in 0..15){
|
||
|
ObjMove_SetX(option, Interpolate_Decelerate(ObjMove_GetX(option), playerX-offsetX1, i/15));
|
||
|
ObjMove_SetY(option, Interpolate_Decelerate(ObjMove_GetY(option), playerY+offsetY1, i/15));
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
else if(value == 3){
|
||
|
|
||
|
ascent(i in 0..15){
|
||
|
ObjMove_SetX(option, Interpolate_Decelerate(ObjMove_GetX(option), playerX-offsetX1*2, i/15));
|
||
|
ObjMove_SetY(option, Interpolate_Decelerate(ObjMove_GetY(option), playerY, i/15));
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
async{
|
||
|
if(GetVirtualKeyState(VK_SHOT) != KEY_FREE && IsPermitPlayerShot && !ripplayer){
|
||
|
|
||
|
if(shotspeed % 5 == 0){
|
||
|
float x = ObjRender_GetX(option);
|
||
|
float y = ObjRender_GetY(option);
|
||
|
|
||
|
ascent(i in -1..1){
|
||
|
let shotA = CreatePlayerShotA1(-50+x+25-50*i, y, 50, ObjMove_GetAngle(option), 2, 1.1, 2);
|
||
|
_BulletRescalePlayer(shotA, 0.7, true, 1);
|
||
|
ObjRender_SetAlpha(shotA, 255*(universalAlpha/100));
|
||
|
Obj_SetRenderPriorityI(shotA, 39);
|
||
|
ObjSound_Play(basesfx);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
else{
|
||
|
|
||
|
async{
|
||
|
|
||
|
if(value == 0){
|
||
|
|
||
|
ascent(i in 0..15){
|
||
|
ObjMove_SetAngle(option, Interpolate_Decelerate(ObjMove_GetAngle(option), 275, i/15));
|
||
|
ObjMove_SetX(option, Interpolate_Decelerate(ObjMove_GetX(option), playerX+offsetX1*0.45, i/15));
|
||
|
ObjMove_SetY(option, Interpolate_Decelerate(ObjMove_GetY(option), playerY+offsetY1, i/15));
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
else if(value == 1){
|
||
|
|
||
|
ascent(i in 0..15){
|
||
|
ObjMove_SetAngle(option, Interpolate_Decelerate(ObjMove_GetAngle(option), 295, i/15));
|
||
|
ObjMove_SetX(option, Interpolate_Decelerate(ObjMove_GetX(option), playerX+offsetX1*0.75, i/15));
|
||
|
ObjMove_SetY(option, Interpolate_Decelerate(ObjMove_GetY(option), playerY, i/15));
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
else if(value == 2){
|
||
|
|
||
|
ascent(i in 0..15){
|
||
|
ObjMove_SetAngle(option, Interpolate_Decelerate(ObjMove_GetAngle(option), 265, i/15));
|
||
|
ObjMove_SetX(option, Interpolate_Decelerate(ObjMove_GetX(option), playerX-offsetX1*0.45, i/15));
|
||
|
ObjMove_SetY(option, Interpolate_Decelerate(ObjMove_GetY(option), playerY+offsetY1, i/15));
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
else if(value == 3){
|
||
|
|
||
|
ascent(i in 0..15){
|
||
|
ObjMove_SetAngle(option, Interpolate_Decelerate(ObjMove_GetAngle(option), 245, i/15));
|
||
|
ObjMove_SetX(option, Interpolate_Decelerate(ObjMove_GetX(option), playerX-offsetX1*0.75, i/15));
|
||
|
ObjMove_SetY(option, Interpolate_Decelerate(ObjMove_GetY(option), playerY, i/15));
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
async{
|
||
|
if(GetVirtualKeyState(VK_SHOT) != KEY_FREE && IsPermitPlayerShot && !ripplayer){
|
||
|
|
||
|
if(shotspeed % 5 == 0){
|
||
|
float x = ObjRender_GetX(option);
|
||
|
float y = ObjRender_GetY(option);
|
||
|
|
||
|
ascent(i in -1..1){
|
||
|
let shotA = CreatePlayerShotA1(-50+x+25-50*i, y, 50, ObjMove_GetAngle(option), 2.6, 1.1, 1);
|
||
|
_BulletRescalePlayer(shotA, 0.7, true, 1);
|
||
|
ObjRender_SetAlpha(shotA, 255*(universalAlpha/100));
|
||
|
Obj_SetRenderPriorityI(shotA, 39);
|
||
|
ObjSound_Play(basesfx);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// Basic player parameters
|
||
|
|
||
|
task parameterrender(){
|
||
|
|
||
|
SetPlayerItemScope(120);
|
||
|
SetPlayerLife(9); // Debug
|
||
|
SetPlayerSpell(2);
|
||
|
SetPlayerSpeed(PlayerSpd[0], PlayerSpd[1]); // (original: 5.25/2.0)
|
||
|
SetPlayerRebirthFrame(12);
|
||
|
SetPlayerAutoItemCollectLine(GetStgFrameHeight/3);
|
||
|
SetPlayerRebirthLossFrame(0);
|
||
|
ObjPlayer_AddIntersectionCircleA1(objPlayer, 0, 0, 1.25, 40);
|
||
|
|
||
|
}
|
||
|
|
||
|
// Renders the shottype
|
||
|
// Player sprites
|
||
|
|
||
|
task playerrender(){
|
||
|
|
||
|
// Why is this movement code so cursed jesus fucking christ
|
||
|
|
||
|
float scale = 0.32; // Scalies
|
||
|
int frame = 0;
|
||
|
|
||
|
ObjPrim_SetTexture(objPlayer, teamimg);
|
||
|
ObjSprite2D_SetSourceRect(objPlayer, 0, 0, 400, 400);
|
||
|
ObjSprite2D_SetDestCenter(objPlayer);
|
||
|
Obj_SetRenderPriorityI(objPlayer, 42);
|
||
|
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, 400, 400, scale, 4, 6);
|
||
|
if (frame >= (5*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
|
||
|
SetForbidPlayerShot(true);
|
||
|
SetForbidPlayerSpell(true);
|
||
|
SetPlayerInvincibilityFrame(32*3+32*3+42*3+120+45);
|
||
|
// Spell object
|
||
|
let manageObj = GetSpellManageObject(); // SPELL BEGINS
|
||
|
ObjSpell_Regist(manageObj);
|
||
|
ObjSound_Play(bombsfx);
|
||
|
SetPlayerSpeed(PlayerSpd[0]*1.5, PlayerSpd[0]*1.5);
|
||
|
|
||
|
int hakkero = CreatePlayerShotA1(playerX, playerY, 0, 0, 12, 999999, 4);
|
||
|
ObjShot_SetIntersectionEnable(hakkero, true);
|
||
|
ObjShot_SetEraseShot(hakkero, true);
|
||
|
ObjShot_SetSpellFactor(hakkero, true);
|
||
|
|
||
|
async{
|
||
|
ascent(i in 0..45){
|
||
|
_BulletRescalePlayer(hakkero, Interpolate_Decelerate(0.1, 1, i/45), true, 1);
|
||
|
ObjRender_SetAlpha(hakkero, Interpolate_Decelerate(0, 255, i/45));
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ascent(i in 0..240){
|
||
|
ObjMove_SetPosition(hakkero, playerX, playerY);
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
// Cleanup, end of spell
|
||
|
ObjShot_FadeDelete(hakkero);
|
||
|
SetPlayerSpeed(PlayerSpd[0], PlayerSpd[1]);
|
||
|
SetForbidPlayerShot(false);
|
||
|
wait(60);
|
||
|
SetForbidPlayerSpell(false);
|
||
|
Obj_Delete(manageObj); // !!! IMPORTANT !!!
|
||
|
|
||
|
}
|
||
|
|
||
|
// Screenshake function for bomb's duration - adapted from Sparen's tutorials
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|