Add existing file
This commit is contained in:
parent
9bedcb263d
commit
d6a4b8bf20
320 changed files with 20855 additions and 0 deletions
BIN
script/player/Jam8_Rinnosuke/Default_Player_MagicCircle.png
Normal file
BIN
script/player/Jam8_Rinnosuke/Default_Player_MagicCircle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
452
script/player/Jam8_Rinnosuke/Rinnosuke_Main.dnh
Normal file
452
script/player/Jam8_Rinnosuke/Rinnosuke_Main.dnh
Normal file
|
@ -0,0 +1,452 @@
|
|||
#TouhouDanmakufu[Player]
|
||||
#ScriptVersion[3]
|
||||
#ID["Rinno"]
|
||||
#Title["Rinnosuke"]
|
||||
#Text["Unfocused Shot: Rage of the Electronic[r]Focused Shot: Doomsday Button[r]Spell Card: Prototype \"Volatile Hakkero\""]
|
||||
//#Image["./kevkou_lib/gayimg.png"]
|
||||
|
||||
#ReplayName["Rinno"]
|
||||
|
||||
#include "script/KevinSystem/Kevin_PlayerLib.txt"
|
||||
#include "./Rinnosuke_ShotConst.dnh"
|
||||
#include "./soundlib.txt"
|
||||
|
||||
#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();
|
||||
|
||||
int targetedenemy = 0; // This will be used to store the enemy ID Kouda's homing shots aim at
|
||||
|
||||
// Images & Sound
|
||||
|
||||
let teamimg = "script/TouhouJam8_SRE/Jam8_Resource/jam8Sprite.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 grazecounter = 0; // For basic graze = PIV mechanic
|
||||
|
||||
// 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{}
|
||||
|
||||
// Stuff
|
||||
parameterrender();
|
||||
playerrender();
|
||||
plrender = Obj_GetRenderPriorityI(objPlayer);
|
||||
|
||||
_SoundTask();
|
||||
|
||||
_Mechanic(ripplayer, _enemyArray, _existArray, GetStgFrameWidth(), GetStgFrameHeight(), objPlayer, GetEnemyBossSceneObjectID(), 3, 2, 30);
|
||||
|
||||
_HitboxRender(ripplayer, objPlayer, teamimg, teamimg, 512, 0, 640, 128, 768, 0, 1024, 256, 0.2, 1);
|
||||
|
||||
// Shot functions
|
||||
|
||||
//_EnemySelect();
|
||||
|
||||
_Homing();
|
||||
//_UnfocusedShot();
|
||||
|
||||
//_ShotType();
|
||||
|
||||
// Shot data loading
|
||||
LoadPlayerShotData(csd ~ "./Rinnosuke_ShotData.dnh");
|
||||
}
|
||||
|
||||
@MainLoop{
|
||||
_enemyArray = GetIntersectionRegistedEnemyID; // Constantly update the enemy ID array
|
||||
shotspeed += 1; // Managing the shot rate
|
||||
playerX = ObjMove_GetX(objPlayer);
|
||||
playerY = ObjMove_GetY(objPlayer);
|
||||
yield;
|
||||
}
|
||||
|
||||
@Event{
|
||||
alternative(GetEventType)
|
||||
|
||||
// PIV-item spawning events
|
||||
|
||||
case(EV_DELETE_SHOT_PLAYER){
|
||||
let graphic = GetEventArgument(2);
|
||||
float[] position = GetEventArgument(1);
|
||||
let obj = CreatePlayerShotA1(position[0], position[1], 0, 0, 0, 99999, graphic);
|
||||
ObjShot_SetIntersectionEnable(obj, false);
|
||||
_DeleteEffect(obj);
|
||||
}
|
||||
|
||||
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, 256, 512, 512, 768, objPlayer, GetPlayerInvincibilityFrame());
|
||||
}
|
||||
else {
|
||||
SetScriptResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
case(EV_HIT){
|
||||
//_DeathbombWarning(teamimg, [2560, 512, 2560+512, 1024], 30, 0.65);
|
||||
ObjSound_Play(predeathsfx);
|
||||
}
|
||||
|
||||
case(EV_PLAYER_SHOOTDOWN){
|
||||
ObjSound_Play(deathsfx);
|
||||
ripplayer = true;
|
||||
_SigilCall(true, teamimg, 0, 512, 256, 768, objPlayer, 120);
|
||||
}
|
||||
|
||||
case(EV_PLAYER_REBIRTH){
|
||||
ripplayer = false;
|
||||
SetPlayerInvincibilityFrame(180);
|
||||
_SigilCall(false, teamimg, 256, 512, 512, 768, objPlayer, GetPlayerInvincibilityFrame());
|
||||
SetPlayerSpell( max(3, GetPlayerSpell()) );
|
||||
}
|
||||
|
||||
case(EV_GRAZE){
|
||||
grazecounter += GetEventArgument(0);
|
||||
while(grazecounter >= 10){
|
||||
SetAreaCommonData("PIV", "currentvalue", GetAreaCommonData("PIV", "currentvalue")+10);
|
||||
grazecounter -= 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Finalize{
|
||||
|
||||
}
|
||||
|
||||
task _DeleteEffect(obj){
|
||||
ObjRender_SetBlendType(obj, BLEND_ADD_ARGB);
|
||||
ascent(i in 0..30){
|
||||
ObjRender_SetAlpha(obj, Interpolate_Decelerate(120, 0, i/30));
|
||||
ObjRender_SetScaleXYZ(obj, Interpolate_Decelerate(0.5, 2, i/30));
|
||||
yield;
|
||||
}
|
||||
Obj_Delete(obj);
|
||||
}
|
||||
// Basic player parameters
|
||||
|
||||
task parameterrender(){
|
||||
SetPlayerItemScope(200); // Special Ability 1
|
||||
SetPlayerLife(5); // Debug
|
||||
SetPlayerSpell(3);
|
||||
SetPlayerSpeed(6.5, 2.8); // (original: 4.5/1.75)
|
||||
SetPlayerRebirthFrame(30); // Special Ability 2
|
||||
SetPlayerAutoItemCollectLine(GetStgFrameHeight/3); //596x632 STG frame
|
||||
SetPlayerRebirthLossFrame(0);
|
||||
ObjPlayer_AddIntersectionCircleA1(objPlayer,0,0,1.5,25);
|
||||
}
|
||||
|
||||
// Renders the shottype
|
||||
|
||||
// Selects an enemy to home on.
|
||||
|
||||
task _HomeShot(int shot_) {
|
||||
|
||||
float duration = 55;
|
||||
bool homingBool = false;
|
||||
float basepenetrate = ObjShot_GetPenetration(shot_);
|
||||
float basedmg = ObjShot_GetDamage(shot_);
|
||||
|
||||
// Original code
|
||||
|
||||
async{
|
||||
_BulletRescalePlayer(shot_, 0.75, true, 1.1);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
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(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 < 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, homeRate)); // Interpolate_Necko
|
||||
f++;
|
||||
yield;
|
||||
}
|
||||
ObjShot_SetAutoDelete(shot_, true);
|
||||
ObjMove_SetAngularVelocity(shot_, 0);
|
||||
homingBool = false;
|
||||
}
|
||||
}
|
||||
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
task _Homing(){
|
||||
|
||||
let optionA = PlayerOption(50, 0, 256, 256, 512, 512);
|
||||
let optionB = PlayerOption(-50, 0, 256, 256, 512, 512);
|
||||
let optionC = PlayerOption(90, 30, 256, 256, 512, 512);
|
||||
let optionD = PlayerOption(-90, 30, 256, 256, 512, 512);
|
||||
|
||||
int shotspeedhome = 0;
|
||||
|
||||
int[] optionList = [optionA, optionB, optionC, optionD];
|
||||
int[] optionList1 = [optionA, optionC];
|
||||
int[] optionList2 = [optionB, optionD];
|
||||
|
||||
int a = 0;
|
||||
|
||||
loop{
|
||||
if(shotspeedhome % 5 == 0 && GetVirtualKeyState(VK_SHOT) != KEY_FREE && IsPermitPlayerShot && !ripplayer){
|
||||
|
||||
if(GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE){
|
||||
|
||||
for each (int option in ref optionList){
|
||||
//"l
|
||||
float x = ObjRender_GetX(option);
|
||||
float y = ObjRender_GetY(option);
|
||||
|
||||
let shotA = CreatePlayerShotA1(x, y, 15, 270, 2.65, 2, FOCUSED);
|
||||
//ObjMove_AddPatternA2(shotA, 1, 5, NO_CHANGE, -0.1, 3.75, rand(-0.4, 0.4));
|
||||
|
||||
_HomeShot(shotA);
|
||||
}
|
||||
|
||||
ascent(i in -2..3){
|
||||
int shot = CreatePlayerShotA1(playerX, playerY, 17, 270-5*i, 3.5, 2, UNFOCUSED);
|
||||
_BulletRescalePlayer(shot, 0.5, true, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
for each (int option in ref optionList1){
|
||||
//"
|
||||
float x = ObjRender_GetX(option);
|
||||
float y = ObjRender_GetY(option);
|
||||
|
||||
ascent(i in -1..2){
|
||||
int shot = CreatePlayerShotA1(x, y, 17, 240-10*i, 4, 1.75, UNFOCUSED);
|
||||
_BulletRescalePlayer(shot, 0.5, true, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for each (int option in ref optionList2){
|
||||
//"
|
||||
float x = ObjRender_GetX(option);
|
||||
float y = ObjRender_GetY(option);
|
||||
|
||||
ascent(i in -1..2){
|
||||
int shot = CreatePlayerShotA1(x, y, 17, 300+10*i, 4, 1.75, UNFOCUSED);
|
||||
_BulletRescalePlayer(shot, 0.5, true, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
shotspeedhome++;
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
// Player option rendering
|
||||
|
||||
function PlayerOption(offsetx, offsety, left, top, right, bottom){
|
||||
let option = ObjPrim_Create(OBJ_SPRITE_2D);
|
||||
bool visible;
|
||||
int animate = 0;
|
||||
float optx;
|
||||
float opty;
|
||||
|
||||
ObjPrim_SetTexture(option, teamimg);
|
||||
ObjSprite2D_SetSourceRect(option, left, top, right, bottom);
|
||||
ObjSprite2D_SetDestCenter(option);
|
||||
ObjRender_SetScaleXYZ(option, 0.25, 0.25, 1);
|
||||
ObjRender_SetBlendType(option, BLEND_ALPHA);
|
||||
ObjRender_SetAlpha(option, 180);
|
||||
Obj_SetRenderPriorityI(option, 41);
|
||||
ObjRender_SetPosition(option, offsetx, offsety, 1);
|
||||
|
||||
async{
|
||||
loop{
|
||||
ObjRender_SetPosition(option, GetPlayerX()+offsetx, GetPlayerY()+offsety, 1);
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
async{
|
||||
loop{
|
||||
if(ripplayer){Obj_SetVisible(option, false); visible = false;}
|
||||
else {Obj_SetVisible(option, true); visible = true;}
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
// Player sprites
|
||||
|
||||
task playerrender(){
|
||||
|
||||
// Why is this movement code so cursed jesus fucking christ
|
||||
|
||||
float scale = 0.4; // Scalies
|
||||
|
||||
ObjPrim_SetTexture(objPlayer, teamimg);
|
||||
ObjSprite2D_SetSourceRect(objPlayer, 0, 256, 256, 512);
|
||||
ObjSprite2D_SetDestCenter(objPlayer);
|
||||
Obj_SetRenderPriorityI(objPlayer, 42);
|
||||
ObjRender_SetScaleXYZ(objPlayer, scale, scale, 1);
|
||||
|
||||
}
|
||||
|
||||
task Bomb(){
|
||||
// Preparation
|
||||
//SetForbidPlayerShot(true);
|
||||
SetForbidPlayerSpell(true);
|
||||
SetPlayerInvincibilityFrame(300);
|
||||
// Spell object
|
||||
let manageObj = GetSpellManageObject(); // SPELL BEGINS
|
||||
ObjSpell_Regist(manageObj);
|
||||
ObjSound_Play(bombsfx);
|
||||
|
||||
// Spell
|
||||
|
||||
int hakkero = CreatePlayerShotA1(playerX, playerY, 0, 0, 12, 999999, BOMB);
|
||||
ObjShot_SetIntersectionEnable(hakkero, true);
|
||||
ObjShot_SetEraseShot(hakkero, true);
|
||||
ObjShot_SetSpellFactor(hakkero, true);
|
||||
|
||||
async{
|
||||
ascent(i in 0..45){
|
||||
_BulletRescalePlayer(hakkero, Interpolate_Decelerate(0.5, 2.25, i/45), true, 1);
|
||||
ObjRender_SetAlpha(hakkero, Interpolate_Decelerate(0, 255, i/45));
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
ascent(i in 0..240){
|
||||
yield;
|
||||
}
|
||||
|
||||
// Cleanup, end of spell
|
||||
ObjShot_FadeDelete(hakkero);
|
||||
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;
|
||||
}
|
7
script/player/Jam8_Rinnosuke/Rinnosuke_ShotConst.dnh
Normal file
7
script/player/Jam8_Rinnosuke/Rinnosuke_ShotConst.dnh
Normal file
|
@ -0,0 +1,7 @@
|
|||
let current = GetCurrentScriptDirectory();
|
||||
let path = current ~ "Rinnosuke_ShotData.dnh";
|
||||
LoadPlayerShotData(path);
|
||||
// -----
|
||||
const FOCUSED = 1;
|
||||
const UNFOCUSED = 2;
|
||||
const BOMB = 3;
|
14
script/player/Jam8_Rinnosuke/Rinnosuke_ShotData.dnh
Normal file
14
script/player/Jam8_Rinnosuke/Rinnosuke_ShotData.dnh
Normal file
|
@ -0,0 +1,14 @@
|
|||
shot_image = "./../../TouhouJam8_SRE/Jam8_Resource/jam8Sprite.png"
|
||||
|
||||
ShotData{
|
||||
id = 0 // Dummy
|
||||
rect = (0,0,0,0)
|
||||
render = ALPHA
|
||||
alpha = 0
|
||||
collision = 12
|
||||
}
|
||||
|
||||
// Rinnosuke's shots
|
||||
ShotData{id = 1 rect = (512, 256, 639, 383) render = ALPHA alpha = 180 collision = 38 fixed_angle = false angular_velocity = 3} // Homing shot, spins
|
||||
ShotData{id = 2 rect = (640, 256, 768, 384) render = ALPHA alpha = 150 collision = 38} // Unfocused shot
|
||||
ShotData{id = 3 rect = (768, 256, 1023, 511) render = ADD_ARGB alpha = 255 collision = 115 fixed_angle = false angular_velocity = 8} // Bomb
|
BIN
script/player/Jam8_Rinnosuke/sound/bfxr_PlayerDie.wav
Normal file
BIN
script/player/Jam8_Rinnosuke/sound/bfxr_PlayerDie.wav
Normal file
Binary file not shown.
BIN
script/player/Jam8_Rinnosuke/sound/bfxr_PreDeath.wav
Normal file
BIN
script/player/Jam8_Rinnosuke/sound/bfxr_PreDeath.wav
Normal file
Binary file not shown.
BIN
script/player/Jam8_Rinnosuke/sound/bfxr_RinnoBomb.wav
Normal file
BIN
script/player/Jam8_Rinnosuke/sound/bfxr_RinnoBomb.wav
Normal file
Binary file not shown.
25
script/player/Jam8_Rinnosuke/soundlib.txt
Normal file
25
script/player/Jam8_Rinnosuke/soundlib.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
let sddir = GetCurrentScriptDirectory() ~ "./sound";
|
||||
|
||||
function LoadEx(targetobj, targetpath, targetvol){
|
||||
|
||||
ObjSound_Load(targetobj, targetpath);
|
||||
ObjSound_SetVolumeRate(targetobj, targetvol);
|
||||
|
||||
}
|
||||
|
||||
// Universal sounds
|
||||
|
||||
let bomb = sddir ~ "./bfxr_RinnoBomb.wav";
|
||||
let ded = sddir ~ "./bfxr_PlayerDie.wav";
|
||||
let hit = sddir ~ "./bfxr_PreDeath.wav";
|
||||
|
||||
let bombsfx = ObjSound_Create();
|
||||
let deathsfx = ObjSound_Create();
|
||||
let predeathsfx = ObjSound_Create();
|
||||
|
||||
task _SoundTask(){
|
||||
LoadEx(bombsfx, bomb, 15);
|
||||
LoadEx(deathsfx, ded, 40);
|
||||
LoadEx(predeathsfx, hit, 55);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue