510 lines
13 KiB
Plaintext
510 lines
13 KiB
Plaintext
// Item script
|
|
|
|
float widthSTG = GetStgFrameWidth();
|
|
float heightSTG = GetStgFrameHeight();
|
|
|
|
float PIV = 0;
|
|
|
|
let POINTER_PIV = LoadAreaCommonDataValuePointer("PIV", "currentvalue", 1000);
|
|
|
|
let POINTER_CHAIN = LoadAreaCommonDataValuePointer("PIV", "ChainAmount", 1);
|
|
let POINTER_CHAINGAUGE = LoadAreaCommonDataValuePointer("PIV", "ChainGauge", 0);
|
|
let POINTER_SPECIALAMMO = LoadAreaCommonDataValuePointer("PIV", "SpecialAmmo", 100);
|
|
let POINTER_SPECIALCHECK = LoadAreaCommonDataValuePointer("PIV", "IsUsingSpecial", false);
|
|
let POINTER_CHAINCHECK = LoadAreaCommonDataValuePointer("PIV", "IsChaining", false);
|
|
|
|
int SPECIAL_BOOST_COUNT = 0;
|
|
|
|
float rateReduceNormal = 100/120;
|
|
float rateReduceCashin = 100/180;
|
|
|
|
#include "script/KevinSystem/kevin_system/Lib_Const.dnh"
|
|
|
|
#include "./Kevin_ItemConst.txt"
|
|
#include "./Kevin_ItemLib.txt"
|
|
#include "./ItemSoundLib.txt"
|
|
|
|
// Chain system: Crystals fill up your chain amount, up to a max of 64x
|
|
// When you use a bomb (IsBomb), items get cancelled into golden point items worth 10000 x Chain Amount (max 640000 per item)
|
|
|
|
@Initialize{
|
|
|
|
SetAutoDeleteObject(true);
|
|
_ItemSoundTask();
|
|
SetDefaultBonusItemEnable(false);
|
|
LoadItemData(GetCurrentScriptDirectory ~ "./Kevin_ItemData.txt");
|
|
|
|
SetAreaCommonData("ScriptID", "ItemID", GetOwnScriptID());
|
|
//SetCommonDataPtr("ItemIDPtr", GetOwnScriptID());
|
|
|
|
}
|
|
|
|
int objPlayer = GetPlayerObjectID();
|
|
float tmpSpd = 0, tmpScl = 0, tmpMtp = 0;
|
|
|
|
@MainLoop{
|
|
|
|
PIV = GetCommonDataPtr(POINTER_PIV, 1000);
|
|
|
|
for each(item in GetItemIdInCircleA1(widthSTG/2, heightSTG/2, heightSTG)){
|
|
|
|
tmpSpd = ObjMove_GetSpeed(item);
|
|
tmpMtp = ObjItem_IsMoveToPlayer(item);
|
|
|
|
if(tmpSpd >= 0){
|
|
if (!tmpMtp && GetPlayerState() != STATE_DOWN){
|
|
ObjItem_SetMoveToPlayer(item, true);
|
|
}
|
|
}
|
|
|
|
if(tmpMtp) {
|
|
ObjMove_SetAngle(item, GetAngleToPlayer(item));
|
|
ObjMove_SetAcceleration(item, 1);
|
|
ObjMove_SetMaxSpeed(item, 24);
|
|
}
|
|
|
|
}
|
|
|
|
yield;
|
|
}
|
|
|
|
@Event
|
|
{
|
|
alternative (GetEventType())
|
|
case (EV_GET_ITEM){
|
|
|
|
let obj = GetEventArgument(0);
|
|
|
|
alternative(obj)
|
|
|
|
case(POINT_REGULAR){
|
|
|
|
AddScore(1000);
|
|
ObjSound_Play(CancelSFX);
|
|
SetCommonDataPtr(POINTER_SPECIALAMMO, min(100, GetCommonDataPtr(POINTER_SPECIALAMMO, 100)+0.1));
|
|
SetCommonDataPtr(POINTER_PIV, GetCommonDataPtr(POINTER_PIV, 1000)+50);
|
|
|
|
}
|
|
|
|
case(POINT_BHESTIE) { AddScore(2*GetCommonDataPtr(POINTER_PIV, 10000)); ObjSound_Play(SpecialItemSFX);}
|
|
|
|
// Rainbow point items give 10000 x Chain Counter
|
|
|
|
case(POINT_GOLD_SMALL) { AddScore(GetCommonDataPtr(POINTER_CHAIN, 1)*GetCommonDataPtr(POINTER_PIV, 10000)); ObjSound_Play(SpecialItemSFX);}
|
|
|
|
case(POINT_GOLD_MEDIUM) { AddScore(GetCommonDataPtr(POINTER_CHAIN, 1)*GetCommonDataPtr(POINTER_PIV, 10000)); ObjSound_Play(SpecialItemSFX);}
|
|
|
|
case(POINT_GOLD_LARGE) {
|
|
|
|
AddScore(GetCommonDataPtr(POINTER_PIV, 1000));
|
|
ObjSound_Play(SpecialItemSFX);
|
|
|
|
}
|
|
|
|
case(POINT_CANCEL) { AddScore(0.05*GetCommonDataPtr(POINTER_PIV, 10000)); ObjSound_Play(CancelSFX);}
|
|
|
|
case(EXTEND_LIFE) { AddScore(GetCommonDataPtr(POINTER_PIV, 10000)); SetPlayerLife(GetPlayerLife()+1); ObjSound_Play(SpellSFX);}
|
|
|
|
case(EXTEND_SPELL) { AddScore(GetCommonDataPtr(POINTER_PIV, 10000)); SetPlayerSpell(GetPlayerSpell()+1); ObjSound_Play(SpecialItemSFX);}
|
|
|
|
// CHAIN ITEM
|
|
|
|
case(PIV_250) {
|
|
|
|
if (GetCommonDataPtr(POINTER_SPECIALCHECK, false) == true){
|
|
|
|
if(SPECIAL_BOOST_COUNT <= 90 && GetCommonDataPtr(POINTER_CHAIN, 1) >= 48){
|
|
|
|
SetCommonDataPtr(POINTER_CHAINGAUGE, min(100, GetCommonDataPtr(POINTER_CHAINGAUGE, 0)+ rateReduceCashin * 5 * (1 - SPECIAL_BOOST_COUNT/90)));
|
|
SPECIAL_BOOST_COUNT++;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
if(GetCommonDataPtr(POINTER_CHAIN, 1) <= 1){
|
|
|
|
SetCommonDataPtr(POINTER_CHAINGAUGE, 100);
|
|
|
|
}
|
|
|
|
SetCommonDataPtr(POINTER_CHAIN, min(64, GetCommonDataPtr(POINTER_CHAIN, 1)+0.15));
|
|
SetCommonDataPtr(POINTER_CHAINGAUGE, min(100, GetCommonDataPtr(POINTER_CHAINGAUGE, 0)+ rateReduceNormal * 20));
|
|
|
|
SPECIAL_BOOST_COUNT = 0;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
case(PIV_500) { SetCommonDataPtr(POINTER_PIV, GetCommonDataPtr(POINTER_PIV, 10000)+500);}
|
|
|
|
case(SPECIAL_AMMO) {
|
|
|
|
SetCommonDataPtr(POINTER_SPECIALAMMO, min(100, GetCommonDataPtr(POINTER_SPECIALAMMO, 100)+0.2));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case (EV_DELETE_SHOT_TO_ITEM){
|
|
|
|
float[] position = GetEventArgument(1);
|
|
|
|
if(GetCommonDataPtr(POINTER_SPECIALCHECK, true) == true && IsPlayerSpellActive() != true && GetPlayerState() == STATE_NORMAL){
|
|
CreateScoreItem(POINT_GOLD_LARGE, position[0], position[1]);
|
|
} // Kouryuu special weapon
|
|
else{
|
|
CreateScoreItem(POINT_REGULAR, position[0], position[1]);
|
|
} // Death or bomb
|
|
|
|
}
|
|
|
|
case (EV_CANCEL_ITEM) {
|
|
|
|
let obj = GetEventArgument(0);
|
|
let type = GetEventArgument(1);
|
|
|
|
//ObjItem_SetMoveToPlayer(obj, false);
|
|
ObjMove_CancelMovement(obj);
|
|
|
|
//_CancelHandling(obj, type);
|
|
|
|
}
|
|
|
|
case (EV_COLLECT_ITEM){
|
|
|
|
let obj = GetEventArgument(0);
|
|
let type = GetEventArgument(1);
|
|
let typeCollect = GetEventArgument(2);
|
|
|
|
//WriteLog(type);
|
|
//_MoveToPlayer(obj, type, typeCollect); // Separate task is used to move the object to the player at customized speeds.
|
|
|
|
}
|
|
|
|
// Drops point items depending on how close you were to the enemy when you killed them.
|
|
/*
|
|
Event arguments:
|
|
|
|
0: PlayerID
|
|
1: EnemyID
|
|
2: Minimum number of point items
|
|
3: Maximum number of point items
|
|
|
|
*/
|
|
|
|
case(EV_DROP_POINT_ENEMY){
|
|
|
|
_DropPointItem(GetEventArgument(0), GetEventArgument(1), GetEventArgument(2), GetEventArgument(3), GetEventArgument(4));
|
|
|
|
}
|
|
|
|
case(EV_DROP_PIV_ENEMY){
|
|
|
|
//_DropPIVItemEnemy(GetEventArgument(0), GetEventArgument(1), GetEventArgument(2), GetEventArgument(3), GetEventArgument(4));
|
|
|
|
}
|
|
|
|
case(EV_DROP_AMMO_ENEMY){
|
|
|
|
//_DropAmmoItemEnemy(GetEventArgument(0), GetEventArgument(1), GetEventArgument(2), GetEventArgument(3), GetEventArgument(4));
|
|
|
|
}
|
|
|
|
// Event arguments: Enemy X, Enemy Y, Item Drop Amount, Item Drop Type
|
|
|
|
case(EV_SINGLE_ITEM_DROP){
|
|
|
|
loop(GetEventArgument(2)){
|
|
CreateScoreItem(GetEventArgument(3), GetEventArgument(0)+rand(-100, 100), GetEventArgument(1)+rand(-100, 100));
|
|
}
|
|
|
|
}
|
|
|
|
case(EV_DROP_EXTEND){
|
|
CreateExtendItem(EXTEND_LIFE, GetEventArgument(0), GetEventArgument(1));
|
|
}
|
|
|
|
}
|
|
|
|
task _CancelHandling(int IDItem, int typeItem){
|
|
|
|
ObjMove_CancelMovement(IDItem);
|
|
|
|
while(GetPlayerState() != STATE_NORMAL){yield;}
|
|
|
|
_MoveToPlayer(IDItem, typeItem, 0);
|
|
|
|
}
|
|
|
|
// Timer is counted in frames (60 frames = 1 second)
|
|
|
|
task _DropPointItem(float[] posEnm, float killTimer, float maxTimer, float pointMin, float pointMax){
|
|
|
|
// If the player kills enemy within maxTimer, the enemy drops the maximum amount of point items
|
|
|
|
float pointFinal = Interpolate_Smooth(pointMax, pointMin, min(1, killTimer/maxTimer));
|
|
|
|
WriteLog(killTimer/maxTimer);
|
|
|
|
if (GetCommonDataPtr(POINTER_CHAINCHECK, false) == true){
|
|
|
|
loop(pointFinal){
|
|
|
|
CreateScoreItem(POINT_GOLD_LARGE, posEnm[0]+rand(-60, 60), posEnm[1]+rand(-60, 60));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
loop(pointFinal){
|
|
|
|
CreateScoreItem(POINT_REGULAR, posEnm[0]+rand(-60, 60), posEnm[1]+rand(-60, 60));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(GetAreaCommonData("Config", "EffectCut", 0) >= 1){}
|
|
else{_ScorePopup(posEnm[0], posEnm[1], "POINT", pointFinal);}
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
task _DropPIVItemEnemy(int IDPlayer, float[] posEnm, int pointMin, int pointMax, int bestDist){
|
|
|
|
// If the player is within at MOST "bestDist" from the enemy, the enemy drops the maximum amount of PIV items
|
|
|
|
float curDist = hypot(posEnm[0]-ObjMove_GetX(IDPlayer), posEnm[1]-ObjMove_GetY(IDPlayer));
|
|
|
|
int pointFinal = Interpolate_Smooth(pointMin, pointMax, min(1, bestDist/curDist));
|
|
//WriteLog(pointFinal);
|
|
|
|
loop(pointFinal){
|
|
|
|
CreatePIVItem(PIV_250, posEnm[0]+rand(-60, 60), posEnm[1]+rand(-60, 60));
|
|
|
|
}
|
|
|
|
/*
|
|
if(GetCommonDataPtr(EFFECTCUT_PTR, 0) >= 1){}
|
|
else{_ScorePopup(posEnm[0], posEnm[1], "PIV", pointFinal);}
|
|
*/
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
task _DropAmmoItemEnemy(int IDPlayer, float[] posEnm, int pointMin, int pointMax, int bestDist){
|
|
|
|
// If the player is within at MOST "bestDist" from the enemy, the enemy drops the maximum amount of PIV items
|
|
|
|
float curDist = hypot(posEnm[0]-ObjMove_GetX(IDPlayer), posEnm[1]-ObjMove_GetY(IDPlayer));
|
|
|
|
int pointFinal = Interpolate_Smooth(pointMin, pointMax, min(1, bestDist/curDist));
|
|
//WriteLog(pointFinal);
|
|
|
|
loop(pointFinal){
|
|
|
|
CreateAmmoItem(posEnm[0]+rand(-60, 60), posEnm[1]+rand(-60, 60));
|
|
|
|
}
|
|
|
|
if(GetCommonDataPtr(EFFECTCUT_PTR, 0) >= 1){}
|
|
else{_ScorePopup(posEnm[0], posEnm[1], "AMMO", pointFinal);}
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
task _MoveToPlayer(obj, type, typeCollect){
|
|
|
|
ObjItem_SetAutoDelete(obj, true);
|
|
ObjMove_SetAcceleration(obj, 1);
|
|
//ObjMove_SetMaxSpeed(obj, 2);
|
|
|
|
// The max speed of movement differs based on item.
|
|
alternative(type)
|
|
|
|
case(POINT_CANCEL) { ObjMove_SetMaxSpeed(obj, 23); }
|
|
|
|
case(PIV_100) { ObjMove_SetMaxSpeed(obj, 18); }
|
|
case(PIV_250) { ObjMove_SetMaxSpeed(obj, 18); }
|
|
case(PIV_500) { ObjMove_SetMaxSpeed(obj, 18); }
|
|
|
|
case(POINT_REGULAR) { ObjMove_SetMaxSpeed(obj, 20); }
|
|
case(POINT_RAINBOW) { ObjMove_SetMaxSpeed(obj, 20); }
|
|
case(POINT_BHESTIE) { ObjMove_SetMaxSpeed(obj, 20); }
|
|
others { ObjMove_SetMaxSpeed(obj, 25); }
|
|
|
|
while (!Obj_IsDeleted(obj)) {
|
|
ObjMove_SetAngle(obj, GetAngleToPlayer(obj));
|
|
//WriteLog(ObjMove_GetSpeed(obj));
|
|
yield;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Text popups. When enemy is defeated, text objects appear showing the number of PIV and point items collected.
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
task _ScorePopup(float enmX, float enmY, string type, int itemNum){
|
|
|
|
if (itemNum <= 0){return;}
|
|
|
|
float offset = 72; // Vertical space between the 2 scoretexts
|
|
float time = 30; // Time that the text objects (appear+)last on screen
|
|
float timeDisappear = 15; // Fade time
|
|
float size = 40;
|
|
float yDes = 60; // Destination text object moves to, relative to enmY
|
|
string font = "GravityRegular5";
|
|
string font2 = "GravityBold8";
|
|
float borderSize = 6;
|
|
|
|
if (type == "POINT")
|
|
{
|
|
|
|
int pointText = CreateTextObject(
|
|
enmX, enmY, size,
|
|
IntToString(itemNum * 10000) ~ " x " ~ IntToString(GetCommonDataPtr(POINTER_CHAIN, 1)), font,
|
|
0x7699FF, 0xFFFFFF,
|
|
0x2A00C0, borderSize,
|
|
42
|
|
);
|
|
|
|
ObjText_SetHorizontalAlignment(pointText, ALIGNMENT_CENTER);
|
|
|
|
if (GetCommonDataPtr(POINTER_CHAINCHECK, false) == true){
|
|
|
|
ObjText_SetFontBorderColor(pointText, 0xFF9700);
|
|
ObjText_SetFontColorTop(pointText, 0xFFD69C);
|
|
ObjText_SetFontSize(pointText, 56);
|
|
ObjText_SetFontType(pointText, font2);
|
|
ObjText_SetText(pointText, IntToString(itemNum * PIV));
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
ObjText_SetFontBorderColor(pointText, 0x2A00C0);
|
|
ObjText_SetFontColorTop(pointText, 0x7699FF);
|
|
ObjText_SetFontSize(pointText, 40);
|
|
ObjText_SetFontType(pointText, font);
|
|
ObjText_SetText(pointText, IntToString(itemNum * 1000) ~ "[r][font tc=(255, 223, 143) oz=4 oc=(123, 45, 23) bc=(219, 163, 21) oy=12 sz=25]+" ~ IntToString(itemNum * 50) ~ " VALUE");
|
|
|
|
}
|
|
|
|
ascent(i in 0..time){
|
|
ObjRender_SetY(pointText, Interpolate_Decelerate(enmY, enmY-yDes, i/time));
|
|
yield;
|
|
}
|
|
|
|
ascent(i in 0..timeDisappear){
|
|
ObjRender_SetAlpha(pointText, Interpolate_Decelerate(255, 0, i/timeDisappear));
|
|
yield;
|
|
}
|
|
Obj_Delete(pointText);
|
|
}
|
|
|
|
else if (type == "PIV")
|
|
{
|
|
int pivText = CreateTextObject(
|
|
enmX, enmY+offset, size,
|
|
"x" ~ IntToString(itemNum), font,
|
|
0xFFB4EC, 0xFFFFFF,
|
|
0xB200AD, borderSize,
|
|
42
|
|
);
|
|
|
|
ObjText_SetHorizontalAlignment(pivText, ALIGNMENT_CENTER);
|
|
|
|
if (GetCommonDataPtr(POINTER_CHAINCHECK, false) == true){
|
|
Obj_SetVisible(pivText, false);
|
|
}
|
|
else{
|
|
Obj_SetVisible(pivText, true);
|
|
}
|
|
|
|
ascent(i in 0..time){
|
|
ObjRender_SetY(pivText, Interpolate_Decelerate(enmY+offset, enmY+offset-yDes, i/time));
|
|
yield;
|
|
}
|
|
|
|
ascent(i in 0..timeDisappear){
|
|
ObjRender_SetAlpha(pivText, Interpolate_Decelerate(255, 0, i/timeDisappear));
|
|
yield;
|
|
}
|
|
|
|
Obj_Delete(pivText);
|
|
}
|
|
|
|
|
|
else if (type == "AMMO")
|
|
{
|
|
int pivText = CreateTextObject(
|
|
enmX, enmY+offset, size,
|
|
"+" ~ rtos("00.00", itemNum*0.2) ~ " [font ox=-24 oy=27 sz=45]AMMO", font,
|
|
0xFFB4EC, 0xFFFFFF,
|
|
0xF63357, borderSize,
|
|
42
|
|
);
|
|
|
|
ObjText_SetHorizontalAlignment(pivText, ALIGNMENT_CENTER);
|
|
|
|
if (GetCommonDataPtr(POINTER_CHAINCHECK, false) == true){
|
|
Obj_SetVisible(pivText, false);
|
|
}
|
|
else{
|
|
Obj_SetVisible(pivText, true);
|
|
}
|
|
|
|
ascent(i in 0..time){
|
|
ObjRender_SetY(pivText, Interpolate_Decelerate(enmY+offset, enmY+offset-yDes, i/time));
|
|
yield;
|
|
}
|
|
|
|
ascent(i in 0..timeDisappear){
|
|
ObjRender_SetAlpha(pivText, Interpolate_Decelerate(255, 0, i/timeDisappear));
|
|
yield;
|
|
}
|
|
|
|
Obj_Delete(pivText);
|
|
}
|
|
|
|
else{}
|
|
}
|