diff --git a/example_mods/introMod/_append/data/introText.txt b/example_mods/introMod/_append/data/introText.txt deleted file mode 100644 index 45e0c08ab..000000000 --- a/example_mods/introMod/_append/data/introText.txt +++ /dev/null @@ -1 +0,0 @@ -swagshit--moneymoney \ No newline at end of file diff --git a/example_mods/introMod/assets/preload/data/introText.txt b/example_mods/introMod/assets/preload/data/introText.txt deleted file mode 100644 index f0dd8224a..000000000 --- a/example_mods/introMod/assets/preload/data/introText.txt +++ /dev/null @@ -1 +0,0 @@ -awesomes tream--really awesome \ No newline at end of file diff --git a/example_mods/introMod/assets/preload/images/gfDanceTitle.png b/example_mods/introMod/assets/preload/images/gfDanceTitle.png deleted file mode 100644 index 989f2a68a..000000000 Binary files a/example_mods/introMod/assets/preload/images/gfDanceTitle.png and /dev/null differ diff --git a/example_mods/testing123/_polymod_icon.png b/example_mods/testing123/_polymod_icon.png deleted file mode 100644 index 2828bd554..000000000 Binary files a/example_mods/testing123/_polymod_icon.png and /dev/null differ diff --git a/example_mods/testing123/_polymod_meta.json b/example_mods/testing123/_polymod_meta.json deleted file mode 100644 index e74efc4f3..000000000 --- a/example_mods/testing123/_polymod_meta.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "title": "Testing123", - "description": "Newgrounds? More like OLDGROUNDS lol.", - "author": "MasterEric", - "api_version": "0.1.0", - "mod_version": "1.0.0", - "license": "Apache-2.0" -} diff --git a/example_mods/testing123/images/newgrounds_logo.png b/example_mods/testing123/images/newgrounds_logo.png deleted file mode 100644 index 2828bd554..000000000 Binary files a/example_mods/testing123/images/newgrounds_logo.png and /dev/null differ diff --git a/source/InitState.hx b/source/InitState.hx index 2183e0d87..7be00f074 100644 --- a/source/InitState.hx +++ b/source/InitState.hx @@ -40,7 +40,7 @@ class InitState extends FlxTransitionableState { trace('This is a debug build, loading InitState...'); #if android - FlxG.android.preventDefaultKeys = [FlxAndroidKey.BACK]; + FlxG.android.preventDefaultKeys = [flixel.input.android.FlxAndroidKey.BACK]; #end #if newgrounds NGio.init(); diff --git a/source/PlayState.hx b/source/PlayState.hx index b7d900238..98380e0dd 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -391,53 +391,12 @@ class PlayState extends MusicBeatState { case 'spookeez' | 'monster' | 'south': curStageId = "spookyMansion"; - - // TODO: Move lightning strike behavior to a scripted class extending Stage. loadStage(curStageId); case 'pico' | 'blammed' | 'philly': - curStageId = 'philly'; + curStageId = 'phillyTrain'; + loadStage(curStageId); - var bg:FlxSprite = new FlxSprite(-100).loadGraphic(Paths.image('philly/sky')); - bg.scrollFactor.set(0.1, 0.1); - add(bg); - - var city:FlxSprite = new FlxSprite(-10).loadGraphic(Paths.image('philly/city')); - city.scrollFactor.set(0.3, 0.3); - city.setGraphicSize(Std.int(city.width * 0.85)); - city.updateHitbox(); - add(city); - - lightFadeShader = new BuildingShaders(); - phillyCityLights = new FlxTypedGroup<FlxSprite>(); - - add(phillyCityLights); - - for (i in 0...5) - { - var light:FlxSprite = new FlxSprite(city.x).loadGraphic(Paths.image('philly/win' + i)); - light.scrollFactor.set(0.3, 0.3); - light.visible = false; - light.setGraphicSize(Std.int(light.width * 0.85)); - light.updateHitbox(); - light.antialiasing = true; - light.shader = lightFadeShader.shader; - phillyCityLights.add(light); - } - - var streetBehind:FlxSprite = new FlxSprite(-40, 50).loadGraphic(Paths.image('philly/behindTrain')); - add(streetBehind); - - phillyTrain = new FlxSprite(2000, 360).loadGraphic(Paths.image('philly/train')); - add(phillyTrain); - - trainSound = new FlxSound().loadEmbedded(Paths.sound('train_passes')); - FlxG.sound.list.add(trainSound); - - // var cityLights:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.win0.png); - - var street:FlxSprite = new FlxSprite(-40, streetBehind.y).loadGraphic(Paths.image('philly/street')); - add(street); case "milf" | 'satin-panties' | 'high': curStageId = 'limo'; defaultCamZoom *= 0.90; @@ -680,7 +639,7 @@ class PlayState extends MusicBeatState case "darnell": loadStageOld('phillyStreets'); default: - loadStageOld('stage'); + loadStage('mainStage'); } } @@ -830,8 +789,8 @@ class PlayState extends MusicBeatState { // We're using Eric's stage handler. // Characters get added to the stage, not the main scene. - curStage.addCharacter(boyfriend, BF); curStage.addCharacter(gf, GF); + curStage.addCharacter(boyfriend, BF); curStage.addCharacter(dad, DAD); // Redo z-indexes. @@ -942,6 +901,35 @@ class PlayState extends MusicBeatState });*/ } + /** + * Removes any references to the current stage, then clears the stage cache, + * then reloads all the stages. + * + * This is useful for when you want to edit a stage without reloading the whole game. + * Reloading works on both the JSON and the HXC, if applicable. + */ + function debug_refreshStages() + { + // Remove the current stage. If the stage gets deleted while it's still in use, + // it'll probably crash the game or something. + if (this.curStage != null) + { + remove(curStage); + curStage.kill(); + curStage = null; + } + + // Forcibly reload scripts so that scripted stages can be edited. + polymod.hscript.PolymodScriptClass.clearScriptClasses(); + polymod.hscript.PolymodScriptClass.registerAllScriptClasses(); + + // Reload the stages in cache. This might cause a lag spike but who cares this is a debug utility. + StageDataParser.loadStageCache(); + + // Reload the level. This should use new data from the assets folder. + LoadingState.loadAndSwitchState(new PlayState()); + } + public var curStage:Stage; /** @@ -1983,9 +1971,6 @@ class PlayState extends MusicBeatState } } - lightFadeShader.update((Conductor.crochet / 1000) * FlxG.elapsed * 1.5); - // phillyCityLights.members[curLight].alpha -= (Conductor.crochet / 1000) * FlxG.elapsed; - case 'tank': moveTank(); } @@ -2006,9 +1991,7 @@ class PlayState extends MusicBeatState persistentDraw = true; paused = true; - // 1 / 1000 chance for Gitaroo Man easter egg - // can this please move to dying it's kinda fucked up that pausing has a 1/1000 chance ur forced to restart - if (FlxG.random.bool(0.1)) + if (FlxG.random.bool(1 / 1000)) { // gitaroo man easter egg FlxG.switchState(new GitarooPause()); @@ -2042,6 +2025,10 @@ class PlayState extends MusicBeatState if (FlxG.keys.justPressed.EIGHT) FlxG.switchState(new ui.animDebugShit.DebugBoundingState()); + // get it like refreshing a browser + if (FlxG.keys.justPressed.F5) + debug_refreshStages(); + if (FlxG.keys.justPressed.NINE) iconP1.swapOldIcon(); @@ -2288,6 +2275,12 @@ class PlayState extends MusicBeatState if (!inCutscene) keyShit(); + + if (curStage != null) + { + // We're using Eric's stage handler. + curStage.onUpdate(elapsed); + } } function applyClipRect(daNote:Note):Void @@ -2725,10 +2718,17 @@ class PlayState extends MusicBeatState { openfl.utils.Assets.cache.clear(Paths.inst(SONG.song)); openfl.utils.Assets.cache.clear(Paths.voices(SONG.song)); - curStage.cleanup(); - curStage = null; + if (curStage != null) + { + remove(curStage); + curStage.kill(); + curStage = null; + } } + /** + * This function is called before switching to a new FlxState. + */ override function switchTo(nextState:FlxState):Bool { performCleanup(); diff --git a/source/baseCharPos.txt b/source/baseCharPos.txt new file mode 100644 index 000000000..fbae4834d --- /dev/null +++ b/source/baseCharPos.txt @@ -0,0 +1,3 @@ +BF: 770, 450 +GF: 400, 130 +DD: 100, 100 \ No newline at end of file diff --git a/source/modding/IHook.hx b/source/modding/IHook.hx index a1a75d08d..9b84b2039 100644 --- a/source/modding/IHook.hx +++ b/source/modding/IHook.hx @@ -1,6 +1,8 @@ package modding; +#if polymod import polymod.hscript.HScriptable; +#end /** * Add this interface to a class to make it a scriptable object. @@ -10,4 +12,4 @@ import polymod.hscript.HScriptable; // ALL of these values are added to ALL scripts in the child classes. context: [FlxG, FlxSprite, Math, Paths, Std] }) -interface IHook extends HScriptable {} +interface IHook #if polymod extends HScriptable #end {} diff --git a/source/play/stage/Stage.hx b/source/play/stage/Stage.hx index 3a2d2b578..125fa7c7d 100644 --- a/source/play/stage/Stage.hx +++ b/source/play/stage/Stage.hx @@ -1,5 +1,6 @@ package play.stage; +import flixel.math.FlxPoint; import flixel.FlxSprite; import flixel.group.FlxSpriteGroup; import flixel.util.FlxSort; @@ -50,6 +51,7 @@ class Stage extends FlxSpriteGroup implements IHook trace('Building stage for display: ${this.stageId}'); this.camZoom = _data.cameraZoom; + // this.scrollFactor = new FlxPoint(1, 1); for (dataProp in _data.props) { @@ -116,6 +118,7 @@ class Stage extends FlxSpriteGroup implements IHook public function refresh() { sort(SortUtil.byZIndex, FlxSort.ASCENDING); + trace('Stage sorted by z-index'); } /** @@ -125,6 +128,27 @@ class Stage extends FlxSpriteGroup implements IHook public function onUpdate(elapsed:Float):Void { // Override me in your scripted stage to perform custom behavior! + // trace('Stage.onUpdate(${elapsed})'); + } + + /** + * Adjusts the position and other properties of the soon-to-be child of this sprite group. + * Private helper to avoid duplicate code in `add()` and `insert()`. + * + * @param Sprite The sprite or sprite group that is about to be added or inserted into the group. + */ + override function preAdd(Sprite:FlxSprite):Void + { + var sprite:FlxSprite = cast Sprite; + sprite.x += x; + sprite.y += y; + sprite.alpha *= alpha; + // Don't override scroll factors. + // sprite.scrollFactor.copyFrom(scrollFactor); + sprite.cameras = _cameras; // _cameras instead of cameras because get_cameras() will not return null + + if (clipRect != null) + clipRectTransform(sprite, clipRect); } /** @@ -143,6 +167,7 @@ class Stage extends FlxSpriteGroup implements IHook public function onBeatHit(curBeat:Int):Void { // Override me in your scripted stage to perform custom behavior! + // trace('Stage.onBeatHit(${curBeat})'); } /** @@ -211,10 +236,56 @@ class Stage extends FlxSpriteGroup implements IHook return this.namedProps.get(name); } - public function cleanup() + /** + * Retrieve a list of all the asset paths required to load the stage. + * Override this in a scripted class to ensure that all necessary assets are loaded! + * + * @return An array of file names. + */ + public function fetchAssetPaths():Array<String> { - this.clear(); + var result:Array<String> = []; + for (dataProp in _data.props) + { + result.push(Paths.image(dataProp.assetPath)); + } + return result; + } + + /** + * Perform cleanup for when you are leaving the level. + */ + public override function kill() + { + super.kill(); + + for (prop in this.namedProps) + { + prop.destroy(); + } namedProps.clear(); + + for (char in this.characters) + { + char.destroy(); + } characters.clear(); + + for (sprite in this.group) + { + sprite.destroy(); + } + group.clear(); + } + + /** + * Perform cleanup for when you are destroying the stage + * and removing all its data from cache. + * + * Call this ONLY when you are performing a hard cache clear. + */ + public override function destroy() + { + super.destroy(); } } diff --git a/source/play/stage/StageData.hx b/source/play/stage/StageData.hx index c64acee19..5912ad824 100644 --- a/source/play/stage/StageData.hx +++ b/source/play/stage/StageData.hx @@ -30,10 +30,11 @@ class StageDataParser */ public static function loadStageCache():Void { - stageCache.clear(); - + // Clear any stages that are cached if there were any. + clearStageCache(); trace("Loading stage cache..."); + #if polymod // // SCRIPTED STAGES // @@ -45,6 +46,11 @@ class StageDataParser if (stage != null) { trace(' Loaded scripted stage: ${stage.stageName}'); + // Disable the rendering logic for stage until it's loaded. + // Note that kill() =/= destroy() + stage.kill(); + + // Then store it. stageCache.set(stage.stageId, stage); } else @@ -52,15 +58,21 @@ class StageDataParser trace(' Failed to instantiate scripted stage class: ${stageCls}'); } } + #end // // UNSCRIPTED STAGES // var stageIdList:Array<String> = DataAssets.listDataFilesInPath('stages/'); - var unscriptedStageIds:Array<String> = stageIdList.filter(function(stageId:String):Bool - { - return !stageCache.exists(stageId); - }); + var unscriptedStageIds:Array<String> = + #if polymod + stageIdList.filter(function(stageId:String):Bool + { + return !stageCache.exists(stageId); + }); + #else + stageIdList; + #end trace(' Instantiating ${unscriptedStageIds.length} non-scripted stages...'); for (stageId in unscriptedStageIds) { @@ -80,7 +92,9 @@ class StageDataParser if (stageCache.exists(stageId)) { trace('Successfully fetch stage: ${stageId}'); - return stageCache.get(stageId); + var stage:Stage = stageCache.get(stageId); + stage.revive(); + return stage; } else { @@ -89,6 +103,18 @@ class StageDataParser } } + static function clearStageCache():Void + { + if (stageCache != null) + { + for (stage in stageCache) + { + stage.destroy(); + } + stageCache.clear(); + } + } + /** * Load a stage's JSON file, parse its data, and return it. *