character scripts
This commit is contained in:
@@ -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
@@ -1 +1 @@
|
||||
309
|
||||
317
|
||||
+5233
-5091
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user