365 lines
8.3 KiB
Plaintext
365 lines
8.3 KiB
Plaintext
|
#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);
|
||
|
|
||
|
}
|