character scripts

This commit is contained in:
YoshiCrafter29
2022-10-11 09:29:58 +02:00
parent c4dcafae91
commit 00fff01e04
12 changed files with 5431 additions and 5111 deletions
+23
View File
@@ -0,0 +1,23 @@
trace("Hello, World!");
function createPost() {
// globalOffset.y -= 150;
}
function update(elapsed:Float) {
// y = y + Math.sin(Conductor.songPosition / 1000 * Math.PI) * 125 * elapsed;
}
function onGetCamPos(deezNuts:Dynamic) {
if (animation.curAnim == null) return;
switch(animation.curAnim.name) {
case "singUP":
deezNuts.y -= 25;
case "singDOWN":
deezNuts.y += 25;
case "singLEFT":
deezNuts.x -= 25;
case "singRIGHT":
deezNuts.x += 25;
}
}
+1 -1
View File
@@ -1 +1 @@
309
317
+5233 -5091
View File
File diff suppressed because it is too large Load Diff
+36 -7
View File
@@ -15,9 +15,12 @@ import flixel.math.FlxRect;
import openfl.utils.Assets;
import haxe.xml.Access;
import haxe.Exception;
import haxe.io.Path;
import funkin.system.Conductor;
import funkin.scripting.events.PlayAnimEvent;
import funkin.scripting.DummyScript;
import funkin.scripting.Script;
import funkin.scripting.events.*;
import funkin.scripting.events.PlayAnimEvent.PlayAnimContext;
using StringTools;
@@ -48,17 +51,26 @@ class Character extends FlxSprite implements IBeatReceiver implements IOffsetCom
public var cameraOffset:FlxPoint = new FlxPoint(0, 0);
public var globalOffset:FlxPoint = new FlxPoint(0, 0);
public var script:Script;
public inline function getCameraPosition() {
var midpoint = getMidpoint();
return FlxPoint.get(
var event = new PointEvent(
midpoint.x + (isPlayer ? -100 : 150) + globalOffset.x + cameraOffset.x,
midpoint.y - 100 + globalOffset.y + cameraOffset.y);
script.call("onGetCamPos", [event]);
// this event cannot be cancelled
return new FlxPoint(event.x, event.y);
}
public function playSingAnim(direction:Int, suffix:String = "") {
public function playSingAnim(direction:Int, suffix:String = "", Reversed:Bool = false, Frame:Int = 0) {
// TODO: Script Events
var anims = ["singLEFT", "singDOWN", "singUP", "singRIGHT"];
playAnim('${anims[direction]}$suffix', true);
var event = new DirectionAnimEvent('${anims[direction]}$suffix', direction, suffix, Reversed, Frame);
script.call("onPlaySingAnim", [event]);
if (!event.cancelled) playAnim(event.animName, event.force, event.reversed, event.frame, SING);
}
public function new(x:Float, y:Float, ?character:String = "bf", ?isPlayer:Bool = false)
@@ -78,12 +90,13 @@ class Character extends FlxSprite implements IBeatReceiver implements IOffsetCom
// case 'your-char': // To hardcode characters
default:
// load xml
if (!Assets.exists(Paths.xml('characters/$curCharacter'))) {
var xmlPath = Paths.xml('characters/$curCharacter');
if (!Assets.exists(xmlPath)) {
curCharacter = "bf";
continue;
}
var plainXML = Assets.getText(Paths.xml('characters/$curCharacter'));
var plainXML = Assets.getText(xmlPath);
var character:Access;
try {
var charXML = Xml.parse(plainXML).firstElement();
@@ -109,9 +122,16 @@ class Character extends FlxSprite implements IBeatReceiver implements IOffsetCom
for(anim in character.nodes.anim) {
XMLUtil.addXMLAnimation(this, anim);
}
// Loads the script and calls it's "create" function
script = Script.create(Paths.script(Path.withoutExtension(xmlPath), null, true));
script.setParent(this);
script.load();
script.call("create");
}
break;
}
if (script == null) script = new DummyScript(curCharacter);
/**
NON CONVERTED CHARACTERS - DO NOT REMOVE
@@ -244,7 +264,6 @@ class Character extends FlxSprite implements IBeatReceiver implements IOffsetCom
// playAnim('idle');
// antialiasing = false;
dance();
isDanceLeftDanceRight = (animation.getByName("danceLeft") != null && animation.getByName("danceRight") != null);
@@ -266,6 +285,8 @@ class Character extends FlxSprite implements IBeatReceiver implements IOffsetCom
switchOffset('singLEFTmiss', 'singRIGHTmiss');
}
if (isPlayer) flipX = !flipX;
dance();
script.call("createPost");
}
var isDanceLeftDanceRight:Bool = false;
@@ -279,6 +300,7 @@ class Character extends FlxSprite implements IBeatReceiver implements IOffsetCom
override function update(elapsed:Float)
{
super.update(elapsed);
script.call("update", [elapsed]);
if (stunned) {
__stunnedTime += elapsed;
if (__stunnedTime > 5 / 60)
@@ -295,6 +317,10 @@ class Character extends FlxSprite implements IBeatReceiver implements IOffsetCom
{
if (!debugMode)
{
var event = new DanceEvent(danced);
script.call("onDance", [event]);
if (event.cancelled) return;
switch (curCharacter)
{
// hardcode custom dance animations here
@@ -315,10 +341,12 @@ class Character extends FlxSprite implements IBeatReceiver implements IOffsetCom
}
public function beatHit(curBeat:Int) {
script.call("beatHit", [curBeat]);
if ((lastHit + (Conductor.stepCrochet * holdTime) < Conductor.songPosition) || animation.curAnim == null || (!animation.curAnim.name.startsWith("sing") && animation.curAnim.finished))
dance();
}
public function stepHit(curStep:Int) {
script.call("stepHit", [curStep]);
// nothing
}
@@ -352,6 +380,7 @@ class Character extends FlxSprite implements IBeatReceiver implements IOffsetCom
{
var event = new PlayAnimEvent(AnimName, Force, Reversed, Frame);
script.call("onPlayAnim", [event]);
// TODO: Character Scripts
if (event.cancelled || event.animName == null) return;
+12 -7
View File
@@ -188,14 +188,20 @@ class PlayState extends MusicBeatState
// Updating Discord Rich Presence.
DiscordClient.changePresence(detailsText, SONG.song + " (" + storyDifficultyText + ")", iconRPC);
#end
var gfVersion = SONG.gf;
if (gfVersion == null) gfVersion = "gf";
gf = new Character(400, 130, gfVersion);
gf.scrollFactor.set(0.95, 0.95);
dad = new Character(100, 100, SONG.player2);
if (dad != null && dad.isGF) {
dad.setPosition(400, 130);
gf = dad;
dad.scrollFactor.set(0.95, 0.95);
} else {
var gfVersion = SONG.gf;
if (gfVersion == null) gfVersion = "gf";
gf = new Character(400, 130, gfVersion);
gf.scrollFactor.set(0.95, 0.95);
}
var camPos:FlxPoint = new FlxPoint(dad.getGraphicMidpoint().x, dad.getGraphicMidpoint().y);
@@ -210,7 +216,6 @@ class PlayState extends MusicBeatState
// case "":
// ADD YOUR HARDCODED SCRIPTS HERE!
default:
trace('charts/${SONG.song}/');
var content = Paths.getFolderContent('charts/${SONG.song}/', false, true, !fromMods);
for(file in content) {
var ext = Path.extension(file).toLowerCase();
+1
View File
@@ -109,6 +109,7 @@ class Stage extends FlxBasic implements IBeatReceiver {
PlayState.instance.add(PlayState.instance.gf);
PlayState.instance.gf;
case "dad" | "opponent":
if (PlayState.instance.dad == null || PlayState.instance.dad.isGF) continue;
doCharNodeShit(PlayState.instance.dad, node);
PlayState.instance.add(PlayState.instance.dad);
PlayState.instance.dad;
@@ -0,0 +1,9 @@
package funkin.scripting.events;
class DanceEvent extends CancellableEvent {
public var danced:Bool;
public function new(danced:Bool = false) {
super();
this.danced = danced;
}
}
@@ -0,0 +1,38 @@
package funkin.scripting.events;
class DirectionAnimEvent extends CancellableEvent {
/**
Default animation that will be played
**/
public var animName:String;
/**
In which direction the animation will be played
**/
public var direction:Int;
/**
The suffix of the animation (ex: "-alt") - Defaults to ""
**/
public var suffix:String;
/**
Whenever the animation will play reversed or not.
**/
public var reversed:Bool;
/**
Whenever the animation will play reversed or not.
**/
public var force:Bool;
/**
At what frame the animation will start playing
**/
public var frame:Int;
public function new(animName:String, direction:Int, suffix:String = "", reversed:Bool = false, frame:Int = 0) {
super();
this.animName = animName;
this.direction = direction;
this.suffix = suffix;
this.reversed = reversed;
this.force = true;
this.frame = frame;
}
}
@@ -0,0 +1,17 @@
package funkin.scripting.events;
class PointEvent extends CancellableEvent {
/**
X position
**/
public var x:Float;
/**
Y position
**/
public var y:Float;
public function new(x:Float, y:Float) {
super();
this.x = x;
this.y = y;
}
}
+3 -5
View File
@@ -100,11 +100,11 @@ class Paths
return getPath('images/$key.png', IMAGE, library);
}
inline static public function script(key:String, ?library:String) {
var scriptPath = getPath(key, TEXT, library);
inline static public function script(key:String, ?library:String, isAssetsPath:Bool = false) {
var scriptPath = isAssetsPath ? key : getPath(key, TEXT, library);
var p:String;
for(ex in Script.scriptExtensions) {
p = getPath('$key.$ex', TEXT, library);
p = isAssetsPath ? '$key.$ex' : getPath('$key.$ex', TEXT, library);
if (OpenFlAssets.exists(p)) {
scriptPath = p;
break;
@@ -161,13 +161,11 @@ class Paths
var libThing = new LimeLibrarySymbol(folderPath);
var library = libThing.library;
trace(library);
if (library is openfl.utils.AssetLibrary) {
var lib = cast(libThing.library, openfl.utils.AssetLibrary);
@:privateAccess
if (lib.__proxy != null) library = lib.__proxy;
}
trace(library);
var content:Array<String> = [];
#if sys
+58
View File
@@ -0,0 +1,58 @@
package scripting;
import funkin.scripting.events.*;
/**
* Contains all callbacks you can add in a Character script.
*
* To add a Character script, create a file here: `data/characters/my-char.hx`
*/
interface CharacterScript {
/**
* Triggered after the characters XML has been loaded.
*/
public function create():Void;
/**
* Triggered after the character has been entirely loaded.
*/
public function createPost():Void;
/**
* Triggered every frame.
*/
public function update(elapsed:Float):Void;
/**
* Triggered everytime the character will dance (play its idle animation).
*/
public function onDance(event:DanceEvent):Void;
/**
* Triggered every beat
*/
public function beatHit(curBeat:Int):Void;
/**
* Triggered every step
*/
public function stepHit(curStep:Int):Void;
/**
* Triggered everytime the game tries to play an animation on your character.
*/
public function onPlayAnim(event:PlayAnimEvent):Void;
/**
* Triggered everytime the game tries to get your player's camera position.
* This event cannot be cancelled.
*/
public function onGetCamPos(event:PointEvent):Void;
/**
* Triggered everytime the game tries to play a sing, alt sing or miss animation.
*/
public function onPlaySingAnim(event:DirectionAnimEvent):Void;
}